[PATCH v2 13/15] powerpc/boot: modify entry point for 64bit

2014-04-24 Thread Cédric Le Goater
This patch adds support a 64bit wrapper entry point. As in 32bit, the
entry point does its own relocation and can be loaded at any address
by the firmware.

Signed-off-by: Cédric Le Goater 
---
 arch/powerpc/boot/crt0.S |  108 --
 1 file changed, 104 insertions(+), 4 deletions(-)

diff --git a/arch/powerpc/boot/crt0.S b/arch/powerpc/boot/crt0.S
index dbd99d064828..689290561e69 100644
--- a/arch/powerpc/boot/crt0.S
+++ b/arch/powerpc/boot/crt0.S
@@ -1,17 +1,20 @@
 /*
  * Copyright (C) Paul Mackerras 1997.
  *
+ * Adapted for 64 bit LE PowerPC by Andrew Tauferner
+ *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
  * as published by the Free Software Foundation; either version
  * 2 of the License, or (at your option) any later version.
  *
- * NOTE: this code runs in 32 bit mode, is position-independent,
- * and is packaged as ELF32.
  */
 
 #include "ppc_asm.h"
 
+RELA = 7
+RELACOUNT = 0x6ff9
+
.text
/* A procedure descriptor used when booting this as a COFF file.
 * When making COFF, this comes first in the link and we're
@@ -21,6 +24,20 @@
 _zimage_start_opd:
.long   0x50, 0, 0, 0
 
+#ifdef __powerpc64__
+.balign 8
+p_start:   .llong  _start
+p_etext:   .llong  _etext
+p_bss_start:   .llong  __bss_start
+p_end: .llong  _end
+
+p_toc: .llong  __toc_start + 0x8000 - p_base
+p_dyn: .llong  __dynamic_start - p_base
+p_rela:.llong  __rela_dyn_start - p_base
+p_prom:.llong  0
+   .weak   _platform_stack_top
+p_pstack:  .llong  _platform_stack_top
+#else
 p_start:   .long   _start
 p_etext:   .long   _etext
 p_bss_start:   .long   __bss_start
@@ -28,6 +45,7 @@ p_end:.long   _end
 
.weak   _platform_stack_top
 p_pstack:  .long   _platform_stack_top
+#endif
 
.weak   _zimage_start
.globl  _zimage_start
@@ -38,6 +56,7 @@ _zimage_start_lib:
   and the address where we're running. */
bl  .+4
 p_base:mflrr10 /* r10 now points to runtime addr of 
p_base */
+#ifndef __powerpc64__
/* grab the link address of the dynamic section in r11 */
addis   r11,r10,(_GLOBAL_OFFSET_TABLE_-p_base)@ha
lwz r11,(_GLOBAL_OFFSET_TABLE_-p_base)@l(r11)
@@ -51,8 +70,6 @@ p_base:   mflrr10 /* r10 now points to 
runtime addr of p_base */
 
/* The dynamic section contains a series of tagged entries.
 * We need the RELA and RELACOUNT entries. */
-RELA = 7
-RELACOUNT = 0x6ff9
li  r9,0
li  r0,0
 9: lwz r8,0(r12)   /* get tag */
@@ -120,7 +137,90 @@ RELACOUNT = 0x6ff9
li  r0,0
stwur0,-16(r1)  /* establish a stack frame */
 6:
