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