📄 head_64.s
字号:
bl .__mmu_off b .__after_prom_start_STATIC(__boot_from_prom) /* Save parameters */ mr r31,r3 mr r30,r4 mr r29,r5 mr r28,r6 mr r27,r7 /* Make sure we are running in 64 bits mode */ bl .enable_64b_mode /* put a relocation offset into r3 */ bl .reloc_offset LOADADDR(r2,__toc_start) addi r2,r2,0x4000 addi r2,r2,0x4000 /* Relocate the TOC from a virt addr to a real addr */ add r2,r2,r3 /* Restore parameters */ mr r3,r31 mr r4,r30 mr r5,r29 mr r6,r28 mr r7,r27 /* Do all of the interaction with OF client interface */ bl .prom_init /* We never return */ trap/* * At this point, r3 contains the physical address we are running at, * returned by prom_init() */_STATIC(__after_prom_start)/* * We need to run with __start at physical address 0. * This will leave some code in the first 256B of * real memory, which are reserved for software use. * The remainder of the first page is loaded with the fixed * interrupt vectors. The next two pages are filled with * unknown exception placeholders. * * Note: This process overwrites the OF exception vectors. * r26 == relocation offset * r27 == KERNELBASE */ bl .reloc_offset mr r26,r3 SET_REG_TO_CONST(r27,KERNELBASE) li r3,0 /* target addr */ // XXX FIXME: Use phys returned by OF (r30) add r4,r27,r26 /* source addr */ /* current address of _start */ /* i.e. where we are running */ /* the source addr */ LOADADDR(r5,copy_to_here) /* # bytes of memory to copy */ sub r5,r5,r27 li r6,0x100 /* Start offset, the first 0x100 */ /* bytes were copied earlier. */ bl .copy_and_flush /* copy the first n bytes */ /* this includes the code being */ /* executed here. */ LOADADDR(r0, 4f) /* Jump to the copy of this code */ mtctr r0 /* that we just made/relocated */ bctr4: LOADADDR(r5,klimit) add r5,r5,r26 ld r5,0(r5) /* get the value of klimit */ sub r5,r5,r27 bl .copy_and_flush /* copy the rest */ b .start_here_multiplatform#endif /* CONFIG_PPC_MULTIPLATFORM *//* * Copy routine used to copy the kernel to start at physical address 0 * and flush and invalidate the caches as needed. * r3 = dest addr, r4 = source addr, r5 = copy limit, r6 = start offset * on exit, r3, r4, r5 are unchanged, r6 is updated to be >= r5. * * Note: this routine *only* clobbers r0, r6 and lr */_GLOBAL(copy_and_flush) addi r5,r5,-8 addi r6,r6,-84: li r0,16 /* Use the least common */ /* denominator cache line */ /* size. This results in */ /* extra cache line flushes */ /* but operation is correct. */ /* Can't get cache line size */ /* from NACA as it is being */ /* moved too. */ mtctr r0 /* put # words/line in ctr */3: addi r6,r6,8 /* copy a cache line */ ldx r0,r6,r4 stdx r0,r6,r3 bdnz 3b dcbst r6,r3 /* write it to memory */ sync icbi r6,r3 /* flush the icache line */ cmpld 0,r6,r5 blt 4b sync addi r5,r5,8 addi r6,r6,8 blr.align 8copy_to_here:#ifdef CONFIG_SMP#ifdef CONFIG_PPC_PMAC/* * On PowerMac, secondary processors starts from the reset vector, which * is temporarily turned into a call to one of the functions below. */ .section ".text"; .align 2 ; .globl __secondary_start_pmac_0__secondary_start_pmac_0: /* NB the entries for cpus 0, 1, 2 must each occupy 8 bytes. */ li r24,0 b 1f li r24,1 b 1f li r24,2 b 1f li r24,31: _GLOBAL(pmac_secondary_start) /* turn on 64-bit mode */ bl .enable_64b_mode isync /* Copy some CPU settings from CPU 0 */ bl .__restore_cpu_setup /* pSeries do that early though I don't think we really need it */ mfmsr r3 ori r3,r3,MSR_RI mtmsrd r3 /* RI on */ /* Set up a paca value for this processor. */ LOADADDR(r4, paca) /* Get base vaddr of paca array */ mulli r13,r24,PACA_SIZE /* Calculate vaddr of right paca */ add r13,r13,r4 /* for this processor. */ mtspr SPRN_SPRG3,r13 /* Save vaddr of paca in SPRG3 */ /* Create a temp kernel stack for use before relocation is on. */ ld r1,PACAEMERGSP(r13) subi r1,r1,STACK_FRAME_OVERHEAD b .__secondary_start#endif /* CONFIG_PPC_PMAC *//* * This function is called after the master CPU has released the * secondary processors. The execution environment is relocation off. * The paca for this processor has the following fields initialized at * this point: * 1. Processor number * 2. Segment table pointer (virtual address) * On entry the following are set: * r1 = stack pointer. vaddr for iSeries, raddr (temp stack) for pSeries * r24 = cpu# (in Linux terms) * r13 = paca virtual address * SPRG3 = paca virtual address */_GLOBAL(__secondary_start) /* Set thread priority to MEDIUM */ HMT_MEDIUM /* Load TOC */ ld r2,PACATOC(r13) /* Do early setup for that CPU (stab, slb, hash table pointer) */ bl .early_setup_secondary /* Initialize the kernel stack. Just a repeat for iSeries. */ LOADADDR(r3,current_set) sldi r28,r24,3 /* get current_set[cpu#] */ ldx r1,r3,r28 addi r1,r1,THREAD_SIZE-STACK_FRAME_OVERHEAD std r1,PACAKSAVE(r13) /* Clear backchain so we get nice backtraces */ li r7,0 mtlr r7 /* enable MMU and jump to start_secondary */ LOADADDR(r3,.start_secondary_prolog) SET_REG_TO_CONST(r4, MSR_KERNEL)#ifdef DO_SOFT_DISABLE ori r4,r4,MSR_EE#endif mtspr SPRN_SRR0,r3 mtspr SPRN_SRR1,r4 rfid b . /* prevent speculative execution *//* * Running with relocation on at this point. All we want to do is * zero the stack back-chain pointer before going into C code. */_GLOBAL(start_secondary_prolog) li r3,0 std r3,0(r1) /* Zero the stack frame pointer */ bl .start_secondary b .#endif/* * This subroutine clobbers r11 and r12 */_GLOBAL(enable_64b_mode) mfmsr r11 /* grab the current MSR */ li r12,1 rldicr r12,r12,MSR_SF_LG,(63-MSR_SF_LG) or r11,r11,r12 li r12,1 rldicr r12,r12,MSR_ISF_LG,(63-MSR_ISF_LG) or r11,r11,r12 mtmsrd r11 isync blr#ifdef CONFIG_PPC_MULTIPLATFORM/* * This is where the main kernel code starts. */_STATIC(start_here_multiplatform) /* get a new offset, now that the kernel has moved. */ bl .reloc_offset mr r26,r3 /* Clear out the BSS. It may have been done in prom_init, * already but that's irrelevant since prom_init will soon * be detached from the kernel completely. Besides, we need * to clear it now for kexec-style entry. */ LOADADDR(r11,__bss_stop) LOADADDR(r8,__bss_start) sub r11,r11,r8 /* bss size */ addi r11,r11,7 /* round up to an even double word */ rldicl. r11,r11,61,3 /* shift right by 3 */ beq 4f addi r8,r8,-8 li r0,0 mtctr r11 /* zero this many doublewords */3: stdu r0,8(r8) bdnz 3b4: mfmsr r6 ori r6,r6,MSR_RI mtmsrd r6 /* RI on */#ifdef CONFIG_HMT /* Start up the second thread on cpu 0 */ mfspr r3,SPRN_PVR srwi r3,r3,16 cmpwi r3,0x34 /* Pulsar */ beq 90f cmpwi r3,0x36 /* Icestar */ beq 90f cmpwi r3,0x37 /* SStar */ beq 90f b 91f /* HMT not supported */90: li r3,0 bl .hmt_start_secondary91:#endif /* The following gets the stack and TOC set up with the regs */ /* pointing to the real addr of the kernel stack. This is */ /* all done to support the C function call below which sets */ /* up the htab. This is done because we have relocated the */ /* kernel but are still running in real mode. */ LOADADDR(r3,init_thread_union) add r3,r3,r26 /* set up a stack pointer (physical address) */ addi r1,r3,THREAD_SIZE li r0,0 stdu r0,-STACK_FRAME_OVERHEAD(r1) /* set up the TOC (physical address) */ LOADADDR(r2,__toc_start) addi r2,r2,0x4000 addi r2,r2,0x4000 add r2,r2,r26 LOADADDR(r3,cpu_specs) add r3,r3,r26 LOADADDR(r4,cur_cpu_spec) add r4,r4,r26 mr r5,r26 bl .identify_cpu /* Save some low level config HIDs of CPU0 to be copied to * other CPUs later on, or used for suspend/resume */ bl .__save_cpu_setup sync /* Setup a valid physical PACA pointer in SPRG3 for early_setup * note that boot_cpuid can always be 0 nowadays since there is * nowhere it can be initialized differently before we reach this * code */ LOADADDR(r27, boot_cpuid) add r27,r27,r26 lwz r27,0(r27) LOADADDR(r24, paca) /* Get base vaddr of paca array */ mulli r13,r27,PACA_SIZE /* Calculate vaddr of right paca */ add r13,r13,r24 /* for this processor. */ add r13,r13,r26 /* convert to physical addr */ mtspr SPRN_SPRG3,r13 /* PPPBBB: Temp... -Peter */ /* Do very early kernel initializations, including initial hash table, * stab and slb setup before we turn on relocation. */ /* Restore parameters passed from prom_init/kexec */ mr r3,r31 bl .early_setup LOADADDR(r3,.start_here_common) SET_REG_TO_CONST(r4, MSR_KERNEL) mtspr SPRN_SRR0,r3 mtspr SPRN_SRR1,r4 rfid b . /* prevent speculative execution */#endif /* CONFIG_PPC_MULTIPLATFORM */ /* This is where all platforms converge execution */_STATIC(start_here_common) /* relocation is on at this point */ /* The following code sets up the SP and TOC now that we are */ /* running with translation enabled. */ LOADADDR(r3,init_thread_union) /* set up the stack */ addi r1,r3,THREAD_SIZE li r0,0 stdu r0,-STACK_FRAME_OVERHEAD(r1) /* Apply the CPUs-specific fixups (nop out sections not relevant * to this CPU */ li r3,0 bl .do_cpu_ftr_fixups LOADADDR(r26, boot_cpuid) lwz r26,0(r26) LOADADDR(r24, paca) /* Get base vaddr of paca array */ mulli r13,r26,PACA_SIZE /* Calculate vaddr of right paca */ add r13,r13,r24 /* for this processor. */ mtspr SPRN_SPRG3,r13 /* ptr to current */ LOADADDR(r4,init_task) std r4,PACACURRENT(r13) /* Load the TOC */ ld r2,PACATOC(r13) std r1,PACAKSAVE(r13) bl .setup_system /* Load up the kernel context */5:#ifdef DO_SOFT_DISABLE li r5,0 stb r5,PACAPROCENABLED(r13) /* Soft Disabled */ mfmsr r5 ori r5,r5,MSR_EE /* Hard Enabled */ mtmsrd r5#endif bl .start_kernel_GLOBAL(hmt_init)#ifdef CONFIG_HMT LOADADDR(r5, hmt_thread_data) mfspr r7,SPRN_PVR srwi r7,r7,16 cmpwi r7,0x34 /* Pulsar */ beq 90f cmpwi r7,0x36 /* Icestar */ beq 91f cmpwi r7,0x37 /* SStar */ beq 91f b 101f90: mfspr r6,SPRN_PIR andi. r6,r6,0x1f b 92f91: mfspr r6,SPRN_PIR andi. r6,r6,0x3ff92: sldi r4,r24,3 stwx r6,r5,r4 bl .hmt_start_secondary b 101f__hmt_secondary_hold: LOADADDR(r5, hmt_thread_data) clrldi r5,r5,4 li r7,0 mfspr r6,SPRN_PIR mfspr r8,SPRN_PVR srwi r8,r8,16 cmpwi r8,0x34 bne 93f andi. r6,r6,0x1f b 103f93: andi. r6,r6,0x3f103: lwzx r8,r5,r7 cmpw r8,r6 beq 104f addi r7,r7,8 b 103b104: addi r7,r7,4 lwzx r9,r5,r7 mr r24,r9101:#endif mr r3,r24 b .pSeries_secondary_smp_init#ifdef CONFIG_HMT_GLOBAL(hmt_start_secondary) LOADADDR(r4,__hmt_secondary_hold) clrldi r4,r4,4 mtspr SPRN_NIADORM, r4 mfspr r4, SPRN_MSRDORM li r5, -65 and r4, r4, r5 mtspr SPRN_MSRDORM, r4 lis r4,0xffef ori r4,r4,0x7403 mtspr SPRN_TSC, r4 li r4,0x1f4 mtspr SPRN_TST, r4 mfspr r4, SPRN_HID0 ori r4, r4, 0x1 mtspr SPRN_HID0, r4 mfspr r4, SPRN_CTRLF oris r4, r4, 0x40 mtspr SPRN_CTRLT, r4 blr#endif/* * We put a few things here that have to be page-aligned. * This stuff goes at the beginning of the bss, which is page-aligned. */ .section ".bss" .align PAGE_SHIFT .globl empty_zero_pageempty_zero_page: .space PAGE_SIZE .globl swapper_pg_dirswapper_pg_dir: .space PAGE_SIZE/* * This space gets a copy of optional info passed to us by the bootstrap * Used to pass parameters into the kernel like root=/dev/sda1, etc. */ .globl cmd_linecmd_line: .space COMMAND_LINE_SIZE
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -