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