This is based on the codes in the head_44x.S. Since we always align to 256M before mapping the PAGE_OFFSET for a relocatable kernel, we also change the init tlb map to 256M size.
Signed-off-by: Kevin Hao <haoke...@gmail.com> --- arch/powerpc/Kconfig | 2 +- arch/powerpc/kernel/fsl_booke_entry_mapping.S | 8 ++- arch/powerpc/kernel/head_fsl_booke.S | 92 +++++++++++++++++++++++++-- 3 files changed, 94 insertions(+), 8 deletions(-) diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index c33e3ad..9eb97ac 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig @@ -866,7 +866,7 @@ config DYNAMIC_MEMSTART config RELOCATABLE bool "Build a relocatable kernel" - depends on ADVANCED_OPTIONS && FLATMEM && 44x + depends on ADVANCED_OPTIONS && FLATMEM && (44x || FSL_BOOKE) select NONSTATIC_KERNEL help This builds a kernel image that is capable of running at the diff --git a/arch/powerpc/kernel/fsl_booke_entry_mapping.S b/arch/powerpc/kernel/fsl_booke_entry_mapping.S index a92c79b..32a4b38 100644 --- a/arch/powerpc/kernel/fsl_booke_entry_mapping.S +++ b/arch/powerpc/kernel/fsl_booke_entry_mapping.S @@ -165,10 +165,10 @@ skpinv: addi r6,r6,1 /* Increment */ lis r6,0x1000 /* Set MAS0(TLBSEL) = TLB1(1), ESEL = 0 */ mtspr SPRN_MAS0,r6 lis r6,(MAS1_VALID|MAS1_IPROT)@h - ori r6,r6,(MAS1_TSIZE(BOOK3E_PAGESZ_64M))@l + ori r6,r6,(MAS1_TSIZE(BOOK3E_PAGESZ_256M))@l mtspr SPRN_MAS1,r6 - lis r6,MAS2_VAL(PAGE_OFFSET, BOOK3E_PAGESZ_64M, M_IF_SMP)@h - ori r6,r6,MAS2_VAL(PAGE_OFFSET, BOOK3E_PAGESZ_64M, M_IF_SMP)@l + lis r6,MAS2_VAL(PAGE_OFFSET, BOOK3E_PAGESZ_256M, M_IF_SMP)@h + ori r6,r6,MAS2_VAL(PAGE_OFFSET, BOOK3E_PAGESZ_256M, M_IF_SMP)@l mtspr SPRN_MAS2,r6 mtspr SPRN_MAS3,r8 tlbwe @@ -176,6 +176,8 @@ skpinv: addi r6,r6,1 /* Increment */ /* 7. Jump to KERNELBASE mapping */ lis r6,(KERNELBASE & ~0xfff)@h ori r6,r6,(KERNELBASE & ~0xfff)@l + rlwinm r7,r25,0,4,31 + add r6,r7,r6 #elif defined(ENTRY_MAPPING_KEXEC_SETUP) /* diff --git a/arch/powerpc/kernel/head_fsl_booke.S b/arch/powerpc/kernel/head_fsl_booke.S index d10a7ca..c3b4c8e53 100644 --- a/arch/powerpc/kernel/head_fsl_booke.S +++ b/arch/powerpc/kernel/head_fsl_booke.S @@ -83,10 +83,43 @@ _ENTRY(_start); andc r31,r20,r18 /* r31 = page base */ or r31,r31,r19 /* r31 = devtree phys addr */ mfspr r30,SPRN_MAS7 - - li r25,0 /* phys kernel start (low) */ li r24,0 /* CPU number */ - li r23,0 /* phys kernel start (high) */ + +#ifdef CONFIG_RELOCATABLE + bl 0f /* Get our runtime address */ +0: mflr r3 /* Make it accessible */ + addis r3,r3,(_stext - 0b)@ha + addi r3,r3,(_stext - 0b)@l /* Get our current runtime base */ + + /* Translate _stext address to physical, save in r23/r25 */ + tlbsx 0,r3 /* must succeed */ + + mfspr r16,SPRN_MAS1 + mfspr r20,SPRN_MAS3 + rlwinm r17,r16,25,0x1f /* r17 = log2(page size) */ + li r18,1024 + slw r18,r18,r17 /* r18 = page size */ + addi r18,r18,-1 + and r19,r3,r18 /* r19 = page offset */ + andc r25,r20,r18 /* r25 = page base */ + or r25,r25,r19 /* r25 = _stext phys addr */ + mfspr r23,SPRN_MAS7 + + /* + * We have the runtime (virutal) address of our base. + * We calculate our shift of offset from a 256M page. + * We could map the 256M page we belong to at PAGE_OFFSET and + * get going from there. + */ + lis r4,KERNELBASE@h + ori r4,r4,KERNELBASE@l + rlwinm r6,r25,0,4,31 /* r6 = PHYS_START % 256M */ + rlwinm r5,r4,0,4,31 /* r5 = KERNELBASE % 256M */ + subf r3,r5,r6 /* r3 = r6 - r5 */ + add r3,r4,r3 /* Required Virutal Address */ + + bl relocate +#endif /* We try to not make any assumptions about how the boot loader * setup or used the TLBs. We invalidate all mappings from the @@ -197,7 +230,58 @@ _ENTRY(__early_start) bl early_init -#ifdef CONFIG_DYNAMIC_MEMSTART +#ifdef CONFIG_RELOCATABLE + /* + * Relocatable kernel support based on processing of dynamic + * relocation entries. + * + * r25/r23 will contain RPN/ERPN for the start address of memory + */ + lis r3,kernstart_addr@ha + la r3,kernstart_addr@l(r3) + +#ifdef CONFIG_PHYS_64BIT + stw r23,0(r3) + stw r25,4(r3) +#else + stw r25,0(r3) +#endif + + /* + * Compute the virt_phys_offset : + * virt_phys_offset = stext.run - kernstart_addr + * + * stext.run = (KERNELBASE & ~0xfffffff) + (kernstart_addr & 0xfffffff) + * When we relocate, we have : + * + * (kernstart_addr & 0xfffffff) = (stext.run & 0xfffffff) + * + * hence: + * virt_phys_offset = (KERNELBASE & ~0xfffffff) - + * (kernstart_addr & ~0xfffffff) + * + */ + + /* KERNELBASE&~0xfffffff => (r4,r5) */ + li r4, 0 /* higer 32bit */ + lis r5,KERNELBASE@h + rlwinm r5,r5,0,0,3 /* Align to 256M, lower 32bit */ + + rlwinm r7,r25,0,0,3 + /* + * 64bit subtraction. + */ + subfc r5,r7,r5 + subfe r4,r23,r4 + + /* Store virt_phys_offset */ + lis r3,virt_phys_offset@ha + la r3,virt_phys_offset@l(r3) + + stw r4,0(r3) + stw r5,4(r3) + +#elif defined(CONFIG_DYNAMIC_MEMSTART) lis r3,kernstart_addr@ha la r3,kernstart_addr@l(r3) #ifdef CONFIG_PHYS_64BIT -- 1.8.1.4 _______________________________________________ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev