diff options
Diffstat (limited to 'arch/powerpc/kernel/head_64.S')
-rw-r--r-- | arch/powerpc/kernel/head_64.S | 44 |
1 files changed, 38 insertions, 6 deletions
diff --git a/arch/powerpc/kernel/head_64.S b/arch/powerpc/kernel/head_64.S index 116f086..9342e97 100644 --- a/arch/powerpc/kernel/head_64.S +++ b/arch/powerpc/kernel/head_64.S @@ -161,6 +161,21 @@ exception_marker: #include "exceptions-64s.S" #endif +#ifdef CONFIG_PPC_BOOK3E +_GLOBAL(fsl_secondary_thread_init) +BEGIN_FTR_SECTION + /* Enable branch prediction */ + lis r3,BUCSR_INIT@h + ori r3,r3,BUCSR_INIT@l + mtspr SPRN_BUCSR,r3 + isync + + mfspr r3, SPRN_PIR + rlwimi r3, r3, 30, 2, 30 + mtspr SPRN_PIR, r3 +END_FTR_SECTION_IFSET(CPU_FTR_SMT) +#endif + _GLOBAL(generic_secondary_thread_init) mr r24,r3 @@ -169,6 +184,7 @@ _GLOBAL(generic_secondary_thread_init) /* get a valid TOC pointer, wherever we're mapped at */ bl .relative_toc + tovirt(r2,r2) #ifdef CONFIG_PPC_BOOK3E /* Book3E initialization */ @@ -195,6 +211,7 @@ _GLOBAL(generic_secondary_smp_init) /* get a valid TOC pointer, wherever we're mapped at */ bl .relative_toc + tovirt(r2,r2) #ifdef CONFIG_PPC_BOOK3E /* Book3E initialization */ @@ -295,7 +312,7 @@ _STATIC(__mmu_off) * * r5 != NULL -> OF entry, we go to prom_init, "legacy" parameter content * in r3...r7 - * + * * r5 == NULL -> kexec style entry. r3 is a physical pointer to the * DT block, r4 is a physical pointer to the kernel itself * @@ -515,7 +532,7 @@ __secondary_start_pmac_0: b 1f li r24,3 1: - + _GLOBAL(pmac_secondary_start) /* turn on 64-bit mode */ bl .enable_64b_mode @@ -531,6 +548,7 @@ _GLOBAL(pmac_secondary_start) /* get TOC pointer (real address) */ bl .relative_toc + tovirt(r2,r2) /* Copy some CPU settings from CPU 0 */ bl .__restore_cpu_ppc970 @@ -620,7 +638,7 @@ __secondary_start: RFI b . /* prevent speculative execution */ -/* +/* * Running with relocation on at this point. All we want to do is * zero the stack back-chain pointer and get the TOC virtual address * before going into C code. @@ -665,6 +683,13 @@ _GLOBAL(enable_64b_mode) * This puts the TOC pointer into r2, offset by 0x8000 (as expected * by the toolchain). It computes the correct value for wherever we * are running at the moment, using position-independent code. + * + * Note: The compiler constructs pointers using offsets from the + * TOC in -mcmodel=medium mode. After we relocate to 0 but before + * the MMU is on we need our TOC to be a virtual address otherwise + * these pointers will be real addresses which may get stored and + * accessed later with the MMU on. We use tovirt() at the call + * sites to handle this. */ _GLOBAL(relative_toc) mflr r0 @@ -681,8 +706,9 @@ p_toc: .llong __toc_start + 0x8000 - 0b * This is where the main kernel code starts. */ _INIT_STATIC(start_here_multiplatform) - /* set up the TOC (real address) */ - bl .relative_toc + /* set up the TOC */ + bl .relative_toc + tovirt(r2,r2) /* Clear out the BSS. It may have been done in prom_init, * already but that's irrelevant since prom_init will soon @@ -748,7 +774,7 @@ _INIT_STATIC(start_here_multiplatform) mtspr SPRN_SRR1,r4 RFI b . /* prevent speculative execution */ - + /* This is where all platforms converge execution */ _INIT_GLOBAL(start_here_common) /* relocation is on at this point */ @@ -760,6 +786,12 @@ _INIT_GLOBAL(start_here_common) /* Do more system initializations in virtual mode */ bl .setup_system +#ifdef CONFIG_PPC_BOOK3E +BEGIN_FTR_SECTION + bl .fsl_enable_threads +END_FTR_SECTION_IFSET(CPU_FTR_SMT) +#endif + /* Mark interrupts soft and hard disabled (they might be enabled * in the PACA when doing hotplug) */ |