]> git.ipfire.org Git - people/ms/u-boot.git/blob - arch/powerpc/cpu/mpc86xx/start.S
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 #if defined(__pic__) && __pic__ == 1
259 /* Needed for upcoming -msingle-pic-base */
260 bl _GLOBAL_OFFSET_TABLE_@local-4
261 mflr r30
262 #endif
263 /* run low-level CPU init code (from Flash) */
264 bl cpu_init_f
265 sync
266
267 #ifdef RUN_DIAG
268
269 /* Load PX_AUX register address in r4 */
270 lis r4, PIXIS_BASE@h
271 ori r4, r4, 0x6
272 /* Load contents of PX_AUX in r3 bits 24 to 31*/
273 lbz r3, 0(r4)
274
275 /* Mask and obtain the bit in r3 */
276 rlwinm. r3, r3, 0, 24, 24
277 /* If not zero, jump and continue with u-boot */
278 bne diag_done
279
280 /* Load back contents of PX_AUX in r3 bits 24 to 31 */
281 lbz r3, 0(r4)
282 /* Set the MSB of the register value */
283 ori r3, r3, 0x80
284 /* Write value in r3 back to PX_AUX */
285 stb r3, 0(r4)
286
287 /* Get the address to jump to in r3*/
288 lis r3, CONFIG_SYS_DIAG_ADDR@h
289 ori r3, r3, CONFIG_SYS_DIAG_ADDR@l
290
291 /* Load the LR with the branch address */
292 mtlr r3
293
294 /* Branch to diagnostic */
295 blr
296
297 diag_done:
298 #endif
299
300 /* bl l2cache_enable */
301
302 /* run 1st part of board init code (from Flash) */
303 bl board_init_f
304 sync
305
306 /* NOTREACHED - board_init_f() does not return */
307
308 .globl invalidate_bats
309 invalidate_bats:
310
311 li r0, 0
312 /* invalidate BATs */
313 mtspr IBAT0U, r0
314 mtspr IBAT1U, r0
315 mtspr IBAT2U, r0
316 mtspr IBAT3U, r0
317 mtspr IBAT4U, r0
318 mtspr IBAT5U, r0
319 mtspr IBAT6U, r0
320 mtspr IBAT7U, r0
321
322 isync
323 mtspr DBAT0U, r0
324 mtspr DBAT1U, r0
325 mtspr DBAT2U, r0
326 mtspr DBAT3U, r0
327 mtspr DBAT4U, r0
328 mtspr DBAT5U, r0
329 mtspr DBAT6U, r0
330 mtspr DBAT7U, r0
331
332 isync
333 sync
334 blr
335
336 /*
337 * early_bats:
338 *
339 * Set up bats needed early on - this is usually the BAT for the
340 * stack-in-cache, the Flash, and CCSR space
341 */
342 .globl early_bats
343 early_bats:
344 /* IBAT 3 */
345 lis r4, CONFIG_SYS_IBAT3L@h
346 ori r4, r4, CONFIG_SYS_IBAT3L@l
347 lis r3, CONFIG_SYS_IBAT3U@h
348 ori r3, r3, CONFIG_SYS_IBAT3U@l
349 mtspr IBAT3L, r4
350 mtspr IBAT3U, r3
351 isync
352
353 /* DBAT 3 */
354 lis r4, CONFIG_SYS_DBAT3L@h
355 ori r4, r4, CONFIG_SYS_DBAT3L@l
356 lis r3, CONFIG_SYS_DBAT3U@h
357 ori r3, r3, CONFIG_SYS_DBAT3U@l
358 mtspr DBAT3L, r4
359 mtspr DBAT3U, r3
360 isync
361
362 /* IBAT 5 */
363 lis r4, CONFIG_SYS_IBAT5L@h
364 ori r4, r4, CONFIG_SYS_IBAT5L@l
365 lis r3, CONFIG_SYS_IBAT5U@h
366 ori r3, r3, CONFIG_SYS_IBAT5U@l
367 mtspr IBAT5L, r4
368 mtspr IBAT5U, r3
369 isync
370
371 /* DBAT 5 */
372 lis r4, CONFIG_SYS_DBAT5L@h
373 ori r4, r4, CONFIG_SYS_DBAT5L@l
374 lis r3, CONFIG_SYS_DBAT5U@h
375 ori r3, r3, CONFIG_SYS_DBAT5U@l
376 mtspr DBAT5L, r4
377 mtspr DBAT5U, r3
378 isync
379
380 /* IBAT 6 */
381 lis r4, CONFIG_SYS_IBAT6L_EARLY@h
382 ori r4, r4, CONFIG_SYS_IBAT6L_EARLY@l
383 lis r3, CONFIG_SYS_IBAT6U_EARLY@h
384 ori r3, r3, CONFIG_SYS_IBAT6U_EARLY@l
385 mtspr IBAT6L, r4
386 mtspr IBAT6U, r3
387 isync
388
389 /* DBAT 6 */
390 lis r4, CONFIG_SYS_DBAT6L_EARLY@h
391 ori r4, r4, CONFIG_SYS_DBAT6L_EARLY@l
392 lis r3, CONFIG_SYS_DBAT6U_EARLY@h
393 ori r3, r3, CONFIG_SYS_DBAT6U_EARLY@l
394 mtspr DBAT6L, r4
395 mtspr DBAT6U, r3
396 isync
397
398 #if(CONFIG_SYS_CCSRBAR_DEFAULT != CONFIG_SYS_CCSRBAR)
399 /* IBAT 7 */
400 lis r4, CONFIG_SYS_CCSR_DEFAULT_IBATL@h
401 ori r4, r4, CONFIG_SYS_CCSR_DEFAULT_IBATL@l
402 lis r3, CONFIG_SYS_CCSR_DEFAULT_IBATU@h
403 ori r3, r3, CONFIG_SYS_CCSR_DEFAULT_IBATU@l
404 mtspr IBAT7L, r4
405 mtspr IBAT7U, r3
406 isync
407
408 /* DBAT 7 */
409 lis r4, CONFIG_SYS_CCSR_DEFAULT_DBATL@h
410 ori r4, r4, CONFIG_SYS_CCSR_DEFAULT_DBATL@l
411 lis r3, CONFIG_SYS_CCSR_DEFAULT_DBATU@h
412 ori r3, r3, CONFIG_SYS_CCSR_DEFAULT_DBATU@l
413 mtspr DBAT7L, r4
414 mtspr DBAT7U, r3
415 isync
416 #endif
417 blr
418
419 .globl clear_tlbs
420 clear_tlbs:
421 addis r3, 0, 0x0000
422 addis r5, 0, 0x4
423 isync
424 tlblp:
425 tlbie r3
426 sync
427 addi r3, r3, 0x1000
428 cmp 0, 0, r3, r5
429 blt tlblp
430 blr
431
432 .globl disable_addr_trans
433 disable_addr_trans:
434 /* disable address translation */
435 mflr r4
436 mfmsr r3
437 andi. r0, r3, (MSR_IR | MSR_DR)
438 beqlr
439 andc r3, r3, r0
440 mtspr SRR0, r4
441 mtspr SRR1, r3
442 rfi
443
444 /*
445 * This code finishes saving the registers to the exception frame
446 * and jumps to the appropriate handler for the exception.
447 * Register r21 is pointer into trap frame, r1 has new stack pointer.
448 */
449 .globl transfer_to_handler
450 transfer_to_handler:
451 stw r22,_NIP(r21)
452 lis r22,MSR_POW@h
453 andc r23,r23,r22
454 stw r23,_MSR(r21)
455 SAVE_GPR(7, r21)
456 SAVE_4GPRS(8, r21)
457 SAVE_8GPRS(12, r21)
458 SAVE_8GPRS(24, r21)
459 mflr r23
460 andi. r24,r23,0x3f00 /* get vector offset */
461 stw r24,TRAP(r21)
462 li r22,0
463 stw r22,RESULT(r21)
464 mtspr SPRG2,r22 /* r1 is now kernel sp */
465 lwz r24,0(r23) /* virtual address of handler */
466 lwz r23,4(r23) /* where to go when done */
467 mtspr SRR0,r24
468 mtspr SRR1,r20
469 mtlr r23
470 SYNC
471 rfi /* jump to handler, enable MMU */
472
473 int_return:
474 mfmsr r28 /* Disable interrupts */
475 li r4,0
476 ori r4,r4,MSR_EE
477 andc r28,r28,r4
478 SYNC /* Some chip revs need this... */
479 mtmsr r28
480 SYNC
481 lwz r2,_CTR(r1)
482 lwz r0,_LINK(r1)
483 mtctr r2
484 mtlr r0
485 lwz r2,_XER(r1)
486 lwz r0,_CCR(r1)
487 mtspr XER,r2
488 mtcrf 0xFF,r0
489 REST_10GPRS(3, r1)
490 REST_10GPRS(13, r1)
491 REST_8GPRS(23, r1)
492 REST_GPR(31, r1)
493 lwz r2,_NIP(r1) /* Restore environment */
494 lwz r0,_MSR(r1)
495 mtspr SRR0,r2
496 mtspr SRR1,r0
497 lwz r0,GPR0(r1)
498 lwz r2,GPR2(r1)
499 lwz r1,GPR1(r1)
500 SYNC
501 rfi
502
503 .globl dc_read
504 dc_read:
505 blr
506
507 .globl get_pvr
508 get_pvr:
509 mfspr r3, PVR
510 blr
511
512 .globl get_svr
513 get_svr:
514 mfspr r3, SVR
515 blr
516
517
518 /*
519 * Function: in8
520 * Description: Input 8 bits
521 */
522 .globl in8
523 in8:
524 lbz r3,0x0000(r3)
525 blr
526
527 /*
528 * Function: out8
529 * Description: Output 8 bits
530 */
531 .globl out8
532 out8:
533 stb r4,0x0000(r3)
534 blr
535
536 /*
537 * Function: out16
538 * Description: Output 16 bits
539 */
540 .globl out16
541 out16:
542 sth r4,0x0000(r3)
543 blr
544
545 /*
546 * Function: out16r
547 * Description: Byte reverse and output 16 bits
548 */
549 .globl out16r
550 out16r:
551 sthbrx r4,r0,r3
552 blr
553
554 /*
555 * Function: out32
556 * Description: Output 32 bits
557 */
558 .globl out32
559 out32:
560 stw r4,0x0000(r3)
561 blr
562
563 /*
564 * Function: out32r
565 * Description: Byte reverse and output 32 bits
566 */
567 .globl out32r
568 out32r:
569 stwbrx r4,r0,r3
570 blr
571
572 /*
573 * Function: in16
574 * Description: Input 16 bits
575 */
576 .globl in16
577 in16:
578 lhz r3,0x0000(r3)
579 blr
580
581 /*
582 * Function: in16r
583 * Description: Input 16 bits and byte reverse
584 */
585 .globl in16r
586 in16r:
587 lhbrx r3,r0,r3
588 blr
589
590 /*
591 * Function: in32
592 * Description: Input 32 bits
593 */
594 .globl in32
595 in32:
596 lwz 3,0x0000(3)
597 blr
598
599 /*
600 * Function: in32r
601 * Description: Input 32 bits and byte reverse
602 */
603 .globl in32r
604 in32r:
605 lwbrx r3,r0,r3
606 blr
607
608 /*
609 * void relocate_code (addr_sp, gd, addr_moni)
610 *
611 * This "function" does not return, instead it continues in RAM
612 * after relocating the monitor code.
613 *
614 * r3 = dest
615 * r4 = src
616 * r5 = length in bytes
617 * r6 = cachelinesize
618 */
619 .globl relocate_code
620 relocate_code:
621
622 mr r1, r3 /* Set new stack pointer */
623 mr r9, r4 /* Save copy of Global Data pointer */
624 mr r10, r5 /* Save copy of Destination Address */
625
626 GET_GOT
627 #if defined(__pic__) && __pic__ == 1
628 /* Needed for upcoming -msingle-pic-base */
629 bl _GLOBAL_OFFSET_TABLE_@local-4
630 mflr r30
631 #endif
632 mr r3, r5 /* Destination Address */
633 lis r4, CONFIG_SYS_MONITOR_BASE@h /* Source Address */
634 ori r4, r4, CONFIG_SYS_MONITOR_BASE@l
635 lwz r5, GOT(__init_end)
636 sub r5, r5, r4
637 li r6, CONFIG_SYS_CACHELINE_SIZE /* Cache Line Size */
638
639 /*
640 * Fix GOT pointer:
641 *
642 * New GOT-PTR = (old GOT-PTR - CONFIG_SYS_MONITOR_BASE) + Destination Address
643 *
644 * Offset:
645 */
646 sub r15, r10, r4
647
648 /* First our own GOT */
649 add r12, r12, r15
650 /* then the one used by the C code */
651 add r30, r30, r15
652
653 /*
654 * Now relocate code
655 */
656 cmplw cr1,r3,r4
657 addi r0,r5,3
658 srwi. r0,r0,2
659 beq cr1,4f /* In place copy is not necessary */
660 beq 7f /* Protect against 0 count */
661 mtctr r0
662 bge cr1,2f
663
664 la r8,-4(r4)
665 la r7,-4(r3)
666 1: lwzu r0,4(r8)
667 stwu r0,4(r7)
668 bdnz 1b
669 b 4f
670
671 2: slwi r0,r0,2
672 add r8,r4,r0
673 add r7,r3,r0
674 3: lwzu r0,-4(r8)
675 stwu r0,-4(r7)
676 bdnz 3b
677 /*
678 * Now flush the cache: note that we must start from a cache aligned
679 * address. Otherwise we might miss one cache line.
680 */
681 4: cmpwi r6,0
682 add r5,r3,r5
683 beq 7f /* Always flush prefetch queue in any case */
684 subi r0,r6,1
685 andc r3,r3,r0
686 mr r4,r3
687 5: dcbst 0,r4
688 add r4,r4,r6
689 cmplw r4,r5
690 blt 5b
691 sync /* Wait for all dcbst to complete on bus */
692 mr r4,r3
693 6: icbi 0,r4
694 add r4,r4,r6
695 cmplw r4,r5
696 blt 6b
697 7: sync /* Wait for all icbi to complete on bus */
698 isync
699
700 /*
701 * We are done. Do not return, instead branch to second part of board
702 * initialization, now running from RAM.
703 */
704 addi r0, r10, in_ram - _start + EXC_OFF_SYS_RESET
705 mtlr r0
706 blr
707
708 in_ram:
709 /*
710 * Relocation Function, r12 point to got2+0x8000
711 *
712 * Adjust got2 pointers, no need to check for 0, this code
713 * already puts a few entries in the table.
714 */
715 li r0,__got2_entries@sectoff@l
716 la r3,GOT(_GOT2_TABLE_)
717 lwz r11,GOT(_GOT2_TABLE_)
718 mtctr r0
719 sub r11,r3,r11
720 addi r3,r3,-4
721 1: lwzu r0,4(r3)
722 cmpwi r0,0
723 beq- 2f
724 add r0,r0,r11
725 stw r0,0(r3)
726 2: bdnz 1b
727
728 /*
729 * Now adjust the fixups and the pointers to the fixups
730 * in case we need to move ourselves again.
731 */
732 li r0,__fixup_entries@sectoff@l
733 lwz r3,GOT(_FIXUP_TABLE_)
734 cmpwi r0,0
735 mtctr r0
736 addi r3,r3,-4
737 beq 4f
738 3: lwzu r4,4(r3)
739 lwzux r0,r4,r11
740 cmpwi r0,0
741 add r0,r0,r11
742 stw r4,0(r3)
743 beq- 5f
744 stw r0,0(r4)
745 5: bdnz 3b
746 4:
747 /* clear_bss: */
748 /*
749 * Now clear BSS segment
750 */
751 lwz r3,GOT(__bss_start)
752 lwz r4,GOT(__bss_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, CONFIG_SYS_TEXT_BASE@h
865 ori r5,r5,CONFIG_SYS_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_SIZE & ~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_SIZE & ~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