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