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