📄 head_32.s
字号:
lwz r15,0(r14) /* instruction, now insert top */ rlwimi r15,r11,16,16,31 /* half of pv const in low half*/ stw r15,0(r14) /* of instruction and restore. */ dcbst r0,r14 /* write it to memory */ sync icbi r0,r14 /* flush the icache line */ cmpw r12,r13 bne 1b sync /* additional sync needed on g4 */ isync /* No speculative loading until now */ blr/*********************************************************************** * Please note that on APUS the exception handlers are located at the * physical address 0xfff0000. For this reason, the exception handlers * cannot use relative branches to access the code below. ***********************************************************************/#endif /* CONFIG_APUS */#ifdef CONFIG_SMP#ifdef CONFIG_GEMINI .globl __secondary_start_gemini__secondary_start_gemini: mfspr r4,SPRN_HID0 ori r4,r4,HID0_ICFI li r3,0 ori r3,r3,HID0_ICE andc r4,r4,r3 mtspr SPRN_HID0,r4 sync b __secondary_start#endif /* CONFIG_GEMINI */ .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: /* on powersurge, we come in here with IR=0 and DR=1, and DBAT 0 set to map the 0xf0000000 - 0xffffffff region */ mfmsr r0 rlwinm r0,r0,0,28,26 /* clear DR (0x10) */ SYNC mtmsr r0 isync .globl __secondary_start__secondary_start: /* Copy some CPU settings from CPU 0 */ bl __restore_cpu_setup lis r3,-KERNELBASE@h mr r4,r24 bl call_setup_cpu /* Call setup_cpu for this CPU */#ifdef CONFIG_6xx lis r3,-KERNELBASE@h bl init_idle_6xx#endif /* CONFIG_6xx */ /* get current_thread_info and current */ lis r1,secondary_ti@ha tophys(r1,r1) lwz r1,secondary_ti@l(r1) tophys(r2,r1) lwz r2,TI_TASK(r2) /* stack */ addi r1,r1,THREAD_SIZE-STACK_FRAME_OVERHEAD li r0,0 tophys(r3,r1) stw r0,0(r3) /* load up the MMU */ bl load_up_mmu /* ptr to phys current thread */ tophys(r4,r2) addi r4,r4,THREAD /* phys address of our thread_struct */ CLR_TOP32(r4) mtspr SPRN_SPRG3,r4 li r3,0 mtspr SPRN_SPRG2,r3 /* 0 => not in RTAS */ /* enable MMU and jump to start_secondary */ li r4,MSR_KERNEL FIX_SRR1(r4,r5) lis r3,start_secondary@h ori r3,r3,start_secondary@l mtspr SPRN_SRR0,r3 mtspr SPRN_SRR1,r4 SYNC RFI#endif /* CONFIG_SMP *//* * Those generic dummy functions are kept for CPUs not * included in CONFIG_6xx */#if !defined(CONFIG_6xx)_GLOBAL(__save_cpu_setup) blr_GLOBAL(__restore_cpu_setup) blr#endif /* !defined(CONFIG_6xx) *//* * Load stuff into the MMU. Intended to be called with * IR=0 and DR=0. */load_up_mmu: sync /* Force all PTE updates to finish */ isync tlbia /* Clear all TLB entries */ sync /* wait for tlbia/tlbie to finish */ TLBSYNC /* ... on all CPUs */ /* Load the SDR1 register (hash table base & size) */ lis r6,_SDR1@ha tophys(r6,r6) lwz r6,_SDR1@l(r6) mtspr SPRN_SDR1,r6 li r0,16 /* load up segment register values */ mtctr r0 /* for context 0 */ lis r3,0x2000 /* Ku = 1, VSID = 0 */ li r4,03: mtsrin r3,r4 addi r3,r3,0x111 /* increment VSID */ addis r4,r4,0x1000 /* address of next segment */ bdnz 3b/* Load the BAT registers with the values set up by MMU_init. MMU_init takes care of whether we're on a 601 or not. */ mfpvr r3 srwi r3,r3,16 cmpwi r3,1 lis r3,BATS@ha addi r3,r3,BATS@l tophys(r3,r3) LOAD_BAT(0,r3,r4,r5) LOAD_BAT(1,r3,r4,r5) LOAD_BAT(2,r3,r4,r5) LOAD_BAT(3,r3,r4,r5) blr/* * This is where the main kernel code starts. */start_here: /* ptr to current */ lis r2,init_task@h ori r2,r2,init_task@l /* Set up for using our exception vectors */ /* ptr to phys current thread */ tophys(r4,r2) addi r4,r4,THREAD /* init task's THREAD */ CLR_TOP32(r4) mtspr SPRN_SPRG3,r4 li r3,0 mtspr SPRN_SPRG2,r3 /* 0 => not in RTAS */ /* stack */ lis r1,init_thread_union@ha addi r1,r1,init_thread_union@l li r0,0 stwu r0,THREAD_SIZE-STACK_FRAME_OVERHEAD(r1)/* * Do early platform-specific initialization, * and set up the MMU. */ mr r3,r31 mr r4,r30 bl machine_init bl __save_cpu_setup bl MMU_init#ifdef CONFIG_APUS /* Copy exception code to exception vector base on APUS. */ lis r4,KERNELBASE@h#ifdef CONFIG_APUS_FAST_EXCEPT lis r3,0xfff0 /* Copy to 0xfff00000 */#else lis r3,0 /* Copy to 0x00000000 */#endif li r5,0x4000 /* # bytes of memory to copy */ li r6,0 bl copy_and_flush /* copy the first 0x4000 bytes */#endif /* CONFIG_APUS *//* * Go back to running unmapped so we can load up new values * for SDR1 (hash table pointer) and the segment registers * and change to using our exception vectors. */ lis r4,2f@h ori r4,r4,2f@l tophys(r4,r4) li r3,MSR_KERNEL & ~(MSR_IR|MSR_DR) FIX_SRR1(r3,r5) mtspr SPRN_SRR0,r4 mtspr SPRN_SRR1,r3 SYNC RFI/* Load up the kernel context */2: bl load_up_mmu#ifdef CONFIG_BDI_SWITCH /* Add helper information for the Abatron bdiGDB debugger. * We do this here because we know the mmu is disabled, and * will be enabled for real in just a few instructions. */ lis r5, abatron_pteptrs@h ori r5, r5, abatron_pteptrs@l stw r5, 0xf0(r0) /* This much match your Abatron config */ lis r6, swapper_pg_dir@h ori r6, r6, swapper_pg_dir@l tophys(r5, r5) stw r6, 0(r5)#endif /* CONFIG_BDI_SWITCH *//* Now turn on the MMU for real! */ li r4,MSR_KERNEL FIX_SRR1(r4,r5) lis r3,start_kernel@h ori r3,r3,start_kernel@l mtspr SPRN_SRR0,r3 mtspr SPRN_SRR1,r4 SYNC RFI/* * Set up the segment registers for a new context. */_GLOBAL(set_context) mulli r3,r3,897 /* multiply context by skew factor */ rlwinm r3,r3,4,8,27 /* VSID = (context & 0xfffff) << 4 */ addis r3,r3,0x6000 /* Set Ks, Ku bits */ li r0,NUM_USER_SEGMENTS mtctr r0#ifdef CONFIG_BDI_SWITCH /* Context switch the PTE pointer for the Abatron BDI2000. * The PGDIR is passed as second argument. */ lis r5, KERNELBASE@h lwz r5, 0xf0(r5) stw r4, 0x4(r5)#endif li r4,0 isync3: mtsrin r3,r4 addi r3,r3,0x111 /* next VSID */ rlwinm r3,r3,0,8,3 /* clear out any overflow from VSID field */ addis r4,r4,0x1000 /* address of next segment */ bdnz 3b sync isync blr/* * An undocumented "feature" of 604e requires that the v bit * be cleared before changing BAT values. * * Also, newer IBM firmware does not clear bat3 and 4 so * this makes sure it's done. * -- Cort */clear_bats: li r10,0 mfspr r9,SPRN_PVR rlwinm r9,r9,16,16,31 /* r9 = 1 for 601, 4 for 604 */ cmpwi r9, 1 beq 1f mtspr SPRN_DBAT0U,r10 mtspr SPRN_DBAT0L,r10 mtspr SPRN_DBAT1U,r10 mtspr SPRN_DBAT1L,r10 mtspr SPRN_DBAT2U,r10 mtspr SPRN_DBAT2L,r10 mtspr SPRN_DBAT3U,r10 mtspr SPRN_DBAT3L,r101: mtspr SPRN_IBAT0U,r10 mtspr SPRN_IBAT0L,r10 mtspr SPRN_IBAT1U,r10 mtspr SPRN_IBAT1L,r10 mtspr SPRN_IBAT2U,r10 mtspr SPRN_IBAT2L,r10 mtspr SPRN_IBAT3U,r10 mtspr SPRN_IBAT3L,r10BEGIN_FTR_SECTION /* Here's a tweak: at this point, CPU setup have * not been called yet, so HIGH_BAT_EN may not be * set in HID0 for the 745x processors. However, it * seems that doesn't affect our ability to actually * write to these SPRs. */ mtspr SPRN_DBAT4U,r10 mtspr SPRN_DBAT4L,r10 mtspr SPRN_DBAT5U,r10 mtspr SPRN_DBAT5L,r10 mtspr SPRN_DBAT6U,r10 mtspr SPRN_DBAT6L,r10 mtspr SPRN_DBAT7U,r10 mtspr SPRN_DBAT7L,r10 mtspr SPRN_IBAT4U,r10 mtspr SPRN_IBAT4L,r10 mtspr SPRN_IBAT5U,r10 mtspr SPRN_IBAT5L,r10 mtspr SPRN_IBAT6U,r10 mtspr SPRN_IBAT6L,r10 mtspr SPRN_IBAT7U,r10 mtspr SPRN_IBAT7L,r10END_FTR_SECTION_IFSET(CPU_FTR_HAS_HIGH_BATS) blrflush_tlbs: lis r10, 0x401: addic. r10, r10, -0x1000 tlbie r10 blt 1b sync blrmmu_off: addi r4, r3, __after_mmu_off - _start mfmsr r3 andi. r0,r3,MSR_DR|MSR_IR /* MMU enabled? */ beqlr andc r3,r3,r0 mtspr SPRN_SRR0,r4 mtspr SPRN_SRR1,r3 sync RFI/* * Use the first pair of BAT registers to map the 1st 16MB * of RAM to KERNELBASE. From this point on we can't safely * call OF any more. */initial_bats: lis r11,KERNELBASE@h mfspr r9,SPRN_PVR rlwinm r9,r9,16,16,31 /* r9 = 1 for 601, 4 for 604 */ cmpwi 0,r9,1 bne 4f ori r11,r11,4 /* set up BAT registers for 601 */ li r8,0x7f /* valid, block length = 8MB */ oris r9,r11,0x800000@h /* set up BAT reg for 2nd 8M */ oris r10,r8,0x800000@h /* set up BAT reg for 2nd 8M */ mtspr SPRN_IBAT0U,r11 /* N.B. 601 has valid bit in */ mtspr SPRN_IBAT0L,r8 /* lower BAT register */ mtspr SPRN_IBAT1U,r9 mtspr SPRN_IBAT1L,r10 isync blr4: tophys(r8,r11)#ifdef CONFIG_SMP ori r8,r8,0x12 /* R/W access, M=1 */#else ori r8,r8,2 /* R/W access */#endif /* CONFIG_SMP */#ifdef CONFIG_APUS ori r11,r11,BL_8M<<2|0x2 /* set up 8MB BAT registers for 604 */#else ori r11,r11,BL_256M<<2|0x2 /* set up BAT registers for 604 */#endif /* CONFIG_APUS */ mtspr SPRN_DBAT0L,r8 /* N.B. 6xx (not 601) have valid */ mtspr SPRN_DBAT0U,r11 /* bit in upper BAT register */ mtspr SPRN_IBAT0L,r8 mtspr SPRN_IBAT0U,r11 isync blr#ifdef CONFIG_8260/* Jump into the system reset for the rom. * We first disable the MMU, and then jump to the ROM reset address. * * r3 is the board info structure, r4 is the location for starting. * I use this for building a small kernel that can load other kernels, * rather than trying to write or rely on a rom monitor that can tftp load. */ .globl m8260_goromm8260_gorom: mfmsr r0 rlwinm r0,r0,0,17,15 /* clear MSR_EE in r0 */ sync mtmsr r0 sync mfspr r11, SPRN_HID0 lis r10, 0 ori r10,r10,HID0_ICE|HID0_DCE andc r11, r11, r10 mtspr SPRN_HID0, r11 isync li r5, MSR_ME|MSR_RI lis r6,2f@h addis r6,r6,-KERNELBASE@h ori r6,r6,2f@l mtspr SPRN_SRR0,r6 mtspr SPRN_SRR1,r5 isync sync rfi2: mtlr 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 .globl sdatasdata: .globl empty_zero_pageempty_zero_page: .space 4096 .globl swapper_pg_dirswapper_pg_dir: .space 4096/* * 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 .globl intercept_tableintercept_table: .long 0, 0, i0x200, i0x300, i0x400, 0, i0x600, i0x700 .long i0x800, 0, 0, 0, 0, i0xd00, 0, 0 .long 0, 0, 0, i0x1300, 0, 0, 0, 0 .long 0, 0, 0, 0, 0, 0, 0, 0 .long 0, 0, 0, 0, 0, 0, 0, 0 .long 0, 0, 0, 0, 0, 0, 0, 0/* Room for two PTE pointers, usually the kernel and current user pointers * to their respective root page table. */abatron_pteptrs: .space 8
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -