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