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>
6 * See file CREDITS for list of people who contributed to this
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.
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.
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,
24 /*------------------------------------------------------------------------------+ */
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. */
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. */
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. */
41 /* COPYRIGHT I B M CORPORATION 1995 */
42 /* LICENSED MATERIAL - PROGRAM PROPERTY OF I B M */
43 /*------------------------------------------------------------------------------- */
45 /* U-Boot - Startup Code for IBM 4xx PowerPC based Embedded Boards
48 * The processor starts at 0xfffffffc and the code is executed
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.
57 * board_init will change CS0 to be positioned at the correct
58 * address and (s)dram will be positioned at address 0
65 #define _LINUX_CONFIG_H 1 /* avoid reading Linux autoconf.h file */
67 #include <ppc_asm.tmpl>
70 #include <asm/cache.h>
73 #ifndef CONFIG_IDENT_STRING
74 #define CONFIG_IDENT_STRING ""
77 #ifdef CFG_INIT_DCACHE_CS
78 # if (CFG_INIT_DCACHE_CS == 0)
82 # if (CFG_INIT_DCACHE_CS == 1)
86 # if (CFG_INIT_DCACHE_CS == 2)
90 # if (CFG_INIT_DCACHE_CS == 3)
94 # if (CFG_INIT_DCACHE_CS == 4)
98 # if (CFG_INIT_DCACHE_CS == 5)
102 # if (CFG_INIT_DCACHE_CS == 6)
106 # if (CFG_INIT_DCACHE_CS == 7)
110 #endif /* CFG_INIT_DCACHE_CS */
112 /* We don't want the MMU yet.
115 #define MSR_KERNEL ( MSR_ME ) /* Machine Check */
118 .extern ext_bus_cntlr_init
122 * Set up GOT: Global Offset Table
124 * Use r14 to access the GOT
127 GOT_ENTRY(_GOT2_TABLE_)
128 GOT_ENTRY(_FIXUP_TABLE_)
131 GOT_ENTRY(_start_of_vectors)
132 GOT_ENTRY(_end_of_vectors)
133 GOT_ENTRY(transfer_to_handler)
140 * 440 Startup -- on reset only the top 4k of the effective
141 * address space is mapped in by an entry in the instruction
142 * and data shadow TLB. The .bootpg section is located in the
143 * top 4k & does only what's necessary to map in the the rest
144 * of the boot rom. Once the boot rom is mapped in we can
145 * proceed with normal startup.
147 * NOTE: CS0 only covers the top 2MB of the effective address
151 #if defined(CONFIG_440)
152 .section .bootpg,"ax"
155 /**************************************************************************/
157 /*----------------------------------------------------------------*/
158 /* Clear and set up some registers. */
159 /*----------------------------------------------------------------*/
160 iccci r0,r0 /* NOTE: operands not used for 440 */
161 dccci r0,r0 /* NOTE: operands not used for 440 */
169 /*----------------------------------------------------------------*/
170 /* Initialize debug */
171 /*----------------------------------------------------------------*/
184 mtspr dbsr,r1 /* Clear all valid bits */
186 /*----------------------------------------------------------------*/
188 /*----------------------------------------------------------------*/
189 /* Disable store gathering & broadcast, guarantee inst/data
190 * cache block touch, force load/store alignment
191 * (see errata 1.12: 440_33)
193 lis r1,0x0030 /* store gathering & broadcast disable */
194 ori r1,r1,0x6000 /* cache touch */
197 /*----------------------------------------------------------------*/
198 /* Setup interrupt vectors */
199 /*----------------------------------------------------------------*/
200 mtspr ivpr,r0 /* Vectors start at 0x0000_0000 */
202 mtspr ivor0,r1 /* Critical input */
204 mtspr ivor1,r1 /* Machine check */
206 mtspr ivor2,r1 /* Data storage */
208 mtspr ivor3,r1 /* Instruction storage */
210 mtspr ivor4,r1 /* External interrupt */
212 mtspr ivor5,r1 /* Alignment */
214 mtspr ivor6,r1 /* Program check */
216 mtspr ivor7,r1 /* Floating point unavailable */
218 mtspr ivor8,r1 /* System call */
220 mtspr ivor10,r1 /* Decrementer (PIT for 440) */
222 mtspr ivor13,r1 /* Data TLB error */
224 mtspr ivor14,r1 /* Instr TLB error */
226 mtspr ivor15,r1 /* Debug */
228 /*----------------------------------------------------------------*/
229 /* Configure cache regions */
230 /*----------------------------------------------------------------*/
248 /*----------------------------------------------------------------*/
249 /* Cache victim limits */
250 /*----------------------------------------------------------------*/
251 /* floors 0, ceiling max to use the entire cache -- nothing locked
258 /*----------------------------------------------------------------*/
259 /* Clear all TLB entries -- TID = 0, TS = 0 */
260 /*----------------------------------------------------------------*/
262 li r1,0x003f /* 64 TLB entries */
264 0: tlbwe r0,r1,0x0000 /* Invalidate all entries (V=0)*/
268 /*----------------------------------------------------------------*/
269 /* TLB entry setup -- step thru tlbtab */
270 /*----------------------------------------------------------------*/
271 bl tlbtab /* Get tlbtab pointer */
273 li r1,0x003f /* 64 TLB entries max */
280 beq 2f /* 0 marks end */
283 tlbwe r0,r4,0 /* TLB Word 0 */
284 tlbwe r1,r4,1 /* TLB Word 1 */
285 tlbwe r2,r4,2 /* TLB Word 2 */
286 addi r4,r4,1 /* Next TLB */
289 /*----------------------------------------------------------------*/
290 /* Continue from 'normal' start */
291 /*----------------------------------------------------------------*/
296 mtspr srr1,r0 /* Keep things disabled for now */
303 * r3 - 1st arg to board_init(): IMMP pointer
304 * r4 - 2nd arg to board_init(): boot flag
307 .long 0x27051956 /* U-Boot Magic Number */
308 .globl version_string
310 .ascii U_BOOT_VERSION
311 .ascii " (", __DATE__, " - ", __TIME__, ")"
312 .ascii CONFIG_IDENT_STRING, "\0"
315 * Maybe this should be moved somewhere else because the current
316 * location (0x100) is where the CriticalInput Execption should be.
318 . = EXC_OFF_SYS_RESET
322 /*****************************************************************************/
323 #if defined(CONFIG_440)
325 /*----------------------------------------------------------------*/
326 /* Clear and set up some registers. */
327 /*----------------------------------------------------------------*/
330 mtspr dec,r0 /* prevent dec exceptions */
331 mtspr tbl,r0 /* prevent fit & wdt exceptions */
333 mtspr tsr,r1 /* clear all timer exception status */
334 mtspr tcr,r0 /* disable all */
335 mtspr esr,r0 /* clear exception syndrome register */
336 mtxer r0 /* clear integer exception register */
337 lis r1,0x0002 /* set CE bit (Critical Exceptions) */
338 ori r1,r1,0x1000 /* set ME bit (Machine Exceptions) */
339 mtmsr r1 /* change MSR */
341 /*----------------------------------------------------------------*/
342 /* Debug setup -- some (not very good) ice's need an event*/
343 /* to establish control :-( Define CFG_INIT_DBCR to the dbsr */
344 /* value you need in this case 0x8cff 0000 should do the trick */
345 /*----------------------------------------------------------------*/
346 #if defined(CFG_INIT_DBCR)
349 mtspr dbsr,r1 /* Clear all status bits */
350 lis r0,CFG_INIT_DBCR@h
351 ori r0,r0,CFG_INIT_DBCR@l
356 /*----------------------------------------------------------------*/
357 /* Setup the internal SRAM */
358 /*----------------------------------------------------------------*/
360 mtdcr isram0_sb1cr,r0 /* Disable bank 1 */
365 and r1,r1,r2 /* Disable parity check */
368 andis. r1,r1,r2 /* Disable pwr mgmt */
371 lis r1,0x8000 /* BAS = 8000_0000 */
372 ori r1,r1,0x0380 /* 8k rw */
373 mtdcr isram0_sb0cr,r1
375 /*----------------------------------------------------------------*/
376 /* Setup the stack in internal SRAM */
377 /*----------------------------------------------------------------*/
378 lis r1,CFG_INIT_RAM_ADDR@h
379 ori r1,r1,CFG_INIT_SP_OFFSET@l
383 stwu r0,-4(r1) /* Terminate call chain */
385 stwu r1,-8(r1) /* Save back chain and move SP */
386 lis r0,RESET_VECTOR@h /* Address of reset vector */
387 ori r0,r0, RESET_VECTOR@l
388 stwu r1,-8(r1) /* Save back chain and move SP */
389 stw r0,+12(r1) /* Save return addr (underflow vect) */
394 #endif /* CONFIG_440 */
396 /*****************************************************************************/
398 /*----------------------------------------------------------------------- */
399 /* Set up some machine state registers. */
400 /*----------------------------------------------------------------------- */
401 addi r0,r0,0x0000 /* initialize r0 to zero */
402 mtspr esr,r0 /* clear Exception Syndrome Reg */
403 mttcr r0 /* timer control register */
404 mtexier r0 /* disable all interrupts */
405 addi r4,r0,0x1000 /* set ME bit (Machine Exceptions) */
406 oris r4,r4,0x2 /* set CE bit (Critical Exceptions) */
407 mtmsr r4 /* change MSR */
408 addis r4,r0,0xFFFF /* set r4 to 0xFFFFFFFF (status in the */
409 ori r4,r4,0xFFFF /* dbsr is cleared by setting bits to 1) */
410 mtdbsr r4 /* clear/reset the dbsr */
411 mtexisr r4 /* clear all pending interrupts */
413 mtexier r4 /* enable critical exceptions */
414 addis r4,r0,0x0000 /* assume 403GCX - enable core clk */
415 ori r4,r4,0x4020 /* dbling (no harm done on GA and GC */
416 mtiocr r4 /* since bit not used) & DRC to latch */
417 /* data bus on rising edge of CAS */
418 /*----------------------------------------------------------------------- */
420 /*----------------------------------------------------------------------- */
422 /*----------------------------------------------------------------------- */
423 /* Invalidate i-cache and d-cache TAG arrays. */
424 /*----------------------------------------------------------------------- */
425 addi r3,0,1024 /* 1/4 of I-cache size, half of D-cache */
426 addi r4,0,1024 /* 1/4 of I-cache */
431 addic. r3,r3,-16 /* move back one cache line */
432 bne ..cloop /* loop back to do rest until r3 = 0 */
435 /* initialize IOP480 so it can read 1 MB code area for SRAM spaces */
436 /* this requires enabling MA[17..0], by default only MA[12..0] are enabled. */
439 /* first copy IOP480 register base address into r3 */
440 addis r3,0,0x5000 /* IOP480 register base address hi */
441 /* ori r3,r3,0x0000 / IOP480 register base address lo */
444 /* use r4 as the working variable */
445 /* turn on CS3 (LOCCTL.7) */
446 lwz r4,0x84(r3) /* LOCTL is at offset 0x84 */
447 andi. r4,r4,0xff7f /* make bit 7 = 0 -- CS3 mode */
448 stw r4,0x84(r3) /* LOCTL is at offset 0x84 */
451 #ifdef CONFIG_DASA_SIM
452 /* use r4 as the working variable */
453 /* turn on MA17 (LOCCTL.7) */
454 lwz r4,0x84(r3) /* LOCTL is at offset 0x84 */
455 ori r4,r4,0x80 /* make bit 7 = 1 -- MA17 mode */
456 stw r4,0x84(r3) /* LOCTL is at offset 0x84 */
459 /* turn on MA16..13 (LCS0BRD.12 = 0) */
460 lwz r4,0x100(r3) /* LCS0BRD is at offset 0x100 */
461 andi. r4,r4,0xefff /* make bit 12 = 0 */
462 stw r4,0x100(r3) /* LCS0BRD is at offset 0x100 */
464 /* make sure above stores all comlete before going on */
467 /* last thing, set local init status done bit (DEVINIT.31) */
468 lwz r4,0x80(r3) /* DEVINIT is at offset 0x80 */
469 oris r4,r4,0x8000 /* make bit 31 = 1 */
470 stw r4,0x80(r3) /* DEVINIT is at offset 0x80 */
472 /* clear all pending interrupts and disable all interrupts */
473 li r4,-1 /* set p1 to 0xffffffff */
474 stw r4,0x1b0(r3) /* clear all pending interrupts */
475 stw r4,0x1b8(r3) /* clear all pending interrupts */
476 li r4,0 /* set r4 to 0 */
477 stw r4,0x1b4(r3) /* disable all interrupts */
478 stw r4,0x1bc(r3) /* disable all interrupts */
480 /* make sure above stores all comlete before going on */
483 /*----------------------------------------------------------------------- */
484 /* Enable two 128MB cachable regions. */
485 /*----------------------------------------------------------------------- */
488 mticcr r1 /* instruction cache */
492 mtdccr r1 /* data cache */
494 addis r1,r0,CFG_INIT_RAM_ADDR@h
495 ori r1,r1,CFG_INIT_SP_OFFSET /* set up the stack to SDRAM */
496 li r0, 0 /* Make room for stack frame header and */
497 stwu r0, -4(r1) /* clear final stack frame so that */
498 stwu r0, -4(r1) /* stack backtraces terminate cleanly */
500 GET_GOT /* initialize GOT access */
502 bl board_init_f /* run first part of init code (from Flash) */
504 #endif /* CONFIG_IOP480 */
506 /*****************************************************************************/
507 #if defined(CONFIG_405GP) || defined(CONFIG_405CR) || defined(CONFIG_405)
508 /*----------------------------------------------------------------------- */
509 /* Clear and set up some registers. */
510 /*----------------------------------------------------------------------- */
514 mtesr r4 /* clear Exception Syndrome Reg */
515 mttcr r4 /* clear Timer Control Reg */
516 mtxer r4 /* clear Fixed-Point Exception Reg */
517 mtevpr r4 /* clear Exception Vector Prefix Reg */
518 addi r4,r0,0x1000 /* set ME bit (Machine Exceptions) */
519 oris r4,r4,0x0002 /* set CE bit (Critical Exceptions) */
520 mtmsr r4 /* change MSR */
521 addi r4,r0,(0xFFFF-0x10000) /* set r4 to 0xFFFFFFFF (status in the */
522 /* dbsr is cleared by setting bits to 1) */
523 mtdbsr r4 /* clear/reset the dbsr */
525 /*----------------------------------------------------------------------- */
526 /* Invalidate I and D caches. Enable I cache for defined memory regions */
527 /* to speed things up. Leave the D cache disabled for now. It will be */
528 /* enabled/left disabled later based on user selected menu options. */
529 /* Be aware that the I cache may be disabled later based on the menu */
530 /* options as well. See miscLib/main.c. */
531 /*----------------------------------------------------------------------- */
535 /*----------------------------------------------------------------------- */
536 /* Enable two 128MB cachable regions. */
537 /*----------------------------------------------------------------------- */
540 mticcr r4 /* instruction cache */
545 mtdccr r4 /* data cache */
547 #if !(defined(CFG_EBC_PB0AP) && defined(CFG_EBC_PB0CR))
548 /*----------------------------------------------------------------------- */
549 /* Tune the speed and size for flash CS0 */
550 /*----------------------------------------------------------------------- */
551 bl ext_bus_cntlr_init
554 #if defined(CFG_OCM_DATA_ADDR) && defined(CFG_OCM_DATA_SIZE)
555 /********************************************************************
556 * Setup OCM - On Chip Memory
557 *******************************************************************/
561 mfdcr r3, ocmiscntl /* get instr-side IRAM config */
562 mfdcr r4, ocmdscntl /* get data-side IRAM config */
563 and r3, r3, r0 /* disable data-side IRAM */
564 and r4, r4, r0 /* disable data-side IRAM */
565 mtdcr ocmiscntl, r3 /* set instr-side IRAM config */
566 mtdcr ocmdscntl, r4 /* set data-side IRAM config */
569 addis r3, 0, CFG_OCM_DATA_ADDR@h /* OCM location */
571 addis r4, 0, 0xC000 /* OCM data area enabled */
576 /*----------------------------------------------------------------------- */
577 /* Setup temporary stack in DCACHE or OCM if needed for SDRAM SPD. */
578 /*----------------------------------------------------------------------- */
579 #ifdef CFG_INIT_DCACHE_CS
580 /*----------------------------------------------------------------------- */
581 /* Memory Bank x (nothingness) initialization 1GB+64MEG */
582 /* used as temporary stack pointer for stage0 */
583 /*----------------------------------------------------------------------- */
596 /* turn on data chache for this region */
600 /* set stack pointer and clear stack to known value */
602 lis r1,CFG_INIT_RAM_ADDR@h
603 ori r1,r1,CFG_INIT_SP_OFFSET@l
605 li r4,2048 /* we store 2048 words to stack */
608 lis r2,CFG_INIT_RAM_ADDR@h /* we also clear data area */
609 ori r2,r2,CFG_INIT_RAM_END@l /* so cant copy value from r1 */
611 lis r4,0xdead /* we store 0xdeaddead in the stack */
618 li r0, 0 /* Make room for stack frame header and */
619 stwu r0, -4(r1) /* clear final stack frame so that */
620 stwu r0, -4(r1) /* stack backtraces terminate cleanly */
622 * Set up a dummy frame to store reset vector as return address.
623 * this causes stack underflow to reset board.
625 stwu r1, -8(r1) /* Save back chain and move SP */
626 addis r0, 0, RESET_VECTOR@h /* Address of reset vector */
627 ori r0, r0, RESET_VECTOR@l
628 stwu r1, -8(r1) /* Save back chain and move SP */
629 stw r0, +12(r1) /* Save return addr (underflow vect) */
631 #elif defined(CFG_TEMP_STACK_OCM) && \
632 (defined(CFG_OCM_DATA_ADDR) && defined(CFG_OCM_DATA_SIZE))
637 /* Set up Stack at top of OCM */
638 lis r1, (CFG_INIT_RAM_ADDR + CFG_INIT_SP_OFFSET)@h
639 ori r1, r1, (CFG_INIT_RAM_ADDR + CFG_INIT_SP_OFFSET)@l
641 /* Set up a zeroized stack frame so that backtrace works right */
647 * Set up a dummy frame to store reset vector as return address.
648 * this causes stack underflow to reset board.
650 stwu r1, -8(r1) /* Save back chain and move SP */
651 lis r0, RESET_VECTOR@h /* Address of reset vector */
652 ori r0, r0, RESET_VECTOR@l
653 stwu r1, -8(r1) /* Save back chain and move SP */
654 stw r0, +12(r1) /* Save return addr (underflow vect) */
655 #endif /* CFG_INIT_DCACHE_CS */
657 /*----------------------------------------------------------------------- */
658 /* Initialize SDRAM Controller */
659 /*----------------------------------------------------------------------- */
663 * Setup temporary stack pointer only for boards
664 * that do not use SDRAM SPD I2C stuff since it
665 * is already initialized to use DCACHE or OCM
668 #if !(defined(CFG_INIT_DCACHE_CS) || defined(CFG_TEMP_STACK_OCM))
669 lis r1, CFG_INIT_RAM_ADDR@h
670 ori r1,r1,CFG_INIT_SP_OFFSET /* set up the stack in SDRAM */
672 li r0, 0 /* Make room for stack frame header and */
673 stwu r0, -4(r1) /* clear final stack frame so that */
674 stwu r0, -4(r1) /* stack backtraces terminate cleanly */
676 * Set up a dummy frame to store reset vector as return address.
677 * this causes stack underflow to reset board.
679 stwu r1, -8(r1) /* Save back chain and move SP */
680 lis r0, RESET_VECTOR@h /* Address of reset vector */
681 ori r0, r0, RESET_VECTOR@l
682 stwu r1, -8(r1) /* Save back chain and move SP */
683 stw r0, +12(r1) /* Save return addr (underflow vect) */
684 #endif /* !(CFG_INIT_DCACHE_CS || !CFG_TEM_STACK_OCM) */
686 GET_GOT /* initialize GOT access */
688 bl cpu_init_f /* run low-level CPU init code (from Flash) */
691 bl board_init_f /* run first part of init code (from Flash) */
693 #endif /* CONFIG_405GP || CONFIG_405CR */
696 .globl _start_of_vectors
700 /*TODO Fixup _start above so we can do this*/
701 /* Critical input. */
702 CRIT_EXCEPTION(0x100, CritcalInput, CritcalInputException)
706 STD_EXCEPTION(0x200, MachineCheck, MachineCheckException)
708 /* Data Storage exception. */
709 STD_EXCEPTION(0x300, DataStorage, UnknownException)
711 /* Instruction Storage exception. */
712 STD_EXCEPTION(0x400, InstStorage, UnknownException)
714 /* External Interrupt exception. */
715 STD_EXCEPTION(0x500, ExtInterrupt, external_interrupt)
717 /* Alignment exception. */
725 addi r3,r1,STACK_FRAME_OVERHEAD
727 rlwimi r20,r23,0,16,16 /* copy EE bit from saved MSR */
728 lwz r6,GOT(transfer_to_handler)
732 .long AlignmentException - _start + EXC_OFF_SYS_RESET
733 .long int_return - _start + EXC_OFF_SYS_RESET
735 /* Program check exception */
739 addi r3,r1,STACK_FRAME_OVERHEAD
741 rlwimi r20,r23,0,16,16 /* copy EE bit from saved MSR */
742 lwz r6,GOT(transfer_to_handler)
746 .long ProgramCheckException - _start + EXC_OFF_SYS_RESET
747 .long int_return - _start + EXC_OFF_SYS_RESET
749 /* No FPU on MPC8xx. This exception is not supposed to happen.
751 STD_EXCEPTION(0x800, FPUnavailable, UnknownException)
753 /* I guess we could implement decrementer, and may have
754 * to someday for timekeeping.
756 STD_EXCEPTION(0x900, Decrementer, timer_interrupt)
757 STD_EXCEPTION(0xa00, Trap_0a, UnknownException)
758 STD_EXCEPTION(0xb00, Trap_0b, UnknownException)
762 * r0 - SYSCALL number
766 addis r11,r0,0 /* get functions table addr */
767 ori r11,r11,0 /* Note: this code is patched in trap_init */
768 addis r12,r0,0 /* get number of functions */
774 rlwinm r0,r0,2,0,31 /* fn_addr = fn_tbl[r0] */
778 li r12,0xd00-4*3 /* save LR & SRRx */
786 li r12,0xc00+_back-SystemCall
795 mfmsr r11 /* Disable interrupts */
799 SYNC /* Some chip revs need this... */
803 li r12,0xd00-4*3 /* restore regs */
814 STD_EXCEPTION(0xd00, SingleStep, UnknownException)
816 STD_EXCEPTION(0xe00, Trap_0e, UnknownException)
817 STD_EXCEPTION(0xf00, Trap_0f, UnknownException)
819 /* On the MPC8xx, this is a software emulation interrupt. It occurs
820 * for all unimplemented and illegal instructions.
822 STD_EXCEPTION(0x1000, PIT, PITException)
824 STD_EXCEPTION(0x1100, InstructionTLBMiss, UnknownException)
825 STD_EXCEPTION(0x1200, DataTLBMiss, UnknownException)
826 STD_EXCEPTION(0x1300, InstructionTLBError, UnknownException)
827 STD_EXCEPTION(0x1400, DataTLBError, UnknownException)
829 STD_EXCEPTION(0x1500, Reserved5, UnknownException)
830 STD_EXCEPTION(0x1600, Reserved6, UnknownException)
831 STD_EXCEPTION(0x1700, Reserved7, UnknownException)
832 STD_EXCEPTION(0x1800, Reserved8, UnknownException)
833 STD_EXCEPTION(0x1900, Reserved9, UnknownException)
834 STD_EXCEPTION(0x1a00, ReservedA, UnknownException)
835 STD_EXCEPTION(0x1b00, ReservedB, UnknownException)
837 STD_EXCEPTION(0x1c00, DataBreakpoint, UnknownException)
838 STD_EXCEPTION(0x1d00, InstructionBreakpoint, UnknownException)
839 STD_EXCEPTION(0x1e00, PeripheralBreakpoint, UnknownException)
840 STD_EXCEPTION(0x1f00, DevPortBreakpoint, UnknownException)
842 CRIT_EXCEPTION(0x2000, DebugBreakpoint, DebugException )
844 .globl _end_of_vectors
851 * This code finishes saving the registers to the exception frame
852 * and jumps to the appropriate handler for the exception.
853 * Register r21 is pointer into trap frame, r1 has new stack pointer.
855 .globl transfer_to_handler
867 mfspr r23,SPRG3 /* if from user, fix up tss.regs */
869 addi r24,r1,STACK_FRAME_OVERHEAD
871 2: addi r2,r23,-TSS /* set r2 to current */
875 andi. r24,r23,0x3f00 /* get vector offset */
879 mtspr SPRG2,r22 /* r1 is now kernel sp */
881 addi r24,r2,TASK_STRUCT_SIZE /* check for kernel stack overflow */
885 bgt stack_ovf /* if r2 < r1 < r2+TASK_STRUCT_SIZE */
887 lwz r24,0(r23) /* virtual address of handler */
888 lwz r23,4(r23) /* where to go when done */
893 rfi /* jump to handler, enable MMU */
896 mfmsr r28 /* Disable interrupts */
900 SYNC /* Some chip revs need this... */
915 lwz r2,_NIP(r1) /* Restore environment */
926 mfmsr r28 /* Disable interrupts */
930 SYNC /* Some chip revs need this... */
945 lwz r2,_NIP(r1) /* Restore environment */
947 mtspr 990,r2 /* SRR2 */
948 mtspr 991,r0 /* SRR3 */
958 iccci r0,r0 /* for 405, iccci invalidates the */
959 blr /* entire I cache */
962 addi r6,0,0x0000 /* clear GPR 6 */
963 /* Do loop for # of dcache congruence classes. */
964 addi r7,r0, (CFG_DCACHE_SIZE / CFG_CACHELINE_SIZE / 2)
965 /* NOTE: dccci invalidates both */
966 mtctr r7 /* ways in the D cache */
968 dccci 0,r6 /* invalidate line */
969 addi r6,r6, CFG_CACHELINE_SIZE /* bump to next line */
974 addis r9,r0,0x0002 /* set mask for EE and CE msr bits */
976 mfmsr r12 /* save msr */
978 mtmsr r9 /* disable EE and CE */
979 addi r10,r0,0x0001 /* enable data cache for unused memory */
980 mfdccr r9 /* region 0xF8000000-0xFFFFFFFF via */
981 or r10,r10,r9 /* bit 31 in dccr */
984 /* do loop for # of congruence classes. */
985 addi r10,r0,(CFG_DCACHE_SIZE / CFG_CACHELINE_SIZE / 2)
986 addi r11,r0,(CFG_DCACHE_SIZE / 2) /* D cache set size - 2 way sets */
988 addi r10,r0,(0xE000-0x10000) /* start at 0xFFFFE000 */
989 add r11,r10,r11 /* add to get to other side of cache line */
991 lwz r3,0(r10) /* least recently used side */
992 lwz r3,0(r11) /* the other side */
993 dccci r0,r11 /* invalidate both sides */
994 addi r10,r10,CFG_CACHELINE_SIZE /* bump to next line */
995 addi r11,r11,CFG_CACHELINE_SIZE /* bump to next line */
996 bdnz ..flush_dcache_loop
997 sync /* allow memory access to complete */
998 mtdccr r9 /* restore dccr */
999 mtmsr r12 /* restore msr */
1002 .globl icache_enable
1005 bl invalidate_icache
1008 addis r3,r0, 0x8000 /* set bit 0 */
1012 .globl icache_disable
1014 addis r3,r0, 0x0000 /* clear bit 0 */
1019 .globl icache_status
1022 srwi r3, r3, 31 /* >>31 => select bit 0 */
1025 .globl dcache_enable
1028 bl invalidate_dcache
1031 addis r3,r0, 0x8000 /* set bit 0 */
1035 .globl dcache_disable
1040 addis r3,r0, 0x0000 /* clear bit 0 */
1044 .globl dcache_status
1047 srwi r3, r3, 31 /* >>31 => select bit 0 */
1055 #if !defined(CONFIG_440)
1067 /*------------------------------------------------------------------------------- */
1069 /* Description: Input 8 bits */
1070 /*------------------------------------------------------------------------------- */
1076 /*------------------------------------------------------------------------------- */
1077 /* Function: out8 */
1078 /* Description: Output 8 bits */
1079 /*------------------------------------------------------------------------------- */
1085 /*------------------------------------------------------------------------------- */
1086 /* Function: out16 */
1087 /* Description: Output 16 bits */
1088 /*------------------------------------------------------------------------------- */
1094 /*------------------------------------------------------------------------------- */
1095 /* Function: out16r */
1096 /* Description: Byte reverse and output 16 bits */
1097 /*------------------------------------------------------------------------------- */
1103 /*------------------------------------------------------------------------------- */
1104 /* Function: out32 */
1105 /* Description: Output 32 bits */
1106 /*------------------------------------------------------------------------------- */
1112 /*------------------------------------------------------------------------------- */
1113 /* Function: out32r */
1114 /* Description: Byte reverse and output 32 bits */
1115 /*------------------------------------------------------------------------------- */
1121 /*------------------------------------------------------------------------------- */
1122 /* Function: in16 */
1123 /* Description: Input 16 bits */
1124 /*------------------------------------------------------------------------------- */
1130 /*------------------------------------------------------------------------------- */
1131 /* Function: in16r */
1132 /* Description: Input 16 bits and byte reverse */
1133 /*------------------------------------------------------------------------------- */
1139 /*------------------------------------------------------------------------------- */
1140 /* Function: in32 */
1141 /* Description: Input 32 bits */
1142 /*------------------------------------------------------------------------------- */
1148 /*------------------------------------------------------------------------------- */
1149 /* Function: in32r */
1150 /* Description: Input 32 bits and byte reverse */
1151 /*------------------------------------------------------------------------------- */
1157 /*------------------------------------------------------------------------------- */
1158 /* Function: ppcDcbf */
1159 /* Description: Data Cache block flush */
1160 /* Input: r3 = effective address */
1162 /*------------------------------------------------------------------------------- */
1168 /*------------------------------------------------------------------------------- */
1169 /* Function: ppcDcbi */
1170 /* Description: Data Cache block Invalidate */
1171 /* Input: r3 = effective address */
1173 /*------------------------------------------------------------------------------- */
1179 /*------------------------------------------------------------------------------- */
1180 /* Function: ppcSync */
1181 /* Description: Processor Synchronize */
1184 /*------------------------------------------------------------------------------- */
1190 /*------------------------------------------------------------------------------*/
1193 * void relocate_code (addr_sp, gd, addr_moni)
1195 * This "function" does not return, instead it continues in RAM
1196 * after relocating the monitor code.
1200 * r5 = length in bytes
1201 * r6 = cachelinesize
1203 .globl relocate_code
1205 mr r1, r3 /* Set new stack pointer */
1206 mr r9, r4 /* Save copy of Init Data pointer */
1207 mr r10, r5 /* Save copy of Destination Address */
1209 mr r3, r5 /* Destination Address */
1210 lis r4, CFG_MONITOR_BASE@h /* Source Address */
1211 ori r4, r4, CFG_MONITOR_BASE@l
1212 lis r5, CFG_MONITOR_LEN@h /* Length in Bytes */
1213 ori r5, r5, CFG_MONITOR_LEN@l
1214 li r6, CFG_CACHELINE_SIZE /* Cache Line Size */
1219 * New GOT-PTR = (old GOT-PTR - CFG_MONITOR_BASE) + Destination Address
1225 /* First our own GOT */
1227 /* the the one used by the C code */
1237 beq cr1,4f /* In place copy is not necessary */
1238 beq 7f /* Protect against 0 count */
1257 * Now flush the cache: note that we must start from a cache aligned
1258 * address. Otherwise we might miss one cache line.
1262 beq 7f /* Always flush prefetch queue in any case */
1270 sync /* Wait for all dcbst to complete on bus */
1276 7: sync /* Wait for all icbi to complete on bus */
1280 * We are done. Do not return, instead branch to second part of board
1281 * initialization, now running from RAM.
1284 addi r0, r10, in_ram - _start + EXC_OFF_SYS_RESET
1286 blr /* NEVER RETURNS! */
1291 * Relocation Function, r14 point to got2+0x8000
1293 * Adjust got2 pointers, no need to check for 0, this code
1294 * already puts a few entries in the table.
1296 li r0,__got2_entries@sectoff@l
1297 la r3,GOT(_GOT2_TABLE_)
1298 lwz r11,GOT(_GOT2_TABLE_)
1308 * Now adjust the fixups and the pointers to the fixups
1309 * in case we need to move ourselves again.
1311 2: li r0,__fixup_entries@sectoff@l
1312 lwz r3,GOT(_FIXUP_TABLE_)
1326 * Now clear BSS segment
1342 mr r3, r9 /* Init Data pointer */
1343 mr r4, r10 /* Destination Address */
1346 /* Problems accessing "end" in C, so do it here */
1353 * Copy exception vector code to low memory
1356 * r7: source address, r8: end address, r9: target address
1361 lwz r8, GOT(_end_of_vectors)
1363 rlwinm r9, r7, 0, 18, 31 /* _start & 0x3FFF */
1366 bgelr /* return if r7>=r8 - just in case */
1368 mflr r4 /* save link register */
1378 * relocate `hdlr' and `int_return' entries
1380 li r7, .L_MachineCheck - _start + EXC_OFF_SYS_RESET
1381 li r8, Alignment - _start + EXC_OFF_SYS_RESET
1384 addi r7, r7, 0x100 /* next exception vector */
1388 li r7, .L_Alignment - _start + EXC_OFF_SYS_RESET
1391 li r7, .L_ProgramCheck - _start + EXC_OFF_SYS_RESET
1394 li r7, .L_FPUnavailable - _start + EXC_OFF_SYS_RESET
1395 li r8, SystemCall - _start + EXC_OFF_SYS_RESET
1398 addi r7, r7, 0x100 /* next exception vector */
1402 li r7, .L_SingleStep - _start + EXC_OFF_SYS_RESET
1403 li r8, _end_of_vectors - _start + EXC_OFF_SYS_RESET
1406 addi r7, r7, 0x100 /* next exception vector */
1410 mtlr r4 /* restore link register */
1414 * Function: relocate entries for one exception vector
1417 lwz r0, 0(r7) /* hdlr ... */
1418 add r0, r0, r3 /* ... += dest_addr */
1421 lwz r0, 4(r7) /* int_return ... */
1422 add r0, r0, r3 /* ... += dest_addr */