From: Mohan Kumar M <mohan@in.ibm.com>
To: ppcdev <linuxppc-dev@ozlabs.org>
Cc: paulus@samba.org, miltonm@bga.com
Subject: [RFC v3 PATCH 3/4] Apply relocation info to vmlinux
Date: Fri, 18 Jul 2008 00:15:41 +0530 [thread overview]
Message-ID: <20080717184541.GD25070@in.ibm.com> (raw)
In-Reply-To: <20080717183339.GA25070@in.ibm.com>
Apply relocation
This code is a wrapper around regular kernel. This checks whether the
kernel is loaded at 32MB, if its not loaded at 32MB, its treated as a
regular kernel and the control is given to the kernel immediately. If
the kernel is loaded at 32MB, it applies relocation delta to each offset
in the list which was generated and appended by patch 1 and 2. After
updating all offsets, control is given to relocatable kernel.
Signed-off-by: Mohan Kumar M <mohan@in.ibm.com>
---
arch/powerpc/boot/reloc_apply.S | 229 ++++++++++++++++++++++++++++++++++++++++
1 file changed, 229 insertions(+)
Index: linux-2.6.26/arch/powerpc/boot/reloc_apply.S
===================================================================
--- /dev/null
+++ linux-2.6.26/arch/powerpc/boot/reloc_apply.S
@@ -0,0 +1,229 @@
+#include <asm/ppc_asm.h>
+
+#define RELOC_DELTA 0x4000000002000000
+
+#define LOADADDR(rn,name) \
+ lis rn,name##@highest; \
+ ori rn,rn,name##@higher; \
+ rldicr rn,rn,32,31; \
+ oris rn,rn,name##@h; \
+ ori rn,rn,name##@l
+
+
+/*
+ * Layout of vmlinux.reloc file
+ * Minimal part of relocation applying code +
+ * vmlinux +
+ * Rest of the relocation applying code
+ */
+
+.section .text.head
+
+.globl start_wrap
+start_wrap:
+ /* Get relocation offset in r15 */
+ bl 1f
+1: mflr r15
+ LOAD_REG_IMMEDIATE(r16,1b)
+ subf r15,r16,r15
+
+ LOAD_REG_IMMEDIATE(r17, _reloc)
+ add r17,r17,r15
+ mtctr r17
+ bctr /* Jump to start_reloc in section ".text.reloc" */
+
+/* Secondary cpus spin code */
+. = 0x60
+ /* Get relocation offset in r15 */
+ bl 1f
+1: mflr r15
+ LOAD_REG_IMMEDIATE(r16,1b)
+ subf r15,r16,r15
+
+ LOADADDR(r18, __spinloop)
+ add r18,r18,r15
+100: ld r19,0(r18)
+ cmpwi 0,r19,1
+ bne 100b
+
+ LOAD_REG_IMMEDIATE(r17, _reloc)
+ add r17,r17,r15
+ addi r17,r17,0x60
+ mtctr r17
+ /* Jump to start_reloc + 0x60 in section ".text.reloc" */
+ bctr
+
+/*
+ * Layout of vmlinux.reloc file
+ * Minimal part of relocation applying code +
+ * vmlinux +
+ * Rest of the relocation applying code
+ */
+
+
+.section .text.reloc
+
+start_reloc:
+ b master
+
+.org start_reloc + 0x60
+ LOADADDR(r18, __spinloop)
+ add r18,r18,r15
+100: ld r19,0(r18)
+ cmpwi 0,r19,2
+ bne 100b
+
+ /* Now vmlinux is at _head */
+ LOAD_REG_IMMEDIATE(r17, _head)
+ add r17,r17,r15
+ addi r17,r17,0x60
+ mtctr r17
+ bctr
+
+master:
+ LOAD_REG_IMMEDIATE(r16, output_len)
+ add r16,r16,r15
+
+ /*
+ * Load the delimiter to distinguish between different relocation
+ * types
+ */
+ LOAD_REG_IMMEDIATE(r24, __delimiter)
+ add r24,r24,r15
+ ld r24,0(r24)
+
+ LOAD_REG_IMMEDIATE(r17, _head)
+ LOAD_REG_IMMEDIATE(r21, _ehead)
+ sub r21,r21,r17 /* Number of bytes in head section */
+
+ sub r16,r16,r21 /* Original output_len */
+
+ /* Destination address */
+ LOAD_REG_IMMEDIATE(r17, _head) /* KERNELBASE */
+ add r17,r17,r15
+
+ /* Source address */
+ LOAD_REG_IMMEDIATE(r18, _text) /* Regular vmlinux */
+ add r18,r18,r15
+
+ /* Number of bytes to copy */
+ LOAD_REG_IMMEDIATE(r19, _etext)
+ add r19,r19,r15
+ sub r19,r19,r18
+
+ /* Move cpu spin code to "text.reloc" section */
+ LOADADDR(r23, __spinloop)
+ add r23,r23,r15
+ li r25,1
+ stw r25,0(r23)
+
+ /* Copy vmlinux code to physical address 0 */
+ bl .copy /* copy(_head, _text, _etext-_text) */
+
+ /*
+ * If its not running at 32MB, assume it to be a normal kernel.
+ * Copy the vmlinux code to KERNELBASE and jump to KERNELBASE
+ */
+ LOAD_REG_IMMEDIATE(r21, RELOC_DELTA)
+ cmpd r15,r21
+ beq apply_relocation
+ li r6,0
+ b skip_apply
+apply_relocation:
+
+ /* Kernel is running at 32MB */
+ mr r22,r15
+ xor r23,r23,r23
+ addi r23,r23,16
+ srw r22,r22,r23
+
+ li r25,0
+
+ LOAD_REG_IMMEDIATE(r26, _head)
+
+ /*
+ * Start reading the relocation offset list from end of file
+ * Based on the relocation type either add the relocation delta
+ * or do logical ORing the relocation delta
+ */
+3:
+ addi r16,r16,-8
+ ld r18,0(r16)
+ cmpdi r18,0 /* Processed all offsets */
+ beq 4f /* Start vmlinux */
+ /* Are we processing reloction type R_PPC64_ADDR16_HI */
+ cmpdi r25,1
+ beq rel_hi
+ cmpd r18,r24
+ beq set_rel_hi
+ /* Process 64bit absolute relocation update */
+rel_addr64:
+ add r18,r18,r15
+ ld r28,0(r18)
+ cmpdi r28,0
+ beq next
+ add r28,r28,r15 /* add relocation offset */
+ add r28,r28,r26 /* add KERNELBASE */
+ std r28,0(r18)
+ b next
+set_rel_hi: /* Enable R_PPC64_ADDR16_HI flag */
+ addi r25,r25,1
+ b 3b
+rel_hi:
+ add r18,r18,r15
+ lhz r28,0(r18)
+ or r28,r28,r22
+ sth r28,0(r18)
+next:
+ b 3b
+4:
+ mr r6,r15
+
+
+skip_apply:
+ isync
+ sync
+
+ /* Now vmlinux is at _head */
+ LOAD_REG_IMMEDIATE(r17, _head)
+ add r17,r17,r15
+ mtctr r17
+
+ /* Move cpu spin code to "text.reloc" section */
+ LOADADDR(r23, __spinloop)
+ add r23,r23,r15
+ li r25,2
+ stw r25,0(r23)
+
+ bctr
+
+/* r17 destination, r18 source, r19 size */
+.copy:
+ addi r19,r19,-8
+ li r22,-8
+4: li r21,8 /* Use the smallest common */
+ /* denominator cache line */
+ /* size. This results in */
+ /* extra cache line flushes */
+ /* but operation is correct. */
+ /* Can't get cache line size */
+ /* from NACA as it is being */
+ /* moved too. */
+
+ mtctr r21 /* put # words/line in ctr */
+3: addi r22,r22,8 /* copy a cache line */
+ ldx r21,r22,r18
+ stdx r21,r22,r17
+ bdnz 3b
+ dcbst r22,r17 /* write it to memory */
+ sync
+ icbi r22,r17 /* flush the icache line */
+ cmpld 0,r22,r19
+ blt 4b
+ sync
+ blr
+
+__delimiter:
+ .llong 0xffffffffffffffff
+__spinloop:
+ .llong 0x0
next prev parent reply other threads:[~2008-07-17 18:45 UTC|newest]
Thread overview: 22+ messages / expand[flat|nested] mbox.gz Atom feed top
2008-07-17 18:33 [RFC v3 PATCH 0/4] Relocatable kernel support for PPC64 Mohan Kumar M
2008-07-17 18:40 ` [RFC v3 PATCH 1/4] Extract list of relocation offsets Mohan Kumar M
2008-07-17 20:06 ` Benjamin Herrenschmidt
2008-07-18 5:32 ` Mohan Kumar M
2008-07-18 17:00 ` Milton Miller
2008-07-21 19:17 ` Mohan Kumar M
2008-07-22 6:29 ` Paul Mackerras
2008-07-22 7:58 ` Mohan Kumar M
2008-07-21 19:20 ` [RFC v3 PATCH 2/4] Build files needed for relocation Mohan Kumar M
2008-07-21 19:21 ` [RFC v3 PATCH 3/4] Apply relocation Mohan Kumar M
2008-07-21 19:23 ` [RFC v3 PATCH 4/4] Relocation support Mohan Kumar M
2008-07-21 19:25 ` [RFC v3 PATCH 5/4] Relocation support for kdump kernel Mohan Kumar M
2008-07-21 19:26 ` [RFC v3 PATCH 6/4] Use LOAD_REG_IMMEDIATE macros Mohan Kumar M
2008-07-22 2:03 ` Paul Mackerras
2008-07-22 4:37 ` Mohan Kumar M
2008-07-22 6:37 ` Paul Mackerras
2008-07-22 17:13 ` Segher Boessenkool
2008-07-17 18:42 ` [RFC v3 PATCH 2/4] Build files needed for relocation support Mohan Kumar M
2008-07-17 18:45 ` Mohan Kumar M [this message]
2008-07-17 18:48 ` [RFC v3 PATCH 4/4] Relocation support Mohan Kumar M
2008-07-18 17:48 ` Segher Boessenkool
2008-07-21 9:11 ` Mohan Kumar M
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20080717184541.GD25070@in.ibm.com \
--to=mohan@in.ibm.com \
--cc=linuxppc-dev@ozlabs.org \
--cc=miltonm@bga.com \
--cc=paulus@samba.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).