diff options
Diffstat (limited to 'arch')
-rw-r--r-- | arch/blackfin/mach-common/head.S | 66 |
1 files changed, 19 insertions, 47 deletions
diff --git a/arch/blackfin/mach-common/head.S b/arch/blackfin/mach-common/head.S index f123a62e2451..42ee2b1831bb 100644 --- a/arch/blackfin/mach-common/head.S +++ b/arch/blackfin/mach-common/head.S | |||
@@ -195,6 +195,19 @@ ENDPROC(__start) | |||
195 | # define WDOG_CTL WDOGA_CTL | 195 | # define WDOG_CTL WDOGA_CTL |
196 | #endif | 196 | #endif |
197 | 197 | ||
198 | ENTRY(__init_clear_bss) | ||
199 | r2 = r2 - r1; | ||
200 | cc = r2 == 0; | ||
201 | if cc jump .L_bss_done; | ||
202 | r2 >>= 2; | ||
203 | p1 = r1; | ||
204 | p2 = r2; | ||
205 | lsetup (1f, 1f) lc0 = p2; | ||
206 | 1: [p1++] = r0; | ||
207 | .L_bss_done: | ||
208 | rts; | ||
209 | ENDPROC(__init_clear_bss) | ||
210 | |||
198 | ENTRY(_real_start) | 211 | ENTRY(_real_start) |
199 | /* Enable nested interrupts */ | 212 | /* Enable nested interrupts */ |
200 | [--sp] = reti; | 213 | [--sp] = reti; |
@@ -206,75 +219,34 @@ ENTRY(_real_start) | |||
206 | w[p0] = r0; | 219 | w[p0] = r0; |
207 | ssync; | 220 | ssync; |
208 | 221 | ||
222 | r0 = 0 (x); | ||
223 | /* Zero out all of the fun bss regions */ | ||
209 | #if L1_DATA_A_LENGTH > 0 | 224 | #if L1_DATA_A_LENGTH > 0 |
210 | r1.l = __sbss_l1; | 225 | r1.l = __sbss_l1; |
211 | r1.h = __sbss_l1; | 226 | r1.h = __sbss_l1; |
212 | r2.l = __ebss_l1; | 227 | r2.l = __ebss_l1; |
213 | r2.h = __ebss_l1; | 228 | r2.h = __ebss_l1; |
214 | r0 = 0 (z); | 229 | call __init_clear_bss |
215 | r2 = r2 - r1; | ||
216 | cc = r2 == 0; | ||
217 | if cc jump .L_a_l1_done; | ||
218 | r2 >>= 2; | ||
219 | p1 = r1; | ||
220 | p2 = r2; | ||
221 | lsetup (.L_clear_a_l1, .L_clear_a_l1 ) lc0 = p2; | ||
222 | .L_clear_a_l1: | ||
223 | [p1++] = r0; | ||
224 | .L_a_l1_done: | ||
225 | #endif | 230 | #endif |
226 | |||
227 | #if L1_DATA_B_LENGTH > 0 | 231 | #if L1_DATA_B_LENGTH > 0 |
228 | r1.l = __sbss_b_l1; | 232 | r1.l = __sbss_b_l1; |
229 | r1.h = __sbss_b_l1; | 233 | r1.h = __sbss_b_l1; |
230 | r2.l = __ebss_b_l1; | 234 | r2.l = __ebss_b_l1; |
231 | r2.h = __ebss_b_l1; | 235 | r2.h = __ebss_b_l1; |
232 | r0 = 0 (z); | 236 | call __init_clear_bss |
233 | r2 = r2 - r1; | ||
234 | cc = r2 == 0; | ||
235 | if cc jump .L_b_l1_done; | ||
236 | r2 >>= 2; | ||
237 | p1 = r1; | ||
238 | p2 = r2; | ||
239 | lsetup (.L_clear_b_l1, .L_clear_b_l1 ) lc0 = p2; | ||
240 | .L_clear_b_l1: | ||
241 | [p1++] = r0; | ||
242 | .L_b_l1_done: | ||
243 | #endif | 237 | #endif |
244 | |||
245 | #if L2_LENGTH > 0 | 238 | #if L2_LENGTH > 0 |
246 | r1.l = __sbss_l2; | 239 | r1.l = __sbss_l2; |
247 | r1.h = __sbss_l2; | 240 | r1.h = __sbss_l2; |
248 | r2.l = __ebss_l2; | 241 | r2.l = __ebss_l2; |
249 | r2.h = __ebss_l2; | 242 | r2.h = __ebss_l2; |
250 | r0 = 0 (z); | 243 | call __init_clear_bss |
251 | r2 = r2 - r1; | ||
252 | cc = r2 == 0; | ||
253 | if cc jump .L_l2_done; | ||
254 | r2 >>= 2; | ||
255 | p1 = r1; | ||
256 | p2 = r2; | ||
257 | lsetup (.L_clear_l2, .L_clear_l2 ) lc0 = p2; | ||
258 | .L_clear_l2: | ||
259 | [p1++] = r0; | ||
260 | .L_l2_done: | ||
261 | #endif | 244 | #endif |
262 | |||
263 | /* Zero out the bss region | ||
264 | * Note: this will fail if bss is 0 bytes ... | ||
265 | */ | ||
266 | r0 = 0 (z); | ||
267 | r1.l = ___bss_start; | 245 | r1.l = ___bss_start; |
268 | r1.h = ___bss_start; | 246 | r1.h = ___bss_start; |
269 | r2.l = ___bss_stop; | 247 | r2.l = ___bss_stop; |
270 | r2.h = ___bss_stop; | 248 | r2.h = ___bss_stop; |
271 | r2 = r2 - r1; | 249 | call __init_clear_bss |
272 | r2 >>= 2; | ||
273 | p1 = r1; | ||
274 | p2 = r2; | ||
275 | lsetup (.L_clear_bss, .L_clear_bss) lc0 = p2; | ||
276 | .L_clear_bss: | ||
277 | [p1++] = r0; | ||
278 | 250 | ||
279 | /* In case there is a NULL pointer reference, | 251 | /* In case there is a NULL pointer reference, |
280 | * zero out region before stext | 252 | * zero out region before stext |