Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f16e9684 authored by Cédric Le Goater's avatar Cédric Le Goater Committed by Benjamin Herrenschmidt
Browse files

powerpc/boot: Modify entry point for 64bit



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: default avatarCédric Le Goater <clg@fr.ibm.com>
Signed-off-by: default avatarBenjamin Herrenschmidt <benh@kernel.crashing.org>
parent 93d39210
Loading
Loading
Loading
Loading
+104 −4
Original line number Diff line number Diff line
/*
 * 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 = 0x6ffffff9

	.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	0x500000, 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:	mflr	r10		/* 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: mflr r10 /* 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 = 0x6ffffff9
	li	r9,0
	li	r0,0
9:	lwz	r8,0(r12)	/* get tag */
@@ -120,7 +137,90 @@ RELACOUNT = 0x6ffffff9
	li	r0,0
	stwu	r0,-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:	addi	r11,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. */
	subf	r7,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
	stdx	r0,r7,r6
	addi	r9,r9,24
	bdnz	13b

	/* 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:	dcbf	r0,r9
	icbi	r0,r9
	addi	r9,r9,0x20
	cmpld	cr0,r9,r8
	blt	4b
	sync
	isync

	/* Clear the BSS */
	ld	r9,p_bss_start-p_base(r10)
	ld	r8,p_end-p_base(r10)
	li	r0,0
5:	std	r0,0(r9)
	addi	r9,r9,8
	cmpld	cr0,r9,r8
	blt	5b

	/* Possibly set up a custom stack */
	ld	r8,p_pstack-p_base(r10)
	cmpdi	r8,0
	beq	6f
	ld	r1,0(r8)
	li	r0,0
	stdu	r0,-16(r1)	/* establish a stack frame */
6:
#endif  /* __powerpc64__ */
	/* Call platform_init() */
	bl	platform_init