blob: 3fe13daaf38d6be5b1f514273fedda65a4379d62 [file] [log] [blame]
wdenk0442ed82002-11-03 10:24:00 +00001/*
2 * Copyright (C) 1998 Dan Malek <dmalek@jlc.net>
3 * Copyright (C) 1999 Magnus Damm <kieraypc01.p.y.kie.era.ericsson.se>
4 * Copyright (C) 2000,2001,2002 Wolfgang Denk <wd@denx.de>
5 *
6 * See file CREDITS for list of people who contributed to this
7 * project.
8 *
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License as
11 * published by the Free Software Foundation; either version 2 of
12 * the License, or (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
22 * MA 02111-1307 USA
23 */
24/*------------------------------------------------------------------------------+ */
25/* */
26/* This source code has been made available to you by IBM on an AS-IS */
27/* basis. Anyone receiving this source is licensed under IBM */
28/* copyrights to use it in any way he or she deems fit, including */
29/* copying it, modifying it, compiling it, and redistributing it either */
30/* with or without modifications. No license under IBM patents or */
31/* patent applications is to be implied by the copyright license. */
32/* */
33/* Any user of this software should understand that IBM cannot provide */
34/* technical support for this software and will not be responsible for */
35/* any consequences resulting from the use of this software. */
36/* */
37/* Any person who transfers this source code or any derivative work */
38/* must include the IBM copyright notice, this paragraph, and the */
39/* preceding two paragraphs in the transferred software. */
40/* */
41/* COPYRIGHT I B M CORPORATION 1995 */
42/* LICENSED MATERIAL - PROGRAM PROPERTY OF I B M */
43/*------------------------------------------------------------------------------- */
44
Wolfgang Denk0ee70772005-09-23 11:05:55 +020045/* U-Boot - Startup Code for AMCC 4xx PowerPC based Embedded Boards
wdenk0442ed82002-11-03 10:24:00 +000046 *
47 *
48 * The processor starts at 0xfffffffc and the code is executed
49 * from flash/rom.
50 * in memory, but as long we don't jump around before relocating.
51 * board_init lies at a quite high address and when the cpu has
52 * jumped there, everything is ok.
53 * This works because the cpu gives the FLASH (CS0) the whole
54 * address space at startup, and board_init lies as a echo of
55 * the flash somewhere up there in the memorymap.
56 *
57 * board_init will change CS0 to be positioned at the correct
58 * address and (s)dram will be positioned at address 0
59 */
60#include <config.h>
61#include <mpc8xx.h>
62#include <ppc4xx.h>
63#include <version.h>
64
65#define _LINUX_CONFIG_H 1 /* avoid reading Linux autoconf.h file */
66
67#include <ppc_asm.tmpl>
68#include <ppc_defs.h>
69
70#include <asm/cache.h>
71#include <asm/mmu.h>
72
73#ifndef CONFIG_IDENT_STRING
74#define CONFIG_IDENT_STRING ""
75#endif
76
77#ifdef CFG_INIT_DCACHE_CS
78# if (CFG_INIT_DCACHE_CS == 0)
79# define PBxAP pb0ap
80# define PBxCR pb0cr
81# endif
82# if (CFG_INIT_DCACHE_CS == 1)
83# define PBxAP pb1ap
84# define PBxCR pb1cr
85# endif
86# if (CFG_INIT_DCACHE_CS == 2)
87# define PBxAP pb2ap
88# define PBxCR pb2cr
89# endif
90# if (CFG_INIT_DCACHE_CS == 3)
91# define PBxAP pb3ap
92# define PBxCR pb3cr
93# endif
94# if (CFG_INIT_DCACHE_CS == 4)
95# define PBxAP pb4ap
96# define PBxCR pb4cr
97# endif
98# if (CFG_INIT_DCACHE_CS == 5)
99# define PBxAP pb5ap
100# define PBxCR pb5cr
101# endif
102# if (CFG_INIT_DCACHE_CS == 6)
103# define PBxAP pb6ap
104# define PBxCR pb6cr
105# endif
106# if (CFG_INIT_DCACHE_CS == 7)
107# define PBxAP pb7ap
108# define PBxCR pb7cr
109# endif
110#endif /* CFG_INIT_DCACHE_CS */
111
112/* We don't want the MMU yet.
113*/
114#undef MSR_KERNEL
115#define MSR_KERNEL ( MSR_ME ) /* Machine Check */
116
117
118 .extern ext_bus_cntlr_init
119 .extern sdram_init
Stefan Roese42fbddd2006-09-07 11:51:23 +0200120#ifdef CONFIG_NAND_U_BOOT
121 .extern reconfig_tlb0
122#endif
wdenk0442ed82002-11-03 10:24:00 +0000123
124/*
125 * Set up GOT: Global Offset Table
126 *
127 * Use r14 to access the GOT
128 */
Stefan Roese42fbddd2006-09-07 11:51:23 +0200129#if !defined(CONFIG_NAND_SPL)
wdenk0442ed82002-11-03 10:24:00 +0000130 START_GOT
131 GOT_ENTRY(_GOT2_TABLE_)
132 GOT_ENTRY(_FIXUP_TABLE_)
133
134 GOT_ENTRY(_start)
135 GOT_ENTRY(_start_of_vectors)
136 GOT_ENTRY(_end_of_vectors)
137 GOT_ENTRY(transfer_to_handler)
138
wdenkb9a83a92003-05-30 12:48:29 +0000139 GOT_ENTRY(__init_end)
wdenk0442ed82002-11-03 10:24:00 +0000140 GOT_ENTRY(_end)
wdenkbf2f8c92003-05-22 22:52:13 +0000141 GOT_ENTRY(__bss_start)
wdenk0442ed82002-11-03 10:24:00 +0000142 END_GOT
Stefan Roese42fbddd2006-09-07 11:51:23 +0200143#endif /* CONFIG_NAND_SPL */
144
145#if defined(CONFIG_NAND_U_BOOT) && !defined(CONFIG_NAND_SPL)
146 /*
147 * NAND U-Boot image is started from offset 0
148 */
149 .text
150 bl reconfig_tlb0
151 GET_GOT
152 bl cpu_init_f /* run low-level CPU init code (from Flash) */
153 bl board_init_f
154#endif
wdenk0442ed82002-11-03 10:24:00 +0000155
156/*
157 * 440 Startup -- on reset only the top 4k of the effective
158 * address space is mapped in by an entry in the instruction
159 * and data shadow TLB. The .bootpg section is located in the
160 * top 4k & does only what's necessary to map in the the rest
161 * of the boot rom. Once the boot rom is mapped in we can
162 * proceed with normal startup.
163 *
164 * NOTE: CS0 only covers the top 2MB of the effective address
165 * space after reset.
166 */
167
168#if defined(CONFIG_440)
Stefan Roese42fbddd2006-09-07 11:51:23 +0200169#if !defined(CONFIG_NAND_SPL)
wdenk0442ed82002-11-03 10:24:00 +0000170 .section .bootpg,"ax"
Stefan Roese42fbddd2006-09-07 11:51:23 +0200171#endif
wdenk0442ed82002-11-03 10:24:00 +0000172 .globl _start_440
173
174/**************************************************************************/
175_start_440:
Wolfgang Denk4df0da52006-10-09 00:42:01 +0200176 /*--------------------------------------------------------------------+
177 | 440EPX BUP Change - Hardware team request
178 +--------------------------------------------------------------------*/
Stefan Roese42fbddd2006-09-07 11:51:23 +0200179#if defined(CONFIG_440EPX) || defined(CONFIG_440GRX)
180 sync
181 nop
182 nop
183#endif
Marian Balakowicz49d0eee2006-06-30 16:30:46 +0200184 /*----------------------------------------------------------------+
185 | Core bug fix. Clear the esr
186 +-----------------------------------------------------------------*/
Marian Balakowiczbe9463b2006-07-06 21:17:24 +0200187 li r0,0
Wolfgang Denkba940932006-07-19 13:50:38 +0200188 mtspr esr,r0
wdenk0442ed82002-11-03 10:24:00 +0000189 /*----------------------------------------------------------------*/
190 /* Clear and set up some registers. */
191 /*----------------------------------------------------------------*/
Wolfgang Denk8dd4d332005-08-06 01:42:58 +0200192 iccci r0,r0 /* NOTE: operands not used for 440 */
193 dccci r0,r0 /* NOTE: operands not used for 440 */
wdenk0442ed82002-11-03 10:24:00 +0000194 sync
195 li r0,0
196 mtspr srr0,r0
197 mtspr srr1,r0
198 mtspr csrr0,r0
199 mtspr csrr1,r0
Stefan Roese42fbddd2006-09-07 11:51:23 +0200200 /* NOTE: 440GX adds machine check status regs */
201#if defined(CONFIG_440) && !defined(CONFIG_440GP)
Wolfgang Denk8dd4d332005-08-06 01:42:58 +0200202 mtspr mcsrr0,r0
203 mtspr mcsrr1,r0
Stefan Roese42fbddd2006-09-07 11:51:23 +0200204 mfspr r1,mcsr
Wolfgang Denk8dd4d332005-08-06 01:42:58 +0200205 mtspr mcsr,r1
wdenk544e9732004-02-06 23:19:44 +0000206#endif
wdenk0442ed82002-11-03 10:24:00 +0000207 /*----------------------------------------------------------------*/
208 /* Initialize debug */
209 /*----------------------------------------------------------------*/
Stefan Roese42fbddd2006-09-07 11:51:23 +0200210 mfspr r1,dbcr0
211 andis. r1, r1, 0x8000 /* test DBCR0[EDM] bit */
212 bne skip_debug_init /* if set, don't clear debug register */
wdenk0442ed82002-11-03 10:24:00 +0000213 mtspr dbcr0,r0
214 mtspr dbcr1,r0
215 mtspr dbcr2,r0
216 mtspr iac1,r0
217 mtspr iac2,r0
218 mtspr iac3,r0
219 mtspr dac1,r0
220 mtspr dac2,r0
221 mtspr dvc1,r0
222 mtspr dvc2,r0
223
224 mfspr r1,dbsr
225 mtspr dbsr,r1 /* Clear all valid bits */
Stefan Roese42fbddd2006-09-07 11:51:23 +0200226skip_debug_init:
wdenk0442ed82002-11-03 10:24:00 +0000227
228 /*----------------------------------------------------------------*/
229 /* CCR0 init */
230 /*----------------------------------------------------------------*/
231 /* Disable store gathering & broadcast, guarantee inst/data
232 * cache block touch, force load/store alignment
233 * (see errata 1.12: 440_33)
234 */
235 lis r1,0x0030 /* store gathering & broadcast disable */
236 ori r1,r1,0x6000 /* cache touch */
237 mtspr ccr0,r1
238
Marian Balakowicz49d0eee2006-06-30 16:30:46 +0200239#if defined (CONFIG_440SPE)
240 /*----------------------------------------------------------------+
241 | Initialize Core Configuration Reg1.
242 | a. ICDPEI: Record even parity. Normal operation.
243 | b. ICTPEI: Record even parity. Normal operation.
244 | c. DCTPEI: Record even parity. Normal operation.
245 | d. DCDPEI: Record even parity. Normal operation.
246 | e. DCUPEI: Record even parity. Normal operation.
247 | f. DCMPEI: Record even parity. Normal operation.
248 | g. FCOM: Normal operation
249 | h. MMUPEI: Record even parity. Normal operation.
250 | i. FFF: Flush only as much data as necessary.
Marian Balakowiczbe9463b2006-07-06 21:17:24 +0200251 | j. TCS: Timebase increments from CPU clock.
Marian Balakowicz49d0eee2006-06-30 16:30:46 +0200252 +-----------------------------------------------------------------*/
Marian Balakowiczbe9463b2006-07-06 21:17:24 +0200253 li r0,0
Marian Balakowicz49d0eee2006-06-30 16:30:46 +0200254 mtspr ccr1, r0
255
256 /*----------------------------------------------------------------+
257 | Reset the timebase.
258 | The previous write to CCR1 sets the timebase source.
259 +-----------------------------------------------------------------*/
Marian Balakowicz49d0eee2006-06-30 16:30:46 +0200260 mtspr tbl, r0
261 mtspr tbu, r0
262#endif
263
wdenk0442ed82002-11-03 10:24:00 +0000264 /*----------------------------------------------------------------*/
265 /* Setup interrupt vectors */
266 /*----------------------------------------------------------------*/
267 mtspr ivpr,r0 /* Vectors start at 0x0000_0000 */
Wolfgang Denk8dd4d332005-08-06 01:42:58 +0200268 li r1,0x0100
wdenk0442ed82002-11-03 10:24:00 +0000269 mtspr ivor0,r1 /* Critical input */
Wolfgang Denk8dd4d332005-08-06 01:42:58 +0200270 li r1,0x0200
wdenk0442ed82002-11-03 10:24:00 +0000271 mtspr ivor1,r1 /* Machine check */
Wolfgang Denk8dd4d332005-08-06 01:42:58 +0200272 li r1,0x0300
wdenk0442ed82002-11-03 10:24:00 +0000273 mtspr ivor2,r1 /* Data storage */
Wolfgang Denk8dd4d332005-08-06 01:42:58 +0200274 li r1,0x0400
wdenk0442ed82002-11-03 10:24:00 +0000275 mtspr ivor3,r1 /* Instruction storage */
276 li r1,0x0500
277 mtspr ivor4,r1 /* External interrupt */
278 li r1,0x0600
279 mtspr ivor5,r1 /* Alignment */
280 li r1,0x0700
281 mtspr ivor6,r1 /* Program check */
282 li r1,0x0800
283 mtspr ivor7,r1 /* Floating point unavailable */
284 li r1,0x0c00
285 mtspr ivor8,r1 /* System call */
286 li r1,0x1000
287 mtspr ivor10,r1 /* Decrementer (PIT for 440) */
288 li r1,0x1400
289 mtspr ivor13,r1 /* Data TLB error */
290 li r1,0x1300
291 mtspr ivor14,r1 /* Instr TLB error */
292 li r1,0x2000
293 mtspr ivor15,r1 /* Debug */
294
295 /*----------------------------------------------------------------*/
296 /* Configure cache regions */
297 /*----------------------------------------------------------------*/
298 mtspr inv0,r0
299 mtspr inv1,r0
300 mtspr inv2,r0
301 mtspr inv3,r0
302 mtspr dnv0,r0
303 mtspr dnv1,r0
304 mtspr dnv2,r0
305 mtspr dnv3,r0
306 mtspr itv0,r0
307 mtspr itv1,r0
308 mtspr itv2,r0
309 mtspr itv3,r0
310 mtspr dtv0,r0
311 mtspr dtv1,r0
312 mtspr dtv2,r0
313 mtspr dtv3,r0
314
315 /*----------------------------------------------------------------*/
316 /* Cache victim limits */
317 /*----------------------------------------------------------------*/
318 /* floors 0, ceiling max to use the entire cache -- nothing locked
319 */
320 lis r1,0x0001
321 ori r1,r1,0xf800
322 mtspr ivlim,r1
323 mtspr dvlim,r1
324
Marian Balakowicz49d0eee2006-06-30 16:30:46 +0200325 /*----------------------------------------------------------------+
326 |Initialize MMUCR[STID] = 0.
327 +-----------------------------------------------------------------*/
328 mfspr r0,mmucr
329 addis r1,0,0xFFFF
330 ori r1,r1,0xFF00
331 and r0,r0,r1
332 mtspr mmucr,r0
333
wdenk0442ed82002-11-03 10:24:00 +0000334 /*----------------------------------------------------------------*/
335 /* Clear all TLB entries -- TID = 0, TS = 0 */
336 /*----------------------------------------------------------------*/
Marian Balakowicz49d0eee2006-06-30 16:30:46 +0200337 addis r0,0,0x0000
wdenk0442ed82002-11-03 10:24:00 +0000338 li r1,0x003f /* 64 TLB entries */
339 mtctr r1
Marian Balakowicz49d0eee2006-06-30 16:30:46 +0200340rsttlb: tlbwe r0,r1,0x0000 /* Invalidate all entries (V=0)*/
341 tlbwe r0,r1,0x0001
342 tlbwe r0,r1,0x0002
wdenk0442ed82002-11-03 10:24:00 +0000343 subi r1,r1,0x0001
Marian Balakowicz49d0eee2006-06-30 16:30:46 +0200344 bdnz rsttlb
wdenk0442ed82002-11-03 10:24:00 +0000345
346 /*----------------------------------------------------------------*/
347 /* TLB entry setup -- step thru tlbtab */
348 /*----------------------------------------------------------------*/
Rafal Jaworowskia2e7ef02006-08-10 12:43:17 +0200349#if defined(CONFIG_440SPE)
350 /*----------------------------------------------------------------*/
351 /* We have different TLB tables for revA and rev B of 440SPe */
352 /*----------------------------------------------------------------*/
353 mfspr r1, PVR
354 lis r0,0x5342
355 ori r0,r0,0x1891
356 cmpw r7,r1,r0
357 bne r7,..revA
358 bl tlbtabB
359 b ..goon
360..revA:
361 bl tlbtabA
362..goon:
363#else
wdenk0442ed82002-11-03 10:24:00 +0000364 bl tlbtab /* Get tlbtab pointer */
Rafal Jaworowskia2e7ef02006-08-10 12:43:17 +0200365#endif
wdenk0442ed82002-11-03 10:24:00 +0000366 mr r5,r0
367 li r1,0x003f /* 64 TLB entries max */
368 mtctr r1
369 li r4,0 /* TLB # */
370
371 addi r5,r5,-4
3721: lwzu r0,4(r5)
373 cmpwi r0,0
374 beq 2f /* 0 marks end */
375 lwzu r1,4(r5)
376 lwzu r2,4(r5)
377 tlbwe r0,r4,0 /* TLB Word 0 */
378 tlbwe r1,r4,1 /* TLB Word 1 */
379 tlbwe r2,r4,2 /* TLB Word 2 */
380 addi r4,r4,1 /* Next TLB */
381 bdnz 1b
382
383 /*----------------------------------------------------------------*/
384 /* Continue from 'normal' start */
385 /*----------------------------------------------------------------*/
Stefan Roese42fbddd2006-09-07 11:51:23 +02003862:
387
388#if defined(CONFIG_NAND_SPL)
389 /*
390 * Enable internal SRAM
391 */
392 lis r2,0x7fff
393 ori r2,r2,0xffff
394 mfdcr r1,isram0_dpc
395 and r1,r1,r2 /* Disable parity check */
396 mtdcr isram0_dpc,r1
397 mfdcr r1,isram0_pmeg
398 and r1,r1,r2 /* Disable pwr mgmt */
399 mtdcr isram0_pmeg,r1
400
401 /*
402 * Copy SPL from cache into internal SRAM
403 */
404 li r4,(CFG_NAND_BOOT_SPL_SIZE >> 2) - 1
405 mtctr r4
406 lis r2,CFG_NAND_BOOT_SPL_SRC@h
407 ori r2,r2,CFG_NAND_BOOT_SPL_SRC@l
408 lis r3,CFG_NAND_BOOT_SPL_DST@h
409 ori r3,r3,CFG_NAND_BOOT_SPL_DST@l
410spl_loop:
411 lwzu r4,4(r2)
412 stwu r4,4(r3)
413 bdnz spl_loop
414
415 /*
416 * Jump to code in RAM
417 */
418 bl 00f
41900: mflr r10
420 lis r3,(CFG_NAND_BOOT_SPL_SRC - CFG_NAND_BOOT_SPL_DST)@h
421 ori r3,r3,(CFG_NAND_BOOT_SPL_SRC - CFG_NAND_BOOT_SPL_DST)@l
422 sub r10,r10,r3
423 addi r10,r10,28
424 mtlr r10
425 blr
426
427start_ram:
428 sync
429 isync
430#endif
431
432 bl 3f
wdenk0442ed82002-11-03 10:24:00 +0000433 b _start
434
4353: li r0,0
436 mtspr srr1,r0 /* Keep things disabled for now */
437 mflr r1
438 mtspr srr0,r1
439 rfi
stroese434979e2003-05-23 11:18:02 +0000440#endif /* CONFIG_440 */
wdenk0442ed82002-11-03 10:24:00 +0000441
442/*
443 * r3 - 1st arg to board_init(): IMMP pointer
444 * r4 - 2nd arg to board_init(): boot flag
445 */
Stefan Roese42fbddd2006-09-07 11:51:23 +0200446#ifndef CONFIG_NAND_SPL
wdenk0442ed82002-11-03 10:24:00 +0000447 .text
448 .long 0x27051956 /* U-Boot Magic Number */
449 .globl version_string
450version_string:
451 .ascii U_BOOT_VERSION
452 .ascii " (", __DATE__, " - ", __TIME__, ")"
453 .ascii CONFIG_IDENT_STRING, "\0"
454
455/*
456 * Maybe this should be moved somewhere else because the current
457 * location (0x100) is where the CriticalInput Execption should be.
458 */
459 . = EXC_OFF_SYS_RESET
Stefan Roese42fbddd2006-09-07 11:51:23 +0200460#endif
wdenk0442ed82002-11-03 10:24:00 +0000461 .globl _start
462_start:
463
464/*****************************************************************************/
465#if defined(CONFIG_440)
466
467 /*----------------------------------------------------------------*/
468 /* Clear and set up some registers. */
469 /*----------------------------------------------------------------*/
470 li r0,0x0000
471 lis r1,0xffff
472 mtspr dec,r0 /* prevent dec exceptions */
473 mtspr tbl,r0 /* prevent fit & wdt exceptions */
474 mtspr tbu,r0
475 mtspr tsr,r1 /* clear all timer exception status */
476 mtspr tcr,r0 /* disable all */
477 mtspr esr,r0 /* clear exception syndrome register */
478 mtxer r0 /* clear integer exception register */
wdenk0442ed82002-11-03 10:24:00 +0000479
480 /*----------------------------------------------------------------*/
481 /* Debug setup -- some (not very good) ice's need an event*/
482 /* to establish control :-( Define CFG_INIT_DBCR to the dbsr */
483 /* value you need in this case 0x8cff 0000 should do the trick */
484 /*----------------------------------------------------------------*/
485#if defined(CFG_INIT_DBCR)
486 lis r1,0xffff
487 ori r1,r1,0xffff
488 mtspr dbsr,r1 /* Clear all status bits */
489 lis r0,CFG_INIT_DBCR@h
490 ori r0,r0,CFG_INIT_DBCR@l
491 mtspr dbcr0,r0
492 isync
493#endif
494
495 /*----------------------------------------------------------------*/
496 /* Setup the internal SRAM */
497 /*----------------------------------------------------------------*/
498 li r0,0
Stefan Roese42fbddd2006-09-07 11:51:23 +0200499
500#ifdef CFG_INIT_RAM_DCACHE
Stefan Roese326c9712005-08-01 16:41:48 +0200501 /* Clear Dcache to use as RAM */
Wolfgang Denk8dd4d332005-08-06 01:42:58 +0200502 addis r3,r0,CFG_INIT_RAM_ADDR@h
503 ori r3,r3,CFG_INIT_RAM_ADDR@l
504 addis r4,r0,CFG_INIT_RAM_END@h
505 ori r4,r4,CFG_INIT_RAM_END@l
Stefan Roese326c9712005-08-01 16:41:48 +0200506 rlwinm. r5,r4,0,27,31
Wolfgang Denk8dd4d332005-08-06 01:42:58 +0200507 rlwinm r5,r4,27,5,31
508 beq ..d_ran
509 addi r5,r5,0x0001
Stefan Roese326c9712005-08-01 16:41:48 +0200510..d_ran:
Wolfgang Denk8dd4d332005-08-06 01:42:58 +0200511 mtctr r5
Stefan Roese326c9712005-08-01 16:41:48 +0200512..d_ag:
Wolfgang Denk8dd4d332005-08-06 01:42:58 +0200513 dcbz r0,r3
514 addi r3,r3,32
515 bdnz ..d_ag
Stefan Roese42fbddd2006-09-07 11:51:23 +0200516#endif /* CFG_INIT_RAM_DCACHE */
517
518 /* 440EP & 440GR are only 440er PPC's without internal SRAM */
519#if !defined(CONFIG_440EP) && !defined(CONFIG_440GR)
520 /* not all PPC's have internal SRAM usable as L2-cache */
521#if defined(CONFIG_440GX) || defined(CONFIG_440SP) || defined(CONFIG_440SPE)
Wolfgang Denk8dd4d332005-08-06 01:42:58 +0200522 mtdcr l2_cache_cfg,r0 /* Ensure L2 Cache is off */
wdenk544e9732004-02-06 23:19:44 +0000523#endif
wdenk0442ed82002-11-03 10:24:00 +0000524
Stefan Roese42fbddd2006-09-07 11:51:23 +0200525 lis r2,0x7fff
wdenk0442ed82002-11-03 10:24:00 +0000526 ori r2,r2,0xffff
527 mfdcr r1,isram0_dpc
528 and r1,r1,r2 /* Disable parity check */
529 mtdcr isram0_dpc,r1
530 mfdcr r1,isram0_pmeg
Stefan Roese42fbddd2006-09-07 11:51:23 +0200531 and r1,r1,r2 /* Disable pwr mgmt */
wdenk0442ed82002-11-03 10:24:00 +0000532 mtdcr isram0_pmeg,r1
533
534 lis r1,0x8000 /* BAS = 8000_0000 */
Stefan Roese99644742005-11-29 18:18:21 +0100535#if defined(CONFIG_440GX) || defined(CONFIG_440SP)
wdenk544e9732004-02-06 23:19:44 +0000536 ori r1,r1,0x0980 /* first 64k */
Wolfgang Denk8dd4d332005-08-06 01:42:58 +0200537 mtdcr isram0_sb0cr,r1
wdenk544e9732004-02-06 23:19:44 +0000538 lis r1,0x8001
539 ori r1,r1,0x0980 /* second 64k */
Wolfgang Denk8dd4d332005-08-06 01:42:58 +0200540 mtdcr isram0_sb1cr,r1
wdenk544e9732004-02-06 23:19:44 +0000541 lis r1, 0x8002
542 ori r1,r1, 0x0980 /* third 64k */
Wolfgang Denk8dd4d332005-08-06 01:42:58 +0200543 mtdcr isram0_sb2cr,r1
wdenk544e9732004-02-06 23:19:44 +0000544 lis r1, 0x8003
545 ori r1,r1, 0x0980 /* fourth 64k */
Wolfgang Denk8dd4d332005-08-06 01:42:58 +0200546 mtdcr isram0_sb3cr,r1
Marian Balakowicz49d0eee2006-06-30 16:30:46 +0200547#elif defined(CONFIG_440SPE)
548 lis r1,0x0000 /* BAS = 0000_0000 */
549 ori r1,r1,0x0984 /* first 64k */
550 mtdcr isram0_sb0cr,r1
551 lis r1,0x0001
552 ori r1,r1,0x0984 /* second 64k */
553 mtdcr isram0_sb1cr,r1
554 lis r1, 0x0002
555 ori r1,r1, 0x0984 /* third 64k */
556 mtdcr isram0_sb2cr,r1
557 lis r1, 0x0003
558 ori r1,r1, 0x0984 /* fourth 64k */
559 mtdcr isram0_sb3cr,r1
Stefan Roese42fbddd2006-09-07 11:51:23 +0200560#elif defined(CONFIG_440GP)
wdenk0442ed82002-11-03 10:24:00 +0000561 ori r1,r1,0x0380 /* 8k rw */
562 mtdcr isram0_sb0cr,r1
Stefan Roese42fbddd2006-09-07 11:51:23 +0200563 mtdcr isram0_sb1cr,r0 /* Disable bank 1 */
Stefan Roese326c9712005-08-01 16:41:48 +0200564#endif
Stefan Roese42fbddd2006-09-07 11:51:23 +0200565#endif /* #if !defined(CONFIG_440EP) && !defined(CONFIG_440GR) */
wdenk0442ed82002-11-03 10:24:00 +0000566
567 /*----------------------------------------------------------------*/
568 /* Setup the stack in internal SRAM */
569 /*----------------------------------------------------------------*/
570 lis r1,CFG_INIT_RAM_ADDR@h
571 ori r1,r1,CFG_INIT_SP_OFFSET@l
wdenk0442ed82002-11-03 10:24:00 +0000572 li r0,0
573 stwu r0,-4(r1)
574 stwu r0,-4(r1) /* Terminate call chain */
575
576 stwu r1,-8(r1) /* Save back chain and move SP */
577 lis r0,RESET_VECTOR@h /* Address of reset vector */
578 ori r0,r0, RESET_VECTOR@l
579 stwu r1,-8(r1) /* Save back chain and move SP */
580 stw r0,+12(r1) /* Save return addr (underflow vect) */
581
Stefan Roese42fbddd2006-09-07 11:51:23 +0200582#ifdef CONFIG_NAND_SPL
583 bl nand_boot /* will not return */
584#else
wdenk0442ed82002-11-03 10:24:00 +0000585 GET_GOT
Stefan Roesec443fe92005-11-22 13:20:42 +0100586
587 bl cpu_init_f /* run low-level CPU init code (from Flash) */
wdenk0442ed82002-11-03 10:24:00 +0000588 bl board_init_f
Stefan Roese42fbddd2006-09-07 11:51:23 +0200589#endif
wdenk0442ed82002-11-03 10:24:00 +0000590
591#endif /* CONFIG_440 */
592
593/*****************************************************************************/
594#ifdef CONFIG_IOP480
595 /*----------------------------------------------------------------------- */
596 /* Set up some machine state registers. */
597 /*----------------------------------------------------------------------- */
598 addi r0,r0,0x0000 /* initialize r0 to zero */
599 mtspr esr,r0 /* clear Exception Syndrome Reg */
600 mttcr r0 /* timer control register */
601 mtexier r0 /* disable all interrupts */
wdenk0442ed82002-11-03 10:24:00 +0000602 addis r4,r0,0xFFFF /* set r4 to 0xFFFFFFFF (status in the */
603 ori r4,r4,0xFFFF /* dbsr is cleared by setting bits to 1) */
604 mtdbsr r4 /* clear/reset the dbsr */
605 mtexisr r4 /* clear all pending interrupts */
606 addis r4,r0,0x8000
607 mtexier r4 /* enable critical exceptions */
608 addis r4,r0,0x0000 /* assume 403GCX - enable core clk */
609 ori r4,r4,0x4020 /* dbling (no harm done on GA and GC */
610 mtiocr r4 /* since bit not used) & DRC to latch */
611 /* data bus on rising edge of CAS */
612 /*----------------------------------------------------------------------- */
613 /* Clear XER. */
614 /*----------------------------------------------------------------------- */
615 mtxer r0
616 /*----------------------------------------------------------------------- */
617 /* Invalidate i-cache and d-cache TAG arrays. */
618 /*----------------------------------------------------------------------- */
619 addi r3,0,1024 /* 1/4 of I-cache size, half of D-cache */
620 addi r4,0,1024 /* 1/4 of I-cache */
621..cloop:
622 iccci 0,r3
623 iccci r4,r3
624 dccci 0,r3
625 addic. r3,r3,-16 /* move back one cache line */
626 bne ..cloop /* loop back to do rest until r3 = 0 */
627
628 /* */
629 /* initialize IOP480 so it can read 1 MB code area for SRAM spaces */
630 /* this requires enabling MA[17..0], by default only MA[12..0] are enabled. */
631 /* */
632
633 /* first copy IOP480 register base address into r3 */
634 addis r3,0,0x5000 /* IOP480 register base address hi */
635/* ori r3,r3,0x0000 / IOP480 register base address lo */
636
637#ifdef CONFIG_ADCIOP
638 /* use r4 as the working variable */
639 /* turn on CS3 (LOCCTL.7) */
640 lwz r4,0x84(r3) /* LOCTL is at offset 0x84 */
641 andi. r4,r4,0xff7f /* make bit 7 = 0 -- CS3 mode */
642 stw r4,0x84(r3) /* LOCTL is at offset 0x84 */
643#endif
644
645#ifdef CONFIG_DASA_SIM
646 /* use r4 as the working variable */
647 /* turn on MA17 (LOCCTL.7) */
648 lwz r4,0x84(r3) /* LOCTL is at offset 0x84 */
649 ori r4,r4,0x80 /* make bit 7 = 1 -- MA17 mode */
650 stw r4,0x84(r3) /* LOCTL is at offset 0x84 */
651#endif
652
653 /* turn on MA16..13 (LCS0BRD.12 = 0) */
654 lwz r4,0x100(r3) /* LCS0BRD is at offset 0x100 */
655 andi. r4,r4,0xefff /* make bit 12 = 0 */
656 stw r4,0x100(r3) /* LCS0BRD is at offset 0x100 */
657
658 /* make sure above stores all comlete before going on */
659 sync
660
661 /* last thing, set local init status done bit (DEVINIT.31) */
662 lwz r4,0x80(r3) /* DEVINIT is at offset 0x80 */
663 oris r4,r4,0x8000 /* make bit 31 = 1 */
664 stw r4,0x80(r3) /* DEVINIT is at offset 0x80 */
665
666 /* clear all pending interrupts and disable all interrupts */
667 li r4,-1 /* set p1 to 0xffffffff */
668 stw r4,0x1b0(r3) /* clear all pending interrupts */
669 stw r4,0x1b8(r3) /* clear all pending interrupts */
670 li r4,0 /* set r4 to 0 */
671 stw r4,0x1b4(r3) /* disable all interrupts */
672 stw r4,0x1bc(r3) /* disable all interrupts */
673
674 /* make sure above stores all comlete before going on */
675 sync
676
677 /*----------------------------------------------------------------------- */
678 /* Enable two 128MB cachable regions. */
679 /*----------------------------------------------------------------------- */
680 addis r1,r0,0x8000
681 addi r1,r1,0x0001
682 mticcr r1 /* instruction cache */
683
684 addis r1,r0,0x0000
685 addi r1,r1,0x0000
686 mtdccr r1 /* data cache */
687
688 addis r1,r0,CFG_INIT_RAM_ADDR@h
689 ori r1,r1,CFG_INIT_SP_OFFSET /* set up the stack to SDRAM */
690 li r0, 0 /* Make room for stack frame header and */
691 stwu r0, -4(r1) /* clear final stack frame so that */
692 stwu r0, -4(r1) /* stack backtraces terminate cleanly */
693
694 GET_GOT /* initialize GOT access */
695
696 bl board_init_f /* run first part of init code (from Flash) */
697
698#endif /* CONFIG_IOP480 */
699
700/*****************************************************************************/
stroese434979e2003-05-23 11:18:02 +0000701#if defined(CONFIG_405GP) || defined(CONFIG_405CR) || defined(CONFIG_405) || defined(CONFIG_405EP)
wdenk0442ed82002-11-03 10:24:00 +0000702 /*----------------------------------------------------------------------- */
703 /* Clear and set up some registers. */
704 /*----------------------------------------------------------------------- */
705 addi r4,r0,0x0000
706 mtspr sgr,r4
707 mtspr dcwr,r4
708 mtesr r4 /* clear Exception Syndrome Reg */
709 mttcr r4 /* clear Timer Control Reg */
710 mtxer r4 /* clear Fixed-Point Exception Reg */
711 mtevpr r4 /* clear Exception Vector Prefix Reg */
wdenk0442ed82002-11-03 10:24:00 +0000712 addi r4,r0,(0xFFFF-0x10000) /* set r4 to 0xFFFFFFFF (status in the */
713 /* dbsr is cleared by setting bits to 1) */
714 mtdbsr r4 /* clear/reset the dbsr */
715
716 /*----------------------------------------------------------------------- */
717 /* Invalidate I and D caches. Enable I cache for defined memory regions */
718 /* to speed things up. Leave the D cache disabled for now. It will be */
719 /* enabled/left disabled later based on user selected menu options. */
720 /* Be aware that the I cache may be disabled later based on the menu */
721 /* options as well. See miscLib/main.c. */
722 /*----------------------------------------------------------------------- */
723 bl invalidate_icache
724 bl invalidate_dcache
725
726 /*----------------------------------------------------------------------- */
727 /* Enable two 128MB cachable regions. */
728 /*----------------------------------------------------------------------- */
729 addis r4,r0,0x8000
730 addi r4,r4,0x0001
731 mticcr r4 /* instruction cache */
732 isync
733
734 addis r4,r0,0x0000
735 addi r4,r4,0x0000
736 mtdccr r4 /* data cache */
737
738#if !(defined(CFG_EBC_PB0AP) && defined(CFG_EBC_PB0CR))
739 /*----------------------------------------------------------------------- */
740 /* Tune the speed and size for flash CS0 */
741 /*----------------------------------------------------------------------- */
742 bl ext_bus_cntlr_init
743#endif
744
stroese434979e2003-05-23 11:18:02 +0000745#if defined(CONFIG_405EP)
746 /*----------------------------------------------------------------------- */
747 /* DMA Status, clear to come up clean */
748 /*----------------------------------------------------------------------- */
Wolfgang Denk8dd4d332005-08-06 01:42:58 +0200749 addis r3,r0, 0xFFFF /* Clear all existing DMA status */
750 ori r3,r3, 0xFFFF
751 mtdcr dmasr, r3
stroese434979e2003-05-23 11:18:02 +0000752
Wolfgang Denk8dd4d332005-08-06 01:42:58 +0200753 bl ppc405ep_init /* do ppc405ep specific init */
stroese434979e2003-05-23 11:18:02 +0000754#endif /* CONFIG_405EP */
755
wdenk0442ed82002-11-03 10:24:00 +0000756#if defined(CFG_OCM_DATA_ADDR) && defined(CFG_OCM_DATA_SIZE)
757 /********************************************************************
758 * Setup OCM - On Chip Memory
759 *******************************************************************/
760 /* Setup OCM */
wdenk57b2d802003-06-27 21:31:46 +0000761 lis r0, 0x7FFF
762 ori r0, r0, 0xFFFF
Wolfgang Denk8dd4d332005-08-06 01:42:58 +0200763 mfdcr r3, ocmiscntl /* get instr-side IRAM config */
wdenk57b2d802003-06-27 21:31:46 +0000764 mfdcr r4, ocmdscntl /* get data-side IRAM config */
765 and r3, r3, r0 /* disable data-side IRAM */
766 and r4, r4, r0 /* disable data-side IRAM */
767 mtdcr ocmiscntl, r3 /* set instr-side IRAM config */
768 mtdcr ocmdscntl, r4 /* set data-side IRAM config */
769 isync
wdenk0442ed82002-11-03 10:24:00 +0000770
771 addis r3, 0, CFG_OCM_DATA_ADDR@h /* OCM location */
772 mtdcr ocmdsarc, r3
773 addis r4, 0, 0xC000 /* OCM data area enabled */
774 mtdcr ocmdscntl, r4
wdenk57b2d802003-06-27 21:31:46 +0000775 isync
wdenk0442ed82002-11-03 10:24:00 +0000776#endif
777
778 /*----------------------------------------------------------------------- */
779 /* Setup temporary stack in DCACHE or OCM if needed for SDRAM SPD. */
780 /*----------------------------------------------------------------------- */
781#ifdef CFG_INIT_DCACHE_CS
782 /*----------------------------------------------------------------------- */
783 /* Memory Bank x (nothingness) initialization 1GB+64MEG */
784 /* used as temporary stack pointer for stage0 */
785 /*----------------------------------------------------------------------- */
786 li r4,PBxAP
787 mtdcr ebccfga,r4
788 lis r4,0x0380
789 ori r4,r4,0x0480
790 mtdcr ebccfgd,r4
791
792 addi r4,0,PBxCR
793 mtdcr ebccfga,r4
794 lis r4,0x400D
795 ori r4,r4,0xa000
796 mtdcr ebccfgd,r4
797
798 /* turn on data chache for this region */
799 lis r4,0x0080
800 mtdccr r4
801
802 /* set stack pointer and clear stack to known value */
803
804 lis r1,CFG_INIT_RAM_ADDR@h
Wolfgang Denk8dd4d332005-08-06 01:42:58 +0200805 ori r1,r1,CFG_INIT_SP_OFFSET@l
wdenk0442ed82002-11-03 10:24:00 +0000806
807 li r4,2048 /* we store 2048 words to stack */
808 mtctr r4
809
810 lis r2,CFG_INIT_RAM_ADDR@h /* we also clear data area */
Wolfgang Denk8dd4d332005-08-06 01:42:58 +0200811 ori r2,r2,CFG_INIT_RAM_END@l /* so cant copy value from r1 */
wdenk0442ed82002-11-03 10:24:00 +0000812
813 lis r4,0xdead /* we store 0xdeaddead in the stack */
814 ori r4,r4,0xdead
815
816..stackloop:
817 stwu r4,-4(r2)
818 bdnz ..stackloop
819
820 li r0, 0 /* Make room for stack frame header and */
821 stwu r0, -4(r1) /* clear final stack frame so that */
822 stwu r0, -4(r1) /* stack backtraces terminate cleanly */
823 /*
824 * Set up a dummy frame to store reset vector as return address.
825 * this causes stack underflow to reset board.
826 */
827 stwu r1, -8(r1) /* Save back chain and move SP */
828 addis r0, 0, 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
833#elif defined(CFG_TEMP_STACK_OCM) && \
834 (defined(CFG_OCM_DATA_ADDR) && defined(CFG_OCM_DATA_SIZE))
835 /*
836 * Stack in OCM.
837 */
838
839 /* Set up Stack at top of OCM */
840 lis r1, (CFG_INIT_RAM_ADDR + CFG_INIT_SP_OFFSET)@h
841 ori r1, r1, (CFG_INIT_RAM_ADDR + CFG_INIT_SP_OFFSET)@l
842
843 /* Set up a zeroized stack frame so that backtrace works right */
844 li r0, 0
845 stwu r0, -4(r1)
846 stwu r0, -4(r1)
847
848 /*
849 * Set up a dummy frame to store reset vector as return address.
850 * this causes stack underflow to reset board.
851 */
852 stwu r1, -8(r1) /* Save back chain and move SP */
853 lis r0, RESET_VECTOR@h /* Address of reset vector */
854 ori r0, r0, RESET_VECTOR@l
855 stwu r1, -8(r1) /* Save back chain and move SP */
856 stw r0, +12(r1) /* Save return addr (underflow vect) */
857#endif /* CFG_INIT_DCACHE_CS */
858
859 /*----------------------------------------------------------------------- */
Wolfgang Denk8dd4d332005-08-06 01:42:58 +0200860 /* Initialize SDRAM Controller */
wdenk0442ed82002-11-03 10:24:00 +0000861 /*----------------------------------------------------------------------- */
862 bl sdram_init
863
864 /*
865 * Setup temporary stack pointer only for boards
866 * that do not use SDRAM SPD I2C stuff since it
867 * is already initialized to use DCACHE or OCM
868 * stacks.
869 */
870#if !(defined(CFG_INIT_DCACHE_CS) || defined(CFG_TEMP_STACK_OCM))
871 lis r1, CFG_INIT_RAM_ADDR@h
872 ori r1,r1,CFG_INIT_SP_OFFSET /* set up the stack in SDRAM */
873
874 li r0, 0 /* Make room for stack frame header and */
875 stwu r0, -4(r1) /* clear final stack frame so that */
876 stwu r0, -4(r1) /* stack backtraces terminate cleanly */
877 /*
878 * Set up a dummy frame to store reset vector as return address.
879 * this causes stack underflow to reset board.
880 */
881 stwu r1, -8(r1) /* Save back chain and move SP */
882 lis r0, RESET_VECTOR@h /* Address of reset vector */
883 ori r0, r0, RESET_VECTOR@l
884 stwu r1, -8(r1) /* Save back chain and move SP */
885 stw r0, +12(r1) /* Save return addr (underflow vect) */
Wolfgang Denk8dd4d332005-08-06 01:42:58 +0200886#endif /* !(CFG_INIT_DCACHE_CS || !CFG_TEM_STACK_OCM) */
wdenk0442ed82002-11-03 10:24:00 +0000887
888 GET_GOT /* initialize GOT access */
889
Wolfgang Denk8dd4d332005-08-06 01:42:58 +0200890 bl cpu_init_f /* run low-level CPU init code (from Flash) */
wdenk0442ed82002-11-03 10:24:00 +0000891
892 /* NEVER RETURNS! */
893 bl board_init_f /* run first part of init code (from Flash) */
894
wdenk232fe0b2003-09-02 22:48:03 +0000895#endif /* CONFIG_405GP || CONFIG_405CR || CONFIG_405 || CONFIG_405EP */
896 /*----------------------------------------------------------------------- */
wdenk0442ed82002-11-03 10:24:00 +0000897
898
Stefan Roese42fbddd2006-09-07 11:51:23 +0200899#ifndef CONFIG_NAND_SPL
stroese434979e2003-05-23 11:18:02 +0000900/*****************************************************************************/
wdenk0442ed82002-11-03 10:24:00 +0000901 .globl _start_of_vectors
902_start_of_vectors:
903
904#if 0
905/*TODO Fixup _start above so we can do this*/
906/* Critical input. */
907 CRIT_EXCEPTION(0x100, CritcalInput, CritcalInputException)
908#endif
909
910/* Machine check */
wdenk381669a2003-06-16 23:50:08 +0000911 CRIT_EXCEPTION(0x200, MachineCheck, MachineCheckException)
wdenk0442ed82002-11-03 10:24:00 +0000912
913/* Data Storage exception. */
914 STD_EXCEPTION(0x300, DataStorage, UnknownException)
915
916/* Instruction Storage exception. */
917 STD_EXCEPTION(0x400, InstStorage, UnknownException)
918
919/* External Interrupt exception. */
920 STD_EXCEPTION(0x500, ExtInterrupt, external_interrupt)
921
922/* Alignment exception. */
923 . = 0x600
924Alignment:
925 EXCEPTION_PROLOG
926 mfspr r4,DAR
927 stw r4,_DAR(r21)
928 mfspr r5,DSISR
929 stw r5,_DSISR(r21)
930 addi r3,r1,STACK_FRAME_OVERHEAD
931 li r20,MSR_KERNEL
932 rlwimi r20,r23,0,16,16 /* copy EE bit from saved MSR */
933 lwz r6,GOT(transfer_to_handler)
934 mtlr r6
935 blrl
936.L_Alignment:
937 .long AlignmentException - _start + EXC_OFF_SYS_RESET
938 .long int_return - _start + EXC_OFF_SYS_RESET
939
940/* Program check exception */
941 . = 0x700
942ProgramCheck:
943 EXCEPTION_PROLOG
944 addi r3,r1,STACK_FRAME_OVERHEAD
945 li r20,MSR_KERNEL
946 rlwimi r20,r23,0,16,16 /* copy EE bit from saved MSR */
947 lwz r6,GOT(transfer_to_handler)
948 mtlr r6
949 blrl
950.L_ProgramCheck:
951 .long ProgramCheckException - _start + EXC_OFF_SYS_RESET
952 .long int_return - _start + EXC_OFF_SYS_RESET
953
954 /* No FPU on MPC8xx. This exception is not supposed to happen.
955 */
956 STD_EXCEPTION(0x800, FPUnavailable, UnknownException)
957
958 /* I guess we could implement decrementer, and may have
959 * to someday for timekeeping.
960 */
961 STD_EXCEPTION(0x900, Decrementer, timer_interrupt)
962 STD_EXCEPTION(0xa00, Trap_0a, UnknownException)
963 STD_EXCEPTION(0xb00, Trap_0b, UnknownException)
wdenk874ac262003-07-24 23:38:38 +0000964 STD_EXCEPTION(0xc00, SystemCall, UnknownException)
wdenk0442ed82002-11-03 10:24:00 +0000965 STD_EXCEPTION(0xd00, SingleStep, UnknownException)
966
967 STD_EXCEPTION(0xe00, Trap_0e, UnknownException)
968 STD_EXCEPTION(0xf00, Trap_0f, UnknownException)
969
970 /* On the MPC8xx, this is a software emulation interrupt. It occurs
971 * for all unimplemented and illegal instructions.
972 */
973 STD_EXCEPTION(0x1000, PIT, PITException)
974
975 STD_EXCEPTION(0x1100, InstructionTLBMiss, UnknownException)
976 STD_EXCEPTION(0x1200, DataTLBMiss, UnknownException)
977 STD_EXCEPTION(0x1300, InstructionTLBError, UnknownException)
978 STD_EXCEPTION(0x1400, DataTLBError, UnknownException)
979
980 STD_EXCEPTION(0x1500, Reserved5, UnknownException)
981 STD_EXCEPTION(0x1600, Reserved6, UnknownException)
982 STD_EXCEPTION(0x1700, Reserved7, UnknownException)
983 STD_EXCEPTION(0x1800, Reserved8, UnknownException)
984 STD_EXCEPTION(0x1900, Reserved9, UnknownException)
985 STD_EXCEPTION(0x1a00, ReservedA, UnknownException)
986 STD_EXCEPTION(0x1b00, ReservedB, UnknownException)
987
988 STD_EXCEPTION(0x1c00, DataBreakpoint, UnknownException)
989 STD_EXCEPTION(0x1d00, InstructionBreakpoint, UnknownException)
990 STD_EXCEPTION(0x1e00, PeripheralBreakpoint, UnknownException)
991 STD_EXCEPTION(0x1f00, DevPortBreakpoint, UnknownException)
992
993 CRIT_EXCEPTION(0x2000, DebugBreakpoint, DebugException )
994
995 .globl _end_of_vectors
996_end_of_vectors:
997
998
999 . = 0x2100
1000
1001/*
1002 * This code finishes saving the registers to the exception frame
1003 * and jumps to the appropriate handler for the exception.
1004 * Register r21 is pointer into trap frame, r1 has new stack pointer.
1005 */
1006 .globl transfer_to_handler
1007transfer_to_handler:
1008 stw r22,_NIP(r21)
1009 lis r22,MSR_POW@h
1010 andc r23,r23,r22
1011 stw r23,_MSR(r21)
1012 SAVE_GPR(7, r21)
1013 SAVE_4GPRS(8, r21)
1014 SAVE_8GPRS(12, r21)
1015 SAVE_8GPRS(24, r21)
1016#if 0
1017 andi. r23,r23,MSR_PR
1018 mfspr r23,SPRG3 /* if from user, fix up tss.regs */
1019 beq 2f
1020 addi r24,r1,STACK_FRAME_OVERHEAD
1021 stw r24,PT_REGS(r23)
10222: addi r2,r23,-TSS /* set r2 to current */
1023 tovirt(r2,r2,r23)
1024#endif
1025 mflr r23
1026 andi. r24,r23,0x3f00 /* get vector offset */
1027 stw r24,TRAP(r21)
1028 li r22,0
1029 stw r22,RESULT(r21)
1030 mtspr SPRG2,r22 /* r1 is now kernel sp */
1031#if 0
1032 addi r24,r2,TASK_STRUCT_SIZE /* check for kernel stack overflow */
1033 cmplw 0,r1,r2
1034 cmplw 1,r1,r24
1035 crand 1,1,4
1036 bgt stack_ovf /* if r2 < r1 < r2+TASK_STRUCT_SIZE */
1037#endif
1038 lwz r24,0(r23) /* virtual address of handler */
1039 lwz r23,4(r23) /* where to go when done */
1040 mtspr SRR0,r24
1041 mtspr SRR1,r20
1042 mtlr r23
1043 SYNC
1044 rfi /* jump to handler, enable MMU */
1045
1046int_return:
1047 mfmsr r28 /* Disable interrupts */
1048 li r4,0
1049 ori r4,r4,MSR_EE
1050 andc r28,r28,r4
1051 SYNC /* Some chip revs need this... */
1052 mtmsr r28
1053 SYNC
1054 lwz r2,_CTR(r1)
1055 lwz r0,_LINK(r1)
1056 mtctr r2
1057 mtlr r0
1058 lwz r2,_XER(r1)
1059 lwz r0,_CCR(r1)
1060 mtspr XER,r2
1061 mtcrf 0xFF,r0
1062 REST_10GPRS(3, r1)
1063 REST_10GPRS(13, r1)
1064 REST_8GPRS(23, r1)
1065 REST_GPR(31, r1)
1066 lwz r2,_NIP(r1) /* Restore environment */
1067 lwz r0,_MSR(r1)
1068 mtspr SRR0,r2
1069 mtspr SRR1,r0
1070 lwz r0,GPR0(r1)
1071 lwz r2,GPR2(r1)
1072 lwz r1,GPR1(r1)
1073 SYNC
1074 rfi
1075
1076crit_return:
1077 mfmsr r28 /* Disable interrupts */
1078 li r4,0
1079 ori r4,r4,MSR_EE
1080 andc r28,r28,r4
1081 SYNC /* Some chip revs need this... */
1082 mtmsr r28
1083 SYNC
1084 lwz r2,_CTR(r1)
1085 lwz r0,_LINK(r1)
1086 mtctr r2
1087 mtlr r0
1088 lwz r2,_XER(r1)
1089 lwz r0,_CCR(r1)
1090 mtspr XER,r2
1091 mtcrf 0xFF,r0
1092 REST_10GPRS(3, r1)
1093 REST_10GPRS(13, r1)
1094 REST_8GPRS(23, r1)
1095 REST_GPR(31, r1)
1096 lwz r2,_NIP(r1) /* Restore environment */
1097 lwz r0,_MSR(r1)
1098 mtspr 990,r2 /* SRR2 */
1099 mtspr 991,r0 /* SRR3 */
1100 lwz r0,GPR0(r1)
1101 lwz r2,GPR2(r1)
1102 lwz r1,GPR1(r1)
1103 SYNC
1104 rfci
Stefan Roese42fbddd2006-09-07 11:51:23 +02001105#endif /* CONFIG_NAND_SPL */
wdenk0442ed82002-11-03 10:24:00 +00001106
1107/* Cache functions.
1108*/
1109invalidate_icache:
1110 iccci r0,r0 /* for 405, iccci invalidates the */
1111 blr /* entire I cache */
1112
1113invalidate_dcache:
1114 addi r6,0,0x0000 /* clear GPR 6 */
1115 /* Do loop for # of dcache congruence classes. */
Wolfgang Denk8dd4d332005-08-06 01:42:58 +02001116 lis r7, (CFG_DCACHE_SIZE / CFG_CACHELINE_SIZE / 2)@ha /* TBS for large sized cache */
1117 ori r7, r7, (CFG_DCACHE_SIZE / CFG_CACHELINE_SIZE / 2)@l
wdenk0442ed82002-11-03 10:24:00 +00001118 /* NOTE: dccci invalidates both */
1119 mtctr r7 /* ways in the D cache */
1120..dcloop:
1121 dccci 0,r6 /* invalidate line */
1122 addi r6,r6, CFG_CACHELINE_SIZE /* bump to next line */
1123 bdnz ..dcloop
1124 blr
1125
1126flush_dcache:
1127 addis r9,r0,0x0002 /* set mask for EE and CE msr bits */
1128 ori r9,r9,0x8000
1129 mfmsr r12 /* save msr */
1130 andc r9,r12,r9
1131 mtmsr r9 /* disable EE and CE */
1132 addi r10,r0,0x0001 /* enable data cache for unused memory */
1133 mfdccr r9 /* region 0xF8000000-0xFFFFFFFF via */
1134 or r10,r10,r9 /* bit 31 in dccr */
1135 mtdccr r10
1136
1137 /* do loop for # of congruence classes. */
Wolfgang Denk8dd4d332005-08-06 01:42:58 +02001138 lis r10,(CFG_DCACHE_SIZE / CFG_CACHELINE_SIZE / 2)@ha /* TBS: for large cache sizes */
1139 ori r10,r10,(CFG_DCACHE_SIZE / CFG_CACHELINE_SIZE / 2)@l
1140 lis r11,(CFG_DCACHE_SIZE / 2)@ha /* D cache set size - 2 way sets */
1141 ori r11,r11,(CFG_DCACHE_SIZE / 2)@l /* D cache set size - 2 way sets */
wdenk0442ed82002-11-03 10:24:00 +00001142 mtctr r10
Wolfgang Denk8dd4d332005-08-06 01:42:58 +02001143 addi r10,r0,(0xE000-0x10000) /* start at 0xFFFFE000 */
wdenk0442ed82002-11-03 10:24:00 +00001144 add r11,r10,r11 /* add to get to other side of cache line */
1145..flush_dcache_loop:
1146 lwz r3,0(r10) /* least recently used side */
1147 lwz r3,0(r11) /* the other side */
1148 dccci r0,r11 /* invalidate both sides */
1149 addi r10,r10,CFG_CACHELINE_SIZE /* bump to next line */
1150 addi r11,r11,CFG_CACHELINE_SIZE /* bump to next line */
1151 bdnz ..flush_dcache_loop
1152 sync /* allow memory access to complete */
1153 mtdccr r9 /* restore dccr */
1154 mtmsr r12 /* restore msr */
1155 blr
1156
1157 .globl icache_enable
1158icache_enable:
1159 mflr r8
1160 bl invalidate_icache
1161 mtlr r8
1162 isync
1163 addis r3,r0, 0x8000 /* set bit 0 */
1164 mticcr r3
1165 blr
1166
1167 .globl icache_disable
1168icache_disable:
1169 addis r3,r0, 0x0000 /* clear bit 0 */
1170 mticcr r3
1171 isync
1172 blr
1173
1174 .globl icache_status
1175icache_status:
1176 mficcr r3
1177 srwi r3, r3, 31 /* >>31 => select bit 0 */
1178 blr
1179
1180 .globl dcache_enable
1181dcache_enable:
1182 mflr r8
1183 bl invalidate_dcache
1184 mtlr r8
1185 isync
1186 addis r3,r0, 0x8000 /* set bit 0 */
1187 mtdccr r3
1188 blr
1189
1190 .globl dcache_disable
1191dcache_disable:
1192 mflr r8
1193 bl flush_dcache
1194 mtlr r8
1195 addis r3,r0, 0x0000 /* clear bit 0 */
1196 mtdccr r3
1197 blr
1198
1199 .globl dcache_status
1200dcache_status:
1201 mfdccr r3
1202 srwi r3, r3, 31 /* >>31 => select bit 0 */
1203 blr
1204
1205 .globl get_pvr
1206get_pvr:
1207 mfspr r3, PVR
1208 blr
1209
1210#if !defined(CONFIG_440)
1211 .globl wr_pit
1212wr_pit:
1213 mtspr pit, r3
1214 blr
1215#endif
1216
1217 .globl wr_tcr
1218wr_tcr:
1219 mtspr tcr, r3
1220 blr
1221
1222/*------------------------------------------------------------------------------- */
1223/* Function: in8 */
1224/* Description: Input 8 bits */
1225/*------------------------------------------------------------------------------- */
1226 .globl in8
1227in8:
1228 lbz r3,0x0000(r3)
1229 blr
1230
1231/*------------------------------------------------------------------------------- */
1232/* Function: out8 */
1233/* Description: Output 8 bits */
1234/*------------------------------------------------------------------------------- */
1235 .globl out8
1236out8:
1237 stb r4,0x0000(r3)
1238 blr
1239
1240/*------------------------------------------------------------------------------- */
1241/* Function: out16 */
1242/* Description: Output 16 bits */
1243/*------------------------------------------------------------------------------- */
1244 .globl out16
1245out16:
1246 sth r4,0x0000(r3)
1247 blr
1248
1249/*------------------------------------------------------------------------------- */
1250/* Function: out16r */
1251/* Description: Byte reverse and output 16 bits */
1252/*------------------------------------------------------------------------------- */
1253 .globl out16r
1254out16r:
1255 sthbrx r4,r0,r3
1256 blr
1257
1258/*------------------------------------------------------------------------------- */
1259/* Function: out32 */
1260/* Description: Output 32 bits */
1261/*------------------------------------------------------------------------------- */
1262 .globl out32
1263out32:
1264 stw r4,0x0000(r3)
1265 blr
1266
1267/*------------------------------------------------------------------------------- */
1268/* Function: out32r */
1269/* Description: Byte reverse and output 32 bits */
1270/*------------------------------------------------------------------------------- */
1271 .globl out32r
1272out32r:
1273 stwbrx r4,r0,r3
1274 blr
1275
1276/*------------------------------------------------------------------------------- */
1277/* Function: in16 */
1278/* Description: Input 16 bits */
1279/*------------------------------------------------------------------------------- */
1280 .globl in16
1281in16:
1282 lhz r3,0x0000(r3)
1283 blr
1284
1285/*------------------------------------------------------------------------------- */
1286/* Function: in16r */
1287/* Description: Input 16 bits and byte reverse */
1288/*------------------------------------------------------------------------------- */
1289 .globl in16r
1290in16r:
1291 lhbrx r3,r0,r3
1292 blr
1293
1294/*------------------------------------------------------------------------------- */
1295/* Function: in32 */
1296/* Description: Input 32 bits */
1297/*------------------------------------------------------------------------------- */
1298 .globl in32
1299in32:
1300 lwz 3,0x0000(3)
1301 blr
1302
1303/*------------------------------------------------------------------------------- */
1304/* Function: in32r */
1305/* Description: Input 32 bits and byte reverse */
1306/*------------------------------------------------------------------------------- */
1307 .globl in32r
1308in32r:
1309 lwbrx r3,r0,r3
1310 blr
1311
1312/*------------------------------------------------------------------------------- */
1313/* Function: ppcDcbf */
1314/* Description: Data Cache block flush */
1315/* Input: r3 = effective address */
1316/* Output: none. */
1317/*------------------------------------------------------------------------------- */
1318 .globl ppcDcbf
1319ppcDcbf:
1320 dcbf r0,r3
1321 blr
1322
1323/*------------------------------------------------------------------------------- */
1324/* Function: ppcDcbi */
1325/* Description: Data Cache block Invalidate */
1326/* Input: r3 = effective address */
1327/* Output: none. */
1328/*------------------------------------------------------------------------------- */
1329 .globl ppcDcbi
1330ppcDcbi:
1331 dcbi r0,r3
1332 blr
1333
1334/*------------------------------------------------------------------------------- */
1335/* Function: ppcSync */
1336/* Description: Processor Synchronize */
1337/* Input: none. */
1338/* Output: none. */
1339/*------------------------------------------------------------------------------- */
1340 .globl ppcSync
1341ppcSync:
1342 sync
1343 blr
1344
1345/*------------------------------------------------------------------------------*/
1346
Stefan Roese42fbddd2006-09-07 11:51:23 +02001347#ifndef CONFIG_NAND_SPL
wdenk0442ed82002-11-03 10:24:00 +00001348/*
1349 * void relocate_code (addr_sp, gd, addr_moni)
1350 *
1351 * This "function" does not return, instead it continues in RAM
1352 * after relocating the monitor code.
1353 *
1354 * r3 = dest
1355 * r4 = src
1356 * r5 = length in bytes
1357 * r6 = cachelinesize
1358 */
1359 .globl relocate_code
1360relocate_code:
Stefan Roese42fbddd2006-09-07 11:51:23 +02001361#if defined(CONFIG_440EP) || defined(CONFIG_440GR) || \
1362 defined(CONFIG_440EPX) || defined(CONFIG_440GRX) || \
1363 defined(CONFIG_440SPE)
Stefan Roese9eba0c82006-06-02 16:18:04 +02001364 /*
1365 * On some 440er platforms the cache is enabled in the first TLB (Boot-CS)
1366 * to speed up the boot process. Now this cache needs to be disabled.
1367 */
1368 iccci 0,0 /* Invalidate inst cache */
1369 dccci 0,0 /* Invalidate data cache, now no longer our stack */
Stefan Roese326c9712005-08-01 16:41:48 +02001370 sync
Stefan Roese9eba0c82006-06-02 16:18:04 +02001371 isync
Stefan Roese99644742005-11-29 18:18:21 +01001372 addi r1,r0,0x0000 /* TLB entry #0 */
Stefan Roese326c9712005-08-01 16:41:48 +02001373 tlbre r0,r1,0x0002 /* Read contents */
Stefan Roese99644742005-11-29 18:18:21 +01001374 ori r0,r0,0x0c00 /* Or in the inhibit, write through bit */
Wolfgang Denk8dd4d332005-08-06 01:42:58 +02001375 tlbwe r0,r1,0x0002 /* Save it out */
Stefan Roese9eba0c82006-06-02 16:18:04 +02001376 sync
Stefan Roese326c9712005-08-01 16:41:48 +02001377 isync
1378#endif
wdenk0442ed82002-11-03 10:24:00 +00001379 mr r1, r3 /* Set new stack pointer */
1380 mr r9, r4 /* Save copy of Init Data pointer */
1381 mr r10, r5 /* Save copy of Destination Address */
1382
1383 mr r3, r5 /* Destination Address */
1384 lis r4, CFG_MONITOR_BASE@h /* Source Address */
1385 ori r4, r4, CFG_MONITOR_BASE@l
wdenkb9a83a92003-05-30 12:48:29 +00001386 lwz r5, GOT(__init_end)
1387 sub r5, r5, r4
wdenk0442ed82002-11-03 10:24:00 +00001388 li r6, CFG_CACHELINE_SIZE /* Cache Line Size */
1389
1390 /*
1391 * Fix GOT pointer:
1392 *
1393 * New GOT-PTR = (old GOT-PTR - CFG_MONITOR_BASE) + Destination Address
1394 *
1395 * Offset:
1396 */
1397 sub r15, r10, r4
1398
1399 /* First our own GOT */
1400 add r14, r14, r15
1401 /* the the one used by the C code */
1402 add r30, r30, r15
1403
1404 /*
1405 * Now relocate code
1406 */
1407
1408 cmplw cr1,r3,r4
1409 addi r0,r5,3
1410 srwi. r0,r0,2
1411 beq cr1,4f /* In place copy is not necessary */
1412 beq 7f /* Protect against 0 count */
1413 mtctr r0
1414 bge cr1,2f
1415
1416 la r8,-4(r4)
1417 la r7,-4(r3)
14181: lwzu r0,4(r8)
1419 stwu r0,4(r7)
1420 bdnz 1b
1421 b 4f
1422
14232: slwi r0,r0,2
1424 add r8,r4,r0
1425 add r7,r3,r0
14263: lwzu r0,-4(r8)
1427 stwu r0,-4(r7)
1428 bdnz 3b
1429
1430/*
1431 * Now flush the cache: note that we must start from a cache aligned
1432 * address. Otherwise we might miss one cache line.
1433 */
14344: cmpwi r6,0
1435 add r5,r3,r5
1436 beq 7f /* Always flush prefetch queue in any case */
1437 subi r0,r6,1
1438 andc r3,r3,r0
1439 mr r4,r3
14405: dcbst 0,r4
1441 add r4,r4,r6
1442 cmplw r4,r5
1443 blt 5b
1444 sync /* Wait for all dcbst to complete on bus */
1445 mr r4,r3
14466: icbi 0,r4
1447 add r4,r4,r6
1448 cmplw r4,r5
1449 blt 6b
14507: sync /* Wait for all icbi to complete on bus */
1451 isync
1452
1453/*
1454 * We are done. Do not return, instead branch to second part of board
1455 * initialization, now running from RAM.
1456 */
1457
1458 addi r0, r10, in_ram - _start + EXC_OFF_SYS_RESET
1459 mtlr r0
1460 blr /* NEVER RETURNS! */
1461
1462in_ram:
1463
1464 /*
1465 * Relocation Function, r14 point to got2+0x8000
1466 *
1467 * Adjust got2 pointers, no need to check for 0, this code
1468 * already puts a few entries in the table.
1469 */
1470 li r0,__got2_entries@sectoff@l
1471 la r3,GOT(_GOT2_TABLE_)
1472 lwz r11,GOT(_GOT2_TABLE_)
1473 mtctr r0
1474 sub r11,r3,r11
1475 addi r3,r3,-4
14761: lwzu r0,4(r3)
1477 add r0,r0,r11
1478 stw r0,0(r3)
1479 bdnz 1b
1480
1481 /*
1482 * Now adjust the fixups and the pointers to the fixups
1483 * in case we need to move ourselves again.
1484 */
14852: li r0,__fixup_entries@sectoff@l
1486 lwz r3,GOT(_FIXUP_TABLE_)
1487 cmpwi r0,0
1488 mtctr r0
1489 addi r3,r3,-4
1490 beq 4f
14913: lwzu r4,4(r3)
1492 lwzux r0,r4,r11
1493 add r0,r0,r11
1494 stw r10,0(r3)
1495 stw r0,0(r4)
1496 bdnz 3b
14974:
1498clear_bss:
1499 /*
1500 * Now clear BSS segment
1501 */
wdenkbf2f8c92003-05-22 22:52:13 +00001502 lwz r3,GOT(__bss_start)
wdenk0442ed82002-11-03 10:24:00 +00001503 lwz r4,GOT(_end)
1504
1505 cmplw 0, r3, r4
1506 beq 6f
1507
1508 li r0, 0
15095:
1510 stw r0, 0(r3)
1511 addi r3, r3, 4
1512 cmplw 0, r3, r4
1513 bne 5b
15146:
1515
1516 mr r3, r9 /* Init Data pointer */
1517 mr r4, r10 /* Destination Address */
1518 bl board_init_r
1519
wdenk0442ed82002-11-03 10:24:00 +00001520 /*
1521 * Copy exception vector code to low memory
1522 *
1523 * r3: dest_addr
1524 * r7: source address, r8: end address, r9: target address
1525 */
1526 .globl trap_init
1527trap_init:
1528 lwz r7, GOT(_start)
1529 lwz r8, GOT(_end_of_vectors)
1530
wdenk4e112c12003-06-03 23:54:09 +00001531 li r9, 0x100 /* reset vector always at 0x100 */
wdenk0442ed82002-11-03 10:24:00 +00001532
1533 cmplw 0, r7, r8
1534 bgelr /* return if r7>=r8 - just in case */
1535
1536 mflr r4 /* save link register */
15371:
1538 lwz r0, 0(r7)
1539 stw r0, 0(r9)
1540 addi r7, r7, 4
1541 addi r9, r9, 4
1542 cmplw 0, r7, r8
1543 bne 1b
1544
1545 /*
1546 * relocate `hdlr' and `int_return' entries
1547 */
1548 li r7, .L_MachineCheck - _start + EXC_OFF_SYS_RESET
1549 li r8, Alignment - _start + EXC_OFF_SYS_RESET
15502:
1551 bl trap_reloc
1552 addi r7, r7, 0x100 /* next exception vector */
1553 cmplw 0, r7, r8
1554 blt 2b
1555
1556 li r7, .L_Alignment - _start + EXC_OFF_SYS_RESET
1557 bl trap_reloc
1558
1559 li r7, .L_ProgramCheck - _start + EXC_OFF_SYS_RESET
1560 bl trap_reloc
1561
1562 li r7, .L_FPUnavailable - _start + EXC_OFF_SYS_RESET
1563 li r8, SystemCall - _start + EXC_OFF_SYS_RESET
15643:
1565 bl trap_reloc
1566 addi r7, r7, 0x100 /* next exception vector */
1567 cmplw 0, r7, r8
1568 blt 3b
1569
1570 li r7, .L_SingleStep - _start + EXC_OFF_SYS_RESET
1571 li r8, _end_of_vectors - _start + EXC_OFF_SYS_RESET
15724:
1573 bl trap_reloc
1574 addi r7, r7, 0x100 /* next exception vector */
1575 cmplw 0, r7, r8
1576 blt 4b
1577
Stefan Roese42fbddd2006-09-07 11:51:23 +02001578#if !defined(CONFIG_440)
Stefan Roese7b12aa82006-03-13 09:42:28 +01001579 addi r7,r0,0x1000 /* set ME bit (Machine Exceptions) */
1580 oris r7,r7,0x0002 /* set CE bit (Critical Exceptions) */
1581 mtmsr r7 /* change MSR */
1582#else
Stefan Roese42fbddd2006-09-07 11:51:23 +02001583 bl __440_msr_set
1584 b __440_msr_continue
Stefan Roese7b12aa82006-03-13 09:42:28 +01001585
Stefan Roese42fbddd2006-09-07 11:51:23 +02001586__440_msr_set:
Stefan Roese7b12aa82006-03-13 09:42:28 +01001587 addi r7,r0,0x1000 /* set ME bit (Machine Exceptions) */
1588 oris r7,r7,0x0002 /* set CE bit (Critical Exceptions) */
1589 mtspr srr1,r7
1590 mflr r7
1591 mtspr srr0,r7
1592 rfi
Stefan Roese42fbddd2006-09-07 11:51:23 +02001593__440_msr_continue:
Stefan Roese7b12aa82006-03-13 09:42:28 +01001594#endif
1595
wdenk0442ed82002-11-03 10:24:00 +00001596 mtlr r4 /* restore link register */
1597 blr
1598
1599 /*
1600 * Function: relocate entries for one exception vector
1601 */
1602trap_reloc:
1603 lwz r0, 0(r7) /* hdlr ... */
1604 add r0, r0, r3 /* ... += dest_addr */
1605 stw r0, 0(r7)
1606
1607 lwz r0, 4(r7) /* int_return ... */
1608 add r0, r0, r3 /* ... += dest_addr */
1609 stw r0, 4(r7)
1610
1611 blr
Stefan Roese42fbddd2006-09-07 11:51:23 +02001612#endif /* CONFIG_NAND_SPL */
stroese434979e2003-05-23 11:18:02 +00001613
1614
1615/**************************************************************************/
Wolfgang Denk8dd4d332005-08-06 01:42:58 +02001616/* PPC405EP specific stuff */
stroese434979e2003-05-23 11:18:02 +00001617/**************************************************************************/
1618#ifdef CONFIG_405EP
1619ppc405ep_init:
stroese5ad6d4d2003-12-09 14:54:43 +00001620
Stefan Roese326c9712005-08-01 16:41:48 +02001621#ifdef CONFIG_BUBINGA
stroese5ad6d4d2003-12-09 14:54:43 +00001622 /*
1623 * Initialize EBC chip selects 1 & 4 and GPIO pins (for alternate
1624 * function) to support FPGA and NVRAM accesses below.
1625 */
1626
1627 lis r3,GPIO0_OSRH@h /* config GPIO output select */
1628 ori r3,r3,GPIO0_OSRH@l
1629 lis r4,CFG_GPIO0_OSRH@h
1630 ori r4,r4,CFG_GPIO0_OSRH@l
1631 stw r4,0(r3)
1632 lis r3,GPIO0_OSRL@h
1633 ori r3,r3,GPIO0_OSRL@l
1634 lis r4,CFG_GPIO0_OSRL@h
1635 ori r4,r4,CFG_GPIO0_OSRL@l
1636 stw r4,0(r3)
1637
1638 lis r3,GPIO0_ISR1H@h /* config GPIO input select */
1639 ori r3,r3,GPIO0_ISR1H@l
1640 lis r4,CFG_GPIO0_ISR1H@h
1641 ori r4,r4,CFG_GPIO0_ISR1H@l
1642 stw r4,0(r3)
1643 lis r3,GPIO0_ISR1L@h
1644 ori r3,r3,GPIO0_ISR1L@l
1645 lis r4,CFG_GPIO0_ISR1L@h
1646 ori r4,r4,CFG_GPIO0_ISR1L@l
1647 stw r4,0(r3)
1648
1649 lis r3,GPIO0_TSRH@h /* config GPIO three-state select */
1650 ori r3,r3,GPIO0_TSRH@l
1651 lis r4,CFG_GPIO0_TSRH@h
1652 ori r4,r4,CFG_GPIO0_TSRH@l
1653 stw r4,0(r3)
1654 lis r3,GPIO0_TSRL@h
1655 ori r3,r3,GPIO0_TSRL@l
1656 lis r4,CFG_GPIO0_TSRL@h
1657 ori r4,r4,CFG_GPIO0_TSRL@l
1658 stw r4,0(r3)
1659
1660 lis r3,GPIO0_TCR@h /* config GPIO driver output enables */
1661 ori r3,r3,GPIO0_TCR@l
1662 lis r4,CFG_GPIO0_TCR@h
1663 ori r4,r4,CFG_GPIO0_TCR@l
1664 stw r4,0(r3)
1665
1666 li r3,pb1ap /* program EBC bank 1 for RTC access */
1667 mtdcr ebccfga,r3
1668 lis r3,CFG_EBC_PB1AP@h
1669 ori r3,r3,CFG_EBC_PB1AP@l
1670 mtdcr ebccfgd,r3
1671 li r3,pb1cr
1672 mtdcr ebccfga,r3
1673 lis r3,CFG_EBC_PB1CR@h
1674 ori r3,r3,CFG_EBC_PB1CR@l
1675 mtdcr ebccfgd,r3
1676
1677 li r3,pb1ap /* program EBC bank 1 for RTC access */
1678 mtdcr ebccfga,r3
1679 lis r3,CFG_EBC_PB1AP@h
1680 ori r3,r3,CFG_EBC_PB1AP@l
1681 mtdcr ebccfgd,r3
1682 li r3,pb1cr
1683 mtdcr ebccfga,r3
1684 lis r3,CFG_EBC_PB1CR@h
1685 ori r3,r3,CFG_EBC_PB1CR@l
1686 mtdcr ebccfgd,r3
1687
1688 li r3,pb4ap /* program EBC bank 4 for FPGA access */
1689 mtdcr ebccfga,r3
1690 lis r3,CFG_EBC_PB4AP@h
1691 ori r3,r3,CFG_EBC_PB4AP@l
1692 mtdcr ebccfgd,r3
1693 li r3,pb4cr
1694 mtdcr ebccfga,r3
1695 lis r3,CFG_EBC_PB4CR@h
1696 ori r3,r3,CFG_EBC_PB4CR@l
1697 mtdcr ebccfgd,r3
1698#endif
1699
Stefan Roesec72b0a42006-10-12 19:50:17 +02001700#ifndef CFG_CPC0_PCI
1701 li r3,CPC0_PCI_HOST_CFG_EN
Stefan Roese326c9712005-08-01 16:41:48 +02001702#ifdef CONFIG_BUBINGA
wdenk57b2d802003-06-27 21:31:46 +00001703 /*
1704 !-----------------------------------------------------------------------
1705 ! Check FPGA for PCI internal/external arbitration
1706 ! If board is set to internal arbitration, update cpc0_pci
1707 !-----------------------------------------------------------------------
stroese434979e2003-05-23 11:18:02 +00001708 */
Wolfgang Denk8dd4d332005-08-06 01:42:58 +02001709 addis r5,r0,FPGA_REG1@h /* set offset for FPGA_REG1 */
1710 ori r5,r5,FPGA_REG1@l
1711 lbz r5,0x0(r5) /* read to get PCI arb selection */
1712 andi. r6,r5,FPGA_REG1_PCI_INT_ARB /* using internal arbiter ?*/
1713 beq ..pci_cfg_set /* if not set, then bypass reg write*/
stroese434979e2003-05-23 11:18:02 +00001714#endif
Wolfgang Denk8dd4d332005-08-06 01:42:58 +02001715 ori r3,r3,CPC0_PCI_ARBIT_EN
Stefan Roesec72b0a42006-10-12 19:50:17 +02001716#else /* CFG_CPC0_PCI */
1717 li r3,CFG_CPC0_PCI
1718#endif /* CFG_CPC0_PCI */
stroese434979e2003-05-23 11:18:02 +00001719..pci_cfg_set:
Wolfgang Denk8dd4d332005-08-06 01:42:58 +02001720 mtdcr CPC0_PCI, r3 /* Enable internal arbiter*/
stroese434979e2003-05-23 11:18:02 +00001721
wdenk57b2d802003-06-27 21:31:46 +00001722 /*
1723 !-----------------------------------------------------------------------
1724 ! Check to see if chip is in bypass mode.
1725 ! If so, write stored CPC0_PLLMR0 and CPC0_PLLMR1 values and perform a
1726 ! CPU reset Otherwise, skip this step and keep going.
Wolfgang Denk8dd4d332005-08-06 01:42:58 +02001727 ! Note: Running BIOS in bypass mode is not supported since PLB speed
1728 ! will not be fast enough for the SDRAM (min 66MHz)
wdenk57b2d802003-06-27 21:31:46 +00001729 !-----------------------------------------------------------------------
stroese434979e2003-05-23 11:18:02 +00001730 */
Wolfgang Denk8dd4d332005-08-06 01:42:58 +02001731 mfdcr r5, CPC0_PLLMR1
1732 rlwinm r4,r5,1,0x1 /* get system clock source (SSCS) */
1733 cmpi cr0,0,r4,0x1
stroese434979e2003-05-23 11:18:02 +00001734
Wolfgang Denk8dd4d332005-08-06 01:42:58 +02001735 beq pll_done /* if SSCS =b'1' then PLL has */
wdenk57b2d802003-06-27 21:31:46 +00001736 /* already been set */
1737 /* and CPU has been reset */
1738 /* so skip to next section */
stroese434979e2003-05-23 11:18:02 +00001739
Stefan Roese326c9712005-08-01 16:41:48 +02001740#ifdef CONFIG_BUBINGA
stroese434979e2003-05-23 11:18:02 +00001741 /*
wdenk57b2d802003-06-27 21:31:46 +00001742 !-----------------------------------------------------------------------
1743 ! Read NVRAM to get value to write in PLLMR.
1744 ! If value has not been correctly saved, write default value
1745 ! Default config values (assuming on-board 33MHz SYS_CLK) are above.
1746 ! See CPU_DEFAULT_200 and CPU_DEFAULT_266 above.
1747 !
1748 ! WARNING: This code assumes the first three words in the nvram_t
Wolfgang Denk8dd4d332005-08-06 01:42:58 +02001749 ! structure in openbios.h. Changing the beginning of
1750 ! the structure will break this code.
wdenk57b2d802003-06-27 21:31:46 +00001751 !
1752 !-----------------------------------------------------------------------
stroese434979e2003-05-23 11:18:02 +00001753 */
Wolfgang Denk8dd4d332005-08-06 01:42:58 +02001754 addis r3,0,NVRAM_BASE@h
1755 addi r3,r3,NVRAM_BASE@l
stroese434979e2003-05-23 11:18:02 +00001756
Wolfgang Denk8dd4d332005-08-06 01:42:58 +02001757 lwz r4, 0(r3)
1758 addis r5,0,NVRVFY1@h
1759 addi r5,r5,NVRVFY1@l
1760 cmp cr0,0,r4,r5 /* Compare 1st NVRAM Magic number*/
1761 bne ..no_pllset
1762 addi r3,r3,4
1763 lwz r4, 0(r3)
1764 addis r5,0,NVRVFY2@h
1765 addi r5,r5,NVRVFY2@l
1766 cmp cr0,0,r4,r5 /* Compare 2 NVRAM Magic number */
1767 bne ..no_pllset
1768 addi r3,r3,8 /* Skip over conf_size */
1769 lwz r4, 4(r3) /* Load PLLMR1 value from NVRAM */
1770 lwz r3, 0(r3) /* Load PLLMR0 value from NVRAM */
1771 rlwinm r5,r4,1,0x1 /* get system clock source (SSCS) */
1772 cmpi cr0,0,r5,1 /* See if PLL is locked */
1773 beq pll_write
stroese434979e2003-05-23 11:18:02 +00001774..no_pllset:
Stefan Roese326c9712005-08-01 16:41:48 +02001775#endif /* CONFIG_BUBINGA */
stroese434979e2003-05-23 11:18:02 +00001776
Wolfgang Denk8dd4d332005-08-06 01:42:58 +02001777 addis r3,0,PLLMR0_DEFAULT@h /* PLLMR0 default value */
1778 ori r3,r3,PLLMR0_DEFAULT@l /* */
1779 addis r4,0,PLLMR1_DEFAULT@h /* PLLMR1 default value */
1780 ori r4,r4,PLLMR1_DEFAULT@l /* */
stroese434979e2003-05-23 11:18:02 +00001781
Wolfgang Denk8dd4d332005-08-06 01:42:58 +02001782 b pll_write /* Write the CPC0_PLLMR with new value */
stroese434979e2003-05-23 11:18:02 +00001783
1784pll_done:
wdenk57b2d802003-06-27 21:31:46 +00001785 /*
1786 !-----------------------------------------------------------------------
1787 ! Clear Soft Reset Register
1788 ! This is needed to enable PCI if not booting from serial EPROM
1789 !-----------------------------------------------------------------------
stroese434979e2003-05-23 11:18:02 +00001790 */
Wolfgang Denk8dd4d332005-08-06 01:42:58 +02001791 addi r3, 0, 0x0
1792 mtdcr CPC0_SRR, r3
stroese434979e2003-05-23 11:18:02 +00001793
Wolfgang Denk8dd4d332005-08-06 01:42:58 +02001794 addis r3,0,0x0010
1795 mtctr r3
stroese434979e2003-05-23 11:18:02 +00001796pci_wait:
Wolfgang Denk8dd4d332005-08-06 01:42:58 +02001797 bdnz pci_wait
stroese434979e2003-05-23 11:18:02 +00001798
1799 blr /* return to main code */
1800
1801/*
1802!-----------------------------------------------------------------------------
Wolfgang Denk8dd4d332005-08-06 01:42:58 +02001803! Function: pll_write
1804! Description: Updates the value of the CPC0_PLLMR according to CMOS27E documentation
1805! That is:
1806! 1. Pll is first disabled (de-activated by putting in bypass mode)
1807! 2. PLL is reset
1808! 3. Clock dividers are set while PLL is held in reset and bypassed
1809! 4. PLL Reset is cleared
1810! 5. Wait 100us for PLL to lock
1811! 6. A core reset is performed
stroese434979e2003-05-23 11:18:02 +00001812! Input: r3 = Value to write to CPC0_PLLMR0
1813! Input: r4 = Value to write to CPC0_PLLMR1
1814! Output r3 = none
1815!-----------------------------------------------------------------------------
1816*/
1817pll_write:
wdenk57b2d802003-06-27 21:31:46 +00001818 mfdcr r5, CPC0_UCR
1819 andis. r5,r5,0xFFFF
Wolfgang Denk8dd4d332005-08-06 01:42:58 +02001820 ori r5,r5,0x0101 /* Stop the UART clocks */
1821 mtdcr CPC0_UCR,r5 /* Before changing PLL */
stroese434979e2003-05-23 11:18:02 +00001822
wdenk57b2d802003-06-27 21:31:46 +00001823 mfdcr r5, CPC0_PLLMR1
Wolfgang Denk8dd4d332005-08-06 01:42:58 +02001824 rlwinm r5,r5,0,0x7FFFFFFF /* Disable PLL */
1825 mtdcr CPC0_PLLMR1,r5
1826 oris r5,r5,0x4000 /* Set PLL Reset */
1827 mtdcr CPC0_PLLMR1,r5
stroese434979e2003-05-23 11:18:02 +00001828
Wolfgang Denk8dd4d332005-08-06 01:42:58 +02001829 mtdcr CPC0_PLLMR0,r3 /* Set clock dividers */
1830 rlwinm r5,r4,0,0x3FFFFFFF /* Reset & Bypass new PLL dividers */
1831 oris r5,r5,0x4000 /* Set PLL Reset */
1832 mtdcr CPC0_PLLMR1,r5 /* Set clock dividers */
1833 rlwinm r5,r5,0,0xBFFFFFFF /* Clear PLL Reset */
1834 mtdcr CPC0_PLLMR1,r5
stroese434979e2003-05-23 11:18:02 +00001835
1836 /*
wdenk57b2d802003-06-27 21:31:46 +00001837 ! Wait min of 100us for PLL to lock.
1838 ! See CMOS 27E databook for more info.
1839 ! At 200MHz, that means waiting 20,000 instructions
stroese434979e2003-05-23 11:18:02 +00001840 */
Wolfgang Denk8dd4d332005-08-06 01:42:58 +02001841 addi r3,0,20000 /* 2000 = 0x4e20 */
1842 mtctr r3
stroese434979e2003-05-23 11:18:02 +00001843pll_wait:
Wolfgang Denk8dd4d332005-08-06 01:42:58 +02001844 bdnz pll_wait
stroese434979e2003-05-23 11:18:02 +00001845
Wolfgang Denk8dd4d332005-08-06 01:42:58 +02001846 oris r5,r5,0x8000 /* Enable PLL */
1847 mtdcr CPC0_PLLMR1,r5 /* Engage */
stroese434979e2003-05-23 11:18:02 +00001848
wdenk57b2d802003-06-27 21:31:46 +00001849 /*
1850 * Reset CPU to guarantee timings are OK
1851 * Not sure if this is needed...
1852 */
1853 addis r3,0,0x1000
Wolfgang Denk8dd4d332005-08-06 01:42:58 +02001854 mtspr dbcr0,r3 /* This will cause a CPU core reset, and */
wdenk57b2d802003-06-27 21:31:46 +00001855 /* execution will continue from the poweron */
1856 /* vector of 0xfffffffc */
stroese434979e2003-05-23 11:18:02 +00001857#endif /* CONFIG_405EP */