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