start.s

来自「最新版的u-boot,2008-10-18发布」· S 代码 · 共 662 行 · 第 1/2 页

S
662
字号
	ldd	[%g2],%l0	ldd	[%g2+8],%l2	std	%l0,[%g4]	std	%l2,[%g4+8]	inc	16,%g2	subcc	%g3,%g2,%g0	bne	reloc_loop	inc	16,%g4	clr	%l0	clr	%l1	clr	%l2	clr	%l3	clr	%g2/* register g4 contain address to start * This means that BSS must be directly after data and code segments * * g3 is length of bss = (__bss_end-__bss_start) * */clr_bss:/* clear bss area (the relocated) */	set	__bss_start,%g2	set	__bss_end,%g3	sub	%g3,%g2,%g3	add	%g3,%g4,%g3	clr	%g1	/* std %g0 uses g0 and g1 *//* clearing 16byte a time ==> linker script need to align to 16 byte offset */clr_bss_16:	std	%g0,[%g4]	std	%g0,[%g4+8]	inc	16,%g4	cmp	%g3,%g4	bne	clr_bss_16	nop/* add offsets to GOT table */fixup_got:	set	__got_start,%g4	set	__got_end,%g3/* * new got offset = (old GOT-PTR (read with ld) - *   CFG_RELOC_MONITOR_BASE(from define) ) + *   Destination Address (from define) */	set	CFG_RELOC_MONITOR_BASE,%g2	set	TEXT_START, %g1	add	%g4,%g2,%g4	sub	%g4,%g1,%g4	add	%g3,%g2,%g3	sub	%g3,%g1,%g3	sub	%g2,%g1,%g2	! prepare register with (new base address) -				!  (old base address)got_loop:	ld	[%g4],%l0	! load old GOT-PTR	add	%l0,%g2,%l0	! increase with (new base address) -				!  (old base)	st	%l0,[%g4]	inc	4,%g4	cmp	%g3,%g4	bne	got_loop	nopprom_relocate:	set	__prom_start, %g2	set	__prom_end, %g3	set	CFG_PROM_OFFSET, %g4prom_relocate_loop:	ldd	[%g2],%l0	ldd	[%g2+8],%l2	std	%l0,[%g4]	std	%l2,[%g4+8]	inc	16,%g2	subcc	%g3,%g2,%g0	bne	prom_relocate_loop	inc	16,%g4/* Trap table has been moved, lets tell CPU about * the new trap table address */	set	CFG_RELOC_MONITOR_BASE, %g2	wr	%g0, %g2, %tbr/*	call	relocate*/	nop/* Call relocated init functions */jump:	set	cpu_init_f2,%o1	set	CFG_RELOC_MONITOR_BASE,%o2	add	%o1,%o2,%o1	sub	%o1,%g1,%o1	call	%o1	clr	%o0	set	board_init_f,%o1	set	CFG_RELOC_MONITOR_BASE,%o2	add	%o1,%o2,%o1	sub	%o1,%g1,%o1	call	%o1	clr	%o0dead:	ta 0				! if call returns...	nop/* Interrupt handler caller, * reg L7: interrupt number * reg L0: psr after interrupt * reg L1: PC * reg L2: next PC * reg L3: wim */_irq_entry:	SAVE_ALL	or	%l0, PSR_PIL, %g2	wr	%g2, 0x0, %psr	WRITE_PAUSE	wr	%g2, PSR_ET, %psr	WRITE_PAUSE	mov	%l7, %o0		! irq level	set	handler_irq, %o1	set	(CFG_RELOC_MONITOR_BASE-TEXT_BASE), %o2	add	%o1, %o2, %o1	call	%o1	add	%sp, SF_REGS_SZ, %o1	! pt_regs ptr	or	%l0, PSR_PIL, %g2	! restore PIL after handler_irq	wr	%g2, PSR_ET, %psr	! keep ET up	WRITE_PAUSE	RESTORE_ALL!Window overflow trap handler.	.global _window_overflow_window_overflow:	mov	%wim, %l3		! Calculate next WIM	mov	%g1, %l7	srl	%l3, 1, %g1	sll	%l3, (CFG_SPARC_NWINDOWS-1) , %l4	or	%l4, %g1, %g1	save				! Get into window to be saved.	mov	%g1, %wim	nop;	nop;	nop	st	%l0, [%sp + 0];	st	%l1, [%sp + 4];	st	%l2, [%sp + 8];	st	%l3, [%sp + 12];	st	%l4, [%sp + 16];	st	%l5, [%sp + 20];	st	%l6, [%sp + 24];	st	%l7, [%sp + 28];	st	%i0, [%sp + 32];	st	%i1, [%sp + 36];	st	%i2, [%sp + 40];	st	%i3, [%sp + 44];	st	%i4, [%sp + 48];	st	%i5, [%sp + 52];	st	%i6, [%sp + 56];	st	%i7, [%sp + 60];	restore				! Go back to trap window.	mov	%l7, %g1	jmp	%l1			! Re-execute save.	rett	%l2/* Window underflow trap handler.  */	.global  _window_underflow_window_underflow:	mov  %wim, %l3			! Calculate next WIM	sll  %l3, 1, %l4	srl  %l3, (CFG_SPARC_NWINDOWS-1), %l5	or   %l5, %l4, %l5	mov  %l5, %wim	nop; nop; nop	restore				! Two restores to get into the	restore				! window to restore	ld	[%sp + 0], %l0;		! Restore window from the stack	ld	[%sp + 4], %l1;	ld	[%sp + 8], %l2;	ld	[%sp + 12], %l3;	ld	[%sp + 16], %l4;	ld	[%sp + 20], %l5;	ld	[%sp + 24], %l6;	ld	[%sp + 28], %l7;	ld	[%sp + 32], %i0;	ld	[%sp + 36], %i1;	ld	[%sp + 40], %i2;	ld	[%sp + 44], %i3;	ld	[%sp + 48], %i4;	ld	[%sp + 52], %i5;	ld	[%sp + 56], %i6;	ld	[%sp + 60], %i7;	save				! Get back to the trap window.	save	jmp	%l1			! Re-execute restore.	rett	%l2	retl_nmi_trap:	nop	jmp %l1	rett %l2_hwerr:	ta 0	nop	nop	b _hwerr			! loop infinite	nop/* Registers to not touch at all. */#define t_psr      l0 /* Set by caller */#define t_pc       l1 /* Set by caller */#define t_npc      l2 /* Set by caller */#define t_wim      l3 /* Set by caller */#define t_twinmask l4 /* Set at beginning of this entry routine. */#define t_kstack   l5 /* Set right before pt_regs frame is built */#define t_retpc    l6 /* If you change this, change winmacro.h header file */#define t_systable l7 /* Never touch this, could be the syscall table ptr. */#define curptr     g6 /* Set after pt_regs frame is built */trap_setup:/* build a pt_regs trap frame. */	sub	%fp, (SF_REGS_SZ + PT_REGS_SZ), %t_kstack	PT_STORE_ALL(t_kstack, t_psr, t_pc, t_npc, g2)	/* See if we are in the trap window. */	mov	1, %t_twinmask	sll	%t_twinmask, %t_psr, %t_twinmask ! t_twinmask = (1 << psr)	andcc	%t_twinmask, %t_wim, %g0	beq	1f		! in trap window, clean up	nop	/*-------------------------------------------------	 * Spill , adjust %wim and go.	 */	srl	%t_wim, 0x1, %g2		! begin computation of new %wim	set	(CFG_SPARC_NWINDOWS-1), %g3	!NWINDOWS-1	sll	%t_wim, %g3, %t_wim	! NWINDOWS-1	or	%t_wim, %g2, %g2	and	%g2, 0xff, %g2	save	%g0, %g0, %g0		! get in window to be saved	/* Set new %wim value */	wr	%g2, 0x0, %wim	/* Save the kernel window onto the corresponding stack. */	RW_STORE(sp)	restore	%g0, %g0, %g0	/*-------------------------------------------------*/1:	/* Trap from kernel with a window available.	 * Just do it...	 */	jmpl	%t_retpc + 0x8, %g0	! return to caller	 mov	%t_kstack, %sp		! jump onto new stack#define twin_tmp1 l4#define glob_tmp  g4#define curptr    g6ret_trap_entry:	wr	%t_psr, 0x0, %psr       ! enable nesting again, clear ET	/* Will the rett land us in the invalid window? */	mov	2, %g1	sll	%g1, %t_psr, %g1	set	CFG_SPARC_NWINDOWS, %g2	!NWINDOWS	srl	%g1, %g2, %g2	or	%g1, %g2, %g1	rd	%wim, %g2	andcc	%g2, %g1, %g0	be	1f		! Nope, just return from the trap	 sll	%g2, 0x1, %g1	/* We have to grab a window before returning. */	set	(CFG_SPARC_NWINDOWS-1), %g3	!NWINDOWS-1	srl	%g2, %g3,  %g2	or	%g1, %g2, %g1	and	%g1, 0xff, %g1	wr	%g1, 0x0, %wim	/* Grrr, make sure we load from the right %sp... */	PT_LOAD_ALL(sp, t_psr, t_pc, t_npc, g1)	restore	%g0, %g0, %g0	RW_LOAD(sp)	b	2f	save	%g0, %g0, %g0	/* Reload the entire frame in case this is from a	 * kernel system call or whatever...	 */1:	PT_LOAD_ALL(sp, t_psr, t_pc, t_npc, g1)2:	wr	%t_psr, 0x0, %psr	nop;	nop;	nop	jmp	%t_pc	rett	%t_npc/* This is called from relocated C-code. * It resets the system by jumping to _start */_reset_reloc:	set	start, %l0	call	%l0	nop

⌨️ 快捷键说明

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