📄 head.s
字号:
st %g4, [%o0 + %lo( C_LABEL(cputyp) )] /* Turn on Supervisor, EnableFloating, and all the PIL bits. * Also puts us in register window zero with traps off. */ set (PSR_PS | PSR_S | PSR_PIL | PSR_EF), %g2 wr %g2, 0x0, %psr WRITE_PAUSE /* I want a kernel stack NOW! */ set C_LABEL(init_task_union), %g1 set (TASK_UNION_SIZE - REGWIN_SZ), %g2 add %g1, %g2, %sp mov 0, %fp /* And for good luck */ /* Zero out our BSS section. */ set C_LABEL(__bss_start) , %o0 ! First address of BSS set C_LABEL(end) , %o1 ! Last address of BSS add %o0, 0x1, %o01: stb %g0, [%o0] subcc %o0, %o1, %g0 bl 1b add %o0, 0x1, %o0 /* Initialize the umask value for init_task just in case. * But first make current_set[boot_cpu_id] point to something useful. */ set C_LABEL(init_task_union), %g6 set C_LABEL(current_set), %g2#ifdef CONFIG_SMP sethi %hi(C_LABEL(boot_cpu_id4)), %g3 ldub [%g3 + %lo(C_LABEL(boot_cpu_id4))], %g3 st %g6, [%g2] add %g2, %g3, %g2#endif st %g6, [%g2] st %g0, [%g6 + AOFF_task_thread + AOFF_thread_uwinmask]/* Compute NWINDOWS and stash it away. Now uses %wim trick explained * in the V8 manual. Ok, this method seems to work, Sparc is cool... * No, it doesn't work, have to play the save/readCWP/restore trick. */ wr %g0, 0x0, %wim ! so we do not get a trap WRITE_PAUSE save rd %psr, %g3 restore and %g3, 0x1f, %g3 add %g3, 0x1, %g3 mov 2, %g1 wr %g1, 0x0, %wim ! make window 1 invalid WRITE_PAUSE cmp %g3, 0x7 bne 2f nop /* Adjust our window handling routines to * do things correctly on 7 window Sparcs. */#define PATCH_INSN(src, dest) \ set src, %g5; \ set dest, %g2; \ ld [%g5], %g4; \ st %g4, [%g2]; /* Patch for window spills... */ PATCH_INSN(spnwin_patch1_7win, spnwin_patch1) PATCH_INSN(spnwin_patch2_7win, spnwin_patch2) PATCH_INSN(spnwin_patch3_7win, spnwin_patch3) /* Patch for window fills... */ PATCH_INSN(fnwin_patch1_7win, fnwin_patch1) PATCH_INSN(fnwin_patch2_7win, fnwin_patch2) /* Patch for trap entry setup... */ PATCH_INSN(tsetup_7win_patch1, tsetup_patch1) PATCH_INSN(tsetup_7win_patch2, tsetup_patch2) PATCH_INSN(tsetup_7win_patch3, tsetup_patch3) PATCH_INSN(tsetup_7win_patch4, tsetup_patch4) PATCH_INSN(tsetup_7win_patch5, tsetup_patch5) PATCH_INSN(tsetup_7win_patch6, tsetup_patch6) /* Patch for returning from traps... */ PATCH_INSN(rtrap_7win_patch1, rtrap_patch1) PATCH_INSN(rtrap_7win_patch2, rtrap_patch2) PATCH_INSN(rtrap_7win_patch3, rtrap_patch3) PATCH_INSN(rtrap_7win_patch4, rtrap_patch4) PATCH_INSN(rtrap_7win_patch5, rtrap_patch5) /* Patch for killing user windows from the register file. */ PATCH_INSN(kuw_patch1_7win, kuw_patch1) /* Now patch the kernel window flush sequences. * This saves 2 traps on every switch and fork. */ set 0x01000000, %g4 set flush_patch_one, %g5 st %g4, [%g5 + 0x18] st %g4, [%g5 + 0x1c] set flush_patch_two, %g5 st %g4, [%g5 + 0x18] st %g4, [%g5 + 0x1c] set flush_patch_three, %g5 st %g4, [%g5 + 0x18] st %g4, [%g5 + 0x1c] set flush_patch_four, %g5 st %g4, [%g5 + 0x18] st %g4, [%g5 + 0x1c] set flush_patch_exception, %g5 st %g4, [%g5 + 0x18] st %g4, [%g5 + 0x1c] set flush_patch_switch, %g5 st %g4, [%g5 + 0x18] st %g4, [%g5 + 0x1c]2: sethi %hi( C_LABEL(nwindows) ), %g4 st %g3, [%g4 + %lo( C_LABEL(nwindows) )] ! store final value sub %g3, 0x1, %g3 sethi %hi( C_LABEL(nwindowsm1) ), %g4 st %g3, [%g4 + %lo( C_LABEL(nwindowsm1) )] /* Here we go, start using Linux's trap table... */ set C_LABEL(trapbase), %g3 wr %g3, 0x0, %tbr WRITE_PAUSE /* Finally, turn on traps so that we can call c-code. */ rd %psr, %g3 wr %g3, 0x0, %psr WRITE_PAUSE wr %g3, PSR_ET, %psr WRITE_PAUSE /* First we call prom_init() to set up PROMLIB, then * off to start_kernel(). */ sethi %hi( C_LABEL(prom_vector_p) ), %g5 ld [%g5 + %lo( C_LABEL(prom_vector_p) )], %o0 call C_LABEL(prom_init) nop call C_LABEL(start_kernel) nop /* We should not get here. */ call halt_me nopsun4_init:#ifdef CONFIG_SUN4/* There, happy now Adrian? */ set C_LABEL(cputypval), %o2 ! Let everyone know we set ' ', %o0 ! are a "sun4 " architecture stb %o0, [%o2 + 0x4] b got_prop nop#else sethi %hi(SUN4_PROM_VECTOR+0x84), %o1 ld [%o1 + %lo(SUN4_PROM_VECTOR+0x84)], %o1 set sun4_notsup, %o0 call %o1 /* printf */ nop sethi %hi(SUN4_PROM_VECTOR+0xc4), %o1 ld [%o1 + %lo(SUN4_PROM_VECTOR+0xc4)], %o1 call %o1 /* exittomon */ nop1: ba 1b ! Cannot exit into KMON nop#endifno_sun4e_here: ld [%g7 + 0x68], %o1 set sun4e_notsup, %o0 call %o1 nop b halt_me nop __INITDATAsun4u_1: .asciz "finddevice" .align 4sun4u_2: .asciz "/chosen" .align 4sun4u_3: .asciz "getprop" .align 4sun4u_4: .asciz "stdout" .align 4sun4u_5: .asciz "write" .align 4sun4u_6: .asciz "\n\rOn sun4u you have to use UltraLinux (64bit) kernel\n\rand not a 32bit sun4[cdem] version\n\r\n\r"sun4u_6e: .align 4sun4u_7: .asciz "exit" .align 8sun4u_a1: .word 0, sun4u_1, 0, 1, 0, 1, 0, sun4u_2, 0sun4u_r1: .word 0sun4u_a2: .word 0, sun4u_3, 0, 4, 0, 1, 0sun4u_i2: .word 0, 0, sun4u_4, 0, sun4u_1, 0, 8, 0sun4u_r2: .word 0sun4u_a3: .word 0, sun4u_5, 0, 3, 0, 1, 0sun4u_i3: .word 0, 0, sun4u_6, 0, sun4u_6e - sun4u_6 - 1, 0sun4u_r3: .word 0sun4u_a4: .word 0, sun4u_7, 0, 0, 0, 0sun4u_r4: __INITno_sun4u_here: set sun4u_a1, %o0 set current_pc, %l2 cmp %l2, %g3 be 1f mov %o4, %l0 sub %g3, %l2, %l6 add %o0, %l6, %o0 mov %o0, %l4 mov sun4u_r4 - sun4u_a1, %l3 ld [%l4], %l52: add %l4, 4, %l4 cmp %l5, %l2 add %l5, %l6, %l5 bgeu,a 3f st %l5, [%l4 - 4]3: subcc %l3, 4, %l3 bne 2b ld [%l4], %l51: call %l0 mov %o0, %l1 ld [%l1 + (sun4u_r1 - sun4u_a1)], %o1 add %l1, (sun4u_a2 - sun4u_a1), %o0 call %l0 st %o1, [%o0 + (sun4u_i2 - sun4u_a2)] ld [%l1 + (sun4u_1 - sun4u_a1)], %o1 add %l1, (sun4u_a3 - sun4u_a1), %o0 call %l0 st %o1, [%o0 + (sun4u_i3 - sun4u_a3)] call %l0 add %l1, (sun4u_a4 - sun4u_a1), %o0 /* Not reached */halt_me: ld [%g7 + 0x74], %o0 call %o0 ! Get us out of here... nop ! Apparently Solaris is better./* Ok, now we continue in the .data/.text sections */ .data .align 4/* * Fill up the prom vector, note in particular the kind first element, * no joke. I don't need all of them in here as the entire prom vector * gets initialized in c-code so all routines can use it. */ .globl C_LABEL(prom_vector_p)C_LABEL(prom_vector_p): .word 0/* We calculate the following at boot time, window fills/spills and trap entry * code uses these to keep track of the register windows. */ .align 4 .globl C_LABEL(nwindows) .globl C_LABEL(nwindowsm1)C_LABEL(nwindows): .word 8C_LABEL(nwindowsm1): .word 7/* Boot time debugger vector value. We need this later on. */ .align 4 .globl C_LABEL(linux_dbvec)C_LABEL(linux_dbvec): .word 0 .word 0 .align 8 .globl C_LABEL(lvl14_save)C_LABEL(lvl14_save): .word 0 .word 0 .word 0 .word 0 .word t_irq14 .section ".fixup",#alloc,#execinstr .globl __ret_efault__ret_efault: ret restore %g0, -EFAULT, %o0
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -