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