📄 head.s
字号:
BAD_TRAP(0xd4) BAD_TRAP(0xd5) BAD_TRAP(0xd6) BAD_TRAP(0xd7) BAD_TRAP(0xd8) BAD_TRAP(0xd9) BAD_TRAP(0xda) BAD_TRAP(0xdb) BAD_TRAP(0xdc) BAD_TRAP(0xdd) BAD_TRAP(0xde) BAD_TRAP(0xdf) BAD_TRAP(0xe0) BAD_TRAP(0xe1) BAD_TRAP(0xe2) BAD_TRAP(0xe3) BAD_TRAP(0xe4) BAD_TRAP(0xe5) BAD_TRAP(0xe6) BAD_TRAP(0xe7) BAD_TRAP(0xe8) BAD_TRAP(0xe9) BAD_TRAP(0xea) BAD_TRAP(0xeb) BAD_TRAP(0xec) BAD_TRAP(0xed) BAD_TRAP(0xee) BAD_TRAP(0xef) BAD_TRAP(0xf0) BAD_TRAP(0xf1) BAD_TRAP(0xf2) BAD_TRAP(0xf3) BAD_TRAP(0xf4) BAD_TRAP(0xf5) BAD_TRAP(0xf6) BAD_TRAP(0xf7) BAD_TRAP(0xf8) BAD_TRAP(0xf9) BAD_TRAP(0xfa) BAD_TRAP(0xfb) BAD_TRAP(0xfc) BAD_TRAP(0xfd) BAD_TRAP(0xfe) BAD_TRAP(0xff)C_LABEL(trapbase_cpu3): BAD_TRAP(0x0) SRMMU_TFAULT TRAP_ENTRY(0x2, bad_instruction) TRAP_ENTRY(0x3, priv_instruction) TRAP_ENTRY(0x4, fpd_trap_handler) WINDOW_SPILL WINDOW_FILL TRAP_ENTRY(0x7, mna_handler) TRAP_ENTRY(0x8, fpe_trap_handler) SRMMU_DFAULT TRAP_ENTRY(0xa, do_tag_overflow) TRAP_ENTRY(0xb, do_watchpoint) BAD_TRAP(0xc) BAD_TRAP(0xd) BAD_TRAP(0xe) BAD_TRAP(0xf) BAD_TRAP(0x10) TRAP_ENTRY_INTERRUPT(1) TRAP_ENTRY_INTERRUPT(2) TRAP_ENTRY_INTERRUPT(3) TRAP_ENTRY_INTERRUPT(4) TRAP_ENTRY_INTERRUPT(5) TRAP_ENTRY_INTERRUPT(6) TRAP_ENTRY_INTERRUPT(7) TRAP_ENTRY_INTERRUPT(8) TRAP_ENTRY_INTERRUPT(9) TRAP_ENTRY_INTERRUPT(10) TRAP_ENTRY_INTERRUPT(11) TRAP_ENTRY_INTERRUPT(12) TRAP_ENTRY_INTERRUPT(13) TRAP_ENTRY_INTERRUPT(14) TRAP_ENTRY(0x1f, linux_trap_ipi15_sun4m) TRAP_ENTRY(0x20, do_reg_access) BAD_TRAP(0x21) BAD_TRAP(0x22) BAD_TRAP(0x23) TRAP_ENTRY(0x24, do_cp_disabled) SKIP_TRAP(0x25, unimp_flush) BAD_TRAP(0x26) BAD_TRAP(0x27) TRAP_ENTRY(0x28, do_cp_exception) SRMMU_DFAULT TRAP_ENTRY(0x2a, do_hw_divzero) BAD_TRAP(0x2b) BAD_TRAP(0x2c) BAD_TRAP(0x2d) BAD_TRAP(0x2e) BAD_TRAP(0x2f) BAD_TRAP(0x30) BAD_TRAP(0x31) BAD_TRAP(0x32) BAD_TRAP(0x33) BAD_TRAP(0x34) BAD_TRAP(0x35) BAD_TRAP(0x36) BAD_TRAP(0x37) BAD_TRAP(0x38) BAD_TRAP(0x39) BAD_TRAP(0x3a) BAD_TRAP(0x3b) BAD_TRAP(0x3c) BAD_TRAP(0x3d) BAD_TRAP(0x3e) BAD_TRAP(0x3f) BAD_TRAP(0x40) BAD_TRAP(0x41) BAD_TRAP(0x42) BAD_TRAP(0x43) BAD_TRAP(0x44) BAD_TRAP(0x45) BAD_TRAP(0x46) BAD_TRAP(0x47) BAD_TRAP(0x48) BAD_TRAP(0x49) BAD_TRAP(0x4a) BAD_TRAP(0x4b) BAD_TRAP(0x4c) BAD_TRAP(0x4d) BAD_TRAP(0x4e) BAD_TRAP(0x4f) BAD_TRAP(0x50) BAD_TRAP(0x51) BAD_TRAP(0x52) BAD_TRAP(0x53) BAD_TRAP(0x54) BAD_TRAP(0x55) BAD_TRAP(0x56) BAD_TRAP(0x57) BAD_TRAP(0x58) BAD_TRAP(0x59) BAD_TRAP(0x5a) BAD_TRAP(0x5b) BAD_TRAP(0x5c) BAD_TRAP(0x5d) BAD_TRAP(0x5e) BAD_TRAP(0x5f) BAD_TRAP(0x60) BAD_TRAP(0x61) BAD_TRAP(0x62) BAD_TRAP(0x63) BAD_TRAP(0x64) BAD_TRAP(0x65) BAD_TRAP(0x66) BAD_TRAP(0x67) BAD_TRAP(0x68) BAD_TRAP(0x69) BAD_TRAP(0x6a) BAD_TRAP(0x6b) BAD_TRAP(0x6c) BAD_TRAP(0x6d) BAD_TRAP(0x6e) BAD_TRAP(0x6f) BAD_TRAP(0x70) BAD_TRAP(0x71) BAD_TRAP(0x72) BAD_TRAP(0x73) BAD_TRAP(0x74) BAD_TRAP(0x75) BAD_TRAP(0x76) BAD_TRAP(0x77) BAD_TRAP(0x78) BAD_TRAP(0x79) BAD_TRAP(0x7a) BAD_TRAP(0x7b) BAD_TRAP(0x7c) BAD_TRAP(0x7d) BAD_TRAP(0x7e) BAD_TRAP(0x7f) SUNOS_SYSCALL_TRAP BREAKPOINT_TRAP TRAP_ENTRY(0x82, do_hw_divzero) TRAP_ENTRY(0x83, do_flush_windows) BAD_TRAP(0x84) BAD_TRAP(0x85) BAD_TRAP(0x86) BAD_TRAP(0x87) SOLARIS_SYSCALL_TRAP NETBSD_SYSCALL_TRAP BAD_TRAP(0x8a) BAD_TRAP(0x8b) BAD_TRAP(0x8c) BAD_TRAP(0x8d) BAD_TRAP(0x8e) BAD_TRAP(0x8f) LINUX_SYSCALL_TRAP BAD_TRAP(0x91) BAD_TRAP(0x92) BAD_TRAP(0x93) BAD_TRAP(0x94) BAD_TRAP(0x95) BAD_TRAP(0x96) BAD_TRAP(0x97) BAD_TRAP(0x98) BAD_TRAP(0x99) BAD_TRAP(0x9a) BAD_TRAP(0x9b) BAD_TRAP(0x9c) BAD_TRAP(0x9d) BAD_TRAP(0x9e) BAD_TRAP(0x9f) GETCC_TRAP SETCC_TRAP GETPSR_TRAP BAD_TRAP(0xa3) BAD_TRAP(0xa4) BAD_TRAP(0xa5) BAD_TRAP(0xa6) INDIRECT_SOLARIS_SYSCALL(156) BAD_TRAP(0xa8) BAD_TRAP(0xa9) BAD_TRAP(0xaa) BAD_TRAP(0xab) BAD_TRAP(0xac) BAD_TRAP(0xad) BAD_TRAP(0xae) BAD_TRAP(0xaf) BAD_TRAP(0xb0) BAD_TRAP(0xb1) BAD_TRAP(0xb2) BAD_TRAP(0xb3) BAD_TRAP(0xb4) BAD_TRAP(0xb5) BAD_TRAP(0xb6) BAD_TRAP(0xb7) BAD_TRAP(0xb8) BAD_TRAP(0xb9) BAD_TRAP(0xba) BAD_TRAP(0xbb) BAD_TRAP(0xbc) BAD_TRAP(0xbd) BAD_TRAP(0xbe) BAD_TRAP(0xbf) BAD_TRAP(0xc0) BAD_TRAP(0xc1) BAD_TRAP(0xc2) BAD_TRAP(0xc3) BAD_TRAP(0xc4) BAD_TRAP(0xc5) BAD_TRAP(0xc6) BAD_TRAP(0xc7) BAD_TRAP(0xc8) BAD_TRAP(0xc9) BAD_TRAP(0xca) BAD_TRAP(0xcb) BAD_TRAP(0xcc) BAD_TRAP(0xcd) BAD_TRAP(0xce) BAD_TRAP(0xcf) BAD_TRAP(0xd0) BAD_TRAP(0xd1) BAD_TRAP(0xd2) BAD_TRAP(0xd3) BAD_TRAP(0xd4) BAD_TRAP(0xd5) BAD_TRAP(0xd6) BAD_TRAP(0xd7) BAD_TRAP(0xd8) BAD_TRAP(0xd9) BAD_TRAP(0xda) BAD_TRAP(0xdb) BAD_TRAP(0xdc) BAD_TRAP(0xdd) BAD_TRAP(0xde) BAD_TRAP(0xdf) BAD_TRAP(0xe0) BAD_TRAP(0xe1) BAD_TRAP(0xe2) BAD_TRAP(0xe3) BAD_TRAP(0xe4) BAD_TRAP(0xe5) BAD_TRAP(0xe6) BAD_TRAP(0xe7) BAD_TRAP(0xe8) BAD_TRAP(0xe9) BAD_TRAP(0xea) BAD_TRAP(0xeb) BAD_TRAP(0xec) BAD_TRAP(0xed) BAD_TRAP(0xee) BAD_TRAP(0xef) BAD_TRAP(0xf0) BAD_TRAP(0xf1) BAD_TRAP(0xf2) BAD_TRAP(0xf3) BAD_TRAP(0xf4) BAD_TRAP(0xf5) BAD_TRAP(0xf6) BAD_TRAP(0xf7) BAD_TRAP(0xf8) BAD_TRAP(0xf9) BAD_TRAP(0xfa) BAD_TRAP(0xfb) BAD_TRAP(0xfc) BAD_TRAP(0xfd) BAD_TRAP(0xfe) BAD_TRAP(0xff)#endif .align PAGE_SIZE/* This was the only reasonable way I could think of to properly align * these page-table data structures. */ .globl C_LABEL(pg0), C_LABEL(pg1), C_LABEL(pg2), C_LABEL(pg3) .globl C_LABEL(empty_bad_page) .globl C_LABEL(empty_bad_page_table) .globl C_LABEL(empty_zero_page) .globl C_LABEL(swapper_pg_dir)C_LABEL(swapper_pg_dir): .skip PAGE_SIZEC_LABEL(pg0): .skip PAGE_SIZEC_LABEL(pg1): .skip PAGE_SIZEC_LABEL(pg2): .skip PAGE_SIZEC_LABEL(pg3): .skip PAGE_SIZEC_LABEL(empty_bad_page): .skip PAGE_SIZEC_LABEL(empty_bad_page_table): .skip PAGE_SIZEC_LABEL(empty_zero_page): .skip PAGE_SIZE .global C_LABEL(root_flags) .global C_LABEL(ram_flags) .global C_LABEL(root_dev) .global C_LABEL(sparc_ramdisk_image) .global C_LABEL(sparc_ramdisk_size)/* This stuff has to be in sync with SILO and other potential boot loaders * Fields should be kept upward compatible and whenever any change is made, * HdrS version should be incremented. */ .ascii "HdrS" .word LINUX_VERSION_CODE .half 0x0203 /* HdrS version */C_LABEL(root_flags): .half 1C_LABEL(root_dev): .half 0C_LABEL(ram_flags): .half 0C_LABEL(sparc_ramdisk_image): .word 0C_LABEL(sparc_ramdisk_size): .word 0 .word C_LABEL(reboot_command) .word 0, 0, 0 .word _end/* Cool, here we go. Pick up the romvec pointer in %o0 and stash it in * %g7 and at prom_vector_p. And also quickly check whether we are on * a v0, v2, or v3 prom. */gokernel: /* Ok, it's nice to know, as early as possible, if we * are already mapped where we expect to be in virtual * memory. The Solaris /boot elf format bootloader * will peek into our elf header and load us where * we want to be, otherwise we have to re-map. * * Some boot loaders don't place the jmp'rs address * in %o7, so we do a pc-relative call to a local * label, then see what %o7 has. */ mov %o7, %g4 ! Save %o7 /* Jump to it, and pray... */current_pc: call 1f nop1: mov %o7, %g3 tst %o0 be no_sun4u_here mov %g4, %o7 /* Previous %o7. */ mov %o0, %l0 ! stash away romvec mov %o0, %g7 ! put it here too mov %o1, %l1 ! stash away debug_vec too /* Ok, let's check out our run time program counter. */ set current_pc, %g5 cmp %g3, %g5 be already_mapped nop /* %l6 will hold the offset we have to subtract * from absolute symbols in order to access areas * in our own image. If already mapped this is * just plain zero, else it is KERNBASE. */ set KERNBASE, %l6 b copy_prom_lvl14 nopalready_mapped: mov 0, %l6 /* Copy over the Prom's level 14 clock handler. */copy_prom_lvl14:#if 1 /* DJHR * preserve our linked/calculated instructions */ set C_LABEL(lvl14_save), %g1 set t_irq14, %g3 sub %g1, %l6, %g1 ! translate to physical sub %g3, %l6, %g3 ! translate to physical ldd [%g3], %g4 std %g4, [%g1] ldd [%g3+8], %g4 std %g4, [%g1+8]#endif rd %tbr, %g1 andn %g1, 0xfff, %g1 ! proms trap table base or %g0, (0x1e<<4), %g2 ! offset to lvl14 intr or %g1, %g2, %g2 set t_irq14, %g3 sub %g3, %l6, %g3 ldd [%g2], %g4 std %g4, [%g3] ldd [%g2 + 0x8], %g4 std %g4, [%g3 + 0x8] ! Copy proms handler/* Must determine whether we are on a sun4c MMU, SRMMU, or SUN4/400 MUTANT * MMU so we can remap ourselves properly. DON'T TOUCH %l0 thru %l5 in these * remapping routines, we need their values afterwards! */ /* Now check whether we are already mapped, if we * are we can skip all this garbage coming up. */copy_prom_done: cmp %l6, 0 be go_to_highmem ! this will be a nop then nop set LOAD_ADDR, %g6 cmp %g7, %g6 bne remap_not_a_sun4 ! This is not a Sun4 nop or %g0, 0x1, %g1 lduba [%g1] ASI_CONTROL, %g1 ! Only safe to try on Sun4. subcc %g1, 0x24, %g0 ! Is this a mutant Sun4/400??? be sun4_mutant_remap ! Ugh, it is... nop b sun4_normal_remap ! regular sun4, 2 level mmu nopremap_not_a_sun4: lda [%g0] ASI_M_MMUREGS, %g1 ! same as ASI_PTE on sun4c and %g1, 0x1, %g1 ! Test SRMMU Enable bit ;-) cmp %g1, 0x0 be sun4c_remap ! A sun4c MMU or normal Sun4 nopsrmmu_remap: /* First, check for a viking (TI) module. */ set 0x40000000, %g2 rd %psr, %g3 and %g2, %g3, %g3 subcc %g3, 0x0, %g0 bz srmmu_nviking nop /* Figure out what kind of viking we are on. * We need to know if we have to play with the * AC bit and disable traps or not. */ /* I've only seen MicroSparc's on SparcClassics with this * bit set. */ set 0x800, %g2 lda [%g0] ASI_M_MMUREGS, %g3 ! peek in the control reg and %g2, %g3, %g3 subcc %g3, 0x0, %g0 bnz srmmu_nviking ! is in mbus mode nop rd %psr, %g3 ! DO NOT TOUCH %g3 andn %g3, PSR_ET, %g2 wr %g2, 0x0, %psr WRITE_PAUSE /* Get context table pointer, then convert to * a physical address, which is 36 bits. */ set AC_M_CTPR, %g4 lda [%g4] ASI_M_MMUREGS, %g4 sll %g4, 0x4, %g4 ! We use this below ! DO NOT TOUCH %g4 /* Set the AC bit in the Viking's MMU control reg. */ lda [%g0] ASI_M_MMUREGS, %g5 ! DO NOT TOUCH %g5 set 0x8000, %g6 ! AC bit mask or %g5, %g6, %g6 ! Or it in... sta %g6, [%g0] ASI_M_MMUREGS ! Close your eyes... /* Grrr, why does it seem like every other load/store * on the sun4m is in some ASI space... * Fine with me, let's get the pointer to the level 1 * page table directory and fetch its entry. */ lda [%g4] ASI_M_BYPASS, %o1 ! This is a level 1 ptr srl %o1, 0x4, %o1 ! Clear low 4 bits sll %o1, 0x8, %o1 ! Make physical /* Ok, pull in the PTD. */ lda [%o1] ASI_M_BYPASS, %o2 ! This is the 0x0 16MB pgd /* Calculate to KERNBASE entry. * * XXX Should not use empirical constant, but Gas gets an XXX * XXX upset stomach with the bitshift I would have to use XXX */ add %o1, 0x3c0, %o3 /* Poke the entry into the calculated address. */ sta %o2, [%o3] ASI_M_BYPASS /* I don't get it Sun, if you engineered all these * boot loaders and the PROM (thank you for the debugging * features btw) why did you not have them load kernel * images up in high address space, since this is necessary * for ABI compliance anyways? Does this low-mapping provide * enhanced interoperability? * * "The PROM is the computer." */ /* Ok, restore the MMU control register we saved in %g5 */ sta %g5, [%g0] ASI_M_MMUREGS ! POW... ouch /* Turn traps back on. We saved it in %g3 earlier. */ wr %g3, 0x0, %psr ! tick tock, tick tock /* Now we burn precious CPU cycles due to bad engineering. */ WRITE_PAUSE /* Wow, all that just to move a 32-bit value from one * place to another... Jump to high memory. */ b go_to_highmem nop /* This works on viking's in Mbus mode and all * other MBUS modules. It is virtually the same as * the above madness sans turning traps off and flipping * the AC bit. */srmmu_nviking: set AC_M_CTPR, %g1 lda [%g1] ASI_M_MMUREGS, %g1 ! get ctx table ptr sll %g1, 0x4, %g1 ! make physical addr
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -