]> git.ipfire.org Git - people/ms/u-boot.git/blame - cpu/mpc83xx/start.S
Decopuled setting of OR/BR and LBLAWBAR/LBLAWAR on MPC83xx
[people/ms/u-boot.git] / cpu / mpc83xx / start.S
CommitLineData
f046ccd1
EL
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>
de1d0a69 31#include <mpc83xx.h>
f046ccd1
EL
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
88version_string:
89 .ascii U_BOOT_VERSION
90 .ascii " (", __DATE__, " - ", __TIME__, ")"
91 .ascii " ", CONFIG_IDENT_STRING, "\0"
de1d0a69 92
f046ccd1
EL
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
f046ccd1
EL
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
de1d0a69 145_start_warm:
f046ccd1
EL
146 li r21, BOOTFLAG_WARM /* Software reboot */
147 b boot_warm
148
149
150boot_cold: /* time t 3 */
151 lis r4, CONFIG_DEFAULT_IMMR@h
152 nop
153boot_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)
de1d0a69 158
f046ccd1
EL
159 /* Initialise the E300 processor core */
160 /*------------------------------------------*/
de1d0a69 161
f046ccd1 162 bl init_e300_core
de1d0a69 163
f046ccd1
EL
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
176in_flash:
177#if 1 /* Remapping flash with LAW0. */
178 bl remap_flash_by_law0
179#endif
180#endif /* CFG_RAMBOOT */
181
182 bl setup_stack_in_data_cache_on_r1
183
184 /* let the C-code set up the rest */
185 /* */
186 /* Be careful to keep code relocatable & stack humble */
187 /*------------------------------------------------------*/
188
189 GET_GOT /* initialize GOT access */
190
191 /* r3: IMMR */
192 lis r3, CFG_IMMRBAR@h
193 /* run low-level CPU init code (in Flash)*/
194 bl cpu_init_f
195
196 /* r3: BOOTFLAG */
197 mr r3, r21
198 /* run 1st part of board init code (in Flash)*/
199 bl board_init_f
200
201/*
202 * Vector Table
203 */
204
205 .globl _start_of_vectors
206_start_of_vectors:
207
208/* Machine check */
209 STD_EXCEPTION(0x200, MachineCheck, MachineCheckException)
210
211/* Data Storage exception. */
212 STD_EXCEPTION(0x300, DataStorage, UnknownException)
213
214/* Instruction Storage exception. */
215 STD_EXCEPTION(0x400, InstStorage, UnknownException)
216
217/* External Interrupt exception. */
218#ifndef FIXME
219 STD_EXCEPTION(0x500, ExtInterrupt, external_interrupt)
de1d0a69 220#endif
f046ccd1
EL
221
222/* Alignment exception. */
223 . = 0x600
224Alignment:
225 EXCEPTION_PROLOG
226 mfspr r4,DAR
227 stw r4,_DAR(r21)
228 mfspr r5,DSISR
229 stw r5,_DSISR(r21)
230 addi r3,r1,STACK_FRAME_OVERHEAD
231 li r20,MSR_KERNEL
232 rlwimi r20,r23,0,16,16 /* copy EE bit from saved MSR */
233 rlwimi r20,r23,0,25,25 /* copy IP bit from saved MSR */
234 lwz r6,GOT(transfer_to_handler)
235 mtlr r6
236 blrl
237.L_Alignment:
238 .long AlignmentException - _start + EXC_OFF_SYS_RESET
239 .long int_return - _start + EXC_OFF_SYS_RESET
240
241/* Program check exception */
242 . = 0x700
243ProgramCheck:
244 EXCEPTION_PROLOG
245 addi r3,r1,STACK_FRAME_OVERHEAD
246 li r20,MSR_KERNEL
247 rlwimi r20,r23,0,16,16 /* copy EE bit from saved MSR */
248 rlwimi r20,r23,0,25,25 /* copy IP bit from saved MSR */
249 lwz r6,GOT(transfer_to_handler)
250 mtlr r6
251 blrl
252.L_ProgramCheck:
253 .long ProgramCheckException - _start + EXC_OFF_SYS_RESET
254 .long int_return - _start + EXC_OFF_SYS_RESET
255
256 STD_EXCEPTION(0x800, FPUnavailable, UnknownException)
257
258 /* I guess we could implement decrementer, and may have
259 * to someday for timekeeping.
260 */
261 STD_EXCEPTION(0x900, Decrementer, timer_interrupt)
262
263 STD_EXCEPTION(0xa00, Trap_0a, UnknownException)
264 STD_EXCEPTION(0xb00, Trap_0b, UnknownException)
265 STD_EXCEPTION(0xc00, SystemCall, UnknownException)
266 STD_EXCEPTION(0xd00, SingleStep, UnknownException)
267
268 STD_EXCEPTION(0xe00, Trap_0e, UnknownException)
269 STD_EXCEPTION(0xf00, Trap_0f, UnknownException)
270
271 STD_EXCEPTION(0x1000, InstructionTLBMiss, UnknownException)
272 STD_EXCEPTION(0x1100, DataLoadTLBMiss, UnknownException)
273 STD_EXCEPTION(0x1200, DataStoreTLBMiss, UnknownException)
274#ifdef DEBUG
275 . = 0x1300
276 /*
277 * This exception occurs when the program counter matches the
278 * Instruction Address Breakpoint Register (IABR).
279 *
280 * I want the cpu to halt if this occurs so I can hunt around
281 * with the debugger and look at things.
282 *
283 * When DEBUG is defined, both machine check enable (in the MSR)
284 * and checkstop reset enable (in the reset mode register) are
285 * turned off and so a checkstop condition will result in the cpu
286 * halting.
287 *
288 * I force the cpu into a checkstop condition by putting an illegal
289 * instruction here (at least this is the theory).
290 *
291 * well - that didnt work, so just do an infinite loop!
292 */
2931: b 1b
294#else
295 STD_EXCEPTION(0x1300, InstructionBreakpoint, DebugException)
296#endif
297 STD_EXCEPTION(0x1400, SMI, UnknownException)
298
299 STD_EXCEPTION(0x1500, Trap_15, UnknownException)
300 STD_EXCEPTION(0x1600, Trap_16, UnknownException)
301 STD_EXCEPTION(0x1700, Trap_17, UnknownException)
302 STD_EXCEPTION(0x1800, Trap_18, UnknownException)
303 STD_EXCEPTION(0x1900, Trap_19, UnknownException)
304 STD_EXCEPTION(0x1a00, Trap_1a, UnknownException)
305 STD_EXCEPTION(0x1b00, Trap_1b, UnknownException)
306 STD_EXCEPTION(0x1c00, Trap_1c, UnknownException)
307 STD_EXCEPTION(0x1d00, Trap_1d, UnknownException)
308 STD_EXCEPTION(0x1e00, Trap_1e, UnknownException)
309 STD_EXCEPTION(0x1f00, Trap_1f, UnknownException)
310 STD_EXCEPTION(0x2000, Trap_20, UnknownException)
311 STD_EXCEPTION(0x2100, Trap_21, UnknownException)
312 STD_EXCEPTION(0x2200, Trap_22, UnknownException)
313 STD_EXCEPTION(0x2300, Trap_23, UnknownException)
314 STD_EXCEPTION(0x2400, Trap_24, UnknownException)
315 STD_EXCEPTION(0x2500, Trap_25, UnknownException)
316 STD_EXCEPTION(0x2600, Trap_26, UnknownException)
317 STD_EXCEPTION(0x2700, Trap_27, UnknownException)
318 STD_EXCEPTION(0x2800, Trap_28, UnknownException)
319 STD_EXCEPTION(0x2900, Trap_29, UnknownException)
320 STD_EXCEPTION(0x2a00, Trap_2a, UnknownException)
321 STD_EXCEPTION(0x2b00, Trap_2b, UnknownException)
322 STD_EXCEPTION(0x2c00, Trap_2c, UnknownException)
323 STD_EXCEPTION(0x2d00, Trap_2d, UnknownException)
324 STD_EXCEPTION(0x2e00, Trap_2e, UnknownException)
325 STD_EXCEPTION(0x2f00, Trap_2f, UnknownException)
326
327
328 .globl _end_of_vectors
329_end_of_vectors:
330
331 . = 0x3000
332
333/*
334 * This code finishes saving the registers to the exception frame
335 * and jumps to the appropriate handler for the exception.
336 * Register r21 is pointer into trap frame, r1 has new stack pointer.
337 */
338 .globl transfer_to_handler
339transfer_to_handler:
340 stw r22,_NIP(r21)
341 lis r22,MSR_POW@h
342 andc r23,r23,r22
343 stw r23,_MSR(r21)
344 SAVE_GPR(7, r21)
345 SAVE_4GPRS(8, r21)
346 SAVE_8GPRS(12, r21)
347 SAVE_8GPRS(24, r21)
348 mflr r23
349 andi. r24,r23,0x3f00 /* get vector offset */
350 stw r24,TRAP(r21)
351 li r22,0
352 stw r22,RESULT(r21)
353 lwz r24,0(r23) /* virtual address of handler */
354 lwz r23,4(r23) /* where to go when done */
355 mtspr SRR0,r24
356 mtspr SRR1,r20
357 mtlr r23
358 SYNC
359 rfi /* jump to handler, enable MMU */
360
361int_return:
362 mfmsr r28 /* Disable interrupts */
363 li r4,0
364 ori r4,r4,MSR_EE
365 andc r28,r28,r4
366 SYNC /* Some chip revs need this... */
367 mtmsr r28
368 SYNC
369 lwz r2,_CTR(r1)
370 lwz r0,_LINK(r1)
371 mtctr r2
372 mtlr r0
373 lwz r2,_XER(r1)
374 lwz r0,_CCR(r1)
375 mtspr XER,r2
376 mtcrf 0xFF,r0
377 REST_10GPRS(3, r1)
378 REST_10GPRS(13, r1)
379 REST_8GPRS(23, r1)
380 REST_GPR(31, r1)
381 lwz r2,_NIP(r1) /* Restore environment */
382 lwz r0,_MSR(r1)
383 mtspr SRR0,r2
384 mtspr SRR1,r0
385 lwz r0,GPR0(r1)
386 lwz r2,GPR2(r1)
387 lwz r1,GPR1(r1)
388 SYNC
389 rfi
390
391/*
392 * This code initialises the E300 processor core
393 * (conforms to PowerPC 603e spec)
394 * Note: expects original MSR contents to be in r5.
395 */
396 .globl init_e300_core
397init_e300_core: /* time t 10 */
398 /* Initialize machine status; enable machine check interrupt */
399 /*-----------------------------------------------------------*/
400
401 li r3, MSR_KERNEL /* Set ME and RI flags */
402 rlwimi r3, r5, 0, 25, 25 /* preserve IP bit set by HRCW */
403#ifdef DEBUG
404 rlwimi r3, r5, 0, 21, 22 /* debugger might set SE & BE bits */
405#endif
406 SYNC /* Some chip revs need this... */
407 mtmsr r3
408 SYNC
409 mtspr SRR1, r3 /* Make SRR1 match MSR */
410
411
412 lis r3, CFG_IMMRBAR@h
413#if defined(CONFIG_WATCHDOG)
414 /* Initialise the Wathcdog values and reset it (if req) */
415 /*------------------------------------------------------*/
416 lis r4, CFG_WATCHDOG_VALUE
417 ori r4, r4, (SWCRR_SWEN | SWCRR_SWRI | SWCRR_SWPR)
418 stw r4, SWCRR(r3)
de1d0a69 419
f046ccd1 420 /* and reset it */
de1d0a69 421
f046ccd1
EL
422 li r4, 0x556C
423 sth r4, SWSRR@l(r3)
424 li r4, 0xAA39
425 sth r4, SWSRR@l(r3)
426#else
427 /* Disable Wathcdog */
428 /*-------------------*/
ec00c335
KG
429 lwz r4, SWCRR(r3)
430 /* Check to see if its enabled for disabling
431 once disabled by SW you can't re-enable */
432 andi. r4, r4, 0x4
433 beq 1f
f046ccd1
EL
434 xor r4, r4, r4
435 stw r4, SWCRR(r3)
ec00c335 4361:
f046ccd1
EL
437#endif /* CONFIG_WATCHDOG */
438
439 /* Initialize the Hardware Implementation-dependent Registers */
440 /* HID0 also contains cache control */
441 /*------------------------------------------------------*/
442
443 lis r3, CFG_HID0_INIT@h
444 ori r3, r3, CFG_HID0_INIT@l
445 SYNC
446 mtspr HID0, r3
447
448 lis r3, CFG_HID0_FINAL@h
449 ori r3, r3, CFG_HID0_FINAL@l
450 SYNC
451 mtspr HID0, r3
452
453 lis r3, CFG_HID2@h
454 ori r3, r3, CFG_HID2@l
455 SYNC
456 mtspr HID2, r3
457
458 /* clear all BAT's */
459 /*----------------------------------*/
460
461 xor r0, r0, r0
462 mtspr DBAT0U, r0
463 mtspr DBAT0L, r0
464 mtspr DBAT1U, r0
465 mtspr DBAT1L, r0
466 mtspr DBAT2U, r0
467 mtspr DBAT2L, r0
468 mtspr DBAT3U, r0
469 mtspr DBAT3L, r0
470 mtspr IBAT0U, r0
471 mtspr IBAT0L, r0
472 mtspr IBAT1U, r0
473 mtspr IBAT1L, r0
474 mtspr IBAT2U, r0
475 mtspr IBAT2L, r0
476 mtspr IBAT3U, r0
477 mtspr IBAT3L, r0
478 SYNC
479
480 /* invalidate all tlb's
481 *
482 * From the 603e User Manual: "The 603e provides the ability to
483 * invalidate a TLB entry. The TLB Invalidate Entry (tlbie)
484 * instruction invalidates the TLB entry indexed by the EA, and
485 * operates on both the instruction and data TLBs simultaneously
486 * invalidating four TLB entries (both sets in each TLB). The
487 * index corresponds to bits 15-19 of the EA. To invalidate all
488 * entries within both TLBs, 32 tlbie instructions should be
489 * issued, incrementing this field by one each time."
490 *
491 * "Note that the tlbia instruction is not implemented on the
492 * 603e."
493 *
494 * bits 15-19 correspond to addresses 0x00000000 to 0x0001F000
495 * incrementing by 0x1000 each time. The code below is sort of
496 * based on code in "flush_tlbs" from arch/ppc/kernel/head.S
497 *
498 */
499
500 li r3, 32
501 mtctr r3
502 li r3, 0
5031: tlbie r3
504 addi r3, r3, 0x1000
505 bdnz 1b
506 SYNC
507
508 /* Done! */
509 /*------------------------------*/
de1d0a69 510 blr
f046ccd1
EL
511
512/* Cache functions.
513 *
514 * Note: requires that all cache bits in
515 * HID0 are in the low half word.
516 */
517 .globl icache_enable
518icache_enable:
519 mfspr r3, HID0
520 ori r3, r3, HID0_ICE
521 lis r4, 0
522 ori r4, r4, HID0_ILOCK
523 andc r3, r3, r4
524 ori r4, r3, HID0_ICFI
525 isync
526 mtspr HID0, r4 /* sets enable and invalidate, clears lock */
527 isync
528 mtspr HID0, r3 /* clears invalidate */
529 blr
530
531 .globl icache_disable
532icache_disable:
533 mfspr r3, HID0
534 lis r4, 0
535 ori r4, r4, HID0_ICE|HID0_ILOCK
536 andc r3, r3, r4
537 ori r4, r3, HID0_ICFI
538 isync
539 mtspr HID0, r4 /* sets invalidate, clears enable and lock*/
540 isync
541 mtspr HID0, r3 /* clears invalidate */
542 blr
543
544 .globl icache_status
545icache_status:
546 mfspr r3, HID0
547 rlwinm r3, r3, HID0_ICE_SHIFT, 31, 31
548 blr
549
550 .globl dcache_enable
551dcache_enable:
552 mfspr r3, HID0
553 ori r3, r3, HID0_ENABLE_DATA_CACHE
554 lis r4, 0
555 ori r4, r4, HID0_LOCK_DATA_CACHE
556 andc r3, r3, r4
557 ori r4, r3, HID0_LOCK_INSTRUCTION_CACHE
558 sync
559 mtspr HID0, r4 /* sets enable and invalidate, clears lock */
560 sync
561 mtspr HID0, r3 /* clears invalidate */
562 blr
563
564 .globl dcache_disable
565dcache_disable:
566 mfspr r3, HID0
567 lis r4, 0
568 ori r4, r4, HID0_ENABLE_DATA_CACHE|HID0_LOCK_DATA_CACHE
569 andc r3, r3, r4
570 ori r4, r3, HID0_INVALIDATE_DATA_CACHE
571 sync
572 mtspr HID0, r4 /* sets invalidate, clears enable and lock */
573 sync
574 mtspr HID0, r3 /* clears invalidate */
575 blr
576
577 .globl dcache_status
578dcache_status:
579 mfspr r3, HID0
580 rlwinm r3, r3, HID0_DCE_SHIFT, 31, 31
581 blr
582
583 .globl get_pvr
584get_pvr:
585 mfspr r3, PVR
586 blr
587
588/*-------------------------------------------------------------------*/
589
590/*
591 * void relocate_code (addr_sp, gd, addr_moni)
592 *
593 * This "function" does not return, instead it continues in RAM
594 * after relocating the monitor code.
595 *
596 * r3 = dest
597 * r4 = src
598 * r5 = length in bytes
599 * r6 = cachelinesize
600 */
601 .globl relocate_code
602relocate_code:
603 mr r1, r3 /* Set new stack pointer */
604 mr r9, r4 /* Save copy of Global Data pointer */
605 mr r10, r5 /* Save copy of Destination Address */
606
607 mr r3, r5 /* Destination Address */
608 lis r4, CFG_MONITOR_BASE@h /* Source Address */
609 ori r4, r4, CFG_MONITOR_BASE@l
610 lwz r5, GOT(__init_end)
611 sub r5, r5, r4
612 li r6, CFG_CACHELINE_SIZE /* Cache Line Size */
613
614 /*
615 * Fix GOT pointer:
616 *
617 * New GOT-PTR = (old GOT-PTR - CFG_MONITOR_BASE)
618 * + Destination Address
619 *
620 * Offset:
621 */
622 sub r15, r10, r4
623
624 /* First our own GOT */
625 add r14, r14, r15
626 /* then the one used by the C code */
627 add r30, r30, r15
628
629 /*
630 * Now relocate code
631 */
632
633 cmplw cr1,r3,r4
634 addi r0,r5,3
635 srwi. r0,r0,2
636 beq cr1,4f /* In place copy is not necessary */
637 beq 7f /* Protect against 0 count */
638 mtctr r0
639 bge cr1,2f
640 la r8,-4(r4)
641 la r7,-4(r3)
642
643 /* copy */
6441: lwzu r0,4(r8)
645 stwu r0,4(r7)
646 bdnz 1b
647
648 addi r0,r5,3
649 srwi. r0,r0,2
650 mtctr r0
651 la r8,-4(r4)
652 la r7,-4(r3)
de1d0a69
JL
653
654 /* and compare */
f046ccd1
EL
65520: lwzu r20,4(r8)
656 lwzu r21,4(r7)
657 xor. r22, r20, r21
658 bne 30f
659 bdnz 20b
660 b 4f
661
662 /* compare failed */
66330: li r3, 0
664 blr
665
6662: slwi r0,r0,2 /* re copy in reverse order ... y do we needed it? */
667 add r8,r4,r0
668 add r7,r3,r0
6693: lwzu r0,-4(r8)
670 stwu r0,-4(r7)
671 bdnz 3b
f046ccd1
EL
672
673/*
674 * Now flush the cache: note that we must start from a cache aligned
675 * address. Otherwise we might miss one cache line.
676 */
de1d0a69 6774:
f046ccd1
EL
678 bl un_setup_stack_in_data_cache
679 mr r7, r3
680 mr r8, r4
681 bl dcache_disable
682 mr r3, r7
683 mr r4, r8
de1d0a69 684
f046ccd1
EL
685 cmpwi r6,0
686 add r5,r3,r5
687 beq 7f /* Always flush prefetch queue in any case */
688 subi r0,r6,1
689 andc r3,r3,r0
690 mfspr r7,HID0 /* don't do dcbst if dcache is disabled*/
691 rlwinm r7,r7,HID0_DCE_SHIFT,31,31
692 cmpwi r7,0
693 beq 9f
694 mr r4,r3
6955: dcbst 0,r4
696 add r4,r4,r6
697 cmplw r4,r5
698 blt 5b
699 sync /* Wait for all dcbst to complete on bus */
7009: mfspr r7,HID0 /* don't do icbi if icache is disabled */
701 rlwinm r7,r7,HID0_DCE_SHIFT,31,31
702 cmpwi r7,0
703 beq 7f
704 mr r4,r3
7056: icbi 0,r4
706 add r4,r4,r6
707 cmplw r4,r5
708 blt 6b
7097: sync /* Wait for all icbi to complete on bus */
710 isync
711
712/*
713 * We are done. Do not return, instead branch to second part of board
714 * initialization, now running from RAM.
715 */
716
717 addi r0, r10, in_ram - _start + EXC_OFF_SYS_RESET
718 mtlr r0
719 blr
720
721in_ram:
722
723 /*
724 * Relocation Function, r14 point to got2+0x8000
725 *
726 * Adjust got2 pointers, no need to check for 0, this code
727 * already puts a few entries in the table.
728 */
729 li r0,__got2_entries@sectoff@l
730 la r3,GOT(_GOT2_TABLE_)
731 lwz r11,GOT(_GOT2_TABLE_)
732 mtctr r0
733 sub r11,r3,r11
734 addi r3,r3,-4
7351: lwzu r0,4(r3)
736 add r0,r0,r11
737 stw r0,0(r3)
738 bdnz 1b
739
740 /*
741 * Now adjust the fixups and the pointers to the fixups
742 * in case we need to move ourselves again.
743 */
7442: li r0,__fixup_entries@sectoff@l
745 lwz r3,GOT(_FIXUP_TABLE_)
746 cmpwi r0,0
747 mtctr r0
748 addi r3,r3,-4
749 beq 4f
7503: lwzu r4,4(r3)
751 lwzux r0,r4,r11
752 add r0,r0,r11
753 stw r10,0(r3)
754 stw r0,0(r4)
755 bdnz 3b
7564:
757clear_bss:
758 /*
759 * Now clear BSS segment
760 */
761 lwz r3,GOT(__bss_start)
762#if defined(CONFIG_HYMOD)
763 /*
764 * For HYMOD - the environment is the very last item in flash.
765 * The real .bss stops just before environment starts, so only
766 * clear up to that point.
767 *
768 * taken from mods for FADS board
769 */
770 lwz r4,GOT(environment)
771#else
772 lwz r4,GOT(_end)
773#endif
774
775 cmplw 0, r3, r4
776 beq 6f
777
778 li r0, 0
7795:
780 stw r0, 0(r3)
781 addi r3, r3, 4
782 cmplw 0, r3, r4
783 bne 5b
7846:
785
786 mr r3, r9 /* Global Data pointer */
787 mr r4, r10 /* Destination Address */
788 bl board_init_r
789
790 /*
791 * Copy exception vector code to low memory
792 *
793 * r3: dest_addr
794 * r7: source address, r8: end address, r9: target address
795 */
796 .globl trap_init
797trap_init:
798 lwz r7, GOT(_start)
799 lwz r8, GOT(_end_of_vectors)
800
801 li r9, 0x100 /* reset vector always at 0x100 */
802
803 cmplw 0, r7, r8
804 bgelr /* return if r7>=r8 - just in case */
805
806 mflr r4 /* save link register */
8071:
808 lwz r0, 0(r7)
809 stw r0, 0(r9)
810 addi r7, r7, 4
811 addi r9, r9, 4
812 cmplw 0, r7, r8
813 bne 1b
814
815 /*
816 * relocate `hdlr' and `int_return' entries
817 */
818 li r7, .L_MachineCheck - _start + EXC_OFF_SYS_RESET
819 li r8, Alignment - _start + EXC_OFF_SYS_RESET
8202:
821 bl trap_reloc
822 addi r7, r7, 0x100 /* next exception vector */
823 cmplw 0, r7, r8
824 blt 2b
825
826 li r7, .L_Alignment - _start + EXC_OFF_SYS_RESET
827 bl trap_reloc
828
829 li r7, .L_ProgramCheck - _start + EXC_OFF_SYS_RESET
830 bl trap_reloc
831
832 li r7, .L_FPUnavailable - _start + EXC_OFF_SYS_RESET
833 li r8, SystemCall - _start + EXC_OFF_SYS_RESET
8343:
835 bl trap_reloc
836 addi r7, r7, 0x100 /* next exception vector */
837 cmplw 0, r7, r8
838 blt 3b
839
840 li r7, .L_SingleStep - _start + EXC_OFF_SYS_RESET
841 li r8, _end_of_vectors - _start + EXC_OFF_SYS_RESET
8424:
843 bl trap_reloc
844 addi r7, r7, 0x100 /* next exception vector */
845 cmplw 0, r7, r8
846 blt 4b
847
848 mfmsr r3 /* now that the vectors have */
849 lis r7, MSR_IP@h /* relocated into low memory */
850 ori r7, r7, MSR_IP@l /* MSR[IP] can be turned off */
851 andc r3, r3, r7 /* (if it was on) */
852 SYNC /* Some chip revs need this... */
853 mtmsr r3
854 SYNC
855
856 mtlr r4 /* restore link register */
857 blr
858
859 /*
860 * Function: relocate entries for one exception vector
861 */
862trap_reloc:
863 lwz r0, 0(r7) /* hdlr ... */
864 add r0, r0, r3 /* ... += dest_addr */
865 stw r0, 0(r7)
866
867 lwz r0, 4(r7) /* int_return ... */
868 add r0, r0, r3 /* ... += dest_addr */
869 stw r0, 4(r7)
870
871 blr
872
873#ifdef CFG_INIT_RAM_LOCK
874.globl unlock_ram_in_cache
875unlock_ram_in_cache:
876 /* invalidate the INIT_RAM section */
877 lis r3, (CFG_INIT_RAM_ADDR & ~31)@h
878 ori r3, r3, (CFG_INIT_RAM_ADDR & ~31)@l
879 li r2,512
880 mtctr r2
8811: icbi r0, r3
882 dcbi r0, r3
883 addi r3, r3, 32
884 bdnz 1b
885 sync /* Wait for all icbi to complete on bus */
886 isync
887 blr
888#endif
889
890map_flash_by_law1:
891 /* When booting from ROM (Flash or EPROM), clear the */
892 /* Address Mask in OR0 so ROM appears everywhere */
893 /*----------------------------------------------------*/
894 lis r3, (CFG_IMMRBAR)@h /* r3 <= CFG_IMMRBAR */
de1d0a69 895 lwz r4, OR0@l(r3)
f046ccd1 896 li r5, 0x7fff /* r5 <= 0x00007FFFF */
de1d0a69 897 and r4, r4, r5
f046ccd1
EL
898 stw r4, OR0@l(r3) /* OR0 <= OR0 & 0x00007FFFF */
899
900 /* As MPC8349E User's Manual presented, when RCW[BMS] is set to 0,
901 * system will boot from 0x0000_0100, and the LBLAWBAR0[BASE_ADDR]
902 * reset value is 0x00000; when RCW[BMS] is set to 1, system will boot
903 * from 0xFFF0_0100, and the LBLAWBAR0[BASE_ADDR] reset value is
904 * 0xFF800. From the hard resetting to here, the processor fetched and
905 * executed the instructions one by one. There is not absolutely
906 * jumping happened. Laterly, the u-boot code has to do an absolutely
907 * jumping to tell the CPU instruction fetching component what the
908 * u-boot TEXT base address is. Because the TEXT base resides in the
909 * boot ROM memory space, to garantee the code can run smoothly after
910 * that jumping, we must map in the entire boot ROM by Local Access
911 * Window. Sometimes, we desire an non-0x00000 or non-0xFF800 starting
912 * address for boot ROM, such as 0xFE000000. In this case, the default
913 * LBIU Local Access Widow 0 will not cover this memory space. So, we
914 * need another window to map in it.
915 */
916 lis r4, (CFG_FLASH_BASE)@h
917 ori r4, r4, (CFG_FLASH_BASE)@l
918 stw r4, LBLAWBAR1(r3) /* LBLAWBAR1 <= CFG_FLASH_BASE */
919 lis r4, (0x80000016)@h
920 ori r4, r4, (0x80000016)@l
921 stw r4, LBLAWAR1(r3) /* LBLAWAR1 <= 8MB Flash Size */
922 blr
923
924 /* Though all the LBIU Local Access Windows and LBC Banks will be
925 * initialized in the C code, we'd better configure boot ROM's
926 * window 0 and bank 0 correctly at here.
927 */
928remap_flash_by_law0:
929 /* Initialize the BR0 with the boot ROM starting address. */
930 lwz r4, BR0(r3)
931 li r5, 0x7FFF
de1d0a69 932 and r4, r4, r5
f046ccd1 933 lis r5, (CFG_FLASH_BASE & 0xFFFF8000)@h
de1d0a69 934 ori r5, r5, (CFG_FLASH_BASE & 0xFFFF8000)@l
f046ccd1
EL
935 or r5, r5, r4
936 stw r5, BR0(r3) /* r5 <= (CFG_FLASH_BASE & 0xFFFF8000) | (BR0 & 0x00007FFF) */
937
938 lwz r4, OR0(r3)
939 lis r5, 0xFF80 /* 8M */
940 or r4, r4, r5
941 stw r4, OR0(r3) /* OR0 <= OR0 | 0xFF800000 */
942
943 lis r4, (CFG_FLASH_BASE)@h
944 ori r4, r4, (CFG_FLASH_BASE)@l
945 stw r4, LBLAWBAR0(r3) /* LBLAWBAR0 <= CFG_FLASH_BASE */
946
947 lis r4, (0x80000016)@h
948 ori r4, r4, (0x80000016)@l
949 stw r4, LBLAWAR0(r3) /* LBLAWAR0 <= 8MB Flash Size */
950
951 xor r4, r4, r4
952 stw r4, LBLAWBAR1(r3)
953 stw r4, LBLAWAR1(r3) /* Off LBIU LAW1 */
954 blr
955
de1d0a69 956setup_stack_in_data_cache_on_r1:
f046ccd1 957 lis r3, (CFG_IMMRBAR)@h
de1d0a69 958
f046ccd1
EL
959 /* setup D-BAT for the D-Cache (with out real memory backup) */
960
961 lis r4, (CFG_INIT_RAM_ADDR & 0xFFFE0000)@h
962 mtspr DBAT0U, r4
963 ori r4, r4, 0x0002
964 mtspr DBAT0L, r4
965 isync
966
de1d0a69 967#if 0
f046ccd1
EL
968 /* Enable MMU */
969 mfmsr r4
970 ori r4, r4, (MSR_DR | MSR_IR)@l
971 mtmsr r4
de1d0a69
JL
972#endif
973
f046ccd1
EL
974 /* Enable and invalidate data cache. */
975 mfspr r4, HID0
976 mr r5, r4
977 ori r4, r4, HID0_DCE | HID0_DCI
978 ori r5, r5, HID0_DCE
979 sync
980 mtspr HID0, r4
981 mtspr HID0, r5
982 sync
de1d0a69 983
f046ccd1
EL
984 /* Allocate Initial RAM in data cache.*/
985 li r0, 0
986 lis r4, (CFG_INIT_RAM_ADDR)@h
987 ori r4, r4, (CFG_INIT_RAM_ADDR)@l
de1d0a69 988 li r5, 128*8 /* 128*8*32=32Kb */
f046ccd1
EL
989 mtctr r5
9901:
991 dcbz r0, r4
992 addi r4, r4, 32
993 bdnz 1b
994 isync
de1d0a69 995
f046ccd1
EL
996 /* Lock all the D-cache, basically leaving the reset of the program without dcache */
997 mfspr r4, HID0
998 ori r4, r4, (HID0_DLOCK)@l
999 sync
1000 mtspr HID0 , r4
1001
1002 /* setup the stack pointer in r1 */
1003 lis r1, (CFG_INIT_RAM_ADDR + CFG_GBL_DATA_OFFSET)@h
1004 ori r1, r1, (CFG_INIT_RAM_ADDR + CFG_GBL_DATA_OFFSET)@l
1005 li r0, 0 /* Make room for stack frame header and */
1006
1007 stwu r0, -4(r1) /* clear final stack frame so that */
1008 stwu r0, -4(r1) /* stack backtraces terminate cleanly */
1009
1010 blr
1011
1012un_setup_stack_in_data_cache:
1013 blr
1014 mr r14, r4
1015 mr r15, r5
de1d0a69 1016
f046ccd1
EL
1017
1018 lis r4, (CFG_INIT_RAM_ADDR & 0xFFFE0000)@h
1019 mtspr DBAT0U, r4
1020 ori r4, r4, 0x0002
1021 mtspr DBAT0L, r4
1022 isync
de1d0a69 1023
f046ccd1
EL
1024 /* un lock all the D-cache */
1025 mfspr r4, HID0
1026 lis r5, (~(HID0_DLOCK))@h
1027 ori r5, r5, (~(HID0_DLOCK))@l
1028 and r4, r4, r5
1029 sync
1030 mtspr HID0 , r4
1031
1032 /* Re - Allocate Initial RAM in data cache.*/
1033 li r0, 0
1034 lis r4, (CFG_INIT_RAM_ADDR)@h
1035 ori r4, r4, (CFG_INIT_RAM_ADDR)@l
de1d0a69 1036 li r5, 128*8 /* 128*8*32=32Kb */
f046ccd1
EL
1037 mtctr r5
10381:
1039 dcbz r0, r4
1040 addi r4, r4, 32
1041 bdnz 1b
1042 isync
de1d0a69 1043
f046ccd1
EL
1044 mflr r16
1045 bl dcache_disable
1046 mtlr r16
de1d0a69 1047
f046ccd1 1048 blr
de1d0a69 1049
f046ccd1
EL
1050#if 0
1051#define GREEN_LIGHT 0x2B0D4046
1052#define RED_LIGHT 0x250D4046
1053#define LIB_CNT 0x4FFF
1054
1055/*
1056 * Lib Light
1057 */
1058
1059 .globl liblight
de1d0a69 1060liblight:
f046ccd1
EL
1061 lis r3, CFG_IMMRBAR@h
1062 ori r3, r3, CFG_IMMRBAR@l
1063 li r4, 0x3002
1064 mtmsr r4
1065 xor r4, r4, r4
1066 mtspr HID0, r4
1067 mtspr HID2, r4
1068 lis r4, 0xF8000000@h
de1d0a69 1069 ori r4, r4, 0xF8000000@l
f046ccd1
EL
1070 stw r4, LBLAWBAR1(r3)
1071 lis r4, 0x8000000E@h
1072 ori r4, r4, 0x8000000E@l
1073 stw r4, LBLAWAR1(r3)
1074 lis r4, 0xF8000801@h
1075 ori r4, r4, 0xF8000801@l
1076 stw r4, BR1(r3)
1077 lis r4, 0xFFFFE8f0@h
1078 ori r4, r4, 0xFFFFE8f0@l
1079 stw r4, OR1(r3)
1080
1081 lis r4, 0xF8000000@h
1082 ori r4, r4, 0xF8000000@l
1083 lis r5, GREEN_LIGHT@h
1084 ori r5, r5, GREEN_LIGHT@l
1085 lis r6, RED_LIGHT@h
1086 ori r6, r6, RED_LIGHT@l
1087 lis r7, LIB_CNT@h
1088 ori r7, r7, LIB_CNT@l
de1d0a69 1089
f046ccd1
EL
10901:
1091 stw r5, 0(r4)
de1d0a69 1092 mtctr r7
f046ccd1
EL
10932: bdnz 2b
1094 stw r6, 0(r4)
de1d0a69 1095 mtctr r7
f046ccd1
EL
10963: bdnz 3b
1097 b 1b
de1d0a69 1098
f046ccd1 1099#endif