+#else /* __powerpc64__ */
+   /* Save the prom pointer at p_prom. */
+   std r5,(p_prom-p_base)(r10)
+
+   /* Set r2 to the TOC. */
+   ld  r2,(p_toc-p_base)(r10)
+   add r2,r2,r10
+
+   /* Grab the link address of the dynamic section in r11. */
+   ld  r11,-32768(r2)
+   cmpwi   r11,0
+   beq 3f  /* if not linked -pie then no dynamic section */
+
+   ld  r11,(p_dyn-p_base)(r10)
+   add r11,r11,r10
+   ld  r9,(p_rela-p_base)(r10)
+   add r9,r9,r10
+
+   li  r7,0
+   li  r8,0
+9: ld  r6,0(r11)   /* get tag */
+   cmpdi   r6,0
+   beq 12f  /* end of list */
+   cmpdi   r6,RELA
+   bne 10f
+   ld  r7,8(r11)   /* get RELA pointer in r7 */
+   b   11f
+10:addis   r6,r6,(-RELACOUNT)@ha
+   cmpdi   r6,RELACOUNT@l
+   bne 11f
+   ld  r8,8(r11)   /* get RELACOUNT value in r8 */
+11:addir11,r11,16
+   b   9b
+12:
+   cmpdi   r7,0/* check we have both RELA and RELACOUNT */
+   cmpdi   cr1,r8,0
+   beq 3f
+   beq cr1,3f
+
+   /* Calcuate the runtime offset. */
+   subfr7,r7,r9
 
+   /* Run through the list of relocations and process the
+* R_PPC64_RELATIVE ones. */
+   mtctr   r8
+13:ld  r0,8(r9)/* ELF64_R_TYPE(reloc->r_info) */
+   cmpdi   r0,22   /* R_PPC64_RELATIVE */
+   bne 3f
+   ld  r6,0(r9)/* reloc->r_offset */
+   ld  r0,16(r9)   /* reloc->r_addend */
+   add r0,r0,r7
+   stdxr0,r7,r6
+   addir9,r9,24
+   bdnz13b
+
+   /* Do a cache flush for our text, in case the loader didn't */
+3: ld  r9,p_start-p_base(r10)  /* note: these are relocated now */
+   ld  r8,p_etext-p_base(r10)
+4: dcbfr0,r9
+   icbir0,r9
+   addir9,r9,0x20
+   cmpld   cr0,r9,r8
+   blt 4b
+   sync
+   isync
+
+   /* Clear the BSS */
+   ld  r9,

[PATCH v2 13/15] powerpc/boot: modify entry point for 64bit

2014-04-14 Thread Cédric Le Goater
This patch adds support a 64bit wrapper entry point. As in 32bit, the
entry point does its own relocation and can be loaded at any address
by the firmware.

Signed-off-by: Cédric Le Goater 
---
 arch/powerpc/boot/crt0.S |  108 --
 1 file changed, 104 insertions(+), 4 deletions(-)

diff --git a/arch/powerpc/boot/crt0.S b/arch/powerpc/boot/crt0.S
index dbd99d064828..689290561e69 100644
--- a/arch/powerpc/boot/crt0.S
+++ b/arch/powerpc/boot/crt0.S
@@ -1,17 +1,20 @@
 /*
  * Copyright (C) Paul Mackerras 1997.
  *
+ * Adapted for 64 bit LE PowerPC by Andrew Tauferner
+ *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
  * as published by the Free Software Foundation; either version
  * 2 of the License, or (at your option) any later version.
  *
- * NOTE: this code runs in 32 bit mode, is position-independent,
- * and is packaged as ELF32.
  */
 
 #include "ppc_asm.h"
 
+RELA = 7
+RELACOUNT = 0x6ff9
+
.text
/* A procedure descriptor used when booting this as a COFF file.
 * When making COFF, this comes first in the link and we're
@@ -21,6 +24,20 @@
 _zimage_start_opd:
.long   0x50, 0, 0, 0
 
+#ifdef __powerpc64__
+.balign 8
+p_start:   .llong  _start
+p_etext:   .llong  _etext
+p_bss_start:   .llong  __bss_start
+p_end: .llong  _end
+
+p_toc: .llong  __toc_start + 0x8000 - p_base
+p_dyn: .llong  __dynamic_start - p_base
+p_rela:.llong  __rela_dyn_start - p_base
+p_prom:.llong  0
+   .weak   _platform_stack_top
+p_pstack:  .llong  _platform_stack_top
+#else
 p_start:   .long   _start
 p_etext:   .long   _etext
 p_bss_start:   .long   __bss_start
@@ -28,6 +45,7 @@ p_end:.long   _end
 
.weak   _platform_stack_top
 p_pstack:  .long   _platform_stack_top
+#endif
 
.weak   _zimage_start
.globl  _zimage_start
@@ -38,6 +56,7 @@ _zimage_start_lib:
   and the address where we're running. */
