📄 head.s
字号:
nop; nop; nop /* PROM never puts any TLB entries into the MMU with the lock bit * set. So we gladly use tlb entry 63 for KERNBASE. And maybe 62 too. */ sethi %hi(KERNBASE), %g3 mov (63 << 3), %g7 stxa %g3, [%l7] ASI_DMMU /* KERNBASE into TLB TAG */ stxa %g5, [%g7] ASI_DTLB_DATA_ACCESS /* TTE into TLB DATA */ membar #Sync stxa %g3, [%l7] ASI_IMMU /* KERNBASE into TLB TAG */ stxa %g5, [%g7] ASI_ITLB_DATA_ACCESS /* TTE into TLB DATA */ membar #Sync flush %g3 membar #Sync sethi %hi(_end), %g3 /* Check for bigkernel case */ or %g3, %lo(_end), %g3 srl %g3, 23, %g3 /* Check if _end > 8M */ brz,pt %g3, 2f sethi %hi(KERNBASE), %g3 /* Restore for fixup code below */ sethi %hi(0x400000), %g3 or %g3, %lo(0x400000), %g3 add %g5, %g3, %g5 /* New tte data */ andn %g5, (_PAGE_G), %g5 sethi %hi(KERNBASE+0x400000), %g3 or %g3, %lo(KERNBASE+0x400000), %g3 mov (62 << 3), %g7 stxa %g3, [%l7] ASI_DMMU stxa %g5, [%g7] ASI_DTLB_DATA_ACCESS membar #Sync stxa %g3, [%l7] ASI_IMMU stxa %g5, [%g7] ASI_ITLB_DATA_ACCESS membar #Sync flush %g3 membar #Sync sethi %hi(KERNBASE), %g3 /* Restore for fixup code below */2: ba,pt %xcc, 1f nop1: set sun4u_init, %g2 jmpl %g2 + %g0, %g0 nopsun4u_init: /* Set ctx 0 */ mov PRIMARY_CONTEXT, %g7 stxa %g0, [%g7] ASI_DMMU membar #Sync mov SECONDARY_CONTEXT, %g7 stxa %g0, [%g7] ASI_DMMU membar #Sync sethi %uhi(PAGE_OFFSET), %g4 sllx %g4, 32, %g4 /* We are now safely (we hope) in Nucleus context (0), rewrite * the KERNBASE TTE's so they no longer have the global bit set. * Don't forget to setup TAG_ACCESS first 8-) */ mov TLB_TAG_ACCESS, %g2 stxa %g3, [%g2] ASI_IMMU stxa %g3, [%g2] ASI_DMMU membar #Sync rdpr %ver, %g1 sethi %hi(0x003e0014), %g5 srlx %g1, 32, %g1 or %g5, %lo(0x003e0014), %g5 cmp %g1, %g5 bne,pt %icc, spitfire_tlb_fixup nopcheetah_tlb_fixup: set (0 << 16) | (15 << 3), %g7 ldxa [%g7] ASI_ITLB_DATA_ACCESS, %g1 andn %g1, (_PAGE_G), %g1 stxa %g1, [%g7] ASI_ITLB_DATA_ACCESS membar #Sync ldxa [%g7] ASI_DTLB_DATA_ACCESS, %g1 andn %g1, (_PAGE_G), %g1 stxa %g1, [%g7] ASI_DTLB_DATA_ACCESS membar #Sync /* Kill instruction prefetch queues. */ flush %g3 membar #Sync /* Set TLB type to cheetah. */ mov 1, %g2 sethi %hi(tlb_type), %g5 stw %g2, [%g5 + %lo(tlb_type)] /* Patch copy/page operations to cheetah optimized versions. */ call cheetah_patch_copyops nop call cheetah_patch_pgcopyops nop ba,pt %xcc, tlb_fixup_done nopspitfire_tlb_fixup: mov (63 << 3), %g7 ldxa [%g7] ASI_ITLB_DATA_ACCESS, %g1 andn %g1, (_PAGE_G), %g1 stxa %g1, [%g7] ASI_ITLB_DATA_ACCESS membar #Sync ldxa [%g7] ASI_DTLB_DATA_ACCESS, %g1 andn %g1, (_PAGE_G), %g1 stxa %g1, [%g7] ASI_DTLB_DATA_ACCESS membar #Sync /* Kill instruction prefetch queues. */ flush %g3 membar #Sync /* Set TLB type to spitfire. */ mov 0, %g2 sethi %hi(tlb_type), %g5 stw %g2, [%g5 + %lo(tlb_type)]tlb_fixup_done: sethi %hi(init_task_union), %g6 or %g6, %lo(init_task_union), %g6 mov %sp, %l6 mov %o4, %l7#if 0 /* We don't do it like this anymore, but for historical hack value * I leave this snippet here to show how crazy we can be sometimes. 8-) */ /* Setup "Linux Current Register", thanks Sun 8-) */ wr %g0, 0x1, %pcr /* Blackbird errata workaround. See commentary in * smp.c:smp_percpu_timer_interrupt() for more * information. */ ba,pt %xcc, 99f nop .align 6499: wr %g6, %g0, %pic rd %pic, %g0#endif wr %g0, ASI_P, %asi mov 1, %g5 sllx %g5, THREAD_SHIFT, %g5 sub %g5, (REGWIN_SZ + STACK_BIAS), %g5 add %g6, %g5, %sp mov 0, %fp wrpr %g0, 0, %wstate wrpr %g0, 0x0, %tl /* Clear the bss */ sethi %hi(__bss_start), %o0 or %o0, %lo(__bss_start), %o0 sethi %hi(_end), %o1 or %o1, %lo(_end), %o1 call __bzero sub %o1, %o0, %o1 mov %l6, %o1 ! OpenPROM stack call prom_init mov %l7, %o0 ! OpenPROM cif handler /* Off we go.... */ call start_kernel nop /* Not reached... *//* IMPORTANT NOTE: Whenever making changes here, check * trampoline.S as well. -jj */ .globl setup_tbasetup_tba: /* i0 = is_starfire */ save %sp, -160, %sp rdpr %tba, %g7 sethi %hi(prom_tba), %o1 or %o1, %lo(prom_tba), %o1 stx %g7, [%o1] /* Setup "Linux" globals 8-) */ rdpr %pstate, %o1 mov %g6, %o2 wrpr %o1, (PSTATE_AG|PSTATE_IE), %pstate sethi %hi(sparc64_ttable_tl0), %g5 wrpr %g5, %tba mov %o2, %g6 /* Set up MMU globals */ wrpr %o1, (PSTATE_MG|PSTATE_IE), %pstate /* Set fixed globals used by dTLB miss handler. */#define KERN_HIGHBITS ((_PAGE_VALID|_PAGE_SZ4MB)^0xfffff80000000000)#define KERN_LOWBITS (_PAGE_CP | _PAGE_CV | _PAGE_P | _PAGE_W)#define VPTE_BASE_SPITFIRE 0xfffffffe00000000#if 1#define VPTE_BASE_CHEETAH VPTE_BASE_SPITFIRE#else#define VPTE_BASE_CHEETAH 0xffe0000000000000#endif mov TSB_REG, %g1 stxa %g0, [%g1] ASI_DMMU membar #Sync mov TLB_SFSR, %g1 sethi %uhi(KERN_HIGHBITS), %g2 or %g2, %ulo(KERN_HIGHBITS), %g2 sllx %g2, 32, %g2 or %g2, KERN_LOWBITS, %g2 rdpr %ver, %g3 sethi %hi(0x003e0014), %g7 srlx %g3, 32, %g3 or %g7, %lo(0x003e0014), %g7 cmp %g3, %g7 bne,pt %icc, 1f nop sethi %uhi(VPTE_BASE_CHEETAH), %g3 or %g3, %ulo(VPTE_BASE_CHEETAH), %g3 ba,pt %xcc, 2f sllx %g3, 32, %g31: sethi %uhi(VPTE_BASE_SPITFIRE), %g3 or %g3, %ulo(VPTE_BASE_SPITFIRE), %g3 sllx %g3, 32, %g32: clr %g7#undef KERN_HIGHBITS#undef KERN_LOWBITS#undef VPTE_BASE_SPITFIRE#undef VPTE_BASE_CHEETAH /* Setup Interrupt globals */ wrpr %o1, (PSTATE_IG|PSTATE_IE), %pstate#ifndef CONFIG_SMP sethi %hi(__up_workvec), %g5 or %g5, %lo(__up_workvec), %g6#else /* By definition of where we are, this is boot_cpu. */ brz,pt %i0, not_starfire sethi %hi(0x1fff4000), %g1 or %g1, %lo(0x1fff4000), %g1 sllx %g1, 12, %g1 or %g1, 0xd0, %g1 lduwa [%g1] ASI_PHYS_BYPASS_EC_E, %g1 b,pt %xcc, set_worklist nopnot_starfire: rdpr %ver, %g1 sethi %hi(0x003e0014), %g5 srlx %g1, 32, %g1 or %g7, %lo(0x003e0014), %g5 cmp %g1, %g5 bne,pt %icc, not_cheetah nop ldxa [%g0] ASI_SAFARI_CONFIG, %g1 srlx %g1, 17, %g1 ba,pt %xcc, set_worklist and %g1, 0x3ff, %g1 ! 10bit Safari Agent IDnot_cheetah: ldxa [%g0] ASI_UPA_CONFIG, %g1 srlx %g1, 17, %g1 and %g1, 0x1f, %g1 /* In theory this is: &(cpu_data[boot_cpu_id].irq_worklists[0]) */set_worklist: sethi %hi(cpu_data), %g5 or %g5, %lo(cpu_data), %g5 sllx %g1, 7, %g1 add %g5, %g1, %g5 add %g5, 64, %g6#endif /* Kill PROM timer */ wr %g0, 0, %tick_cmpr rdpr %ver, %g1 sethi %hi(0x003e0014), %g5 srlx %g1, 32, %g1 or %g7, %lo(0x003e0014), %g5 cmp %g1, %g5 bne,pt %icc, 1f nop /* Disable STICK_INT interrupts. */ sethi %hi(0x80000000), %g1 sllx %g1, 32, %g1 wr %g1, %asr25 /* Ok, we're done setting up all the state our trap mechanims needs, * now get back into normal globals and let the PROM know what is up. */1: wrpr %g0, %g0, %wstate wrpr %o1, PSTATE_IE, %pstate sethi %hi(sparc64_ttable_tl0), %g5 call prom_set_trap_table mov %g5, %o0 rdpr %pstate, %o1 or %o1, PSTATE_IE, %o1 wrpr %o1, 0, %pstate ret restore/* * The following skips make sure the trap table in ttable.S is aligned * on a 32K boundary as required by the v9 specs for TBA register. */sparc64_boot_end: .skip 0x2000 + _start - sparc64_boot_endbootup_user_stack_end: .skip 0x2000#ifdef CONFIG_SBUS/* This is just a hack to fool make depend config.h discovering strategy: As the .S files below need config.h, but make depend does not find it for them, we include config.h in head.S */#endif! 0x0000000000408000#include "ttable.S"#include "systbls.S" .align 1024 .globl swapper_pg_dirswapper_pg_dir: .word 0#include "etrap.S"#include "rtrap.S"#include "winfixup.S"#include "entry.S" /* This is just anal retentiveness on my part... */ .align 16384 .data .align 8 .globl prom_tbaprom_tba: .xword 0 .section ".fixup",#alloc,#execinstr .globl __ret_efault__ret_efault: ret restore %g0, -EFAULT, %o0
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -