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