head.s
来自「LINUX 2.6.17.4的源码」· S 代码 · 共 698 行 · 第 1/2 页
S
698 行
/* $Id: head.S,v 1.87 2002/02/09 19:49:31 davem Exp $ * head.S: Initial boot code for the Sparc64 port of Linux. * * Copyright (C) 1996,1997 David S. Miller (davem@caip.rutgers.edu) * Copyright (C) 1996 David Sitsky (David.Sitsky@anu.edu.au) * Copyright (C) 1997,1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz) * Copyright (C) 1997 Miguel de Icaza (miguel@nuclecu.unam.mx) */#include <linux/config.h>#include <linux/version.h>#include <linux/errno.h>#include <linux/threads.h>#include <asm/thread_info.h>#include <asm/asi.h>#include <asm/pstate.h>#include <asm/ptrace.h>#include <asm/spitfire.h>#include <asm/page.h>#include <asm/pgtable.h>#include <asm/errno.h>#include <asm/signal.h>#include <asm/processor.h>#include <asm/lsu.h>#include <asm/dcr.h>#include <asm/dcu.h>#include <asm/head.h>#include <asm/ttable.h>#include <asm/mmu.h>#include <asm/cpudata.h> /* This section from from _start to sparc64_boot_end should fit into * 0x0000000000404000 to 0x0000000000408000. */ .text .globl start, _start, stext, _stext_start:start:_stext:stext:! 0x0000000000404000 b sparc64_boot flushw /* Flush register file. *//* 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. */ .global root_flags, ram_flags, root_dev .global sparc_ramdisk_image, sparc_ramdisk_size .global sparc_ramdisk_image64 .ascii "HdrS" .word LINUX_VERSION_CODE /* History: * * 0x0300 : Supports being located at other than 0x4000 * 0x0202 : Supports kernel params string * 0x0201 : Supports reboot_command */ .half 0x0301 /* HdrS version */root_flags: .half 1root_dev: .half 0ram_flags: .half 0sparc_ramdisk_image: .word 0sparc_ramdisk_size: .word 0 .xword reboot_command .xword bootstr_infosparc_ramdisk_image64: .xword 0 .word _end /* PROM cif handler code address is in %o4. */sparc64_boot:1: rd %pc, %g7 set 1b, %g1 cmp %g1, %g7 be,pn %xcc, sparc64_boot_after_remap mov %o4, %l7 /* We need to remap the kernel. Use position independant * code to remap us to KERNBASE. * * SILO can invoke us with 32-bit address masking enabled, * so make sure that's clear. */ rdpr %pstate, %g1 andn %g1, PSTATE_AM, %g1 wrpr %g1, 0x0, %pstate ba,a,pt %xcc, 1f .globl prom_finddev_name, prom_chosen_path, prom_root_node .globl prom_getprop_name, prom_mmu_name, prom_peer_name .globl prom_callmethod_name, prom_translate_name, prom_root_compatible .globl prom_map_name, prom_unmap_name, prom_mmu_ihandle_cache .globl prom_boot_mapped_pc, prom_boot_mapping_mode .globl prom_boot_mapping_phys_high, prom_boot_mapping_phys_low .globl is_sun4vprom_peer_name: .asciz "peer"prom_compatible_name: .asciz "compatible"prom_finddev_name: .asciz "finddevice"prom_chosen_path: .asciz "/chosen"prom_getprop_name: .asciz "getprop"prom_mmu_name: .asciz "mmu"prom_callmethod_name: .asciz "call-method"prom_translate_name: .asciz "translate"prom_map_name: .asciz "map"prom_unmap_name: .asciz "unmap"prom_sun4v_name: .asciz "sun4v" .align 4prom_root_compatible: .skip 64prom_root_node: .word 0prom_mmu_ihandle_cache: .word 0prom_boot_mapped_pc: .word 0prom_boot_mapping_mode: .word 0 .align 8prom_boot_mapping_phys_high: .xword 0prom_boot_mapping_phys_low: .xword 0is_sun4v: .word 01: rd %pc, %l0 mov (1b - prom_peer_name), %l1 sub %l0, %l1, %l1 mov 0, %l2 /* prom_root_node = prom_peer(0) */ stx %l1, [%sp + 2047 + 128 + 0x00] ! service, "peer" mov 1, %l3 stx %l3, [%sp + 2047 + 128 + 0x08] ! num_args, 1 stx %l3, [%sp + 2047 + 128 + 0x10] ! num_rets, 1 stx %l2, [%sp + 2047 + 128 + 0x18] ! arg1, 0 stx %g0, [%sp + 2047 + 128 + 0x20] ! ret1 call %l7 add %sp, (2047 + 128), %o0 ! argument array ldx [%sp + 2047 + 128 + 0x20], %l4 ! prom root node mov (1b - prom_root_node), %l1 sub %l0, %l1, %l1 stw %l4, [%l1] mov (1b - prom_getprop_name), %l1 mov (1b - prom_compatible_name), %l2 mov (1b - prom_root_compatible), %l5 sub %l0, %l1, %l1 sub %l0, %l2, %l2 sub %l0, %l5, %l5 /* prom_getproperty(prom_root_node, "compatible", * &prom_root_compatible, 64) */ stx %l1, [%sp + 2047 + 128 + 0x00] ! service, "getprop" mov 4, %l3 stx %l3, [%sp + 2047 + 128 + 0x08] ! num_args, 4 mov 1, %l3 stx %l3, [%sp + 2047 + 128 + 0x10] ! num_rets, 1 stx %l4, [%sp + 2047 + 128 + 0x18] ! arg1, prom_root_node stx %l2, [%sp + 2047 + 128 + 0x20] ! arg2, "compatible" stx %l5, [%sp + 2047 + 128 + 0x28] ! arg3, &prom_root_compatible mov 64, %l3 stx %l3, [%sp + 2047 + 128 + 0x30] ! arg4, size stx %g0, [%sp + 2047 + 128 + 0x38] ! ret1 call %l7 add %sp, (2047 + 128), %o0 ! argument array mov (1b - prom_finddev_name), %l1 mov (1b - prom_chosen_path), %l2 mov (1b - prom_boot_mapped_pc), %l3 sub %l0, %l1, %l1 sub %l0, %l2, %l2 sub %l0, %l3, %l3 stw %l0, [%l3] sub %sp, (192 + 128), %sp /* chosen_node = prom_finddevice("/chosen") */ stx %l1, [%sp + 2047 + 128 + 0x00] ! service, "finddevice" mov 1, %l3 stx %l3, [%sp + 2047 + 128 + 0x08] ! num_args, 1 stx %l3, [%sp + 2047 + 128 + 0x10] ! num_rets, 1 stx %l2, [%sp + 2047 + 128 + 0x18] ! arg1, "/chosen" stx %g0, [%sp + 2047 + 128 + 0x20] ! ret1 call %l7 add %sp, (2047 + 128), %o0 ! argument array ldx [%sp + 2047 + 128 + 0x20], %l4 ! chosen device node mov (1b - prom_getprop_name), %l1 mov (1b - prom_mmu_name), %l2 mov (1b - prom_mmu_ihandle_cache), %l5 sub %l0, %l1, %l1 sub %l0, %l2, %l2 sub %l0, %l5, %l5 /* prom_mmu_ihandle_cache = prom_getint(chosen_node, "mmu") */ stx %l1, [%sp + 2047 + 128 + 0x00] ! service, "getprop" mov 4, %l3 stx %l3, [%sp + 2047 + 128 + 0x08] ! num_args, 4 mov 1, %l3 stx %l3, [%sp + 2047 + 128 + 0x10] ! num_rets, 1 stx %l4, [%sp + 2047 + 128 + 0x18] ! arg1, chosen_node stx %l2, [%sp + 2047 + 128 + 0x20] ! arg2, "mmu" stx %l5, [%sp + 2047 + 128 + 0x28] ! arg3, &prom_mmu_ihandle_cache mov 4, %l3 stx %l3, [%sp + 2047 + 128 + 0x30] ! arg4, sizeof(arg3) stx %g0, [%sp + 2047 + 128 + 0x38] ! ret1 call %l7 add %sp, (2047 + 128), %o0 ! argument array mov (1b - prom_callmethod_name), %l1 mov (1b - prom_translate_name), %l2 sub %l0, %l1, %l1 sub %l0, %l2, %l2 lduw [%l5], %l5 ! prom_mmu_ihandle_cache stx %l1, [%sp + 2047 + 128 + 0x00] ! service, "call-method" mov 3, %l3 stx %l3, [%sp + 2047 + 128 + 0x08] ! num_args, 3 mov 5, %l3 stx %l3, [%sp + 2047 + 128 + 0x10] ! num_rets, 5 stx %l2, [%sp + 2047 + 128 + 0x18] ! arg1: "translate" stx %l5, [%sp + 2047 + 128 + 0x20] ! arg2: prom_mmu_ihandle_cache /* PAGE align */ srlx %l0, 13, %l3 sllx %l3, 13, %l3 stx %l3, [%sp + 2047 + 128 + 0x28] ! arg3: vaddr, our PC stx %g0, [%sp + 2047 + 128 + 0x30] ! res1 stx %g0, [%sp + 2047 + 128 + 0x38] ! res2 stx %g0, [%sp + 2047 + 128 + 0x40] ! res3 stx %g0, [%sp + 2047 + 128 + 0x48] ! res4 stx %g0, [%sp + 2047 + 128 + 0x50] ! res5 call %l7 add %sp, (2047 + 128), %o0 ! argument array ldx [%sp + 2047 + 128 + 0x40], %l1 ! translation mode mov (1b - prom_boot_mapping_mode), %l4 sub %l0, %l4, %l4 stw %l1, [%l4] mov (1b - prom_boot_mapping_phys_high), %l4 sub %l0, %l4, %l4 ldx [%sp + 2047 + 128 + 0x48], %l2 ! physaddr high stx %l2, [%l4 + 0x0] ldx [%sp + 2047 + 128 + 0x50], %l3 ! physaddr low /* 4MB align */ srlx %l3, 22, %l3 sllx %l3, 22, %l3 stx %l3, [%l4 + 0x8] /* Leave service as-is, "call-method" */ mov 7, %l3 stx %l3, [%sp + 2047 + 128 + 0x08] ! num_args, 7 mov 1, %l3 stx %l3, [%sp + 2047 + 128 + 0x10] ! num_rets, 1 mov (1b - prom_map_name), %l3 sub %l0, %l3, %l3 stx %l3, [%sp + 2047 + 128 + 0x18] ! arg1: "map" /* Leave arg2 as-is, prom_mmu_ihandle_cache */ mov -1, %l3 stx %l3, [%sp + 2047 + 128 + 0x28] ! arg3: mode (-1 default) sethi %hi(8 * 1024 * 1024), %l3 stx %l3, [%sp + 2047 + 128 + 0x30] ! arg4: size (8MB) sethi %hi(KERNBASE), %l3 stx %l3, [%sp + 2047 + 128 + 0x38] ! arg5: vaddr (KERNBASE) stx %g0, [%sp + 2047 + 128 + 0x40] ! arg6: empty mov (1b - prom_boot_mapping_phys_low), %l3 sub %l0, %l3, %l3 ldx [%l3], %l3 stx %l3, [%sp + 2047 + 128 + 0x48] ! arg7: phys addr call %l7 add %sp, (2047 + 128), %o0 ! argument array add %sp, (192 + 128), %spsparc64_boot_after_remap: sethi %hi(prom_root_compatible), %g1 or %g1, %lo(prom_root_compatible), %g1 sethi %hi(prom_sun4v_name), %g7 or %g7, %lo(prom_sun4v_name), %g7 mov 5, %g31: ldub [%g7], %g2 ldub [%g1], %g4 cmp %g2, %g4 bne,pn %icc, 2f add %g7, 1, %g7 subcc %g3, 1, %g3 bne,pt %xcc, 1b add %g1, 1, %g1 sethi %hi(is_sun4v), %g1 or %g1, %lo(is_sun4v), %g1 mov 1, %g7 stw %g7, [%g1]2: BRANCH_IF_SUN4V(g1, jump_to_sun4u_init) BRANCH_IF_CHEETAH_BASE(g1,g7,cheetah_boot) BRANCH_IF_CHEETAH_PLUS_OR_FOLLOWON(g1,g7,cheetah_plus_boot) ba,pt %xcc, spitfire_boot nopcheetah_plus_boot: /* Preserve OBP chosen DCU and DCR register settings. */ ba,pt %xcc, cheetah_generic_boot nopcheetah_boot: mov DCR_BPE | DCR_RPE | DCR_SI | DCR_IFPOE | DCR_MS, %g1 wr %g1, %asr18 sethi %uhi(DCU_ME|DCU_RE|DCU_HPE|DCU_SPE|DCU_SL|DCU_WE), %g7 or %g7, %ulo(DCU_ME|DCU_RE|DCU_HPE|DCU_SPE|DCU_SL|DCU_WE), %g7 sllx %g7, 32, %g7 or %g7, DCU_DM | DCU_IM | DCU_DC | DCU_IC, %g7 stxa %g7, [%g0] ASI_DCU_CONTROL_REG membar #Synccheetah_generic_boot: mov TSB_EXTENSION_P, %g3 stxa %g0, [%g3] ASI_DMMU stxa %g0, [%g3] ASI_IMMU membar #Sync mov TSB_EXTENSION_S, %g3 stxa %g0, [%g3] ASI_DMMU
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?