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