1
2
3
4
5
6
7
8 #include "ppc_asm.h"
9
10 RELA = 7
11 RELACOUNT = 0x6ffffff9
12
13 .data
14
15
16
17
18 .globl _zimage_start_opd
19 _zimage_start_opd:
20 .long 0x500000, 0, 0, 0
21 .text
22 b _zimage_start
23
24 #ifdef __powerpc64__
25 .balign 8
26 p_start: .8byte _start
27 p_etext: .8byte _etext
28 p_bss_start: .8byte __bss_start
29 p_end: .8byte _end
30
31 p_toc: .8byte __toc_start + 0x8000 - p_base
32 p_dyn: .8byte __dynamic_start - p_base
33 p_rela: .8byte __rela_dyn_start - p_base
34 p_prom: .8byte 0
35 .weak _platform_stack_top
36 p_pstack: .8byte _platform_stack_top
37 #else
38 p_start: .long _start
39 p_etext: .long _etext
40 p_bss_start: .long __bss_start
41 p_end: .long _end
42
43 .weak _platform_stack_top
44 p_pstack: .long _platform_stack_top
45 #endif
46
47 .globl _zimage_start
48
49
50 .weak _zimage_start
51 _zimage_start:
52 .globl _zimage_start_lib
53 _zimage_start_lib:
54
55
56 bl .+4
57 p_base: mflr r10
58 #ifndef __powerpc64__
59
60 addis r11,r10,(_GLOBAL_OFFSET_TABLE_-p_base)@ha
61 lwz r11,(_GLOBAL_OFFSET_TABLE_-p_base)@l(r11)
62 cmpwi r11,0
63 beq 3f
64
65 .weak __dynamic_start
66 addis r12,r10,(__dynamic_start-p_base)@ha
67 addi r12,r12,(__dynamic_start-p_base)@l
68 subf r11,r11,r12
69
70
71
72 li r9,0
73 li r0,0
74 9: lwz r8,0(r12)
75 cmpwi r8,0
76 beq 10f
77 cmpwi r8,RELA
78 bne 11f
79 lwz r9,4(r12)
80 b 12f
81 11: addis r8,r8,(-RELACOUNT)@ha
82 cmpwi r8,RELACOUNT@l
83 bne 12f
84 lwz r0,4(r12)
85 12: addi r12,r12,8
86 b 9b
87
88
89
90
91
92
93 10:
94 cmpwi r0,0
95 beq 3f
96 cmpwi r9,0
97 beq 3f
98
99 add r9,r9,r11
100 mtctr r0
101 2: lbz r0,4+3(r9)
102 cmpwi r0,22
103 bne 3f
104 lwz r12,0(r9)
105 lwz r0,8(r9)
106 add r0,r0,r11
107 stwx r0,r11,r12
108 addi r9,r9,12
109 bdnz 2b
110
111
112 3: lwz r9,p_start-p_base(r10)
113 lwz r8,p_etext-p_base(r10)
114 4: dcbf r0,r9
115 icbi r0,r9
116 addi r9,r9,0x20
117 cmplw cr0,r9,r8
118 blt 4b
119 sync
120 isync
121
122
123 lwz r9,p_bss_start-p_base(r10)
124 lwz r8,p_end-p_base(r10)
125 li r0,0
126 5: stw r0,0(r9)
127 addi r9,r9,4
128 cmplw cr0,r9,r8
129 blt 5b
130
131
132 lwz r8,p_pstack-p_base(r10)
133 cmpwi r8,0
134 beq 6f
135 lwz r1,0(r8)
136 li r0,0
137 stwu r0,-16(r1)
138 6:
139 #else
140
141 std r5,(p_prom-p_base)(r10)
142
143
144 ld r2,(p_toc-p_base)(r10)
145 add r2,r2,r10
146
147
148 ld r11,-32768(r2)
149 cmpwi r11,0
150 beq 3f
151
152 ld r11,(p_dyn-p_base)(r10)
153 add r11,r11,r10
154 ld r9,(p_rela-p_base)(r10)
155 add r9,r9,r10
156
157 li r13,0
158 li r8,0
159 9: ld r12,0(r11)
160 cmpdi r12,0
161 beq 12f
162 cmpdi r12,RELA
163 bne 10f
164 ld r13,8(r11)
165 b 11f
166 10: addis r12,r12,(-RELACOUNT)@ha
167 cmpdi r12,RELACOUNT@l
168 bne 11f
169 ld r8,8(r11)
170 11: addi r11,r11,16
171 b 9b
172 12:
173 cmpdi r13,0
174 cmpdi cr1,r8,0
175 beq 3f
176 beq cr1,3f
177
178
179 subf r13,r13,r9
180
181
182
183 mtctr r8
184 13: ld r0,8(r9)
185 cmpdi r0,22
186 bne 3f
187 ld r12,0(r9)
188 ld r0,16(r9)
189 add r0,r0,r13
190 stdx r0,r13,r12
191 addi r9,r9,24
192 bdnz 13b
193
194
195 3: ld r9,p_start-p_base(r10)
196 ld r8,p_etext-p_base(r10)
197 4: dcbf r0,r9
198 icbi r0,r9
199 addi r9,r9,0x20
200 cmpld cr0,r9,r8
201 blt 4b
202 sync
203 isync
204
205
206 ld r9,p_bss_start-p_base(r10)
207 ld r8,p_end-p_base(r10)
208 li r0,0
209 5: std r0,0(r9)
210 addi r9,r9,8
211 cmpld cr0,r9,r8
212 blt 5b
213
214
215 ld r8,p_pstack-p_base(r10)
216 cmpdi r8,0
217 beq 6f
218 ld r1,0(r8)
219 li r0,0
220 stdu r0,-112(r1)
221 6:
222 #endif
223
224 bl platform_init
225
226
227 b start
228
229 #ifdef __powerpc64__
230
231 #define PROM_FRAME_SIZE 512
232 #define SAVE_GPR(n, base) std n,8*(n)(base)
233 #define REST_GPR(n, base) ld n,8*(n)(base)
234 #define SAVE_2GPRS(n, base) SAVE_GPR(n, base); SAVE_GPR(n+1, base)
235 #define SAVE_4GPRS(n, base) SAVE_2GPRS(n, base); SAVE_2GPRS(n+2, base)
236 #define SAVE_8GPRS(n, base) SAVE_4GPRS(n, base); SAVE_4GPRS(n+4, base)
237 #define SAVE_10GPRS(n, base) SAVE_8GPRS(n, base); SAVE_2GPRS(n+8, base)
238 #define REST_2GPRS(n, base) REST_GPR(n, base); REST_GPR(n+1, base)
239 #define REST_4GPRS(n, base) REST_2GPRS(n, base); REST_2GPRS(n+2, base)
240 #define REST_8GPRS(n, base) REST_4GPRS(n, base); REST_4GPRS(n+4, base)
241 #define REST_10GPRS(n, base) REST_8GPRS(n, base); REST_2GPRS(n+8, base)
242
243
244
245 .globl prom
246 prom:
247 mflr r0
248 std r0,16(r1)
249 stdu r1,-PROM_FRAME_SIZE(r1)
250
251 SAVE_GPR(2, r1)
252 SAVE_GPR(13, r1)
253 SAVE_8GPRS(14, r1)
254 SAVE_10GPRS(22, r1)
255 mfcr r10
256 std r10,8*32(r1)
257 mfmsr r10
258 std r10,8*33(r1)
259
260
261 mfmsr r10
262 rldicr r10,r10,0,62
263 mtsrr1 r10
264
265
266 bl 0f
267 0: mflr r10
268 addi r11,r10,(1f-0b)
269 mtlr r11
270
271 ld r10,(p_prom-0b)(r10)
272 mtsrr0 r10
273
274 rfid
275
276 1:
277 FIXUP_ENDIAN
278
279
280 rldicl r1,r1,0,32
281
282
283 ld r10,8*(33)(r1)
284 mtmsr r10
285 isync
286
287
288 REST_GPR(2, r1)
289 REST_GPR(13, r1)
290 REST_8GPRS(14, r1)
291 REST_10GPRS(22, r1)
292 ld r10,8*32(r1)
293 mtcr r10
294
295 addi r1,r1,PROM_FRAME_SIZE
296 ld r0,16(r1)
297 mtlr r0
298 blr
299 #endif