blob: 468923c9987b91be839884d521f9bbf6451905c1 [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)
365 li r0,0x2000
366 mtspr HID1,r0
367 isync
368#endif
369
370 /* Enable Branch Prediction */
371#if defined(CONFIG_BTB)
372 li r0,0x201 /* BBFI = 1, BPEN = 1 */
373 mtspr BUCSR,r0
374 isync
375#endif
376
377#if defined(CFG_INIT_DBCR)
378 lis r1,0xffff
379 ori r1,r1,0xffff
380 mtspr dbsr,r1 /* Clear all status bits */
381 lis r0,CFG_INIT_DBCR@h /* DBCR0[IDM] must be set */
382 ori r0,r0,CFG_INIT_DBCR@l
383 mtspr dbcr0,r0
384 isync
385#endif
386
387/* L1 DCache is used for initial RAM */
388 mfspr r2, L1CSR0
389 ori r2, r2, 0x0003
390 oris r2, r2, 0x0001
391 msync
392 isync
393 mtspr L1CSR0, r2 /* enable/invalidate L1 Dcache */
394 isync
395
396 /* Allocate Initial RAM in data cache.
397 */
398 lis r3, CFG_INIT_RAM_ADDR@h
399 ori r3, r3, CFG_INIT_RAM_ADDR@l
400 li r2, 512 /* 512*32=16K */
401 mtctr r2
402 li r0, 0
4031:
404 dcbz r0, r3
405 dcbtls 0,r0, r3
406 addi r3, r3, 32
407 bdnz 1b
408
409#ifndef CFG_RAMBOOT
410 /* Calculate absolute address in FLASH and jump there */
411 /*--------------------------------------------------------------*/
412 lis r3, CFG_MONITOR_BASE@h
413 ori r3, r3, CFG_MONITOR_BASE@l
414 addi r3, r3, in_flash - _start + EXC_OFF_SYS_RESET
415 mtlr r3
416 blr
417
418in_flash:
419#endif /* CFG_RAMBOOT */
420
421 /* Setup the stack in initial RAM,could be L2-as-SRAM or L1 dcache*/
422 lis r1,CFG_INIT_RAM_ADDR@h
423 ori r1,r1,CFG_INIT_SP_OFFSET@l
424
425 li r0,0
426 stwu r0,-4(r1)
427 stwu r0,-4(r1) /* Terminate call chain */
428
429 stwu r1,-8(r1) /* Save back chain and move SP */
430 lis r0,RESET_VECTOR@h /* Address of reset vector */
431 ori r0,r0, RESET_VECTOR@l
432 stwu r1,-8(r1) /* Save back chain and move SP */
433 stw r0,+12(r1) /* Save return addr (underflow vect) */
434
435 GET_GOT
436 bl cpu_init_f
437 bl icache_enable
438 bl board_init_f
439 sync
440
441
442/* --FIXME-- machine check with MCSRRn and rfmci */
443
444 .globl _start_of_vectors
445_start_of_vectors:
446#if 0
447/* Critical input. */
448 CRIT_EXCEPTION(0x0100, CritcalInput, CritcalInputException)
449#endif
450/* Machine check --FIXME-- Should be MACH_EXCEPTION */
451 CRIT_EXCEPTION(0x0200, MachineCheck, MachineCheckException)
452
453/* Data Storage exception. */
454 STD_EXCEPTION(0x0300, DataStorage, UnknownException)
455
456/* Instruction Storage exception. */
457 STD_EXCEPTION(0x0400, InstStorage, UnknownException)
458
459/* External Interrupt exception. */
460 STD_EXCEPTION(0x0500, ExtInterrupt, UnknownException)
461
462/* Alignment exception. */
463 . = 0x0600
464Alignment:
465 EXCEPTION_PROLOG
466 mfspr r4,DAR
467 stw r4,_DAR(r21)
468 mfspr r5,DSISR
469 stw r5,_DSISR(r21)
470 addi r3,r1,STACK_FRAME_OVERHEAD
471 li r20,MSR_KERNEL
472 rlwimi r20,r23,0,16,16 /* copy EE bit from saved MSR */
473 lwz r6,GOT(transfer_to_handler)
474 mtlr r6
475 blrl
476.L_Alignment:
477 .long AlignmentException - _start + EXC_OFF_SYS_RESET
478 .long int_return - _start + EXC_OFF_SYS_RESET
479
480/* Program check exception */
481 . = 0x0700
482ProgramCheck:
483 EXCEPTION_PROLOG
484 addi r3,r1,STACK_FRAME_OVERHEAD
485 li r20,MSR_KERNEL
486 rlwimi r20,r23,0,16,16 /* copy EE bit from saved MSR */
487 lwz r6,GOT(transfer_to_handler)
488 mtlr r6
489 blrl
490.L_ProgramCheck:
491 .long ProgramCheckException - _start + EXC_OFF_SYS_RESET
492 .long int_return - _start + EXC_OFF_SYS_RESET
493
494 /* No FPU on MPC85xx. This exception is not supposed to happen.
495 */
496 STD_EXCEPTION(0x0800, FPUnavailable, UnknownException)
497 STD_EXCEPTION(0x0900, Decrementer, timer_interrupt)
498 STD_EXCEPTION(0x0a00, Trap_0a, UnknownException)
499 STD_EXCEPTION(0x0b00, Trap_0b, UnknownException)
500
501 . = 0x0c00
502/*
503 * r0 - SYSCALL number
504 * r3-... arguments
505 */
506SystemCall:
507 addis r11,r0,0 /* get functions table addr */
508 ori r11,r11,0 /* Note: this code is patched in trap_init */
509 addis r12,r0,0 /* get number of functions */
510 ori r12,r12,0
511
512 cmplw 0, r0, r12
513 bge 1f
514
515 rlwinm r0,r0,2,0,31 /* fn_addr = fn_tbl[r0] */
516 add r11,r11,r0
517 lwz r11,0(r11)
518
519 li r20,0xd00-4 /* Get stack pointer */
520 lwz r12,0(r20)
521 subi r12,r12,12 /* Adjust stack pointer */
522 li r0,0xc00+_end_back-SystemCall
523 cmplw 0, r0, r12 /* Check stack overflow */
524 bgt 1f
525 stw r12,0(r20)
526
527 mflr r0
528 stw r0,0(r12)
529 mfspr r0,SRR0
530 stw r0,4(r12)
531 mfspr r0,SRR1
532 stw r0,8(r12)
533
534 li r12,0xc00+_back-SystemCall
535 mtlr r12
536 mtspr SRR0,r11
537
5381: SYNC
539 rfi
540_back:
541
542 mfmsr r11 /* Disable interrupts */
543 li r12,0
544 ori r12,r12,MSR_EE
545 andc r11,r11,r12
546 SYNC /* Some chip revs need this... */
547 mtmsr r11
548 SYNC
549
550 li r12,0xd00-4 /* restore regs */
551 lwz r12,0(r12)
552
553 lwz r11,0(r12)
554 mtlr r11
555 lwz r11,4(r12)
556 mtspr SRR0,r11
557 lwz r11,8(r12)
558 mtspr SRR1,r11
559
560 addi r12,r12,12 /* Adjust stack pointer */
561 li r20,0xd00-4
562 stw r12,0(r20)
563
564 SYNC
565 rfi
566_end_back:
567
568 STD_EXCEPTION(0xd00, SingleStep, UnknownException)
569
570 STD_EXCEPTION(0xe00, Trap_0e, UnknownException)
571 STD_EXCEPTION(0xf00, Trap_0f, UnknownException)
572
573 STD_EXCEPTION(0x1000, PIT, PITException)
574
575 STD_EXCEPTION(0x1100, InstructionTLBMiss, UnknownException)
576 STD_EXCEPTION(0x1200, DataTLBMiss, UnknownException)
577 STD_EXCEPTION(0x1300, InstructionTLBError, UnknownException)
578 STD_EXCEPTION(0x1400, DataTLBError, UnknownException)
579
580 STD_EXCEPTION(0x1500, Reserved5, UnknownException)
581 STD_EXCEPTION(0x1600, Reserved6, UnknownException)
582 STD_EXCEPTION(0x1700, Reserved7, UnknownException)
583 STD_EXCEPTION(0x1800, Reserved8, UnknownException)
584 STD_EXCEPTION(0x1900, Reserved9, UnknownException)
585 STD_EXCEPTION(0x1a00, ReservedA, UnknownException)
586 STD_EXCEPTION(0x1b00, ReservedB, UnknownException)
587
588 STD_EXCEPTION(0x1c00, DataBreakpoint, UnknownException)
589 STD_EXCEPTION(0x1d00, InstructionBreakpoint, UnknownException)
590 STD_EXCEPTION(0x1e00, PeripheralBreakpoint, UnknownException)
591 STD_EXCEPTION(0x1f00, DevPortBreakpoint, UnknownException)
592
593 CRIT_EXCEPTION(0x2000, DebugBreakpoint, DebugException )
594
595 .globl _end_of_vectors
596_end_of_vectors:
597
598
599 . = 0x2100
600
601/*
602 * This code finishes saving the registers to the exception frame
603 * and jumps to the appropriate handler for the exception.
604 * Register r21 is pointer into trap frame, r1 has new stack pointer.
605 */
606 .globl transfer_to_handler
607transfer_to_handler:
608 stw r22,_NIP(r21)
609 lis r22,MSR_POW@h
610 andc r23,r23,r22
611 stw r23,_MSR(r21)
612 SAVE_GPR(7, r21)
613 SAVE_4GPRS(8, r21)
614 SAVE_8GPRS(12, r21)
615 SAVE_8GPRS(24, r21)
616
617 mflr r23
618 andi. r24,r23,0x3f00 /* get vector offset */
619 stw r24,TRAP(r21)
620 li r22,0
621 stw r22,RESULT(r21)
622 mtspr SPRG2,r22 /* r1 is now kernel sp */
623
624 lwz r24,0(r23) /* virtual address of handler */
625 lwz r23,4(r23) /* where to go when done */
626 mtspr SRR0,r24
627 mtspr SRR1,r20
628 mtlr r23
629 SYNC
630 rfi /* jump to handler, enable MMU */
631
632int_return:
633 mfmsr r28 /* Disable interrupts */
634 li r4,0
635 ori r4,r4,MSR_EE
636 andc r28,r28,r4
637 SYNC /* Some chip revs need this... */
638 mtmsr r28
639 SYNC
640 lwz r2,_CTR(r1)
641 lwz r0,_LINK(r1)
642 mtctr r2
643 mtlr r0
644 lwz r2,_XER(r1)
645 lwz r0,_CCR(r1)
646 mtspr XER,r2
647 mtcrf 0xFF,r0
648 REST_10GPRS(3, r1)
649 REST_10GPRS(13, r1)
650 REST_8GPRS(23, r1)
651 REST_GPR(31, r1)
652 lwz r2,_NIP(r1) /* Restore environment */
653 lwz r0,_MSR(r1)
654 mtspr SRR0,r2
655 mtspr SRR1,r0
656 lwz r0,GPR0(r1)
657 lwz r2,GPR2(r1)
658 lwz r1,GPR1(r1)
659 SYNC
660 rfi
661
662crit_return:
663 mfmsr r28 /* Disable interrupts */
664 li r4,0
665 ori r4,r4,MSR_EE
666 andc r28,r28,r4
667 SYNC /* Some chip revs need this... */
668 mtmsr r28
669 SYNC
670 lwz r2,_CTR(r1)
671 lwz r0,_LINK(r1)
672 mtctr r2
673 mtlr r0
674 lwz r2,_XER(r1)
675 lwz r0,_CCR(r1)
676 mtspr XER,r2
677 mtcrf 0xFF,r0
678 REST_10GPRS(3, r1)
679 REST_10GPRS(13, r1)
680 REST_8GPRS(23, r1)
681 REST_GPR(31, r1)
682 lwz r2,_NIP(r1) /* Restore environment */
683 lwz r0,_MSR(r1)
684 mtspr 990,r2 /* SRR2 */
685 mtspr 991,r0 /* SRR3 */
686 lwz r0,GPR0(r1)
687 lwz r2,GPR2(r1)
688 lwz r1,GPR1(r1)
689 SYNC
690 rfci
691
692/* Cache functions.
693*/
694invalidate_icache:
695 mfspr r0,L1CSR1
696 ori r0,r0,0x0002
697 mtspr L1CSR1,r0
698 isync
699 blr /* entire I cache */
700
701invalidate_dcache:
702 mfspr r0,L1CSR0
703 ori r0,r0,0x0002
704 msync
705 isync
706 mtspr L1CSR0,r0
707 isync
708 blr
709
710 .globl icache_enable
711icache_enable:
712 mflr r8
713 bl invalidate_icache
714 mtlr r8
715 isync
716 mfspr r4,L1CSR1
717 ori r4,r4,0x0001
718 oris r4,r4,0x0001
719 mtspr L1CSR1,r4
720 isync
721 blr
722
723 .globl icache_disable
724icache_disable:
725 mfspr r0,L1CSR1
726 lis r1,0xfffffffe@h
727 ori r1,r1,0xfffffffe@l
728 and r0,r0,r1
729 mtspr L1CSR1,r0
730 isync
731 blr
732
733 .globl icache_status
734icache_status:
735 mfspr r3,L1CSR1
736 srwi r3, r3, 31 /* >>31 => select bit 0 */
737 blr
738
739 .globl dcache_enable
740dcache_enable:
741 mflr r8
742 bl invalidate_dcache
743 mtlr r8
744 isync
745 mfspr r0,L1CSR0
746 ori r0,r0,0x0001
747 oris r0,r0,0x0001
748 msync
749 isync
750 mtspr L1CSR0,r0
751 isync
752 blr
753
754 .globl dcache_disable
755dcache_disable:
756 mfspr r0,L1CSR0
757 lis r1,0xfffffffe@h
758 ori r1,r1,0xfffffffe@l
759 and r0,r0,r1
760 msync
761 isync
762 mtspr L1CSR0,r0
763 isync
764 blr
765
766 .globl dcache_status
767dcache_status:
768 mfspr r3,L1CSR0
769 srwi r3, r3, 31 /* >>31 => select bit 0 */
770 blr
771
772 .globl get_pir
773get_pir:
774 mfspr r3, PIR
775 blr
776
777 .globl get_pvr
778get_pvr:
779 mfspr r3, PVR
780 blr
781
782 .globl wr_tcr
783wr_tcr:
784 mtspr TCR, r3
785 blr
786
787/*------------------------------------------------------------------------------- */
788/* Function: in8 */
789/* Description: Input 8 bits */
790/*------------------------------------------------------------------------------- */
791 .globl in8
792in8:
793 lbz r3,0x0000(r3)
794 blr
795
796/*------------------------------------------------------------------------------- */
797/* Function: out8 */
798/* Description: Output 8 bits */
799/*------------------------------------------------------------------------------- */
800 .globl out8
801out8:
802 stb r4,0x0000(r3)
803 blr
804
805/*------------------------------------------------------------------------------- */
806/* Function: out16 */
807/* Description: Output 16 bits */
808/*------------------------------------------------------------------------------- */
809 .globl out16
810out16:
811 sth r4,0x0000(r3)
812 blr
813
814/*------------------------------------------------------------------------------- */
815/* Function: out16r */
816/* Description: Byte reverse and output 16 bits */
817/*------------------------------------------------------------------------------- */
818 .globl out16r
819out16r:
820 sthbrx r4,r0,r3
821 blr
822
823/*------------------------------------------------------------------------------- */
824/* Function: out32 */
825/* Description: Output 32 bits */
826/*------------------------------------------------------------------------------- */
827 .globl out32
828out32:
829 stw r4,0x0000(r3)
830 blr
831
832/*------------------------------------------------------------------------------- */
833/* Function: out32r */
834/* Description: Byte reverse and output 32 bits */
835/*------------------------------------------------------------------------------- */
836 .globl out32r
837out32r:
838 stwbrx r4,r0,r3
839 blr
840
841/*------------------------------------------------------------------------------- */
842/* Function: in16 */
843/* Description: Input 16 bits */
844/*------------------------------------------------------------------------------- */
845 .globl in16
846in16:
847 lhz r3,0x0000(r3)
848 blr
849
850/*------------------------------------------------------------------------------- */
851/* Function: in16r */
852/* Description: Input 16 bits and byte reverse */
853/*------------------------------------------------------------------------------- */
854 .globl in16r
855in16r:
856 lhbrx r3,r0,r3
857 blr
858
859/*------------------------------------------------------------------------------- */
860/* Function: in32 */
861/* Description: Input 32 bits */
862/*------------------------------------------------------------------------------- */
863 .globl in32
864in32:
865 lwz 3,0x0000(3)
866 blr
867
868/*------------------------------------------------------------------------------- */
869/* Function: in32r */
870/* Description: Input 32 bits and byte reverse */
871/*------------------------------------------------------------------------------- */
872 .globl in32r
873in32r:
874 lwbrx r3,r0,r3
875 blr
876
877/*------------------------------------------------------------------------------- */
878/* Function: ppcDcbf */
879/* Description: Data Cache block flush */
880/* Input: r3 = effective address */
881/* Output: none. */
882/*------------------------------------------------------------------------------- */
883 .globl ppcDcbf
884ppcDcbf:
885 dcbf r0,r3
886 blr
887
888/*------------------------------------------------------------------------------- */
889/* Function: ppcDcbi */
890/* Description: Data Cache block Invalidate */
891/* Input: r3 = effective address */
892/* Output: none. */
893/*------------------------------------------------------------------------------- */
894 .globl ppcDcbi
895ppcDcbi:
896 dcbi r0,r3
897 blr
898
899/*------------------------------------------------------------------------------- */
900/* Function: ppcSync */
901/* Description: Processor Synchronize */
902/* Input: none. */
903/* Output: none. */
904/*------------------------------------------------------------------------------- */
905 .globl ppcSync
906ppcSync:
907 sync
908 blr
909
910/*------------------------------------------------------------------------------*/
911
912/*
913 * void relocate_code (addr_sp, gd, addr_moni)
914 *
915 * This "function" does not return, instead it continues in RAM
916 * after relocating the monitor code.
917 *
918 * r3 = dest
919 * r4 = src
920 * r5 = length in bytes
921 * r6 = cachelinesize
922 */
923 .globl relocate_code
924relocate_code:
925 mr r1, r3 /* Set new stack pointer */
926 mr r9, r4 /* Save copy of Init Data pointer */
927 mr r10, r5 /* Save copy of Destination Address */
928
929 mr r3, r5 /* Destination Address */
930 lis r4, CFG_MONITOR_BASE@h /* Source Address */
931 ori r4, r4, CFG_MONITOR_BASE@l
932 lwz r5,GOT(__init_end)
933 sub r5,r5,r4
934 li r6, CFG_CACHELINE_SIZE /* Cache Line Size */
935
936 /*
937 * Fix GOT pointer:
938 *
939 * New GOT-PTR = (old GOT-PTR - CFG_MONITOR_BASE) + Destination Address
940 *
941 * Offset:
942 */
943 sub r15, r10, r4
944
945 /* First our own GOT */
946 add r14, r14, r15
947 /* the the one used by the C code */
948 add r30, r30, r15
949
950 /*
951 * Now relocate code
952 */
953
954 cmplw cr1,r3,r4
955 addi r0,r5,3
956 srwi. r0,r0,2
957 beq cr1,4f /* In place copy is not necessary */
958 beq 7f /* Protect against 0 count */
959 mtctr r0
960 bge cr1,2f
961
962 la r8,-4(r4)
963 la r7,-4(r3)
9641: lwzu r0,4(r8)
965 stwu r0,4(r7)
966 bdnz 1b
967 b 4f
968
9692: slwi r0,r0,2
970 add r8,r4,r0
971 add r7,r3,r0
9723: lwzu r0,-4(r8)
973 stwu r0,-4(r7)
974 bdnz 3b
975
976/*
977 * Now flush the cache: note that we must start from a cache aligned
978 * address. Otherwise we might miss one cache line.
979 */
9804: cmpwi r6,0
981 add r5,r3,r5
982 beq 7f /* Always flush prefetch queue in any case */
983 subi r0,r6,1
984 andc r3,r3,r0
985 mr r4,r3
9865: dcbst 0,r4
987 add r4,r4,r6
988 cmplw r4,r5
989 blt 5b
990 sync /* Wait for all dcbst to complete on bus */
991 mr r4,r3
9926: icbi 0,r4
993 add r4,r4,r6
994 cmplw r4,r5
995 blt 6b
9967: sync /* Wait for all icbi to complete on bus */
997 isync
998
999/*
1000 * We are done. Do not return, instead branch to second part of board
1001 * initialization, now running from RAM.
1002 */
1003
1004 addi r0, r10, in_ram - _start + EXC_OFF_SYS_RESET
1005 mtlr r0
1006 blr /* NEVER RETURNS! */
1007
1008in_ram:
1009
1010 /*
1011 * Relocation Function, r14 point to got2+0x8000
1012 *
1013 * Adjust got2 pointers, no need to check for 0, this code
1014 * already puts a few entries in the table.
1015 */
1016 li r0,__got2_entries@sectoff@l
1017 la r3,GOT(_GOT2_TABLE_)
1018 lwz r11,GOT(_GOT2_TABLE_)
1019 mtctr r0
1020 sub r11,r3,r11
1021 addi r3,r3,-4
10221: lwzu r0,4(r3)
1023 add r0,r0,r11
1024 stw r0,0(r3)
1025 bdnz 1b
1026
1027 /*
1028 * Now adjust the fixups and the pointers to the fixups
1029 * in case we need to move ourselves again.
1030 */
10312: li r0,__fixup_entries@sectoff@l
1032 lwz r3,GOT(_FIXUP_TABLE_)
1033 cmpwi r0,0
1034 mtctr r0
1035 addi r3,r3,-4
1036 beq 4f
10373: lwzu r4,4(r3)
1038 lwzux r0,r4,r11
1039 add r0,r0,r11
1040 stw r10,0(r3)
1041 stw r0,0(r4)
1042 bdnz 3b
10434:
1044clear_bss:
1045 /*
1046 * Now clear BSS segment
1047 */
1048 lwz r3,GOT(__bss_start)
1049 lwz r4,GOT(_end)
1050
1051 cmplw 0, r3, r4
1052 beq 6f
1053
1054 li r0, 0
10555:
1056 stw r0, 0(r3)
1057 addi r3, r3, 4
1058 cmplw 0, r3, r4
1059 bne 5b
10606:
1061
1062 mr r3, r9 /* Init Data pointer */
1063 mr r4, r10 /* Destination Address */
1064 bl board_init_r
1065
1066 /*
1067 * Copy exception vector code to low memory
1068 *
1069 * r3: dest_addr
1070 * r7: source address, r8: end address, r9: target address
1071 */
1072 .globl trap_init
1073trap_init:
1074 lwz r7, GOT(_start)
1075 lwz r8, GOT(_end_of_vectors)
1076
1077 li r9, 0x100 /* reset vector always at 0x100 */
1078
1079 cmplw 0, r7, r8
1080 bgelr /* return if r7>=r8 - just in case */
1081
1082 mflr r4 /* save link register */
10831:
1084 lwz r0, 0(r7)
1085 stw r0, 0(r9)
1086 addi r7, r7, 4
1087 addi r9, r9, 4
1088 cmplw 0, r7, r8
1089 bne 1b
1090
1091 /*
1092 * relocate `hdlr' and `int_return' entries
1093 */
1094 li r7, .L_MachineCheck - _start + EXC_OFF_SYS_RESET
1095 li r8, Alignment - _start + EXC_OFF_SYS_RESET
10962:
1097 bl trap_reloc
1098 addi r7, r7, 0x100 /* next exception vector */
1099 cmplw 0, r7, r8
1100 blt 2b
1101
1102 li r7, .L_Alignment - _start + EXC_OFF_SYS_RESET
1103 bl trap_reloc
1104
1105 li r7, .L_ProgramCheck - _start + EXC_OFF_SYS_RESET
1106 bl trap_reloc
1107
1108 li r7, .L_FPUnavailable - _start + EXC_OFF_SYS_RESET
1109 li r8, SystemCall - _start + EXC_OFF_SYS_RESET
11103:
1111 bl trap_reloc
1112 addi r7, r7, 0x100 /* next exception vector */
1113 cmplw 0, r7, r8
1114 blt 3b
1115
1116 li r7, .L_SingleStep - _start + EXC_OFF_SYS_RESET
1117 li r8, _end_of_vectors - _start + EXC_OFF_SYS_RESET
11184:
1119 bl trap_reloc
1120 addi r7, r7, 0x100 /* next exception vector */
1121 cmplw 0, r7, r8
1122 blt 4b
1123
1124 mtlr r4 /* restore link register */
1125 blr
1126
1127 /*
1128 * Function: relocate entries for one exception vector
1129 */
1130trap_reloc:
1131 lwz r0, 0(r7) /* hdlr ... */
1132 add r0, r0, r3 /* ... += dest_addr */
1133 stw r0, 0(r7)
1134
1135 lwz r0, 4(r7) /* int_return ... */
1136 add r0, r0, r3 /* ... += dest_addr */
1137 stw r0, 4(r7)
1138
1139 blr
1140
1141#ifdef CFG_INIT_RAM_LOCK
1142.globl unlock_ram_in_cache
1143unlock_ram_in_cache:
1144 /* invalidate the INIT_RAM section */
1145 lis r3, (CFG_INIT_RAM_ADDR & ~31)@h
1146 ori r3, r3, (CFG_INIT_RAM_ADDR & ~31)@l
1147 li r2,512
1148 mtctr r2
11491: icbi r0, r3
1150 dcbi r0, r3
1151 addi r3, r3, 32
1152 bdnz 1b
1153 sync /* Wait for all icbi to complete on bus */
1154 isync
1155 blr
1156#endif