#include "ppc_asm.h"
RELA = 7
RELASZ = 8
RELAENT = 9
.data
.globl _zimage_start_opd
_zimage_start_opd:
.long 0x500000, 0, 0, 0
.text
b _zimage_start
#ifdef __powerpc64__
.balign 8
p_start: .8byte _start
p_etext: .8byte _etext
p_bss_start: .8byte __bss_start
p_end: .8byte _end
p_toc: .8byte .TOC. - p_base
p_dyn: .8byte __dynamic_start - p_base
p_rela: .8byte __rela_dyn_start - p_base
p_prom: .8byte 0
.weak _platform_stack_top
p_pstack: .8byte _platform_stack_top
#else
p_start: .long _start
p_etext: .long _etext
p_bss_start: .long __bss_start
p_end: .long _end
.weak _platform_stack_top
p_pstack: .long _platform_stack_top
#endif
.weak _zimage_start
_zimage_start:
.globl _zimage_start_lib
_zimage_start_lib:
bcl 20,31,.+4
p_base: mflr r10
#ifndef __powerpc64__
addis r11,r10,(_GLOBAL_OFFSET_TABLE_-p_base)@ha
lwz r11,(_GLOBAL_OFFSET_TABLE_-p_base)@l(r11)
cmpwi r11,0
beq 3f
.weak __dynamic_start
addis r12,r10,(__dynamic_start-p_base)@ha
addi r12,r12,(__dynamic_start-p_base)@l
subf r11,r11,r12
li r9,0
li r0,0
9: lwz r8,0(r12)
cmpwi r8,0
beq 10f
cmpwi r8,RELA
bne 11f
lwz r9,4(r12)
b 12f
11: cmpwi r8,RELASZ
bne .Lcheck_for_relaent
lwz r0,4(r12)
b 12f
.Lcheck_for_relaent:
cmpwi r8,RELAENT
bne 12f
lwz r14,4(r12)
12: addi r12,r12,8
b 9b
10:
cmpwi r0,0
beq 3f
cmpwi r9,0
beq 3f
cmpwi r14,0
beq 3f
add r9,r9,r11
divwu r0,r0,r14
mtctr r0
2: lbz r0,4+3(r9)
cmpwi r0,22
bne .Lnext
lwz r12,0(r9)
lwz r0,8(r9)
add r0,r0,r11
stwx r0,r11,r12
.Lnext: add r9,r9,r14
bdnz 2b
3: lwz r9,p_start-p_base(r10)
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
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
lwz r8,p_pstack-p_base(r10)
cmpwi r8,0
beq 6f
lwz r1,0(r8)
li r0,0
stwu r0,-16(r1)
6:
#else
std r5,(p_prom-p_base)(r10)
ld r2,(p_toc-p_base)(r10)
add r2,r2,r10
ld r11,-32768(r2)
cmpwi r11,0
beq 3f
ld r11,(p_dyn-p_base)(r10)
add r11,r11,r10
ld r9,(p_rela-p_base)(r10)
add r9,r9,r10
li r13,0
li r8,0
9: ld r12,0(r11)
cmpdi r12,0
beq 12f
cmpdi r12,RELA
bne 10f
ld r13,8(r11)
b 11f
10: cmpwi r12,RELASZ
bne .Lcheck_for_relaent
lwz r8,8(r11)
b 11f
.Lcheck_for_relaent:
cmpwi r12,RELAENT
bne 11f
lwz r14,8(r11)
11: addi r11,r11,16
b 9b
12:
cmpdi r13,0
cmpdi cr1,r8,0
beq 3f
beq cr1,3f
cmpdi r14,0
beq 3f
subf r13,r13,r9
divdu r8,r8,r14
mtctr r8
13: ld r0,8(r9)
cmpdi r0,22
bne .Lnext
ld r12,0(r9)
ld r0,16(r9)
add r0,r0,r13
stdx r0,r13,r12
.Lnext: add r9,r9,r14
bdnz 13b
3: ld r9,p_start-p_base(r10)
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
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
ld r8,p_pstack-p_base(r10)
cmpdi r8,0
beq 6f
ld r1,0(r8)
li r0,0
stdu r0,-112(r1)
6:
#endif
bl platform_init
b start
#ifdef __powerpc64__
#define PROM_FRAME_SIZE 512
.macro OP_REGS op, width, start, end, base, offset
.Lreg=\start
.rept (\end - \start + 1)
\op .Lreg,\offset+\width*.Lreg(\base)
.Lreg=.Lreg+1
.endr
.endm
#define SAVE_GPRS(start, end, base) OP_REGS std, 8, start, end, base, 0
#define REST_GPRS(start, end, base) OP_REGS ld, 8, start, end, base, 0
#define SAVE_GPR(n, base) SAVE_GPRS(n, n, base)
#define REST_GPR(n, base) REST_GPRS(n, n, base)
.globl prom
prom:
mflr r0
std r0,16(r1)
stdu r1,-PROM_FRAME_SIZE(r1)
SAVE_GPR(2, r1)
SAVE_GPRS(13, 31, r1)
mfcr r10
std r10,8*32(r1)
mfmsr r10
std r10,8*33(r1)
mfmsr r10
rldicr r10,r10,0,62
mtsrr1 r10
bcl 20,31,0f
0: mflr r10
addi r11,r10,(1f-0b)
mtlr r11
ld r10,(p_prom-0b)(r10)
mtsrr0 r10
rfid
1:
FIXUP_ENDIAN
rldicl r1,r1,0,32
ld r10,8*(33)(r1)
mtmsr r10
isync
REST_GPR(2, r1)
REST_GPRS(13, 31, r1)
ld r10,8*32(r1)
mtcr r10
addi r1,r1,PROM_FRAME_SIZE
ld r0,16(r1)
mtlr r0
blr
#endif