Merge branch 'master' of git://git.denx.de/u-boot-arm
[platform/kernel/u-boot.git] / arch / powerpc / cpu / mpc824x / start.S
1 /*
2  *  Copyright (C) 1998  Dan Malek <dmalek@jlc.net>
3  *  Copyright (C) 1999  Magnus Damm <kieraypc01.p.y.kie.era.ericsson.se>
4  *  Copyright (C) 2000,2001,2002 Wolfgang Denk <wd@denx.de>
5  *
6  * See file CREDITS for list of people who contributed to this
7  * project.
8  *
9  * This program is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU General Public License as
11  * published by the Free Software Foundation; either version 2 of
12  * the License, or (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
22  * MA 02111-1307 USA
23  */
24
25 /* U-Boot - Startup Code for PowerPC based Embedded Boards
26  *
27  *
28  * The processor starts at 0x00000100 and the code is executed
29  * from flash. The code is organized to be at an other address
30  * in memory, but as long we don't jump around before relocating.
31  * board_init lies at a quite high address and when the cpu has
32  * jumped there, everything is ok.
33  * This works because the cpu gives the FLASH (CS0) the whole
34  * address space at startup, and board_init lies as a echo of
35  * the flash somewhere up there in the memorymap.
36  *
37  * board_init will change CS0 to be positioned at the correct
38  * address and (s)dram will be positioned at address 0
39  */
40 #include <asm-offsets.h>
41 #include <config.h>
42 #include <mpc824x.h>
43 #include <version.h>
44
45 #define _LINUX_CONFIG_H 1       /* avoid reading Linux autoconf.h file  */
46
47 #include <ppc_asm.tmpl>
48 #include <ppc_defs.h>
49
50 #include <asm/cache.h>
51 #include <asm/mmu.h>
52 #include <asm/u-boot.h>
53
54 /* We don't want the MMU yet.
55 */
56 #undef  MSR_KERNEL
57 /* FP, Machine Check and Recoverable Interr. */
58 #define MSR_KERNEL ( MSR_FP | MSR_ME | MSR_RI )
59
60 /*
61  * Set up GOT: Global Offset Table
62  *
63  * Use r12 to access the GOT
64  */
65         START_GOT
66         GOT_ENTRY(_GOT2_TABLE_)
67         GOT_ENTRY(_FIXUP_TABLE_)
68
69         GOT_ENTRY(_start)
70         GOT_ENTRY(_start_of_vectors)
71         GOT_ENTRY(_end_of_vectors)
72         GOT_ENTRY(transfer_to_handler)
73
74         GOT_ENTRY(__init_end)
75         GOT_ENTRY(__bss_end__)
76         GOT_ENTRY(__bss_start)
77 #if defined(CONFIG_FADS)
78         GOT_ENTRY(environment)
79 #endif
80         END_GOT
81
82 /*
83  * r3 - 1st arg to board_init(): IMMP pointer
84  * r4 - 2nd arg to board_init(): boot flag
85  */
86         .text
87         .long   0x27051956              /* U-Boot Magic Number                  */
88         .globl  version_string
89 version_string:
90         .ascii U_BOOT_VERSION_STRING, "\0"
91
92         . = EXC_OFF_SYS_RESET
93         .globl  _start
94 _start:
95         /* Initialize machine status; enable machine check interrupt            */
96         /*----------------------------------------------------------------------*/
97         li      r3, MSR_KERNEL          /* Set FP, ME, RI flags */
98         mtmsr   r3
99         mtspr   SRR1, r3                /* Make SRR1 match MSR */
100
101         addis   r0,0,0x0000             /* lets make sure that r0 is really 0 */
102         mtspr   HID0, r0                /* disable I and D caches */
103
104         mfspr   r3, ICR                 /* clear Interrupt Cause Register */
105
106         mfmsr   r3                      /* turn off address translation */
107         addis   r4,0,0xffff
108         ori     r4,r4,0xffcf
109         and     r3,r3,r4
110         mtmsr   r3
111         isync
112         sync                            /* the MMU should be off... */
113
114
115 in_flash:
116         /*
117          * Setup BATs - cannot be done in C since we don't have a stack yet
118          */
119         bl      setup_bats
120
121         /* Enable MMU.
122          */
123         mfmsr   r3
124         ori     r3, r3, (MSR_IR | MSR_DR)
125         mtmsr   r3
126
127         /* Enable and invalidate data cache.
128          */
129         mfspr   r3, HID0
130         mr      r2, r3
131         ori     r3, r3, HID0_DCE | HID0_DCI
132         ori     r2, r2, HID0_DCE
133         sync
134         mtspr   HID0, r3
135         mtspr   HID0, r2
136         sync
137
138         /* Allocate Initial RAM in data cache.
139          */
140         lis     r3, CONFIG_SYS_INIT_RAM_ADDR@h
141         ori     r3, r3, CONFIG_SYS_INIT_RAM_ADDR@l
142         li      r2, 128
143         mtctr   r2
144 1:
145         dcbz    r0, r3
146         addi    r3, r3, 32
147         bdnz    1b
148
149         /* Lock way0 in data cache.
150          */
151         mfspr   r3, 1011
152         lis     r2, 0xffff
153         ori     r2, r2, 0xff1f
154         and     r3, r3, r2
155         ori     r3, r3, 0x0080
156         sync
157         mtspr   1011, r3
158
159         /*
160          * Thisk the stack pointer *somewhere* sensible. Doesnt
161          * matter much where as we'll move it when we relocate
162          */
163         lis     r1, (CONFIG_SYS_INIT_RAM_ADDR + CONFIG_SYS_GBL_DATA_OFFSET)@h
164         ori     r1, r1, (CONFIG_SYS_INIT_RAM_ADDR + CONFIG_SYS_GBL_DATA_OFFSET)@l
165
166         li      r0, 0                   /* Make room for stack frame header and */
167         stwu    r0, -4(r1)              /* clear final stack frame so that      */
168         stwu    r0, -4(r1)              /* stack backtraces terminate cleanly   */
169
170         /* let the C-code set up the rest                                       */
171         /*                                                                      */
172         /* Be careful to keep code relocatable !                                */
173         /*----------------------------------------------------------------------*/
174
175         GET_GOT                 /* initialize GOT access                        */
176
177         /* r3: IMMR */
178         bl      cpu_init_f      /* run low-level CPU init code     (from Flash) */
179
180         bl      board_init_f    /* run 1st part of board init code (from Flash) */
181
182         /* NOTREACHED - board_init_f() does not return */
183
184
185         .globl  _start_of_vectors
186 _start_of_vectors:
187
188 /* Machine check */
189         STD_EXCEPTION(EXC_OFF_MACH_CHCK, MachineCheck, MachineCheckException)
190
191 /* Data Storage exception.  "Never" generated on the 860. */
192         STD_EXCEPTION(EXC_OFF_DATA_STOR, DataStorage, UnknownException)
193
194 /* Instruction Storage exception.  "Never" generated on the 860. */
195         STD_EXCEPTION(EXC_OFF_INS_STOR, InstStorage, UnknownException)
196
197 /* External Interrupt exception. */
198         STD_EXCEPTION(EXC_OFF_EXTERNAL, ExtInterrupt, external_interrupt)
199
200 /* Alignment exception. */
201         . = EXC_OFF_ALIGN
202 Alignment:
203         EXCEPTION_PROLOG(SRR0, SRR1)
204         mfspr   r4,DAR
205         stw     r4,_DAR(r21)
206         mfspr   r5,DSISR
207         stw     r5,_DSISR(r21)
208         addi    r3,r1,STACK_FRAME_OVERHEAD
209         EXC_XFER_TEMPLATE(Alignment, AlignmentException, MSR_KERNEL, COPY_EE)
210
211 /* Program check exception */
212         . = EXC_OFF_PROGRAM
213 ProgramCheck:
214         EXCEPTION_PROLOG(SRR0, SRR1)
215         addi    r3,r1,STACK_FRAME_OVERHEAD
216         EXC_XFER_TEMPLATE(ProgramCheck, ProgramCheckException,
217                 MSR_KERNEL, COPY_EE)
218
219         /* No FPU on MPC8xx. This exception is not supposed to happen.
220         */
221         STD_EXCEPTION(EXC_OFF_FPUNAVAIL, FPUnavailable, UnknownException)
222
223         /* I guess we could implement decrementer, and may have
224          * to someday for timekeeping.
225          */
226         STD_EXCEPTION(EXC_OFF_DECR, Decrementer, timer_interrupt)
227         STD_EXCEPTION(0xa00, Trap_0a, UnknownException)
228         STD_EXCEPTION(0xb00, Trap_0b, UnknownException)
229         STD_EXCEPTION(0xc00, SystemCall, UnknownException)
230
231         STD_EXCEPTION(EXC_OFF_TRACE, SingleStep, UnknownException)
232
233         STD_EXCEPTION(EXC_OFF_FPUNASSIST, Trap_0e, UnknownException)
234         STD_EXCEPTION(EXC_OFF_PMI, Trap_0f, UnknownException)
235
236         STD_EXCEPTION(EXC_OFF_ITME, InstructionTransMiss, UnknownException)
237         STD_EXCEPTION(EXC_OFF_DLTME, DataLoadTransMiss, UnknownException)
238         STD_EXCEPTION(EXC_OFF_DSTME, DataStoreTransMiss, UnknownException)
239         STD_EXCEPTION(EXC_OFF_IABE, InstructionBreakpoint, DebugException)
240         STD_EXCEPTION(EXC_OFF_SMIE, SysManageInt, UnknownException)
241         STD_EXCEPTION(0x1500, Reserved5, UnknownException)
242         STD_EXCEPTION(0x1600, Reserved6, UnknownException)
243         STD_EXCEPTION(0x1700, Reserved7, UnknownException)
244         STD_EXCEPTION(0x1800, Reserved8, UnknownException)
245         STD_EXCEPTION(0x1900, Reserved9, UnknownException)
246         STD_EXCEPTION(0x1a00, ReservedA, UnknownException)
247         STD_EXCEPTION(0x1b00, ReservedB, UnknownException)
248         STD_EXCEPTION(0x1c00, ReservedC, UnknownException)
249         STD_EXCEPTION(0x1d00, ReservedD, UnknownException)
250         STD_EXCEPTION(0x1e00, ReservedE, UnknownException)
251         STD_EXCEPTION(0x1f00, ReservedF, UnknownException)
252
253         STD_EXCEPTION(EXC_OFF_RMTE, RunModeTrace, UnknownException)
254
255         .globl  _end_of_vectors
256 _end_of_vectors:
257
258
259         . = 0x3000
260
261 /*
262  * This code finishes saving the registers to the exception frame
263  * and jumps to the appropriate handler for the exception.
264  * Register r21 is pointer into trap frame, r1 has new stack pointer.
265  */
266         .globl  transfer_to_handler
267 transfer_to_handler:
268         stw     r22,_NIP(r21)
269         lis     r22,MSR_POW@h
270         andc    r23,r23,r22
271         stw     r23,_MSR(r21)
272         SAVE_GPR(7, r21)
273         SAVE_4GPRS(8, r21)
274         SAVE_8GPRS(12, r21)
275         SAVE_8GPRS(24, r21)
276 #if 0
277         andi.   r23,r23,MSR_PR
278         mfspr   r23,SPRG3               /* if from user, fix up tss.regs */
279         beq     2f
280         addi    r24,r1,STACK_FRAME_OVERHEAD
281         stw     r24,PT_REGS(r23)
282 2:      addi    r2,r23,-TSS             /* set r2 to current */
283         tovirt(r2,r2,r23)
284 #endif
285         mflr    r23
286         andi.   r24,r23,0x3f00          /* get vector offset */
287         stw     r24,TRAP(r21)
288         li      r22,0
289         stw     r22,RESULT(r21)
290         mtspr   SPRG2,r22               /* r1 is now kernel sp */
291 #if 0
292         addi    r24,r2,TASK_STRUCT_SIZE /* check for kernel stack overflow */
293         cmplw   0,r1,r2
294         cmplw   1,r1,r24
295         crand   1,1,4
296         bgt     stack_ovf               /* if r2 < r1 < r2+TASK_STRUCT_SIZE */
297 #endif
298         lwz     r24,0(r23)              /* virtual address of handler */
299         lwz     r23,4(r23)              /* where to go when done */
300         mtspr   SRR0,r24
301         ori     r20,r20,0x30            /* enable IR, DR */
302         mtspr   SRR1,r20
303         mtlr    r23
304         SYNC
305         rfi                             /* jump to handler, enable MMU */
306
307 int_return:
308         mfmsr   r28             /* Disable interrupts */
309         li      r4,0
310         ori     r4,r4,MSR_EE
311         andc    r28,r28,r4
312         SYNC                    /* Some chip revs need this... */
313         mtmsr   r28
314         SYNC
315         lwz     r2,_CTR(r1)
316         lwz     r0,_LINK(r1)
317         mtctr   r2
318         mtlr    r0
319         lwz     r2,_XER(r1)
320         lwz     r0,_CCR(r1)
321         mtspr   XER,r2
322         mtcrf   0xFF,r0
323         REST_10GPRS(3, r1)
324         REST_10GPRS(13, r1)
325         REST_8GPRS(23, r1)
326         REST_GPR(31, r1)
327         lwz     r2,_NIP(r1)     /* Restore environment */
328         lwz     r0,_MSR(r1)
329         mtspr   SRR0,r2
330         mtspr   SRR1,r0
331         lwz     r0,GPR0(r1)
332         lwz     r2,GPR2(r1)
333         lwz     r1,GPR1(r1)
334         SYNC
335         rfi
336
337 /* Cache functions.
338 */
339         .globl  icache_enable
340 icache_enable:
341         mfspr   r5,HID0         /* turn on the I cache. */
342         ori     r5,r5,0x8800    /* Instruction cache only! */
343         addis   r6,0,0xFFFF
344         ori     r6,r6,0xF7FF
345         and     r6,r5,r6        /* clear the invalidate bit */
346         sync
347         mtspr   HID0,r5
348         mtspr   HID0,r6
349         isync
350         sync
351         blr
352
353         .globl  icache_disable
354 icache_disable:
355         mfspr   r5,HID0
356         addis   r6,0,0xFFFF
357         ori     r6,r6,0x7FFF
358         and     r5,r5,r6
359         sync
360         mtspr   HID0,r5
361         isync
362         sync
363         blr
364
365         .globl  icache_status
366 icache_status:
367         mfspr   r3, HID0
368         srwi    r3, r3, 15      /* >>15 & 1=> select bit 16 */
369         andi.   r3, r3, 1
370         blr
371
372         .globl  dcache_enable
373 dcache_enable:
374         mfspr   r5,HID0         /* turn on the D cache. */
375         ori     r5,r5,0x4400    /* Data cache only! */
376         mfspr   r4, PVR         /* read PVR */
377         srawi   r3, r4, 16      /* shift off the least 16 bits */
378         cmpi    0, 0, r3, 0xC   /* Check for Max pvr */
379         bne     NotMax
380         ori     r5,r5,0x0040    /* setting the DCFA bit, for Max rev 1 errata */
381 NotMax:
382         addis   r6,0,0xFFFF
383         ori     r6,r6,0xFBFF
384         and     r6,r5,r6        /* clear the invalidate bit */
385         sync
386         mtspr   HID0,r5
387         mtspr   HID0,r6
388         isync
389         sync
390         blr
391
392         .globl  dcache_disable
393 dcache_disable:
394         mfspr   r5,HID0
395         addis   r6,0,0xFFFF
396         ori     r6,r6,0xBFFF
397         and     r5,r5,r6
398         sync
399         mtspr   HID0,r5
400         isync
401         sync
402         blr
403
404         .globl  dcache_status
405 dcache_status:
406         mfspr   r3, HID0
407         srwi    r3, r3, 14      /* >>14 & 1=> select bit 17 */
408         andi.   r3, r3, 1
409         blr
410
411         .globl  dc_read
412 dc_read:
413 /*TODO : who uses this, what should it do?
414 */
415         blr
416
417
418         .globl get_pvr
419 get_pvr:
420         mfspr   r3, PVR
421         blr
422
423
424 /*------------------------------------------------------------------------------*/
425
426 /*
427  * void relocate_code (addr_sp, gd, addr_moni)
428  *
429  * This "function" does not return, instead it continues in RAM
430  * after relocating the monitor code.
431  *
432  * r3 = dest
433  * r4 = src
434  * r5 = length in bytes
435  * r6 = cachelinesize
436  */
437         .globl  relocate_code
438 relocate_code:
439
440         mr      r1,  r3         /* Set new stack pointer                */
441         mr      r9,  r4         /* Save copy of Global Data pointer     */
442         mr      r10, r5         /* Save copy of Destination Address     */
443
444         GET_GOT
445         mr      r3,  r5                         /* Destination Address  */
446 #ifdef CONFIG_SYS_RAMBOOT
447         lis     r4, CONFIG_SYS_SDRAM_BASE@h             /* Source      Address  */
448         ori     r4, r4, CONFIG_SYS_SDRAM_BASE@l
449 #else
450         lis     r4, CONFIG_SYS_MONITOR_BASE@h           /* Source      Address  */
451         ori     r4, r4, CONFIG_SYS_MONITOR_BASE@l
452 #endif
453         lwz     r5, GOT(__init_end)
454         sub     r5, r5, r4
455         li      r6, CONFIG_SYS_CACHELINE_SIZE           /* Cache Line Size      */
456
457         /*
458          * Fix GOT pointer:
459          *
460          * New GOT-PTR = (old GOT-PTR - CONFIG_SYS_MONITOR_BASE) + Destination Address
461          *
462          * Offset:
463          */
464         sub     r15, r10, r4
465
466         /* First our own GOT */
467         add     r12, r12, r15
468         /* the the one used by the C code */
469         add     r30, r30, r15
470
471         /*
472          * Now relocate code
473          */
474
475         cmplw   cr1,r3,r4
476         addi    r0,r5,3
477         srwi.   r0,r0,2
478         beq     cr1,4f          /* In place copy is not necessary       */
479         beq     7f              /* Protect against 0 count              */
480         mtctr   r0
481         bge     cr1,2f
482
483         la      r8,-4(r4)
484         la      r7,-4(r3)
485 1:      lwzu    r0,4(r8)
486         stwu    r0,4(r7)
487         bdnz    1b
488         b       4f
489
490 2:      slwi    r0,r0,2
491         add     r8,r4,r0
492         add     r7,r3,r0
493 3:      lwzu    r0,-4(r8)
494         stwu    r0,-4(r7)
495         bdnz    3b
496
497 4:
498 /* Unlock the data cache and invalidate locked area */
499         xor     r0, r0, r0
500         mtspr   1011, r0
501         lis     r4, CONFIG_SYS_INIT_RAM_ADDR@h
502         ori     r4, r4, CONFIG_SYS_INIT_RAM_ADDR@l
503         li      r0, 128
504         mtctr   r0
505 41:
506         dcbi    r0, r4
507         addi    r4, r4, 32
508         bdnz    41b
509
510 /*
511  * Now flush the cache: note that we must start from a cache aligned
512  * address. Otherwise we might miss one cache line.
513  */
514         cmpwi   r6,0
515         add     r5,r3,r5
516         beq     7f              /* Always flush prefetch queue in any case */
517         subi    r0,r6,1
518         andc    r3,r3,r0
519         mr      r4,r3
520 5:      dcbst   0,r4
521         add     r4,r4,r6
522         cmplw   r4,r5
523         blt     5b
524         sync                    /* Wait for all dcbst to complete on bus */
525         mr      r4,r3
526 6:      icbi    0,r4
527         add     r4,r4,r6
528         cmplw   r4,r5
529         blt     6b
530 7:      sync                    /* Wait for all icbi to complete on bus */
531         isync
532
533 /*
534  * We are done. Do not return, instead branch to second part of board
535  * initialization, now running from RAM.
536  */
537
538         addi    r0, r10, in_ram - _start + EXC_OFF_SYS_RESET
539         mtlr    r0
540         blr
541
542 in_ram:
543
544         /*
545          * Relocation Function, r12 point to got2+0x8000
546          *
547          * Adjust got2 pointers, no need to check for 0, this code
548          * already puts a few entries in the table.
549          */
550         li      r0,__got2_entries@sectoff@l
551         la      r3,GOT(_GOT2_TABLE_)
552         lwz     r11,GOT(_GOT2_TABLE_)
553         mtctr   r0
554         sub     r11,r3,r11
555         addi    r3,r3,-4
556 1:      lwzu    r0,4(r3)
557         cmpwi   r0,0
558         beq-    2f
559         add     r0,r0,r11
560         stw     r0,0(r3)
561 2:      bdnz    1b
562
563         /*
564          * Now adjust the fixups and the pointers to the fixups
565          * in case we need to move ourselves again.
566          */
567         li      r0,__fixup_entries@sectoff@l
568         lwz     r3,GOT(_FIXUP_TABLE_)
569         cmpwi   r0,0
570         mtctr   r0
571         addi    r3,r3,-4
572         beq     4f
573 3:      lwzu    r4,4(r3)
574         lwzux   r0,r4,r11
575         cmpwi   r0,0
576         add     r0,r0,r11
577         stw     r4,0(r3)
578         beq-    5f
579         stw     r0,0(r4)
580 5:      bdnz    3b
581 4:
582 clear_bss:
583         /*
584          * Now clear BSS segment
585          */
586         lwz     r3,GOT(__bss_start)
587         lwz     r4,GOT(__bss_end__)
588
589         cmplw   0, r3, r4
590         beq     6f
591
592         li      r0, 0
593 5:
594         stw     r0, 0(r3)
595         addi    r3, r3, 4
596         cmplw   0, r3, r4
597         blt     5b
598 6:
599
600         mr      r3, r9          /* Global Data pointer          */
601         mr      r4, r10         /* Destination Address          */
602         bl      board_init_r
603
604         /*
605          * Copy exception vector code to low memory
606          *
607          * r3: dest_addr
608          * r7: source address, r8: end address, r9: target address
609          */
610         .globl  trap_init
611 trap_init:
612         mflr    r4                      /* save link register           */
613         GET_GOT
614         lwz     r7, GOT(_start)
615         lwz     r8, GOT(_end_of_vectors)
616
617         li      r9, 0x100               /* reset vector always at 0x100 */
618
619         cmplw   0, r7, r8
620         bgelr                           /* return if r7>=r8 - just in case */
621 1:
622         lwz     r0, 0(r7)
623         stw     r0, 0(r9)
624         addi    r7, r7, 4
625         addi    r9, r9, 4
626         cmplw   0, r7, r8
627         bne     1b
628
629         /*
630          * relocate `hdlr' and `int_return' entries
631          */
632         li      r7, .L_MachineCheck - _start + EXC_OFF_SYS_RESET
633         li      r8, Alignment - _start + EXC_OFF_SYS_RESET
634 2:
635         bl      trap_reloc
636         addi    r7, r7, 0x100           /* next exception vector        */
637         cmplw   0, r7, r8
638         blt     2b
639
640         li      r7, .L_Alignment - _start + EXC_OFF_SYS_RESET
641         bl      trap_reloc
642
643         li      r7, .L_ProgramCheck - _start + EXC_OFF_SYS_RESET
644         bl      trap_reloc
645
646         li      r7, .L_FPUnavailable - _start + EXC_OFF_SYS_RESET
647         li      r8, SystemCall - _start + EXC_OFF_SYS_RESET
648 3:
649         bl      trap_reloc
650         addi    r7, r7, 0x100           /* next exception vector        */
651         cmplw   0, r7, r8
652         blt     3b
653
654         li      r7, .L_SingleStep - _start + EXC_OFF_SYS_RESET
655         li      r8, _end_of_vectors - _start + EXC_OFF_SYS_RESET
656 4:
657         bl      trap_reloc
658         addi    r7, r7, 0x100           /* next exception vector        */
659         cmplw   0, r7, r8
660         blt     4b
661
662         mtlr    r4                      /* restore link register        */
663         blr
664
665         /* Setup the BAT registers.
666          */
667 setup_bats:
668         lis     r4, CONFIG_SYS_IBAT0L@h
669         ori     r4, r4, CONFIG_SYS_IBAT0L@l
670         lis     r3, CONFIG_SYS_IBAT0U@h
671         ori     r3, r3, CONFIG_SYS_IBAT0U@l
672         mtspr   IBAT0L, r4
673         mtspr   IBAT0U, r3
674         isync
675
676         lis     r4, CONFIG_SYS_DBAT0L@h
677         ori     r4, r4, CONFIG_SYS_DBAT0L@l
678         lis     r3, CONFIG_SYS_DBAT0U@h
679         ori     r3, r3, CONFIG_SYS_DBAT0U@l
680         mtspr   DBAT0L, r4
681         mtspr   DBAT0U, r3
682         isync
683
684         lis     r4, CONFIG_SYS_IBAT1L@h
685         ori     r4, r4, CONFIG_SYS_IBAT1L@l
686         lis     r3, CONFIG_SYS_IBAT1U@h
687         ori     r3, r3, CONFIG_SYS_IBAT1U@l
688         mtspr   IBAT1L, r4
689         mtspr   IBAT1U, r3
690         isync
691
692         lis     r4, CONFIG_SYS_DBAT1L@h
693         ori     r4, r4, CONFIG_SYS_DBAT1L@l
694         lis     r3, CONFIG_SYS_DBAT1U@h
695         ori     r3, r3, CONFIG_SYS_DBAT1U@l
696         mtspr   DBAT1L, r4
697         mtspr   DBAT1U, r3
698         isync
699
700         lis     r4, CONFIG_SYS_IBAT2L@h
701         ori     r4, r4, CONFIG_SYS_IBAT2L@l
702         lis     r3, CONFIG_SYS_IBAT2U@h
703         ori     r3, r3, CONFIG_SYS_IBAT2U@l
704         mtspr   IBAT2L, r4
705         mtspr   IBAT2U, r3
706         isync
707
708         lis     r4, CONFIG_SYS_DBAT2L@h
709         ori     r4, r4, CONFIG_SYS_DBAT2L@l
710         lis     r3, CONFIG_SYS_DBAT2U@h
711         ori     r3, r3, CONFIG_SYS_DBAT2U@l
712         mtspr   DBAT2L, r4
713         mtspr   DBAT2U, r3
714         isync
715
716         lis     r4, CONFIG_SYS_IBAT3L@h
717         ori     r4, r4, CONFIG_SYS_IBAT3L@l
718         lis     r3, CONFIG_SYS_IBAT3U@h
719         ori     r3, r3, CONFIG_SYS_IBAT3U@l
720         mtspr   IBAT3L, r4
721         mtspr   IBAT3U, r3
722         isync
723
724         lis     r4, CONFIG_SYS_DBAT3L@h
725         ori     r4, r4, CONFIG_SYS_DBAT3L@l
726         lis     r3, CONFIG_SYS_DBAT3U@h
727         ori     r3, r3, CONFIG_SYS_DBAT3U@l
728         mtspr   DBAT3L, r4
729         mtspr   DBAT3U, r3
730         isync
731
732         /* Invalidate TLBs.
733          * -> for (val = 0; val < 0x20000; val+=0x1000)
734          * ->   tlbie(val);
735          */
736         lis     r3, 0
737         lis     r5, 2
738
739 1:
740         tlbie   r3
741         addi    r3, r3, 0x1000
742         cmp     0, 0, r3, r5
743         blt     1b
744
745         blr