summaryrefslogtreecommitdiffstats
path: root/arch/powerpc/mm/fsl_booke_mmu.c
diff options
context:
space:
mode:
authorKevin Hao <haokexin@gmail.com>2013-12-24 15:12:06 +0800
committerScott Wood <scottwood@freescale.com>2014-01-09 17:52:16 -0600
commitdd189692d40948d6445bbaeb8cb9bf9d15f54dc6 (patch)
treea52bf15f5aaa9cecb53efe0cd2bdf3bcc9c463ef /arch/powerpc/mm/fsl_booke_mmu.c
parent1c49abec677c7ff495837dbaafad8e12f09c29fc (diff)
powerpc: enable the relocatable support for the fsl booke 32bit kernel
This is based on the codes in the head_44x.S. The difference is that the init tlb size we used is 64M. With this patch we can only load the kernel at address between memstart_addr ~ memstart_addr + 64M. We will fix this restriction in the following patches. Signed-off-by: Kevin Hao <haokexin@gmail.com> Signed-off-by: Scott Wood <scottwood@freescale.com>
Diffstat (limited to 'arch/powerpc/mm/fsl_booke_mmu.c')
-rw-r--r--arch/powerpc/mm/fsl_booke_mmu.c28
1 files changed, 28 insertions, 0 deletions
diff --git a/arch/powerpc/mm/fsl_booke_mmu.c b/arch/powerpc/mm/fsl_booke_mmu.c
index 07ba45b0f07..ce4a1163ddd 100644
--- a/arch/powerpc/mm/fsl_booke_mmu.c
+++ b/arch/powerpc/mm/fsl_booke_mmu.c
@@ -241,4 +241,32 @@ void setup_initial_memory_limit(phys_addr_t first_memblock_base,
/* 64M mapped initially according to head_fsl_booke.S */
memblock_set_current_limit(min_t(u64, limit, 0x04000000));
}
+
+#ifdef CONFIG_RELOCATABLE
+notrace void __init relocate_init(phys_addr_t start)
+{
+ unsigned long base = KERNELBASE;
+
+ /*
+ * Relocatable kernel support based on processing of dynamic
+ * relocation entries.
+ * Compute the virt_phys_offset :
+ * virt_phys_offset = stext.run - kernstart_addr
+ *
+ * stext.run = (KERNELBASE & ~0x3ffffff) + (kernstart_addr & 0x3ffffff)
+ * When we relocate, we have :
+ *
+ * (kernstart_addr & 0x3ffffff) = (stext.run & 0x3ffffff)
+ *
+ * hence:
+ * virt_phys_offset = (KERNELBASE & ~0x3ffffff) -
+ * (kernstart_addr & ~0x3ffffff)
+ *
+ */
+ kernstart_addr = start;
+ start &= ~0x3ffffff;
+ base &= ~0x3ffffff;
+ virt_phys_offset = base - start;
+}
+#endif
#endif