/* SPDX-License-Identifier: GPL-2.0-or-later */ /* * Copyright (C) Paul Mackerras 1997. * * Adapted for 64 bit LE PowerPC by Andrew Tauferner
*/
#include "ppc_asm.h"
RELA = 7
RELASZ = 8
RELAENT = 9
.data /* A procedure descriptor used when booting this as a COFF file. * When making COFF, this comes first in the link and we're * linked at 0x500000.
*/
.globl _zimage_start_opd
_zimage_start_opd:
.long 0x500000, 0, 0, 0
.text
b _zimage_start
.weak _zimage_start
_zimage_start:
.globl _zimage_start_lib
_zimage_start_lib: /* Work out the offset between the address we were linked at
and the address where we're running. */
bcl 20,31,.+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)
cmpwi r11,0
beq 3f /* if not linked -pie */ /* get the runtime address of the dynamic section in r12 */
.weak __dynamic_start
addis r12,r10,(__dynamic_start-p_base)@ha
addi r12,r12,(__dynamic_start-p_base)@l
subf r11,r11,r12 /* runtime - linktime offset */
/* The dynamic section contains a series of tagged entries.
* We need the RELA and RELACOUNT entries. */
li r9,0
li r0,0
9: lwz r8,0(r12) /* get tag */
cmpwi r8,0
beq 10f /* end of list */
cmpwi r8,RELA
bne 11f
lwz r9,4(r12) /* get RELA pointer in r9 */
b 12f
11: cmpwi r8,RELASZ
bne .Lcheck_for_relaent
lwz r0,4(r12) /* get RELASZ value in r0 */
b 12f
.Lcheck_for_relaent:
cmpwi r8,RELAENT
bne 12f
lwz r14,4(r12) /* get RELAENT value in r14 */
12: addi r12,r12,8
b 9b
/* The relocation section contains a list of relocations. * We now do the R_PPC_RELATIVE ones, which point to words
* which need to be initialized with addend + offset */
10: /* skip relocation if we don't have both */
cmpwi r0,0
beq 3f
cmpwi r9,0
beq 3f
cmpwi r14,0
beq 3f
/* Do a cache flush for our text, in case the loader didn't */
3: lwz r9,p_start-p_base(r10) /* note: these are relocated now */
lwz r8,p_etext-p_base(r10)
4: dcbf r0,r9
icbi r0,r9
addi r9,r9,0x20
cmplw cr0,r9,r8
blt 4b
sync
isync
/* Clear the BSS */
lwz r9,p_bss_start-p_base(r10)
lwz r8,p_end-p_base(r10)
li r0,0
5: stw r0,0(r9)
addi r9,r9,4
cmplw cr0,r9,r8
blt 5b
/* Possibly set up a custom stack */
lwz r8,p_pstack-p_base(r10)
cmpwi r8,0
beq 6f
lwz r1,0(r8)
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 */
li r13,0
li r8,0
9: ld r12,0(r11) /* get tag */
cmpdi r12,0
beq 12f /* end of list */
cmpdi r12,RELA
bne 10f ld r13,8(r11) /* get RELA pointer in r13 */
b 11f
10: cmpwi r12,RELASZ
bne .Lcheck_for_relaent
lwz r8,8(r11) /* get RELASZ pointer in r8 */
b 11f
.Lcheck_for_relaent:
cmpwi r12,RELAENT
bne 11f
lwz r14,8(r11) /* get RELAENT pointer in r14 */
11: addi r11,r11,16
b 9b
12:
cmpdi r13,0 /* check we have both RELA, RELASZ, RELAENT*/
cmpdi cr1,r8,0
beq 3f
beq cr1,3f
cmpdi r14,0
beq 3f
/* Calcuate the runtime offset. */
subf r13,r13,r9
/* Run through the list of relocations and process the
* R_PPC64_RELATIVE ones. */
divdu r8,r8,r14 /* RELASZ / RELAENT */
mtctr r8
13: ld r0,8(r9) /* ELF64_R_TYPE(reloc->r_info) */
cmpdi r0,22 /* R_PPC64_RELATIVE */
bne .Lnext ld r12,0(r9) /* reloc->r_offset */ ld r0,16(r9) /* reloc->r_addend */
add r0,r0,r13
stdx r0,r13,r12
.Lnext: add r9,r9,r14
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,-112(r1) /* establish a stack frame */
6:
#endif /* __powerpc64__ */ /* Call platform_init() */
bl platform_init
/* prom handles the jump into and return from firmware. The prom args pointer
is loaded in r3. */
.globl prom
prom:
mflr r0
std r0,16(r1)
stdu r1,-PROM_FRAME_SIZE(r1) /* Save SP and create stack space */
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.