📄 head.s
字号:
srl %g3, 3, %g4 sta %g4, [%g0] ASI_M_VIKING_TMP1 sethi %hi(boot_cpu_id), %g5 stb %g4, [%g5 + %lo(boot_cpu_id)] sll %g4, 2, %g4 sethi %hi(boot_cpu_id4), %g5 stb %g4, [%g5 + %lo(boot_cpu_id4)]#endif /* Fall through to sun4m_init */sun4m_init: /* XXX Fucking Cypress... */ lda [%g0] ASI_M_MMUREGS, %g5 srl %g5, 28, %g4 cmp %g4, 1 bne 1f srl %g5, 24, %g4 and %g4, 0xf, %g4 cmp %g4, 7 /* This would be a HyperSparc. */ bne 2f nop1:#define PATCH_IT(dst, src) \ set (dst), %g5; \ set (src), %g4; \ ld [%g4], %g3; \ st %g3, [%g5]; \ ld [%g4+0x4], %g3; \ st %g3, [%g5+0x4]; /* Signed multiply. */ PATCH_IT(.mul, .mul_patch) PATCH_IT(.mul+0x08, .mul_patch+0x08) /* Signed remainder. */ PATCH_IT(.rem, .rem_patch) PATCH_IT(.rem+0x08, .rem_patch+0x08) PATCH_IT(.rem+0x10, .rem_patch+0x10) PATCH_IT(.rem+0x18, .rem_patch+0x18) PATCH_IT(.rem+0x20, .rem_patch+0x20) PATCH_IT(.rem+0x28, .rem_patch+0x28) /* Signed division. */ PATCH_IT(.div, .div_patch) PATCH_IT(.div+0x08, .div_patch+0x08) PATCH_IT(.div+0x10, .div_patch+0x10) PATCH_IT(.div+0x18, .div_patch+0x18) PATCH_IT(.div+0x20, .div_patch+0x20) /* Unsigned multiply. */ PATCH_IT(.umul, .umul_patch) PATCH_IT(.umul+0x08, .umul_patch+0x08) /* Unsigned remainder. */ PATCH_IT(.urem, .urem_patch) PATCH_IT(.urem+0x08, .urem_patch+0x08) PATCH_IT(.urem+0x10, .urem_patch+0x10) PATCH_IT(.urem+0x18, .urem_patch+0x18) /* Unsigned division. */ PATCH_IT(.udiv, .udiv_patch) PATCH_IT(.udiv+0x08, .udiv_patch+0x08) PATCH_IT(.udiv+0x10, .udiv_patch+0x10)#undef PATCH_IT/* Ok, the PROM could have done funny things and apple cider could still * be sitting in the fault status/address registers. Read them all to * clear them so we don't get magic faults later on. *//* This sucks, apparently this makes Vikings call prom panic, will fix later */2: rd %psr, %o1 srl %o1, 28, %o1 ! Get a type of the CPU subcc %o1, 4, %g0 ! TI: Viking or MicroSPARC be sun4c_continue_boot nop set AC_M_SFSR, %o0 lda [%o0] ASI_M_MMUREGS, %g0 set AC_M_SFAR, %o0 lda [%o0] ASI_M_MMUREGS, %g0 /* Fujitsu MicroSPARC-II has no asynchronous flavors of FARs */ subcc %o1, 0, %g0 be sun4c_continue_boot nop set AC_M_AFSR, %o0 lda [%o0] ASI_M_MMUREGS, %g0 set AC_M_AFAR, %o0 lda [%o0] ASI_M_MMUREGS, %g0 nopsun4c_continue_boot:/* Aieee, now set PC and nPC, enable traps, give ourselves a stack and it's * show-time! */ sethi %hi(cputyp), %o0 st %g4, [%o0 + %lo(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 init_thread_union, %g1 set (THREAD_SIZE - STACKFRAME_SZ), %g2 add %g1, %g2, %sp mov 0, %fp /* And for good luck */ /* Zero out our BSS section. */ set __bss_start , %o0 ! First address of BSS set 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 uwinmask value for init task just in case. * But first make current_set[boot_cpu_id] point to something useful. */ set init_thread_union, %g6 set current_set, %g2#ifdef CONFIG_SMP sethi %hi(boot_cpu_id4), %g3 ldub [%g3 + %lo(boot_cpu_id4)], %g3 st %g6, [%g2] add %g2, %g3, %g2#endif st %g6, [%g2] st %g0, [%g6 + TI_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(nwindows), %g4 st %g3, [%g4 + %lo(nwindows)] ! store final value sub %g3, 0x1, %g3 sethi %hi(nwindowsm1), %g4 st %g3, [%g4 + %lo(nwindowsm1)] /* Here we go, start using Linux's trap table... */ set 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(prom_vector_p), %g5 ld [%g5 + %lo(prom_vector_p)], %o0 call prom_init nop call start_kernel nop /* We should not get here. */ call halt_me nopsun4_init:#ifdef CONFIG_SUN4/* There, happy now Adrian? */ set 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 prom_vector_pprom_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 nwindows .globl nwindowsm1nwindows: .word 8nwindowsm1: .word 7/* Boot time debugger vector value. We need this later on. */ .align 4 .globl linux_dbveclinux_dbvec: .word 0 .word 0 .align 8 .globl lvl14_savelvl14_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 + -