]> git.ipfire.org Git - people/ms/u-boot.git/blame - cpu/ppc4xx/start.S
ppc4xx: Enable Primordial Stack for 40x and Unify ECC Handling
[people/ms/u-boot.git] / cpu / ppc4xx / start.S
CommitLineData
0442ed86
WD
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>
3cb86f3e 5 * Copyright (C) 2007 Stefan Roese <sr@denx.de>, DENX Software Engineering
c821b5f1
GE
6 * Copyright (c) 2008 Nuovation System Designs, LLC
7 * Grant Erickson <gerickson@nuovations.com>
0442ed86
WD
8 *
9 * See file CREDITS for list of people who contributed to this
10 * project.
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License as
14 * published by the Free Software Foundation; either version 2 of
15 * the License, or (at your option) any later version.
16 *
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
25 * MA 02111-1307 USA
26 */
83b4cfa3
WD
27/*------------------------------------------------------------------------------+
28 *
29 * This source code has been made available to you by IBM on an AS-IS
30 * basis. Anyone receiving this source is licensed under IBM
31 * copyrights to use it in any way he or she deems fit, including
32 * copying it, modifying it, compiling it, and redistributing it either
33 * with or without modifications. No license under IBM patents or
34 * patent applications is to be implied by the copyright license.
35 *
36 * Any user of this software should understand that IBM cannot provide
37 * technical support for this software and will not be responsible for
38 * any consequences resulting from the use of this software.
39 *
40 * Any person who transfers this source code or any derivative work
41 * must include the IBM copyright notice, this paragraph, and the
42 * preceding two paragraphs in the transferred software.
43 *
44 * COPYRIGHT I B M CORPORATION 1995
45 * LICENSED MATERIAL - PROGRAM PROPERTY OF I B M
46 *-------------------------------------------------------------------------------
47 */
0442ed86 48
0c8721a4 49/* U-Boot - Startup Code for AMCC 4xx PowerPC based Embedded Boards
0442ed86
WD
50 *
51 *
52 * The processor starts at 0xfffffffc and the code is executed
53 * from flash/rom.
54 * in memory, but as long we don't jump around before relocating.
55 * board_init lies at a quite high address and when the cpu has
56 * jumped there, everything is ok.
57 * This works because the cpu gives the FLASH (CS0) the whole
58 * address space at startup, and board_init lies as a echo of
59 * the flash somewhere up there in the memorymap.
60 *
61 * board_init will change CS0 to be positioned at the correct
62 * address and (s)dram will be positioned at address 0
63 */
64#include <config.h>
0442ed86
WD
65#include <ppc4xx.h>
66#include <version.h>
67
68#define _LINUX_CONFIG_H 1 /* avoid reading Linux autoconf.h file */
69
70#include <ppc_asm.tmpl>
71#include <ppc_defs.h>
72
73#include <asm/cache.h>
74#include <asm/mmu.h>
75
76#ifndef CONFIG_IDENT_STRING
77#define CONFIG_IDENT_STRING ""
78#endif
79
80#ifdef CFG_INIT_DCACHE_CS
81# if (CFG_INIT_DCACHE_CS == 0)
82# define PBxAP pb0ap
83# define PBxCR pb0cr
c821b5f1
GE
84# if (defined(CFG_EBC_PB0AP) && defined(CFG_EBC_PB0CR))
85# define PBxAP_VAL CFG_EBC_PB0AP
86# define PBxCR_VAL CFG_EBC_PB0CR
87# endif
0442ed86
WD
88# endif
89# if (CFG_INIT_DCACHE_CS == 1)
90# define PBxAP pb1ap
91# define PBxCR pb1cr
c821b5f1
GE
92# if (defined(CFG_EBC_PB1AP) && defined(CFG_EBC_PB1CR))
93# define PBxAP_VAL CFG_EBC_PB1AP
94# define PBxCR_VAL CFG_EBC_PB1CR
95# endif
0442ed86
WD
96# endif
97# if (CFG_INIT_DCACHE_CS == 2)
98# define PBxAP pb2ap
99# define PBxCR pb2cr
c821b5f1
GE
100# if (defined(CFG_EBC_PB2AP) && defined(CFG_EBC_PB2CR))
101# define PBxAP_VAL CFG_EBC_PB2AP
102# define PBxCR_VAL CFG_EBC_PB2CR
103# endif
0442ed86
WD
104# endif
105# if (CFG_INIT_DCACHE_CS == 3)
106# define PBxAP pb3ap
107# define PBxCR pb3cr
c821b5f1
GE
108# if (defined(CFG_EBC_PB3AP) && defined(CFG_EBC_PB3CR))
109# define PBxAP_VAL CFG_EBC_PB3AP
110# define PBxCR_VAL CFG_EBC_PB3CR
111# endif
0442ed86
WD
112# endif
113# if (CFG_INIT_DCACHE_CS == 4)
114# define PBxAP pb4ap
115# define PBxCR pb4cr
c821b5f1
GE
116# if (defined(CFG_EBC_PB4AP) && defined(CFG_EBC_PB4CR))
117# define PBxAP_VAL CFG_EBC_PB4AP
118# define PBxCR_VAL CFG_EBC_PB4CR
119# endif
0442ed86
WD
120# endif
121# if (CFG_INIT_DCACHE_CS == 5)
122# define PBxAP pb5ap
123# define PBxCR pb5cr
c821b5f1
GE
124# if (defined(CFG_EBC_PB5AP) && defined(CFG_EBC_PB5CR))
125# define PBxAP_VAL CFG_EBC_PB5AP
126# define PBxCR_VAL CFG_EBC_PB5CR
127# endif
0442ed86
WD
128# endif
129# if (CFG_INIT_DCACHE_CS == 6)
130# define PBxAP pb6ap
131# define PBxCR pb6cr
c821b5f1
GE
132# if (defined(CFG_EBC_PB6AP) && defined(CFG_EBC_PB6CR))
133# define PBxAP_VAL CFG_EBC_PB6AP
134# define PBxCR_VAL CFG_EBC_PB6CR
135# endif
0442ed86
WD
136# endif
137# if (CFG_INIT_DCACHE_CS == 7)
138# define PBxAP pb7ap
139# define PBxCR pb7cr
c821b5f1
GE
140# if (defined(CFG_EBC_PB7AP) && defined(CFG_EBC_PB7CR))
141# define PBxAP_VAL CFG_EBC_PB7AP
142# define PBxCR_VAL CFG_EBC_PB7CR
143# endif
144# endif
145# ifndef PBxAP_VAL
146# define PBxAP_VAL 0
147# endif
148# ifndef PBxCR_VAL
149# define PBxCR_VAL 0
150# endif
151/*
152 * Memory Bank x (nothingness) initialization CFG_INIT_RAM_ADDR + 64 MiB
153 * used as temporary stack pointer for the primordial stack
154 */
155# ifndef CFG_INIT_DCACHE_PBxAR
156# define CFG_INIT_DCACHE_PBxAR (EBC_BXAP_BME_DISABLED | \
157 EBC_BXAP_TWT_ENCODE(7) | \
158 EBC_BXAP_BCE_DISABLE | \
159 EBC_BXAP_BCT_2TRANS | \
160 EBC_BXAP_CSN_ENCODE(0) | \
161 EBC_BXAP_OEN_ENCODE(0) | \
162 EBC_BXAP_WBN_ENCODE(0) | \
163 EBC_BXAP_WBF_ENCODE(0) | \
164 EBC_BXAP_TH_ENCODE(2) | \
165 EBC_BXAP_RE_DISABLED | \
166 EBC_BXAP_SOR_NONDELAYED | \
167 EBC_BXAP_BEM_WRITEONLY | \
168 EBC_BXAP_PEN_DISABLED)
169# endif /* CFG_INIT_DCACHE_PBxAR */
170# ifndef CFG_INIT_DCACHE_PBxCR
171# define CFG_INIT_DCACHE_PBxCR (EBC_BXCR_BAS_ENCODE(CFG_INIT_RAM_ADDR) | \
172 EBC_BXCR_BS_64MB | \
173 EBC_BXCR_BU_RW | \
174 EBC_BXCR_BW_16BIT)
175# endif /* CFG_INIT_DCACHE_PBxCR */
176# ifndef CFG_INIT_RAM_PATTERN
177# define CFG_INIT_RAM_PATTERN 0xDEADDEAD
0442ed86
WD
178# endif
179#endif /* CFG_INIT_DCACHE_CS */
180
28d77d96
SR
181#if (defined(CFG_INIT_RAM_DCACHE) && (CFG_INIT_RAM_END > (4 << 10)))
182#error Only 4k of init-ram is supported - please adjust CFG_INIT_RAM_END!
183#endif
184
c821b5f1
GE
185/*
186 * Unless otherwise overriden, enable two 128MB cachable instruction regions
187 * at CFG_SDRAM_BASE and another 128MB cacheable instruction region covering
188 * NOR flash at CFG_FLASH_BASE. Disable all cacheable data regions.
189 */
190#if !defined(CFG_ICACHE_SACR_VALUE)
191# define CFG_ICACHE_SACR_VALUE \
192 (PPC_128MB_SACR_VALUE(CFG_SDRAM_BASE + ( 0 << 20)) | \
193 PPC_128MB_SACR_VALUE(CFG_SDRAM_BASE + (128 << 20)) | \
194 PPC_128MB_SACR_VALUE(CFG_FLASH_BASE))
195#endif /* !defined(CFG_ICACHE_SACR_VALUE) */
196
197#if !defined(CFG_DCACHE_SACR_VALUE)
198# define CFG_DCACHE_SACR_VALUE \
199 (0x00000000)
200#endif /* !defined(CFG_DCACHE_SACR_VALUE) */
201
83b4cfa3 202#define function_prolog(func_name) .text; \
cf959c7d
SR
203 .align 2; \
204 .globl func_name; \
205 func_name:
83b4cfa3 206#define function_epilog(func_name) .type func_name,@function; \
cf959c7d
SR
207 .size func_name,.-func_name
208
0442ed86
WD
209/* We don't want the MMU yet.
210*/
211#undef MSR_KERNEL
212#define MSR_KERNEL ( MSR_ME ) /* Machine Check */
213
214
215 .extern ext_bus_cntlr_init
216 .extern sdram_init
887e2ec9
SR
217#ifdef CONFIG_NAND_U_BOOT
218 .extern reconfig_tlb0
219#endif
0442ed86
WD
220
221/*
222 * Set up GOT: Global Offset Table
223 *
224 * Use r14 to access the GOT
225 */
887e2ec9 226#if !defined(CONFIG_NAND_SPL)
0442ed86
WD
227 START_GOT
228 GOT_ENTRY(_GOT2_TABLE_)
229 GOT_ENTRY(_FIXUP_TABLE_)
230
231 GOT_ENTRY(_start)
232 GOT_ENTRY(_start_of_vectors)
233 GOT_ENTRY(_end_of_vectors)
234 GOT_ENTRY(transfer_to_handler)
235
3b57fe0a 236 GOT_ENTRY(__init_end)
0442ed86 237 GOT_ENTRY(_end)
5d232d0e 238 GOT_ENTRY(__bss_start)
0442ed86 239 END_GOT
887e2ec9
SR
240#endif /* CONFIG_NAND_SPL */
241
242#if defined(CONFIG_NAND_U_BOOT) && !defined(CONFIG_NAND_SPL)
243 /*
244 * NAND U-Boot image is started from offset 0
245 */
246 .text
c440bfe6 247#if defined(CONFIG_440)
887e2ec9 248 bl reconfig_tlb0
c440bfe6 249#endif
887e2ec9
SR
250 GET_GOT
251 bl cpu_init_f /* run low-level CPU init code (from Flash) */
252 bl board_init_f
253#endif
0442ed86
WD
254
255/*
256 * 440 Startup -- on reset only the top 4k of the effective
257 * address space is mapped in by an entry in the instruction
258 * and data shadow TLB. The .bootpg section is located in the
259 * top 4k & does only what's necessary to map in the the rest
260 * of the boot rom. Once the boot rom is mapped in we can
261 * proceed with normal startup.
262 *
263 * NOTE: CS0 only covers the top 2MB of the effective address
264 * space after reset.
265 */
266
267#if defined(CONFIG_440)
887e2ec9 268#if !defined(CONFIG_NAND_SPL)
0442ed86 269 .section .bootpg,"ax"
887e2ec9 270#endif
0442ed86
WD
271 .globl _start_440
272
273/**************************************************************************/
274_start_440:
511d0c72
WD
275 /*--------------------------------------------------------------------+
276 | 440EPX BUP Change - Hardware team request
277 +--------------------------------------------------------------------*/
887e2ec9
SR
278#if defined(CONFIG_440EPX) || defined(CONFIG_440GRX)
279 sync
280 nop
281 nop
282#endif
6c5879f3
MB
283 /*----------------------------------------------------------------+
284 | Core bug fix. Clear the esr
285 +-----------------------------------------------------------------*/
edd6cf20 286 li r0,0
b87dfd28 287 mtspr esr,r0
0442ed86
WD
288 /*----------------------------------------------------------------*/
289 /* Clear and set up some registers. */
290 /*----------------------------------------------------------------*/
f901a83b
WD
291 iccci r0,r0 /* NOTE: operands not used for 440 */
292 dccci r0,r0 /* NOTE: operands not used for 440 */
0442ed86
WD
293 sync
294 li r0,0
295 mtspr srr0,r0
296 mtspr srr1,r0
297 mtspr csrr0,r0
298 mtspr csrr1,r0
887e2ec9
SR
299 /* NOTE: 440GX adds machine check status regs */
300#if defined(CONFIG_440) && !defined(CONFIG_440GP)
f901a83b
WD
301 mtspr mcsrr0,r0
302 mtspr mcsrr1,r0
887e2ec9 303 mfspr r1,mcsr
f901a83b 304 mtspr mcsr,r1
ba56f625 305#endif
20532833
SR
306
307 /*----------------------------------------------------------------*/
308 /* CCR0 init */
309 /*----------------------------------------------------------------*/
310 /* Disable store gathering & broadcast, guarantee inst/data
311 * cache block touch, force load/store alignment
312 * (see errata 1.12: 440_33)
313 */
314 lis r1,0x0030 /* store gathering & broadcast disable */
315 ori r1,r1,0x6000 /* cache touch */
316 mtspr ccr0,r1
317
0442ed86
WD
318 /*----------------------------------------------------------------*/
319 /* Initialize debug */
320 /*----------------------------------------------------------------*/
887e2ec9
SR
321 mfspr r1,dbcr0
322 andis. r1, r1, 0x8000 /* test DBCR0[EDM] bit */
323 bne skip_debug_init /* if set, don't clear debug register */
0442ed86
WD
324 mtspr dbcr0,r0
325 mtspr dbcr1,r0
326 mtspr dbcr2,r0
327 mtspr iac1,r0
328 mtspr iac2,r0
329 mtspr iac3,r0
330 mtspr dac1,r0
331 mtspr dac2,r0
332 mtspr dvc1,r0
333 mtspr dvc2,r0
334
335 mfspr r1,dbsr
336 mtspr dbsr,r1 /* Clear all valid bits */
887e2ec9 337skip_debug_init:
0442ed86 338
6c5879f3
MB
339#if defined (CONFIG_440SPE)
340 /*----------------------------------------------------------------+
341 | Initialize Core Configuration Reg1.
342 | a. ICDPEI: Record even parity. Normal operation.
343 | b. ICTPEI: Record even parity. Normal operation.
344 | c. DCTPEI: Record even parity. Normal operation.
345 | d. DCDPEI: Record even parity. Normal operation.
346 | e. DCUPEI: Record even parity. Normal operation.
347 | f. DCMPEI: Record even parity. Normal operation.
348 | g. FCOM: Normal operation
349 | h. MMUPEI: Record even parity. Normal operation.
350 | i. FFF: Flush only as much data as necessary.
edd6cf20 351 | j. TCS: Timebase increments from CPU clock.
6c5879f3 352 +-----------------------------------------------------------------*/
edd6cf20 353 li r0,0
6c5879f3
MB
354 mtspr ccr1, r0
355
356 /*----------------------------------------------------------------+
357 | Reset the timebase.
358 | The previous write to CCR1 sets the timebase source.
359 +-----------------------------------------------------------------*/
6c5879f3
MB
360 mtspr tbl, r0
361 mtspr tbu, r0
362#endif
363
0442ed86
WD
364 /*----------------------------------------------------------------*/
365 /* Setup interrupt vectors */
366 /*----------------------------------------------------------------*/
367 mtspr ivpr,r0 /* Vectors start at 0x0000_0000 */
f901a83b 368 li r1,0x0100
0442ed86 369 mtspr ivor0,r1 /* Critical input */
f901a83b 370 li r1,0x0200
0442ed86 371 mtspr ivor1,r1 /* Machine check */
f901a83b 372 li r1,0x0300
0442ed86 373 mtspr ivor2,r1 /* Data storage */
f901a83b 374 li r1,0x0400
0442ed86
WD
375 mtspr ivor3,r1 /* Instruction storage */
376 li r1,0x0500
377 mtspr ivor4,r1 /* External interrupt */
378 li r1,0x0600
379 mtspr ivor5,r1 /* Alignment */
380 li r1,0x0700
381 mtspr ivor6,r1 /* Program check */
382 li r1,0x0800
383 mtspr ivor7,r1 /* Floating point unavailable */
384 li r1,0x0c00
385 mtspr ivor8,r1 /* System call */
efa35cf1 386 li r1,0x0a00
83b4cfa3 387 mtspr ivor9,r1 /* Auxiliary Processor unavailable */
efa35cf1
GB
388 li r1,0x0900
389 mtspr ivor10,r1 /* Decrementer */
0442ed86 390 li r1,0x1300
efa35cf1
GB
391 mtspr ivor13,r1 /* Data TLB error */
392 li r1,0x1400
0442ed86
WD
393 mtspr ivor14,r1 /* Instr TLB error */
394 li r1,0x2000
395 mtspr ivor15,r1 /* Debug */
396
397 /*----------------------------------------------------------------*/
398 /* Configure cache regions */
399 /*----------------------------------------------------------------*/
400 mtspr inv0,r0
401 mtspr inv1,r0
402 mtspr inv2,r0
403 mtspr inv3,r0
404 mtspr dnv0,r0
405 mtspr dnv1,r0
406 mtspr dnv2,r0
407 mtspr dnv3,r0
408 mtspr itv0,r0
409 mtspr itv1,r0
410 mtspr itv2,r0
411 mtspr itv3,r0
412 mtspr dtv0,r0
413 mtspr dtv1,r0
414 mtspr dtv2,r0
415 mtspr dtv3,r0
416
417 /*----------------------------------------------------------------*/
418 /* Cache victim limits */
419 /*----------------------------------------------------------------*/
420 /* floors 0, ceiling max to use the entire cache -- nothing locked
421 */
422 lis r1,0x0001
423 ori r1,r1,0xf800
424 mtspr ivlim,r1
425 mtspr dvlim,r1
426
6c5879f3
MB
427 /*----------------------------------------------------------------+
428 |Initialize MMUCR[STID] = 0.
429 +-----------------------------------------------------------------*/
430 mfspr r0,mmucr
431 addis r1,0,0xFFFF
432 ori r1,r1,0xFF00
433 and r0,r0,r1
434 mtspr mmucr,r0
435
0442ed86
WD
436 /*----------------------------------------------------------------*/
437 /* Clear all TLB entries -- TID = 0, TS = 0 */
438 /*----------------------------------------------------------------*/
6c5879f3 439 addis r0,0,0x0000
0442ed86
WD
440 li r1,0x003f /* 64 TLB entries */
441 mtctr r1
6c5879f3
MB
442rsttlb: tlbwe r0,r1,0x0000 /* Invalidate all entries (V=0)*/
443 tlbwe r0,r1,0x0001
444 tlbwe r0,r1,0x0002
0442ed86 445 subi r1,r1,0x0001
6c5879f3 446 bdnz rsttlb
0442ed86
WD
447
448 /*----------------------------------------------------------------*/
449 /* TLB entry setup -- step thru tlbtab */
450 /*----------------------------------------------------------------*/
692519b1
RJ
451#if defined(CONFIG_440SPE)
452 /*----------------------------------------------------------------*/
453 /* We have different TLB tables for revA and rev B of 440SPe */
454 /*----------------------------------------------------------------*/
455 mfspr r1, PVR
456 lis r0,0x5342
457 ori r0,r0,0x1891
458 cmpw r7,r1,r0
459 bne r7,..revA
460 bl tlbtabB
461 b ..goon
462..revA:
463 bl tlbtabA
464..goon:
465#else
0442ed86 466 bl tlbtab /* Get tlbtab pointer */
692519b1 467#endif
0442ed86
WD
468 mr r5,r0
469 li r1,0x003f /* 64 TLB entries max */
470 mtctr r1
471 li r4,0 /* TLB # */
472
473 addi r5,r5,-4
4741: lwzu r0,4(r5)
475 cmpwi r0,0
476 beq 2f /* 0 marks end */
477 lwzu r1,4(r5)
478 lwzu r2,4(r5)
479 tlbwe r0,r4,0 /* TLB Word 0 */
480 tlbwe r1,r4,1 /* TLB Word 1 */
481 tlbwe r2,r4,2 /* TLB Word 2 */
482 addi r4,r4,1 /* Next TLB */
483 bdnz 1b
484
485 /*----------------------------------------------------------------*/
486 /* Continue from 'normal' start */
487 /*----------------------------------------------------------------*/
887e2ec9
SR
4882:
489
490#if defined(CONFIG_NAND_SPL)
71665ebf
SR
491#if defined(CONFIG_440EPX) || defined(CONFIG_440GRX) || \
492 defined(CONFIG_460EX) || defined(CONFIG_460GT)
887e2ec9 493 /*
cf959c7d 494 * Enable internal SRAM (only on 440EPx/GRx, 440EP/GR have no OCM)
887e2ec9
SR
495 */
496 lis r2,0x7fff
497 ori r2,r2,0xffff
498 mfdcr r1,isram0_dpc
499 and r1,r1,r2 /* Disable parity check */
500 mtdcr isram0_dpc,r1
501 mfdcr r1,isram0_pmeg
502 and r1,r1,r2 /* Disable pwr mgmt */
503 mtdcr isram0_pmeg,r1
71665ebf
SR
504#if defined(CONFIG_460EX) || defined(CONFIG_460GT)
505 lis r1,0x4000 /* BAS = 8000_0000 */
506 ori r1,r1,0x4580 /* 16k */
507 mtdcr isram0_sb0cr,r1
508#endif
cf959c7d
SR
509#endif
510#if defined(CONFIG_440EP)
511 /*
512 * On 440EP with no internal SRAM, we setup SDRAM very early
513 * and copy the NAND_SPL to SDRAM and jump to it
514 */
515 /* Clear Dcache to use as RAM */
516 addis r3,r0,CFG_INIT_RAM_ADDR@h
517 ori r3,r3,CFG_INIT_RAM_ADDR@l
518 addis r4,r0,CFG_INIT_RAM_END@h
519 ori r4,r4,CFG_INIT_RAM_END@l
520 rlwinm. r5,r4,0,27,31
521 rlwinm r5,r4,27,5,31
522 beq ..d_ran3
523 addi r5,r5,0x0001
524..d_ran3:
525 mtctr r5
526..d_ag3:
527 dcbz r0,r3
528 addi r3,r3,32
529 bdnz ..d_ag3
530 /*----------------------------------------------------------------*/
531 /* Setup the stack in internal SRAM */
532 /*----------------------------------------------------------------*/
533 lis r1,CFG_INIT_RAM_ADDR@h
534 ori r1,r1,CFG_INIT_SP_OFFSET@l
535 li r0,0
536 stwu r0,-4(r1)
537 stwu r0,-4(r1) /* Terminate call chain */
538
539 stwu r1,-8(r1) /* Save back chain and move SP */
540 lis r0,RESET_VECTOR@h /* Address of reset vector */
541 ori r0,r0, RESET_VECTOR@l
542 stwu r1,-8(r1) /* Save back chain and move SP */
543 stw r0,+12(r1) /* Save return addr (underflow vect) */
544 sync
545 bl early_sdram_init
546 sync
547#endif /* CONFIG_440EP */
887e2ec9
SR
548
549 /*
550 * Copy SPL from cache into internal SRAM
551 */
552 li r4,(CFG_NAND_BOOT_SPL_SIZE >> 2) - 1
553 mtctr r4
554 lis r2,CFG_NAND_BOOT_SPL_SRC@h
555 ori r2,r2,CFG_NAND_BOOT_SPL_SRC@l
556 lis r3,CFG_NAND_BOOT_SPL_DST@h
557 ori r3,r3,CFG_NAND_BOOT_SPL_DST@l
558spl_loop:
559 lwzu r4,4(r2)
560 stwu r4,4(r3)
561 bdnz spl_loop
562
563 /*
564 * Jump to code in RAM
565 */
566 bl 00f
56700: mflr r10
568 lis r3,(CFG_NAND_BOOT_SPL_SRC - CFG_NAND_BOOT_SPL_DST)@h
569 ori r3,r3,(CFG_NAND_BOOT_SPL_SRC - CFG_NAND_BOOT_SPL_DST)@l
570 sub r10,r10,r3
571 addi r10,r10,28
572 mtlr r10
573 blr
574
575start_ram:
576 sync
577 isync
cf959c7d 578#endif /* CONFIG_NAND_SPL */
887e2ec9
SR
579
580 bl 3f
0442ed86
WD
581 b _start
582
5833: li r0,0
584 mtspr srr1,r0 /* Keep things disabled for now */
585 mflr r1
586 mtspr srr0,r1
587 rfi
b867d705 588#endif /* CONFIG_440 */
0442ed86
WD
589
590/*
591 * r3 - 1st arg to board_init(): IMMP pointer
592 * r4 - 2nd arg to board_init(): boot flag
593 */
887e2ec9 594#ifndef CONFIG_NAND_SPL
0442ed86
WD
595 .text
596 .long 0x27051956 /* U-Boot Magic Number */
597 .globl version_string
598version_string:
599 .ascii U_BOOT_VERSION
600 .ascii " (", __DATE__, " - ", __TIME__, ")"
601 .ascii CONFIG_IDENT_STRING, "\0"
602
0442ed86 603 . = EXC_OFF_SYS_RESET
efa35cf1
GB
604 .globl _start_of_vectors
605_start_of_vectors:
606
607/* Critical input. */
608 CRIT_EXCEPTION(0x100, CritcalInput, UnknownException)
609
610#ifdef CONFIG_440
611/* Machine check */
83b4cfa3 612 MCK_EXCEPTION(0x200, MachineCheck, MachineCheckException)
efa35cf1 613#else
83b4cfa3 614 CRIT_EXCEPTION(0x200, MachineCheck, MachineCheckException)
efa35cf1
GB
615#endif /* CONFIG_440 */
616
617/* Data Storage exception. */
618 STD_EXCEPTION(0x300, DataStorage, UnknownException)
619
620/* Instruction Storage exception. */
621 STD_EXCEPTION(0x400, InstStorage, UnknownException)
622
623/* External Interrupt exception. */
624 STD_EXCEPTION(0x500, ExtInterrupt, external_interrupt)
625
626/* Alignment exception. */
627 . = 0x600
628Alignment:
629 EXCEPTION_PROLOG(SRR0, SRR1)
630 mfspr r4,DAR
631 stw r4,_DAR(r21)
632 mfspr r5,DSISR
633 stw r5,_DSISR(r21)
634 addi r3,r1,STACK_FRAME_OVERHEAD
635 li r20,MSR_KERNEL
636 rlwimi r20,r23,0,16,16 /* copy EE bit from saved MSR */
637 lwz r6,GOT(transfer_to_handler)
638 mtlr r6
639 blrl
640.L_Alignment:
641 .long AlignmentException - _start + _START_OFFSET
642 .long int_return - _start + _START_OFFSET
643
644/* Program check exception */
645 . = 0x700
646ProgramCheck:
647 EXCEPTION_PROLOG(SRR0, SRR1)
648 addi r3,r1,STACK_FRAME_OVERHEAD
649 li r20,MSR_KERNEL
650 rlwimi r20,r23,0,16,16 /* copy EE bit from saved MSR */
651 lwz r6,GOT(transfer_to_handler)
652 mtlr r6
653 blrl
654.L_ProgramCheck:
655 .long ProgramCheckException - _start + _START_OFFSET
656 .long int_return - _start + _START_OFFSET
657
658#ifdef CONFIG_440
659 STD_EXCEPTION(0x800, FPUnavailable, UnknownException)
660 STD_EXCEPTION(0x900, Decrementer, DecrementerPITException)
661 STD_EXCEPTION(0xa00, APU, UnknownException)
df8a24cd 662#endif
efa35cf1
GB
663 STD_EXCEPTION(0xc00, SystemCall, UnknownException)
664
665#ifdef CONFIG_440
666 STD_EXCEPTION(0x1300, DataTLBError, UnknownException)
667 STD_EXCEPTION(0x1400, InstructionTLBError, UnknownException)
668#else
669 STD_EXCEPTION(0x1000, PIT, DecrementerPITException)
670 STD_EXCEPTION(0x1100, InstructionTLBMiss, UnknownException)
671 STD_EXCEPTION(0x1200, DataTLBMiss, UnknownException)
672#endif
673 CRIT_EXCEPTION(0x2000, DebugBreakpoint, DebugException )
674
675 .globl _end_of_vectors
676_end_of_vectors:
677 . = _START_OFFSET
887e2ec9 678#endif
0442ed86
WD
679 .globl _start
680_start:
681
682/*****************************************************************************/
683#if defined(CONFIG_440)
684
685 /*----------------------------------------------------------------*/
686 /* Clear and set up some registers. */
687 /*----------------------------------------------------------------*/
688 li r0,0x0000
689 lis r1,0xffff
690 mtspr dec,r0 /* prevent dec exceptions */
691 mtspr tbl,r0 /* prevent fit & wdt exceptions */
692 mtspr tbu,r0
693 mtspr tsr,r1 /* clear all timer exception status */
694 mtspr tcr,r0 /* disable all */
695 mtspr esr,r0 /* clear exception syndrome register */
696 mtxer r0 /* clear integer exception register */
0442ed86
WD
697
698 /*----------------------------------------------------------------*/
699 /* Debug setup -- some (not very good) ice's need an event*/
700 /* to establish control :-( Define CFG_INIT_DBCR to the dbsr */
701 /* value you need in this case 0x8cff 0000 should do the trick */
702 /*----------------------------------------------------------------*/
703#if defined(CFG_INIT_DBCR)
704 lis r1,0xffff
705 ori r1,r1,0xffff
706 mtspr dbsr,r1 /* Clear all status bits */
707 lis r0,CFG_INIT_DBCR@h
708 ori r0,r0,CFG_INIT_DBCR@l
709 mtspr dbcr0,r0
710 isync
711#endif
712
713 /*----------------------------------------------------------------*/
714 /* Setup the internal SRAM */
715 /*----------------------------------------------------------------*/
716 li r0,0
887e2ec9
SR
717
718#ifdef CFG_INIT_RAM_DCACHE
c157d8e2 719 /* Clear Dcache to use as RAM */
f901a83b
WD
720 addis r3,r0,CFG_INIT_RAM_ADDR@h
721 ori r3,r3,CFG_INIT_RAM_ADDR@l
722 addis r4,r0,CFG_INIT_RAM_END@h
723 ori r4,r4,CFG_INIT_RAM_END@l
c157d8e2 724 rlwinm. r5,r4,0,27,31
f901a83b
WD
725 rlwinm r5,r4,27,5,31
726 beq ..d_ran
727 addi r5,r5,0x0001
c157d8e2 728..d_ran:
f901a83b 729 mtctr r5
c157d8e2 730..d_ag:
f901a83b
WD
731 dcbz r0,r3
732 addi r3,r3,32
733 bdnz ..d_ag
e02c521d
SR
734
735 /*
736 * Lock the init-ram/stack in d-cache, so that other regions
737 * may use d-cache as well
738 * Note, that this current implementation locks exactly 4k
739 * of d-cache, so please make sure that you don't define a
740 * bigger init-ram area. Take a look at the lwmon5 440EPx
741 * implementation as a reference.
742 */
743 msync
744 isync
745 /* 8. set TFLOOR/NFLOOR to 8 (-> 8*16*32 bytes locked -> 4k) */
746 lis r1,0x0201
747 ori r1,r1,0xf808
748 mtspr dvlim,r1
749 lis r1,0x0808
750 ori r1,r1,0x0808
751 mtspr dnv0,r1
752 mtspr dnv1,r1
753 mtspr dnv2,r1
754 mtspr dnv3,r1
755 mtspr dtv0,r1
756 mtspr dtv1,r1
757 mtspr dtv2,r1
758 mtspr dtv3,r1
759 msync
760 isync
887e2ec9
SR
761#endif /* CFG_INIT_RAM_DCACHE */
762
763 /* 440EP & 440GR are only 440er PPC's without internal SRAM */
764#if !defined(CONFIG_440EP) && !defined(CONFIG_440GR)
765 /* not all PPC's have internal SRAM usable as L2-cache */
2801b2d2
SR
766#if defined(CONFIG_440GX) || \
767 defined(CONFIG_440SP) || defined(CONFIG_440SPE) || \
768 defined(CONFIG_460EX) || defined(CONFIG_460GT)
f901a83b 769 mtdcr l2_cache_cfg,r0 /* Ensure L2 Cache is off */
ba56f625 770#endif
0442ed86 771
887e2ec9 772 lis r2,0x7fff
0442ed86
WD
773 ori r2,r2,0xffff
774 mfdcr r1,isram0_dpc
775 and r1,r1,r2 /* Disable parity check */
776 mtdcr isram0_dpc,r1
777 mfdcr r1,isram0_pmeg
887e2ec9 778 and r1,r1,r2 /* Disable pwr mgmt */
0442ed86
WD
779 mtdcr isram0_pmeg,r1
780
781 lis r1,0x8000 /* BAS = 8000_0000 */
6e7fb6ea 782#if defined(CONFIG_440GX) || defined(CONFIG_440SP)
ba56f625 783 ori r1,r1,0x0980 /* first 64k */
f901a83b 784 mtdcr isram0_sb0cr,r1
ba56f625
WD
785 lis r1,0x8001
786 ori r1,r1,0x0980 /* second 64k */
f901a83b 787 mtdcr isram0_sb1cr,r1
ba56f625
WD
788 lis r1, 0x8002
789 ori r1,r1, 0x0980 /* third 64k */
f901a83b 790 mtdcr isram0_sb2cr,r1
ba56f625
WD
791 lis r1, 0x8003
792 ori r1,r1, 0x0980 /* fourth 64k */
f901a83b 793 mtdcr isram0_sb3cr,r1
6c5879f3
MB
794#elif defined(CONFIG_440SPE)
795 lis r1,0x0000 /* BAS = 0000_0000 */
796 ori r1,r1,0x0984 /* first 64k */
797 mtdcr isram0_sb0cr,r1
798 lis r1,0x0001
799 ori r1,r1,0x0984 /* second 64k */
800 mtdcr isram0_sb1cr,r1
801 lis r1, 0x0002
802 ori r1,r1, 0x0984 /* third 64k */
803 mtdcr isram0_sb2cr,r1
804 lis r1, 0x0003
805 ori r1,r1, 0x0984 /* fourth 64k */
806 mtdcr isram0_sb3cr,r1
2801b2d2
SR
807#elif defined(CONFIG_460EX) || defined(CONFIG_460GT)
808 lis r1,0x4000 /* BAS = 8000_0000 */
809 ori r1,r1,0x4580 /* 16k */
810 mtdcr isram0_sb0cr,r1
887e2ec9 811#elif defined(CONFIG_440GP)
0442ed86
WD
812 ori r1,r1,0x0380 /* 8k rw */
813 mtdcr isram0_sb0cr,r1
887e2ec9 814 mtdcr isram0_sb1cr,r0 /* Disable bank 1 */
c157d8e2 815#endif
887e2ec9 816#endif /* #if !defined(CONFIG_440EP) && !defined(CONFIG_440GR) */
0442ed86
WD
817
818 /*----------------------------------------------------------------*/
819 /* Setup the stack in internal SRAM */
820 /*----------------------------------------------------------------*/
821 lis r1,CFG_INIT_RAM_ADDR@h
822 ori r1,r1,CFG_INIT_SP_OFFSET@l
0442ed86
WD
823 li r0,0
824 stwu r0,-4(r1)
825 stwu r0,-4(r1) /* Terminate call chain */
826
827 stwu r1,-8(r1) /* Save back chain and move SP */
828 lis r0,RESET_VECTOR@h /* Address of reset vector */
829 ori r0,r0, RESET_VECTOR@l
830 stwu r1,-8(r1) /* Save back chain and move SP */
831 stw r0,+12(r1) /* Save return addr (underflow vect) */
832
887e2ec9
SR
833#ifdef CONFIG_NAND_SPL
834 bl nand_boot /* will not return */
835#else
0442ed86 836 GET_GOT
5568e613
SR
837
838 bl cpu_init_f /* run low-level CPU init code (from Flash) */
0442ed86 839 bl board_init_f
887e2ec9 840#endif
0442ed86
WD
841
842#endif /* CONFIG_440 */
843
844/*****************************************************************************/
845#ifdef CONFIG_IOP480
846 /*----------------------------------------------------------------------- */
847 /* Set up some machine state registers. */
848 /*----------------------------------------------------------------------- */
849 addi r0,r0,0x0000 /* initialize r0 to zero */
850 mtspr esr,r0 /* clear Exception Syndrome Reg */
851 mttcr r0 /* timer control register */
852 mtexier r0 /* disable all interrupts */
0442ed86
WD
853 addis r4,r0,0xFFFF /* set r4 to 0xFFFFFFFF (status in the */
854 ori r4,r4,0xFFFF /* dbsr is cleared by setting bits to 1) */
855 mtdbsr r4 /* clear/reset the dbsr */
856 mtexisr r4 /* clear all pending interrupts */
857 addis r4,r0,0x8000
858 mtexier r4 /* enable critical exceptions */
859 addis r4,r0,0x0000 /* assume 403GCX - enable core clk */
860 ori r4,r4,0x4020 /* dbling (no harm done on GA and GC */
861 mtiocr r4 /* since bit not used) & DRC to latch */
862 /* data bus on rising edge of CAS */
863 /*----------------------------------------------------------------------- */
864 /* Clear XER. */
865 /*----------------------------------------------------------------------- */
866 mtxer r0
867 /*----------------------------------------------------------------------- */
868 /* Invalidate i-cache and d-cache TAG arrays. */
869 /*----------------------------------------------------------------------- */
870 addi r3,0,1024 /* 1/4 of I-cache size, half of D-cache */
871 addi r4,0,1024 /* 1/4 of I-cache */
872..cloop:
873 iccci 0,r3
874 iccci r4,r3
875 dccci 0,r3
876 addic. r3,r3,-16 /* move back one cache line */
877 bne ..cloop /* loop back to do rest until r3 = 0 */
878
879 /* */
880 /* initialize IOP480 so it can read 1 MB code area for SRAM spaces */
881 /* this requires enabling MA[17..0], by default only MA[12..0] are enabled. */
882 /* */
883
884 /* first copy IOP480 register base address into r3 */
885 addis r3,0,0x5000 /* IOP480 register base address hi */
886/* ori r3,r3,0x0000 / IOP480 register base address lo */
887
888#ifdef CONFIG_ADCIOP
889 /* use r4 as the working variable */
890 /* turn on CS3 (LOCCTL.7) */
891 lwz r4,0x84(r3) /* LOCTL is at offset 0x84 */
892 andi. r4,r4,0xff7f /* make bit 7 = 0 -- CS3 mode */
893 stw r4,0x84(r3) /* LOCTL is at offset 0x84 */
894#endif
895
896#ifdef CONFIG_DASA_SIM
897 /* use r4 as the working variable */
898 /* turn on MA17 (LOCCTL.7) */
899 lwz r4,0x84(r3) /* LOCTL is at offset 0x84 */
900 ori r4,r4,0x80 /* make bit 7 = 1 -- MA17 mode */
901 stw r4,0x84(r3) /* LOCTL is at offset 0x84 */
902#endif
903
904 /* turn on MA16..13 (LCS0BRD.12 = 0) */
905 lwz r4,0x100(r3) /* LCS0BRD is at offset 0x100 */
906 andi. r4,r4,0xefff /* make bit 12 = 0 */
907 stw r4,0x100(r3) /* LCS0BRD is at offset 0x100 */
908
909 /* make sure above stores all comlete before going on */
910 sync
911
912 /* last thing, set local init status done bit (DEVINIT.31) */
913 lwz r4,0x80(r3) /* DEVINIT is at offset 0x80 */
914 oris r4,r4,0x8000 /* make bit 31 = 1 */
915 stw r4,0x80(r3) /* DEVINIT is at offset 0x80 */
916
917 /* clear all pending interrupts and disable all interrupts */
918 li r4,-1 /* set p1 to 0xffffffff */
919 stw r4,0x1b0(r3) /* clear all pending interrupts */
920 stw r4,0x1b8(r3) /* clear all pending interrupts */
921 li r4,0 /* set r4 to 0 */
922 stw r4,0x1b4(r3) /* disable all interrupts */
923 stw r4,0x1bc(r3) /* disable all interrupts */
924
925 /* make sure above stores all comlete before going on */
926 sync
927
c821b5f1
GE
928 /* Set-up icache cacheability. */
929 lis r1, CFG_ICACHE_SACR_VALUE@h
930 ori r1, r1, CFG_ICACHE_SACR_VALUE@l
931 mticcr r1
932 isync
0442ed86 933
c821b5f1
GE
934 /* Set-up dcache cacheability. */
935 lis r1, CFG_DCACHE_SACR_VALUE@h
936 ori r1, r1, CFG_DCACHE_SACR_VALUE@l
937 mtdccr r1
0442ed86
WD
938
939 addis r1,r0,CFG_INIT_RAM_ADDR@h
53677ef1 940 ori r1,r1,CFG_INIT_SP_OFFSET /* set up the stack to SDRAM */
0442ed86
WD
941 li r0, 0 /* Make room for stack frame header and */
942 stwu r0, -4(r1) /* clear final stack frame so that */
943 stwu r0, -4(r1) /* stack backtraces terminate cleanly */
944
945 GET_GOT /* initialize GOT access */
946
947 bl board_init_f /* run first part of init code (from Flash) */
948
949#endif /* CONFIG_IOP480 */
950
951/*****************************************************************************/
e01bd218
SR
952#if defined(CONFIG_405GP) || defined(CONFIG_405CR) || \
953 defined(CONFIG_405EP) || defined(CONFIG_405EZ) || \
dbbd1257 954 defined(CONFIG_405EX) || defined(CONFIG_405)
0442ed86
WD
955 /*----------------------------------------------------------------------- */
956 /* Clear and set up some registers. */
957 /*----------------------------------------------------------------------- */
958 addi r4,r0,0x0000
dbbd1257 959#if !defined(CONFIG_405EX)
0442ed86 960 mtspr sgr,r4
dbbd1257
SR
961#else
962 /*
963 * On 405EX, completely clearing the SGR leads to PPC hangup
964 * upon PCIe configuration access. The PCIe memory regions
965 * need to be guarded!
966 */
967 lis r3,0x0000
968 ori r3,r3,0x7FFC
969 mtspr sgr,r3
970#endif
0442ed86
WD
971 mtspr dcwr,r4
972 mtesr r4 /* clear Exception Syndrome Reg */
973 mttcr r4 /* clear Timer Control Reg */
974 mtxer r4 /* clear Fixed-Point Exception Reg */
975 mtevpr r4 /* clear Exception Vector Prefix Reg */
0442ed86
WD
976 addi r4,r0,(0xFFFF-0x10000) /* set r4 to 0xFFFFFFFF (status in the */
977 /* dbsr is cleared by setting bits to 1) */
978 mtdbsr r4 /* clear/reset the dbsr */
979
c821b5f1 980 /* Invalidate the i- and d-caches. */
0442ed86
WD
981 bl invalidate_icache
982 bl invalidate_dcache
983
c821b5f1
GE
984 /* Set-up icache cacheability. */
985 lis r4, CFG_ICACHE_SACR_VALUE@h
986 ori r4, r4, CFG_ICACHE_SACR_VALUE@l
987 mticcr r4
0442ed86
WD
988 isync
989
c821b5f1
GE
990 /* Set-up dcache cacheability. */
991 lis r4, CFG_DCACHE_SACR_VALUE@h
992 ori r4, r4, CFG_DCACHE_SACR_VALUE@l
993 mtdccr r4
0442ed86 994
dbbd1257 995#if !(defined(CFG_EBC_PB0AP) && defined(CFG_EBC_PB0CR)) || defined(CONFIG_405EX)
0442ed86
WD
996 /*----------------------------------------------------------------------- */
997 /* Tune the speed and size for flash CS0 */
998 /*----------------------------------------------------------------------- */
999 bl ext_bus_cntlr_init
1000#endif
dbbd1257
SR
1001#if !(defined(CFG_INIT_DCACHE_CS) || defined(CFG_TEMP_STACK_OCM))
1002 /*
c821b5f1
GE
1003 * For boards that don't have OCM and can't use the data cache
1004 * for their primordial stack, setup stack here directly after the
1005 * SDRAM is initialized in ext_bus_cntlr_init.
dbbd1257
SR
1006 */
1007 lis r1, CFG_INIT_RAM_ADDR@h
1008 ori r1,r1,CFG_INIT_SP_OFFSET /* set up the stack in SDRAM */
1009
1010 li r0, 0 /* Make room for stack frame header and */
1011 stwu r0, -4(r1) /* clear final stack frame so that */
1012 stwu r0, -4(r1) /* stack backtraces terminate cleanly */
1013 /*
1014 * Set up a dummy frame to store reset vector as return address.
1015 * this causes stack underflow to reset board.
1016 */
1017 stwu r1, -8(r1) /* Save back chain and move SP */
1018 lis r0, RESET_VECTOR@h /* Address of reset vector */
1019 ori r0, r0, RESET_VECTOR@l
1020 stwu r1, -8(r1) /* Save back chain and move SP */
1021 stw r0, +12(r1) /* Save return addr (underflow vect) */
1022#endif /* !(CFG_INIT_DCACHE_CS || !CFG_TEM_STACK_OCM) */
0442ed86 1023
b867d705
SR
1024#if defined(CONFIG_405EP)
1025 /*----------------------------------------------------------------------- */
1026 /* DMA Status, clear to come up clean */
1027 /*----------------------------------------------------------------------- */
53677ef1 1028 addis r3,r0, 0xFFFF /* Clear all existing DMA status */
f901a83b
WD
1029 ori r3,r3, 0xFFFF
1030 mtdcr dmasr, r3
b867d705 1031
53677ef1 1032 bl ppc405ep_init /* do ppc405ep specific init */
b867d705
SR
1033#endif /* CONFIG_405EP */
1034
0442ed86 1035#if defined(CFG_OCM_DATA_ADDR) && defined(CFG_OCM_DATA_SIZE)
e01bd218
SR
1036#if defined(CONFIG_405EZ)
1037 /********************************************************************
1038 * Setup OCM - On Chip Memory - PPC405EZ uses OCM Controller V2
1039 *******************************************************************/
1040 /*
1041 * We can map the OCM on the PLB3, so map it at
1042 * CFG_OCM_DATA_ADDR + 0x8000
1043 */
1044 lis r3,CFG_OCM_DATA_ADDR@h /* OCM location */
1045 ori r3,r3,CFG_OCM_DATA_ADDR@l
df8a24cd 1046 ori r3,r3,0x0270 /* 16K for Bank 1, R/W/Enable */
e01bd218
SR
1047 mtdcr ocmplb3cr1,r3 /* Set PLB Access */
1048 ori r3,r3,0x4000 /* Add 0x4000 for bank 2 */
1049 mtdcr ocmplb3cr2,r3 /* Set PLB Access */
1050 isync
1051
83b4cfa3 1052 lis r3,CFG_OCM_DATA_ADDR@h /* OCM location */
e01bd218 1053 ori r3,r3,CFG_OCM_DATA_ADDR@l
83b4cfa3
WD
1054 ori r3,r3,0x0270 /* 16K for Bank 1, R/W/Enable */
1055 mtdcr ocmdscr1, r3 /* Set Data Side */
1056 mtdcr ocmiscr1, r3 /* Set Instruction Side */
e01bd218 1057 ori r3,r3,0x4000 /* Add 0x4000 for bank 2 */
83b4cfa3
WD
1058 mtdcr ocmdscr2, r3 /* Set Data Side */
1059 mtdcr ocmiscr2, r3 /* Set Instruction Side */
1060 addis r3,0,0x0800 /* OCM Data Parity Disable - 1 Wait State */
d7568947 1061 mtdcr ocmdsisdpc,r3
e01bd218
SR
1062
1063 isync
3cb86f3e 1064#else /* CONFIG_405EZ */
0442ed86
WD
1065 /********************************************************************
1066 * Setup OCM - On Chip Memory
1067 *******************************************************************/
1068 /* Setup OCM */
8bde7f77
WD
1069 lis r0, 0x7FFF
1070 ori r0, r0, 0xFFFF
f901a83b 1071 mfdcr r3, ocmiscntl /* get instr-side IRAM config */
3cb86f3e
SR
1072 mfdcr r4, ocmdscntl /* get data-side IRAM config */
1073 and r3, r3, r0 /* disable data-side IRAM */
1074 and r4, r4, r0 /* disable data-side IRAM */
1075 mtdcr ocmiscntl, r3 /* set instr-side IRAM config */
1076 mtdcr ocmdscntl, r4 /* set data-side IRAM config */
8bde7f77 1077 isync
0442ed86 1078
83b4cfa3 1079 lis r3,CFG_OCM_DATA_ADDR@h /* OCM location */
3cb86f3e 1080 ori r3,r3,CFG_OCM_DATA_ADDR@l
0442ed86
WD
1081 mtdcr ocmdsarc, r3
1082 addis r4, 0, 0xC000 /* OCM data area enabled */
1083 mtdcr ocmdscntl, r4
8bde7f77 1084 isync
e01bd218 1085#endif /* CONFIG_405EZ */
0442ed86
WD
1086#endif
1087
c440bfe6
SR
1088#ifdef CONFIG_NAND_SPL
1089 /*
1090 * Copy SPL from cache into internal SRAM
1091 */
1092 li r4,(CFG_NAND_BOOT_SPL_SIZE >> 2) - 1
1093 mtctr r4
1094 lis r2,CFG_NAND_BOOT_SPL_SRC@h
1095 ori r2,r2,CFG_NAND_BOOT_SPL_SRC@l
1096 lis r3,CFG_NAND_BOOT_SPL_DST@h
1097 ori r3,r3,CFG_NAND_BOOT_SPL_DST@l
1098spl_loop:
1099 lwzu r4,4(r2)
1100 stwu r4,4(r3)
1101 bdnz spl_loop
1102
1103 /*
1104 * Jump to code in RAM
1105 */
1106 bl 00f
110700: mflr r10
1108 lis r3,(CFG_NAND_BOOT_SPL_SRC - CFG_NAND_BOOT_SPL_DST)@h
1109 ori r3,r3,(CFG_NAND_BOOT_SPL_SRC - CFG_NAND_BOOT_SPL_DST)@l
1110 sub r10,r10,r3
1111 addi r10,r10,28
1112 mtlr r10
1113 blr
1114
1115start_ram:
1116 sync
1117 isync
1118#endif /* CONFIG_NAND_SPL */
1119
0442ed86
WD
1120 /*----------------------------------------------------------------------- */
1121 /* Setup temporary stack in DCACHE or OCM if needed for SDRAM SPD. */
1122 /*----------------------------------------------------------------------- */
1123#ifdef CFG_INIT_DCACHE_CS
c821b5f1
GE
1124 li r4, PBxAP
1125 mtdcr ebccfga, r4
1126 lis r4, CFG_INIT_DCACHE_PBxAR@h
1127 ori r4, r4, CFG_INIT_DCACHE_PBxAR@l
1128 mtdcr ebccfgd, r4
1129
1130 addi r4, 0, PBxCR
1131 mtdcr ebccfga, r4
1132 lis r4, CFG_INIT_DCACHE_PBxCR@h
1133 ori r4, r4, CFG_INIT_DCACHE_PBxCR@l
1134 mtdcr ebccfgd, r4
1135
1136 /*
1137 * Enable the data cache for the 128MB storage access control region
1138 * at CFG_INIT_RAM_ADDR.
1139 */
1140 mfdccr r4
1141 oris r4, r4, PPC_128MB_SACR_VALUE(CFG_INIT_RAM_ADDR)@h
1142 ori r4, r4, PPC_128MB_SACR_VALUE(CFG_INIT_RAM_ADDR)@l
0442ed86
WD
1143 mtdccr r4
1144
c821b5f1
GE
1145 /*
1146 * Preallocate data cache lines to be used to avoid a subsequent
1147 * cache miss and an ensuing machine check exception when exceptions
1148 * are enabled.
1149 */
1150 li r0, 0
0442ed86 1151
c821b5f1
GE
1152 lis r3, CFG_INIT_RAM_ADDR@h
1153 ori r3, r3, CFG_INIT_RAM_ADDR@l
0442ed86 1154
c821b5f1
GE
1155 lis r4, CFG_INIT_RAM_END@h
1156 ori r4, r4, CFG_INIT_RAM_END@l
1157
1158 /*
1159 * Convert the size, in bytes, to the number of cache lines/blocks
1160 * to preallocate.
1161 */
1162 clrlwi. r5, r4, (32 - L1_CACHE_SHIFT)
1163 srwi r5, r4, L1_CACHE_SHIFT
1164 beq ..load_counter
1165 addi r5, r5, 0x0001
1166..load_counter:
1167 mtctr r5
1168
1169 /* Preallocate the computed number of cache blocks. */
1170..alloc_dcache_block:
1171 dcba r0, r3
1172 addi r3, r3, L1_CACHE_BYTES
1173 bdnz ..alloc_dcache_block
1174 sync
1175
1176 /*
1177 * Load the initial stack pointer and data area and convert the size,
1178 * in bytes, to the number of words to initialize to a known value.
1179 */
1180 lis r1, CFG_INIT_RAM_ADDR@h
1181 ori r1, r1, CFG_INIT_SP_OFFSET@l
1182
1183 lis r4, (CFG_INIT_RAM_END >> 2)@h
1184 ori r4, r4, (CFG_INIT_RAM_END >> 2)@l
0442ed86
WD
1185 mtctr r4
1186
c821b5f1
GE
1187 lis r2, CFG_INIT_RAM_ADDR@h
1188 ori r2, r2, CFG_INIT_RAM_END@l
0442ed86 1189
c821b5f1
GE
1190 lis r4, CFG_INIT_RAM_PATTERN@h
1191 ori r4, r4, CFG_INIT_RAM_PATTERN@l
0442ed86
WD
1192
1193..stackloop:
c821b5f1 1194 stwu r4, -4(r2)
0442ed86
WD
1195 bdnz ..stackloop
1196
c821b5f1
GE
1197 /*
1198 * Make room for stack frame header and clear final stack frame so
1199 * that stack backtraces terminate cleanly.
1200 */
1201 stwu r0, -4(r1)
1202 stwu r0, -4(r1)
1203
0442ed86
WD
1204 /*
1205 * Set up a dummy frame to store reset vector as return address.
1206 * this causes stack underflow to reset board.
1207 */
1208 stwu r1, -8(r1) /* Save back chain and move SP */
1209 addis r0, 0, RESET_VECTOR@h /* Address of reset vector */
1210 ori r0, r0, RESET_VECTOR@l
1211 stwu r1, -8(r1) /* Save back chain and move SP */
1212 stw r0, +12(r1) /* Save return addr (underflow vect) */
1213
1214#elif defined(CFG_TEMP_STACK_OCM) && \
1215 (defined(CFG_OCM_DATA_ADDR) && defined(CFG_OCM_DATA_SIZE))
1216 /*
1217 * Stack in OCM.
1218 */
1219
1220 /* Set up Stack at top of OCM */
1221 lis r1, (CFG_INIT_RAM_ADDR + CFG_INIT_SP_OFFSET)@h
1222 ori r1, r1, (CFG_INIT_RAM_ADDR + CFG_INIT_SP_OFFSET)@l
1223
1224 /* Set up a zeroized stack frame so that backtrace works right */
1225 li r0, 0
1226 stwu r0, -4(r1)
1227 stwu r0, -4(r1)
1228
1229 /*
1230 * Set up a dummy frame to store reset vector as return address.
1231 * this causes stack underflow to reset board.
1232 */
1233 stwu r1, -8(r1) /* Save back chain and move SP */
1234 lis r0, RESET_VECTOR@h /* Address of reset vector */
1235 ori r0, r0, RESET_VECTOR@l
1236 stwu r1, -8(r1) /* Save back chain and move SP */
1237 stw r0, +12(r1) /* Save return addr (underflow vect) */
1238#endif /* CFG_INIT_DCACHE_CS */
1239
1240 /*----------------------------------------------------------------------- */
f901a83b 1241 /* Initialize SDRAM Controller */
0442ed86
WD
1242 /*----------------------------------------------------------------------- */
1243 bl sdram_init
1244
c440bfe6
SR
1245#ifdef CONFIG_NAND_SPL
1246 bl nand_boot /* will not return */
1247#else
0442ed86
WD
1248 GET_GOT /* initialize GOT access */
1249
f901a83b 1250 bl cpu_init_f /* run low-level CPU init code (from Flash) */
0442ed86
WD
1251
1252 /* NEVER RETURNS! */
1253 bl board_init_f /* run first part of init code (from Flash) */
c440bfe6 1254#endif /* CONFIG_NAND_SPL */
0442ed86 1255
12f34241
WD
1256#endif /* CONFIG_405GP || CONFIG_405CR || CONFIG_405 || CONFIG_405EP */
1257 /*----------------------------------------------------------------------- */
0442ed86
WD
1258
1259
887e2ec9 1260#ifndef CONFIG_NAND_SPL
0442ed86
WD
1261/*
1262 * This code finishes saving the registers to the exception frame
1263 * and jumps to the appropriate handler for the exception.
1264 * Register r21 is pointer into trap frame, r1 has new stack pointer.
1265 */
1266 .globl transfer_to_handler
1267transfer_to_handler:
1268 stw r22,_NIP(r21)
1269 lis r22,MSR_POW@h
1270 andc r23,r23,r22
1271 stw r23,_MSR(r21)
1272 SAVE_GPR(7, r21)
1273 SAVE_4GPRS(8, r21)
1274 SAVE_8GPRS(12, r21)
1275 SAVE_8GPRS(24, r21)
0442ed86
WD
1276 mflr r23
1277 andi. r24,r23,0x3f00 /* get vector offset */
1278 stw r24,TRAP(r21)
1279 li r22,0
1280 stw r22,RESULT(r21)
1281 mtspr SPRG2,r22 /* r1 is now kernel sp */
0442ed86
WD
1282 lwz r24,0(r23) /* virtual address of handler */
1283 lwz r23,4(r23) /* where to go when done */
1284 mtspr SRR0,r24
1285 mtspr SRR1,r20
1286 mtlr r23
1287 SYNC
1288 rfi /* jump to handler, enable MMU */
1289
1290int_return:
1291 mfmsr r28 /* Disable interrupts */
1292 li r4,0
1293 ori r4,r4,MSR_EE
1294 andc r28,r28,r4
1295 SYNC /* Some chip revs need this... */
1296 mtmsr r28
1297 SYNC
1298 lwz r2,_CTR(r1)
1299 lwz r0,_LINK(r1)
1300 mtctr r2
1301 mtlr r0
1302 lwz r2,_XER(r1)
1303 lwz r0,_CCR(r1)
1304 mtspr XER,r2
1305 mtcrf 0xFF,r0
1306 REST_10GPRS(3, r1)
1307 REST_10GPRS(13, r1)
1308 REST_8GPRS(23, r1)
1309 REST_GPR(31, r1)
1310 lwz r2,_NIP(r1) /* Restore environment */
1311 lwz r0,_MSR(r1)
1312 mtspr SRR0,r2
1313 mtspr SRR1,r0
1314 lwz r0,GPR0(r1)
1315 lwz r2,GPR2(r1)
1316 lwz r1,GPR1(r1)
1317 SYNC
1318 rfi
1319
1320crit_return:
1321 mfmsr r28 /* Disable interrupts */
1322 li r4,0
1323 ori r4,r4,MSR_EE
1324 andc r28,r28,r4
1325 SYNC /* Some chip revs need this... */
1326 mtmsr r28
1327 SYNC
1328 lwz r2,_CTR(r1)
1329 lwz r0,_LINK(r1)
1330 mtctr r2
1331 mtlr r0
1332 lwz r2,_XER(r1)
1333 lwz r0,_CCR(r1)
1334 mtspr XER,r2
1335 mtcrf 0xFF,r0
1336 REST_10GPRS(3, r1)
1337 REST_10GPRS(13, r1)
1338 REST_8GPRS(23, r1)
1339 REST_GPR(31, r1)
1340 lwz r2,_NIP(r1) /* Restore environment */
1341 lwz r0,_MSR(r1)
83b4cfa3
WD
1342 mtspr csrr0,r2
1343 mtspr csrr1,r0
0442ed86
WD
1344 lwz r0,GPR0(r1)
1345 lwz r2,GPR2(r1)
1346 lwz r1,GPR1(r1)
1347 SYNC
1348 rfci
1349
efa35cf1
GB
1350#ifdef CONFIG_440
1351mck_return:
83b4cfa3
WD
1352 mfmsr r28 /* Disable interrupts */
1353 li r4,0
1354 ori r4,r4,MSR_EE
1355 andc r28,r28,r4
1356 SYNC /* Some chip revs need this... */
1357 mtmsr r28
1358 SYNC
1359 lwz r2,_CTR(r1)
1360 lwz r0,_LINK(r1)
1361 mtctr r2
1362 mtlr r0
1363 lwz r2,_XER(r1)
1364 lwz r0,_CCR(r1)
1365 mtspr XER,r2
1366 mtcrf 0xFF,r0
1367 REST_10GPRS(3, r1)
1368 REST_10GPRS(13, r1)
1369 REST_8GPRS(23, r1)
1370 REST_GPR(31, r1)
1371 lwz r2,_NIP(r1) /* Restore environment */
1372 lwz r0,_MSR(r1)
1373 mtspr mcsrr0,r2
1374 mtspr mcsrr1,r0
1375 lwz r0,GPR0(r1)
1376 lwz r2,GPR2(r1)
1377 lwz r1,GPR1(r1)
1378 SYNC
1379 rfmci
efa35cf1
GB
1380#endif /* CONFIG_440 */
1381
1382
0442ed86
WD
1383 .globl get_pvr
1384get_pvr:
1385 mfspr r3, PVR
1386 blr
1387
0442ed86
WD
1388/*------------------------------------------------------------------------------- */
1389/* Function: out16 */
1390/* Description: Output 16 bits */
1391/*------------------------------------------------------------------------------- */
1392 .globl out16
1393out16:
1394 sth r4,0x0000(r3)
1395 blr
1396
1397/*------------------------------------------------------------------------------- */
1398/* Function: out16r */
1399/* Description: Byte reverse and output 16 bits */
1400/*------------------------------------------------------------------------------- */
1401 .globl out16r
1402out16r:
1403 sthbrx r4,r0,r3
1404 blr
1405
0442ed86
WD
1406/*------------------------------------------------------------------------------- */
1407/* Function: out32r */
1408/* Description: Byte reverse and output 32 bits */
1409/*------------------------------------------------------------------------------- */
1410 .globl out32r
1411out32r:
1412 stwbrx r4,r0,r3
1413 blr
1414
1415/*------------------------------------------------------------------------------- */
1416/* Function: in16 */
1417/* Description: Input 16 bits */
1418/*------------------------------------------------------------------------------- */
1419 .globl in16
1420in16:
1421 lhz r3,0x0000(r3)
1422 blr
1423
1424/*------------------------------------------------------------------------------- */
1425/* Function: in16r */
1426/* Description: Input 16 bits and byte reverse */
1427/*------------------------------------------------------------------------------- */
1428 .globl in16r
1429in16r:
1430 lhbrx r3,r0,r3
1431 blr
1432
0442ed86
WD
1433/*------------------------------------------------------------------------------- */
1434/* Function: in32r */
1435/* Description: Input 32 bits and byte reverse */
1436/*------------------------------------------------------------------------------- */
1437 .globl in32r
1438in32r:
1439 lwbrx r3,r0,r3
1440 blr
1441
0442ed86
WD
1442/*
1443 * void relocate_code (addr_sp, gd, addr_moni)
1444 *
1445 * This "function" does not return, instead it continues in RAM
1446 * after relocating the monitor code.
1447 *
c821b5f1
GE
1448 * r3 = Relocated stack pointer
1449 * r4 = Relocated global data pointer
1450 * r5 = Relocated text pointer
0442ed86
WD
1451 */
1452 .globl relocate_code
1453relocate_code:
c821b5f1 1454#if defined(CONFIG_4xx_DCACHE) || defined(CFG_INIT_DCACHE_CS)
9b94ac61 1455 /*
c821b5f1
GE
1456 * We need to flush the initial global data (gd_t) before the dcache
1457 * will be invalidated.
9b94ac61
SR
1458 */
1459
c821b5f1
GE
1460 /* Save registers */
1461 mr r9, r3
1462 mr r10, r4
1463 mr r11, r5
9b94ac61 1464
c821b5f1
GE
1465 /* Flush initial global data range */
1466 mr r3, r4
1467 addi r4, r4, CFG_GBL_DATA_SIZE@l
9b94ac61
SR
1468 bl flush_dcache_range
1469
c821b5f1
GE
1470#if defined(CFG_INIT_DCACHE_CS)
1471 /*
1472 * Undo the earlier data cache set-up for the primordial stack and
1473 * data area. First, invalidate the data cache and then disable data
1474 * cacheability for that area. Finally, restore the EBC values, if
1475 * any.
1476 */
1477
1478 /* Invalidate the primordial stack and data area in cache */
1479 lis r3, CFG_INIT_RAM_ADDR@h
1480 ori r3, r3, CFG_INIT_RAM_ADDR@l
1481
1482 lis r4, CFG_INIT_RAM_END@h
1483 ori r4, r4, CFG_INIT_RAM_END@l
1484 add r4, r4, r3
1485
1486 bl invalidate_dcache_range
1487
1488 /* Disable cacheability for the region */
1489 mfdccr r3
1490 lis r4, ~PPC_128MB_SACR_VALUE(CFG_INIT_RAM_ADDR)@h
1491 ori r4, r4, ~PPC_128MB_SACR_VALUE(CFG_INIT_RAM_ADDR)@l
1492 and r3, r3, r4
1493 mtdccr r3
1494
1495 /* Restore the EBC parameters */
1496 li r3, PBxAP
1497 mtdcr ebccfga, r3
1498 lis r3, PBxAP_VAL@h
1499 ori r3, r3, PBxAP_VAL@l
1500 mtdcr ebccfgd, r3
1501
1502 li r3, PBxCR
1503 mtdcr ebccfga, r3
1504 lis r3, PBxCR_VAL@h
1505 ori r3, r3, PBxCR_VAL@l
1506 mtdcr ebccfgd, r3
1507#endif /* defined(CFG_INIT_DCACHE_CS) */
1508
1509 /* Restore registers */
1510 mr r3, r9
1511 mr r4, r10
1512 mr r5, r11
1513#endif /* defined(CONFIG_4xx_DCACHE) || defined(CFG_INIT_DCACHE_CS) */
e02c521d
SR
1514
1515#ifdef CFG_INIT_RAM_DCACHE
1516 /*
1517 * Unlock the previously locked d-cache
1518 */
1519 msync
1520 isync
1521 /* set TFLOOR/NFLOOR to 0 again */
1522 lis r6,0x0001
1523 ori r6,r6,0xf800
1524 mtspr dvlim,r6
1525 lis r6,0x0000
1526 ori r6,r6,0x0000
1527 mtspr dnv0,r6
1528 mtspr dnv1,r6
1529 mtspr dnv2,r6
1530 mtspr dnv3,r6
1531 mtspr dtv0,r6
1532 mtspr dtv1,r6
1533 mtspr dtv2,r6
1534 mtspr dtv3,r6
1535 msync
1536 isync
1537#endif /* CFG_INIT_RAM_DCACHE */
1538
887e2ec9
SR
1539#if defined(CONFIG_440EP) || defined(CONFIG_440GR) || \
1540 defined(CONFIG_440EPX) || defined(CONFIG_440GRX) || \
2801b2d2
SR
1541 defined(CONFIG_440SP) || defined(CONFIG_440SPE) || \
1542 defined(CONFIG_460EX) || defined(CONFIG_460GT)
a4c8d138
SR
1543 /*
1544 * On some 440er platforms the cache is enabled in the first TLB (Boot-CS)
1545 * to speed up the boot process. Now this cache needs to be disabled.
1546 */
1547 iccci 0,0 /* Invalidate inst cache */
1548 dccci 0,0 /* Invalidate data cache, now no longer our stack */
c157d8e2 1549 sync
a4c8d138 1550 isync
85dc2a7f
NG
1551#ifdef CFG_TLB_FOR_BOOT_FLASH
1552 addi r1,r0,CFG_TLB_FOR_BOOT_FLASH /* Use defined TLB */
1553#else
1554 addi r1,r0,0x0000 /* Default TLB entry is #0 */
c821b5f1 1555#endif /* CFG_TLB_FOR_BOOT_FLASH */
c157d8e2 1556 tlbre r0,r1,0x0002 /* Read contents */
6e7fb6ea 1557 ori r0,r0,0x0c00 /* Or in the inhibit, write through bit */
f901a83b 1558 tlbwe r0,r1,0x0002 /* Save it out */
a4c8d138 1559 sync
c157d8e2 1560 isync
c821b5f1 1561#endif /* defined(CONFIG_440EP) || ... || defined(CONFIG_460GT) */
0442ed86
WD
1562 mr r1, r3 /* Set new stack pointer */
1563 mr r9, r4 /* Save copy of Init Data pointer */
1564 mr r10, r5 /* Save copy of Destination Address */
1565
1566 mr r3, r5 /* Destination Address */
1567 lis r4, CFG_MONITOR_BASE@h /* Source Address */
1568 ori r4, r4, CFG_MONITOR_BASE@l
3b57fe0a
WD
1569 lwz r5, GOT(__init_end)
1570 sub r5, r5, r4
9b94ac61 1571 li r6, L1_CACHE_BYTES /* Cache Line Size */
0442ed86
WD
1572
1573 /*
1574 * Fix GOT pointer:
1575 *
1576 * New GOT-PTR = (old GOT-PTR - CFG_MONITOR_BASE) + Destination Address
1577 *
1578 * Offset:
1579 */
1580 sub r15, r10, r4
1581
1582 /* First our own GOT */
1583 add r14, r14, r15
c821b5f1 1584 /* then the one used by the C code */
0442ed86
WD
1585 add r30, r30, r15
1586
1587 /*
1588 * Now relocate code
1589 */
1590
1591 cmplw cr1,r3,r4
1592 addi r0,r5,3
1593 srwi. r0,r0,2
1594 beq cr1,4f /* In place copy is not necessary */
1595 beq 7f /* Protect against 0 count */
1596 mtctr r0
1597 bge cr1,2f
1598
1599 la r8,-4(r4)
1600 la r7,-4(r3)
16011: lwzu r0,4(r8)
1602 stwu r0,4(r7)
1603 bdnz 1b
1604 b 4f
1605
16062: slwi r0,r0,2
1607 add r8,r4,r0
1608 add r7,r3,r0
16093: lwzu r0,-4(r8)
1610 stwu r0,-4(r7)
1611 bdnz 3b
1612
1613/*
1614 * Now flush the cache: note that we must start from a cache aligned
1615 * address. Otherwise we might miss one cache line.
1616 */
16174: cmpwi r6,0
1618 add r5,r3,r5
1619 beq 7f /* Always flush prefetch queue in any case */
1620 subi r0,r6,1
1621 andc r3,r3,r0
1622 mr r4,r3
16235: dcbst 0,r4
1624 add r4,r4,r6
1625 cmplw r4,r5
1626 blt 5b
1627 sync /* Wait for all dcbst to complete on bus */
1628 mr r4,r3
16296: icbi 0,r4
1630 add r4,r4,r6
1631 cmplw r4,r5
1632 blt 6b
16337: sync /* Wait for all icbi to complete on bus */
1634 isync
1635
1636/*
1637 * We are done. Do not return, instead branch to second part of board
1638 * initialization, now running from RAM.
1639 */
1640
efa35cf1 1641 addi r0, r10, in_ram - _start + _START_OFFSET
0442ed86
WD
1642 mtlr r0
1643 blr /* NEVER RETURNS! */
1644
1645in_ram:
1646
1647 /*
1648 * Relocation Function, r14 point to got2+0x8000
1649 *
1650 * Adjust got2 pointers, no need to check for 0, this code
1651 * already puts a few entries in the table.
1652 */
1653 li r0,__got2_entries@sectoff@l
1654 la r3,GOT(_GOT2_TABLE_)
1655 lwz r11,GOT(_GOT2_TABLE_)
1656 mtctr r0
1657 sub r11,r3,r11
1658 addi r3,r3,-4
16591: lwzu r0,4(r3)
1660 add r0,r0,r11
1661 stw r0,0(r3)
1662 bdnz 1b
1663
1664 /*
1665 * Now adjust the fixups and the pointers to the fixups
1666 * in case we need to move ourselves again.
1667 */
16682: li r0,__fixup_entries@sectoff@l
1669 lwz r3,GOT(_FIXUP_TABLE_)
1670 cmpwi r0,0
1671 mtctr r0
1672 addi r3,r3,-4
1673 beq 4f
16743: lwzu r4,4(r3)
1675 lwzux r0,r4,r11
1676 add r0,r0,r11
1677 stw r10,0(r3)
1678 stw r0,0(r4)
1679 bdnz 3b
16804:
1681clear_bss:
1682 /*
1683 * Now clear BSS segment
1684 */
5d232d0e 1685 lwz r3,GOT(__bss_start)
0442ed86
WD
1686 lwz r4,GOT(_end)
1687
1688 cmplw 0, r3, r4
42ed33ff 1689 beq 7f
0442ed86
WD
1690
1691 li r0, 0
42ed33ff
AG
1692
1693 andi. r5, r4, 3
1694 beq 6f
1695 sub r4, r4, r5
1696 mtctr r5
1697 mr r5, r4
16985: stb r0, 0(r5)
1699 addi r5, r5, 1
1700 bdnz 5b
17016:
0442ed86
WD
1702 stw r0, 0(r3)
1703 addi r3, r3, 4
1704 cmplw 0, r3, r4
42ed33ff 1705 bne 6b
0442ed86 1706
42ed33ff 17077:
0442ed86
WD
1708 mr r3, r9 /* Init Data pointer */
1709 mr r4, r10 /* Destination Address */
1710 bl board_init_r
1711
0442ed86
WD
1712 /*
1713 * Copy exception vector code to low memory
1714 *
1715 * r3: dest_addr
1716 * r7: source address, r8: end address, r9: target address
1717 */
1718 .globl trap_init
1719trap_init:
efa35cf1 1720 lwz r7, GOT(_start_of_vectors)
0442ed86
WD
1721 lwz r8, GOT(_end_of_vectors)
1722
682011ff 1723 li r9, 0x100 /* reset vector always at 0x100 */
0442ed86
WD
1724
1725 cmplw 0, r7, r8
1726 bgelr /* return if r7>=r8 - just in case */
1727
1728 mflr r4 /* save link register */
17291:
1730 lwz r0, 0(r7)
1731 stw r0, 0(r9)
1732 addi r7, r7, 4
1733 addi r9, r9, 4
1734 cmplw 0, r7, r8
1735 bne 1b
1736
1737 /*
1738 * relocate `hdlr' and `int_return' entries
1739 */
efa35cf1
GB
1740 li r7, .L_MachineCheck - _start + _START_OFFSET
1741 li r8, Alignment - _start + _START_OFFSET
0442ed86
WD
17422:
1743 bl trap_reloc
efa35cf1 1744 addi r7, r7, 0x100 /* next exception vector */
0442ed86
WD
1745 cmplw 0, r7, r8
1746 blt 2b
1747
efa35cf1 1748 li r7, .L_Alignment - _start + _START_OFFSET
0442ed86
WD
1749 bl trap_reloc
1750
efa35cf1 1751 li r7, .L_ProgramCheck - _start + _START_OFFSET
0442ed86
WD
1752 bl trap_reloc
1753
efa35cf1
GB
1754#ifdef CONFIG_440
1755 li r7, .L_FPUnavailable - _start + _START_OFFSET
83b4cfa3 1756 bl trap_reloc
0442ed86 1757
efa35cf1 1758 li r7, .L_Decrementer - _start + _START_OFFSET
83b4cfa3 1759 bl trap_reloc
efa35cf1
GB
1760
1761 li r7, .L_APU - _start + _START_OFFSET
83b4cfa3 1762 bl trap_reloc
df8a24cd 1763
83b4cfa3
WD
1764 li r7, .L_InstructionTLBError - _start + _START_OFFSET
1765 bl trap_reloc
efa35cf1 1766
83b4cfa3
WD
1767 li r7, .L_DataTLBError - _start + _START_OFFSET
1768 bl trap_reloc
efa35cf1
GB
1769#else /* CONFIG_440 */
1770 li r7, .L_PIT - _start + _START_OFFSET
83b4cfa3 1771 bl trap_reloc
efa35cf1
GB
1772
1773 li r7, .L_InstructionTLBMiss - _start + _START_OFFSET
83b4cfa3 1774 bl trap_reloc
efa35cf1
GB
1775
1776 li r7, .L_DataTLBMiss - _start + _START_OFFSET
83b4cfa3 1777 bl trap_reloc
efa35cf1
GB
1778#endif /* CONFIG_440 */
1779
83b4cfa3
WD
1780 li r7, .L_DebugBreakpoint - _start + _START_OFFSET
1781 bl trap_reloc
0442ed86 1782
887e2ec9 1783#if !defined(CONFIG_440)
9a7b408c
SR
1784 addi r7,r0,0x1000 /* set ME bit (Machine Exceptions) */
1785 oris r7,r7,0x0002 /* set CE bit (Critical Exceptions) */
1786 mtmsr r7 /* change MSR */
1787#else
887e2ec9
SR
1788 bl __440_msr_set
1789 b __440_msr_continue
9a7b408c 1790
887e2ec9 1791__440_msr_set:
9a7b408c
SR
1792 addi r7,r0,0x1000 /* set ME bit (Machine Exceptions) */
1793 oris r7,r7,0x0002 /* set CE bit (Critical Exceptions) */
1794 mtspr srr1,r7
1795 mflr r7
1796 mtspr srr0,r7
1797 rfi
887e2ec9 1798__440_msr_continue:
9a7b408c
SR
1799#endif
1800
0442ed86
WD
1801 mtlr r4 /* restore link register */
1802 blr
1803
1804 /*
1805 * Function: relocate entries for one exception vector
1806 */
1807trap_reloc:
1808 lwz r0, 0(r7) /* hdlr ... */
1809 add r0, r0, r3 /* ... += dest_addr */
1810 stw r0, 0(r7)
1811
1812 lwz r0, 4(r7) /* int_return ... */
1813 add r0, r0, r3 /* ... += dest_addr */
1814 stw r0, 4(r7)
1815
1816 blr
cf959c7d
SR
1817
1818#if defined(CONFIG_440)
1819/*----------------------------------------------------------------------------+
1820| dcbz_area.
1821+----------------------------------------------------------------------------*/
1822 function_prolog(dcbz_area)
1823 rlwinm. r5,r4,0,27,31
83b4cfa3
WD
1824 rlwinm r5,r4,27,5,31
1825 beq ..d_ra2
1826 addi r5,r5,0x0001
1827..d_ra2:mtctr r5
1828..d_ag2:dcbz r0,r3
1829 addi r3,r3,32
1830 bdnz ..d_ag2
cf959c7d
SR
1831 sync
1832 blr
1833 function_epilog(dcbz_area)
cf959c7d 1834#endif /* CONFIG_440 */
887e2ec9 1835#endif /* CONFIG_NAND_SPL */
b867d705 1836
cf959c7d
SR
1837/*------------------------------------------------------------------------------- */
1838/* Function: in8 */
1839/* Description: Input 8 bits */
1840/*------------------------------------------------------------------------------- */
1841 .globl in8
1842in8:
1843 lbz r3,0x0000(r3)
1844 blr
1845
1846/*------------------------------------------------------------------------------- */
1847/* Function: out8 */
1848/* Description: Output 8 bits */
1849/*------------------------------------------------------------------------------- */
1850 .globl out8
1851out8:
1852 stb r4,0x0000(r3)
1853 blr
1854
1855/*------------------------------------------------------------------------------- */
1856/* Function: out32 */
1857/* Description: Output 32 bits */
1858/*------------------------------------------------------------------------------- */
1859 .globl out32
1860out32:
1861 stw r4,0x0000(r3)
1862 blr
1863
1864/*------------------------------------------------------------------------------- */
1865/* Function: in32 */
1866/* Description: Input 32 bits */
1867/*------------------------------------------------------------------------------- */
1868 .globl in32
1869in32:
1870 lwz 3,0x0000(3)
1871 blr
b867d705
SR
1872
1873/**************************************************************************/
f901a83b 1874/* PPC405EP specific stuff */
b867d705
SR
1875/**************************************************************************/
1876#ifdef CONFIG_405EP
1877ppc405ep_init:
b828dda6 1878
c157d8e2 1879#ifdef CONFIG_BUBINGA
b828dda6
SR
1880 /*
1881 * Initialize EBC chip selects 1 & 4 and GPIO pins (for alternate
1882 * function) to support FPGA and NVRAM accesses below.
1883 */
1884
1885 lis r3,GPIO0_OSRH@h /* config GPIO output select */
1886 ori r3,r3,GPIO0_OSRH@l
1887 lis r4,CFG_GPIO0_OSRH@h
1888 ori r4,r4,CFG_GPIO0_OSRH@l
1889 stw r4,0(r3)
1890 lis r3,GPIO0_OSRL@h
1891 ori r3,r3,GPIO0_OSRL@l
1892 lis r4,CFG_GPIO0_OSRL@h
1893 ori r4,r4,CFG_GPIO0_OSRL@l
1894 stw r4,0(r3)
1895
1896 lis r3,GPIO0_ISR1H@h /* config GPIO input select */
1897 ori r3,r3,GPIO0_ISR1H@l
1898 lis r4,CFG_GPIO0_ISR1H@h
1899 ori r4,r4,CFG_GPIO0_ISR1H@l
1900 stw r4,0(r3)
1901 lis r3,GPIO0_ISR1L@h
1902 ori r3,r3,GPIO0_ISR1L@l
1903 lis r4,CFG_GPIO0_ISR1L@h
1904 ori r4,r4,CFG_GPIO0_ISR1L@l
1905 stw r4,0(r3)
1906
1907 lis r3,GPIO0_TSRH@h /* config GPIO three-state select */
1908 ori r3,r3,GPIO0_TSRH@l
1909 lis r4,CFG_GPIO0_TSRH@h
1910 ori r4,r4,CFG_GPIO0_TSRH@l
1911 stw r4,0(r3)
1912 lis r3,GPIO0_TSRL@h
1913 ori r3,r3,GPIO0_TSRL@l
1914 lis r4,CFG_GPIO0_TSRL@h
1915 ori r4,r4,CFG_GPIO0_TSRL@l
1916 stw r4,0(r3)
1917
1918 lis r3,GPIO0_TCR@h /* config GPIO driver output enables */
1919 ori r3,r3,GPIO0_TCR@l
1920 lis r4,CFG_GPIO0_TCR@h
1921 ori r4,r4,CFG_GPIO0_TCR@l
1922 stw r4,0(r3)
1923
1924 li r3,pb1ap /* program EBC bank 1 for RTC access */
1925 mtdcr ebccfga,r3
1926 lis r3,CFG_EBC_PB1AP@h
1927 ori r3,r3,CFG_EBC_PB1AP@l
1928 mtdcr ebccfgd,r3
1929 li r3,pb1cr
1930 mtdcr ebccfga,r3
1931 lis r3,CFG_EBC_PB1CR@h
1932 ori r3,r3,CFG_EBC_PB1CR@l
1933 mtdcr ebccfgd,r3
1934
1935 li r3,pb1ap /* program EBC bank 1 for RTC access */
1936 mtdcr ebccfga,r3
1937 lis r3,CFG_EBC_PB1AP@h
1938 ori r3,r3,CFG_EBC_PB1AP@l
1939 mtdcr ebccfgd,r3
1940 li r3,pb1cr
1941 mtdcr ebccfga,r3
1942 lis r3,CFG_EBC_PB1CR@h
1943 ori r3,r3,CFG_EBC_PB1CR@l
1944 mtdcr ebccfgd,r3
1945
1946 li r3,pb4ap /* program EBC bank 4 for FPGA access */
1947 mtdcr ebccfga,r3
1948 lis r3,CFG_EBC_PB4AP@h
1949 ori r3,r3,CFG_EBC_PB4AP@l
1950 mtdcr ebccfgd,r3
1951 li r3,pb4cr
1952 mtdcr ebccfga,r3
1953 lis r3,CFG_EBC_PB4CR@h
1954 ori r3,r3,CFG_EBC_PB4CR@l
1955 mtdcr ebccfgd,r3
1956#endif
8bde7f77
WD
1957
1958 /*
1959 !-----------------------------------------------------------------------
1960 ! Check to see if chip is in bypass mode.
1961 ! If so, write stored CPC0_PLLMR0 and CPC0_PLLMR1 values and perform a
1962 ! CPU reset Otherwise, skip this step and keep going.
f901a83b
WD
1963 ! Note: Running BIOS in bypass mode is not supported since PLB speed
1964 ! will not be fast enough for the SDRAM (min 66MHz)
8bde7f77 1965 !-----------------------------------------------------------------------
b867d705 1966 */
f901a83b 1967 mfdcr r5, CPC0_PLLMR1
53677ef1 1968 rlwinm r4,r5,1,0x1 /* get system clock source (SSCS) */
f901a83b 1969 cmpi cr0,0,r4,0x1
b867d705 1970
53677ef1
WD
1971 beq pll_done /* if SSCS =b'1' then PLL has */
1972 /* already been set */
1973 /* and CPU has been reset */
1974 /* so skip to next section */
b867d705 1975
c157d8e2 1976#ifdef CONFIG_BUBINGA
b867d705 1977 /*
8bde7f77
WD
1978 !-----------------------------------------------------------------------
1979 ! Read NVRAM to get value to write in PLLMR.
1980 ! If value has not been correctly saved, write default value
1981 ! Default config values (assuming on-board 33MHz SYS_CLK) are above.
1982 ! See CPU_DEFAULT_200 and CPU_DEFAULT_266 above.
1983 !
1984 ! WARNING: This code assumes the first three words in the nvram_t
f901a83b
WD
1985 ! structure in openbios.h. Changing the beginning of
1986 ! the structure will break this code.
8bde7f77
WD
1987 !
1988 !-----------------------------------------------------------------------
b867d705 1989 */
f901a83b
WD
1990 addis r3,0,NVRAM_BASE@h
1991 addi r3,r3,NVRAM_BASE@l
1992
1993 lwz r4, 0(r3)
1994 addis r5,0,NVRVFY1@h
1995 addi r5,r5,NVRVFY1@l
53677ef1 1996 cmp cr0,0,r4,r5 /* Compare 1st NVRAM Magic number*/
f901a83b
WD
1997 bne ..no_pllset
1998 addi r3,r3,4
1999 lwz r4, 0(r3)
2000 addis r5,0,NVRVFY2@h
2001 addi r5,r5,NVRVFY2@l
53677ef1 2002 cmp cr0,0,r4,r5 /* Compare 2 NVRAM Magic number */
f901a83b
WD
2003 bne ..no_pllset
2004 addi r3,r3,8 /* Skip over conf_size */
2005 lwz r4, 4(r3) /* Load PLLMR1 value from NVRAM */
2006 lwz r3, 0(r3) /* Load PLLMR0 value from NVRAM */
2007 rlwinm r5,r4,1,0x1 /* get system clock source (SSCS) */
2008 cmpi cr0,0,r5,1 /* See if PLL is locked */
2009 beq pll_write
b867d705 2010..no_pllset:
c157d8e2 2011#endif /* CONFIG_BUBINGA */
b867d705 2012
d4024bb7
JO
2013#ifdef CONFIG_TAIHU
2014 mfdcr r4, CPC0_BOOT
2015 andi. r5, r4, CPC0_BOOT_SEP@l
2016 bne strap_1 /* serial eeprom present */
2017 addis r5,0,CPLD_REG0_ADDR@h
2018 ori r5,r5,CPLD_REG0_ADDR@l
2019 andi. r5, r5, 0x10
2020 bne _pci_66mhz
2021#endif /* CONFIG_TAIHU */
2022
779e9751
SR
2023#if defined(CONFIG_ZEUS)
2024 mfdcr r4, CPC0_BOOT
2025 andi. r5, r4, CPC0_BOOT_SEP@l
53677ef1 2026 bne strap_1 /* serial eeprom present */
779e9751
SR
2027 lis r3,0x0000
2028 addi r3,r3,0x3030
2029 lis r4,0x8042
2030 addi r4,r4,0x223e
2031 b 1f
2032strap_1:
2033 mfdcr r3, CPC0_PLLMR0
2034 mfdcr r4, CPC0_PLLMR1
2035 b 1f
2036#endif
2037
53677ef1
WD
2038 addis r3,0,PLLMR0_DEFAULT@h /* PLLMR0 default value */
2039 ori r3,r3,PLLMR0_DEFAULT@l /* */
2040 addis r4,0,PLLMR1_DEFAULT@h /* PLLMR1 default value */
2041 ori r4,r4,PLLMR1_DEFAULT@l /* */
b867d705 2042
d4024bb7
JO
2043#ifdef CONFIG_TAIHU
2044 b 1f
2045_pci_66mhz:
2046 addis r3,0,PLLMR0_DEFAULT_PCI66@h
2047 ori r3,r3,PLLMR0_DEFAULT_PCI66@l
2048 addis r4,0,PLLMR1_DEFAULT_PCI66@h
2049 ori r4,r4,PLLMR1_DEFAULT_PCI66@l
2050 b 1f
2051strap_1:
2052 mfdcr r3, CPC0_PLLMR0
2053 mfdcr r4, CPC0_PLLMR1
d4024bb7
JO
2054#endif /* CONFIG_TAIHU */
2055
779e9751 20561:
53677ef1 2057 b pll_write /* Write the CPC0_PLLMR with new value */
b867d705
SR
2058
2059pll_done:
8bde7f77
WD
2060 /*
2061 !-----------------------------------------------------------------------
2062 ! Clear Soft Reset Register
2063 ! This is needed to enable PCI if not booting from serial EPROM
2064 !-----------------------------------------------------------------------
b867d705 2065 */
f901a83b
WD
2066 addi r3, 0, 0x0
2067 mtdcr CPC0_SRR, r3
b867d705 2068
f901a83b
WD
2069 addis r3,0,0x0010
2070 mtctr r3
b867d705 2071pci_wait:
f901a83b 2072 bdnz pci_wait
b867d705 2073
53677ef1 2074 blr /* return to main code */
b867d705
SR
2075
2076/*
2077!-----------------------------------------------------------------------------
f901a83b
WD
2078! Function: pll_write
2079! Description: Updates the value of the CPC0_PLLMR according to CMOS27E documentation
2080! That is:
2081! 1. Pll is first disabled (de-activated by putting in bypass mode)
2082! 2. PLL is reset
2083! 3. Clock dividers are set while PLL is held in reset and bypassed
2084! 4. PLL Reset is cleared
2085! 5. Wait 100us for PLL to lock
2086! 6. A core reset is performed
b867d705
SR
2087! Input: r3 = Value to write to CPC0_PLLMR0
2088! Input: r4 = Value to write to CPC0_PLLMR1
2089! Output r3 = none
2090!-----------------------------------------------------------------------------
2091*/
2092pll_write:
8bde7f77
WD
2093 mfdcr r5, CPC0_UCR
2094 andis. r5,r5,0xFFFF
53677ef1
WD
2095 ori r5,r5,0x0101 /* Stop the UART clocks */
2096 mtdcr CPC0_UCR,r5 /* Before changing PLL */
8bde7f77
WD
2097
2098 mfdcr r5, CPC0_PLLMR1
53677ef1 2099 rlwinm r5,r5,0,0x7FFFFFFF /* Disable PLL */
f901a83b 2100 mtdcr CPC0_PLLMR1,r5
53677ef1 2101 oris r5,r5,0x4000 /* Set PLL Reset */
f901a83b
WD
2102 mtdcr CPC0_PLLMR1,r5
2103
53677ef1
WD
2104 mtdcr CPC0_PLLMR0,r3 /* Set clock dividers */
2105 rlwinm r5,r4,0,0x3FFFFFFF /* Reset & Bypass new PLL dividers */
2106 oris r5,r5,0x4000 /* Set PLL Reset */
2107 mtdcr CPC0_PLLMR1,r5 /* Set clock dividers */
2108 rlwinm r5,r5,0,0xBFFFFFFF /* Clear PLL Reset */
f901a83b 2109 mtdcr CPC0_PLLMR1,r5
b867d705
SR
2110
2111 /*
8bde7f77
WD
2112 ! Wait min of 100us for PLL to lock.
2113 ! See CMOS 27E databook for more info.
2114 ! At 200MHz, that means waiting 20,000 instructions
b867d705 2115 */
f901a83b
WD
2116 addi r3,0,20000 /* 2000 = 0x4e20 */
2117 mtctr r3
b867d705 2118pll_wait:
f901a83b 2119 bdnz pll_wait
8bde7f77 2120
f901a83b
WD
2121 oris r5,r5,0x8000 /* Enable PLL */
2122 mtdcr CPC0_PLLMR1,r5 /* Engage */
8bde7f77
WD
2123
2124 /*
2125 * Reset CPU to guarantee timings are OK
2126 * Not sure if this is needed...
2127 */
2128 addis r3,0,0x1000
53677ef1
WD
2129 mtspr dbcr0,r3 /* This will cause a CPU core reset, and */
2130 /* execution will continue from the poweron */
2131 /* vector of 0xfffffffc */
b867d705 2132#endif /* CONFIG_405EP */
4745acaa
SR
2133
2134#if defined(CONFIG_440)
4745acaa
SR
2135/*----------------------------------------------------------------------------+
2136| mttlb3.
2137+----------------------------------------------------------------------------*/
2138 function_prolog(mttlb3)
2139 TLBWE(4,3,2)
2140 blr
2141 function_epilog(mttlb3)
2142
2143/*----------------------------------------------------------------------------+
2144| mftlb3.
2145+----------------------------------------------------------------------------*/
2146 function_prolog(mftlb3)
74357114 2147 TLBRE(3,3,2)
4745acaa
SR
2148 blr
2149 function_epilog(mftlb3)
2150
2151/*----------------------------------------------------------------------------+
2152| mttlb2.
2153+----------------------------------------------------------------------------*/
2154 function_prolog(mttlb2)
2155 TLBWE(4,3,1)
2156 blr
2157 function_epilog(mttlb2)
2158
2159/*----------------------------------------------------------------------------+
2160| mftlb2.
2161+----------------------------------------------------------------------------*/
2162 function_prolog(mftlb2)
74357114 2163 TLBRE(3,3,1)
4745acaa
SR
2164 blr
2165 function_epilog(mftlb2)
2166
2167/*----------------------------------------------------------------------------+
2168| mttlb1.
2169+----------------------------------------------------------------------------*/
2170 function_prolog(mttlb1)
2171 TLBWE(4,3,0)
2172 blr
2173 function_epilog(mttlb1)
2174
2175/*----------------------------------------------------------------------------+
2176| mftlb1.
2177+----------------------------------------------------------------------------*/
2178 function_prolog(mftlb1)
74357114 2179 TLBRE(3,3,0)
4745acaa
SR
2180 blr
2181 function_epilog(mftlb1)
2182#endif /* CONFIG_440 */