blob: b2baf02ebfdf7dc0dec3912094a1f744c12073dd [file] [log] [blame]
wdenk42d1f032003-10-15 23:53:47 +00001/*
2 * Copyright (C) 2003 Motorola,Inc.
3 * Xianghua Xiao<X.Xiao@motorola.com>
4 *
5 * See file CREDITS for list of people who contributed to this
6 * project.
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License as
10 * published by the Free Software Foundation; either version 2 of
11 * the License, or (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
21 * MA 02111-1307 USA
22 */
23
24/* U-Boot Startup Code for Motorola 85xx PowerPC based Embedded Boards
25 *
26 * The processor starts at 0xfffffffc and the code is first executed in the
27 * last 4K page(0xfffff000-0xffffffff) in flash/rom.
28 *
29 */
30
31#include <config.h>
32#include <mpc85xx.h>
33#include <version.h>
34
35#define _LINUX_CONFIG_H 1 /* avoid reading Linux autoconf.h file */
36
37#include <ppc_asm.tmpl>
38#include <ppc_defs.h>
39
40#include <asm/cache.h>
41#include <asm/mmu.h>
42
43#ifndef CONFIG_IDENT_STRING
44#define CONFIG_IDENT_STRING ""
45#endif
46
47#undef MSR_KERNEL
48#define MSR_KERNEL ( MSR_ME ) /* Machine Check */
49
50/*
51 * Set up GOT: Global Offset Table
52 *
53 * Use r14 to access the GOT
54 */
55 START_GOT
56 GOT_ENTRY(_GOT2_TABLE_)
57 GOT_ENTRY(_FIXUP_TABLE_)
58
59 GOT_ENTRY(_start)
60 GOT_ENTRY(_start_of_vectors)
61 GOT_ENTRY(_end_of_vectors)
62 GOT_ENTRY(transfer_to_handler)
63
64 GOT_ENTRY(__init_end)
65 GOT_ENTRY(_end)
66 GOT_ENTRY(__bss_start)
67 END_GOT
68
69/*
70 * e500 Startup -- after reset only the last 4KB of the effective
71 * address space is mapped in the MMU L2 TLB1 Entry0. The .bootpg
72 * section is located at THIS LAST page and basically does three
73 * things: clear some registers, set up exception tables and
74 * add more TLB entries for 'larger spaces'(e.g. the boot rom) to
75 * continue the boot procedure.
76
77 * Once the boot rom is mapped by TLB entries we can proceed
78 * with normal startup.
79 *
80 */
81
82 .section .bootpg,"ax"
83 .globl _start_e500
84
85_start_e500:
86#if defined(CONFIG_MPC85xx_REV1)
87 li r0,0x2000
88 mtspr 977,r0
89#endif
90
91 /* Clear and set up some registers. Note: Some registers need strict
92 * synchronization by sync/mbar/msync/isync when being "mtspr".
93 * BookE: isync before PID,tlbivax,tlbwe
94 * BookE: isync after MSR,PID; msync_isync after tlbivax & tlbwe
95 * E500: msync,isync before L1CSR0
96 * E500: isync after BBEAR,BBTAR,BUCSR,DBCR0,DBCR1,HID0,HID1,L1CSR0
97 * L1CSR1, MAS[0,1,2,3,4,6],MMUCSR0, PID[0,1,2],SPEFCSR
98 */
99
100 /* invalidate d-cache */
101 mfspr r0,L1CSR0
102 ori r0,r0,0x0002
103 msync
104 isync
105 mtspr L1CSR0,r0
106 isync
107
108 /* disable d-cache */
109 li r0,0x0
110 mtspr L1CSR0,r0
111 isync
112
113 /* invalidate i-cache */
114 mfspr r0,L1CSR1
115 ori r0,r0,0x0002
116 mtspr L1CSR1,r0
117 isync
118
119 /* disable i-cache */
120 li r0,0x0
121 mtspr L1CSR1,r0
122 isync
123
124 /* clear registers */
125 sync
126 li r0,0
127 mtspr SRR0,r0
128 mtspr SRR1,r0
129 mtspr CSRR0,r0
130 mtspr CSRR1,r0
131 mtspr MCSRR0,r0
132 mtspr MCSRR1,r0
133
134 mtspr ESR,r0
135 mtspr MCSR,r0
136 mtspr DEAR,r0
137
138 mtspr DBCR0,r0
139 isync
140 mtspr DBCR1,r0
141 isync
142 mtspr DBCR2,r0
143 isync
144 mtspr IAC1,r0
145 mtspr IAC2,r0
146 mtspr DAC1,r0
147 mtspr DAC2,r0
148
149 mfspr r1,DBSR
150 mtspr DBSR,r1 /* Clear all valid bits */
151
152 isync
153 mtspr PID0,r0
154 isync
155 mtspr PID1,r0
156 isync
157 mtspr PID2,r0
158 isync
159
160 mtspr TCR,r0
161
162 mtspr BUCSR,r0 /* disable branch prediction */
163 isync
164
165 mtspr HID0,r0
166 isync
167 mtspr HID1,r0
168 isync
169
170 mtspr MAS4,r0
171 isync
172 mtspr MAS6,r0
173 isync
174
175 /* Setup interrupt vectors */
176 mtspr IVPR, r0
177
178 li r1,0x0100
179 mtspr IVOR0,r1 /* 0: Critical input */
180 li r1,0x0200
181 mtspr IVOR1,r1 /* 1: Machine check */
182 li r1,0x0300
183 mtspr IVOR2,r1 /* 2: Data storage */
184 li r1,0x0400
185 mtspr IVOR3,r1 /* 3: Instruction storage */
186 li r1,0x0500
187 mtspr IVOR4,r1 /* 4: External interrupt */
188 li r1,0x0600
189 mtspr IVOR5,r1 /* 5: Alignment */
190 li r1,0x0700
191 mtspr IVOR6,r1 /* 6: Program check */
192 li r1,0x0800
193 mtspr IVOR7,r1 /* 7: floating point unavailable */
194 li r1,0x0c00
195 mtspr IVOR8,r1 /* 8: System call */
196 /* 9: Auxiliary processor unavailable(unsupported) */
197 li r1,0x1000
198 mtspr IVOR10,r1 /* 10: Decrementer */
199 li r1,0x1400
200 mtspr IVOR13,r1 /* 13: Data TLB error */
201 li r1,0x1300
202 mtspr IVOR14,r1 /* 14: Instruction TLB error */
203 li r1,0x2000
204 mtspr IVOR15,r1 /* 15: Debug */
205
206 /* invalidate MMU L1/L2 */
207 /* Note: before invalidate MMU L1/L2, we read TLB1 Entry 0 and then
208 * write it back immediately to fixup a bug(Errata CPU4) for this initial
209 * TLB1 entry 0,otherwise the TLB1 entry 0 will be invalidated.
210 */
211#if defined(CONFIG_MPC85xx_REV1)
212 lis r2,0x1000
213 mtspr MAS0,r2
214 tlbre
215 tlbwe
216 isync
217 li r2, 0x001e
218 mtspr MMUCSR0, r2
219 isync
220#endif
221
222 /* After reset, CCSRBAR is located at CFG_CCSRBAR_DEFAULT, i.e.
223 * 0xff700000-0xff800000. We need add a TLB1 entry for this 1MB
224 * region before we can access any CCSR registers such as L2
225 * registers, Local Access Registers,etc. We will also re-allocate
226 * CFG_CCSRBAR_DEFAULT to CFG_CCSRBAR immediately after TLB1 setup.
227 *
228 * Please refer to board-specif directory for TLB1 entry configuration.
229 * (e.g. board/<yourboard>/init.S)
230 *
231 */
232 bl tlb1_entry
233 mr r5,r0
234 li r1,0x000f /* max 16 TLB1 entries */
235 mtctr r1
236 lwzu r4,0(r5) /* how many TLB1 entries we actually use */
237
2380: cmpwi r4,0
239 beq 1f
240 lwzu r0,4(r5)
241 lwzu r1,4(r5)
242 lwzu r2,4(r5)
243 lwzu r3,4(r5)
244 mtspr MAS0,r0
245 mtspr MAS1,r1
246 mtspr MAS2,r2
247 mtspr MAS3,r3
248 isync
249 msync
250 tlbwe
251 isync
252 addi r4,r4,-1
253 bdnz 0b
254
2551:
256#if (CFG_CCSRBAR_DEFAULT != CFG_CCSRBAR)
257 /* Special sequence needed to update CCSRBAR itself */
258 lis r4, CFG_CCSRBAR_DEFAULT@h
259 ori r4, r4, CFG_CCSRBAR_DEFAULT@l
260
261 lis r5, CFG_CCSRBAR@h
262 ori r5, r5, CFG_CCSRBAR@l
263 srwi r6,r5,12
264 stw r6, 0(r4)
265 isync
266
267 lis r5, 0xffff
268 ori r5,r5,0xf000
269 lwz r5, 0(r5)
270 isync
271
272 lis r3, CFG_CCSRBAR@h
273 lwz r5, CFG_CCSRBAR@l(r3)
274 isync
275#endif
276
277 /* invalidate all TLB0 entries */
278 li r3,4
279 li r4,0
280 tlbivax r4,r3
281#if defined(CONFIG_MPC85xx_REV1) /* Errata CPU6 */
282 nop
283#endif
284
285 /* set up local access windows, defined at board/<boardname>/init.S */
286 lis r7,CFG_CCSRBAR@h
287 ori r7,r7,CFG_CCSRBAR@l
288
289 bl law_entry
290 mr r6,r0
291#if defined(CONFIG_RAM_AS_FLASH)
292 li r1,0x0006
293#else
294 li r1,0x0007 /*we have 8 LAWs, but reseve one for boot-over-rio-or-pci */
295#endif
296 mtctr r1
297 lwzu r5,0(r6) /* how many windows we actually use */
298
299#if defined(CONFIG_RAM_AS_FLASH)
300 li r2,0x0c48
301 li r1,0x0c50
302#else
303 li r2,0x0c28 /* the first pair is reserved for boot-over-rio-or-pci */
304 li r1,0x0c30
305#endif
306
3070: cmpwi r5,0
308 beq 1f
309 lwzu r4,4(r6)
310 lwzu r3,4(r6)
311 stwx r4,r7,r2
312 stwx r3,r7,r1
313 addi r5,r5,-1
314 addi r2,r2,0x0020
315 addi r1,r1,0x0020
316 bdnz 0b
317
318 /* Jump out the last 4K page and continue to 'normal' start */
3191: bl 3f
320 b _start
321
3223: li r0,0
323 mtspr SRR1,r0 /* Keep things disabled for now */
324 mflr r1
325 mtspr SRR0,r1
326 rfi
327
328/*
329 * r3 - 1st arg to board_init(): IMMP pointer
330 * r4 - 2nd arg to board_init(): boot flag
331 */
332 .text
333 .long 0x27051956 /* U-BOOT Magic Number */
334 .globl version_string
335version_string:
336 .ascii U_BOOT_VERSION
337 .ascii " (", __DATE__, " - ", __TIME__, ")"
338 .ascii CONFIG_IDENT_STRING, "\0"
339
340 . = EXC_OFF_SYS_RESET
341 .globl _start
342_start:
343 /* Clear and set up some registers. */
344 li r0,0x0000
345 lis r1,0xffff
346 mtspr DEC,r0 /* prevent dec exceptions */
347 mttbl r0 /* prevent fit & wdt exceptions */
348 mttbu r0
349 mtspr TSR,r1 /* clear all timer exception status */
350 mtspr TCR,r0 /* disable all */
351 mtspr ESR,r0 /* clear exception syndrome register */
352 mtspr MCSR,r0 /* machine check syndrome register */
353 mtxer r0 /* clear integer exception register */
354 lis r1,0x0002 /* set CE bit (Critical Exceptions) */
355 ori r1,r1,0x1200 /* set ME/DE bit */
356 mtmsr r1 /* change MSR */
357 isync
358
359 /* Enable Time Base and Select Time Base Clock */
360 li r0,0x4000 /* time base is processor clock */
361 mtspr HID0,r0
362 isync
363
364#if defined(CONFIG_ADDR_STREAMING)
wdenka57a4962003-10-26 22:52:58 +0000365 li r0,0x3000
366#else
367 li r0,0x1000
368#endif
wdenk42d1f032003-10-15 23:53:47 +0000369 mtspr HID1,r0
370 isync
wdenk42d1f032003-10-15 23:53:47 +0000371
372 /* Enable Branch Prediction */
373#if defined(CONFIG_BTB)
374 li r0,0x201 /* BBFI = 1, BPEN = 1 */
375 mtspr BUCSR,r0
376 isync
377#endif
378
379#if defined(CFG_INIT_DBCR)
380 lis r1,0xffff
381 ori r1,r1,0xffff
382 mtspr dbsr,r1 /* Clear all status bits */
383 lis r0,CFG_INIT_DBCR@h /* DBCR0[IDM] must be set */
384 ori r0,r0,CFG_INIT_DBCR@l
385 mtspr dbcr0,r0
386 isync
387#endif
388
389/* L1 DCache is used for initial RAM */
390 mfspr r2, L1CSR0
391 ori r2, r2, 0x0003
392 oris r2, r2, 0x0001
393 msync
394 isync
395 mtspr L1CSR0, r2 /* enable/invalidate L1 Dcache */
396 isync
397
398 /* Allocate Initial RAM in data cache.
399 */
400 lis r3, CFG_INIT_RAM_ADDR@h
401 ori r3, r3, CFG_INIT_RAM_ADDR@l
402 li r2, 512 /* 512*32=16K */
403 mtctr r2
404 li r0, 0
4051:
406 dcbz r0, r3
407 dcbtls 0,r0, r3
408 addi r3, r3, 32
409 bdnz 1b
410
411#ifndef CFG_RAMBOOT
412 /* Calculate absolute address in FLASH and jump there */
413 /*--------------------------------------------------------------*/
414 lis r3, CFG_MONITOR_BASE@h
415 ori r3, r3, CFG_MONITOR_BASE@l
416 addi r3, r3, in_flash - _start + EXC_OFF_SYS_RESET
417 mtlr r3
418 blr
419
420in_flash:
421#endif /* CFG_RAMBOOT */
422
423 /* Setup the stack in initial RAM,could be L2-as-SRAM or L1 dcache*/
424 lis r1,CFG_INIT_RAM_ADDR@h
425 ori r1,r1,CFG_INIT_SP_OFFSET@l
426
427 li r0,0
428 stwu r0,-4(r1)
429 stwu r0,-4(r1) /* Terminate call chain */
430
431 stwu r1,-8(r1) /* Save back chain and move SP */
432 lis r0,RESET_VECTOR@h /* Address of reset vector */
433 ori r0,r0, RESET_VECTOR@l
434 stwu r1,-8(r1) /* Save back chain and move SP */
435 stw r0,+12(r1) /* Save return addr (underflow vect) */
436
437 GET_GOT
438 bl cpu_init_f
439 bl icache_enable
440 bl board_init_f
441 sync
442
443
444/* --FIXME-- machine check with MCSRRn and rfmci */
445
446 .globl _start_of_vectors
447_start_of_vectors:
448#if 0
449/* Critical input. */
450 CRIT_EXCEPTION(0x0100, CritcalInput, CritcalInputException)
451#endif
452/* Machine check --FIXME-- Should be MACH_EXCEPTION */
453 CRIT_EXCEPTION(0x0200, MachineCheck, MachineCheckException)
454
455/* Data Storage exception. */
456 STD_EXCEPTION(0x0300, DataStorage, UnknownException)
457
458/* Instruction Storage exception. */
459 STD_EXCEPTION(0x0400, InstStorage, UnknownException)
460
461/* External Interrupt exception. */
462 STD_EXCEPTION(0x0500, ExtInterrupt, UnknownException)
463
464/* Alignment exception. */
465 . = 0x0600
466Alignment:
467 EXCEPTION_PROLOG
468 mfspr r4,DAR
469 stw r4,_DAR(r21)
470 mfspr r5,DSISR
471 stw r5,_DSISR(r21)
472 addi r3,r1,STACK_FRAME_OVERHEAD
473 li r20,MSR_KERNEL
474 rlwimi r20,r23,0,16,16 /* copy EE bit from saved MSR */
475 lwz r6,GOT(transfer_to_handler)
476 mtlr r6
477 blrl
478.L_Alignment:
479 .long AlignmentException - _start + EXC_OFF_SYS_RESET
480 .long int_return - _start + EXC_OFF_SYS_RESET
481
482/* Program check exception */
483 . = 0x0700
484ProgramCheck:
485 EXCEPTION_PROLOG
486 addi r3,r1,STACK_FRAME_OVERHEAD
487 li r20,MSR_KERNEL
488 rlwimi r20,r23,0,16,16 /* copy EE bit from saved MSR */
489 lwz r6,GOT(transfer_to_handler)
490 mtlr r6
491 blrl
492.L_ProgramCheck:
493 .long ProgramCheckException - _start + EXC_OFF_SYS_RESET
494 .long int_return - _start + EXC_OFF_SYS_RESET
495
496 /* No FPU on MPC85xx. This exception is not supposed to happen.
497 */
498 STD_EXCEPTION(0x0800, FPUnavailable, UnknownException)
499 STD_EXCEPTION(0x0900, Decrementer, timer_interrupt)
500 STD_EXCEPTION(0x0a00, Trap_0a, UnknownException)
501 STD_EXCEPTION(0x0b00, Trap_0b, UnknownException)
502
503 . = 0x0c00
504/*
505 * r0 - SYSCALL number
506 * r3-... arguments
507 */
508SystemCall:
509 addis r11,r0,0 /* get functions table addr */
510 ori r11,r11,0 /* Note: this code is patched in trap_init */
511 addis r12,r0,0 /* get number of functions */
512 ori r12,r12,0
513
514 cmplw 0, r0, r12
515 bge 1f
516
517 rlwinm r0,r0,2,0,31 /* fn_addr = fn_tbl[r0] */
518 add r11,r11,r0
519 lwz r11,0(r11)
520
521 li r20,0xd00-4 /* Get stack pointer */
522 lwz r12,0(r20)
523 subi r12,r12,12 /* Adjust stack pointer */
524 li r0,0xc00+_end_back-SystemCall
525 cmplw 0, r0, r12 /* Check stack overflow */
526 bgt 1f
527 stw r12,0(r20)
528
529 mflr r0
530 stw r0,0(r12)
531 mfspr r0,SRR0
532 stw r0,4(r12)
533 mfspr r0,SRR1
534 stw r0,8(r12)
535
536 li r12,0xc00+_back-SystemCall
537 mtlr r12
538 mtspr SRR0,r11
539
5401: SYNC
541 rfi
542_back:
543
544 mfmsr r11 /* Disable interrupts */
545 li r12,0
546 ori r12,r12,MSR_EE
547 andc r11,r11,r12
548 SYNC /* Some chip revs need this... */
549 mtmsr r11
550 SYNC
551
552 li r12,0xd00-4 /* restore regs */
553 lwz r12,0(r12)
554
555 lwz r11,0(r12)
556 mtlr r11
557 lwz r11,4(r12)
558 mtspr SRR0,r11
559 lwz r11,8(r12)
560 mtspr SRR1,r11
561
562 addi r12,r12,12 /* Adjust stack pointer */
563 li r20,0xd00-4
564 stw r12,0(r20)
565
566 SYNC
567 rfi
568_end_back:
569
570 STD_EXCEPTION(0xd00, SingleStep, UnknownException)
571
572 STD_EXCEPTION(0xe00, Trap_0e, UnknownException)
573 STD_EXCEPTION(0xf00, Trap_0f, UnknownException)
574
575 STD_EXCEPTION(0x1000, PIT, PITException)
576
577 STD_EXCEPTION(0x1100, InstructionTLBMiss, UnknownException)
578 STD_EXCEPTION(0x1200, DataTLBMiss, UnknownException)
579 STD_EXCEPTION(0x1300, InstructionTLBError, UnknownException)
580 STD_EXCEPTION(0x1400, DataTLBError, UnknownException)
581
582 STD_EXCEPTION(0x1500, Reserved5, UnknownException)
583 STD_EXCEPTION(0x1600, Reserved6, UnknownException)
584 STD_EXCEPTION(0x1700, Reserved7, UnknownException)
585 STD_EXCEPTION(0x1800, Reserved8, UnknownException)
586 STD_EXCEPTION(0x1900, Reserved9, UnknownException)
587 STD_EXCEPTION(0x1a00, ReservedA, UnknownException)
588 STD_EXCEPTION(0x1b00, ReservedB, UnknownException)
589
590 STD_EXCEPTION(0x1c00, DataBreakpoint, UnknownException)
591 STD_EXCEPTION(0x1d00, InstructionBreakpoint, UnknownException)
592 STD_EXCEPTION(0x1e00, PeripheralBreakpoint, UnknownException)
593 STD_EXCEPTION(0x1f00, DevPortBreakpoint, UnknownException)
594
595 CRIT_EXCEPTION(0x2000, DebugBreakpoint, DebugException )
596
597 .globl _end_of_vectors
598_end_of_vectors:
599
600
601 . = 0x2100
602
603/*
604 * This code finishes saving the registers to the exception frame
605 * and jumps to the appropriate handler for the exception.
606 * Register r21 is pointer into trap frame, r1 has new stack pointer.
607 */
608 .globl transfer_to_handler
609transfer_to_handler:
610 stw r22,_NIP(r21)
611 lis r22,MSR_POW@h
612 andc r23,r23,r22
613 stw r23,_MSR(r21)
614 SAVE_GPR(7, r21)
615 SAVE_4GPRS(8, r21)
616 SAVE_8GPRS(12, r21)
617 SAVE_8GPRS(24, r21)
618
619 mflr r23
620 andi. r24,r23,0x3f00 /* get vector offset */
621 stw r24,TRAP(r21)
622 li r22,0
623 stw r22,RESULT(r21)
624 mtspr SPRG2,r22 /* r1 is now kernel sp */
625
626 lwz r24,0(r23) /* virtual address of handler */
627 lwz r23,4(r23) /* where to go when done */
628 mtspr SRR0,r24
629 mtspr SRR1,r20
630 mtlr r23
631 SYNC
632 rfi /* jump to handler, enable MMU */
633
634int_return:
635 mfmsr r28 /* Disable interrupts */
636 li r4,0
637 ori r4,r4,MSR_EE
638 andc r28,r28,r4
639 SYNC /* Some chip revs need this... */
640 mtmsr r28
641 SYNC
642 lwz r2,_CTR(r1)
643 lwz r0,_LINK(r1)
644 mtctr r2
645 mtlr r0
646 lwz r2,_XER(r1)
647 lwz r0,_CCR(r1)
648 mtspr XER,r2
649 mtcrf 0xFF,r0
650 REST_10GPRS(3, r1)
651 REST_10GPRS(13, r1)
652 REST_8GPRS(23, r1)
653 REST_GPR(31, r1)
654 lwz r2,_NIP(r1) /* Restore environment */
655 lwz r0,_MSR(r1)
656 mtspr SRR0,r2
657 mtspr SRR1,r0
658 lwz r0,GPR0(r1)
659 lwz r2,GPR2(r1)
660 lwz r1,GPR1(r1)
661 SYNC
662 rfi
663
664crit_return:
665 mfmsr r28 /* Disable interrupts */
666 li r4,0
667 ori r4,r4,MSR_EE
668 andc r28,r28,r4
669 SYNC /* Some chip revs need this... */
670 mtmsr r28
671 SYNC
672 lwz r2,_CTR(r1)
673 lwz r0,_LINK(r1)
674 mtctr r2
675 mtlr r0
676 lwz r2,_XER(r1)
677 lwz r0,_CCR(r1)
678 mtspr XER,r2
679 mtcrf 0xFF,r0
680 REST_10GPRS(3, r1)
681 REST_10GPRS(13, r1)
682 REST_8GPRS(23, r1)
683 REST_GPR(31, r1)
684 lwz r2,_NIP(r1) /* Restore environment */
685 lwz r0,_MSR(r1)
686 mtspr 990,r2 /* SRR2 */
687 mtspr 991,r0 /* SRR3 */
688 lwz r0,GPR0(r1)
689 lwz r2,GPR2(r1)
690 lwz r1,GPR1(r1)
691 SYNC
692 rfci
693
694/* Cache functions.
695*/
696invalidate_icache:
697 mfspr r0,L1CSR1
698 ori r0,r0,0x0002
699 mtspr L1CSR1,r0
700 isync
701 blr /* entire I cache */
702
703invalidate_dcache:
704 mfspr r0,L1CSR0
705 ori r0,r0,0x0002
706 msync
707 isync
708 mtspr L1CSR0,r0
709 isync
710 blr
711
712 .globl icache_enable
713icache_enable:
714 mflr r8
715 bl invalidate_icache
716 mtlr r8
717 isync
718 mfspr r4,L1CSR1
719 ori r4,r4,0x0001
720 oris r4,r4,0x0001
721 mtspr L1CSR1,r4
722 isync
723 blr
724
725 .globl icache_disable
726icache_disable:
727 mfspr r0,L1CSR1
728 lis r1,0xfffffffe@h
729 ori r1,r1,0xfffffffe@l
730 and r0,r0,r1
731 mtspr L1CSR1,r0
732 isync
733 blr
734
735 .globl icache_status
736icache_status:
737 mfspr r3,L1CSR1
738 srwi r3, r3, 31 /* >>31 => select bit 0 */
739 blr
740
741 .globl dcache_enable
742dcache_enable:
743 mflr r8
744 bl invalidate_dcache
745 mtlr r8
746 isync
747 mfspr r0,L1CSR0
748 ori r0,r0,0x0001
749 oris r0,r0,0x0001
750 msync
751 isync
752 mtspr L1CSR0,r0
753 isync
754 blr
755
756 .globl dcache_disable
757dcache_disable:
758 mfspr r0,L1CSR0
759 lis r1,0xfffffffe@h
760 ori r1,r1,0xfffffffe@l
761 and r0,r0,r1
762 msync
763 isync
764 mtspr L1CSR0,r0
765 isync
766 blr
767
768 .globl dcache_status
769dcache_status:
770 mfspr r3,L1CSR0
771 srwi r3, r3, 31 /* >>31 => select bit 0 */
772 blr
773
774 .globl get_pir
775get_pir:
776 mfspr r3, PIR
777 blr
778
779 .globl get_pvr
780get_pvr:
781 mfspr r3, PVR
782 blr
783
784 .globl wr_tcr
785wr_tcr:
786 mtspr TCR, r3
787 blr
788
789/*------------------------------------------------------------------------------- */
790/* Function: in8 */
791/* Description: Input 8 bits */
792/*------------------------------------------------------------------------------- */
793 .globl in8
794in8:
795 lbz r3,0x0000(r3)
796 blr
797
798/*------------------------------------------------------------------------------- */
799/* Function: out8 */
800/* Description: Output 8 bits */
801/*------------------------------------------------------------------------------- */
802 .globl out8
803out8:
804 stb r4,0x0000(r3)
805 blr
806
807/*------------------------------------------------------------------------------- */
808/* Function: out16 */
809/* Description: Output 16 bits */
810/*------------------------------------------------------------------------------- */
811 .globl out16
812out16:
813 sth r4,0x0000(r3)
814 blr
815
816/*------------------------------------------------------------------------------- */
817/* Function: out16r */
818/* Description: Byte reverse and output 16 bits */
819/*------------------------------------------------------------------------------- */
820 .globl out16r
821out16r:
822 sthbrx r4,r0,r3
823 blr
824
825/*------------------------------------------------------------------------------- */
826/* Function: out32 */
827/* Description: Output 32 bits */
828/*------------------------------------------------------------------------------- */
829 .globl out32
830out32:
831 stw r4,0x0000(r3)
832 blr
833
834/*------------------------------------------------------------------------------- */
835/* Function: out32r */
836/* Description: Byte reverse and output 32 bits */
837/*------------------------------------------------------------------------------- */
838 .globl out32r
839out32r:
840 stwbrx r4,r0,r3
841 blr
842
843/*------------------------------------------------------------------------------- */
844/* Function: in16 */
845/* Description: Input 16 bits */
846/*------------------------------------------------------------------------------- */
847 .globl in16
848in16:
849 lhz r3,0x0000(r3)
850 blr
851
852/*------------------------------------------------------------------------------- */
853/* Function: in16r */
854/* Description: Input 16 bits and byte reverse */
855/*------------------------------------------------------------------------------- */
856 .globl in16r
857in16r:
858 lhbrx r3,r0,r3
859 blr
860
861/*------------------------------------------------------------------------------- */
862/* Function: in32 */
863/* Description: Input 32 bits */
864/*------------------------------------------------------------------------------- */
865 .globl in32
866in32:
867 lwz 3,0x0000(3)
868 blr
869
870/*------------------------------------------------------------------------------- */
871/* Function: in32r */
872/* Description: Input 32 bits and byte reverse */
873/*------------------------------------------------------------------------------- */
874 .globl in32r
875in32r:
876 lwbrx r3,r0,r3
877 blr
878
879/*------------------------------------------------------------------------------- */
880/* Function: ppcDcbf */
881/* Description: Data Cache block flush */
882/* Input: r3 = effective address */
883/* Output: none. */
884/*------------------------------------------------------------------------------- */
885 .globl ppcDcbf
886ppcDcbf:
887 dcbf r0,r3
888 blr
889
890/*------------------------------------------------------------------------------- */
891/* Function: ppcDcbi */
892/* Description: Data Cache block Invalidate */
893/* Input: r3 = effective address */
894/* Output: none. */
895/*------------------------------------------------------------------------------- */
896 .globl ppcDcbi
897ppcDcbi:
898 dcbi r0,r3
899 blr
900
901/*------------------------------------------------------------------------------- */
902/* Function: ppcSync */
903/* Description: Processor Synchronize */
904/* Input: none. */
905/* Output: none. */
906/*------------------------------------------------------------------------------- */
907 .globl ppcSync
908ppcSync:
909 sync
910 blr
911
912/*------------------------------------------------------------------------------*/
913
914/*
915 * void relocate_code (addr_sp, gd, addr_moni)
916 *
917 * This "function" does not return, instead it continues in RAM
918 * after relocating the monitor code.
919 *
920 * r3 = dest
921 * r4 = src
922 * r5 = length in bytes
923 * r6 = cachelinesize
924 */
925 .globl relocate_code
926relocate_code:
927 mr r1, r3 /* Set new stack pointer */
928 mr r9, r4 /* Save copy of Init Data pointer */
929 mr r10, r5 /* Save copy of Destination Address */
930
931 mr r3, r5 /* Destination Address */
932 lis r4, CFG_MONITOR_BASE@h /* Source Address */
933 ori r4, r4, CFG_MONITOR_BASE@l
934 lwz r5,GOT(__init_end)
935 sub r5,r5,r4
936 li r6, CFG_CACHELINE_SIZE /* Cache Line Size */
937
938 /*
939 * Fix GOT pointer:
940 *
941 * New GOT-PTR = (old GOT-PTR - CFG_MONITOR_BASE) + Destination Address
942 *
943 * Offset:
944 */
945 sub r15, r10, r4
946
947 /* First our own GOT */
948 add r14, r14, r15
949 /* the the one used by the C code */
950 add r30, r30, r15
951
952 /*
953 * Now relocate code
954 */
955
956 cmplw cr1,r3,r4
957 addi r0,r5,3
958 srwi. r0,r0,2
959 beq cr1,4f /* In place copy is not necessary */
960 beq 7f /* Protect against 0 count */
961 mtctr r0
962 bge cr1,2f
963
964 la r8,-4(r4)
965 la r7,-4(r3)
9661: lwzu r0,4(r8)
967 stwu r0,4(r7)
968 bdnz 1b
969 b 4f
970
9712: slwi r0,r0,2
972 add r8,r4,r0
973 add r7,r3,r0
9743: lwzu r0,-4(r8)
975 stwu r0,-4(r7)
976 bdnz 3b
977
978/*
979 * Now flush the cache: note that we must start from a cache aligned
980 * address. Otherwise we might miss one cache line.
981 */
9824: cmpwi r6,0
983 add r5,r3,r5
984 beq 7f /* Always flush prefetch queue in any case */
985 subi r0,r6,1
986 andc r3,r3,r0
987 mr r4,r3
9885: dcbst 0,r4
989 add r4,r4,r6
990 cmplw r4,r5
991 blt 5b
992 sync /* Wait for all dcbst to complete on bus */
993 mr r4,r3
9946: icbi 0,r4
995 add r4,r4,r6
996 cmplw r4,r5
997 blt 6b
9987: sync /* Wait for all icbi to complete on bus */
999 isync
1000
1001/*
1002 * We are done. Do not return, instead branch to second part of board
1003 * initialization, now running from RAM.
1004 */
1005
1006 addi r0, r10, in_ram - _start + EXC_OFF_SYS_RESET
1007 mtlr r0
1008 blr /* NEVER RETURNS! */
1009
1010in_ram:
1011
1012 /*
1013 * Relocation Function, r14 point to got2+0x8000
1014 *
1015 * Adjust got2 pointers, no need to check for 0, this code
1016 * already puts a few entries in the table.
1017 */
1018 li r0,__got2_entries@sectoff@l
1019 la r3,GOT(_GOT2_TABLE_)
1020 lwz r11,GOT(_GOT2_TABLE_)
1021 mtctr r0
1022 sub r11,r3,r11
1023 addi r3,r3,-4
10241: lwzu r0,4(r3)
1025 add r0,r0,r11
1026 stw r0,0(r3)
1027 bdnz 1b
1028
1029 /*
1030 * Now adjust the fixups and the pointers to the fixups
1031 * in case we need to move ourselves again.
1032 */
10332: li r0,__fixup_entries@sectoff@l
1034 lwz r3,GOT(_FIXUP_TABLE_)
1035 cmpwi r0,0
1036 mtctr r0
1037 addi r3,r3,-4
1038 beq 4f
10393: lwzu r4,4(r3)
1040 lwzux r0,r4,r11
1041 add r0,r0,r11
1042 stw r10,0(r3)
1043 stw r0,0(r4)
1044 bdnz 3b
10454:
1046clear_bss:
1047 /*
1048 * Now clear BSS segment
1049 */
1050 lwz r3,GOT(__bss_start)
1051 lwz r4,GOT(_end)
1052
1053 cmplw 0, r3, r4
1054 beq 6f
1055
1056 li r0, 0
10575:
1058 stw r0, 0(r3)
1059 addi r3, r3, 4
1060 cmplw 0, r3, r4
1061 bne 5b
10626:
1063
1064 mr r3, r9 /* Init Data pointer */
1065 mr r4, r10 /* Destination Address */
1066 bl board_init_r
1067
1068 /*
1069 * Copy exception vector code to low memory
1070 *
1071 * r3: dest_addr
1072 * r7: source address, r8: end address, r9: target address
1073 */
1074 .globl trap_init
1075trap_init:
1076 lwz r7, GOT(_start)
1077 lwz r8, GOT(_end_of_vectors)
1078
1079 li r9, 0x100 /* reset vector always at 0x100 */
1080
1081 cmplw 0, r7, r8
1082 bgelr /* return if r7>=r8 - just in case */
1083
1084 mflr r4 /* save link register */
10851:
1086 lwz r0, 0(r7)
1087 stw r0, 0(r9)
1088 addi r7, r7, 4
1089 addi r9, r9, 4
1090 cmplw 0, r7, r8
1091 bne 1b
1092
1093 /*
1094 * relocate `hdlr' and `int_return' entries
1095 */
1096 li r7, .L_MachineCheck - _start + EXC_OFF_SYS_RESET
1097 li r8, Alignment - _start + EXC_OFF_SYS_RESET
10982:
1099 bl trap_reloc
1100 addi r7, r7, 0x100 /* next exception vector */
1101 cmplw 0, r7, r8
1102 blt 2b
1103
1104 li r7, .L_Alignment - _start + EXC_OFF_SYS_RESET
1105 bl trap_reloc
1106
1107 li r7, .L_ProgramCheck - _start + EXC_OFF_SYS_RESET
1108 bl trap_reloc
1109
1110 li r7, .L_FPUnavailable - _start + EXC_OFF_SYS_RESET
1111 li r8, SystemCall - _start + EXC_OFF_SYS_RESET
11123:
1113 bl trap_reloc
1114 addi r7, r7, 0x100 /* next exception vector */
1115 cmplw 0, r7, r8
1116 blt 3b
1117
1118 li r7, .L_SingleStep - _start + EXC_OFF_SYS_RESET
1119 li r8, _end_of_vectors - _start + EXC_OFF_SYS_RESET
11204:
1121 bl trap_reloc
1122 addi r7, r7, 0x100 /* next exception vector */
1123 cmplw 0, r7, r8
1124 blt 4b
1125
1126 mtlr r4 /* restore link register */
1127 blr
1128
1129 /*
1130 * Function: relocate entries for one exception vector
1131 */
1132trap_reloc:
1133 lwz r0, 0(r7) /* hdlr ... */
1134 add r0, r0, r3 /* ... += dest_addr */
1135 stw r0, 0(r7)
1136
1137 lwz r0, 4(r7) /* int_return ... */
1138 add r0, r0, r3 /* ... += dest_addr */
1139 stw r0, 4(r7)
1140
1141 blr
1142
1143#ifdef CFG_INIT_RAM_LOCK
1144.globl unlock_ram_in_cache
1145unlock_ram_in_cache:
1146 /* invalidate the INIT_RAM section */
1147 lis r3, (CFG_INIT_RAM_ADDR & ~31)@h
1148 ori r3, r3, (CFG_INIT_RAM_ADDR & ~31)@l
1149 li r2,512
1150 mtctr r2
11511: icbi r0, r3
1152 dcbi r0, r3
1153 addi r3, r3, 32
1154 bdnz 1b
1155 sync /* Wait for all icbi to complete on bus */
1156 isync
1157 blr
1158#endif