]> git.karo-electronics.de Git - karo-tx-uboot.git/blob - cpu/mpc85xx/start.S
Update U-Boot's build timestamp on every compile
[karo-tx-uboot.git] / cpu / mpc85xx / start.S
1 /*
2  * Copyright 2004, 2007 Freescale Semiconductor.
3  * Copyright (C) 2003  Motorola,Inc.
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 <timestamp.h>
34 #include <version.h>
35
36 #define _LINUX_CONFIG_H 1       /* avoid reading Linux autoconf.h file  */
37
38 #include <ppc_asm.tmpl>
39 #include <ppc_defs.h>
40
41 #include <asm/cache.h>
42 #include <asm/mmu.h>
43
44 #ifndef  CONFIG_IDENT_STRING
45 #define  CONFIG_IDENT_STRING ""
46 #endif
47
48 #undef  MSR_KERNEL
49 #define MSR_KERNEL ( MSR_ME )   /* Machine Check */
50
51 /*
52  * Set up GOT: Global Offset Table
53  *
54  * Use r14 to access the GOT
55  */
56         START_GOT
57         GOT_ENTRY(_GOT2_TABLE_)
58         GOT_ENTRY(_FIXUP_TABLE_)
59
60         GOT_ENTRY(_start)
61         GOT_ENTRY(_start_of_vectors)
62         GOT_ENTRY(_end_of_vectors)
63         GOT_ENTRY(transfer_to_handler)
64
65         GOT_ENTRY(__init_end)
66         GOT_ENTRY(_end)
67         GOT_ENTRY(__bss_start)
68         END_GOT
69
70 /*
71  * e500 Startup -- after reset only the last 4KB of the effective
72  * address space is mapped in the MMU L2 TLB1 Entry0. The .bootpg
73  * section is located at THIS LAST page and basically does three
74  * things: clear some registers, set up exception tables and
75  * add more TLB entries for 'larger spaces'(e.g. the boot rom) to
76  * continue the boot procedure.
77
78  * Once the boot rom is mapped by TLB entries we can proceed
79  * with normal startup.
80  *
81  */
82
83         .section .bootpg,"ax"
84         .globl _start_e500
85
86 _start_e500:
87
88 /* clear registers/arrays not reset by hardware */
89
90         /* L1 */
91         li      r0,2
92         mtspr   L1CSR0,r0       /* invalidate d-cache */
93         mtspr   L1CSR1,r0       /* invalidate i-cache */
94
95         mfspr   r1,DBSR
96         mtspr   DBSR,r1         /* Clear all valid bits */
97
98         /*
99          *      Enable L1 Caches early
100          *
101          */
102
103         lis     r2,L1CSR0_CPE@H /* enable parity */
104         ori     r2,r2,L1CSR0_DCE
105         mtspr   L1CSR0,r2       /* enable L1 Dcache */
106         isync
107         mtspr   L1CSR1,r2       /* enable L1 Icache */
108         isync
109         msync
110
111         /* Setup interrupt vectors */
112         lis     r1,TEXT_BASE@h
113         mtspr   IVPR,r1
114
115         li      r1,0x0100
116         mtspr   IVOR0,r1        /* 0: Critical input */
117         li      r1,0x0200
118         mtspr   IVOR1,r1        /* 1: Machine check */
119         li      r1,0x0300
120         mtspr   IVOR2,r1        /* 2: Data storage */
121         li      r1,0x0400
122         mtspr   IVOR3,r1        /* 3: Instruction storage */
123         li      r1,0x0500
124         mtspr   IVOR4,r1        /* 4: External interrupt */
125         li      r1,0x0600
126         mtspr   IVOR5,r1        /* 5: Alignment */
127         li      r1,0x0700
128         mtspr   IVOR6,r1        /* 6: Program check */
129         li      r1,0x0800
130         mtspr   IVOR7,r1        /* 7: floating point unavailable */
131         li      r1,0x0900
132         mtspr   IVOR8,r1        /* 8: System call */
133         /* 9: Auxiliary processor unavailable(unsupported) */
134         li      r1,0x0a00
135         mtspr   IVOR10,r1       /* 10: Decrementer */
136         li      r1,0x0b00
137         mtspr   IVOR11,r1       /* 11: Interval timer */
138         li      r1,0x0c00
139         mtspr   IVOR12,r1       /* 12: Watchdog timer */
140         li      r1,0x0d00
141         mtspr   IVOR13,r1       /* 13: Data TLB error */
142         li      r1,0x0e00
143         mtspr   IVOR14,r1       /* 14: Instruction TLB error */
144         li      r1,0x0f00
145         mtspr   IVOR15,r1       /* 15: Debug */
146
147         /* Clear and set up some registers. */
148         li      r0,0x0000
149         lis     r1,0xffff
150         mtspr   DEC,r0                  /* prevent dec exceptions */
151         mttbl   r0                      /* prevent fit & wdt exceptions */
152         mttbu   r0
153         mtspr   TSR,r1                  /* clear all timer exception status */
154         mtspr   TCR,r0                  /* disable all */
155         mtspr   ESR,r0                  /* clear exception syndrome register */
156         mtspr   MCSR,r0                 /* machine check syndrome register */
157         mtxer   r0                      /* clear integer exception register */
158
159         /* Enable Time Base and Select Time Base Clock */
160         lis     r0,HID0_EMCP@h          /* Enable machine check */
161 #if defined(CONFIG_ENABLE_36BIT_PHYS)
162         ori     r0,r0,HID0_ENMAS7@l     /* Enable MAS7 */
163 #endif
164         ori     r0,r0,HID0_TBEN@l       /* Enable Timebase */
165         mtspr   HID0,r0
166
167 #ifndef CONFIG_E500MC
168         li      r0,(HID1_ASTME|HID1_ABE)@l      /* Addr streaming & broadcast */
169         mtspr   HID1,r0
170 #endif
171
172         /* Enable Branch Prediction */
173 #if defined(CONFIG_BTB)
174         li      r0,0x201                /* BBFI = 1, BPEN = 1 */
175         mtspr   BUCSR,r0
176 #endif
177
178 #if defined(CONFIG_SYS_INIT_DBCR)
179         lis     r1,0xffff
180         ori     r1,r1,0xffff
181         mtspr   DBSR,r1                 /* Clear all status bits */
182         lis     r0,CONFIG_SYS_INIT_DBCR@h       /* DBCR0[IDM] must be set */
183         ori     r0,r0,CONFIG_SYS_INIT_DBCR@l
184         mtspr   DBCR0,r0
185 #endif
186
187         /* create a temp mapping in AS=1 to the boot window */
188         lis     r6,FSL_BOOKE_MAS0(1, 15, 0)@h
189         ori     r6,r6,FSL_BOOKE_MAS0(1, 15, 0)@l
190
191         lis     r7,FSL_BOOKE_MAS1(1, 1, 0, 1, BOOKE_PAGESZ_16M)@h
192         ori     r7,r7,FSL_BOOKE_MAS1(1, 1, 0, 1, BOOKE_PAGESZ_16M)@l
193
194         /* Align the mapping to 16MB */
195         lis     r8,FSL_BOOKE_MAS2(TEXT_BASE & 0xff000000, (MAS2_I|MAS2_G))@h
196         ori     r8,r8,FSL_BOOKE_MAS2(TEXT_BASE & 0xff000000, (MAS2_I|MAS2_G))@l
197
198         lis     r9,FSL_BOOKE_MAS3(0xff000000, 0, (MAS3_SX|MAS3_SW|MAS3_SR))@h
199         ori     r9,r9,FSL_BOOKE_MAS3(0xff000000, 0, (MAS3_SX|MAS3_SW|MAS3_SR))@l
200
201         mtspr   MAS0,r6
202         mtspr   MAS1,r7
203         mtspr   MAS2,r8
204         mtspr   MAS3,r9
205         isync
206         msync
207         tlbwe
208
209         /* create a temp mapping in AS=1 to the stack */
210         lis     r6,FSL_BOOKE_MAS0(1, 14, 0)@h
211         ori     r6,r6,FSL_BOOKE_MAS0(1, 14, 0)@l
212
213         lis     r7,FSL_BOOKE_MAS1(1, 1, 0, 1, BOOKE_PAGESZ_16K)@h
214         ori     r7,r7,FSL_BOOKE_MAS1(1, 1, 0, 1, BOOKE_PAGESZ_16K)@l
215
216         lis     r8,FSL_BOOKE_MAS2(CONFIG_SYS_INIT_RAM_ADDR, 0)@h
217         ori     r8,r8,FSL_BOOKE_MAS2(CONFIG_SYS_INIT_RAM_ADDR, 0)@l
218
219         lis     r9,FSL_BOOKE_MAS3(CONFIG_SYS_INIT_RAM_ADDR, 0, (MAS3_SX|MAS3_SW|MAS3_SR))@h
220         ori     r9,r9,FSL_BOOKE_MAS3(CONFIG_SYS_INIT_RAM_ADDR, 0, (MAS3_SX|MAS3_SW|MAS3_SR))@l
221
222         mtspr   MAS0,r6
223         mtspr   MAS1,r7
224         mtspr   MAS2,r8
225         mtspr   MAS3,r9
226         isync
227         msync
228         tlbwe
229
230         lis     r6,MSR_CE|MSR_ME|MSR_DE|MSR_IS|MSR_DS@h
231         ori     r6,r6,MSR_CE|MSR_ME|MSR_DE|MSR_IS|MSR_DS@l
232         lis     r7,switch_as@h
233         ori     r7,r7,switch_as@l
234
235         mtspr   SPRN_SRR0,r7
236         mtspr   SPRN_SRR1,r6
237         rfi
238
239 switch_as:
240 /* L1 DCache is used for initial RAM */
241
242         /* Allocate Initial RAM in data cache.
243          */
244         lis     r3,CONFIG_SYS_INIT_RAM_ADDR@h
245         ori     r3,r3,CONFIG_SYS_INIT_RAM_ADDR@l
246         mfspr   r2, L1CFG0
247         andi.   r2, r2, 0x1ff
248         /* cache size * 1024 / (2 * L1 line size) */
249         slwi    r2, r2, (10 - 1 - L1_CACHE_SHIFT)
250         mtctr   r2
251         li      r0,0
252 1:
253         dcbz    r0,r3
254         dcbtls  0,r0,r3
255         addi    r3,r3,CONFIG_SYS_CACHELINE_SIZE
256         bdnz    1b
257
258         /* Jump out the last 4K page and continue to 'normal' start */
259 #ifdef CONFIG_SYS_RAMBOOT
260         b       _start_cont
261 #else
262         /* Calculate absolute address in FLASH and jump there           */
263         /*--------------------------------------------------------------*/
264         lis     r3,CONFIG_SYS_MONITOR_BASE@h
265         ori     r3,r3,CONFIG_SYS_MONITOR_BASE@l
266         addi    r3,r3,_start_cont - _start + _START_OFFSET
267         mtlr    r3
268         blr
269 #endif
270
271         .text
272         .globl  _start
273 _start:
274         .long   0x27051956              /* U-BOOT Magic Number */
275         .globl  version_string
276 version_string:
277         .ascii U_BOOT_VERSION
278         .ascii " (", U_BOOT_DATE, " - ", U_BOOT_TIME, ")"
279         .ascii CONFIG_IDENT_STRING, "\0"
280
281         .align  4
282         .globl  _start_cont
283 _start_cont:
284         /* Setup the stack in initial RAM,could be L2-as-SRAM or L1 dcache*/
285         lis     r1,CONFIG_SYS_INIT_RAM_ADDR@h
286         ori     r1,r1,CONFIG_SYS_INIT_SP_OFFSET@l
287
288         li      r0,0
289         stwu    r0,-4(r1)
290         stwu    r0,-4(r1)               /* Terminate call chain */
291
292         stwu    r1,-8(r1)               /* Save back chain and move SP */
293         lis     r0,RESET_VECTOR@h       /* Address of reset vector */
294         ori     r0,r0,RESET_VECTOR@l
295         stwu    r1,-8(r1)               /* Save back chain and move SP */
296         stw     r0,+12(r1)              /* Save return addr (underflow vect) */
297
298         GET_GOT
299         bl      cpu_init_early_f
300
301         /* switch back to AS = 0 */
302         lis     r3,(MSR_CE|MSR_ME|MSR_DE)@h
303         ori     r3,r3,(MSR_CE|MSR_ME|MSR_DE)@l
304         mtmsr   r3
305         isync
306
307         bl      cpu_init_f
308         bl      board_init_f
309         isync
310
311         . = EXC_OFF_SYS_RESET
312         .globl  _start_of_vectors
313 _start_of_vectors:
314
315 /* Critical input. */
316         CRIT_EXCEPTION(0x0100, CriticalInput, CritcalInputException)
317
318 /* Machine check */
319         MCK_EXCEPTION(0x200, MachineCheck, MachineCheckException)
320
321 /* Data Storage exception. */
322         STD_EXCEPTION(0x0300, DataStorage, UnknownException)
323
324 /* Instruction Storage exception. */
325         STD_EXCEPTION(0x0400, InstStorage, UnknownException)
326
327 /* External Interrupt exception. */
328         STD_EXCEPTION(0x0500, ExtInterrupt, ExtIntException)
329
330 /* Alignment exception. */
331         . = 0x0600
332 Alignment:
333         EXCEPTION_PROLOG(SRR0, SRR1)
334         mfspr   r4,DAR
335         stw     r4,_DAR(r21)
336         mfspr   r5,DSISR
337         stw     r5,_DSISR(r21)
338         addi    r3,r1,STACK_FRAME_OVERHEAD
339         li      r20,MSR_KERNEL
340         rlwimi  r20,r23,0,16,16         /* copy EE bit from saved MSR */
341         lwz     r6,GOT(transfer_to_handler)
342         mtlr    r6
343         blrl
344 .L_Alignment:
345         .long   AlignmentException - _start + _START_OFFSET
346         .long   int_return - _start + _START_OFFSET
347
348 /* Program check exception */
349         . = 0x0700
350 ProgramCheck:
351         EXCEPTION_PROLOG(SRR0, SRR1)
352         addi    r3,r1,STACK_FRAME_OVERHEAD
353         li      r20,MSR_KERNEL
354         rlwimi  r20,r23,0,16,16         /* copy EE bit from saved MSR */
355         lwz     r6,GOT(transfer_to_handler)
356         mtlr    r6
357         blrl
358 .L_ProgramCheck:
359         .long   ProgramCheckException - _start + _START_OFFSET
360         .long   int_return - _start + _START_OFFSET
361
362         /* No FPU on MPC85xx.  This exception is not supposed to happen.
363         */
364         STD_EXCEPTION(0x0800, FPUnavailable, UnknownException)
365
366         . = 0x0900
367 /*
368  * r0 - SYSCALL number
369  * r3-... arguments
370  */
371 SystemCall:
372         addis   r11,r0,0        /* get functions table addr */
373         ori     r11,r11,0       /* Note: this code is patched in trap_init */
374         addis   r12,r0,0        /* get number of functions */
375         ori     r12,r12,0
376
377         cmplw   0,r0,r12
378         bge     1f
379
380         rlwinm  r0,r0,2,0,31    /* fn_addr = fn_tbl[r0] */
381         add     r11,r11,r0
382         lwz     r11,0(r11)
383
384         li      r20,0xd00-4     /* Get stack pointer */
385         lwz     r12,0(r20)
386         subi    r12,r12,12      /* Adjust stack pointer */
387         li      r0,0xc00+_end_back-SystemCall
388         cmplw   0,r0,r12        /* Check stack overflow */
389         bgt     1f
390         stw     r12,0(r20)
391
392         mflr    r0
393         stw     r0,0(r12)
394         mfspr   r0,SRR0
395         stw     r0,4(r12)
396         mfspr   r0,SRR1
397         stw     r0,8(r12)
398
399         li      r12,0xc00+_back-SystemCall
400         mtlr    r12
401         mtspr   SRR0,r11
402
403 1:      SYNC
404         rfi
405 _back:
406
407         mfmsr   r11                     /* Disable interrupts */
408         li      r12,0
409         ori     r12,r12,MSR_EE
410         andc    r11,r11,r12
411         SYNC                            /* Some chip revs need this... */
412         mtmsr   r11
413         SYNC
414
415         li      r12,0xd00-4             /* restore regs */
416         lwz     r12,0(r12)
417
418         lwz     r11,0(r12)
419         mtlr    r11
420         lwz     r11,4(r12)
421         mtspr   SRR0,r11
422         lwz     r11,8(r12)
423         mtspr   SRR1,r11
424
425         addi    r12,r12,12              /* Adjust stack pointer */
426         li      r20,0xd00-4
427         stw     r12,0(r20)
428
429         SYNC
430         rfi
431 _end_back:
432
433         STD_EXCEPTION(0x0a00, Decrementer, timer_interrupt)
434         STD_EXCEPTION(0x0b00, IntervalTimer, UnknownException)
435         STD_EXCEPTION(0x0c00, WatchdogTimer, UnknownException)
436
437         STD_EXCEPTION(0x0d00, DataTLBError, UnknownException)
438         STD_EXCEPTION(0x0e00, InstructionTLBError, UnknownException)
439
440         CRIT_EXCEPTION(0x0f00, DebugBreakpoint, DebugException )
441
442         .globl  _end_of_vectors
443 _end_of_vectors:
444
445
446         . = . + (0x100 - ( . & 0xff ))  /* align for debug */
447
448 /*
449  * This code finishes saving the registers to the exception frame
450  * and jumps to the appropriate handler for the exception.
451  * Register r21 is pointer into trap frame, r1 has new stack pointer.
452  */
453         .globl  transfer_to_handler
454 transfer_to_handler:
455         stw     r22,_NIP(r21)
456         lis     r22,MSR_POW@h
457         andc    r23,r23,r22
458         stw     r23,_MSR(r21)
459         SAVE_GPR(7, r21)
460         SAVE_4GPRS(8, r21)
461         SAVE_8GPRS(12, r21)
462         SAVE_8GPRS(24, r21)
463
464         mflr    r23
465         andi.   r24,r23,0x3f00          /* get vector offset */
466         stw     r24,TRAP(r21)
467         li      r22,0
468         stw     r22,RESULT(r21)
469         mtspr   SPRG2,r22               /* r1 is now kernel sp */
470
471         lwz     r24,0(r23)              /* virtual address of handler */
472         lwz     r23,4(r23)              /* where to go when done */
473         mtspr   SRR0,r24
474         mtspr   SRR1,r20
475         mtlr    r23
476         SYNC
477         rfi                             /* jump to handler, enable MMU */
478
479 int_return:
480         mfmsr   r28             /* Disable interrupts */
481         li      r4,0
482         ori     r4,r4,MSR_EE
483         andc    r28,r28,r4
484         SYNC                    /* Some chip revs need this... */
485         mtmsr   r28
486         SYNC
487         lwz     r2,_CTR(r1)
488         lwz     r0,_LINK(r1)
489         mtctr   r2
490         mtlr    r0
491         lwz     r2,_XER(r1)
492         lwz     r0,_CCR(r1)
493         mtspr   XER,r2
494         mtcrf   0xFF,r0
495         REST_10GPRS(3, r1)
496         REST_10GPRS(13, r1)
497         REST_8GPRS(23, r1)
498         REST_GPR(31, r1)
499         lwz     r2,_NIP(r1)     /* Restore environment */
500         lwz     r0,_MSR(r1)
501         mtspr   SRR0,r2
502         mtspr   SRR1,r0
503         lwz     r0,GPR0(r1)
504         lwz     r2,GPR2(r1)
505         lwz     r1,GPR1(r1)
506         SYNC
507         rfi
508
509 crit_return:
510         mfmsr   r28             /* Disable interrupts */
511         li      r4,0
512         ori     r4,r4,MSR_EE
513         andc    r28,r28,r4
514         SYNC                    /* Some chip revs need this... */
515         mtmsr   r28
516         SYNC
517         lwz     r2,_CTR(r1)
518         lwz     r0,_LINK(r1)
519         mtctr   r2
520         mtlr    r0
521         lwz     r2,_XER(r1)
522         lwz     r0,_CCR(r1)
523         mtspr   XER,r2
524         mtcrf   0xFF,r0
525         REST_10GPRS(3, r1)
526         REST_10GPRS(13, r1)
527         REST_8GPRS(23, r1)
528         REST_GPR(31, r1)
529         lwz     r2,_NIP(r1)     /* Restore environment */
530         lwz     r0,_MSR(r1)
531         mtspr   SPRN_CSRR0,r2
532         mtspr   SPRN_CSRR1,r0
533         lwz     r0,GPR0(r1)
534         lwz     r2,GPR2(r1)
535         lwz     r1,GPR1(r1)
536         SYNC
537         rfci
538
539 mck_return:
540         mfmsr   r28             /* Disable interrupts */
541         li      r4,0
542         ori     r4,r4,MSR_EE
543         andc    r28,r28,r4
544         SYNC                    /* Some chip revs need this... */
545         mtmsr   r28
546         SYNC
547         lwz     r2,_CTR(r1)
548         lwz     r0,_LINK(r1)
549         mtctr   r2
550         mtlr    r0
551         lwz     r2,_XER(r1)
552         lwz     r0,_CCR(r1)
553         mtspr   XER,r2
554         mtcrf   0xFF,r0
555         REST_10GPRS(3, r1)
556         REST_10GPRS(13, r1)
557         REST_8GPRS(23, r1)
558         REST_GPR(31, r1)
559         lwz     r2,_NIP(r1)     /* Restore environment */
560         lwz     r0,_MSR(r1)
561         mtspr   SPRN_MCSRR0,r2
562         mtspr   SPRN_MCSRR1,r0
563         lwz     r0,GPR0(r1)
564         lwz     r2,GPR2(r1)
565         lwz     r1,GPR1(r1)
566         SYNC
567         rfmci
568
569 /* Cache functions.
570 */
571 .globl invalidate_icache
572 invalidate_icache:
573         mfspr   r0,L1CSR1
574         ori     r0,r0,L1CSR1_ICFI
575         msync
576         isync
577         mtspr   L1CSR1,r0
578         isync
579         blr                             /* entire I cache */
580
581 .globl invalidate_dcache
582 invalidate_dcache:
583         mfspr   r0,L1CSR0
584         ori     r0,r0,L1CSR0_DCFI
585         msync
586         isync
587         mtspr   L1CSR0,r0
588         isync
589         blr
590
591         .globl  icache_enable
592 icache_enable:
593         mflr    r8
594         bl      invalidate_icache
595         mtlr    r8
596         isync
597         mfspr   r4,L1CSR1
598         ori     r4,r4,0x0001
599         oris    r4,r4,0x0001
600         mtspr   L1CSR1,r4
601         isync
602         blr
603
604         .globl  icache_disable
605 icache_disable:
606         mfspr   r0,L1CSR1
607         lis     r3,0
608         ori     r3,r3,L1CSR1_ICE
609         andc    r0,r0,r3
610         mtspr   L1CSR1,r0
611         isync
612         blr
613
614         .globl  icache_status
615 icache_status:
616         mfspr   r3,L1CSR1
617         andi.   r3,r3,L1CSR1_ICE
618         blr
619
620         .globl  dcache_enable
621 dcache_enable:
622         mflr    r8
623         bl      invalidate_dcache
624         mtlr    r8
625         isync
626         mfspr   r0,L1CSR0
627         ori     r0,r0,0x0001
628         oris    r0,r0,0x0001
629         msync
630         isync
631         mtspr   L1CSR0,r0
632         isync
633         blr
634
635         .globl  dcache_disable
636 dcache_disable:
637         mfspr   r3,L1CSR0
638         lis     r4,0
639         ori     r4,r4,L1CSR0_DCE
640         andc    r3,r3,r4
641         mtspr   L1CSR0,r0
642         isync
643         blr
644
645         .globl  dcache_status
646 dcache_status:
647         mfspr   r3,L1CSR0
648         andi.   r3,r3,L1CSR0_DCE
649         blr
650
651         .globl get_pir
652 get_pir:
653         mfspr   r3,PIR
654         blr
655
656         .globl get_pvr
657 get_pvr:
658         mfspr   r3,PVR
659         blr
660
661         .globl get_svr
662 get_svr:
663         mfspr   r3,SVR
664         blr
665
666         .globl wr_tcr
667 wr_tcr:
668         mtspr   TCR,r3
669         blr
670
671 /*------------------------------------------------------------------------------- */
672 /* Function:     in8 */
673 /* Description:  Input 8 bits */
674 /*------------------------------------------------------------------------------- */
675         .globl  in8
676 in8:
677         lbz     r3,0x0000(r3)
678         blr
679
680 /*------------------------------------------------------------------------------- */
681 /* Function:     out8 */
682 /* Description:  Output 8 bits */
683 /*------------------------------------------------------------------------------- */
684         .globl  out8
685 out8:
686         stb     r4,0x0000(r3)
687         sync
688         blr
689
690 /*------------------------------------------------------------------------------- */
691 /* Function:     out16 */
692 /* Description:  Output 16 bits */
693 /*------------------------------------------------------------------------------- */
694         .globl  out16
695 out16:
696         sth     r4,0x0000(r3)
697         sync
698         blr
699
700 /*------------------------------------------------------------------------------- */
701 /* Function:     out16r */
702 /* Description:  Byte reverse and output 16 bits */
703 /*------------------------------------------------------------------------------- */
704         .globl  out16r
705 out16r:
706         sthbrx  r4,r0,r3
707         sync
708         blr
709
710 /*------------------------------------------------------------------------------- */
711 /* Function:     out32 */
712 /* Description:  Output 32 bits */
713 /*------------------------------------------------------------------------------- */
714         .globl  out32
715 out32:
716         stw     r4,0x0000(r3)
717         sync
718         blr
719
720 /*------------------------------------------------------------------------------- */
721 /* Function:     out32r */
722 /* Description:  Byte reverse and output 32 bits */
723 /*------------------------------------------------------------------------------- */
724         .globl  out32r
725 out32r:
726         stwbrx  r4,r0,r3
727         sync
728         blr
729
730 /*------------------------------------------------------------------------------- */
731 /* Function:     in16 */
732 /* Description:  Input 16 bits */
733 /*------------------------------------------------------------------------------- */
734         .globl  in16
735 in16:
736         lhz     r3,0x0000(r3)
737         blr
738
739 /*------------------------------------------------------------------------------- */
740 /* Function:     in16r */
741 /* Description:  Input 16 bits and byte reverse */
742 /*------------------------------------------------------------------------------- */
743         .globl  in16r
744 in16r:
745         lhbrx   r3,r0,r3
746         blr
747
748 /*------------------------------------------------------------------------------- */
749 /* Function:     in32 */
750 /* Description:  Input 32 bits */
751 /*------------------------------------------------------------------------------- */
752         .globl  in32
753 in32:
754         lwz     3,0x0000(3)
755         blr
756
757 /*------------------------------------------------------------------------------- */
758 /* Function:     in32r */
759 /* Description:  Input 32 bits and byte reverse */
760 /*------------------------------------------------------------------------------- */
761         .globl  in32r
762 in32r:
763         lwbrx   r3,r0,r3
764         blr
765
766 /*------------------------------------------------------------------------------*/
767
768 /*
769  * void relocate_code (addr_sp, gd, addr_moni)
770  *
771  * This "function" does not return, instead it continues in RAM
772  * after relocating the monitor code.
773  *
774  * r3 = dest
775  * r4 = src
776  * r5 = length in bytes
777  * r6 = cachelinesize
778  */
779         .globl  relocate_code
780 relocate_code:
781         mr      r1,r3           /* Set new stack pointer                */
782         mr      r9,r4           /* Save copy of Init Data pointer       */
783         mr      r10,r5          /* Save copy of Destination Address     */
784
785         mr      r3,r5                           /* Destination Address  */
786         lis     r4,CONFIG_SYS_MONITOR_BASE@h            /* Source      Address  */
787         ori     r4,r4,CONFIG_SYS_MONITOR_BASE@l
788         lwz     r5,GOT(__init_end)
789         sub     r5,r5,r4
790         li      r6,CONFIG_SYS_CACHELINE_SIZE            /* Cache Line Size      */
791
792         /*
793          * Fix GOT pointer:
794          *
795          * New GOT-PTR = (old GOT-PTR - CONFIG_SYS_MONITOR_BASE) + Destination Address
796          *
797          * Offset:
798          */
799         sub     r15,r10,r4
800
801         /* First our own GOT */
802         add     r14,r14,r15
803         /* the the one used by the C code */
804         add     r30,r30,r15
805
806         /*
807          * Now relocate code
808          */
809
810         cmplw   cr1,r3,r4
811         addi    r0,r5,3
812         srwi.   r0,r0,2
813         beq     cr1,4f          /* In place copy is not necessary       */
814         beq     7f              /* Protect against 0 count              */
815         mtctr   r0
816         bge     cr1,2f
817
818         la      r8,-4(r4)
819         la      r7,-4(r3)
820 1:      lwzu    r0,4(r8)
821         stwu    r0,4(r7)
822         bdnz    1b
823         b       4f
824
825 2:      slwi    r0,r0,2
826         add     r8,r4,r0
827         add     r7,r3,r0
828 3:      lwzu    r0,-4(r8)
829         stwu    r0,-4(r7)
830         bdnz    3b
831
832 /*
833  * Now flush the cache: note that we must start from a cache aligned
834  * address. Otherwise we might miss one cache line.
835  */
836 4:      cmpwi   r6,0
837         add     r5,r3,r5
838         beq     7f              /* Always flush prefetch queue in any case */
839         subi    r0,r6,1
840         andc    r3,r3,r0
841         mr      r4,r3
842 5:      dcbst   0,r4
843         add     r4,r4,r6
844         cmplw   r4,r5
845         blt     5b
846         sync                    /* Wait for all dcbst to complete on bus */
847         mr      r4,r3
848 6:      icbi    0,r4
849         add     r4,r4,r6
850         cmplw   r4,r5
851         blt     6b
852 7:      sync                    /* Wait for all icbi to complete on bus */
853         isync
854
855         /*
856          * Re-point the IVPR at RAM
857          */
858         mtspr   IVPR,r10
859
860 /*
861  * We are done. Do not return, instead branch to second part of board
862  * initialization, now running from RAM.
863  */
864
865         addi    r0,r10,in_ram - _start + _START_OFFSET
866         mtlr    r0
867         blr                             /* NEVER RETURNS! */
868         .globl  in_ram
869 in_ram:
870
871         /*
872          * Relocation Function, r14 point to got2+0x8000
873          *
874          * Adjust got2 pointers, no need to check for 0, this code
875          * already puts a few entries in the table.
876          */
877         li      r0,__got2_entries@sectoff@l
878         la      r3,GOT(_GOT2_TABLE_)
879         lwz     r11,GOT(_GOT2_TABLE_)
880         mtctr   r0
881         sub     r11,r3,r11
882         addi    r3,r3,-4
883 1:      lwzu    r0,4(r3)
884         add     r0,r0,r11
885         stw     r0,0(r3)
886         bdnz    1b
887
888         /*
889          * Now adjust the fixups and the pointers to the fixups
890          * in case we need to move ourselves again.
891          */
892 2:      li      r0,__fixup_entries@sectoff@l
893         lwz     r3,GOT(_FIXUP_TABLE_)
894         cmpwi   r0,0
895         mtctr   r0
896         addi    r3,r3,-4
897         beq     4f
898 3:      lwzu    r4,4(r3)
899         lwzux   r0,r4,r11
900         add     r0,r0,r11
901         stw     r10,0(r3)
902         stw     r0,0(r4)
903         bdnz    3b
904 4:
905 clear_bss:
906         /*
907          * Now clear BSS segment
908          */
909         lwz     r3,GOT(__bss_start)
910         lwz     r4,GOT(_end)
911
912         cmplw   0,r3,r4
913         beq     6f
914
915         li      r0,0
916 5:
917         stw     r0,0(r3)
918         addi    r3,r3,4
919         cmplw   0,r3,r4
920         bne     5b
921 6:
922
923         mr      r3,r9           /* Init Data pointer            */
924         mr      r4,r10          /* Destination Address          */
925         bl      board_init_r
926
927         /*
928          * Copy exception vector code to low memory
929          *
930          * r3: dest_addr
931          * r7: source address, r8: end address, r9: target address
932          */
933         .globl  trap_init
934 trap_init:
935         lwz     r7,GOT(_start_of_vectors)
936         lwz     r8,GOT(_end_of_vectors)
937
938         li      r9,0x100                /* reset vector always at 0x100 */
939
940         cmplw   0,r7,r8
941         bgelr                           /* return if r7>=r8 - just in case */
942
943         mflr    r4                      /* save link register           */
944 1:
945         lwz     r0,0(r7)
946         stw     r0,0(r9)
947         addi    r7,r7,4
948         addi    r9,r9,4
949         cmplw   0,r7,r8
950         bne     1b
951
952         /*
953          * relocate `hdlr' and `int_return' entries
954          */
955         li      r7,.L_CriticalInput - _start + _START_OFFSET
956         bl      trap_reloc
957         li      r7,.L_MachineCheck - _start + _START_OFFSET
958         bl      trap_reloc
959         li      r7,.L_DataStorage - _start + _START_OFFSET
960         bl      trap_reloc
961         li      r7,.L_InstStorage - _start + _START_OFFSET
962         bl      trap_reloc
963         li      r7,.L_ExtInterrupt - _start + _START_OFFSET
964         bl      trap_reloc
965         li      r7,.L_Alignment - _start + _START_OFFSET
966         bl      trap_reloc
967         li      r7,.L_ProgramCheck - _start + _START_OFFSET
968         bl      trap_reloc
969         li      r7,.L_FPUnavailable - _start + _START_OFFSET
970         bl      trap_reloc
971         li      r7,.L_Decrementer - _start + _START_OFFSET
972         bl      trap_reloc
973         li      r7,.L_IntervalTimer - _start + _START_OFFSET
974         li      r8,_end_of_vectors - _start + _START_OFFSET
975 2:
976         bl      trap_reloc
977         addi    r7,r7,0x100             /* next exception vector        */
978         cmplw   0,r7,r8
979         blt     2b
980
981         lis     r7,0x0
982         mtspr   IVPR,r7
983
984         mtlr    r4                      /* restore link register        */
985         blr
986
987         /*
988          * Function: relocate entries for one exception vector
989          */
990 trap_reloc:
991         lwz     r0,0(r7)                /* hdlr ...                     */
992         add     r0,r0,r3                /*  ... += dest_addr            */
993         stw     r0,0(r7)
994
995         lwz     r0,4(r7)                /* int_return ...               */
996         add     r0,r0,r3                /*  ... += dest_addr            */
997         stw     r0,4(r7)
998
999         blr
1000
1001 .globl unlock_ram_in_cache
1002 unlock_ram_in_cache:
1003         /* invalidate the INIT_RAM section */
1004         lis     r3,(CONFIG_SYS_INIT_RAM_ADDR & ~(CONFIG_SYS_CACHELINE_SIZE-1))@h
1005         ori     r3,r3,(CONFIG_SYS_INIT_RAM_ADDR & ~(CONFIG_SYS_CACHELINE_SIZE-1))@l
1006         mfspr   r4,L1CFG0
1007         andi.   r4,r4,0x1ff
1008         slwi    r4,r4,(10 - 1 - L1_CACHE_SHIFT)
1009         mtctr   r4
1010 1:      dcbi    r0,r3
1011         addi    r3,r3,CONFIG_SYS_CACHELINE_SIZE
1012         bdnz    1b
1013         sync
1014
1015         /* Invalidate the TLB entries for the cache */
1016         lis     r3,CONFIG_SYS_INIT_RAM_ADDR@h
1017         ori     r3,r3,CONFIG_SYS_INIT_RAM_ADDR@l
1018         tlbivax 0,r3
1019         addi    r3,r3,0x1000
1020         tlbivax 0,r3
1021         addi    r3,r3,0x1000
1022         tlbivax 0,r3
1023         addi    r3,r3,0x1000
1024         tlbivax 0,r3
1025         isync
1026         blr
1027
1028 .globl flush_dcache
1029 flush_dcache:
1030         mfspr   r3,SPRN_L1CFG0
1031
1032         rlwinm  r5,r3,9,3       /* Extract cache block size */
1033         twlgti  r5,1            /* Only 32 and 64 byte cache blocks
1034                                  * are currently defined.
1035                                  */
1036         li      r4,32
1037         subfic  r6,r5,2         /* r6 = log2(1KiB / cache block size) -
1038                                  *      log2(number of ways)
1039                                  */
1040         slw     r5,r4,r5        /* r5 = cache block size */
1041
1042         rlwinm  r7,r3,0,0xff    /* Extract number of KiB in the cache */
1043         mulli   r7,r7,13        /* An 8-way cache will require 13
1044                                  * loads per set.
1045                                  */
1046         slw     r7,r7,r6
1047
1048         /* save off HID0 and set DCFA */
1049         mfspr   r8,SPRN_HID0
1050         ori     r9,r8,HID0_DCFA@l
1051         mtspr   SPRN_HID0,r9
1052         isync
1053
1054         lis     r4,0
1055         mtctr   r7
1056
1057 1:      lwz     r3,0(r4)        /* Load... */
1058         add     r4,r4,r5
1059         bdnz    1b
1060
1061         msync
1062         lis     r4,0
1063         mtctr   r7
1064
1065 1:      dcbf    0,r4            /* ...and flush. */
1066         add     r4,r4,r5
1067         bdnz    1b
1068
1069         /* restore HID0 */
1070         mtspr   SPRN_HID0,r8
1071         isync
1072
1073         blr