📄 head.s
字号:
mtfsf 0xff,fr0 REST_32FPRS(0, r5)#ifndef CONFIG_SMP subi r4,r5,THREAD /* Back to 'current' */ std r4,last_task_used_math@l(r3)#endif /* CONFIG_SMP */ /* restore registers and return */ b fast_exception_return/* * FP unavailable trap from kernel - print a message, but let * the task use FP in the kernel until it returns to user mode. */_GLOBAL(KernelFP) ld r3,_MSR(r1) ori r3,r3,MSR_FP std r3,_MSR(r1) /* enable use of FP after return */ LOADADDR(r3,86f) mfspr r4,SPRG3 /* Get PACA */ ld r4,PACACURRENT(r4) /* current */ ld r5,_NIP(r1) b .ret_from_except86: .string "floating point used in kernel (task=%p, pc=%x)\n" .align 4/* * giveup_fpu(tsk) * Disable FP for the task given as the argument, * and save the floating-point registers in its thread_struct. * Enables the FPU for use in the kernel on return. */_GLOBAL(giveup_fpu) mfmsr r5 ori r5,r5,MSR_FP mtmsrd r5 /* enable use of fpu now */ isync cmpi 0,r3,0 beqlr- /* if no previous owner, done */ addi r3,r3,THREAD /* want THREAD of task */ ld r5,PT_REGS(r3) cmpi 0,r5,0 SAVE_32FPRS(0, r3) mffs fr0 stfd fr0,THREAD_FPSCR-4(r3) beq 1f ld r4,_MSR-STACK_FRAME_OVERHEAD(r5) li r3,MSR_FP|MSR_FE0|MSR_FE1 andc r4,r4,r3 /* disable FP for previous task */ std r4,_MSR-STACK_FRAME_OVERHEAD(r5)1:#ifndef CONFIG_SMP li r5,0 LOADBASE(r4,last_task_used_math) std r5,last_task_used_math@l(r4)#endif /* CONFIG_SMP */ blr#ifdef CONFIG_SMP/* * 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) * r25 = Paca virtual address * SPRG3 = Paca virtual address */_GLOBAL(__secondary_start) HMT_MEDIUM /* Set thread priority to MEDIUM */ /* set up the TOC (virtual address) */ LOADADDR(r2,__toc_start) addi r2,r2,0x4000 addi r2,r2,0x4000 std r2,PACATOC(r25) li r6,0 std r6,PACAKSAVE(r25) stb r6,PACAPROCENABLED(r25)#ifndef CONFIG_PPC_ISERIES /* Initialize the page table pointer register. */ LOADADDR(r6,_SDR1) ld r6,0(r6) /* get the value of _SDR1 */ mtspr SDR1,r6 /* set the htab location */#endif /* Initialize the first segment table (or SLB) entry */ ld r3,PACASTABVIRT(r25) /* get addr of segment table */ bl .stab_initialize /* load current into r13 */ ld r13,PACACURRENT(r25) /* 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 subi r1,r1,STACK_FRAME_OVERHEAD ld r3,PACASTABREAL(r25) /* get raddr of segment table */ ori r4,r3,1 /* turn on valid bit */#ifdef CONFIG_PPC_ISERIES li r0,-1 /* hypervisor call */ li r3,1 sldi r3,r3,63 /* 0x8000000000000000 */ ori r3,r3,4 /* 0x8000000000000004 */ sc /* HvCall_setASR */#else mtasr r4 /* set the stab location */#endif 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 SRR0,r3 mtspr SRR1,r4 rfid#endif /* CONFIG_SMP *//* * 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/* * This subroutine clobbers r11, r12 and the LR */_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/* * This subroutine clobbers r11, r12 and the LR */_GLOBAL(enable_32b_mode) mfmsr r11 /* grab the current MSR */ li r12,1 rldicr r12,r12,MSR_SF_LG,(63-MSR_SF_LG) andc r11,r11,r12 li r12,1 rldicr r12,r12,MSR_ISF_LG,(63-MSR_ISF_LG) andc r11,r11,r12 mtmsrd r11 isync blr/* * This is where the main kernel code starts. */_STATIC(start_here_pSeries) /* get a new offset, now that the kernel has moved. */ bl .reloc_offset mr r26,r3 /* setup the naca pointer which is needed by *tab_initialize */ LOADADDR(r6,naca) sub r6,r6,r26 /* addr of the variable naca */ li r27,0x4000 std r27,0(r6) /* set the value of naca */#ifdef CONFIG_HMT /* Start up the second thread on cpu 0 */ mfspr r3,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#ifdef CONFIG_SMP /* All secondary cpus are now spinning on a common * spinloop, release them all now so they can start * to spin on their individual Paca spinloops. * For non SMP kernels, the secondary cpus never * get out of the common spinloop. */ li r3,1 LOADADDR(r5,__secondary_hold_spinloop) tophys(r4,r5) std r3,0(r4)#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) sub 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 sub r2,r2,r26 /* Init naca->debug_switch so it can be used in stab & htab init. */ bl .ppcdbg_initialize /* Get the pointer to the segment table which is used by */ /* stab_initialize */ li r27,0x4000 ld r6,PACA(r27) /* Get the base Paca pointer */ sub r6,r6,r26 /* convert to physical addr */ mtspr SPRG3,r6 /* PPPBBB: Temp... -Peter */ ld r3,PACASTABREAL(r6) ori r4,r3,1 /* turn on valid bit */ mtasr r4 /* set the stab location */ /* Initialize an initial memory mapping and turn on relocation. */ bl .stab_initialize bl .htab_initialize LOADADDR(r6,_SDR1) sub r6,r6,r26 ld r6,0(r6) /* get the value of _SDR1 */ mtspr SDR1,r6 /* set the htab location */ LOADADDR(r3,.start_here_common) SET_REG_TO_CONST(r4, MSR_KERNEL) mtspr SRR0,r3 mtspr SRR1,r4 rfid /* This is where all platforms converge execution */_STATIC(start_here_common) /* relocation is on at this point */ /* Clear out the BSS */ LOADADDR(r11,_end) 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: /* 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) /* set up the TOC */ LOADADDR(r2,__toc_start) addi r2,r2,0x4000 addi r2,r2,0x4000 /* setup the naca pointer */ LOADADDR(r9,naca) SET_REG_TO_CONST(r8, KERNELBASE) addi r8,r8,0x4000 std r8,0(r9) /* set the value of the naca ptr */ LOADADDR(r4,naca) /* Get Naca ptr address */ ld r4,0(r4) /* Get the location of the naca */ ld r4,PACA(r4) /* Get the base Paca pointer */ mtspr SPRG3,r4 /* ptr to current */ LOADADDR(r13,init_task) std r13,PACACURRENT(r4) std r2,PACATOC(r4) li r5,0 std r0,PACAKSAVE(r4) /* ptr to hardware interrupt stack for processor 0 */ LOADADDR(r3, hardware_int_paca0) li r5,0x1000 sldi r5,r5,3 subi r5,r5,STACK_FRAME_OVERHEAD add r3,r3,r5 std r3,PACAHRDWINTSTACK(r4) li r3,0 stb r3,PACAHRDWINTCOUNT(r4) /* Restore the parms passed in from the bootloader. */ mr r3,r31 mr r4,r30 mr r5,r29 mr r6,r28 mr r7,r27 bl .setup_system /* Load up the kernel context */5:#ifdef DO_SOFT_DISABLE mfspr r4,SPRG3 li r5,0 stb r5,PACAPROCENABLED(r4) /* 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,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,PIR andi. r6,r6,0x1f b 92f91: mfspr r6,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,PIR mfspr r8,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 NIADORM, r4 mfspr r4, MSRDORM li r5, -65 and r4, r4, r5 mtspr MSRDORM, r4 lis r4,0xffef ori r4,r4,0x7403 mtspr TSC, r4 li r4,0x1f4 mtspr TST, r4 mfspr r4, HID0 ori r4, r4, 0x1 mtspr HID0, r4 mfspr r4, CTRLF oris r4, r4, 0x40 mtspr CTRLT, r4 blr#endif/* * We put a few things here that have to be page-aligned. * This stuff goes at the beginning of the data segment, * which is page-aligned. */ .data .align 12 .globl sdatasdata: .globl empty_zero_pageempty_zero_page: .space 4096 .globl swapper_pg_dirswapper_pg_dir: .space 4096 .globl ioremap_dirioremap_dir: .space 4096 .globl hardware_int_paca0hardware_int_paca0: .space 8*4096/* 1 page segment table per cpu (max 48, cpu0 allocated at 0x5000) */ .globl stab_arraystab_array: .space 4096 * 47 /* * 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 512
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -