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