start.s

来自「U-boot源码 ARM7启动代码」· S 代码 · 共 2,098 行 · 第 1/4 页

S
2,098
字号
	/*	 * Setup temporary stack pointer only for boards	 * that do not use SDRAM SPD I2C stuff since it	 * is already initialized to use DCACHE or OCM	 * stacks.	 */#if !(defined(CFG_INIT_DCACHE_CS) || defined(CFG_TEMP_STACK_OCM))	lis	r1, CFG_INIT_RAM_ADDR@h	ori	r1,r1,CFG_INIT_SP_OFFSET /* set up the stack in SDRAM */	li	r0, 0			/* Make room for stack frame header and */	stwu	r0, -4(r1)		/* clear final stack frame so that	*/	stwu	r0, -4(r1)		/* stack backtraces terminate cleanly	*/	/*	 * Set up a dummy frame to store reset vector as return address.	 * this causes stack underflow to reset board.	 */	stwu	r1, -8(r1)		/* Save back chain and move SP */	lis	r0, RESET_VECTOR@h	/* Address of reset vector */	ori	r0, r0, RESET_VECTOR@l	stwu	r1, -8(r1)		/* Save back chain and move SP */	stw	r0, +12(r1)		/* Save return addr (underflow vect) */#endif /* !(CFG_INIT_DCACHE_CS	|| !CFG_TEM_STACK_OCM) */#ifdef CONFIG_NAND_SPL	bl	nand_boot		/* will not return */#else	GET_GOT			/* initialize GOT access			*/	bl	cpu_init_f	/* run low-level CPU init code	   (from Flash) */	/* NEVER RETURNS! */	bl	board_init_f	/* run first part of init code (from Flash)	*/#endif /* CONFIG_NAND_SPL */#endif	/* CONFIG_405GP || CONFIG_405CR || CONFIG_405 || CONFIG_405EP */	/*----------------------------------------------------------------------- */#ifndef CONFIG_NAND_SPL/* * This code finishes saving the registers to the exception frame * and jumps to the appropriate handler for the exception. * Register r21 is pointer into trap frame, r1 has new stack pointer. */	.globl	transfer_to_handlertransfer_to_handler:	stw	r22,_NIP(r21)	lis	r22,MSR_POW@h	andc	r23,r23,r22	stw	r23,_MSR(r21)	SAVE_GPR(7, r21)	SAVE_4GPRS(8, r21)	SAVE_8GPRS(12, r21)	SAVE_8GPRS(24, r21)	mflr	r23	andi.	r24,r23,0x3f00		/* get vector offset */	stw	r24,TRAP(r21)	li	r22,0	stw	r22,RESULT(r21)	mtspr	SPRG2,r22		/* r1 is now kernel sp */	lwz	r24,0(r23)		/* virtual address of handler */	lwz	r23,4(r23)		/* where to go when done */	mtspr	SRR0,r24	mtspr	SRR1,r20	mtlr	r23	SYNC	rfi				/* jump to handler, enable MMU */int_return:	mfmsr	r28		/* Disable interrupts */	li	r4,0	ori	r4,r4,MSR_EE	andc	r28,r28,r4	SYNC			/* Some chip revs need this... */	mtmsr	r28	SYNC	lwz	r2,_CTR(r1)	lwz	r0,_LINK(r1)	mtctr	r2	mtlr	r0	lwz	r2,_XER(r1)	lwz	r0,_CCR(r1)	mtspr	XER,r2	mtcrf	0xFF,r0	REST_10GPRS(3, r1)	REST_10GPRS(13, r1)	REST_8GPRS(23, r1)	REST_GPR(31, r1)	lwz	r2,_NIP(r1)	/* Restore environment */	lwz	r0,_MSR(r1)	mtspr	SRR0,r2	mtspr	SRR1,r0	lwz	r0,GPR0(r1)	lwz	r2,GPR2(r1)	lwz	r1,GPR1(r1)	SYNC	rficrit_return:	mfmsr	r28		/* Disable interrupts */	li	r4,0	ori	r4,r4,MSR_EE	andc	r28,r28,r4	SYNC			/* Some chip revs need this... */	mtmsr	r28	SYNC	lwz	r2,_CTR(r1)	lwz	r0,_LINK(r1)	mtctr	r2	mtlr	r0	lwz	r2,_XER(r1)	lwz	r0,_CCR(r1)	mtspr	XER,r2	mtcrf	0xFF,r0	REST_10GPRS(3, r1)	REST_10GPRS(13, r1)	REST_8GPRS(23, r1)	REST_GPR(31, r1)	lwz	r2,_NIP(r1)	/* Restore environment */	lwz	r0,_MSR(r1)	mtspr	csrr0,r2	mtspr	csrr1,r0	lwz	r0,GPR0(r1)	lwz	r2,GPR2(r1)	lwz	r1,GPR1(r1)	SYNC	rfci#ifdef CONFIG_440mck_return:	mfmsr	r28		/* Disable interrupts */	li	r4,0	ori	r4,r4,MSR_EE	andc	r28,r28,r4	SYNC			/* Some chip revs need this... */	mtmsr	r28	SYNC	lwz	r2,_CTR(r1)	lwz	r0,_LINK(r1)	mtctr	r2	mtlr	r0	lwz	r2,_XER(r1)	lwz	r0,_CCR(r1)	mtspr	XER,r2	mtcrf	0xFF,r0	REST_10GPRS(3, r1)	REST_10GPRS(13, r1)	REST_8GPRS(23, r1)	REST_GPR(31, r1)	lwz	r2,_NIP(r1)	/* Restore environment */	lwz	r0,_MSR(r1)	mtspr	mcsrr0,r2	mtspr	mcsrr1,r0	lwz	r0,GPR0(r1)	lwz	r2,GPR2(r1)	lwz	r1,GPR1(r1)	SYNC	rfmci#endif /* CONFIG_440 *//* * Cache functions. * * NOTE: currently the 440s run with dcache _disabled_ once relocated to DRAM, * although for some cache-ralated calls stubs have to be provided to satisfy * symbols resolution. * Icache-related functions are used in POST framework. * */#ifdef CONFIG_440       .globl  dcache_disable       .globl  icache_disable       .globl  icache_enabledcache_disable:icache_disable:icache_enable:	blr	.globl	dcache_status	.globl	icache_statusdcache_status:icache_status:	mr	r3,  0	blr#elseflush_dcache:	addis	r9,r0,0x0002		/* set mask for EE and CE msr bits */	ori	r9,r9,0x8000	mfmsr	r12			/* save msr */	andc	r9,r12,r9	mtmsr	r9			/* disable EE and CE */	addi	r10,r0,0x0001		/* enable data cache for unused memory */	mfdccr	r9			/* region 0xF8000000-0xFFFFFFFF via */	or	r10,r10,r9		/* bit 31 in dccr */	mtdccr	r10	/* do loop for # of congruence classes. */	lis	r10,(CFG_DCACHE_SIZE / CFG_CACHELINE_SIZE / 2)@ha	/* TBS: for large cache sizes */	ori	r10,r10,(CFG_DCACHE_SIZE / CFG_CACHELINE_SIZE / 2)@l	lis	r11,(CFG_DCACHE_SIZE / 2)@ha /* D cache set size - 2 way sets */	ori	r11,r11,(CFG_DCACHE_SIZE / 2)@l /* D cache set size - 2 way sets */	mtctr	r10	addi	r10,r0,(0xE000-0x10000) /* start at 0xFFFFE000 */	add	r11,r10,r11		/* add to get to other side of cache line */..flush_dcache_loop:	lwz	r3,0(r10)		/* least recently used side */	lwz	r3,0(r11)		/* the other side */	dccci	r0,r11			/* invalidate both sides */	addi	r10,r10,CFG_CACHELINE_SIZE /* bump to next line */	addi	r11,r11,CFG_CACHELINE_SIZE /* bump to next line */	bdnz	..flush_dcache_loop	sync				/* allow memory access to complete */	mtdccr	r9			/* restore dccr */	mtmsr	r12			/* restore msr */	blr	.globl	icache_enableicache_enable:	mflr	r8	bl	invalidate_icache	mtlr	r8	isync	addis	r3,r0, 0x8000	      /* set bit 0 */	mticcr	r3	blr	.globl	icache_disableicache_disable:	addis	r3,r0, 0x0000	      /* clear bit 0 */	mticcr	r3	isync	blr	.globl	icache_statusicache_status:	mficcr	r3	srwi	r3, r3, 31	/* >>31 => select bit 0 */	blr	.globl	dcache_enabledcache_enable:	mflr	r8	bl	invalidate_dcache	mtlr	r8	isync	addis	r3,r0, 0x8000	      /* set bit 0 */	mtdccr	r3	blr	.globl	dcache_disabledcache_disable:	mflr	r8	bl	flush_dcache	mtlr	r8	addis	r3,r0, 0x0000	      /* clear bit 0 */	mtdccr	r3	blr	.globl	dcache_statusdcache_status:	mfdccr	r3	srwi	r3, r3, 31	/* >>31 => select bit 0 */	blr#endif	.globl get_pvrget_pvr:	mfspr	r3, PVR	blr/*------------------------------------------------------------------------------- *//* Function:	 out16 *//* Description:	 Output 16 bits *//*------------------------------------------------------------------------------- */	.globl	out16out16:	sth	r4,0x0000(r3)	blr/*------------------------------------------------------------------------------- *//* Function:	 out16r *//* Description:	 Byte reverse and output 16 bits *//*------------------------------------------------------------------------------- */	.globl	out16rout16r:	sthbrx	r4,r0,r3	blr/*------------------------------------------------------------------------------- *//* Function:	 out32r *//* Description:	 Byte reverse and output 32 bits *//*------------------------------------------------------------------------------- */	.globl	out32rout32r:	stwbrx	r4,r0,r3	blr/*------------------------------------------------------------------------------- *//* Function:	 in16 *//* Description:	 Input 16 bits *//*------------------------------------------------------------------------------- */	.globl	in16in16:	lhz	r3,0x0000(r3)	blr/*------------------------------------------------------------------------------- *//* Function:	 in16r *//* Description:	 Input 16 bits and byte reverse *//*------------------------------------------------------------------------------- */	.globl	in16rin16r:	lhbrx	r3,r0,r3	blr/*------------------------------------------------------------------------------- *//* Function:	 in32r *//* Description:	 Input 32 bits and byte reverse *//*------------------------------------------------------------------------------- */	.globl	in32rin32r:	lwbrx	r3,r0,r3	blr/*------------------------------------------------------------------------------- *//* Function:	 ppcDcbf *//* Description:	 Data Cache block flush *//* Input:	 r3 = effective address *//* Output:	 none. *//*------------------------------------------------------------------------------- */	.globl	ppcDcbfppcDcbf:	dcbf	r0,r3	blr/*------------------------------------------------------------------------------- *//* Function:	 ppcDcbi *//* Description:	 Data Cache block Invalidate *//* Input:	 r3 = effective address *//* Output:	 none. *//*------------------------------------------------------------------------------- */	.globl	ppcDcbippcDcbi:	dcbi	r0,r3	blr/*------------------------------------------------------------------------------- *//* Function:	 ppcSync *//* Description:	 Processor Synchronize *//* Input:	 none. *//* Output:	 none. *//*------------------------------------------------------------------------------- */	.globl	ppcSyncppcSync:	sync	blr/* * void relocate_code (addr_sp, gd, addr_moni) * * This "function" does not return, instead it continues in RAM * after relocating the monitor code. * * r3 = dest * r4 = src * r5 = length in bytes * r6 = cachelinesize */	.globl	relocate_coderelocate_code:#if defined(CONFIG_440EP) || defined(CONFIG_440GR) || \    defined(CONFIG_440EPX) || defined(CONFIG_440GRX) || \    defined(CONFIG_440SP) || defined(CONFIG_440SPE)	/*	 * On some 440er platforms the cache is enabled in the first TLB (Boot-CS)	 * to speed up the boot process. Now this cache needs to be disabled.	 */	iccci	0,0			/* Invalidate inst cache */	dccci	0,0			/* Invalidate data cache, now no longer our stack */	sync	isync	addi	r1,r0,0x0000		/* TLB entry #0 */	tlbre	r0,r1,0x0002		/* Read contents */	ori	r0,r0,0x0c00		/* Or in the inhibit, write through bit */	tlbwe	r0,r1,0x0002		/* Save it out */	sync	isync#endif	mr	r1,  r3		/* Set new stack pointer		*/	mr	r9,  r4		/* Save copy of Init Data pointer	*/	mr	r10, r5		/* Save copy of Destination Address	*/	mr	r3,  r5				/* Destination Address	*/	lis	r4, CFG_MONITOR_BASE@h		/* Source      Address	*/	ori	r4, r4, CFG_MONITOR_BASE@l	lwz	r5, GOT(__init_end)	sub	r5, r5, r4	li	r6, CFG_CACHELINE_SIZE		/* Cache Line Size	*/	/*	 * Fix GOT pointer:	 *	 * New GOT-PTR = (old GOT-PTR - CFG_MONITOR_BASE) + Destination Address	 *	 * Offset:	 */	sub	r15, r10, r4	/* First our own GOT */	add	r14, r14, r15	/* the the one used by the C code */	add	r30, r30, r15	/*	 * Now relocate code	 */	cmplw	cr1,r3,r4	addi	r0,r5,3	srwi.	r0,r0,2	beq	cr1,4f		/* In place copy is not necessary	*/	beq	7f		/* Protect against 0 count		*/	mtctr	r0	bge	cr1,2f	la	r8,-4(r4)	la	r7,-4(r3)1:	lwzu	r0,4(r8)	stwu	r0,4(r7)	bdnz	1b	b	4f2:	slwi	r0,r0,2	add	r8,r4,r0	add	r7,r3,r03:	lwzu	r0,-4(r8)	stwu	r0,-4(r7)	bdnz	3b/* * Now flush the cache: note that we must start from a cache aligned * address. Otherwise we might miss one cache line. */4:	cmpwi	r6,0	add	r5,r3,r5	beq	7f		/* Always flush prefetch queue in any case */	subi	r0,r6,1	andc	r3,r3,r0	mr	r4,r35:	dcbst	0,r4	add	r4,r4,r6	cmplw	r4,r5	blt	5b	sync			/* Wait for all dcbst to complete on bus */	mr	r4,r36:	icbi	0,r4	add	r4,r4,r6	cmplw	r4,r5	blt	6b7:	sync			/* Wait for all icbi to complete on bus */	isync/* * We are done. Do not return, instead branch to second part of board * initialization, now running from RAM. */	addi	r0, r10, in_ram - _start + _START_OFFSET	mtlr	r0	blr				/* NEVER RETURNS! */in_ram:	/*	 * Relocation Function, r14 point to got2+0x8000	 *	 * Adjust got2 pointers, no need to check for 0, this code	 * already puts a few entries in the table.	 */	li	r0,__got2_entries@sectoff@l	la	r3,GOT(_GOT2_TABLE_)	lwz	r11,GOT(_GOT2_TABLE_)	mtctr	r0	sub	r11,r3,r11	addi	r3,r3,-41:	lwzu	r0,4(r3)	add	r0,r0,r11	stw	r0,0(r3)	bdnz	1b	/*	 * Now adjust the fixups and the pointers to the fixups	 * in case we need to move ourselves again.	 */2:	li	r0,__fixup_entries@sectoff@l	lwz	r3,GOT(_FIXUP_TABLE_)	cmpwi	r0,0	mtctr	r0	addi	r3,r3,-4	beq	4f3:	lwzu	r4,4(r3)	lwzux	r0,r4,r11	add	r0,r0,r11	stw	r10,0(r3)	stw	r0,0(r4)	bdnz	3b4:clear_bss:	/*	 * Now clear BSS segment	 */	lwz	r3,GOT(__bss_start)	lwz	r4,GOT(_end)	cmplw	0, r3, r4	beq	6f	li	r0, 05:	stw	r0, 0(r3)	addi	r3, r3, 4	cmplw	0, r3, r4

⌨️ 快捷键说明

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