Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/arch/powerpc/boot/crt0.S
10818 views
1
/*
2
* Copyright (C) Paul Mackerras 1997.
3
*
4
* This program is free software; you can redistribute it and/or
5
* modify it under the terms of the GNU General Public License
6
* as published by the Free Software Foundation; either version
7
* 2 of the License, or (at your option) any later version.
8
*
9
* NOTE: this code runs in 32 bit mode, is position-independent,
10
* and is packaged as ELF32.
11
*/
12
13
#include "ppc_asm.h"
14
15
.text
16
/* A procedure descriptor used when booting this as a COFF file.
17
* When making COFF, this comes first in the link and we're
18
* linked at 0x500000.
19
*/
20
.globl _zimage_start_opd
21
_zimage_start_opd:
22
.long 0x500000, 0, 0, 0
23
24
p_start: .long _start
25
p_etext: .long _etext
26
p_bss_start: .long __bss_start
27
p_end: .long _end
28
29
.weak _platform_stack_top
30
p_pstack: .long _platform_stack_top
31
32
.weak _zimage_start
33
.globl _zimage_start
34
_zimage_start:
35
.globl _zimage_start_lib
36
_zimage_start_lib:
37
/* Work out the offset between the address we were linked at
38
and the address where we're running. */
39
bl .+4
40
p_base: mflr r10 /* r10 now points to runtime addr of p_base */
41
/* grab the link address of the dynamic section in r11 */
42
addis r11,r10,(_GLOBAL_OFFSET_TABLE_-p_base)@ha
43
lwz r11,(_GLOBAL_OFFSET_TABLE_-p_base)@l(r11)
44
cmpwi r11,0
45
beq 3f /* if not linked -pie */
46
/* get the runtime address of the dynamic section in r12 */
47
.weak __dynamic_start
48
addis r12,r10,(__dynamic_start-p_base)@ha
49
addi r12,r12,(__dynamic_start-p_base)@l
50
subf r11,r11,r12 /* runtime - linktime offset */
51
52
/* The dynamic section contains a series of tagged entries.
53
* We need the RELA and RELACOUNT entries. */
54
RELA = 7
55
RELACOUNT = 0x6ffffff9
56
li r9,0
57
li r0,0
58
9: lwz r8,0(r12) /* get tag */
59
cmpwi r8,0
60
beq 10f /* end of list */
61
cmpwi r8,RELA
62
bne 11f
63
lwz r9,4(r12) /* get RELA pointer in r9 */
64
b 12f
65
11: addis r8,r8,(-RELACOUNT)@ha
66
cmpwi r8,RELACOUNT@l
67
bne 12f
68
lwz r0,4(r12) /* get RELACOUNT value in r0 */
69
12: addi r12,r12,8
70
b 9b
71
72
/* The relocation section contains a list of relocations.
73
* We now do the R_PPC_RELATIVE ones, which point to words
74
* which need to be initialized with addend + offset.
75
* The R_PPC_RELATIVE ones come first and there are RELACOUNT
76
* of them. */
77
10: /* skip relocation if we don't have both */
78
cmpwi r0,0
79
beq 3f
80
cmpwi r9,0
81
beq 3f
82
83
add r9,r9,r11 /* Relocate RELA pointer */
84
mtctr r0
85
2: lbz r0,4+3(r9) /* ELF32_R_INFO(reloc->r_info) */
86
cmpwi r0,22 /* R_PPC_RELATIVE */
87
bne 3f
88
lwz r12,0(r9) /* reloc->r_offset */
89
lwz r0,8(r9) /* reloc->r_addend */
90
add r0,r0,r11
91
stwx r0,r11,r12
92
addi r9,r9,12
93
bdnz 2b
94
95
/* Do a cache flush for our text, in case the loader didn't */
96
3: lwz r9,p_start-p_base(r10) /* note: these are relocated now */
97
lwz r8,p_etext-p_base(r10)
98
4: dcbf r0,r9
99
icbi r0,r9
100
addi r9,r9,0x20
101
cmplw cr0,r9,r8
102
blt 4b
103
sync
104
isync
105
106
/* Clear the BSS */
107
lwz r9,p_bss_start-p_base(r10)
108
lwz r8,p_end-p_base(r10)
109
li r0,0
110
5: stw r0,0(r9)
111
addi r9,r9,4
112
cmplw cr0,r9,r8
113
blt 5b
114
115
/* Possibly set up a custom stack */
116
lwz r8,p_pstack-p_base(r10)
117
cmpwi r8,0
118
beq 6f
119
lwz r1,0(r8)
120
li r0,0
121
stwu r0,-16(r1) /* establish a stack frame */
122
6:
123
124
/* Call platform_init() */
125
bl platform_init
126
127
/* Call start */
128
b start
129
130