bl  .+4
 p_base:mflrr10 /* r10 now points to runtime addr of 
p_base */
+#ifndef __powerpc64__
/* grab the link address of the dynamic section in r11 */
addis   r11,r10,(_GLOBAL_OFFSET_TABLE_-p_base)@ha
lwz r11,(_GLOBAL_OFFSET_TABLE_-p_base)@l(r11)
@@ -51,8 +70,6 @@ p_base:   mflrr10 /* r10 now points to 
runtime addr of p_base */
 
/* The dynamic section contains a series of tagged entries.
 * We need the RELA and RELACOUNT entries. */
-RELA = 7
-RELACOUNT = 0x6ff9
li  r9,0
li  r0,0
 9: lwz r8,0(r12)   /* get tag */
@@ -120,7 +137,90 @@ RELACOUNT = 0x6ff9
li  r0,0
stwur0,-16(r1)  /* establish a stack frame */
 6:
+#else /* __powerpc64__ */
+   /* Save the prom pointer at p_prom. */
+   std r5,(p_prom-p_base)(r10)
+
+   /* Set r2 to the TOC. */
+   ld  r2,(p_toc-p_base)(r10)
+   add r2,r2,r10
+
+   /* Grab the link address of the dynamic section in r11. */
+   ld  r11,-32768(r2)
+   cmpwi   r11,0
+   beq 3f  /* if not linked -pie then no dynamic section */
+
+   ld  r11,(p_dyn-p_base)(r10)
+   add r11,r11,r10
+   ld  r9,(p_rela-p_base)(r10)
+   add r9,r9,r10
+
+   li  r7,0
+   li  r8,0
+9: ld  r6,0(r11)   /* get tag */
+   cmpdi   r6,0
+   beq 12f  /* end of list */
+   cmpdi   r6,RELA
+   bne 10f
+   ld  r7,8(r11)   /* get RELA pointer in r7 */
+   b   11f
+10:addis   r6,r6,(-RELACOUNT)@ha
+   cmpdi   r6,RELACOUNT@l
+   bne 11f
+   ld  r8,8(r11)   /* get RELACOUNT value in r8 */
+11:addir11,r11,16
+   b   9b
+12:
+   cmpdi   r7,0/* check we have both RELA and RELACOUNT */
+   cmpdi   cr1,r8,0
+   beq 3f
+   beq cr1,3f
+
+   /* Calcuate the runtime offset. */
+   subfr7,r7,r9
 
+   /* Run through the list of relocations and process the
+* R_PPC64_RELATIVE ones. */
+   mtctr   r8
+13:ld  r0,8(r9)/* ELF64_R_TYPE(reloc->r_info) */
+   cmpdi   r0,22   /* R_PPC64_RELATIVE */
+   bne 3f
+   ld  r6,0(r9)/* reloc->r_offset */
+   ld  r0,16(r9)   /* reloc->r_addend */
+   add r0,r0,r7
+   stdxr0,r7,r6
+   addir9,r9,24
+   bdnz13b
+
+   /* Do a cache flush for our text, in case the loader didn't */
+3: ld  r9,p_start-p_base(r10)  /* note: these are relocated now */
+   ld  r8,p_etext-p_base(r10)
+4: dcbfr0,r9
+   icbir0,r9
+   addir9,r9,0x20
+   cmpld   cr0,r9,r8
+   blt 4b
+   sync
+   isync
+
+   /* Clear the BSS */
+   ld  r9,