source: SVN/rincon/u-boot/cpu/mpc83xx/start.S @ 55

Last change on this file since 55 was 55, checked in by Tim Harvey, 22 months ago

rincon: added latest u-boot source

restored form server backup

Signed-off-by: Tim Harvey <tharvey@…>

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