]> git.ipfire.org Git - people/ms/u-boot.git/blob - arch/powerpc/cpu/mpc5xxx/start.S
Add GPL-2.0+ SPDX-License-Identifier to source files
[people/ms/u-boot.git] / arch / powerpc / cpu / mpc5xxx / start.S
1 /*
2 * Copyright (C) 1998 Dan Malek <dmalek@jlc.net>
3 * Copyright (C) 1999 Magnus Damm <kieraypc01.p.y.kie.era.ericsson.se>
4 * Copyright (C) 2000 - 2003 Wolfgang Denk <wd@denx.de>
5 *
6 * SPDX-License-Identifier: GPL-2.0+
7 */
8
9 /*
10 * U-Boot - Startup Code for MPC5xxx CPUs
11 */
12 #include <asm-offsets.h>
13 #include <config.h>
14 #include <mpc5xxx.h>
15 #include <version.h>
16
17 #define CONFIG_MPC5xxx 1 /* needed for Linux kernel header files */
18 #define _LINUX_CONFIG_H 1 /* avoid reading Linux autoconf.h file */
19
20 #include <ppc_asm.tmpl>
21 #include <ppc_defs.h>
22
23 #include <asm/cache.h>
24 #include <asm/mmu.h>
25 #include <asm/u-boot.h>
26
27 /* We don't want the MMU yet.
28 */
29 #undef MSR_KERNEL
30 /* Floating Point enable, Machine Check and Recoverable Interr. */
31 #ifdef DEBUG
32 #define MSR_KERNEL (MSR_FP|MSR_RI)
33 #else
34 #define MSR_KERNEL (MSR_FP|MSR_ME|MSR_RI)
35 #endif
36
37 #ifndef CONFIG_SPL_BUILD
38 /*
39 * Set up GOT: Global Offset Table
40 *
41 * Use r12 to access the GOT
42 */
43 START_GOT
44 GOT_ENTRY(_GOT2_TABLE_)
45 GOT_ENTRY(_FIXUP_TABLE_)
46
47 GOT_ENTRY(_start)
48 GOT_ENTRY(_start_of_vectors)
49 GOT_ENTRY(_end_of_vectors)
50 GOT_ENTRY(transfer_to_handler)
51
52 GOT_ENTRY(__init_end)
53 GOT_ENTRY(__bss_end)
54 GOT_ENTRY(__bss_start)
55 END_GOT
56 #endif
57
58 /*
59 * Version string
60 */
61 .data
62 .globl version_string
63 version_string:
64 .ascii U_BOOT_VERSION_STRING, "\0"
65
66 /*
67 * Exception vectors
68 */
69 .text
70 . = EXC_OFF_SYS_RESET
71 .globl _start
72 _start:
73
74 #if defined(CONFIG_SPL) && !defined(CONFIG_SPL_BUILD)
75 /*
76 * This is the entry of the real U-Boot from a board port
77 * that supports SPL booting on the MPC5200. We only need
78 * to call board_init_f() here. Everything else has already
79 * been done in the SPL u-boot version.
80 */
81 GET_GOT /* initialize GOT access */
82 bl board_init_f /* run 1st part of board init code (in Flash)*/
83 /* NOTREACHED - board_init_f() does not return */
84 #else
85 mfmsr r5 /* save msr contents */
86
87 /* Move CSBoot and adjust instruction pointer */
88 /*--------------------------------------------------------------*/
89
90 #if defined(CONFIG_SYS_LOWBOOT)
91 # if defined(CONFIG_SYS_RAMBOOT)
92 # error CONFIG_SYS_LOWBOOT is incompatible with CONFIG_SYS_RAMBOOT
93 # endif /* CONFIG_SYS_RAMBOOT */
94 lis r4, CONFIG_SYS_DEFAULT_MBAR@h
95 lis r3, START_REG(CONFIG_SYS_BOOTCS_START)@h
96 ori r3, r3, START_REG(CONFIG_SYS_BOOTCS_START)@l
97 stw r3, 0x4(r4) /* CS0 start */
98 lis r3, STOP_REG(CONFIG_SYS_BOOTCS_START, CONFIG_SYS_BOOTCS_SIZE)@h
99 ori r3, r3, STOP_REG(CONFIG_SYS_BOOTCS_START, CONFIG_SYS_BOOTCS_SIZE)@l
100 stw r3, 0x8(r4) /* CS0 stop */
101 lis r3, 0x02010000@h
102 ori r3, r3, 0x02010000@l
103 stw r3, 0x54(r4) /* CS0 and Boot enable */
104
105 lis r3, lowboot_reentry@h /* jump from bootlow address space (0x0000xxxx) */
106 ori r3, r3, lowboot_reentry@l /* to the address space the linker used */
107 mtlr r3
108 blr
109
110 lowboot_reentry:
111 lis r3, START_REG(CONFIG_SYS_BOOTCS_START)@h
112 ori r3, r3, START_REG(CONFIG_SYS_BOOTCS_START)@l
113 stw r3, 0x4c(r4) /* Boot start */
114 lis r3, STOP_REG(CONFIG_SYS_BOOTCS_START, CONFIG_SYS_BOOTCS_SIZE)@h
115 ori r3, r3, STOP_REG(CONFIG_SYS_BOOTCS_START, CONFIG_SYS_BOOTCS_SIZE)@l
116 stw r3, 0x50(r4) /* Boot stop */
117 lis r3, 0x02000001@h
118 ori r3, r3, 0x02000001@l
119 stw r3, 0x54(r4) /* Boot enable, CS0 disable */
120 #endif /* CONFIG_SYS_LOWBOOT */
121
122 #if defined(CONFIG_SYS_DEFAULT_MBAR) && !defined(CONFIG_SYS_RAMBOOT)
123 lis r3, CONFIG_SYS_MBAR@h
124 ori r3, r3, CONFIG_SYS_MBAR@l
125 /* MBAR is mirrored into the MBAR SPR */
126 mtspr MBAR,r3
127 rlwinm r3, r3, 16, 16, 31
128 lis r4, CONFIG_SYS_DEFAULT_MBAR@h
129 stw r3, 0(r4)
130 #endif /* CONFIG_SYS_DEFAULT_MBAR */
131
132 /* Initialise the MPC5xxx processor core */
133 /*--------------------------------------------------------------*/
134
135 bl init_5xxx_core
136
137 /* initialize some things that are hard to access from C */
138 /*--------------------------------------------------------------*/
139
140 /* set up stack in on-chip SRAM */
141 lis r3, CONFIG_SYS_INIT_RAM_ADDR@h
142 ori r3, r3, CONFIG_SYS_INIT_RAM_ADDR@l
143 ori r1, r3, CONFIG_SYS_INIT_SP_OFFSET
144 li r0, 0 /* Make room for stack frame header and */
145 stwu r0, -4(r1) /* clear final stack frame so that */
146 stwu r0, -4(r1) /* stack backtraces terminate cleanly */
147
148 /* let the C-code set up the rest */
149 /* */
150 /* Be careful to keep code relocatable ! */
151 /*--------------------------------------------------------------*/
152
153 #ifndef CONFIG_SPL_BUILD
154 GET_GOT /* initialize GOT access */
155 #endif
156
157 /* r3: IMMR */
158 bl cpu_init_f /* run low-level CPU init code (in Flash)*/
159
160 bl board_init_f /* run 1st part of board init code (in Flash)*/
161
162 /* NOTREACHED - board_init_f() does not return */
163 #endif
164
165 #ifndef CONFIG_SPL_BUILD
166 /*
167 * Vector Table
168 */
169
170 .globl _start_of_vectors
171 _start_of_vectors:
172
173 /* Machine check */
174 STD_EXCEPTION(0x200, MachineCheck, MachineCheckException)
175
176 /* Data Storage exception. */
177 STD_EXCEPTION(0x300, DataStorage, UnknownException)
178
179 /* Instruction Storage exception. */
180 STD_EXCEPTION(0x400, InstStorage, UnknownException)
181
182 /* External Interrupt exception. */
183 STD_EXCEPTION(0x500, ExtInterrupt, external_interrupt)
184
185 /* Alignment exception. */
186 . = 0x600
187 Alignment:
188 EXCEPTION_PROLOG(SRR0, SRR1)
189 mfspr r4,DAR
190 stw r4,_DAR(r21)
191 mfspr r5,DSISR
192 stw r5,_DSISR(r21)
193 addi r3,r1,STACK_FRAME_OVERHEAD
194 EXC_XFER_TEMPLATE(Alignment, AlignmentException, MSR_KERNEL, COPY_EE)
195
196 /* Program check exception */
197 . = 0x700
198 ProgramCheck:
199 EXCEPTION_PROLOG(SRR0, SRR1)
200 addi r3,r1,STACK_FRAME_OVERHEAD
201 EXC_XFER_TEMPLATE(ProgramCheck, ProgramCheckException,
202 MSR_KERNEL, COPY_EE)
203
204 STD_EXCEPTION(0x800, FPUnavailable, UnknownException)
205
206 /* I guess we could implement decrementer, and may have
207 * to someday for timekeeping.
208 */
209 STD_EXCEPTION(0x900, Decrementer, timer_interrupt)
210
211 STD_EXCEPTION(0xa00, Trap_0a, UnknownException)
212 STD_EXCEPTION(0xb00, Trap_0b, UnknownException)
213 STD_EXCEPTION(0xc00, SystemCall, UnknownException)
214 STD_EXCEPTION(0xd00, SingleStep, UnknownException)
215
216 STD_EXCEPTION(0xe00, Trap_0e, UnknownException)
217 STD_EXCEPTION(0xf00, Trap_0f, UnknownException)
218
219 STD_EXCEPTION(0x1000, InstructionTLBMiss, UnknownException)
220 STD_EXCEPTION(0x1100, DataLoadTLBMiss, UnknownException)
221 STD_EXCEPTION(0x1200, DataStoreTLBMiss, UnknownException)
222 #ifdef DEBUG
223 . = 0x1300
224 /*
225 * This exception occurs when the program counter matches the
226 * Instruction Address Breakpoint Register (IABR).
227 *
228 * I want the cpu to halt if this occurs so I can hunt around
229 * with the debugger and look at things.
230 *
231 * When DEBUG is defined, both machine check enable (in the MSR)
232 * and checkstop reset enable (in the reset mode register) are
233 * turned off and so a checkstop condition will result in the cpu
234 * halting.
235 *
236 * I force the cpu into a checkstop condition by putting an illegal
237 * instruction here (at least this is the theory).
238 *
239 * well - that didnt work, so just do an infinite loop!
240 */
241 1: b 1b
242 #else
243 STD_EXCEPTION(0x1300, InstructionBreakpoint, DebugException)
244 #endif
245 STD_EXCEPTION(0x1400, SMI, UnknownException)
246
247 STD_EXCEPTION(0x1500, Trap_15, UnknownException)
248 STD_EXCEPTION(0x1600, Trap_16, UnknownException)
249 STD_EXCEPTION(0x1700, Trap_17, UnknownException)
250 STD_EXCEPTION(0x1800, Trap_18, UnknownException)
251 STD_EXCEPTION(0x1900, Trap_19, UnknownException)
252 STD_EXCEPTION(0x1a00, Trap_1a, UnknownException)
253 STD_EXCEPTION(0x1b00, Trap_1b, UnknownException)
254 STD_EXCEPTION(0x1c00, Trap_1c, UnknownException)
255 STD_EXCEPTION(0x1d00, Trap_1d, UnknownException)
256 STD_EXCEPTION(0x1e00, Trap_1e, UnknownException)
257 STD_EXCEPTION(0x1f00, Trap_1f, UnknownException)
258 STD_EXCEPTION(0x2000, Trap_20, UnknownException)
259 STD_EXCEPTION(0x2100, Trap_21, UnknownException)
260 STD_EXCEPTION(0x2200, Trap_22, UnknownException)
261 STD_EXCEPTION(0x2300, Trap_23, UnknownException)
262 STD_EXCEPTION(0x2400, Trap_24, UnknownException)
263 STD_EXCEPTION(0x2500, Trap_25, UnknownException)
264 STD_EXCEPTION(0x2600, Trap_26, UnknownException)
265 STD_EXCEPTION(0x2700, Trap_27, UnknownException)
266 STD_EXCEPTION(0x2800, Trap_28, UnknownException)
267 STD_EXCEPTION(0x2900, Trap_29, UnknownException)
268 STD_EXCEPTION(0x2a00, Trap_2a, UnknownException)
269 STD_EXCEPTION(0x2b00, Trap_2b, UnknownException)
270 STD_EXCEPTION(0x2c00, Trap_2c, UnknownException)
271 STD_EXCEPTION(0x2d00, Trap_2d, UnknownException)
272 STD_EXCEPTION(0x2e00, Trap_2e, UnknownException)
273 STD_EXCEPTION(0x2f00, Trap_2f, UnknownException)
274
275
276 .globl _end_of_vectors
277 _end_of_vectors:
278
279 . = 0x3000
280
281 /*
282 * This code finishes saving the registers to the exception frame
283 * and jumps to the appropriate handler for the exception.
284 * Register r21 is pointer into trap frame, r1 has new stack pointer.
285 */
286 .globl transfer_to_handler
287 transfer_to_handler:
288 stw r22,_NIP(r21)
289 lis r22,MSR_POW@h
290 andc r23,r23,r22
291 stw r23,_MSR(r21)
292 SAVE_GPR(7, r21)
293 SAVE_4GPRS(8, r21)
294 SAVE_8GPRS(12, r21)
295 SAVE_8GPRS(24, r21)
296 mflr r23
297 andi. r24,r23,0x3f00 /* get vector offset */
298 stw r24,TRAP(r21)
299 li r22,0
300 stw r22,RESULT(r21)
301 lwz r24,0(r23) /* virtual address of handler */
302 lwz r23,4(r23) /* where to go when done */
303 mtspr SRR0,r24
304 mtspr SRR1,r20
305 mtlr r23
306 SYNC
307 rfi /* jump to handler, enable MMU */
308
309 int_return:
310 mfmsr r28 /* Disable interrupts */
311 li r4,0
312 ori r4,r4,MSR_EE
313 andc r28,r28,r4
314 SYNC /* Some chip revs need this... */
315 mtmsr r28
316 SYNC
317 lwz r2,_CTR(r1)
318 lwz r0,_LINK(r1)
319 mtctr r2
320 mtlr r0
321 lwz r2,_XER(r1)
322 lwz r0,_CCR(r1)
323 mtspr XER,r2
324 mtcrf 0xFF,r0
325 REST_10GPRS(3, r1)
326 REST_10GPRS(13, r1)
327 REST_8GPRS(23, r1)
328 REST_GPR(31, r1)
329 lwz r2,_NIP(r1) /* Restore environment */
330 lwz r0,_MSR(r1)
331 mtspr SRR0,r2
332 mtspr SRR1,r0
333 lwz r0,GPR0(r1)
334 lwz r2,GPR2(r1)
335 lwz r1,GPR1(r1)
336 SYNC
337 rfi
338 #endif /* CONFIG_SPL_BUILD */
339
340 /*
341 * This code initialises the MPC5xxx processor core
342 * (conforms to PowerPC 603e spec)
343 * Note: expects original MSR contents to be in r5.
344 */
345
346 .globl init_5xx_core
347 init_5xxx_core:
348
349 /* Initialize machine status; enable machine check interrupt */
350 /*--------------------------------------------------------------*/
351
352 li r3, MSR_KERNEL /* Set ME and RI flags */
353 rlwimi r3, r5, 0, 25, 25 /* preserve IP bit set by HRCW */
354 #ifdef DEBUG
355 rlwimi r3, r5, 0, 21, 22 /* debugger might set SE & BE bits */
356 #endif
357 SYNC /* Some chip revs need this... */
358 mtmsr r3
359 SYNC
360 mtspr SRR1, r3 /* Make SRR1 match MSR */
361
362 /* Initialize the Hardware Implementation-dependent Registers */
363 /* HID0 also contains cache control */
364 /*--------------------------------------------------------------*/
365
366 lis r3, CONFIG_SYS_HID0_INIT@h
367 ori r3, r3, CONFIG_SYS_HID0_INIT@l
368 SYNC
369 mtspr HID0, r3
370
371 lis r3, CONFIG_SYS_HID0_FINAL@h
372 ori r3, r3, CONFIG_SYS_HID0_FINAL@l
373 SYNC
374 mtspr HID0, r3
375
376 /* clear all BAT's */
377 /*--------------------------------------------------------------*/
378
379 li r0, 0
380 mtspr DBAT0U, r0
381 mtspr DBAT0L, r0
382 mtspr DBAT1U, r0
383 mtspr DBAT1L, r0
384 mtspr DBAT2U, r0
385 mtspr DBAT2L, r0
386 mtspr DBAT3U, r0
387 mtspr DBAT3L, r0
388 mtspr DBAT4U, r0
389 mtspr DBAT4L, r0
390 mtspr DBAT5U, r0
391 mtspr DBAT5L, r0
392 mtspr DBAT6U, r0
393 mtspr DBAT6L, r0
394 mtspr DBAT7U, r0
395 mtspr DBAT7L, r0
396 mtspr IBAT0U, r0
397 mtspr IBAT0L, r0
398 mtspr IBAT1U, r0
399 mtspr IBAT1L, r0
400 mtspr IBAT2U, r0
401 mtspr IBAT2L, r0
402 mtspr IBAT3U, r0
403 mtspr IBAT3L, r0
404 mtspr IBAT4U, r0
405 mtspr IBAT4L, r0
406 mtspr IBAT5U, r0
407 mtspr IBAT5L, r0
408 mtspr IBAT6U, r0
409 mtspr IBAT6L, r0
410 mtspr IBAT7U, r0
411 mtspr IBAT7L, r0
412 SYNC
413
414 /* invalidate all tlb's */
415 /* */
416 /* From the 603e User Manual: "The 603e provides the ability to */
417 /* invalidate a TLB entry. The TLB Invalidate Entry (tlbie) */
418 /* instruction invalidates the TLB entry indexed by the EA, and */
419 /* operates on both the instruction and data TLBs simultaneously*/
420 /* invalidating four TLB entries (both sets in each TLB). The */
421 /* index corresponds to bits 15-19 of the EA. To invalidate all */
422 /* entries within both TLBs, 32 tlbie instructions should be */
423 /* issued, incrementing this field by one each time." */
424 /* */
425 /* "Note that the tlbia instruction is not implemented on the */
426 /* 603e." */
427 /* */
428 /* bits 15-19 correspond to addresses 0x00000000 to 0x0001F000 */
429 /* incrementing by 0x1000 each time. The code below is sort of */
430 /* based on code in "flush_tlbs" from arch/powerpc/kernel/head.S */
431 /* */
432 /*--------------------------------------------------------------*/
433
434 li r3, 32
435 mtctr r3
436 li r3, 0
437 1: tlbie r3
438 addi r3, r3, 0x1000
439 bdnz 1b
440 SYNC
441
442 /* Done! */
443 /*--------------------------------------------------------------*/
444
445 blr
446
447 /* Cache functions.
448 *
449 * Note: requires that all cache bits in
450 * HID0 are in the low half word.
451 */
452 .globl icache_enable
453 icache_enable:
454 mfspr r3, HID0
455 ori r3, r3, HID0_ICE
456 lis r4, 0
457 ori r4, r4, HID0_ILOCK
458 andc r3, r3, r4
459 ori r4, r3, HID0_ICFI
460 isync
461 mtspr HID0, r4 /* sets enable and invalidate, clears lock */
462 isync
463 mtspr HID0, r3 /* clears invalidate */
464 blr
465
466 .globl icache_disable
467 icache_disable:
468 mfspr r3, HID0
469 lis r4, 0
470 ori r4, r4, HID0_ICE|HID0_ILOCK
471 andc r3, r3, r4
472 ori r4, r3, HID0_ICFI
473 isync
474 mtspr HID0, r4 /* sets invalidate, clears enable and lock */
475 isync
476 mtspr HID0, r3 /* clears invalidate */
477 blr
478
479 .globl icache_status
480 icache_status:
481 mfspr r3, HID0
482 rlwinm r3, r3, HID0_ICE_BITPOS + 1, 31, 31
483 blr
484
485 .globl dcache_enable
486 dcache_enable:
487 mfspr r3, HID0
488 ori r3, r3, HID0_DCE
489 lis r4, 0
490 ori r4, r4, HID0_DLOCK
491 andc r3, r3, r4
492 ori r4, r3, HID0_DCI
493 sync
494 mtspr HID0, r4 /* sets enable and invalidate, clears lock */
495 sync
496 mtspr HID0, r3 /* clears invalidate */
497 blr
498
499 .globl dcache_disable
500 dcache_disable:
501 mfspr r3, HID0
502 lis r4, 0
503 ori r4, r4, HID0_DCE|HID0_DLOCK
504 andc r3, r3, r4
505 ori r4, r3, HID0_DCI
506 sync
507 mtspr HID0, r4 /* sets invalidate, clears enable and lock */
508 sync
509 mtspr HID0, r3 /* clears invalidate */
510 blr
511
512 .globl dcache_status
513 dcache_status:
514 mfspr r3, HID0
515 rlwinm r3, r3, HID0_DCE_BITPOS + 1, 31, 31
516 blr
517
518 .globl get_svr
519 get_svr:
520 mfspr r3, SVR
521 blr
522
523 .globl get_pvr
524 get_pvr:
525 mfspr r3, PVR
526 blr
527
528 #ifndef CONFIG_SPL_BUILD
529 /*------------------------------------------------------------------------------*/
530
531 /*
532 * void relocate_code (addr_sp, gd, addr_moni)
533 *
534 * This "function" does not return, instead it continues in RAM
535 * after relocating the monitor code.
536 *
537 * r3 = dest
538 * r4 = src
539 * r5 = length in bytes
540 * r6 = cachelinesize
541 */
542 .globl relocate_code
543 relocate_code:
544 mr r1, r3 /* Set new stack pointer */
545 mr r9, r4 /* Save copy of Global Data pointer */
546 mr r10, r5 /* Save copy of Destination Address */
547
548 GET_GOT
549 mr r3, r5 /* Destination Address */
550 lis r4, CONFIG_SYS_MONITOR_BASE@h /* Source Address */
551 ori r4, r4, CONFIG_SYS_MONITOR_BASE@l
552 lwz r5, GOT(__init_end)
553 sub r5, r5, r4
554 li r6, CONFIG_SYS_CACHELINE_SIZE /* Cache Line Size */
555
556 /*
557 * Fix GOT pointer:
558 *
559 * New GOT-PTR = (old GOT-PTR - CONFIG_SYS_MONITOR_BASE) + Destination Address
560 *
561 * Offset:
562 */
563 sub r15, r10, r4
564
565 /* First our own GOT */
566 add r12, r12, r15
567 /* then the one used by the C code */
568 add r30, r30, r15
569
570 /*
571 * Now relocate code
572 */
573
574 cmplw cr1,r3,r4
575 addi r0,r5,3
576 srwi. r0,r0,2
577 beq cr1,4f /* In place copy is not necessary */
578 beq 7f /* Protect against 0 count */
579 mtctr r0
580 bge cr1,2f
581
582 la r8,-4(r4)
583 la r7,-4(r3)
584 1: lwzu r0,4(r8)
585 stwu r0,4(r7)
586 bdnz 1b
587 b 4f
588
589 2: slwi r0,r0,2
590 add r8,r4,r0
591 add r7,r3,r0
592 3: lwzu r0,-4(r8)
593 stwu r0,-4(r7)
594 bdnz 3b
595
596 /*
597 * Now flush the cache: note that we must start from a cache aligned
598 * address. Otherwise we might miss one cache line.
599 */
600 4: cmpwi r6,0
601 add r5,r3,r5
602 beq 7f /* Always flush prefetch queue in any case */
603 subi r0,r6,1
604 andc r3,r3,r0
605 mfspr r7,HID0 /* don't do dcbst if dcache is disabled */
606 rlwinm r7,r7,HID0_DCE_BITPOS+1,31,31
607 cmpwi r7,0
608 beq 9f
609 mr r4,r3
610 5: dcbst 0,r4
611 add r4,r4,r6
612 cmplw r4,r5
613 blt 5b
614 sync /* Wait for all dcbst to complete on bus */
615 9: mfspr r7,HID0 /* don't do icbi if icache is disabled */
616 rlwinm r7,r7,HID0_ICE_BITPOS+1,31,31
617 cmpwi r7,0
618 beq 7f
619 mr r4,r3
620 6: icbi 0,r4
621 add r4,r4,r6
622 cmplw r4,r5
623 blt 6b
624 7: sync /* Wait for all icbi to complete on bus */
625 isync
626
627 /*
628 * We are done. Do not return, instead branch to second part of board
629 * initialization, now running from RAM.
630 */
631
632 addi r0, r10, in_ram - _start + EXC_OFF_SYS_RESET
633 mtlr r0
634 blr
635
636 in_ram:
637
638 /*
639 * Relocation Function, r12 point to got2+0x8000
640 *
641 * Adjust got2 pointers, no need to check for 0, this code
642 * already puts a few entries in the table.
643 */
644 li r0,__got2_entries@sectoff@l
645 la r3,GOT(_GOT2_TABLE_)
646 lwz r11,GOT(_GOT2_TABLE_)
647 mtctr r0
648 sub r11,r3,r11
649 addi r3,r3,-4
650 1: lwzu r0,4(r3)
651 cmpwi r0,0
652 beq- 2f
653 add r0,r0,r11
654 stw r0,0(r3)
655 2: bdnz 1b
656
657 /*
658 * Now adjust the fixups and the pointers to the fixups
659 * in case we need to move ourselves again.
660 */
661 li r0,__fixup_entries@sectoff@l
662 lwz r3,GOT(_FIXUP_TABLE_)
663 cmpwi r0,0
664 mtctr r0
665 addi r3,r3,-4
666 beq 4f
667 3: lwzu r4,4(r3)
668 lwzux r0,r4,r11
669 cmpwi r0,0
670 add r0,r0,r11
671 stw r4,0(r3)
672 beq- 5f
673 stw r0,0(r4)
674 5: bdnz 3b
675 4:
676 clear_bss:
677 /*
678 * Now clear BSS segment
679 */
680 lwz r3,GOT(__bss_start)
681 lwz r4,GOT(__bss_end)
682
683 cmplw 0, r3, r4
684 beq 6f
685
686 li r0, 0
687 5:
688 stw r0, 0(r3)
689 addi r3, r3, 4
690 cmplw 0, r3, r4
691 bne 5b
692 6:
693
694 mr r3, r9 /* Global Data pointer */
695 mr r4, r10 /* Destination Address */
696 bl board_init_r
697
698 /*
699 * Copy exception vector code to low memory
700 *
701 * r3: dest_addr
702 * r7: source address, r8: end address, r9: target address
703 */
704 .globl trap_init
705 trap_init:
706 mflr r4 /* save link register */
707 GET_GOT
708 lwz r7, GOT(_start)
709 lwz r8, GOT(_end_of_vectors)
710
711 li r9, 0x100 /* reset vector always at 0x100 */
712
713 cmplw 0, r7, r8
714 bgelr /* return if r7>=r8 - just in case */
715 1:
716 lwz r0, 0(r7)
717 stw r0, 0(r9)
718 addi r7, r7, 4
719 addi r9, r9, 4
720 cmplw 0, r7, r8
721 bne 1b
722
723 /*
724 * relocate `hdlr' and `int_return' entries
725 */
726 li r7, .L_MachineCheck - _start + EXC_OFF_SYS_RESET
727 li r8, Alignment - _start + EXC_OFF_SYS_RESET
728 2:
729 bl trap_reloc
730 addi r7, r7, 0x100 /* next exception vector */
731 cmplw 0, r7, r8
732 blt 2b
733
734 li r7, .L_Alignment - _start + EXC_OFF_SYS_RESET
735 bl trap_reloc
736
737 li r7, .L_ProgramCheck - _start + EXC_OFF_SYS_RESET
738 bl trap_reloc
739
740 li r7, .L_FPUnavailable - _start + EXC_OFF_SYS_RESET
741 li r8, SystemCall - _start + EXC_OFF_SYS_RESET
742 3:
743 bl trap_reloc
744 addi r7, r7, 0x100 /* next exception vector */
745 cmplw 0, r7, r8
746 blt 3b
747
748 li r7, .L_SingleStep - _start + EXC_OFF_SYS_RESET
749 li r8, _end_of_vectors - _start + EXC_OFF_SYS_RESET
750 4:
751 bl trap_reloc
752 addi r7, r7, 0x100 /* next exception vector */
753 cmplw 0, r7, r8
754 blt 4b
755
756 mfmsr r3 /* now that the vectors have */
757 lis r7, MSR_IP@h /* relocated into low memory */
758 ori r7, r7, MSR_IP@l /* MSR[IP] can be turned off */
759 andc r3, r3, r7 /* (if it was on) */
760 SYNC /* Some chip revs need this... */
761 mtmsr r3
762 SYNC
763
764 mtlr r4 /* restore link register */
765 blr
766
767 #endif /* CONFIG_SPL_BUILD */