]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - cpu/mpc83xx/start.S
1dfbf62239760e5d8b78f79fd1c78ad8f9d1087b
[karo-tx-uboot.git] / cpu / mpc83xx / 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, 2001,2002 Wolfgang Denk <wd@denx.de>
5  * Copyright Freescale Semiconductor, Inc. 2004, 2006. All rights reserved.
6  *
7  * See file CREDITS for list of people who contributed to this
8  * project.
9  *
10  * This program is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU General Public License as
12  * published by the Free Software Foundation; either version 2 of
13  * the License, or (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program; if not, write to the Free Software
22  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
23  * MA 02111-1307 USA
24  */
25
26 /*
27  *  U-Boot - Startup Code for MPC83xx PowerPC based Embedded Boards
28  */
29
30 #include <config.h>
31 #include <mpc83xx.h>
32 #include <version.h>
33
34 #define CONFIG_83XX     1               /* needed for Linux kernel header files*/
35 #define _LINUX_CONFIG_H 1       /* avoid reading Linux autoconf.h file */
36
37 #include <ppc_asm.tmpl>
38 #include <ppc_defs.h>
39
40 #include <asm/cache.h>
41 #include <asm/mmu.h>
42
43 #ifndef  CONFIG_IDENT_STRING
44 #define  CONFIG_IDENT_STRING "MPC83XX"
45 #endif
46
47 /* We don't want the  MMU yet.
48  */
49 #undef  MSR_KERNEL
50
51 /*
52  * Floating Point enable, Machine Check and Recoverable Interr.
53  */
54 #ifdef DEBUG
55 #define MSR_KERNEL (MSR_FP|MSR_RI)
56 #else
57 #define MSR_KERNEL (MSR_FP|MSR_ME|MSR_RI)
58 #endif
59
60 /*
61  * Set up GOT: Global Offset Table
62  *
63  * Use r14 to access the GOT
64  */
65         START_GOT
66         GOT_ENTRY(_GOT2_TABLE_)
67         GOT_ENTRY(_FIXUP_TABLE_)
68
69         GOT_ENTRY(_start)
70         GOT_ENTRY(_start_of_vectors)
71         GOT_ENTRY(_end_of_vectors)
72         GOT_ENTRY(transfer_to_handler)
73
74         GOT_ENTRY(__init_end)
75         GOT_ENTRY(_end)
76         GOT_ENTRY(__bss_start)
77         END_GOT
78
79 /*
80  * The Hard Reset Configuration Word (HRCW) table is in the first 64
81  * (0x40) bytes of flash.  It has 8 bytes, but each byte is repeated 8
82  * times so the processor can fetch it out of flash whether the flash
83  * is 8, 16, 32, or 64 bits wide (hardware trickery).
84  */
85         .text
86 #define _HRCW_TABLE_ENTRY(w)            \
87         .fill   8,1,(((w)>>24)&0xff);   \
88         .fill   8,1,(((w)>>16)&0xff);   \
89         .fill   8,1,(((w)>> 8)&0xff);   \
90         .fill   8,1,(((w)    )&0xff)
91
92         _HRCW_TABLE_ENTRY(CFG_HRCW_LOW)
93         _HRCW_TABLE_ENTRY(CFG_HRCW_HIGH)
94
95 /*
96  * Magic number and version string - put it after the HRCW since it
97  * cannot be first in flash like it is in many other processors.
98  */
99         .long   0x27051956              /* U-Boot Magic Number */
100
101         .globl  version_string
102 version_string:
103         .ascii U_BOOT_VERSION
104         .ascii " (", __DATE__, " - ", __TIME__, ")"
105         .ascii " ", CONFIG_IDENT_STRING, "\0"
106
107
108 #ifndef CONFIG_DEFAULT_IMMR
109 #error CONFIG_DEFAULT_IMMR must be defined
110 #endif /* CFG_DEFAULT_IMMR */
111 #ifndef CFG_IMMR
112 #define CFG_IMMR CONFIG_DEFAULT_IMMR
113 #endif /* CFG_IMMR */
114
115 /*
116  * After configuration, a system reset exception is executed using the
117  * vector at offset 0x100 relative to the base set by MSR[IP]. If
118  * MSR[IP] is 0, the base address is 0x00000000. If MSR[IP] is 1, the
119  * base address is 0xfff00000. In the case of a Power On Reset or Hard
120  * Reset, the value of MSR[IP] is determined by the CIP field in the
121  * HRCW.
122  *
123  * Other bits in the HRCW set up the Base Address and Port Size in BR0.
124  * This determines the location of the boot ROM (flash or EPROM) in the
125  * processor's address space at boot time. As long as the HRCW is set up
126  * so that we eventually end up executing the code below when the
127  * processor executes the reset exception, the actual values used should
128  * not matter.
129  *
130  * Once we have got here, the address mask in OR0 is cleared so that the
131  * bottom 32K of the boot ROM is effectively repeated all throughout the
132  * processor's address space, after which we can jump to the absolute
133  * address at which the boot ROM was linked at compile time, and proceed
134  * to initialise the memory controller without worrying if the rug will
135  * be pulled out from under us, so to speak (it will be fine as long as
136  * we configure BR0 with the same boot ROM link address).
137  */
138         . = EXC_OFF_SYS_RESET
139
140         .globl  _start
141 _start: /* time t 0 */
142         li      r21, BOOTFLAG_COLD  /* Normal Power-On: Boot from FLASH*/
143         nop
144         b       boot_cold
145
146         . = EXC_OFF_SYS_RESET + 0x10
147
148         .globl  _start_warm
149 _start_warm:
150         li      r21, BOOTFLAG_WARM      /* Software reboot      */
151         b       boot_warm
152
153
154 boot_cold: /* time t 3 */
155         lis     r4, CONFIG_DEFAULT_IMMR@h
156         nop
157 boot_warm: /* time t 5 */
158         mfmsr   r5                      /* save msr contents    */
159         lis     r3, CFG_IMMR@h
160         ori     r3, r3, CFG_IMMR@l
161         stw     r3, IMMRBAR(r4)
162
163         /* Initialise the E300 processor core           */
164         /*------------------------------------------*/
165
166         bl      init_e300_core
167
168 #ifndef CFG_RAMBOOT
169
170         /* Inflate flash location so it appears everywhere, calculate */
171         /* the absolute address in final location of the FLASH, jump  */
172         /* there and deflate the flash size back to minimal size      */
173         /*------------------------------------------------------------*/
174         bl map_flash_by_law1
175         lis r4, (CFG_MONITOR_BASE)@h
176         ori r4, r4, (CFG_MONITOR_BASE)@l
177         addi r5, r4, in_flash - _start + EXC_OFF_SYS_RESET
178         mtlr r5
179         blr
180 in_flash:
181 #if 1 /* Remapping flash with LAW0. */
182         bl remap_flash_by_law0
183 #endif
184 #endif  /* CFG_RAMBOOT */
185
186         /* setup the bats */
187         bl      setup_bats
188         sync
189
190         /*
191          * Cache must be enabled here for stack-in-cache trick.
192          * This means we need to enable the BATS.
193          * This means:
194          *   1) for the EVB, original gt regs need to be mapped
195          *   2) need to have an IBAT for the 0xf region,
196          *      we are running there!
197          * Cache should be turned on after BATs, since by default
198          * everything is write-through.
199          * The init-mem BAT can be reused after reloc. The old
200          * gt-regs BAT can be reused after board_init_f calls
201          * board_early_init_f (EVB only).
202          */
203         /* enable address translation */
204         bl      enable_addr_trans
205         sync
206
207         /* enable and invalidate the data cache */
208         bl      dcache_enable
209         sync
210 #ifdef CFG_INIT_RAM_LOCK
211         bl      lock_ram_in_cache
212         sync
213 #endif
214
215         /* set up the stack pointer in our newly created
216          * cache-ram (r1) */
217         lis     r1, (CFG_INIT_RAM_ADDR + CFG_GBL_DATA_OFFSET)@h
218         ori     r1, r1, (CFG_INIT_RAM_ADDR + CFG_GBL_DATA_OFFSET)@l
219
220         li      r0, 0           /* Make room for stack frame header and */
221         stwu    r0, -4(r1)      /* clear final stack frame so that      */
222         stwu    r0, -4(r1)      /* stack backtraces terminate cleanly   */
223
224
225         /* let the C-code set up the rest                           */
226         /*                                                          */
227         /* Be careful to keep code relocatable & stack humble   */
228         /*------------------------------------------------------*/
229
230         GET_GOT                 /* initialize GOT access        */
231
232         /* r3: IMMR */
233         lis     r3, CFG_IMMR@h
234         /* run low-level CPU init code (in Flash)*/
235         bl      cpu_init_f
236
237         /* r3: BOOTFLAG */
238         mr      r3, r21
239         /* run 1st part of board init code (in Flash)*/
240         bl      board_init_f
241
242 /*
243  * Vector Table
244  */
245
246         .globl  _start_of_vectors
247 _start_of_vectors:
248
249 /* Machine check */
250         STD_EXCEPTION(0x200, MachineCheck, MachineCheckException)
251
252 /* Data Storage exception. */
253         STD_EXCEPTION(0x300, DataStorage, UnknownException)
254
255 /* Instruction Storage exception. */
256         STD_EXCEPTION(0x400, InstStorage, UnknownException)
257
258 /* External Interrupt exception. */
259 #ifndef FIXME
260         STD_EXCEPTION(0x500, ExtInterrupt, external_interrupt)
261 #endif
262
263 /* Alignment exception. */
264         . = 0x600
265 Alignment:
266         EXCEPTION_PROLOG(SRR0, SRR1)
267         mfspr   r4,DAR
268         stw     r4,_DAR(r21)
269         mfspr   r5,DSISR
270         stw     r5,_DSISR(r21)
271         addi    r3,r1,STACK_FRAME_OVERHEAD
272         li      r20,MSR_KERNEL
273         rlwimi  r20,r23,0,16,16         /* copy EE bit from saved MSR */
274         rlwimi  r20,r23,0,25,25         /* copy IP bit from saved MSR */
275         lwz     r6,GOT(transfer_to_handler)
276         mtlr    r6
277         blrl
278 .L_Alignment:
279         .long   AlignmentException - _start + EXC_OFF_SYS_RESET
280         .long   int_return - _start + EXC_OFF_SYS_RESET
281
282 /* Program check exception */
283         . = 0x700
284 ProgramCheck:
285         EXCEPTION_PROLOG(SRR0, SRR1)
286         addi    r3,r1,STACK_FRAME_OVERHEAD
287         li      r20,MSR_KERNEL
288         rlwimi  r20,r23,0,16,16         /* copy EE bit from saved MSR */
289         rlwimi  r20,r23,0,25,25         /* copy IP bit from saved MSR */
290         lwz     r6,GOT(transfer_to_handler)
291         mtlr    r6
292         blrl
293 .L_ProgramCheck:
294         .long   ProgramCheckException - _start + EXC_OFF_SYS_RESET
295         .long   int_return - _start + EXC_OFF_SYS_RESET
296
297         STD_EXCEPTION(0x800, FPUnavailable, UnknownException)
298
299         /* I guess we could implement decrementer, and may have
300          * to someday for timekeeping.
301          */
302         STD_EXCEPTION(0x900, Decrementer, timer_interrupt)
303
304         STD_EXCEPTION(0xa00, Trap_0a, UnknownException)
305         STD_EXCEPTION(0xb00, Trap_0b, UnknownException)
306         STD_EXCEPTION(0xc00, SystemCall, UnknownException)
307         STD_EXCEPTION(0xd00, SingleStep, UnknownException)
308
309         STD_EXCEPTION(0xe00, Trap_0e, UnknownException)
310         STD_EXCEPTION(0xf00, Trap_0f, UnknownException)
311
312         STD_EXCEPTION(0x1000, InstructionTLBMiss, UnknownException)
313         STD_EXCEPTION(0x1100, DataLoadTLBMiss, UnknownException)
314         STD_EXCEPTION(0x1200, DataStoreTLBMiss, UnknownException)
315 #ifdef DEBUG
316         . = 0x1300
317         /*
318          * This exception occurs when the program counter matches the
319          * Instruction Address Breakpoint Register (IABR).
320          *
321          * I want the cpu to halt if this occurs so I can hunt around
322          * with the debugger and look at things.
323          *
324          * When DEBUG is defined, both machine check enable (in the MSR)
325          * and checkstop reset enable (in the reset mode register) are
326          * turned off and so a checkstop condition will result in the cpu
327          * halting.
328          *
329          * I force the cpu into a checkstop condition by putting an illegal
330          * instruction here (at least this is the theory).
331          *
332          * well - that didnt work, so just do an infinite loop!
333          */
334 1:      b       1b
335 #else
336         STD_EXCEPTION(0x1300, InstructionBreakpoint, DebugException)
337 #endif
338         STD_EXCEPTION(0x1400, SMI, UnknownException)
339
340         STD_EXCEPTION(0x1500, Trap_15, UnknownException)
341         STD_EXCEPTION(0x1600, Trap_16, UnknownException)
342         STD_EXCEPTION(0x1700, Trap_17, UnknownException)
343         STD_EXCEPTION(0x1800, Trap_18, UnknownException)
344         STD_EXCEPTION(0x1900, Trap_19, UnknownException)
345         STD_EXCEPTION(0x1a00, Trap_1a, UnknownException)
346         STD_EXCEPTION(0x1b00, Trap_1b, UnknownException)
347         STD_EXCEPTION(0x1c00, Trap_1c, UnknownException)
348         STD_EXCEPTION(0x1d00, Trap_1d, UnknownException)
349         STD_EXCEPTION(0x1e00, Trap_1e, UnknownException)
350         STD_EXCEPTION(0x1f00, Trap_1f, UnknownException)
351         STD_EXCEPTION(0x2000, Trap_20, UnknownException)
352         STD_EXCEPTION(0x2100, Trap_21, UnknownException)
353         STD_EXCEPTION(0x2200, Trap_22, UnknownException)
354         STD_EXCEPTION(0x2300, Trap_23, UnknownException)
355         STD_EXCEPTION(0x2400, Trap_24, UnknownException)
356         STD_EXCEPTION(0x2500, Trap_25, UnknownException)
357         STD_EXCEPTION(0x2600, Trap_26, UnknownException)
358         STD_EXCEPTION(0x2700, Trap_27, UnknownException)
359         STD_EXCEPTION(0x2800, Trap_28, UnknownException)
360         STD_EXCEPTION(0x2900, Trap_29, UnknownException)
361         STD_EXCEPTION(0x2a00, Trap_2a, UnknownException)
362         STD_EXCEPTION(0x2b00, Trap_2b, UnknownException)
363         STD_EXCEPTION(0x2c00, Trap_2c, UnknownException)
364         STD_EXCEPTION(0x2d00, Trap_2d, UnknownException)
365         STD_EXCEPTION(0x2e00, Trap_2e, UnknownException)
366         STD_EXCEPTION(0x2f00, Trap_2f, UnknownException)
367
368
369         .globl  _end_of_vectors
370 _end_of_vectors:
371
372         . = 0x3000
373
374 /*
375  * This code finishes saving the registers to the exception frame
376  * and jumps to the appropriate handler for the exception.
377  * Register r21 is pointer into trap frame, r1 has new stack pointer.
378  */
379         .globl  transfer_to_handler
380 transfer_to_handler:
381         stw     r22,_NIP(r21)
382         lis     r22,MSR_POW@h
383         andc    r23,r23,r22
384         stw     r23,_MSR(r21)
385         SAVE_GPR(7, r21)
386         SAVE_4GPRS(8, r21)
387         SAVE_8GPRS(12, r21)
388         SAVE_8GPRS(24, r21)
389         mflr    r23
390         andi.   r24,r23,0x3f00          /* get vector offset */
391         stw     r24,TRAP(r21)
392         li      r22,0
393         stw     r22,RESULT(r21)
394         lwz     r24,0(r23)              /* virtual address of handler */
395         lwz     r23,4(r23)              /* where to go when done */
396         mtspr   SRR0,r24
397         mtspr   SRR1,r20
398         mtlr    r23
399         SYNC
400         rfi                             /* jump to handler, enable MMU */
401
402 int_return:
403         mfmsr   r28             /* Disable interrupts */
404         li      r4,0
405         ori     r4,r4,MSR_EE
406         andc    r28,r28,r4
407         SYNC                    /* Some chip revs need this... */
408         mtmsr   r28
409         SYNC
410         lwz     r2,_CTR(r1)
411         lwz     r0,_LINK(r1)
412         mtctr   r2
413         mtlr    r0
414         lwz     r2,_XER(r1)
415         lwz     r0,_CCR(r1)
416         mtspr   XER,r2
417         mtcrf   0xFF,r0
418         REST_10GPRS(3, r1)
419         REST_10GPRS(13, r1)
420         REST_8GPRS(23, r1)
421         REST_GPR(31, r1)
422         lwz     r2,_NIP(r1)     /* Restore environment */
423         lwz     r0,_MSR(r1)
424         mtspr   SRR0,r2
425         mtspr   SRR1,r0
426         lwz     r0,GPR0(r1)
427         lwz     r2,GPR2(r1)
428         lwz     r1,GPR1(r1)
429         SYNC
430         rfi
431
432 /*
433  * This code initialises the E300 processor core
434  * (conforms to PowerPC 603e spec)
435  * Note: expects original MSR contents to be in r5.
436  */
437         .globl  init_e300_core
438 init_e300_core: /* time t 10 */
439         /* Initialize machine status; enable machine check interrupt */
440         /*-----------------------------------------------------------*/
441
442         li      r3, MSR_KERNEL                  /* Set ME and RI flags */
443         rlwimi  r3, r5, 0, 25, 25       /* preserve IP bit set by HRCW */
444 #ifdef DEBUG
445         rlwimi  r3, r5, 0, 21, 22   /* debugger might set SE & BE bits */
446 #endif
447         SYNC                                            /* Some chip revs need this... */
448         mtmsr   r3
449         SYNC
450         mtspr   SRR1, r3                        /* Make SRR1 match MSR */
451
452
453         lis     r3, CFG_IMMR@h
454 #if defined(CONFIG_WATCHDOG)
455         /* Initialise the Wathcdog values and reset it (if req) */
456         /*------------------------------------------------------*/
457         lis r4, CFG_WATCHDOG_VALUE
458         ori r4, r4, (SWCRR_SWEN | SWCRR_SWRI | SWCRR_SWPR)
459         stw r4, SWCRR(r3)
460
461         /* and reset it */
462
463         li      r4, 0x556C
464         sth     r4, SWSRR@l(r3)
465         li      r4, -0x55C7
466         sth     r4, SWSRR@l(r3)
467 #else
468         /* Disable Wathcdog  */
469         /*-------------------*/
470         lwz r4, SWCRR(r3)
471         /* Check to see if its enabled for disabling
472            once disabled by SW you can't re-enable */
473         andi. r4, r4, 0x4
474         beq 1f
475         xor r4, r4, r4
476         stw r4, SWCRR(r3)
477 1:
478 #endif /* CONFIG_WATCHDOG */
479
480         /* Initialize the Hardware Implementation-dependent Registers */
481         /* HID0 also contains cache control                     */
482         /*------------------------------------------------------*/
483
484         lis     r3, CFG_HID0_INIT@h
485         ori     r3, r3, CFG_HID0_INIT@l
486         SYNC
487         mtspr   HID0, r3
488
489         lis     r3, CFG_HID0_FINAL@h
490         ori     r3, r3, CFG_HID0_FINAL@l
491         SYNC
492         mtspr   HID0, r3
493
494         lis     r3, CFG_HID2@h
495         ori     r3, r3, CFG_HID2@l
496         SYNC
497         mtspr   HID2, r3
498
499         /* clear all BAT's                                      */
500         /*----------------------------------*/
501
502         xor     r0, r0, r0
503         mtspr   DBAT0U, r0
504         mtspr   DBAT0L, r0
505         mtspr   DBAT1U, r0
506         mtspr   DBAT1L, r0
507         mtspr   DBAT2U, r0
508         mtspr   DBAT2L, r0
509         mtspr   DBAT3U, r0
510         mtspr   DBAT3L, r0
511         mtspr   IBAT0U, r0
512         mtspr   IBAT0L, r0
513         mtspr   IBAT1U, r0
514         mtspr   IBAT1L, r0
515         mtspr   IBAT2U, r0
516         mtspr   IBAT2L, r0
517         mtspr   IBAT3U, r0
518         mtspr   IBAT3L, r0
519         SYNC
520
521         /* invalidate all tlb's
522          *
523          * From the 603e User Manual: "The 603e provides the ability to
524          * invalidate a TLB entry. The TLB Invalidate Entry (tlbie)
525          * instruction invalidates the TLB entry indexed by the EA, and
526          * operates on both the instruction and data TLBs simultaneously
527          * invalidating four TLB entries (both sets in each TLB). The
528          * index corresponds to bits 15-19 of the EA. To invalidate all
529          * entries within both TLBs, 32 tlbie instructions should be
530          * issued, incrementing this field by one each time."
531          *
532          * "Note that the tlbia instruction is not implemented on the
533          * 603e."
534          *
535          * bits 15-19 correspond to addresses 0x00000000 to 0x0001F000
536          * incrementing by 0x1000 each time. The code below is sort of
537          * based on code in "flush_tlbs" from arch/ppc/kernel/head.S
538          *
539          */
540
541         li      r3, 32
542         mtctr   r3
543         li      r3, 0
544 1:      tlbie   r3
545         addi    r3, r3, 0x1000
546         bdnz    1b
547         SYNC
548
549         /* Done!                                                */
550         /*------------------------------*/
551         blr
552
553         .globl  invalidate_bats
554 invalidate_bats:
555         /* invalidate BATs */
556         mtspr   IBAT0U, r0
557         mtspr   IBAT1U, r0
558         mtspr   IBAT2U, r0
559         mtspr   IBAT3U, r0
560 #if (CFG_HID2 & HID2_HBE)
561         mtspr   IBAT4U, r0
562         mtspr   IBAT5U, r0
563         mtspr   IBAT6U, r0
564         mtspr   IBAT7U, r0
565 #endif
566         isync
567         mtspr   DBAT0U, r0
568         mtspr   DBAT1U, r0
569         mtspr   DBAT2U, r0
570         mtspr   DBAT3U, r0
571 #if (CFG_HID2 & HID2_HBE)
572         mtspr   DBAT4U, r0
573         mtspr   DBAT5U, r0
574         mtspr   DBAT6U, r0
575         mtspr   DBAT7U, r0
576 #endif
577         isync
578         sync
579         blr
580
581         /* setup_bats - set them up to some initial state */
582         .globl  setup_bats
583 setup_bats:
584         addis   r0, r0, 0x0000
585
586         /* IBAT 0 */
587         addis   r4, r0, CFG_IBAT0L@h
588         ori     r4, r4, CFG_IBAT0L@l
589         addis   r3, r0, CFG_IBAT0U@h
590         ori     r3, r3, CFG_IBAT0U@l
591         mtspr   IBAT0L, r4
592         mtspr   IBAT0U, r3
593         isync
594
595         /* DBAT 0 */
596         addis   r4, r0, CFG_DBAT0L@h
597         ori     r4, r4, CFG_DBAT0L@l
598         addis   r3, r0, CFG_DBAT0U@h
599         ori     r3, r3, CFG_DBAT0U@l
600         mtspr   DBAT0L, r4
601         mtspr   DBAT0U, r3
602         isync
603
604         /* IBAT 1 */
605         addis   r4, r0, CFG_IBAT1L@h
606         ori     r4, r4, CFG_IBAT1L@l
607         addis   r3, r0, CFG_IBAT1U@h
608         ori     r3, r3, CFG_IBAT1U@l
609         mtspr   IBAT1L, r4
610         mtspr   IBAT1U, r3
611         isync
612
613         /* DBAT 1 */
614         addis   r4, r0, CFG_DBAT1L@h
615         ori     r4, r4, CFG_DBAT1L@l
616         addis   r3, r0, CFG_DBAT1U@h
617         ori     r3, r3, CFG_DBAT1U@l
618         mtspr   DBAT1L, r4
619         mtspr   DBAT1U, r3
620         isync
621
622         /* IBAT 2 */
623         addis   r4, r0, CFG_IBAT2L@h
624         ori     r4, r4, CFG_IBAT2L@l
625         addis   r3, r0, CFG_IBAT2U@h
626         ori     r3, r3, CFG_IBAT2U@l
627         mtspr   IBAT2L, r4
628         mtspr   IBAT2U, r3
629         isync
630
631         /* DBAT 2 */
632         addis   r4, r0, CFG_DBAT2L@h
633         ori     r4, r4, CFG_DBAT2L@l
634         addis   r3, r0, CFG_DBAT2U@h
635         ori     r3, r3, CFG_DBAT2U@l
636         mtspr   DBAT2L, r4
637         mtspr   DBAT2U, r3
638         isync
639
640         /* IBAT 3 */
641         addis   r4, r0, CFG_IBAT3L@h
642         ori     r4, r4, CFG_IBAT3L@l
643         addis   r3, r0, CFG_IBAT3U@h
644         ori     r3, r3, CFG_IBAT3U@l
645         mtspr   IBAT3L, r4
646         mtspr   IBAT3U, r3
647         isync
648
649         /* DBAT 3 */
650         addis   r4, r0, CFG_DBAT3L@h
651         ori     r4, r4, CFG_DBAT3L@l
652         addis   r3, r0, CFG_DBAT3U@h
653         ori     r3, r3, CFG_DBAT3U@l
654         mtspr   DBAT3L, r4
655         mtspr   DBAT3U, r3
656         isync
657
658 #if (CFG_HID2 & HID2_HBE)
659         /* IBAT 4 */
660         addis   r4, r0, CFG_IBAT4L@h
661         ori     r4, r4, CFG_IBAT4L@l
662         addis   r3, r0, CFG_IBAT4U@h
663         ori     r3, r3, CFG_IBAT4U@l
664         mtspr   IBAT4L, r4
665         mtspr   IBAT4U, r3
666         isync
667
668         /* DBAT 4 */
669         addis   r4, r0, CFG_DBAT4L@h
670         ori     r4, r4, CFG_DBAT4L@l
671         addis   r3, r0, CFG_DBAT4U@h
672         ori     r3, r3, CFG_DBAT4U@l
673         mtspr   DBAT4L, r4
674         mtspr   DBAT4U, r3
675         isync
676
677         /* IBAT 5 */
678         addis   r4, r0, CFG_IBAT5L@h
679         ori     r4, r4, CFG_IBAT5L@l
680         addis   r3, r0, CFG_IBAT5U@h
681         ori     r3, r3, CFG_IBAT5U@l
682         mtspr   IBAT5L, r4
683         mtspr   IBAT5U, r3
684         isync
685
686         /* DBAT 5 */
687         addis   r4, r0, CFG_DBAT5L@h
688         ori     r4, r4, CFG_DBAT5L@l
689         addis   r3, r0, CFG_DBAT5U@h
690         ori     r3, r3, CFG_DBAT5U@l
691         mtspr   DBAT5L, r4
692         mtspr   DBAT5U, r3
693         isync
694
695         /* IBAT 6 */
696         addis   r4, r0, CFG_IBAT6L@h
697         ori     r4, r4, CFG_IBAT6L@l
698         addis   r3, r0, CFG_IBAT6U@h
699         ori     r3, r3, CFG_IBAT6U@l
700         mtspr   IBAT6L, r4
701         mtspr   IBAT6U, r3
702         isync
703
704         /* DBAT 6 */
705         addis   r4, r0, CFG_DBAT6L@h
706         ori     r4, r4, CFG_DBAT6L@l
707         addis   r3, r0, CFG_DBAT6U@h
708         ori     r3, r3, CFG_DBAT6U@l
709         mtspr   DBAT6L, r4
710         mtspr   DBAT6U, r3
711         isync
712
713         /* IBAT 7 */
714         addis   r4, r0, CFG_IBAT7L@h
715         ori     r4, r4, CFG_IBAT7L@l
716         addis   r3, r0, CFG_IBAT7U@h
717         ori     r3, r3, CFG_IBAT7U@l
718         mtspr   IBAT7L, r4
719         mtspr   IBAT7U, r3
720         isync
721
722         /* DBAT 7 */
723         addis   r4, r0, CFG_DBAT7L@h
724         ori     r4, r4, CFG_DBAT7L@l
725         addis   r3, r0, CFG_DBAT7U@h
726         ori     r3, r3, CFG_DBAT7U@l
727         mtspr   DBAT7L, r4
728         mtspr   DBAT7U, r3
729         isync
730 #endif
731
732         /* Invalidate TLBs.
733          * -> for (val = 0; val < 0x20000; val+=0x1000)
734          * ->   tlbie(val);
735          */
736         lis     r3, 0
737         lis     r5, 2
738
739 1:
740         tlbie   r3
741         addi    r3, r3, 0x1000
742         cmp     0, 0, r3, r5
743         blt     1b
744
745         blr
746
747         .globl enable_addr_trans
748 enable_addr_trans:
749         /* enable address translation */
750         mfmsr   r5
751         ori     r5, r5, (MSR_IR | MSR_DR)
752         mtmsr   r5
753         isync
754         blr
755
756         .globl disable_addr_trans
757 disable_addr_trans:
758         /* disable address translation */
759         mflr    r4
760         mfmsr   r3
761         andi.   r0, r3, (MSR_IR | MSR_DR)
762         beqlr
763         andc    r3, r3, r0
764         mtspr   SRR0, r4
765         mtspr   SRR1, r3
766         rfi
767
768 /* Cache functions.
769  *
770  * Note: requires that all cache bits in
771  * HID0 are in the low half word.
772  */
773         .globl  icache_enable
774 icache_enable:
775         mfspr   r3, HID0
776         ori     r3, r3, HID0_ICE
777         lis     r4, 0
778         ori     r4, r4, HID0_ILOCK
779         andc    r3, r3, r4
780         ori     r4, r3, HID0_ICFI
781         isync
782         mtspr   HID0, r4    /* sets enable and invalidate, clears lock */
783         isync
784         mtspr   HID0, r3        /* clears invalidate */
785         blr
786
787         .globl  icache_disable
788 icache_disable:
789         mfspr   r3, HID0
790         lis     r4, 0
791         ori     r4, r4, HID0_ICE|HID0_ILOCK
792         andc    r3, r3, r4
793         ori     r4, r3, HID0_ICFI
794         isync
795         mtspr   HID0, r4     /* sets invalidate, clears enable and lock*/
796         isync
797         mtspr   HID0, r3        /* clears invalidate */
798         blr
799
800         .globl  icache_status
801 icache_status:
802         mfspr   r3, HID0
803         rlwinm  r3, r3, (31 - HID0_ICE_SHIFT + 1), 31, 31
804         blr
805
806         .globl  dcache_enable
807 dcache_enable:
808         mfspr   r3, HID0
809         li      r5, HID0_DCFI|HID0_DLOCK
810         andc    r3, r3, r5
811         mtspr   HID0, r3                /* no invalidate, unlock */
812         ori     r3, r3, HID0_DCE
813         ori     r5, r3, HID0_DCFI
814         mtspr   HID0, r5                /* enable + invalidate */
815         mtspr   HID0, r3                /* enable */
816         sync
817         blr
818
819         .globl  dcache_disable
820 dcache_disable:
821         mfspr   r3, HID0
822         lis     r4, 0
823         ori     r4, r4, HID0_DCE|HID0_DLOCK
824         andc    r3, r3, r4
825         ori     r4, r3, HID0_DCI
826         sync
827         mtspr   HID0, r4        /* sets invalidate, clears enable and lock */
828         sync
829         mtspr   HID0, r3        /* clears invalidate */
830         blr
831
832         .globl  dcache_status
833 dcache_status:
834         mfspr   r3, HID0
835         rlwinm  r3, r3, (31 - HID0_DCE_SHIFT + 1), 31, 31
836         blr
837
838         .globl get_pvr
839 get_pvr:
840         mfspr   r3, PVR
841         blr
842
843 /*------------------------------------------------------------------------------- */
844 /* Function:     ppcDcbf */
845 /* Description:  Data Cache block flush */
846 /* Input:        r3 = effective address */
847 /* Output:       none. */
848 /*------------------------------------------------------------------------------- */
849         .globl  ppcDcbf
850 ppcDcbf:
851         dcbf    r0,r3
852         blr
853
854 /*------------------------------------------------------------------------------- */
855 /* Function:     ppcDcbi */
856 /* Description:  Data Cache block Invalidate */
857 /* Input:        r3 = effective address */
858 /* Output:       none. */
859 /*------------------------------------------------------------------------------- */
860         .globl  ppcDcbi
861 ppcDcbi:
862         dcbi    r0,r3
863         blr
864
865 /*--------------------------------------------------------------------------
866  * Function:     ppcDcbz
867  * Description:  Data Cache block zero.
868  * Input:        r3 = effective address
869  * Output:       none.
870  *-------------------------------------------------------------------------- */
871
872         .globl  ppcDcbz
873 ppcDcbz:
874         dcbz    r0,r3
875         blr
876
877         .globl  ppcDWstore
878 ppcDWstore:
879         lfd     1, 0(r4)
880         stfd    1, 0(r3)
881         blr
882
883         .globl  ppcDWload
884 ppcDWload:
885         lfd     1, 0(r3)
886         stfd    1, 0(r4)
887         blr
888
889 /*-------------------------------------------------------------------*/
890
891 /*
892  * void relocate_code (addr_sp, gd, addr_moni)
893  *
894  * This "function" does not return, instead it continues in RAM
895  * after relocating the monitor code.
896  *
897  * r3 = dest
898  * r4 = src
899  * r5 = length in bytes
900  * r6 = cachelinesize
901  */
902         .globl  relocate_code
903 relocate_code:
904         mr      r1,  r3         /* Set new stack pointer        */
905         mr      r9,  r4         /* Save copy of Global Data pointer */
906         mr      r10, r5         /* Save copy of Destination Address */
907
908         mr      r3,  r5                         /* Destination Address */
909         lis     r4, CFG_MONITOR_BASE@h          /* Source      Address */
910         ori     r4, r4, CFG_MONITOR_BASE@l
911         lwz     r5, GOT(__init_end)
912         sub     r5, r5, r4
913         li      r6, CFG_CACHELINE_SIZE          /* Cache Line Size */
914
915         /*
916          * Fix GOT pointer:
917          *
918          * New GOT-PTR = (old GOT-PTR - CFG_MONITOR_BASE)
919          *              + Destination Address
920          *
921          * Offset:
922          */
923         sub     r15, r10, r4
924
925         /* First our own GOT */
926         add     r14, r14, r15
927         /* then the one used by the C code */
928         add     r30, r30, r15
929
930         /*
931          * Now relocate code
932          */
933
934         cmplw   cr1,r3,r4
935         addi    r0,r5,3
936         srwi.   r0,r0,2
937         beq     cr1,4f          /* In place copy is not necessary */
938         beq     7f              /* Protect against 0 count        */
939         mtctr   r0
940         bge     cr1,2f
941         la      r8,-4(r4)
942         la      r7,-4(r3)
943
944         /* copy */
945 1:      lwzu    r0,4(r8)
946         stwu    r0,4(r7)
947         bdnz    1b
948
949         addi    r0,r5,3
950         srwi.   r0,r0,2
951         mtctr   r0
952         la      r8,-4(r4)
953         la      r7,-4(r3)
954
955         /* and compare */
956 20:     lwzu    r20,4(r8)
957         lwzu    r21,4(r7)
958         xor. r22, r20, r21
959         bne  30f
960         bdnz    20b
961         b 4f
962
963         /* compare failed */
964 30:     li r3, 0
965         blr
966
967 2:      slwi    r0,r0,2 /* re copy in reverse order ... y do we needed it? */
968         add     r8,r4,r0
969         add     r7,r3,r0
970 3:      lwzu    r0,-4(r8)
971         stwu    r0,-4(r7)
972         bdnz    3b
973
974 /*
975  * Now flush the cache: note that we must start from a cache aligned
976  * address. Otherwise we might miss one cache line.
977  */
978 4:      cmpwi   r6,0
979         add     r5,r3,r5
980         beq     7f              /* Always flush prefetch queue in any case */
981         subi    r0,r6,1
982         andc    r3,r3,r0
983         mr      r4,r3
984 5:      dcbst   0,r4
985         add     r4,r4,r6
986         cmplw   r4,r5
987         blt     5b
988         sync                    /* Wait for all dcbst to complete on bus */
989         mr      r4,r3
990 6:      icbi    0,r4
991         add     r4,r4,r6
992         cmplw   r4,r5
993         blt     6b
994 7:      sync                    /* Wait for all icbi to complete on bus */
995         isync
996
997 /*
998  * We are done. Do not return, instead branch to second part of board
999  * initialization, now running from RAM.
1000  */
1001         addi    r0, r10, in_ram - _start + EXC_OFF_SYS_RESET
1002         mtlr    r0
1003         blr
1004
1005 in_ram:
1006
1007         /*
1008          * Relocation Function, r14 point to got2+0x8000
1009          *
1010          * Adjust got2 pointers, no need to check for 0, this code
1011          * already puts a few entries in the table.
1012          */
1013         li      r0,__got2_entries@sectoff@l
1014         la      r3,GOT(_GOT2_TABLE_)
1015         lwz     r11,GOT(_GOT2_TABLE_)
1016         mtctr   r0
1017         sub     r11,r3,r11
1018         addi    r3,r3,-4
1019 1:      lwzu    r0,4(r3)
1020         add     r0,r0,r11
1021         stw     r0,0(r3)
1022         bdnz    1b
1023
1024         /*
1025          * Now adjust the fixups and the pointers to the fixups
1026          * in case we need to move ourselves again.
1027          */
1028 2:      li      r0,__fixup_entries@sectoff@l
1029         lwz     r3,GOT(_FIXUP_TABLE_)
1030         cmpwi   r0,0
1031         mtctr   r0
1032         addi    r3,r3,-4
1033         beq     4f
1034 3:      lwzu    r4,4(r3)
1035         lwzux   r0,r4,r11
1036         add     r0,r0,r11
1037         stw     r10,0(r3)
1038         stw     r0,0(r4)
1039         bdnz    3b
1040 4:
1041 clear_bss:
1042         /*
1043          * Now clear BSS segment
1044          */
1045         lwz     r3,GOT(__bss_start)
1046 #if defined(CONFIG_HYMOD)
1047         /*
1048          * For HYMOD - the environment is the very last item in flash.
1049          * The real .bss stops just before environment starts, so only
1050          * clear up to that point.
1051          *
1052          * taken from mods for FADS board
1053          */
1054         lwz     r4,GOT(environment)
1055 #else
1056         lwz     r4,GOT(_end)
1057 #endif
1058
1059         cmplw   0, r3, r4
1060         beq     6f
1061
1062         li      r0, 0
1063 5:
1064         stw     r0, 0(r3)
1065         addi    r3, r3, 4
1066         cmplw   0, r3, r4
1067         bne     5b
1068 6:
1069
1070         mr      r3, r9          /* Global Data pointer          */
1071         mr      r4, r10         /* Destination Address          */
1072         bl      board_init_r
1073
1074         /*
1075          * Copy exception vector code to low memory
1076          *
1077          * r3: dest_addr
1078          * r7: source address, r8: end address, r9: target address
1079          */
1080         .globl  trap_init
1081 trap_init:
1082         lwz     r7, GOT(_start)
1083         lwz     r8, GOT(_end_of_vectors)
1084
1085         li      r9, 0x100       /* reset vector always at 0x100 */
1086
1087         cmplw   0, r7, r8
1088         bgelr                   /* return if r7>=r8 - just in case */
1089
1090         mflr    r4              /* save link register */
1091 1:
1092         lwz     r0, 0(r7)
1093         stw     r0, 0(r9)
1094         addi    r7, r7, 4
1095         addi    r9, r9, 4
1096         cmplw   0, r7, r8
1097         bne     1b
1098
1099         /*
1100          * relocate `hdlr' and `int_return' entries
1101          */
1102         li      r7, .L_MachineCheck - _start + EXC_OFF_SYS_RESET
1103         li      r8, Alignment - _start + EXC_OFF_SYS_RESET
1104 2:
1105         bl      trap_reloc
1106         addi    r7, r7, 0x100           /* next exception vector */
1107         cmplw   0, r7, r8
1108         blt     2b
1109
1110         li      r7, .L_Alignment - _start + EXC_OFF_SYS_RESET
1111         bl      trap_reloc
1112
1113         li      r7, .L_ProgramCheck - _start + EXC_OFF_SYS_RESET
1114         bl      trap_reloc
1115
1116         li      r7, .L_FPUnavailable - _start + EXC_OFF_SYS_RESET
1117         li      r8, SystemCall - _start + EXC_OFF_SYS_RESET
1118 3:
1119         bl      trap_reloc
1120         addi    r7, r7, 0x100           /* next exception vector */
1121         cmplw   0, r7, r8
1122         blt     3b
1123
1124         li      r7, .L_SingleStep - _start + EXC_OFF_SYS_RESET
1125         li      r8, _end_of_vectors - _start + EXC_OFF_SYS_RESET
1126 4:
1127         bl      trap_reloc
1128         addi    r7, r7, 0x100           /* next exception vector */
1129         cmplw   0, r7, r8
1130         blt     4b
1131
1132         mfmsr   r3                      /* now that the vectors have */
1133         lis     r7, MSR_IP@h            /* relocated into low memory */
1134         ori     r7, r7, MSR_IP@l        /* MSR[IP] can be turned off */
1135         andc    r3, r3, r7              /* (if it was on) */
1136         SYNC                            /* Some chip revs need this... */
1137         mtmsr   r3
1138         SYNC
1139
1140         mtlr    r4                      /* restore link register    */
1141         blr
1142
1143         /*
1144          * Function: relocate entries for one exception vector
1145          */
1146 trap_reloc:
1147         lwz     r0, 0(r7)               /* hdlr ...             */
1148         add     r0, r0, r3              /*  ... += dest_addr    */
1149         stw     r0, 0(r7)
1150
1151         lwz     r0, 4(r7)               /* int_return ...       */
1152         add     r0, r0, r3              /*  ... += dest_addr    */
1153         stw     r0, 4(r7)
1154
1155         blr
1156
1157 #ifdef CFG_INIT_RAM_LOCK
1158 lock_ram_in_cache:
1159         /* Allocate Initial RAM in data cache.
1160          */
1161         lis     r3, (CFG_INIT_RAM_ADDR & ~31)@h
1162         ori     r3, r3, (CFG_INIT_RAM_ADDR & ~31)@l
1163         li      r2, ((CFG_INIT_RAM_END & ~31) + \
1164                      (CFG_INIT_RAM_ADDR & 31) + 31) / 32
1165         mtctr   r2
1166 1:
1167         dcbz    r0, r3
1168         addi    r3, r3, 32
1169         bdnz    1b
1170
1171         /* Lock the data cache */
1172         mfspr   r0, HID0
1173         ori     r0, r0, 0x1000
1174         sync
1175         mtspr   HID0, r0
1176         sync
1177         blr
1178
1179 .globl unlock_ram_in_cache
1180 unlock_ram_in_cache:
1181         /* invalidate the INIT_RAM section */
1182         lis     r3, (CFG_INIT_RAM_ADDR & ~31)@h
1183         ori     r3, r3, (CFG_INIT_RAM_ADDR & ~31)@l
1184         li      r2,512
1185         mtctr   r2
1186 1:      icbi    r0, r3
1187         dcbi    r0, r3
1188         addi    r3, r3, 32
1189         bdnz    1b
1190         sync                    /* Wait for all icbi to complete on bus */
1191         isync
1192
1193         /* Unlock the data cache and invalidate it */
1194         mfspr   r3, HID0
1195         li      r5, HID0_DLOCK|HID0_DCFI
1196         andc    r3, r3, r5              /* no invalidate, unlock */
1197         ori     r5, r3, HID0_DCFI       /* invalidate, unlock */
1198         mtspr   HID0, r5                /* invalidate, unlock */
1199         mtspr   HID0, r3                /* no invalidate, unlock */
1200         sync
1201         blr
1202 #endif
1203
1204 map_flash_by_law1:
1205         /* When booting from ROM (Flash or EPROM), clear the  */
1206         /* Address Mask in OR0 so ROM appears everywhere      */
1207         /*----------------------------------------------------*/
1208         lis     r3, (CFG_IMMR)@h  /* r3 <= CFG_IMMR    */
1209         lwz     r4, OR0@l(r3)
1210         li      r5, 0x7fff        /* r5 <= 0x00007FFFF */
1211         and     r4, r4, r5
1212         stw     r4, OR0@l(r3)     /* OR0 <= OR0 & 0x00007FFFF */
1213
1214         /* As MPC8349E User's Manual presented, when RCW[BMS] is set to 0,
1215          * system will boot from 0x0000_0100, and the LBLAWBAR0[BASE_ADDR]
1216          * reset value is 0x00000; when RCW[BMS] is set to 1, system will boot
1217          * from 0xFFF0_0100, and the LBLAWBAR0[BASE_ADDR] reset value is
1218          * 0xFF800.  From the hard resetting to here, the processor fetched and
1219          * executed the instructions one by one.  There is not absolutely
1220          * jumping happened.  Laterly, the u-boot code has to do an absolutely
1221          * jumping to tell the CPU instruction fetching component what the
1222          * u-boot TEXT base address is.  Because the TEXT base resides in the
1223          * boot ROM memory space, to garantee the code can run smoothly after
1224          * that jumping, we must map in the entire boot ROM by Local Access
1225          * Window.  Sometimes, we desire an non-0x00000 or non-0xFF800 starting
1226          * address for boot ROM, such as 0xFE000000.  In this case, the default
1227          * LBIU Local Access Widow 0 will not cover this memory space.  So, we
1228          * need another window to map in it.
1229          */
1230         lis r4, (CFG_FLASH_BASE)@h
1231         ori r4, r4, (CFG_FLASH_BASE)@l
1232         stw r4, LBLAWBAR1(r3) /* LBLAWBAR1 <= CFG_FLASH_BASE */
1233
1234         /* Store 0x80000012 + log2(CFG_FLASH_SIZE) into LBLAWAR1 */
1235         lis r4, (0x80000012)@h
1236         ori r4, r4, (0x80000012)@l
1237         li r5, CFG_FLASH_SIZE
1238 1:      srawi. r5, r5, 1        /* r5 = r5 >> 1 */
1239         addi r4, r4, 1
1240         bne 1b
1241
1242         stw r4, LBLAWAR1(r3) /* LBLAWAR1 <= 8MB Flash Size */
1243         blr
1244
1245         /* Though all the LBIU Local Access Windows and LBC Banks will be
1246          * initialized in the C code, we'd better configure boot ROM's
1247          * window 0 and bank 0 correctly at here.
1248          */
1249 remap_flash_by_law0:
1250         /* Initialize the BR0 with the boot ROM starting address. */
1251         lwz r4, BR0(r3)
1252         li  r5, 0x7FFF
1253         and r4, r4, r5
1254         lis r5, (CFG_FLASH_BASE & 0xFFFF8000)@h
1255         ori r5, r5, (CFG_FLASH_BASE & 0xFFFF8000)@l
1256         or  r5, r5, r4
1257         stw r5, BR0(r3) /* r5 <= (CFG_FLASH_BASE & 0xFFFF8000) | (BR0 & 0x00007FFF) */
1258
1259         lwz r4, OR0(r3)
1260         lis r5, ~((CFG_FLASH_SIZE << 4) - 1)
1261         or r4, r4, r5
1262         stw r4, OR0(r3)
1263
1264         lis r4, (CFG_FLASH_BASE)@h
1265         ori r4, r4, (CFG_FLASH_BASE)@l
1266         stw r4, LBLAWBAR0(r3) /* LBLAWBAR0 <= CFG_FLASH_BASE */
1267
1268         /* Store 0x80000012 + log2(CFG_FLASH_SIZE) into LBLAWAR0 */
1269         lis r4, (0x80000012)@h
1270         ori r4, r4, (0x80000012)@l
1271         li r5, CFG_FLASH_SIZE
1272 1:      srawi. r5, r5, 1 /* r5 = r5 >> 1 */
1273         addi r4, r4, 1
1274         bne 1b
1275         stw r4, LBLAWAR0(r3) /* LBLAWAR0 <= Flash Size */
1276
1277
1278         xor r4, r4, r4
1279         stw r4, LBLAWBAR1(r3)
1280         stw r4, LBLAWAR1(r3) /* Off LBIU LAW1 */
1281         blr