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 + -
显示快捷键?