]> git.ipfire.org Git - thirdparty/u-boot.git/blob - arch/powerpc/cpu/mpc86xx/start.S
Add GPL-2.0+ SPDX-License-Identifier to source files
[thirdparty/u-boot.git] / arch / powerpc / cpu / mpc86xx / start.S
1 /*
2 * Copyright 2004, 2007, 2011 Freescale Semiconductor.
3 * Srikanth Srinivasan <srikanth.srinivaan@freescale.com>
4 *
5 * SPDX-License-Identifier: GPL-2.0+
6 */
7
8 /* U-Boot - Startup Code for 86xx PowerPC based Embedded Boards
9 *
10 *
11 * The processor starts at 0xfff00100 and the code is executed
12 * from flash. The code is organized to be at an other address
13 * in memory, but as long we don't jump around before relocating.
14 * board_init lies at a quite high address and when the cpu has
15 * jumped there, everything is ok.
16 */
17 #include <asm-offsets.h>
18 #include <config.h>
19 #include <mpc86xx.h>
20 #include <version.h>
21
22 #include <ppc_asm.tmpl>
23 #include <ppc_defs.h>
24
25 #include <asm/cache.h>
26 #include <asm/mmu.h>
27 #include <asm/u-boot.h>
28
29 /*
30 * Need MSR_DR | MSR_IR enabled to access I/O (printf) in exceptions
31 */
32
33 /*
34 * Set up GOT: Global Offset Table
35 *
36 * Use r12 to access the GOT
37 */
38 START_GOT
39 GOT_ENTRY(_GOT2_TABLE_)
40 GOT_ENTRY(_FIXUP_TABLE_)
41
42 GOT_ENTRY(_start)
43 GOT_ENTRY(_start_of_vectors)
44 GOT_ENTRY(_end_of_vectors)
45 GOT_ENTRY(transfer_to_handler)
46
47 GOT_ENTRY(__init_end)
48 GOT_ENTRY(__bss_end)
49 GOT_ENTRY(__bss_start)
50 END_GOT
51
52 /*
53 * r3 - 1st arg to board_init(): IMMP pointer
54 * r4 - 2nd arg to board_init(): boot flag
55 */
56 .text
57 .long 0x27051956 /* U-Boot Magic Number */
58 .globl version_string
59 version_string:
60 .ascii U_BOOT_VERSION_STRING, "\0"
61
62 . = EXC_OFF_SYS_RESET
63 .globl _start
64 _start:
65 b boot_cold
66
67 /* the boot code is located below the exception table */
68
69 .globl _start_of_vectors
70 _start_of_vectors:
71
72 /* Machine check */
73 STD_EXCEPTION(0x200, MachineCheck, MachineCheckException)
74
75 /* Data Storage exception. */
76 STD_EXCEPTION(0x300, DataStorage, UnknownException)
77
78 /* Instruction Storage exception. */
79 STD_EXCEPTION(0x400, InstStorage, UnknownException)
80
81 /* External Interrupt exception. */
82 STD_EXCEPTION(0x500, ExtInterrupt, external_interrupt)
83
84 /* Alignment exception. */
85 . = 0x600
86 Alignment:
87 EXCEPTION_PROLOG(SRR0, SRR1)
88 mfspr r4,DAR
89 stw r4,_DAR(r21)
90 mfspr r5,DSISR
91 stw r5,_DSISR(r21)
92 addi r3,r1,STACK_FRAME_OVERHEAD
93 EXC_XFER_TEMPLATE(Alignment, AlignmentException, MSR_KERNEL, COPY_EE)
94
95 /* Program check exception */
96 . = 0x700
97 ProgramCheck:
98 EXCEPTION_PROLOG(SRR0, SRR1)
99 addi r3,r1,STACK_FRAME_OVERHEAD
100 EXC_XFER_TEMPLATE(ProgramCheck, ProgramCheckException,
101 MSR_KERNEL, COPY_EE)
102
103 STD_EXCEPTION(0x800, FPUnavailable, UnknownException)
104
105 /* I guess we could implement decrementer, and may have
106 * to someday for timekeeping.
107 */
108 STD_EXCEPTION(0x900, Decrementer, timer_interrupt)
109 STD_EXCEPTION(0xa00, Trap_0a, UnknownException)
110 STD_EXCEPTION(0xb00, Trap_0b, UnknownException)
111 STD_EXCEPTION(0xc00, SystemCall, UnknownException)
112 STD_EXCEPTION(0xd00, SingleStep, UnknownException)
113 STD_EXCEPTION(0xe00, Trap_0e, UnknownException)
114 STD_EXCEPTION(0xf00, Trap_0f, UnknownException)
115 STD_EXCEPTION(0x1000, SoftEmu, SoftEmuException)
116 STD_EXCEPTION(0x1100, InstructionTLBMiss, UnknownException)
117 STD_EXCEPTION(0x1200, DataTLBMiss, UnknownException)
118 STD_EXCEPTION(0x1300, InstructionTLBError, UnknownException)
119 STD_EXCEPTION(0x1400, DataTLBError, UnknownException)
120 STD_EXCEPTION(0x1500, Reserved5, UnknownException)
121 STD_EXCEPTION(0x1600, Reserved6, UnknownException)
122 STD_EXCEPTION(0x1700, Reserved7, UnknownException)
123 STD_EXCEPTION(0x1800, Reserved8, UnknownException)
124 STD_EXCEPTION(0x1900, Reserved9, UnknownException)
125 STD_EXCEPTION(0x1a00, ReservedA, UnknownException)
126 STD_EXCEPTION(0x1b00, ReservedB, UnknownException)
127 STD_EXCEPTION(0x1c00, DataBreakpoint, UnknownException)
128 STD_EXCEPTION(0x1d00, InstructionBreakpoint, UnknownException)
129 STD_EXCEPTION(0x1e00, PeripheralBreakpoint, UnknownException)
130 STD_EXCEPTION(0x1f00, DevPortBreakpoint, UnknownException)
131
132 .globl _end_of_vectors
133 _end_of_vectors:
134
135 . = 0x2000
136
137 boot_cold:
138 /*
139 * NOTE: Only Cpu 0 will ever come here. Other cores go to an
140 * address specified by the BPTR
141 */
142 1:
143 #ifdef CONFIG_SYS_RAMBOOT
144 /* disable everything */
145 li r0, 0
146 mtspr HID0, r0
147 sync
148 mtmsr 0
149 #endif
150
151 /* Invalidate BATs */
152 bl invalidate_bats
153 sync
154 /* Invalidate all of TLB before MMU turn on */
155 bl clear_tlbs
156 sync
157
158 #ifdef CONFIG_SYS_L2
159 /* init the L2 cache */
160 lis r3, L2_INIT@h
161 ori r3, r3, L2_INIT@l
162 mtspr l2cr, r3
163 /* invalidate the L2 cache */
164 bl l2cache_invalidate
165 sync
166 #endif
167
168 /*
169 * Calculate absolute address in FLASH and jump there
170 *------------------------------------------------------*/
171 lis r3, CONFIG_SYS_MONITOR_BASE_EARLY@h
172 ori r3, r3, CONFIG_SYS_MONITOR_BASE_EARLY@l
173 addi r3, r3, in_flash - _start + EXC_OFF_SYS_RESET
174 mtlr r3
175 blr
176
177 in_flash:
178 /* let the C-code set up the rest */
179 /* */
180 /* Be careful to keep code relocatable ! */
181 /*------------------------------------------------------*/
182 /* perform low-level init */
183
184 /* enable extended addressing */
185 bl enable_ext_addr
186
187 /* setup the bats */
188 bl early_bats
189
190 /*
191 * Cache must be enabled here for stack-in-cache trick.
192 * This means we need to enable the BATS.
193 * Cache should be turned on after BATs, since by default
194 * everything is write-through.
195 */
196
197 /* enable address translation */
198 mfmsr r5
199 ori r5, r5, (MSR_IR | MSR_DR)
200 lis r3,addr_trans_enabled@h
201 ori r3, r3, addr_trans_enabled@l
202 mtspr SPRN_SRR0,r3
203 mtspr SPRN_SRR1,r5
204 rfi
205
206 addr_trans_enabled:
207 /* enable and invalidate the data cache */
208 /* bl l1dcache_enable */
209 bl dcache_enable
210 sync
211
212 #if 1
213 bl icache_enable
214 #endif
215
216 #ifdef CONFIG_SYS_INIT_RAM_LOCK
217 bl lock_ram_in_cache
218 sync
219 #endif
220
221 #if (CONFIG_SYS_CCSRBAR_DEFAULT != CONFIG_SYS_CCSRBAR)
222 bl setup_ccsrbar
223 #endif
224
225 /* set up the stack pointer in our newly created
226 * cache-ram (r1) */
227 lis r1, (CONFIG_SYS_INIT_RAM_ADDR + CONFIG_SYS_GBL_DATA_OFFSET)@h
228 ori r1, r1, (CONFIG_SYS_INIT_RAM_ADDR + CONFIG_SYS_GBL_DATA_OFFSET)@l
229
230 li r0, 0 /* Make room for stack frame header and */
231 stwu r0, -4(r1) /* clear final stack frame so that */
232 stwu r0, -4(r1) /* stack backtraces terminate cleanly */
233
234 GET_GOT /* initialize GOT access */
235
236 /* run low-level CPU init code (from Flash) */
237 bl cpu_init_f
238 sync
239
240 #ifdef RUN_DIAG
241
242 /* Load PX_AUX register address in r4 */
243 lis r4, PIXIS_BASE@h
244 ori r4, r4, 0x6
245 /* Load contents of PX_AUX in r3 bits 24 to 31*/
246 lbz r3, 0(r4)
247
248 /* Mask and obtain the bit in r3 */
249 rlwinm. r3, r3, 0, 24, 24
250 /* If not zero, jump and continue with u-boot */
251 bne diag_done
252
253 /* Load back contents of PX_AUX in r3 bits 24 to 31 */
254 lbz r3, 0(r4)
255 /* Set the MSB of the register value */
256 ori r3, r3, 0x80
257 /* Write value in r3 back to PX_AUX */
258 stb r3, 0(r4)
259
260 /* Get the address to jump to in r3*/
261 lis r3, CONFIG_SYS_DIAG_ADDR@h
262 ori r3, r3, CONFIG_SYS_DIAG_ADDR@l
263
264 /* Load the LR with the branch address */
265 mtlr r3
266
267 /* Branch to diagnostic */
268 blr
269
270 diag_done:
271 #endif
272
273 /* bl l2cache_enable */
274
275 /* run 1st part of board init code (from Flash) */
276 bl board_init_f
277 sync
278
279 /* NOTREACHED - board_init_f() does not return */
280
281 .globl invalidate_bats
282 invalidate_bats:
283
284 li r0, 0
285 /* invalidate BATs */
286 mtspr IBAT0U, r0
287 mtspr IBAT1U, r0
288 mtspr IBAT2U, r0
289 mtspr IBAT3U, r0
290 mtspr IBAT4U, r0
291 mtspr IBAT5U, r0
292 mtspr IBAT6U, r0
293 mtspr IBAT7U, r0
294
295 isync
296 mtspr DBAT0U, r0
297 mtspr DBAT1U, r0
298 mtspr DBAT2U, r0
299 mtspr DBAT3U, r0
300 mtspr DBAT4U, r0
301 mtspr DBAT5U, r0
302 mtspr DBAT6U, r0
303 mtspr DBAT7U, r0
304
305 isync
306 sync
307 blr
308
309 #define CONFIG_BAT_PAIR(n) \
310 lis r4, CONFIG_SYS_IBAT##n##L@h; \
311 ori r4, r4, CONFIG_SYS_IBAT##n##L@l; \
312 lis r3, CONFIG_SYS_IBAT##n##U@h; \
313 ori r3, r3, CONFIG_SYS_IBAT##n##U@l; \
314 mtspr IBAT##n##L, r4; \
315 mtspr IBAT##n##U, r3; \
316 lis r4, CONFIG_SYS_DBAT##n##L@h; \
317 ori r4, r4, CONFIG_SYS_DBAT##n##L@l; \
318 lis r3, CONFIG_SYS_DBAT##n##U@h; \
319 ori r3, r3, CONFIG_SYS_DBAT##n##U@l; \
320 mtspr DBAT##n##L, r4; \
321 mtspr DBAT##n##U, r3;
322
323 /*
324 * setup_bats:
325 *
326 * Set up the final BAT registers now that setup is done.
327 *
328 * Assumes that:
329 * 1) Address translation is enabled upon entry
330 * 2) The boot rom is still accessible via 1:1 translation
331 */
332 .globl setup_bats
333 setup_bats:
334 mflr r5
335 sync
336
337 /*
338 * When we disable address translation, we will get 1:1 (VA==PA)
339 * translation. The only place we know for sure is safe for that is
340 * the bootrom where we originally started out. Pop back into there.
341 */
342 lis r4, CONFIG_SYS_MONITOR_BASE_EARLY@h
343 ori r4, r4, CONFIG_SYS_MONITOR_BASE_EARLY@l
344 addi r4, r4, trans_disabled - _start + EXC_OFF_SYS_RESET
345
346 /* disable address translation */
347 mfmsr r3
348 rlwinm r3, r3, 0, 28, 25
349 mtspr SRR0, r4
350 mtspr SRR1, r3
351 rfi
352
353 trans_disabled:
354 #if defined(CONFIG_SYS_DBAT0U) && defined(CONFIG_SYS_DBAT0L) \
355 && defined(CONFIG_SYS_IBAT0U) && defined(CONFIG_SYS_IBAT0L)
356 CONFIG_BAT_PAIR(0)
357 #endif
358 CONFIG_BAT_PAIR(1)
359 CONFIG_BAT_PAIR(2)
360 CONFIG_BAT_PAIR(3)
361 CONFIG_BAT_PAIR(4)
362 CONFIG_BAT_PAIR(5)
363 CONFIG_BAT_PAIR(6)
364 CONFIG_BAT_PAIR(7)
365
366 sync
367 isync
368
369 /* Turn translation back on and return */
370 mfmsr r3
371 ori r3, r3, (MSR_IR | MSR_DR)
372 mtspr SPRN_SRR0,r5
373 mtspr SPRN_SRR1,r3
374 rfi
375
376 /*
377 * early_bats:
378 *
379 * Set up bats needed early on - this is usually the BAT for the
380 * stack-in-cache, the Flash, and CCSR space
381 */
382 .globl early_bats
383 early_bats:
384 /* IBAT 3 */
385 lis r4, CONFIG_SYS_IBAT3L@h
386 ori r4, r4, CONFIG_SYS_IBAT3L@l
387 lis r3, CONFIG_SYS_IBAT3U@h
388 ori r3, r3, CONFIG_SYS_IBAT3U@l
389 mtspr IBAT3L, r4
390 mtspr IBAT3U, r3
391 isync
392
393 /* DBAT 3 */
394 lis r4, CONFIG_SYS_DBAT3L@h
395 ori r4, r4, CONFIG_SYS_DBAT3L@l
396 lis r3, CONFIG_SYS_DBAT3U@h
397 ori r3, r3, CONFIG_SYS_DBAT3U@l
398 mtspr DBAT3L, r4
399 mtspr DBAT3U, r3
400 isync
401
402 /* IBAT 5 */
403 lis r4, CONFIG_SYS_IBAT5L@h
404 ori r4, r4, CONFIG_SYS_IBAT5L@l
405 lis r3, CONFIG_SYS_IBAT5U@h
406 ori r3, r3, CONFIG_SYS_IBAT5U@l
407 mtspr IBAT5L, r4
408 mtspr IBAT5U, r3
409 isync
410
411 /* DBAT 5 */
412 lis r4, CONFIG_SYS_DBAT5L@h
413 ori r4, r4, CONFIG_SYS_DBAT5L@l
414 lis r3, CONFIG_SYS_DBAT5U@h
415 ori r3, r3, CONFIG_SYS_DBAT5U@l
416 mtspr DBAT5L, r4
417 mtspr DBAT5U, r3
418 isync
419
420 /* IBAT 6 */
421 lis r4, CONFIG_SYS_IBAT6L_EARLY@h
422 ori r4, r4, CONFIG_SYS_IBAT6L_EARLY@l
423 lis r3, CONFIG_SYS_IBAT6U_EARLY@h
424 ori r3, r3, CONFIG_SYS_IBAT6U_EARLY@l
425 mtspr IBAT6L, r4
426 mtspr IBAT6U, r3
427 isync
428
429 /* DBAT 6 */
430 lis r4, CONFIG_SYS_DBAT6L_EARLY@h
431 ori r4, r4, CONFIG_SYS_DBAT6L_EARLY@l
432 lis r3, CONFIG_SYS_DBAT6U_EARLY@h
433 ori r3, r3, CONFIG_SYS_DBAT6U_EARLY@l
434 mtspr DBAT6L, r4
435 mtspr DBAT6U, r3
436 isync
437
438 #if(CONFIG_SYS_CCSRBAR_DEFAULT != CONFIG_SYS_CCSRBAR)
439 /* IBAT 7 */
440 lis r4, CONFIG_SYS_CCSR_DEFAULT_IBATL@h
441 ori r4, r4, CONFIG_SYS_CCSR_DEFAULT_IBATL@l
442 lis r3, CONFIG_SYS_CCSR_DEFAULT_IBATU@h
443 ori r3, r3, CONFIG_SYS_CCSR_DEFAULT_IBATU@l
444 mtspr IBAT7L, r4
445 mtspr IBAT7U, r3
446 isync
447
448 /* DBAT 7 */
449 lis r4, CONFIG_SYS_CCSR_DEFAULT_DBATL@h
450 ori r4, r4, CONFIG_SYS_CCSR_DEFAULT_DBATL@l
451 lis r3, CONFIG_SYS_CCSR_DEFAULT_DBATU@h
452 ori r3, r3, CONFIG_SYS_CCSR_DEFAULT_DBATU@l
453 mtspr DBAT7L, r4
454 mtspr DBAT7U, r3
455 isync
456 #endif
457 blr
458
459 .globl clear_tlbs
460 clear_tlbs:
461 addis r3, 0, 0x0000
462 addis r5, 0, 0x4
463 isync
464 tlblp:
465 tlbie r3
466 sync
467 addi r3, r3, 0x1000
468 cmp 0, 0, r3, r5
469 blt tlblp
470 blr
471
472 .globl disable_addr_trans
473 disable_addr_trans:
474 /* disable address translation */
475 mflr r4
476 mfmsr r3
477 andi. r0, r3, (MSR_IR | MSR_DR)
478 beqlr
479 andc r3, r3, r0
480 mtspr SRR0, r4
481 mtspr SRR1, r3
482 rfi
483
484 /*
485 * This code finishes saving the registers to the exception frame
486 * and jumps to the appropriate handler for the exception.
487 * Register r21 is pointer into trap frame, r1 has new stack pointer.
488 */
489 .globl transfer_to_handler
490 transfer_to_handler:
491 stw r22,_NIP(r21)
492 lis r22,MSR_POW@h
493 andc r23,r23,r22
494 stw r23,_MSR(r21)
495 SAVE_GPR(7, r21)
496 SAVE_4GPRS(8, r21)
497 SAVE_8GPRS(12, r21)
498 SAVE_8GPRS(24, r21)
499 mflr r23
500 andi. r24,r23,0x3f00 /* get vector offset */
501 stw r24,TRAP(r21)
502 li r22,0
503 stw r22,RESULT(r21)
504 mtspr SPRG2,r22 /* r1 is now kernel sp */
505 lwz r24,0(r23) /* virtual address of handler */
506 lwz r23,4(r23) /* where to go when done */
507 mtspr SRR0,r24
508 mtspr SRR1,r20
509 mtlr r23
510 SYNC
511 rfi /* jump to handler, enable MMU */
512
513 int_return:
514 mfmsr r28 /* Disable interrupts */
515 li r4,0
516 ori r4,r4,MSR_EE
517 andc r28,r28,r4
518 SYNC /* Some chip revs need this... */
519 mtmsr r28
520 SYNC
521 lwz r2,_CTR(r1)
522 lwz r0,_LINK(r1)
523 mtctr r2
524 mtlr r0
525 lwz r2,_XER(r1)
526 lwz r0,_CCR(r1)
527 mtspr XER,r2
528 mtcrf 0xFF,r0
529 REST_10GPRS(3, r1)
530 REST_10GPRS(13, r1)
531 REST_8GPRS(23, r1)
532 REST_GPR(31, r1)
533 lwz r2,_NIP(r1) /* Restore environment */
534 lwz r0,_MSR(r1)
535 mtspr SRR0,r2
536 mtspr SRR1,r0
537 lwz r0,GPR0(r1)
538 lwz r2,GPR2(r1)
539 lwz r1,GPR1(r1)
540 SYNC
541 rfi
542
543 .globl dc_read
544 dc_read:
545 blr
546
547 .globl get_pvr
548 get_pvr:
549 mfspr r3, PVR
550 blr
551
552 .globl get_svr
553 get_svr:
554 mfspr r3, SVR
555 blr
556
557
558 /*
559 * Function: in8
560 * Description: Input 8 bits
561 */
562 .globl in8
563 in8:
564 lbz r3,0x0000(r3)
565 blr
566
567 /*
568 * Function: out8
569 * Description: Output 8 bits
570 */
571 .globl out8
572 out8:
573 stb r4,0x0000(r3)
574 blr
575
576 /*
577 * Function: out16
578 * Description: Output 16 bits
579 */
580 .globl out16
581 out16:
582 sth r4,0x0000(r3)
583 blr
584
585 /*
586 * Function: out16r
587 * Description: Byte reverse and output 16 bits
588 */
589 .globl out16r
590 out16r:
591 sthbrx r4,r0,r3
592 blr
593
594 /*
595 * Function: out32
596 * Description: Output 32 bits
597 */
598 .globl out32
599 out32:
600 stw r4,0x0000(r3)
601 blr
602
603 /*
604 * Function: out32r
605 * Description: Byte reverse and output 32 bits
606 */
607 .globl out32r
608 out32r:
609 stwbrx r4,r0,r3
610 blr
611
612 /*
613 * Function: in16
614 * Description: Input 16 bits
615 */
616 .globl in16
617 in16:
618 lhz r3,0x0000(r3)
619 blr
620
621 /*
622 * Function: in16r
623 * Description: Input 16 bits and byte reverse
624 */
625 .globl in16r
626 in16r:
627 lhbrx r3,r0,r3
628 blr
629
630 /*
631 * Function: in32
632 * Description: Input 32 bits
633 */
634 .globl in32
635 in32:
636 lwz 3,0x0000(3)
637 blr
638
639 /*
640 * Function: in32r
641 * Description: Input 32 bits and byte reverse
642 */
643 .globl in32r
644 in32r:
645 lwbrx r3,r0,r3
646 blr
647
648 /*
649 * void relocate_code (addr_sp, gd, addr_moni)
650 *
651 * This "function" does not return, instead it continues in RAM
652 * after relocating the monitor code.
653 *
654 * r3 = dest
655 * r4 = src
656 * r5 = length in bytes
657 * r6 = cachelinesize
658 */
659 .globl relocate_code
660 relocate_code:
661
662 mr r1, r3 /* Set new stack pointer */
663 mr r9, r4 /* Save copy of Global Data pointer */
664 mr r10, r5 /* Save copy of Destination Address */
665
666 GET_GOT
667 mr r3, r5 /* Destination Address */
668 lis r4, CONFIG_SYS_MONITOR_BASE@h /* Source Address */
669 ori r4, r4, CONFIG_SYS_MONITOR_BASE@l
670 lwz r5, GOT(__init_end)
671 sub r5, r5, r4
672 li r6, CONFIG_SYS_CACHELINE_SIZE /* Cache Line Size */
673
674 /*
675 * Fix GOT pointer:
676 *
677 * New GOT-PTR = (old GOT-PTR - CONFIG_SYS_MONITOR_BASE) + Destination Address
678 *
679 * Offset:
680 */
681 sub r15, r10, r4
682
683 /* First our own GOT */
684 add r12, r12, r15
685 /* then the one used by the C code */
686 add r30, r30, r15
687
688 /*
689 * Now relocate code
690 */
691 cmplw cr1,r3,r4
692 addi r0,r5,3
693 srwi. r0,r0,2
694 beq cr1,4f /* In place copy is not necessary */
695 beq 7f /* Protect against 0 count */
696 mtctr r0
697 bge cr1,2f
698
699 la r8,-4(r4)
700 la r7,-4(r3)
701 1: lwzu r0,4(r8)
702 stwu r0,4(r7)
703 bdnz 1b
704 b 4f
705
706 2: slwi r0,r0,2
707 add r8,r4,r0
708 add r7,r3,r0
709 3: lwzu r0,-4(r8)
710 stwu r0,-4(r7)
711 bdnz 3b
712 /*
713 * Now flush the cache: note that we must start from a cache aligned
714 * address. Otherwise we might miss one cache line.
715 */
716 4: cmpwi r6,0
717 add r5,r3,r5
718 beq 7f /* Always flush prefetch queue in any case */
719 subi r0,r6,1
720 andc r3,r3,r0
721 mr r4,r3
722 5: dcbst 0,r4
723 add r4,r4,r6
724 cmplw r4,r5
725 blt 5b
726 sync /* Wait for all dcbst to complete on bus */
727 mr r4,r3
728 6: icbi 0,r4
729 add r4,r4,r6
730 cmplw r4,r5
731 blt 6b
732 7: sync /* Wait for all icbi to complete on bus */
733 isync
734
735 /*
736 * We are done. Do not return, instead branch to second part of board
737 * initialization, now running from RAM.
738 */
739 addi r0, r10, in_ram - _start + EXC_OFF_SYS_RESET
740 mtlr r0
741 blr
742
743 in_ram:
744 /*
745 * Relocation Function, r12 point to got2+0x8000
746 *
747 * Adjust got2 pointers, no need to check for 0, this code
748 * already puts a few entries in the table.
749 */
750 li r0,__got2_entries@sectoff@l
751 la r3,GOT(_GOT2_TABLE_)
752 lwz r11,GOT(_GOT2_TABLE_)
753 mtctr r0
754 sub r11,r3,r11
755 addi r3,r3,-4
756 1: lwzu r0,4(r3)
757 cmpwi r0,0
758 beq- 2f
759 add r0,r0,r11
760 stw r0,0(r3)
761 2: bdnz 1b
762
763 /*
764 * Now adjust the fixups and the pointers to the fixups
765 * in case we need to move ourselves again.
766 */
767 li r0,__fixup_entries@sectoff@l
768 lwz r3,GOT(_FIXUP_TABLE_)
769 cmpwi r0,0
770 mtctr r0
771 addi r3,r3,-4
772 beq 4f
773 3: lwzu r4,4(r3)
774 lwzux r0,r4,r11
775 cmpwi r0,0
776 add r0,r0,r11
777 stw r4,0(r3)
778 beq- 5f
779 stw r0,0(r4)
780 5: bdnz 3b
781 4:
782 /* clear_bss: */
783 /*
784 * Now clear BSS segment
785 */
786 lwz r3,GOT(__bss_start)
787 lwz r4,GOT(__bss_end)
788
789 cmplw 0, r3, r4
790 beq 6f
791
792 li r0, 0
793 5:
794 stw r0, 0(r3)
795 addi r3, r3, 4
796 cmplw 0, r3, r4
797 bne 5b
798 6:
799 mr r3, r9 /* Init Date pointer */
800 mr r4, r10 /* Destination Address */
801 bl board_init_r
802
803 /* not reached - end relocate_code */
804 /*-----------------------------------------------------------------------*/
805
806 /*
807 * Copy exception vector code to low memory
808 *
809 * r3: dest_addr
810 * r7: source address, r8: end address, r9: target address
811 */
812 .globl trap_init
813 trap_init:
814 mflr r4 /* save link register */
815 GET_GOT
816 lwz r7, GOT(_start)
817 lwz r8, GOT(_end_of_vectors)
818
819 li r9, 0x100 /* reset vector always at 0x100 */
820
821 cmplw 0, r7, r8
822 bgelr /* return if r7>=r8 - just in case */
823 1:
824 lwz r0, 0(r7)
825 stw r0, 0(r9)
826 addi r7, r7, 4
827 addi r9, r9, 4
828 cmplw 0, r7, r8
829 bne 1b
830
831 /*
832 * relocate `hdlr' and `int_return' entries
833 */
834 li r7, .L_MachineCheck - _start + EXC_OFF_SYS_RESET
835 li r8, Alignment - _start + EXC_OFF_SYS_RESET
836 2:
837 bl trap_reloc
838 addi r7, r7, 0x100 /* next exception vector */
839 cmplw 0, r7, r8
840 blt 2b
841
842 li r7, .L_Alignment - _start + EXC_OFF_SYS_RESET
843 bl trap_reloc
844
845 li r7, .L_ProgramCheck - _start + EXC_OFF_SYS_RESET
846 bl trap_reloc
847
848 li r7, .L_FPUnavailable - _start + EXC_OFF_SYS_RESET
849 li r8, SystemCall - _start + EXC_OFF_SYS_RESET
850 3:
851 bl trap_reloc
852 addi r7, r7, 0x100 /* next exception vector */
853 cmplw 0, r7, r8
854 blt 3b
855
856 li r7, .L_SingleStep - _start + EXC_OFF_SYS_RESET
857 li r8, _end_of_vectors - _start + EXC_OFF_SYS_RESET
858 4:
859 bl trap_reloc
860 addi r7, r7, 0x100 /* next exception vector */
861 cmplw 0, r7, r8
862 blt 4b
863
864 /* enable execptions from RAM vectors */
865 mfmsr r7
866 li r8,MSR_IP
867 andc r7,r7,r8
868 ori r7,r7,MSR_ME /* Enable Machine Check */
869 mtmsr r7
870
871 mtlr r4 /* restore link register */
872 blr
873
874 .globl enable_ext_addr
875 enable_ext_addr:
876 mfspr r0, HID0
877 lis r0, (HID0_HIGH_BAT_EN | HID0_XBSEN | HID0_XAEN)@h
878 ori r0, r0, (HID0_HIGH_BAT_EN | HID0_XBSEN | HID0_XAEN)@l
879 mtspr HID0, r0
880 sync
881 isync
882 blr
883
884 #if (CONFIG_SYS_CCSRBAR_DEFAULT != CONFIG_SYS_CCSRBAR)
885 .globl setup_ccsrbar
886 setup_ccsrbar:
887 /* Special sequence needed to update CCSRBAR itself */
888 lis r4, CONFIG_SYS_CCSRBAR_DEFAULT@h
889 ori r4, r4, CONFIG_SYS_CCSRBAR_DEFAULT@l
890
891 lis r5, CONFIG_SYS_CCSRBAR_PHYS_LOW@h
892 ori r5, r5, CONFIG_SYS_CCSRBAR_PHYS_LOW@l
893 srwi r5,r5,12
894 li r6, CONFIG_SYS_CCSRBAR_PHYS_HIGH@l
895 rlwimi r5,r6,20,8,11
896 stw r5, 0(r4) /* Store physical value of CCSR */
897 isync
898
899 lis r5, CONFIG_SYS_TEXT_BASE@h
900 ori r5,r5,CONFIG_SYS_TEXT_BASE@l
901 lwz r5, 0(r5)
902 isync
903
904 /* Use VA of CCSR to do read */
905 lis r3, CONFIG_SYS_CCSRBAR@h
906 lwz r5, CONFIG_SYS_CCSRBAR@l(r3)
907 isync
908
909 blr
910 #endif
911
912 #ifdef CONFIG_SYS_INIT_RAM_LOCK
913 lock_ram_in_cache:
914 /* Allocate Initial RAM in data cache.
915 */
916 lis r3, (CONFIG_SYS_INIT_RAM_ADDR & ~31)@h
917 ori r3, r3, (CONFIG_SYS_INIT_RAM_ADDR & ~31)@l
918 li r4, ((CONFIG_SYS_INIT_RAM_SIZE & ~31) + \
919 (CONFIG_SYS_INIT_RAM_ADDR & 31) + 31) / 32
920 mtctr r4
921 1:
922 dcbz r0, r3
923 addi r3, r3, 32
924 bdnz 1b
925 #if 1
926 /* Lock the data cache */
927 mfspr r0, HID0
928 ori r0, r0, 0x1000
929 sync
930 mtspr HID0, r0
931 sync
932 blr
933 #endif
934 #if 0
935 /* Lock the first way of the data cache */
936 mfspr r0, LDSTCR
937 ori r0, r0, 0x0080
938 #if defined(CONFIG_ALTIVEC)
939 dssall
940 #endif
941 sync
942 mtspr LDSTCR, r0
943 sync
944 isync
945 blr
946 #endif
947
948 .globl unlock_ram_in_cache
949 unlock_ram_in_cache:
950 /* invalidate the INIT_RAM section */
951 lis r3, (CONFIG_SYS_INIT_RAM_ADDR & ~31)@h
952 ori r3, r3, (CONFIG_SYS_INIT_RAM_ADDR & ~31)@l
953 li r4, ((CONFIG_SYS_INIT_RAM_SIZE & ~31) + \
954 (CONFIG_SYS_INIT_RAM_ADDR & 31) + 31) / 32
955 mtctr r4
956 1: icbi r0, r3
957 addi r3, r3, 32
958 bdnz 1b
959 sync /* Wait for all icbi to complete on bus */
960 isync
961 #if 1
962 /* Unlock the data cache and invalidate it */
963 mfspr r0, HID0
964 li r3,0x1000
965 andc r0,r0,r3
966 li r3,0x0400
967 or r0,r0,r3
968 sync
969 mtspr HID0, r0
970 sync
971 blr
972 #endif
973 #if 0
974 /* Unlock the first way of the data cache */
975 mfspr r0, LDSTCR
976 li r3,0x0080
977 andc r0,r0,r3
978 #ifdef CONFIG_ALTIVEC
979 dssall
980 #endif
981 sync
982 mtspr LDSTCR, r0
983 sync
984 isync
985 li r3,0x0400
986 or r0,r0,r3
987 sync
988 mtspr HID0, r0
989 sync
990 blr
991 #endif
992 #endif