[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <1617283633-18598-4-git-send-email-hejinyang@loongson.cn>
Date: Thu, 1 Apr 2021 21:27:13 +0800
From: Jinyang He <hejinyang@...ngson.cn>
To: Thomas Bogendoerfer <tsbogend@...ha.franken.de>,
Paul Burton <paulburton@...nel.org>
Cc: linux-mips@...r.kernel.org, linux-kernel@...r.kernel.org
Subject: [PATCH RFC 3/3] MIPS: relocate: Add support to relocate kernel auto
These asm code is based on relocate.c. And in this stage,
only do relocate for _text and ex_table.
Signed-off-by: Jinyang He <hejinyang@...ngson.cn>
---
arch/mips/kernel/head.S | 149 ++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 149 insertions(+)
diff --git a/arch/mips/kernel/head.S b/arch/mips/kernel/head.S
index a25af1d..dc59b11 100644
--- a/arch/mips/kernel/head.S
+++ b/arch/mips/kernel/head.S
@@ -13,6 +13,7 @@
* Kevin Kissell, kevink@...s.com and Carsten Langgaard, carstenl@...s.com
* Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved.
*/
+
#include <linux/init.h>
#include <linux/threads.h>
@@ -26,6 +27,152 @@
#include <kernel-entry-init.h>
+ .macro do_relocate_kernel
+ .set push
+#ifdef CONFIG_RELOCATABLE
+#define R_MIPS_32 2
+#define R_MIPS_26 4
+#define R_MIPS_HI16 5
+#define R_MIPS_64 18
+ /* Save args */
+ move s0, a0
+ move s1, a1
+ move s2, a2
+ move s3, a3
+
+ /* Whether the PC meets expectation */
+ bal 1f
+1: move a0, ra
+ PTR_LA a1, 1b
+ PTR_SUB a0, a0, a1
+ beqz a0, 999f
+
+ /* Whether offset 64KB aligned */
+ and t0, a0, 0xffff
+ bnez t0, 999f
+
+ /* Whether current _text and _end are in the PC region */
+ PTR_LA t0, _end
+ PTR_ADDU t1, t0, a0
+ PTR_SRL t1, 28
+ PTR_SRL t0, 28
+ bne t0, t1, 999f
+
+ PTR_LA t0, _text
+ PTR_ADDU t1, t0, a0
+ move a3, t1
+ PTR_SRL t1, 28
+ PTR_SRL t0, 28
+ bne t0, t1, 999f
+
+ /* get current __start/stop___ex_table address */
+ PTR_LA a1, __start___ex_table
+ PTR_ADDU a1, a0
+ PTR_LA a2, __stop___ex_table
+ PTR_ADDU a2, a0
+
+ /*
+ * a0: offset
+ * a1: current __start___ex_table
+ * a2: current __stop___ex_table
+ */
+1: beq a1, a2, 998f
+ PTR_L t0, 0(a1)
+ PTR_ADDU t0, a0
+ PTR_S t0, 0(a1)
+ LONG_ADDIU a1, PTRSIZE
+ b 1b
+
+998:
+ /* get current _relocation_start address */
+ PTR_LA a1, _relocation_start
+ PTR_ADDU a1, a0
+
+ /*
+ * a0: offset
+ * a1: _relocation_start[]
+ * a2: offset >> 16, to relocate R_MIPS_HI16
+ * a3: current _text
+ * t0: to load _relocation_start[]
+ * t1: relocation type
+ * t2: current relocate position
+ * t3: temporarily
+ * t8: 0x00ffffff, mask, to get relocate position
+ * t9: offset >> 2, to relocate R_MIPS_26
+ */
+ li t8, 0x00ffffff
+ LONG_SRL t9, a0, 2
+ LONG_SRL a2, a0, 16
+1: lw t0, 0(a1)
+ beqz t0, 900f
+ LONG_SRL t1, t0, 24
+ and t1, 0xff
+ and t2, t0, t8
+ LONG_SLL t2, 2
+ PTR_ADDU t2, a3
+
+ li t3, R_MIPS_64
+ beq t1, t3, 964f
+ li t3, R_MIPS_32
+ beq t1, t3, 932f
+ li t3, R_MIPS_26
+ beq t1, t3, 926f
+ li t3, R_MIPS_HI16
+ beq t1, t3, 916f
+ b 999f
+
+964:
+#ifdef CONFIG_64BIT
+ ld t3, 0(t2)
+ LONG_ADDU t3, a0
+ sd t3, 0(t2)
+#endif
+ LONG_ADDIU a1, 4
+ b 1b
+
+932:
+ lw t3, 0(t2)
+ LONG_ADDU t3, a0
+ sw t3, 0(t2)
+ LONG_ADDIU a1, 4
+ b 1b
+
+926:
+ lw t3, 0(t2)
+ LONG_ADDU t3, t9
+ sw t3, 0(t2)
+ LONG_ADDIU a1, 4
+ b 1b
+
+916:
+ lw t3, 0(t2)
+ LONG_ADDU t3, a2
+ sw t3, 0(t2)
+ LONG_ADDIU a1, 4
+ b 1b
+
+900:
+ /* Complete! And flush i-cache */
+ PTR_LA a0, _text
+ PTR_LA a1, _end
+ synci 0(a0)
+ rdhwr t0, $1
+ beqz t0, 999f
+ PTR_ADDU a0, t0
+ PTR_SUBU t0, a1, a0
+ bgtz t0, 900b
+ sync
+
+999:
+ /* Restore args */
+ move a0, s0
+ move a1, s1
+ move a2, s2
+ move a3, s3
+#endif /* CONFIG_RELOCATABLE */
+ .set pop
+ .endm
+
/*
* For the moment disable interrupts, mark the kernel mode and
* set ST0_KX so that the CPU does not spit fire when using
@@ -83,6 +230,8 @@ FEXPORT(__kernel_entry)
NESTED(kernel_entry, 16, sp) # kernel entry point
+ do_relocate_kernel
+
kernel_entry_setup # cpu specific setup
setup_c0_status_pri
--
2.1.0
Powered by blists - more mailing lists