]> git.ipfire.org Git - people/ms/u-boot.git/blob - cpu/ppc4xx/start.S
Patch by Travis Sawyer, 30 Dec 2003:
[people/ms/u-boot.git] / cpu / ppc4xx / start.S
1 /*
2 * Copyright (C) 1998 Dan Malek <dmalek@jlc.net>
3 * Copyright (C) 1999 Magnus Damm <kieraypc01.p.y.kie.era.ericsson.se>
4 * Copyright (C) 2000,2001,2002 Wolfgang Denk <wd@denx.de>
5 *
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
45 /* U-Boot - Startup Code for IBM 4xx PowerPC based Embedded Boards
46 *
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
120
121 /*
122 * Set up GOT: Global Offset Table
123 *
124 * Use r14 to access the GOT
125 */
126 START_GOT
127 GOT_ENTRY(_GOT2_TABLE_)
128 GOT_ENTRY(_FIXUP_TABLE_)
129
130 GOT_ENTRY(_start)
131 GOT_ENTRY(_start_of_vectors)
132 GOT_ENTRY(_end_of_vectors)
133 GOT_ENTRY(transfer_to_handler)
134
135 GOT_ENTRY(__init_end)
136 GOT_ENTRY(_end)
137 GOT_ENTRY(__bss_start)
138 END_GOT
139
140 /*
141 * 440 Startup -- on reset only the top 4k of the effective
142 * address space is mapped in by an entry in the instruction
143 * and data shadow TLB. The .bootpg section is located in the
144 * top 4k & does only what's necessary to map in the the rest
145 * of the boot rom. Once the boot rom is mapped in we can
146 * proceed with normal startup.
147 *
148 * NOTE: CS0 only covers the top 2MB of the effective address
149 * space after reset.
150 */
151
152 #if defined(CONFIG_440)
153 .section .bootpg,"ax"
154 .globl _start_440
155
156 /**************************************************************************/
157 _start_440:
158 /*----------------------------------------------------------------*/
159 /* Clear and set up some registers. */
160 /*----------------------------------------------------------------*/
161 iccci r0,r0 /* NOTE: operands not used for 440 */
162 dccci r0,r0 /* NOTE: operands not used for 440 */
163 sync
164 li r0,0
165 mtspr srr0,r0
166 mtspr srr1,r0
167 mtspr csrr0,r0
168 mtspr csrr1,r0
169 #if defined (CONFIG_440_GX) /* NOTE: 440GX adds machine check status regs */
170 mtspr mcsrr0,r0
171 mtspr mcsrr1,r0
172 mfspr r1, mcsr
173 mtspr mcsr,r1
174 #endif
175 /*----------------------------------------------------------------*/
176 /* Initialize debug */
177 /*----------------------------------------------------------------*/
178 mtspr dbcr0,r0
179 mtspr dbcr1,r0
180 mtspr dbcr2,r0
181 mtspr iac1,r0
182 mtspr iac2,r0
183 mtspr iac3,r0
184 mtspr dac1,r0
185 mtspr dac2,r0
186 mtspr dvc1,r0
187 mtspr dvc2,r0
188
189 mfspr r1,dbsr
190 mtspr dbsr,r1 /* Clear all valid bits */
191
192 /*----------------------------------------------------------------*/
193 /* CCR0 init */
194 /*----------------------------------------------------------------*/
195 /* Disable store gathering & broadcast, guarantee inst/data
196 * cache block touch, force load/store alignment
197 * (see errata 1.12: 440_33)
198 */
199 lis r1,0x0030 /* store gathering & broadcast disable */
200 ori r1,r1,0x6000 /* cache touch */
201 mtspr ccr0,r1
202
203 /*----------------------------------------------------------------*/
204 /* Setup interrupt vectors */
205 /*----------------------------------------------------------------*/
206 mtspr ivpr,r0 /* Vectors start at 0x0000_0000 */
207 li r1,0x0100
208 mtspr ivor0,r1 /* Critical input */
209 li r1,0x0200
210 mtspr ivor1,r1 /* Machine check */
211 li r1,0x0300
212 mtspr ivor2,r1 /* Data storage */
213 li r1,0x0400
214 mtspr ivor3,r1 /* Instruction storage */
215 li r1,0x0500
216 mtspr ivor4,r1 /* External interrupt */
217 li r1,0x0600
218 mtspr ivor5,r1 /* Alignment */
219 li r1,0x0700
220 mtspr ivor6,r1 /* Program check */
221 li r1,0x0800
222 mtspr ivor7,r1 /* Floating point unavailable */
223 li r1,0x0c00
224 mtspr ivor8,r1 /* System call */
225 li r1,0x1000
226 mtspr ivor10,r1 /* Decrementer (PIT for 440) */
227 li r1,0x1400
228 mtspr ivor13,r1 /* Data TLB error */
229 li r1,0x1300
230 mtspr ivor14,r1 /* Instr TLB error */
231 li r1,0x2000
232 mtspr ivor15,r1 /* Debug */
233
234 /*----------------------------------------------------------------*/
235 /* Configure cache regions */
236 /*----------------------------------------------------------------*/
237 mtspr inv0,r0
238 mtspr inv1,r0
239 mtspr inv2,r0
240 mtspr inv3,r0
241 mtspr dnv0,r0
242 mtspr dnv1,r0
243 mtspr dnv2,r0
244 mtspr dnv3,r0
245 mtspr itv0,r0
246 mtspr itv1,r0
247 mtspr itv2,r0
248 mtspr itv3,r0
249 mtspr dtv0,r0
250 mtspr dtv1,r0
251 mtspr dtv2,r0
252 mtspr dtv3,r0
253
254 /*----------------------------------------------------------------*/
255 /* Cache victim limits */
256 /*----------------------------------------------------------------*/
257 /* floors 0, ceiling max to use the entire cache -- nothing locked
258 */
259 lis r1,0x0001
260 ori r1,r1,0xf800
261 mtspr ivlim,r1
262 mtspr dvlim,r1
263
264 /*----------------------------------------------------------------*/
265 /* Clear all TLB entries -- TID = 0, TS = 0 */
266 /*----------------------------------------------------------------*/
267 mtspr mmucr,r0
268 li r1,0x003f /* 64 TLB entries */
269 mtctr r1
270 0: tlbwe r0,r1,0x0000 /* Invalidate all entries (V=0)*/
271 subi r1,r1,0x0001
272 bdnz 0b
273
274 /*----------------------------------------------------------------*/
275 /* TLB entry setup -- step thru tlbtab */
276 /*----------------------------------------------------------------*/
277 bl tlbtab /* Get tlbtab pointer */
278 mr r5,r0
279 li r1,0x003f /* 64 TLB entries max */
280 mtctr r1
281 li r4,0 /* TLB # */
282
283 addi r5,r5,-4
284 1: lwzu r0,4(r5)
285 cmpwi r0,0
286 beq 2f /* 0 marks end */
287 lwzu r1,4(r5)
288 lwzu r2,4(r5)
289 tlbwe r0,r4,0 /* TLB Word 0 */
290 tlbwe r1,r4,1 /* TLB Word 1 */
291 tlbwe r2,r4,2 /* TLB Word 2 */
292 addi r4,r4,1 /* Next TLB */
293 bdnz 1b
294
295 /*----------------------------------------------------------------*/
296 /* Continue from 'normal' start */
297 /*----------------------------------------------------------------*/
298 2: bl 3f
299 b _start
300
301 3: li r0,0
302 mtspr srr1,r0 /* Keep things disabled for now */
303 mflr r1
304 mtspr srr0,r1
305 rfi
306 #endif /* CONFIG_440 */
307
308 /*
309 * r3 - 1st arg to board_init(): IMMP pointer
310 * r4 - 2nd arg to board_init(): boot flag
311 */
312 .text
313 .long 0x27051956 /* U-Boot Magic Number */
314 .globl version_string
315 version_string:
316 .ascii U_BOOT_VERSION
317 .ascii " (", __DATE__, " - ", __TIME__, ")"
318 .ascii CONFIG_IDENT_STRING, "\0"
319
320 /*
321 * Maybe this should be moved somewhere else because the current
322 * location (0x100) is where the CriticalInput Execption should be.
323 */
324 . = EXC_OFF_SYS_RESET
325 .globl _start
326 _start:
327
328 /*****************************************************************************/
329 #if defined(CONFIG_440)
330
331 /*----------------------------------------------------------------*/
332 /* Clear and set up some registers. */
333 /*----------------------------------------------------------------*/
334 li r0,0x0000
335 lis r1,0xffff
336 mtspr dec,r0 /* prevent dec exceptions */
337 mtspr tbl,r0 /* prevent fit & wdt exceptions */
338 mtspr tbu,r0
339 mtspr tsr,r1 /* clear all timer exception status */
340 mtspr tcr,r0 /* disable all */
341 mtspr esr,r0 /* clear exception syndrome register */
342 mtxer r0 /* clear integer exception register */
343 #if !defined(CONFIG_440_GX)
344 lis r1,0x0002 /* set CE bit (Critical Exceptions) */
345 ori r1,r1,0x1000 /* set ME bit (Machine Exceptions) */
346 mtmsr r1 /* change MSR */
347 #else
348 bl __440gx_msr_set
349 b __440gx_msr_continue
350
351 __440gx_msr_set:
352 lis r1, 0x0002 /* set CE bit (Critical Exceptions) */
353 ori r1,r1,0x1000 /* set ME bit (Machine Exceptions) */
354 mtspr srr1,r1
355 mflr r1
356 mtspr srr0,r1
357 rfi
358 __440gx_msr_continue:
359 #endif
360
361 /*----------------------------------------------------------------*/
362 /* Debug setup -- some (not very good) ice's need an event*/
363 /* to establish control :-( Define CFG_INIT_DBCR to the dbsr */
364 /* value you need in this case 0x8cff 0000 should do the trick */
365 /*----------------------------------------------------------------*/
366 #if defined(CFG_INIT_DBCR)
367 lis r1,0xffff
368 ori r1,r1,0xffff
369 mtspr dbsr,r1 /* Clear all status bits */
370 lis r0,CFG_INIT_DBCR@h
371 ori r0,r0,CFG_INIT_DBCR@l
372 mtspr dbcr0,r0
373 isync
374 #endif
375
376 /*----------------------------------------------------------------*/
377 /* Setup the internal SRAM */
378 /*----------------------------------------------------------------*/
379 li r0,0
380 #if defined (CONFIG_440_GX)
381 mtdcr l2_cache_cfg,r0 /* Ensure L2 Cache is off */
382 #endif
383 mtdcr isram0_sb1cr,r0 /* Disable bank 1 */
384
385 li r2,0x7fff
386 ori r2,r2,0xffff
387 mfdcr r1,isram0_dpc
388 and r1,r1,r2 /* Disable parity check */
389 mtdcr isram0_dpc,r1
390 mfdcr r1,isram0_pmeg
391 andis. r1,r1,r2 /* Disable pwr mgmt */
392 mtdcr isram0_pmeg,r1
393
394 lis r1,0x8000 /* BAS = 8000_0000 */
395 #if defined(CONFIG_440_GX)
396 ori r1,r1,0x0980 /* first 64k */
397 mtdcr isram0_sb0cr,r1
398 lis r1,0x8001
399 ori r1,r1,0x0980 /* second 64k */
400 mtdcr isram0_sb1cr,r1
401 lis r1, 0x8002
402 ori r1,r1, 0x0980 /* third 64k */
403 mtdcr isram0_sb2cr,r1
404 lis r1, 0x8003
405 ori r1,r1, 0x0980 /* fourth 64k */
406 mtdcr isram0_sb3cr,r1
407 #else
408 ori r1,r1,0x0380 /* 8k rw */
409 mtdcr isram0_sb0cr,r1
410 #endif
411
412 /*----------------------------------------------------------------*/
413 /* Setup the stack in internal SRAM */
414 /*----------------------------------------------------------------*/
415 lis r1,CFG_INIT_RAM_ADDR@h
416 ori r1,r1,CFG_INIT_SP_OFFSET@l
417
418 li r0,0
419 stwu r0,-4(r1)
420 stwu r0,-4(r1) /* Terminate call chain */
421
422 stwu r1,-8(r1) /* Save back chain and move SP */
423 lis r0,RESET_VECTOR@h /* Address of reset vector */
424 ori r0,r0, RESET_VECTOR@l
425 stwu r1,-8(r1) /* Save back chain and move SP */
426 stw r0,+12(r1) /* Save return addr (underflow vect) */
427
428 GET_GOT
429 bl board_init_f
430
431 #endif /* CONFIG_440 */
432
433 /*****************************************************************************/
434 #ifdef CONFIG_IOP480
435 /*----------------------------------------------------------------------- */
436 /* Set up some machine state registers. */
437 /*----------------------------------------------------------------------- */
438 addi r0,r0,0x0000 /* initialize r0 to zero */
439 mtspr esr,r0 /* clear Exception Syndrome Reg */
440 mttcr r0 /* timer control register */
441 mtexier r0 /* disable all interrupts */
442 addi r4,r0,0x1000 /* set ME bit (Machine Exceptions) */
443 oris r4,r4,0x2 /* set CE bit (Critical Exceptions) */
444 mtmsr r4 /* change MSR */
445 addis r4,r0,0xFFFF /* set r4 to 0xFFFFFFFF (status in the */
446 ori r4,r4,0xFFFF /* dbsr is cleared by setting bits to 1) */
447 mtdbsr r4 /* clear/reset the dbsr */
448 mtexisr r4 /* clear all pending interrupts */
449 addis r4,r0,0x8000
450 mtexier r4 /* enable critical exceptions */
451 addis r4,r0,0x0000 /* assume 403GCX - enable core clk */
452 ori r4,r4,0x4020 /* dbling (no harm done on GA and GC */
453 mtiocr r4 /* since bit not used) & DRC to latch */
454 /* data bus on rising edge of CAS */
455 /*----------------------------------------------------------------------- */
456 /* Clear XER. */
457 /*----------------------------------------------------------------------- */
458 mtxer r0
459 /*----------------------------------------------------------------------- */
460 /* Invalidate i-cache and d-cache TAG arrays. */
461 /*----------------------------------------------------------------------- */
462 addi r3,0,1024 /* 1/4 of I-cache size, half of D-cache */
463 addi r4,0,1024 /* 1/4 of I-cache */
464 ..cloop:
465 iccci 0,r3
466 iccci r4,r3
467 dccci 0,r3
468 addic. r3,r3,-16 /* move back one cache line */
469 bne ..cloop /* loop back to do rest until r3 = 0 */
470
471 /* */
472 /* initialize IOP480 so it can read 1 MB code area for SRAM spaces */
473 /* this requires enabling MA[17..0], by default only MA[12..0] are enabled. */
474 /* */
475
476 /* first copy IOP480 register base address into r3 */
477 addis r3,0,0x5000 /* IOP480 register base address hi */
478 /* ori r3,r3,0x0000 / IOP480 register base address lo */
479
480 #ifdef CONFIG_ADCIOP
481 /* use r4 as the working variable */
482 /* turn on CS3 (LOCCTL.7) */
483 lwz r4,0x84(r3) /* LOCTL is at offset 0x84 */
484 andi. r4,r4,0xff7f /* make bit 7 = 0 -- CS3 mode */
485 stw r4,0x84(r3) /* LOCTL is at offset 0x84 */
486 #endif
487
488 #ifdef CONFIG_DASA_SIM
489 /* use r4 as the working variable */
490 /* turn on MA17 (LOCCTL.7) */
491 lwz r4,0x84(r3) /* LOCTL is at offset 0x84 */
492 ori r4,r4,0x80 /* make bit 7 = 1 -- MA17 mode */
493 stw r4,0x84(r3) /* LOCTL is at offset 0x84 */
494 #endif
495
496 /* turn on MA16..13 (LCS0BRD.12 = 0) */
497 lwz r4,0x100(r3) /* LCS0BRD is at offset 0x100 */
498 andi. r4,r4,0xefff /* make bit 12 = 0 */
499 stw r4,0x100(r3) /* LCS0BRD is at offset 0x100 */
500
501 /* make sure above stores all comlete before going on */
502 sync
503
504 /* last thing, set local init status done bit (DEVINIT.31) */
505 lwz r4,0x80(r3) /* DEVINIT is at offset 0x80 */
506 oris r4,r4,0x8000 /* make bit 31 = 1 */
507 stw r4,0x80(r3) /* DEVINIT is at offset 0x80 */
508
509 /* clear all pending interrupts and disable all interrupts */
510 li r4,-1 /* set p1 to 0xffffffff */
511 stw r4,0x1b0(r3) /* clear all pending interrupts */
512 stw r4,0x1b8(r3) /* clear all pending interrupts */
513 li r4,0 /* set r4 to 0 */
514 stw r4,0x1b4(r3) /* disable all interrupts */
515 stw r4,0x1bc(r3) /* disable all interrupts */
516
517 /* make sure above stores all comlete before going on */
518 sync
519
520 /*----------------------------------------------------------------------- */
521 /* Enable two 128MB cachable regions. */
522 /*----------------------------------------------------------------------- */
523 addis r1,r0,0x8000
524 addi r1,r1,0x0001
525 mticcr r1 /* instruction cache */
526
527 addis r1,r0,0x0000
528 addi r1,r1,0x0000
529 mtdccr r1 /* data cache */
530
531 addis r1,r0,CFG_INIT_RAM_ADDR@h
532 ori r1,r1,CFG_INIT_SP_OFFSET /* set up the stack to SDRAM */
533 li r0, 0 /* Make room for stack frame header and */
534 stwu r0, -4(r1) /* clear final stack frame so that */
535 stwu r0, -4(r1) /* stack backtraces terminate cleanly */
536
537 GET_GOT /* initialize GOT access */
538
539 bl board_init_f /* run first part of init code (from Flash) */
540
541 #endif /* CONFIG_IOP480 */
542
543 /*****************************************************************************/
544 #if defined(CONFIG_405GP) || defined(CONFIG_405CR) || defined(CONFIG_405) || defined(CONFIG_405EP)
545 /*----------------------------------------------------------------------- */
546 /* Clear and set up some registers. */
547 /*----------------------------------------------------------------------- */
548 addi r4,r0,0x0000
549 mtspr sgr,r4
550 mtspr dcwr,r4
551 mtesr r4 /* clear Exception Syndrome Reg */
552 mttcr r4 /* clear Timer Control Reg */
553 mtxer r4 /* clear Fixed-Point Exception Reg */
554 mtevpr r4 /* clear Exception Vector Prefix Reg */
555 addi r4,r0,0x1000 /* set ME bit (Machine Exceptions) */
556 oris r4,r4,0x0002 /* set CE bit (Critical Exceptions) */
557 mtmsr r4 /* change MSR */
558 addi r4,r0,(0xFFFF-0x10000) /* set r4 to 0xFFFFFFFF (status in the */
559 /* dbsr is cleared by setting bits to 1) */
560 mtdbsr r4 /* clear/reset the dbsr */
561
562 /*----------------------------------------------------------------------- */
563 /* Invalidate I and D caches. Enable I cache for defined memory regions */
564 /* to speed things up. Leave the D cache disabled for now. It will be */
565 /* enabled/left disabled later based on user selected menu options. */
566 /* Be aware that the I cache may be disabled later based on the menu */
567 /* options as well. See miscLib/main.c. */
568 /*----------------------------------------------------------------------- */
569 bl invalidate_icache
570 bl invalidate_dcache
571
572 /*----------------------------------------------------------------------- */
573 /* Enable two 128MB cachable regions. */
574 /*----------------------------------------------------------------------- */
575 addis r4,r0,0x8000
576 addi r4,r4,0x0001
577 mticcr r4 /* instruction cache */
578 isync
579
580 addis r4,r0,0x0000
581 addi r4,r4,0x0000
582 mtdccr r4 /* data cache */
583
584 #if !(defined(CFG_EBC_PB0AP) && defined(CFG_EBC_PB0CR))
585 /*----------------------------------------------------------------------- */
586 /* Tune the speed and size for flash CS0 */
587 /*----------------------------------------------------------------------- */
588 bl ext_bus_cntlr_init
589 #endif
590
591 #if defined(CONFIG_405EP)
592 /*----------------------------------------------------------------------- */
593 /* DMA Status, clear to come up clean */
594 /*----------------------------------------------------------------------- */
595 addis r3,r0, 0xFFFF /* Clear all existing DMA status */
596 ori r3,r3, 0xFFFF
597 mtdcr dmasr, r3
598
599 bl ppc405ep_init /* do ppc405ep specific init */
600 #endif /* CONFIG_405EP */
601
602 #if defined(CFG_OCM_DATA_ADDR) && defined(CFG_OCM_DATA_SIZE)
603 /********************************************************************
604 * Setup OCM - On Chip Memory
605 *******************************************************************/
606 /* Setup OCM */
607 lis r0, 0x7FFF
608 ori r0, r0, 0xFFFF
609 mfdcr r3, ocmiscntl /* get instr-side IRAM config */
610 mfdcr r4, ocmdscntl /* get data-side IRAM config */
611 and r3, r3, r0 /* disable data-side IRAM */
612 and r4, r4, r0 /* disable data-side IRAM */
613 mtdcr ocmiscntl, r3 /* set instr-side IRAM config */
614 mtdcr ocmdscntl, r4 /* set data-side IRAM config */
615 isync
616
617 addis r3, 0, CFG_OCM_DATA_ADDR@h /* OCM location */
618 mtdcr ocmdsarc, r3
619 addis r4, 0, 0xC000 /* OCM data area enabled */
620 mtdcr ocmdscntl, r4
621 isync
622 #endif
623
624 /*----------------------------------------------------------------------- */
625 /* Setup temporary stack in DCACHE or OCM if needed for SDRAM SPD. */
626 /*----------------------------------------------------------------------- */
627 #ifdef CFG_INIT_DCACHE_CS
628 /*----------------------------------------------------------------------- */
629 /* Memory Bank x (nothingness) initialization 1GB+64MEG */
630 /* used as temporary stack pointer for stage0 */
631 /*----------------------------------------------------------------------- */
632 li r4,PBxAP
633 mtdcr ebccfga,r4
634 lis r4,0x0380
635 ori r4,r4,0x0480
636 mtdcr ebccfgd,r4
637
638 addi r4,0,PBxCR
639 mtdcr ebccfga,r4
640 lis r4,0x400D
641 ori r4,r4,0xa000
642 mtdcr ebccfgd,r4
643
644 /* turn on data chache for this region */
645 lis r4,0x0080
646 mtdccr r4
647
648 /* set stack pointer and clear stack to known value */
649
650 lis r1,CFG_INIT_RAM_ADDR@h
651 ori r1,r1,CFG_INIT_SP_OFFSET@l
652
653 li r4,2048 /* we store 2048 words to stack */
654 mtctr r4
655
656 lis r2,CFG_INIT_RAM_ADDR@h /* we also clear data area */
657 ori r2,r2,CFG_INIT_RAM_END@l /* so cant copy value from r1 */
658
659 lis r4,0xdead /* we store 0xdeaddead in the stack */
660 ori r4,r4,0xdead
661
662 ..stackloop:
663 stwu r4,-4(r2)
664 bdnz ..stackloop
665
666 li r0, 0 /* Make room for stack frame header and */
667 stwu r0, -4(r1) /* clear final stack frame so that */
668 stwu r0, -4(r1) /* stack backtraces terminate cleanly */
669 /*
670 * Set up a dummy frame to store reset vector as return address.
671 * this causes stack underflow to reset board.
672 */
673 stwu r1, -8(r1) /* Save back chain and move SP */
674 addis r0, 0, RESET_VECTOR@h /* Address of reset vector */
675 ori r0, r0, RESET_VECTOR@l
676 stwu r1, -8(r1) /* Save back chain and move SP */
677 stw r0, +12(r1) /* Save return addr (underflow vect) */
678
679 #elif defined(CFG_TEMP_STACK_OCM) && \
680 (defined(CFG_OCM_DATA_ADDR) && defined(CFG_OCM_DATA_SIZE))
681 /*
682 * Stack in OCM.
683 */
684
685 /* Set up Stack at top of OCM */
686 lis r1, (CFG_INIT_RAM_ADDR + CFG_INIT_SP_OFFSET)@h
687 ori r1, r1, (CFG_INIT_RAM_ADDR + CFG_INIT_SP_OFFSET)@l
688
689 /* Set up a zeroized stack frame so that backtrace works right */
690 li r0, 0
691 stwu r0, -4(r1)
692 stwu r0, -4(r1)
693
694 /*
695 * Set up a dummy frame to store reset vector as return address.
696 * this causes stack underflow to reset board.
697 */
698 stwu r1, -8(r1) /* Save back chain and move SP */
699 lis r0, RESET_VECTOR@h /* Address of reset vector */
700 ori r0, r0, RESET_VECTOR@l
701 stwu r1, -8(r1) /* Save back chain and move SP */
702 stw r0, +12(r1) /* Save return addr (underflow vect) */
703 #endif /* CFG_INIT_DCACHE_CS */
704
705 /*----------------------------------------------------------------------- */
706 /* Initialize SDRAM Controller */
707 /*----------------------------------------------------------------------- */
708 bl sdram_init
709
710 /*
711 * Setup temporary stack pointer only for boards
712 * that do not use SDRAM SPD I2C stuff since it
713 * is already initialized to use DCACHE or OCM
714 * stacks.
715 */
716 #if !(defined(CFG_INIT_DCACHE_CS) || defined(CFG_TEMP_STACK_OCM))
717 lis r1, CFG_INIT_RAM_ADDR@h
718 ori r1,r1,CFG_INIT_SP_OFFSET /* set up the stack in SDRAM */
719
720 li r0, 0 /* Make room for stack frame header and */
721 stwu r0, -4(r1) /* clear final stack frame so that */
722 stwu r0, -4(r1) /* stack backtraces terminate cleanly */
723 /*
724 * Set up a dummy frame to store reset vector as return address.
725 * this causes stack underflow to reset board.
726 */
727 stwu r1, -8(r1) /* Save back chain and move SP */
728 lis r0, RESET_VECTOR@h /* Address of reset vector */
729 ori r0, r0, RESET_VECTOR@l
730 stwu r1, -8(r1) /* Save back chain and move SP */
731 stw r0, +12(r1) /* Save return addr (underflow vect) */
732 #endif /* !(CFG_INIT_DCACHE_CS || !CFG_TEM_STACK_OCM) */
733
734 GET_GOT /* initialize GOT access */
735
736 bl cpu_init_f /* run low-level CPU init code (from Flash) */
737
738 /* NEVER RETURNS! */
739 bl board_init_f /* run first part of init code (from Flash) */
740
741 #endif /* CONFIG_405GP || CONFIG_405CR || CONFIG_405 || CONFIG_405EP */
742 /*----------------------------------------------------------------------- */
743
744
745 /*****************************************************************************/
746 .globl _start_of_vectors
747 _start_of_vectors:
748
749 #if 0
750 /*TODO Fixup _start above so we can do this*/
751 /* Critical input. */
752 CRIT_EXCEPTION(0x100, CritcalInput, CritcalInputException)
753 #endif
754
755 /* Machine check */
756 CRIT_EXCEPTION(0x200, MachineCheck, MachineCheckException)
757
758 /* Data Storage exception. */
759 STD_EXCEPTION(0x300, DataStorage, UnknownException)
760
761 /* Instruction Storage exception. */
762 STD_EXCEPTION(0x400, InstStorage, UnknownException)
763
764 /* External Interrupt exception. */
765 STD_EXCEPTION(0x500, ExtInterrupt, external_interrupt)
766
767 /* Alignment exception. */
768 . = 0x600
769 Alignment:
770 EXCEPTION_PROLOG
771 mfspr r4,DAR
772 stw r4,_DAR(r21)
773 mfspr r5,DSISR
774 stw r5,_DSISR(r21)
775 addi r3,r1,STACK_FRAME_OVERHEAD
776 li r20,MSR_KERNEL
777 rlwimi r20,r23,0,16,16 /* copy EE bit from saved MSR */
778 lwz r6,GOT(transfer_to_handler)
779 mtlr r6
780 blrl
781 .L_Alignment:
782 .long AlignmentException - _start + EXC_OFF_SYS_RESET
783 .long int_return - _start + EXC_OFF_SYS_RESET
784
785 /* Program check exception */
786 . = 0x700
787 ProgramCheck:
788 EXCEPTION_PROLOG
789 addi r3,r1,STACK_FRAME_OVERHEAD
790 li r20,MSR_KERNEL
791 rlwimi r20,r23,0,16,16 /* copy EE bit from saved MSR */
792 lwz r6,GOT(transfer_to_handler)
793 mtlr r6
794 blrl
795 .L_ProgramCheck:
796 .long ProgramCheckException - _start + EXC_OFF_SYS_RESET
797 .long int_return - _start + EXC_OFF_SYS_RESET
798
799 /* No FPU on MPC8xx. This exception is not supposed to happen.
800 */
801 STD_EXCEPTION(0x800, FPUnavailable, UnknownException)
802
803 /* I guess we could implement decrementer, and may have
804 * to someday for timekeeping.
805 */
806 STD_EXCEPTION(0x900, Decrementer, timer_interrupt)
807 STD_EXCEPTION(0xa00, Trap_0a, UnknownException)
808 STD_EXCEPTION(0xb00, Trap_0b, UnknownException)
809 STD_EXCEPTION(0xc00, SystemCall, UnknownException)
810 STD_EXCEPTION(0xd00, SingleStep, UnknownException)
811
812 STD_EXCEPTION(0xe00, Trap_0e, UnknownException)
813 STD_EXCEPTION(0xf00, Trap_0f, UnknownException)
814
815 /* On the MPC8xx, this is a software emulation interrupt. It occurs
816 * for all unimplemented and illegal instructions.
817 */
818 STD_EXCEPTION(0x1000, PIT, PITException)
819
820 STD_EXCEPTION(0x1100, InstructionTLBMiss, UnknownException)
821 STD_EXCEPTION(0x1200, DataTLBMiss, UnknownException)
822 STD_EXCEPTION(0x1300, InstructionTLBError, UnknownException)
823 STD_EXCEPTION(0x1400, DataTLBError, UnknownException)
824
825 STD_EXCEPTION(0x1500, Reserved5, UnknownException)
826 STD_EXCEPTION(0x1600, Reserved6, UnknownException)
827 STD_EXCEPTION(0x1700, Reserved7, UnknownException)
828 STD_EXCEPTION(0x1800, Reserved8, UnknownException)
829 STD_EXCEPTION(0x1900, Reserved9, UnknownException)
830 STD_EXCEPTION(0x1a00, ReservedA, UnknownException)
831 STD_EXCEPTION(0x1b00, ReservedB, UnknownException)
832
833 STD_EXCEPTION(0x1c00, DataBreakpoint, UnknownException)
834 STD_EXCEPTION(0x1d00, InstructionBreakpoint, UnknownException)
835 STD_EXCEPTION(0x1e00, PeripheralBreakpoint, UnknownException)
836 STD_EXCEPTION(0x1f00, DevPortBreakpoint, UnknownException)
837
838 CRIT_EXCEPTION(0x2000, DebugBreakpoint, DebugException )
839
840 .globl _end_of_vectors
841 _end_of_vectors:
842
843
844 . = 0x2100
845
846 /*
847 * This code finishes saving the registers to the exception frame
848 * and jumps to the appropriate handler for the exception.
849 * Register r21 is pointer into trap frame, r1 has new stack pointer.
850 */
851 .globl transfer_to_handler
852 transfer_to_handler:
853 stw r22,_NIP(r21)
854 lis r22,MSR_POW@h
855 andc r23,r23,r22
856 stw r23,_MSR(r21)
857 SAVE_GPR(7, r21)
858 SAVE_4GPRS(8, r21)
859 SAVE_8GPRS(12, r21)
860 SAVE_8GPRS(24, r21)
861 #if 0
862 andi. r23,r23,MSR_PR
863 mfspr r23,SPRG3 /* if from user, fix up tss.regs */
864 beq 2f
865 addi r24,r1,STACK_FRAME_OVERHEAD
866 stw r24,PT_REGS(r23)
867 2: addi r2,r23,-TSS /* set r2 to current */
868 tovirt(r2,r2,r23)
869 #endif
870 mflr r23
871 andi. r24,r23,0x3f00 /* get vector offset */
872 stw r24,TRAP(r21)
873 li r22,0
874 stw r22,RESULT(r21)
875 mtspr SPRG2,r22 /* r1 is now kernel sp */
876 #if 0
877 addi r24,r2,TASK_STRUCT_SIZE /* check for kernel stack overflow */
878 cmplw 0,r1,r2
879 cmplw 1,r1,r24
880 crand 1,1,4
881 bgt stack_ovf /* if r2 < r1 < r2+TASK_STRUCT_SIZE */
882 #endif
883 lwz r24,0(r23) /* virtual address of handler */
884 lwz r23,4(r23) /* where to go when done */
885 mtspr SRR0,r24
886 mtspr SRR1,r20
887 mtlr r23
888 SYNC
889 rfi /* jump to handler, enable MMU */
890
891 int_return:
892 mfmsr r28 /* Disable interrupts */
893 li r4,0
894 ori r4,r4,MSR_EE
895 andc r28,r28,r4
896 SYNC /* Some chip revs need this... */
897 mtmsr r28
898 SYNC
899 lwz r2,_CTR(r1)
900 lwz r0,_LINK(r1)
901 mtctr r2
902 mtlr r0
903 lwz r2,_XER(r1)
904 lwz r0,_CCR(r1)
905 mtspr XER,r2
906 mtcrf 0xFF,r0
907 REST_10GPRS(3, r1)
908 REST_10GPRS(13, r1)
909 REST_8GPRS(23, r1)
910 REST_GPR(31, r1)
911 lwz r2,_NIP(r1) /* Restore environment */
912 lwz r0,_MSR(r1)
913 mtspr SRR0,r2
914 mtspr SRR1,r0
915 lwz r0,GPR0(r1)
916 lwz r2,GPR2(r1)
917 lwz r1,GPR1(r1)
918 SYNC
919 rfi
920
921 crit_return:
922 mfmsr r28 /* Disable interrupts */
923 li r4,0
924 ori r4,r4,MSR_EE
925 andc r28,r28,r4
926 SYNC /* Some chip revs need this... */
927 mtmsr r28
928 SYNC
929 lwz r2,_CTR(r1)
930 lwz r0,_LINK(r1)
931 mtctr r2
932 mtlr r0
933 lwz r2,_XER(r1)
934 lwz r0,_CCR(r1)
935 mtspr XER,r2
936 mtcrf 0xFF,r0
937 REST_10GPRS(3, r1)
938 REST_10GPRS(13, r1)
939 REST_8GPRS(23, r1)
940 REST_GPR(31, r1)
941 lwz r2,_NIP(r1) /* Restore environment */
942 lwz r0,_MSR(r1)
943 mtspr 990,r2 /* SRR2 */
944 mtspr 991,r0 /* SRR3 */
945 lwz r0,GPR0(r1)
946 lwz r2,GPR2(r1)
947 lwz r1,GPR1(r1)
948 SYNC
949 rfci
950
951 /* Cache functions.
952 */
953 invalidate_icache:
954 iccci r0,r0 /* for 405, iccci invalidates the */
955 blr /* entire I cache */
956
957 invalidate_dcache:
958 addi r6,0,0x0000 /* clear GPR 6 */
959 /* Do loop for # of dcache congruence classes. */
960 #if defined(CONFIG_440_GX)
961 lis r7, (CFG_DCACHE_SIZE / CFG_CACHELINE_SIZE / 2)@ha /* TBS for large sized cache */
962 ori r7, r7, (CFG_DCACHE_SIZE / CFG_CACHELINE_SIZE / 2)@l
963 #else
964 addi r7,r0, (CFG_DCACHE_SIZE / CFG_CACHELINE_SIZE / 2)
965 #endif
966 /* NOTE: dccci invalidates both */
967 mtctr r7 /* ways in the D cache */
968 ..dcloop:
969 dccci 0,r6 /* invalidate line */
970 addi r6,r6, CFG_CACHELINE_SIZE /* bump to next line */
971 bdnz ..dcloop
972 blr
973
974 flush_dcache:
975 addis r9,r0,0x0002 /* set mask for EE and CE msr bits */
976 ori r9,r9,0x8000
977 mfmsr r12 /* save msr */
978 andc r9,r12,r9
979 mtmsr r9 /* disable EE and CE */
980 addi r10,r0,0x0001 /* enable data cache for unused memory */
981 mfdccr r9 /* region 0xF8000000-0xFFFFFFFF via */
982 or r10,r10,r9 /* bit 31 in dccr */
983 mtdccr r10
984
985 /* do loop for # of congruence classes. */
986 #if defined(CONFIG_440_GX)
987 lis r10,(CFG_DCACHE_SIZE / CFG_CACHELINE_SIZE / 2)@ha /* TBS: for large cache sizes */
988 ori r10,r10,(CFG_DCACHE_SIZE / CFG_CACHELINE_SIZE / 2)@l
989 lis r11,(CFG_DCACHE_SIZE / 2)@ha /* D cache set size - 2 way sets */
990 ori r11,r11,(CFG_DCACHE_SIZE / 2)@l /* D cache set size - 2 way sets */
991 #else
992 addi r10,r0,(CFG_DCACHE_SIZE / CFG_CACHELINE_SIZE / 2)
993 addi r11,r0,(CFG_DCACHE_SIZE / 2) /* D cache set size - 2 way sets */
994 #endif
995 mtctr r10
996 addi r10,r0,(0xE000-0x10000) /* start at 0xFFFFE000 */
997 add r11,r10,r11 /* add to get to other side of cache line */
998 ..flush_dcache_loop:
999 lwz r3,0(r10) /* least recently used side */
1000 lwz r3,0(r11) /* the other side */
1001 dccci r0,r11 /* invalidate both sides */
1002 addi r10,r10,CFG_CACHELINE_SIZE /* bump to next line */
1003 addi r11,r11,CFG_CACHELINE_SIZE /* bump to next line */
1004 bdnz ..flush_dcache_loop
1005 sync /* allow memory access to complete */
1006 mtdccr r9 /* restore dccr */
1007 mtmsr r12 /* restore msr */
1008 blr
1009
1010 .globl icache_enable
1011 icache_enable:
1012 mflr r8
1013 bl invalidate_icache
1014 mtlr r8
1015 isync
1016 addis r3,r0, 0x8000 /* set bit 0 */
1017 mticcr r3
1018 blr
1019
1020 .globl icache_disable
1021 icache_disable:
1022 addis r3,r0, 0x0000 /* clear bit 0 */
1023 mticcr r3
1024 isync
1025 blr
1026
1027 .globl icache_status
1028 icache_status:
1029 mficcr r3
1030 srwi r3, r3, 31 /* >>31 => select bit 0 */
1031 blr
1032
1033 .globl dcache_enable
1034 dcache_enable:
1035 mflr r8
1036 bl invalidate_dcache
1037 mtlr r8
1038 isync
1039 addis r3,r0, 0x8000 /* set bit 0 */
1040 mtdccr r3
1041 blr
1042
1043 .globl dcache_disable
1044 dcache_disable:
1045 mflr r8
1046 bl flush_dcache
1047 mtlr r8
1048 addis r3,r0, 0x0000 /* clear bit 0 */
1049 mtdccr r3
1050 blr
1051
1052 .globl dcache_status
1053 dcache_status:
1054 mfdccr r3
1055 srwi r3, r3, 31 /* >>31 => select bit 0 */
1056 blr
1057
1058 .globl get_pvr
1059 get_pvr:
1060 mfspr r3, PVR
1061 blr
1062
1063 #if !defined(CONFIG_440)
1064 .globl wr_pit
1065 wr_pit:
1066 mtspr pit, r3
1067 blr
1068 #endif
1069
1070 .globl wr_tcr
1071 wr_tcr:
1072 mtspr tcr, r3
1073 blr
1074
1075 /*------------------------------------------------------------------------------- */
1076 /* Function: in8 */
1077 /* Description: Input 8 bits */
1078 /*------------------------------------------------------------------------------- */
1079 .globl in8
1080 in8:
1081 lbz r3,0x0000(r3)
1082 blr
1083
1084 /*------------------------------------------------------------------------------- */
1085 /* Function: out8 */
1086 /* Description: Output 8 bits */
1087 /*------------------------------------------------------------------------------- */
1088 .globl out8
1089 out8:
1090 stb r4,0x0000(r3)
1091 blr
1092
1093 /*------------------------------------------------------------------------------- */
1094 /* Function: out16 */
1095 /* Description: Output 16 bits */
1096 /*------------------------------------------------------------------------------- */
1097 .globl out16
1098 out16:
1099 sth r4,0x0000(r3)
1100 blr
1101
1102 /*------------------------------------------------------------------------------- */
1103 /* Function: out16r */
1104 /* Description: Byte reverse and output 16 bits */
1105 /*------------------------------------------------------------------------------- */
1106 .globl out16r
1107 out16r:
1108 sthbrx r4,r0,r3
1109 blr
1110
1111 /*------------------------------------------------------------------------------- */
1112 /* Function: out32 */
1113 /* Description: Output 32 bits */
1114 /*------------------------------------------------------------------------------- */
1115 .globl out32
1116 out32:
1117 stw r4,0x0000(r3)
1118 blr
1119
1120 /*------------------------------------------------------------------------------- */
1121 /* Function: out32r */
1122 /* Description: Byte reverse and output 32 bits */
1123 /*------------------------------------------------------------------------------- */
1124 .globl out32r
1125 out32r:
1126 stwbrx r4,r0,r3
1127 blr
1128
1129 /*------------------------------------------------------------------------------- */
1130 /* Function: in16 */
1131 /* Description: Input 16 bits */
1132 /*------------------------------------------------------------------------------- */
1133 .globl in16
1134 in16:
1135 lhz r3,0x0000(r3)
1136 blr
1137
1138 /*------------------------------------------------------------------------------- */
1139 /* Function: in16r */
1140 /* Description: Input 16 bits and byte reverse */
1141 /*------------------------------------------------------------------------------- */
1142 .globl in16r
1143 in16r:
1144 lhbrx r3,r0,r3
1145 blr
1146
1147 /*------------------------------------------------------------------------------- */
1148 /* Function: in32 */
1149 /* Description: Input 32 bits */
1150 /*------------------------------------------------------------------------------- */
1151 .globl in32
1152 in32:
1153 lwz 3,0x0000(3)
1154 blr
1155
1156 /*------------------------------------------------------------------------------- */
1157 /* Function: in32r */
1158 /* Description: Input 32 bits and byte reverse */
1159 /*------------------------------------------------------------------------------- */
1160 .globl in32r
1161 in32r:
1162 lwbrx r3,r0,r3
1163 blr
1164
1165 /*------------------------------------------------------------------------------- */
1166 /* Function: ppcDcbf */
1167 /* Description: Data Cache block flush */
1168 /* Input: r3 = effective address */
1169 /* Output: none. */
1170 /*------------------------------------------------------------------------------- */
1171 .globl ppcDcbf
1172 ppcDcbf:
1173 dcbf r0,r3
1174 blr
1175
1176 /*------------------------------------------------------------------------------- */
1177 /* Function: ppcDcbi */
1178 /* Description: Data Cache block Invalidate */
1179 /* Input: r3 = effective address */
1180 /* Output: none. */
1181 /*------------------------------------------------------------------------------- */
1182 .globl ppcDcbi
1183 ppcDcbi:
1184 dcbi r0,r3
1185 blr
1186
1187 /*------------------------------------------------------------------------------- */
1188 /* Function: ppcSync */
1189 /* Description: Processor Synchronize */
1190 /* Input: none. */
1191 /* Output: none. */
1192 /*------------------------------------------------------------------------------- */
1193 .globl ppcSync
1194 ppcSync:
1195 sync
1196 blr
1197
1198 /*------------------------------------------------------------------------------*/
1199
1200 /*
1201 * void relocate_code (addr_sp, gd, addr_moni)
1202 *
1203 * This "function" does not return, instead it continues in RAM
1204 * after relocating the monitor code.
1205 *
1206 * r3 = dest
1207 * r4 = src
1208 * r5 = length in bytes
1209 * r6 = cachelinesize
1210 */
1211 .globl relocate_code
1212 relocate_code:
1213 mr r1, r3 /* Set new stack pointer */
1214 mr r9, r4 /* Save copy of Init Data pointer */
1215 mr r10, r5 /* Save copy of Destination Address */
1216
1217 mr r3, r5 /* Destination Address */
1218 lis r4, CFG_MONITOR_BASE@h /* Source Address */
1219 ori r4, r4, CFG_MONITOR_BASE@l
1220 lwz r5, GOT(__init_end)
1221 sub r5, r5, r4
1222 li r6, CFG_CACHELINE_SIZE /* Cache Line Size */
1223
1224 /*
1225 * Fix GOT pointer:
1226 *
1227 * New GOT-PTR = (old GOT-PTR - CFG_MONITOR_BASE) + Destination Address
1228 *
1229 * Offset:
1230 */
1231 sub r15, r10, r4
1232
1233 /* First our own GOT */
1234 add r14, r14, r15
1235 /* the the one used by the C code */
1236 add r30, r30, r15
1237
1238 /*
1239 * Now relocate code
1240 */
1241
1242 cmplw cr1,r3,r4
1243 addi r0,r5,3
1244 srwi. r0,r0,2
1245 beq cr1,4f /* In place copy is not necessary */
1246 beq 7f /* Protect against 0 count */
1247 mtctr r0
1248 bge cr1,2f
1249
1250 la r8,-4(r4)
1251 la r7,-4(r3)
1252 1: lwzu r0,4(r8)
1253 stwu r0,4(r7)
1254 bdnz 1b
1255 b 4f
1256
1257 2: slwi r0,r0,2
1258 add r8,r4,r0
1259 add r7,r3,r0
1260 3: lwzu r0,-4(r8)
1261 stwu r0,-4(r7)
1262 bdnz 3b
1263
1264 /*
1265 * Now flush the cache: note that we must start from a cache aligned
1266 * address. Otherwise we might miss one cache line.
1267 */
1268 4: cmpwi r6,0
1269 add r5,r3,r5
1270 beq 7f /* Always flush prefetch queue in any case */
1271 subi r0,r6,1
1272 andc r3,r3,r0
1273 mr r4,r3
1274 5: dcbst 0,r4
1275 add r4,r4,r6
1276 cmplw r4,r5
1277 blt 5b
1278 sync /* Wait for all dcbst to complete on bus */
1279 mr r4,r3
1280 6: icbi 0,r4
1281 add r4,r4,r6
1282 cmplw r4,r5
1283 blt 6b
1284 7: sync /* Wait for all icbi to complete on bus */
1285 isync
1286
1287 /*
1288 * We are done. Do not return, instead branch to second part of board
1289 * initialization, now running from RAM.
1290 */
1291
1292 addi r0, r10, in_ram - _start + EXC_OFF_SYS_RESET
1293 mtlr r0
1294 blr /* NEVER RETURNS! */
1295
1296 in_ram:
1297
1298 /*
1299 * Relocation Function, r14 point to got2+0x8000
1300 *
1301 * Adjust got2 pointers, no need to check for 0, this code
1302 * already puts a few entries in the table.
1303 */
1304 li r0,__got2_entries@sectoff@l
1305 la r3,GOT(_GOT2_TABLE_)
1306 lwz r11,GOT(_GOT2_TABLE_)
1307 mtctr r0
1308 sub r11,r3,r11
1309 addi r3,r3,-4
1310 1: lwzu r0,4(r3)
1311 add r0,r0,r11
1312 stw r0,0(r3)
1313 bdnz 1b
1314
1315 /*
1316 * Now adjust the fixups and the pointers to the fixups
1317 * in case we need to move ourselves again.
1318 */
1319 2: li r0,__fixup_entries@sectoff@l
1320 lwz r3,GOT(_FIXUP_TABLE_)
1321 cmpwi r0,0
1322 mtctr r0
1323 addi r3,r3,-4
1324 beq 4f
1325 3: lwzu r4,4(r3)
1326 lwzux r0,r4,r11
1327 add r0,r0,r11
1328 stw r10,0(r3)
1329 stw r0,0(r4)
1330 bdnz 3b
1331 4:
1332 clear_bss:
1333 /*
1334 * Now clear BSS segment
1335 */
1336 lwz r3,GOT(__bss_start)
1337 lwz r4,GOT(_end)
1338
1339 cmplw 0, r3, r4
1340 beq 6f
1341
1342 li r0, 0
1343 5:
1344 stw r0, 0(r3)
1345 addi r3, r3, 4
1346 cmplw 0, r3, r4
1347 bne 5b
1348 6:
1349
1350 mr r3, r9 /* Init Data pointer */
1351 mr r4, r10 /* Destination Address */
1352 bl board_init_r
1353
1354 /*
1355 * Copy exception vector code to low memory
1356 *
1357 * r3: dest_addr
1358 * r7: source address, r8: end address, r9: target address
1359 */
1360 .globl trap_init
1361 trap_init:
1362 lwz r7, GOT(_start)
1363 lwz r8, GOT(_end_of_vectors)
1364
1365 li r9, 0x100 /* reset vector always at 0x100 */
1366
1367 cmplw 0, r7, r8
1368 bgelr /* return if r7>=r8 - just in case */
1369
1370 mflr r4 /* save link register */
1371 1:
1372 lwz r0, 0(r7)
1373 stw r0, 0(r9)
1374 addi r7, r7, 4
1375 addi r9, r9, 4
1376 cmplw 0, r7, r8
1377 bne 1b
1378
1379 /*
1380 * relocate `hdlr' and `int_return' entries
1381 */
1382 li r7, .L_MachineCheck - _start + EXC_OFF_SYS_RESET
1383 li r8, Alignment - _start + EXC_OFF_SYS_RESET
1384 2:
1385 bl trap_reloc
1386 addi r7, r7, 0x100 /* next exception vector */
1387 cmplw 0, r7, r8
1388 blt 2b
1389
1390 li r7, .L_Alignment - _start + EXC_OFF_SYS_RESET
1391 bl trap_reloc
1392
1393 li r7, .L_ProgramCheck - _start + EXC_OFF_SYS_RESET
1394 bl trap_reloc
1395
1396 li r7, .L_FPUnavailable - _start + EXC_OFF_SYS_RESET
1397 li r8, SystemCall - _start + EXC_OFF_SYS_RESET
1398 3:
1399 bl trap_reloc
1400 addi r7, r7, 0x100 /* next exception vector */
1401 cmplw 0, r7, r8
1402 blt 3b
1403
1404 li r7, .L_SingleStep - _start + EXC_OFF_SYS_RESET
1405 li r8, _end_of_vectors - _start + EXC_OFF_SYS_RESET
1406 4:
1407 bl trap_reloc
1408 addi r7, r7, 0x100 /* next exception vector */
1409 cmplw 0, r7, r8
1410 blt 4b
1411
1412 mtlr r4 /* restore link register */
1413 blr
1414
1415 /*
1416 * Function: relocate entries for one exception vector
1417 */
1418 trap_reloc:
1419 lwz r0, 0(r7) /* hdlr ... */
1420 add r0, r0, r3 /* ... += dest_addr */
1421 stw r0, 0(r7)
1422
1423 lwz r0, 4(r7) /* int_return ... */
1424 add r0, r0, r3 /* ... += dest_addr */
1425 stw r0, 4(r7)
1426
1427 blr
1428
1429
1430 /**************************************************************************/
1431 /* PPC405EP specific stuff */
1432 /**************************************************************************/
1433 #ifdef CONFIG_405EP
1434 ppc405ep_init:
1435
1436 #ifdef CONFIG_BUBINGA405EP
1437 /*
1438 * Initialize EBC chip selects 1 & 4 and GPIO pins (for alternate
1439 * function) to support FPGA and NVRAM accesses below.
1440 */
1441
1442 lis r3,GPIO0_OSRH@h /* config GPIO output select */
1443 ori r3,r3,GPIO0_OSRH@l
1444 lis r4,CFG_GPIO0_OSRH@h
1445 ori r4,r4,CFG_GPIO0_OSRH@l
1446 stw r4,0(r3)
1447 lis r3,GPIO0_OSRL@h
1448 ori r3,r3,GPIO0_OSRL@l
1449 lis r4,CFG_GPIO0_OSRL@h
1450 ori r4,r4,CFG_GPIO0_OSRL@l
1451 stw r4,0(r3)
1452
1453 lis r3,GPIO0_ISR1H@h /* config GPIO input select */
1454 ori r3,r3,GPIO0_ISR1H@l
1455 lis r4,CFG_GPIO0_ISR1H@h
1456 ori r4,r4,CFG_GPIO0_ISR1H@l
1457 stw r4,0(r3)
1458 lis r3,GPIO0_ISR1L@h
1459 ori r3,r3,GPIO0_ISR1L@l
1460 lis r4,CFG_GPIO0_ISR1L@h
1461 ori r4,r4,CFG_GPIO0_ISR1L@l
1462 stw r4,0(r3)
1463
1464 lis r3,GPIO0_TSRH@h /* config GPIO three-state select */
1465 ori r3,r3,GPIO0_TSRH@l
1466 lis r4,CFG_GPIO0_TSRH@h
1467 ori r4,r4,CFG_GPIO0_TSRH@l
1468 stw r4,0(r3)
1469 lis r3,GPIO0_TSRL@h
1470 ori r3,r3,GPIO0_TSRL@l
1471 lis r4,CFG_GPIO0_TSRL@h
1472 ori r4,r4,CFG_GPIO0_TSRL@l
1473 stw r4,0(r3)
1474
1475 lis r3,GPIO0_TCR@h /* config GPIO driver output enables */
1476 ori r3,r3,GPIO0_TCR@l
1477 lis r4,CFG_GPIO0_TCR@h
1478 ori r4,r4,CFG_GPIO0_TCR@l
1479 stw r4,0(r3)
1480
1481 li r3,pb1ap /* program EBC bank 1 for RTC access */
1482 mtdcr ebccfga,r3
1483 lis r3,CFG_EBC_PB1AP@h
1484 ori r3,r3,CFG_EBC_PB1AP@l
1485 mtdcr ebccfgd,r3
1486 li r3,pb1cr
1487 mtdcr ebccfga,r3
1488 lis r3,CFG_EBC_PB1CR@h
1489 ori r3,r3,CFG_EBC_PB1CR@l
1490 mtdcr ebccfgd,r3
1491
1492 li r3,pb1ap /* program EBC bank 1 for RTC access */
1493 mtdcr ebccfga,r3
1494 lis r3,CFG_EBC_PB1AP@h
1495 ori r3,r3,CFG_EBC_PB1AP@l
1496 mtdcr ebccfgd,r3
1497 li r3,pb1cr
1498 mtdcr ebccfga,r3
1499 lis r3,CFG_EBC_PB1CR@h
1500 ori r3,r3,CFG_EBC_PB1CR@l
1501 mtdcr ebccfgd,r3
1502
1503 li r3,pb4ap /* program EBC bank 4 for FPGA access */
1504 mtdcr ebccfga,r3
1505 lis r3,CFG_EBC_PB4AP@h
1506 ori r3,r3,CFG_EBC_PB4AP@l
1507 mtdcr ebccfgd,r3
1508 li r3,pb4cr
1509 mtdcr ebccfga,r3
1510 lis r3,CFG_EBC_PB4CR@h
1511 ori r3,r3,CFG_EBC_PB4CR@l
1512 mtdcr ebccfgd,r3
1513 #endif
1514
1515 addi r3,0,CPC0_PCI_HOST_CFG_EN
1516 #ifdef CONFIG_BUBINGA405EP
1517 /*
1518 !-----------------------------------------------------------------------
1519 ! Check FPGA for PCI internal/external arbitration
1520 ! If board is set to internal arbitration, update cpc0_pci
1521 !-----------------------------------------------------------------------
1522 */
1523 addis r5,r0,FPGA_REG1@h /* set offset for FPGA_REG1 */
1524 ori r5,r5,FPGA_REG1@l
1525 lbz r5,0x0(r5) /* read to get PCI arb selection */
1526 andi. r6,r5,FPGA_REG1_PCI_INT_ARB /* using internal arbiter ?*/
1527 beq ..pci_cfg_set /* if not set, then bypass reg write*/
1528 #endif
1529 ori r3,r3,CPC0_PCI_ARBIT_EN
1530 ..pci_cfg_set:
1531 mtdcr CPC0_PCI, r3 /* Enable internal arbiter*/
1532
1533 /*
1534 !-----------------------------------------------------------------------
1535 ! Check to see if chip is in bypass mode.
1536 ! If so, write stored CPC0_PLLMR0 and CPC0_PLLMR1 values and perform a
1537 ! CPU reset Otherwise, skip this step and keep going.
1538 ! Note: Running BIOS in bypass mode is not supported since PLB speed
1539 ! will not be fast enough for the SDRAM (min 66MHz)
1540 !-----------------------------------------------------------------------
1541 */
1542 mfdcr r5, CPC0_PLLMR1
1543 rlwinm r4,r5,1,0x1 /* get system clock source (SSCS) */
1544 cmpi cr0,0,r4,0x1
1545
1546 beq pll_done /* if SSCS =b'1' then PLL has */
1547 /* already been set */
1548 /* and CPU has been reset */
1549 /* so skip to next section */
1550
1551 #ifdef CONFIG_BUBINGA405EP
1552 /*
1553 !-----------------------------------------------------------------------
1554 ! Read NVRAM to get value to write in PLLMR.
1555 ! If value has not been correctly saved, write default value
1556 ! Default config values (assuming on-board 33MHz SYS_CLK) are above.
1557 ! See CPU_DEFAULT_200 and CPU_DEFAULT_266 above.
1558 !
1559 ! WARNING: This code assumes the first three words in the nvram_t
1560 ! structure in openbios.h. Changing the beginning of
1561 ! the structure will break this code.
1562 !
1563 !-----------------------------------------------------------------------
1564 */
1565 addis r3,0,NVRAM_BASE@h
1566 addi r3,r3,NVRAM_BASE@l
1567
1568 lwz r4, 0(r3)
1569 addis r5,0,NVRVFY1@h
1570 addi r5,r5,NVRVFY1@l
1571 cmp cr0,0,r4,r5 /* Compare 1st NVRAM Magic number*/
1572 bne ..no_pllset
1573 addi r3,r3,4
1574 lwz r4, 0(r3)
1575 addis r5,0,NVRVFY2@h
1576 addi r5,r5,NVRVFY2@l
1577 cmp cr0,0,r4,r5 /* Compare 2 NVRAM Magic number */
1578 bne ..no_pllset
1579 addi r3,r3,8 /* Skip over conf_size */
1580 lwz r4, 4(r3) /* Load PLLMR1 value from NVRAM */
1581 lwz r3, 0(r3) /* Load PLLMR0 value from NVRAM */
1582 rlwinm r5,r4,1,0x1 /* get system clock source (SSCS) */
1583 cmpi cr0,0,r5,1 /* See if PLL is locked */
1584 beq pll_write
1585 ..no_pllset:
1586 #endif /* CONFIG_BUBINGA405EP */
1587
1588 addis r3,0,PLLMR0_DEFAULT@h /* PLLMR0 default value */
1589 ori r3,r3,PLLMR0_DEFAULT@l /* */
1590 addis r4,0,PLLMR1_DEFAULT@h /* PLLMR1 default value */
1591 ori r4,r4,PLLMR1_DEFAULT@l /* */
1592
1593 b pll_write /* Write the CPC0_PLLMR with new value */
1594
1595 pll_done:
1596 /*
1597 !-----------------------------------------------------------------------
1598 ! Clear Soft Reset Register
1599 ! This is needed to enable PCI if not booting from serial EPROM
1600 !-----------------------------------------------------------------------
1601 */
1602 addi r3, 0, 0x0
1603 mtdcr CPC0_SRR, r3
1604
1605 addis r3,0,0x0010
1606 mtctr r3
1607 pci_wait:
1608 bdnz pci_wait
1609
1610 blr /* return to main code */
1611
1612 /*
1613 !-----------------------------------------------------------------------------
1614 ! Function: pll_write
1615 ! Description: Updates the value of the CPC0_PLLMR according to CMOS27E documentation
1616 ! That is:
1617 ! 1. Pll is first disabled (de-activated by putting in bypass mode)
1618 ! 2. PLL is reset
1619 ! 3. Clock dividers are set while PLL is held in reset and bypassed
1620 ! 4. PLL Reset is cleared
1621 ! 5. Wait 100us for PLL to lock
1622 ! 6. A core reset is performed
1623 ! Input: r3 = Value to write to CPC0_PLLMR0
1624 ! Input: r4 = Value to write to CPC0_PLLMR1
1625 ! Output r3 = none
1626 !-----------------------------------------------------------------------------
1627 */
1628 pll_write:
1629 mfdcr r5, CPC0_UCR
1630 andis. r5,r5,0xFFFF
1631 ori r5,r5,0x0101 /* Stop the UART clocks */
1632 mtdcr CPC0_UCR,r5 /* Before changing PLL */
1633
1634 mfdcr r5, CPC0_PLLMR1
1635 rlwinm r5,r5,0,0x7FFFFFFF /* Disable PLL */
1636 mtdcr CPC0_PLLMR1,r5
1637 oris r5,r5,0x4000 /* Set PLL Reset */
1638 mtdcr CPC0_PLLMR1,r5
1639
1640 mtdcr CPC0_PLLMR0,r3 /* Set clock dividers */
1641 rlwinm r5,r4,0,0x3FFFFFFF /* Reset & Bypass new PLL dividers */
1642 oris r5,r5,0x4000 /* Set PLL Reset */
1643 mtdcr CPC0_PLLMR1,r5 /* Set clock dividers */
1644 rlwinm r5,r5,0,0xBFFFFFFF /* Clear PLL Reset */
1645 mtdcr CPC0_PLLMR1,r5
1646
1647 /*
1648 ! Wait min of 100us for PLL to lock.
1649 ! See CMOS 27E databook for more info.
1650 ! At 200MHz, that means waiting 20,000 instructions
1651 */
1652 addi r3,0,20000 /* 2000 = 0x4e20 */
1653 mtctr r3
1654 pll_wait:
1655 bdnz pll_wait
1656
1657 oris r5,r5,0x8000 /* Enable PLL */
1658 mtdcr CPC0_PLLMR1,r5 /* Engage */
1659
1660 /*
1661 * Reset CPU to guarantee timings are OK
1662 * Not sure if this is needed...
1663 */
1664 addis r3,0,0x1000
1665 mtspr dbcr0,r3 /* This will cause a CPU core reset, and */
1666 /* execution will continue from the poweron */
1667 /* vector of 0xfffffffc */
1668 #endif /* CONFIG_405EP */