]> git.ipfire.org Git - people/ms/u-boot.git/blame - cpu/mpc83xx/start.S
Fix style issues primarily in 85xx and 83xx boards.
[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 /*-------------------*/
429 xor r4, r4, r4
430 stw r4, SWCRR(r3)
431#endif /* CONFIG_WATCHDOG */
432
433 /* Initialize the Hardware Implementation-dependent Registers */
434 /* HID0 also contains cache control */
435 /*------------------------------------------------------*/
436
437 lis r3, CFG_HID0_INIT@h
438 ori r3, r3, CFG_HID0_INIT@l
439 SYNC
440 mtspr HID0, r3
441
442 lis r3, CFG_HID0_FINAL@h
443 ori r3, r3, CFG_HID0_FINAL@l
444 SYNC
445 mtspr HID0, r3
446
447 lis r3, CFG_HID2@h
448 ori r3, r3, CFG_HID2@l
449 SYNC
450 mtspr HID2, r3
451
452 /* clear all BAT's */
453 /*----------------------------------*/
454
455 xor r0, r0, r0
456 mtspr DBAT0U, r0
457 mtspr DBAT0L, r0
458 mtspr DBAT1U, r0
459 mtspr DBAT1L, r0
460 mtspr DBAT2U, r0
461 mtspr DBAT2L, r0
462 mtspr DBAT3U, r0
463 mtspr DBAT3L, r0
464 mtspr IBAT0U, r0
465 mtspr IBAT0L, r0
466 mtspr IBAT1U, r0
467 mtspr IBAT1L, r0
468 mtspr IBAT2U, r0
469 mtspr IBAT2L, r0
470 mtspr IBAT3U, r0
471 mtspr IBAT3L, r0
472 SYNC
473
474 /* invalidate all tlb's
475 *
476 * From the 603e User Manual: "The 603e provides the ability to
477 * invalidate a TLB entry. The TLB Invalidate Entry (tlbie)
478 * instruction invalidates the TLB entry indexed by the EA, and
479 * operates on both the instruction and data TLBs simultaneously
480 * invalidating four TLB entries (both sets in each TLB). The
481 * index corresponds to bits 15-19 of the EA. To invalidate all
482 * entries within both TLBs, 32 tlbie instructions should be
483 * issued, incrementing this field by one each time."
484 *
485 * "Note that the tlbia instruction is not implemented on the
486 * 603e."
487 *
488 * bits 15-19 correspond to addresses 0x00000000 to 0x0001F000
489 * incrementing by 0x1000 each time. The code below is sort of
490 * based on code in "flush_tlbs" from arch/ppc/kernel/head.S
491 *
492 */
493
494 li r3, 32
495 mtctr r3
496 li r3, 0
4971: tlbie r3
498 addi r3, r3, 0x1000
499 bdnz 1b
500 SYNC
501
502 /* Done! */
503 /*------------------------------*/
de1d0a69 504 blr
f046ccd1
EL
505
506/* Cache functions.
507 *
508 * Note: requires that all cache bits in
509 * HID0 are in the low half word.
510 */
511 .globl icache_enable
512icache_enable:
513 mfspr r3, HID0
514 ori r3, r3, HID0_ICE
515 lis r4, 0
516 ori r4, r4, HID0_ILOCK
517 andc r3, r3, r4
518 ori r4, r3, HID0_ICFI
519 isync
520 mtspr HID0, r4 /* sets enable and invalidate, clears lock */
521 isync
522 mtspr HID0, r3 /* clears invalidate */
523 blr
524
525 .globl icache_disable
526icache_disable:
527 mfspr r3, HID0
528 lis r4, 0
529 ori r4, r4, HID0_ICE|HID0_ILOCK
530 andc r3, r3, r4
531 ori r4, r3, HID0_ICFI
532 isync
533 mtspr HID0, r4 /* sets invalidate, clears enable and lock*/
534 isync
535 mtspr HID0, r3 /* clears invalidate */
536 blr
537
538 .globl icache_status
539icache_status:
540 mfspr r3, HID0
541 rlwinm r3, r3, HID0_ICE_SHIFT, 31, 31
542 blr
543
544 .globl dcache_enable
545dcache_enable:
546 mfspr r3, HID0
547 ori r3, r3, HID0_ENABLE_DATA_CACHE
548 lis r4, 0
549 ori r4, r4, HID0_LOCK_DATA_CACHE
550 andc r3, r3, r4
551 ori r4, r3, HID0_LOCK_INSTRUCTION_CACHE
552 sync
553 mtspr HID0, r4 /* sets enable and invalidate, clears lock */
554 sync
555 mtspr HID0, r3 /* clears invalidate */
556 blr
557
558 .globl dcache_disable
559dcache_disable:
560 mfspr r3, HID0
561 lis r4, 0
562 ori r4, r4, HID0_ENABLE_DATA_CACHE|HID0_LOCK_DATA_CACHE
563 andc r3, r3, r4
564 ori r4, r3, HID0_INVALIDATE_DATA_CACHE
565 sync
566 mtspr HID0, r4 /* sets invalidate, clears enable and lock */
567 sync
568 mtspr HID0, r3 /* clears invalidate */
569 blr
570
571 .globl dcache_status
572dcache_status:
573 mfspr r3, HID0
574 rlwinm r3, r3, HID0_DCE_SHIFT, 31, 31
575 blr
576
577 .globl get_pvr
578get_pvr:
579 mfspr r3, PVR
580 blr
581
582/*-------------------------------------------------------------------*/
583
584/*
585 * void relocate_code (addr_sp, gd, addr_moni)
586 *
587 * This "function" does not return, instead it continues in RAM
588 * after relocating the monitor code.
589 *
590 * r3 = dest
591 * r4 = src
592 * r5 = length in bytes
593 * r6 = cachelinesize
594 */
595 .globl relocate_code
596relocate_code:
597 mr r1, r3 /* Set new stack pointer */
598 mr r9, r4 /* Save copy of Global Data pointer */
599 mr r10, r5 /* Save copy of Destination Address */
600
601 mr r3, r5 /* Destination Address */
602 lis r4, CFG_MONITOR_BASE@h /* Source Address */
603 ori r4, r4, CFG_MONITOR_BASE@l
604 lwz r5, GOT(__init_end)
605 sub r5, r5, r4
606 li r6, CFG_CACHELINE_SIZE /* Cache Line Size */
607
608 /*
609 * Fix GOT pointer:
610 *
611 * New GOT-PTR = (old GOT-PTR - CFG_MONITOR_BASE)
612 * + Destination Address
613 *
614 * Offset:
615 */
616 sub r15, r10, r4
617
618 /* First our own GOT */
619 add r14, r14, r15
620 /* then the one used by the C code */
621 add r30, r30, r15
622
623 /*
624 * Now relocate code
625 */
626
627 cmplw cr1,r3,r4
628 addi r0,r5,3
629 srwi. r0,r0,2
630 beq cr1,4f /* In place copy is not necessary */
631 beq 7f /* Protect against 0 count */
632 mtctr r0
633 bge cr1,2f
634 la r8,-4(r4)
635 la r7,-4(r3)
636
637 /* copy */
6381: lwzu r0,4(r8)
639 stwu r0,4(r7)
640 bdnz 1b
641
642 addi r0,r5,3
643 srwi. r0,r0,2
644 mtctr r0
645 la r8,-4(r4)
646 la r7,-4(r3)
de1d0a69
JL
647
648 /* and compare */
f046ccd1
EL
64920: lwzu r20,4(r8)
650 lwzu r21,4(r7)
651 xor. r22, r20, r21
652 bne 30f
653 bdnz 20b
654 b 4f
655
656 /* compare failed */
65730: li r3, 0
658 blr
659
6602: slwi r0,r0,2 /* re copy in reverse order ... y do we needed it? */
661 add r8,r4,r0
662 add r7,r3,r0
6633: lwzu r0,-4(r8)
664 stwu r0,-4(r7)
665 bdnz 3b
f046ccd1
EL
666
667/*
668 * Now flush the cache: note that we must start from a cache aligned
669 * address. Otherwise we might miss one cache line.
670 */
de1d0a69 6714:
f046ccd1
EL
672 bl un_setup_stack_in_data_cache
673 mr r7, r3
674 mr r8, r4
675 bl dcache_disable
676 mr r3, r7
677 mr r4, r8
de1d0a69 678
f046ccd1
EL
679 cmpwi r6,0
680 add r5,r3,r5
681 beq 7f /* Always flush prefetch queue in any case */
682 subi r0,r6,1
683 andc r3,r3,r0
684 mfspr r7,HID0 /* don't do dcbst if dcache is disabled*/
685 rlwinm r7,r7,HID0_DCE_SHIFT,31,31
686 cmpwi r7,0
687 beq 9f
688 mr r4,r3
6895: dcbst 0,r4
690 add r4,r4,r6
691 cmplw r4,r5
692 blt 5b
693 sync /* Wait for all dcbst to complete on bus */
6949: mfspr r7,HID0 /* don't do icbi if icache is disabled */
695 rlwinm r7,r7,HID0_DCE_SHIFT,31,31
696 cmpwi r7,0
697 beq 7f
698 mr r4,r3
6996: icbi 0,r4
700 add r4,r4,r6
701 cmplw r4,r5
702 blt 6b
7037: sync /* Wait for all icbi to complete on bus */
704 isync
705
706/*
707 * We are done. Do not return, instead branch to second part of board
708 * initialization, now running from RAM.
709 */
710
711 addi r0, r10, in_ram - _start + EXC_OFF_SYS_RESET
712 mtlr r0
713 blr
714
715in_ram:
716
717 /*
718 * Relocation Function, r14 point to got2+0x8000
719 *
720 * Adjust got2 pointers, no need to check for 0, this code
721 * already puts a few entries in the table.
722 */
723 li r0,__got2_entries@sectoff@l
724 la r3,GOT(_GOT2_TABLE_)
725 lwz r11,GOT(_GOT2_TABLE_)
726 mtctr r0
727 sub r11,r3,r11
728 addi r3,r3,-4
7291: lwzu r0,4(r3)
730 add r0,r0,r11
731 stw r0,0(r3)
732 bdnz 1b
733
734 /*
735 * Now adjust the fixups and the pointers to the fixups
736 * in case we need to move ourselves again.
737 */
7382: li r0,__fixup_entries@sectoff@l
739 lwz r3,GOT(_FIXUP_TABLE_)
740 cmpwi r0,0
741 mtctr r0
742 addi r3,r3,-4
743 beq 4f
7443: lwzu r4,4(r3)
745 lwzux r0,r4,r11
746 add r0,r0,r11
747 stw r10,0(r3)
748 stw r0,0(r4)
749 bdnz 3b
7504:
751clear_bss:
752 /*
753 * Now clear BSS segment
754 */
755 lwz r3,GOT(__bss_start)
756#if defined(CONFIG_HYMOD)
757 /*
758 * For HYMOD - the environment is the very last item in flash.
759 * The real .bss stops just before environment starts, so only
760 * clear up to that point.
761 *
762 * taken from mods for FADS board
763 */
764 lwz r4,GOT(environment)
765#else
766 lwz r4,GOT(_end)
767#endif
768
769 cmplw 0, r3, r4
770 beq 6f
771
772 li r0, 0
7735:
774 stw r0, 0(r3)
775 addi r3, r3, 4
776 cmplw 0, r3, r4
777 bne 5b
7786:
779
780 mr r3, r9 /* Global Data pointer */
781 mr r4, r10 /* Destination Address */
782 bl board_init_r
783
784 /*
785 * Copy exception vector code to low memory
786 *
787 * r3: dest_addr
788 * r7: source address, r8: end address, r9: target address
789 */
790 .globl trap_init
791trap_init:
792 lwz r7, GOT(_start)
793 lwz r8, GOT(_end_of_vectors)
794
795 li r9, 0x100 /* reset vector always at 0x100 */
796
797 cmplw 0, r7, r8
798 bgelr /* return if r7>=r8 - just in case */
799
800 mflr r4 /* save link register */
8011:
802 lwz r0, 0(r7)
803 stw r0, 0(r9)
804 addi r7, r7, 4
805 addi r9, r9, 4
806 cmplw 0, r7, r8
807 bne 1b
808
809 /*
810 * relocate `hdlr' and `int_return' entries
811 */
812 li r7, .L_MachineCheck - _start + EXC_OFF_SYS_RESET
813 li r8, Alignment - _start + EXC_OFF_SYS_RESET
8142:
815 bl trap_reloc
816 addi r7, r7, 0x100 /* next exception vector */
817 cmplw 0, r7, r8
818 blt 2b
819
820 li r7, .L_Alignment - _start + EXC_OFF_SYS_RESET
821 bl trap_reloc
822
823 li r7, .L_ProgramCheck - _start + EXC_OFF_SYS_RESET
824 bl trap_reloc
825
826 li r7, .L_FPUnavailable - _start + EXC_OFF_SYS_RESET
827 li r8, SystemCall - _start + EXC_OFF_SYS_RESET
8283:
829 bl trap_reloc
830 addi r7, r7, 0x100 /* next exception vector */
831 cmplw 0, r7, r8
832 blt 3b
833
834 li r7, .L_SingleStep - _start + EXC_OFF_SYS_RESET
835 li r8, _end_of_vectors - _start + EXC_OFF_SYS_RESET
8364:
837 bl trap_reloc
838 addi r7, r7, 0x100 /* next exception vector */
839 cmplw 0, r7, r8
840 blt 4b
841
842 mfmsr r3 /* now that the vectors have */
843 lis r7, MSR_IP@h /* relocated into low memory */
844 ori r7, r7, MSR_IP@l /* MSR[IP] can be turned off */
845 andc r3, r3, r7 /* (if it was on) */
846 SYNC /* Some chip revs need this... */
847 mtmsr r3
848 SYNC
849
850 mtlr r4 /* restore link register */
851 blr
852
853 /*
854 * Function: relocate entries for one exception vector
855 */
856trap_reloc:
857 lwz r0, 0(r7) /* hdlr ... */
858 add r0, r0, r3 /* ... += dest_addr */
859 stw r0, 0(r7)
860
861 lwz r0, 4(r7) /* int_return ... */
862 add r0, r0, r3 /* ... += dest_addr */
863 stw r0, 4(r7)
864
865 blr
866
867#ifdef CFG_INIT_RAM_LOCK
868.globl unlock_ram_in_cache
869unlock_ram_in_cache:
870 /* invalidate the INIT_RAM section */
871 lis r3, (CFG_INIT_RAM_ADDR & ~31)@h
872 ori r3, r3, (CFG_INIT_RAM_ADDR & ~31)@l
873 li r2,512
874 mtctr r2
8751: icbi r0, r3
876 dcbi r0, r3
877 addi r3, r3, 32
878 bdnz 1b
879 sync /* Wait for all icbi to complete on bus */
880 isync
881 blr
882#endif
883
884map_flash_by_law1:
885 /* When booting from ROM (Flash or EPROM), clear the */
886 /* Address Mask in OR0 so ROM appears everywhere */
887 /*----------------------------------------------------*/
888 lis r3, (CFG_IMMRBAR)@h /* r3 <= CFG_IMMRBAR */
de1d0a69 889 lwz r4, OR0@l(r3)
f046ccd1 890 li r5, 0x7fff /* r5 <= 0x00007FFFF */
de1d0a69 891 and r4, r4, r5
f046ccd1
EL
892 stw r4, OR0@l(r3) /* OR0 <= OR0 & 0x00007FFFF */
893
894 /* As MPC8349E User's Manual presented, when RCW[BMS] is set to 0,
895 * system will boot from 0x0000_0100, and the LBLAWBAR0[BASE_ADDR]
896 * reset value is 0x00000; when RCW[BMS] is set to 1, system will boot
897 * from 0xFFF0_0100, and the LBLAWBAR0[BASE_ADDR] reset value is
898 * 0xFF800. From the hard resetting to here, the processor fetched and
899 * executed the instructions one by one. There is not absolutely
900 * jumping happened. Laterly, the u-boot code has to do an absolutely
901 * jumping to tell the CPU instruction fetching component what the
902 * u-boot TEXT base address is. Because the TEXT base resides in the
903 * boot ROM memory space, to garantee the code can run smoothly after
904 * that jumping, we must map in the entire boot ROM by Local Access
905 * Window. Sometimes, we desire an non-0x00000 or non-0xFF800 starting
906 * address for boot ROM, such as 0xFE000000. In this case, the default
907 * LBIU Local Access Widow 0 will not cover this memory space. So, we
908 * need another window to map in it.
909 */
910 lis r4, (CFG_FLASH_BASE)@h
911 ori r4, r4, (CFG_FLASH_BASE)@l
912 stw r4, LBLAWBAR1(r3) /* LBLAWBAR1 <= CFG_FLASH_BASE */
913 lis r4, (0x80000016)@h
914 ori r4, r4, (0x80000016)@l
915 stw r4, LBLAWAR1(r3) /* LBLAWAR1 <= 8MB Flash Size */
916 blr
917
918 /* Though all the LBIU Local Access Windows and LBC Banks will be
919 * initialized in the C code, we'd better configure boot ROM's
920 * window 0 and bank 0 correctly at here.
921 */
922remap_flash_by_law0:
923 /* Initialize the BR0 with the boot ROM starting address. */
924 lwz r4, BR0(r3)
925 li r5, 0x7FFF
de1d0a69 926 and r4, r4, r5
f046ccd1 927 lis r5, (CFG_FLASH_BASE & 0xFFFF8000)@h
de1d0a69 928 ori r5, r5, (CFG_FLASH_BASE & 0xFFFF8000)@l
f046ccd1
EL
929 or r5, r5, r4
930 stw r5, BR0(r3) /* r5 <= (CFG_FLASH_BASE & 0xFFFF8000) | (BR0 & 0x00007FFF) */
931
932 lwz r4, OR0(r3)
933 lis r5, 0xFF80 /* 8M */
934 or r4, r4, r5
935 stw r4, OR0(r3) /* OR0 <= OR0 | 0xFF800000 */
936
937 lis r4, (CFG_FLASH_BASE)@h
938 ori r4, r4, (CFG_FLASH_BASE)@l
939 stw r4, LBLAWBAR0(r3) /* LBLAWBAR0 <= CFG_FLASH_BASE */
940
941 lis r4, (0x80000016)@h
942 ori r4, r4, (0x80000016)@l
943 stw r4, LBLAWAR0(r3) /* LBLAWAR0 <= 8MB Flash Size */
944
945 xor r4, r4, r4
946 stw r4, LBLAWBAR1(r3)
947 stw r4, LBLAWAR1(r3) /* Off LBIU LAW1 */
948 blr
949
de1d0a69 950setup_stack_in_data_cache_on_r1:
f046ccd1 951 lis r3, (CFG_IMMRBAR)@h
de1d0a69 952
f046ccd1
EL
953 /* setup D-BAT for the D-Cache (with out real memory backup) */
954
955 lis r4, (CFG_INIT_RAM_ADDR & 0xFFFE0000)@h
956 mtspr DBAT0U, r4
957 ori r4, r4, 0x0002
958 mtspr DBAT0L, r4
959 isync
960
de1d0a69 961#if 0
f046ccd1
EL
962 /* Enable MMU */
963 mfmsr r4
964 ori r4, r4, (MSR_DR | MSR_IR)@l
965 mtmsr r4
de1d0a69
JL
966#endif
967
f046ccd1
EL
968 /* Enable and invalidate data cache. */
969 mfspr r4, HID0
970 mr r5, r4
971 ori r4, r4, HID0_DCE | HID0_DCI
972 ori r5, r5, HID0_DCE
973 sync
974 mtspr HID0, r4
975 mtspr HID0, r5
976 sync
de1d0a69 977
f046ccd1
EL
978 /* Allocate Initial RAM in data cache.*/
979 li r0, 0
980 lis r4, (CFG_INIT_RAM_ADDR)@h
981 ori r4, r4, (CFG_INIT_RAM_ADDR)@l
de1d0a69 982 li r5, 128*8 /* 128*8*32=32Kb */
f046ccd1
EL
983 mtctr r5
9841:
985 dcbz r0, r4
986 addi r4, r4, 32
987 bdnz 1b
988 isync
de1d0a69 989
f046ccd1
EL
990 /* Lock all the D-cache, basically leaving the reset of the program without dcache */
991 mfspr r4, HID0
992 ori r4, r4, (HID0_DLOCK)@l
993 sync
994 mtspr HID0 , r4
995
996 /* setup the stack pointer in r1 */
997 lis r1, (CFG_INIT_RAM_ADDR + CFG_GBL_DATA_OFFSET)@h
998 ori r1, r1, (CFG_INIT_RAM_ADDR + CFG_GBL_DATA_OFFSET)@l
999 li r0, 0 /* Make room for stack frame header and */
1000
1001 stwu r0, -4(r1) /* clear final stack frame so that */
1002 stwu r0, -4(r1) /* stack backtraces terminate cleanly */
1003
1004 blr
1005
1006un_setup_stack_in_data_cache:
1007 blr
1008 mr r14, r4
1009 mr r15, r5
de1d0a69 1010
f046ccd1
EL
1011
1012 lis r4, (CFG_INIT_RAM_ADDR & 0xFFFE0000)@h
1013 mtspr DBAT0U, r4
1014 ori r4, r4, 0x0002
1015 mtspr DBAT0L, r4
1016 isync
de1d0a69 1017
f046ccd1
EL
1018 /* un lock all the D-cache */
1019 mfspr r4, HID0
1020 lis r5, (~(HID0_DLOCK))@h
1021 ori r5, r5, (~(HID0_DLOCK))@l
1022 and r4, r4, r5
1023 sync
1024 mtspr HID0 , r4
1025
1026 /* Re - Allocate Initial RAM in data cache.*/
1027 li r0, 0
1028 lis r4, (CFG_INIT_RAM_ADDR)@h
1029 ori r4, r4, (CFG_INIT_RAM_ADDR)@l
de1d0a69 1030 li r5, 128*8 /* 128*8*32=32Kb */
f046ccd1
EL
1031 mtctr r5
10321:
1033 dcbz r0, r4
1034 addi r4, r4, 32
1035 bdnz 1b
1036 isync
de1d0a69 1037
f046ccd1
EL
1038 mflr r16
1039 bl dcache_disable
1040 mtlr r16
de1d0a69 1041
f046ccd1 1042 blr
de1d0a69 1043
f046ccd1
EL
1044#if 0
1045#define GREEN_LIGHT 0x2B0D4046
1046#define RED_LIGHT 0x250D4046
1047#define LIB_CNT 0x4FFF
1048
1049/*
1050 * Lib Light
1051 */
1052
1053 .globl liblight
de1d0a69 1054liblight:
f046ccd1
EL
1055 lis r3, CFG_IMMRBAR@h
1056 ori r3, r3, CFG_IMMRBAR@l
1057 li r4, 0x3002
1058 mtmsr r4
1059 xor r4, r4, r4
1060 mtspr HID0, r4
1061 mtspr HID2, r4
1062 lis r4, 0xF8000000@h
de1d0a69 1063 ori r4, r4, 0xF8000000@l
f046ccd1
EL
1064 stw r4, LBLAWBAR1(r3)
1065 lis r4, 0x8000000E@h
1066 ori r4, r4, 0x8000000E@l
1067 stw r4, LBLAWAR1(r3)
1068 lis r4, 0xF8000801@h
1069 ori r4, r4, 0xF8000801@l
1070 stw r4, BR1(r3)
1071 lis r4, 0xFFFFE8f0@h
1072 ori r4, r4, 0xFFFFE8f0@l
1073 stw r4, OR1(r3)
1074
1075 lis r4, 0xF8000000@h
1076 ori r4, r4, 0xF8000000@l
1077 lis r5, GREEN_LIGHT@h
1078 ori r5, r5, GREEN_LIGHT@l
1079 lis r6, RED_LIGHT@h
1080 ori r6, r6, RED_LIGHT@l
1081 lis r7, LIB_CNT@h
1082 ori r7, r7, LIB_CNT@l
de1d0a69 1083
f046ccd1
EL
10841:
1085 stw r5, 0(r4)
de1d0a69 1086 mtctr r7
f046ccd1
EL
10872: bdnz 2b
1088 stw r6, 0(r4)
de1d0a69 1089 mtctr r7
f046ccd1
EL
10903: bdnz 3b
1091 b 1b
de1d0a69 1092
f046ccd1 1093#endif