Linux 6.9-rc1
[linux-2.6-microblaze.git] / arch / powerpc / kernel / head_book3s_32.S
1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2 /*
3  *  PowerPC version
4  *    Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
5  *
6  *  Rewritten by Cort Dougan (cort@cs.nmt.edu) for PReP
7  *    Copyright (C) 1996 Cort Dougan <cort@cs.nmt.edu>
8  *  Adapted for Power Macintosh by Paul Mackerras.
9  *  Low-level exception handlers and MMU support
10  *  rewritten by Paul Mackerras.
11  *    Copyright (C) 1996 Paul Mackerras.
12  *  MPC8xx modifications Copyright (C) 1997 Dan Malek (dmalek@jlc.net).
13  *
14  *  This file contains the low-level support and setup for the
15  *  PowerPC platform, including trap and interrupt dispatch.
16  *  (The PPC 8xx embedded CPUs use head_8xx.S instead.)
17  */
18
19 #include <linux/init.h>
20 #include <linux/pgtable.h>
21 #include <linux/linkage.h>
22
23 #include <asm/reg.h>
24 #include <asm/page.h>
25 #include <asm/mmu.h>
26 #include <asm/cputable.h>
27 #include <asm/cache.h>
28 #include <asm/thread_info.h>
29 #include <asm/ppc_asm.h>
30 #include <asm/asm-offsets.h>
31 #include <asm/ptrace.h>
32 #include <asm/bug.h>
33 #include <asm/kvm_book3s_asm.h>
34 #include <asm/feature-fixups.h>
35 #include <asm/interrupt.h>
36
37 #include "head_32.h"
38
39 #define LOAD_BAT(n, reg, RA, RB)        \
40         /* see the comment for clear_bats() -- Cort */ \
41         li      RA,0;                   \
42         mtspr   SPRN_IBAT##n##U,RA;     \
43         mtspr   SPRN_DBAT##n##U,RA;     \
44         lwz     RA,(n*16)+0(reg);       \
45         lwz     RB,(n*16)+4(reg);       \
46         mtspr   SPRN_IBAT##n##U,RA;     \
47         mtspr   SPRN_IBAT##n##L,RB;     \
48         lwz     RA,(n*16)+8(reg);       \
49         lwz     RB,(n*16)+12(reg);      \
50         mtspr   SPRN_DBAT##n##U,RA;     \
51         mtspr   SPRN_DBAT##n##L,RB
52
53         __HEAD
54 _GLOBAL(_stext);
55
56 /*
57  * _start is defined this way because the XCOFF loader in the OpenFirmware
58  * on the powermac expects the entry point to be a procedure descriptor.
59  */
60 _GLOBAL(_start);
61         /*
62          * These are here for legacy reasons, the kernel used to
63          * need to look like a coff function entry for the pmac
64          * but we're always started by some kind of bootloader now.
65          *  -- Cort
66          */
67         nop     /* used by __secondary_hold on prep (mtx) and chrp smp */
68         nop     /* used by __secondary_hold on prep (mtx) and chrp smp */
69         nop
70
71 /* PMAC
72  * Enter here with the kernel text, data and bss loaded starting at
73  * 0, running with virtual == physical mapping.
74  * r5 points to the prom entry point (the client interface handler
75  * address).  Address translation is turned on, with the prom
76  * managing the hash table.  Interrupts are disabled.  The stack
77  * pointer (r1) points to just below the end of the half-meg region
78  * from 0x380000 - 0x400000, which is mapped in already.
79  *
80  * If we are booted from MacOS via BootX, we enter with the kernel
81  * image loaded somewhere, and the following values in registers:
82  *  r3: 'BooX' (0x426f6f58)
83  *  r4: virtual address of boot_infos_t
84  *  r5: 0
85  *
86  * PREP
87  * This is jumped to on prep systems right after the kernel is relocated
88  * to its proper place in memory by the boot loader.  The expected layout
89  * of the regs is:
90  *   r3: ptr to residual data
91  *   r4: initrd_start or if no initrd then 0
92  *   r5: initrd_end - unused if r4 is 0
93  *   r6: Start of command line string
94  *   r7: End of command line string
95  *
96  * This just gets a minimal mmu environment setup so we can call
97  * start_here() to do the real work.
98  * -- Cort
99  */
100
101         .globl  __start
102 __start:
103 /*
104  * We have to do any OF calls before we map ourselves to KERNELBASE,
105  * because OF may have I/O devices mapped into that area
106  * (particularly on CHRP).
107  */
108         cmpwi   0,r5,0
109         beq     1f
110
111 #ifdef CONFIG_PPC_OF_BOOT_TRAMPOLINE
112         /* find out where we are now */
113         bcl     20,31,$+4
114 0:      mflr    r8                      /* r8 = runtime addr here */
115         addis   r8,r8,(_stext - 0b)@ha
116         addi    r8,r8,(_stext - 0b)@l   /* current runtime base addr */
117         bl      prom_init
118 #endif /* CONFIG_PPC_OF_BOOT_TRAMPOLINE */
119
120         /* We never return. We also hit that trap if trying to boot
121          * from OF while CONFIG_PPC_OF_BOOT_TRAMPOLINE isn't selected */
122         trap
123
124 /*
125  * Check for BootX signature when supporting PowerMac and branch to
126  * appropriate trampoline if it's present
127  */
128 #ifdef CONFIG_PPC_PMAC
129 1:      lis     r31,0x426f
130         ori     r31,r31,0x6f58
131         cmpw    0,r3,r31
132         bne     1f
133         bl      bootx_init
134         trap
135 #endif /* CONFIG_PPC_PMAC */
136
137 1:      mr      r31,r3                  /* save device tree ptr */
138         li      r24,0                   /* cpu # */
139
140 /*
141  * early_init() does the early machine identification and does
142  * the necessary low-level setup and clears the BSS
143  *  -- Cort <cort@fsmlabs.com>
144  */
145         bl      early_init
146
147 /* Switch MMU off, clear BATs and flush TLB. At this point, r3 contains
148  * the physical address we are running at, returned by early_init()
149  */
150         bl      mmu_off
151 __after_mmu_off:
152         bl      clear_bats
153         bl      flush_tlbs
154
155         bl      initial_bats
156         bl      load_segment_registers
157         bl      reloc_offset
158         bl      early_hash_table
159 #if defined(CONFIG_BOOTX_TEXT)
160         bl      setup_disp_bat
161 #endif
162 #ifdef CONFIG_PPC_EARLY_DEBUG_CPM
163         bl      setup_cpm_bat
164 #endif
165 #ifdef CONFIG_PPC_EARLY_DEBUG_USBGECKO
166         bl      setup_usbgecko_bat
167 #endif
168
169 /*
170  * Call setup_cpu for CPU 0 and initialize 6xx Idle
171  */
172         bl      reloc_offset
173         li      r24,0                   /* cpu# */
174         bl      call_setup_cpu          /* Call setup_cpu for this CPU */
175         bl      reloc_offset
176         bl      init_idle_6xx
177
178
179 /*
180  * We need to run with _start at physical address 0.
181  * On CHRP, we are loaded at 0x10000 since OF on CHRP uses
182  * the exception vectors at 0 (and therefore this copy
183  * overwrites OF's exception vectors with our own).
184  * The MMU is off at this point.
185  */
186         bl      reloc_offset
187         mr      r26,r3
188         addis   r4,r3,KERNELBASE@h      /* current address of _start */
189         lis     r5,PHYSICAL_START@h
190         cmplw   0,r4,r5                 /* already running at PHYSICAL_START? */
191         bne     relocate_kernel
192 /*
193  * we now have the 1st 16M of ram mapped with the bats.
194  * prep needs the mmu to be turned on here, but pmac already has it on.
195  * this shouldn't bother the pmac since it just gets turned on again
196  * as we jump to our code at KERNELBASE. -- Cort
197  * Actually no, pmac doesn't have it on any more. BootX enters with MMU
198  * off, and in other cases, we now turn it off before changing BATs above.
199  */
200 turn_on_mmu:
201         mfmsr   r0
202         ori     r0,r0,MSR_DR|MSR_IR|MSR_RI
203         mtspr   SPRN_SRR1,r0
204         lis     r0,start_here@h
205         ori     r0,r0,start_here@l
206         mtspr   SPRN_SRR0,r0
207         rfi                             /* enables MMU */
208
209 /*
210  * We need __secondary_hold as a place to hold the other cpus on
211  * an SMP machine, even when we are running a UP kernel.
212  */
213         . = 0xc0                        /* for prep bootloader */
214         li      r3,1                    /* MTX only has 1 cpu */
215         .globl  __secondary_hold
216 __secondary_hold:
217         /* tell the master we're here */
218         stw     r3,__secondary_hold_acknowledge@l(0)
219 #ifdef CONFIG_SMP
220 100:    lwz     r4,0(0)
221         /* wait until we're told to start */
222         cmpw    0,r4,r3
223         bne     100b
224         /* our cpu # was at addr 0 - go */
225         mr      r24,r3                  /* cpu # */
226         b       __secondary_start
227 #else
228         b       .
229 #endif /* CONFIG_SMP */
230
231         .globl  __secondary_hold_spinloop
232 __secondary_hold_spinloop:
233         .long   0
234         .globl  __secondary_hold_acknowledge
235 __secondary_hold_acknowledge:
236         .long   -1
237
238 /* System reset */
239 /* core99 pmac starts the seconary here by changing the vector, and
240    putting it back to what it was (unknown_async_exception) when done.  */
241         EXCEPTION(INTERRUPT_SYSTEM_RESET, Reset, unknown_async_exception)
242
243 /* Machine check */
244 /*
245  * On CHRP, this is complicated by the fact that we could get a
246  * machine check inside RTAS, and we have no guarantee that certain
247  * critical registers will have the values we expect.  The set of
248  * registers that might have bad values includes all the GPRs
249  * and all the BATs.  We indicate that we are in RTAS by putting
250  * a non-zero value, the address of the exception frame to use,
251  * in thread.rtas_sp.  The machine check handler checks thread.rtas_sp
252  * and uses its value if it is non-zero.
253  * (Other exception handlers assume that r1 is a valid kernel stack
254  * pointer when we take an exception from supervisor mode.)
255  *      -- paulus.
256  */
257         START_EXCEPTION(INTERRUPT_MACHINE_CHECK, MachineCheck)
258         EXCEPTION_PROLOG_0
259 #ifdef CONFIG_PPC_CHRP
260         mtspr   SPRN_SPRG_SCRATCH2,r1
261         mfspr   r1, SPRN_SPRG_THREAD
262         lwz     r1, RTAS_SP(r1)
263         cmpwi   cr1, r1, 0
264         bne     cr1, 7f
265         mfspr   r1, SPRN_SPRG_SCRATCH2
266 #endif /* CONFIG_PPC_CHRP */
267         EXCEPTION_PROLOG_1
268 7:      EXCEPTION_PROLOG_2 0x200 MachineCheck
269 #ifdef CONFIG_PPC_CHRP
270         beq     cr1, 1f
271         twi     31, 0, 0
272 #endif
273 1:      prepare_transfer_to_handler
274         bl      machine_check_exception
275         b       interrupt_return
276
277 /* Data access exception. */
278         START_EXCEPTION(INTERRUPT_DATA_STORAGE, DataAccess)
279 #ifdef CONFIG_PPC_BOOK3S_604
280 BEGIN_MMU_FTR_SECTION
281         mtspr   SPRN_SPRG_SCRATCH2,r10
282         mfspr   r10, SPRN_SPRG_THREAD
283         stw     r11, THR11(r10)
284         mfspr   r10, SPRN_DSISR
285         mfcr    r11
286         andis.  r10, r10, (DSISR_BAD_FAULT_32S | DSISR_DABRMATCH)@h
287         mfspr   r10, SPRN_SPRG_THREAD
288         beq     hash_page_dsi
289 .Lhash_page_dsi_cont:
290         mtcr    r11
291         lwz     r11, THR11(r10)
292         mfspr   r10, SPRN_SPRG_SCRATCH2
293 MMU_FTR_SECTION_ELSE
294         b       1f
295 ALT_MMU_FTR_SECTION_END_IFSET(MMU_FTR_HPTE_TABLE)
296 #endif
297 1:      EXCEPTION_PROLOG_0 handle_dar_dsisr=1
298         EXCEPTION_PROLOG_1
299         EXCEPTION_PROLOG_2 INTERRUPT_DATA_STORAGE DataAccess handle_dar_dsisr=1
300         prepare_transfer_to_handler
301         lwz     r5, _DSISR(r1)
302         andis.  r0, r5, DSISR_DABRMATCH@h
303         bne-    1f
304         bl      do_page_fault
305         b       interrupt_return
306 1:      bl      do_break
307         REST_NVGPRS(r1)
308         b       interrupt_return
309
310
311 /* Instruction access exception. */
312         START_EXCEPTION(INTERRUPT_INST_STORAGE, InstructionAccess)
313         mtspr   SPRN_SPRG_SCRATCH0,r10
314         mtspr   SPRN_SPRG_SCRATCH1,r11
315         mfspr   r10, SPRN_SPRG_THREAD
316         mfspr   r11, SPRN_SRR0
317         stw     r11, SRR0(r10)
318         mfspr   r11, SPRN_SRR1          /* check whether user or kernel */
319         stw     r11, SRR1(r10)
320         mfcr    r10
321 #ifdef CONFIG_PPC_BOOK3S_604
322 BEGIN_MMU_FTR_SECTION
323         andis.  r11, r11, SRR1_ISI_NOPT@h       /* no pte found? */
324         bne     hash_page_isi
325 .Lhash_page_isi_cont:
326         mfspr   r11, SPRN_SRR1          /* check whether user or kernel */
327 END_MMU_FTR_SECTION_IFSET(MMU_FTR_HPTE_TABLE)
328 #endif
329         andi.   r11, r11, MSR_PR
330
331         EXCEPTION_PROLOG_1
332         EXCEPTION_PROLOG_2 INTERRUPT_INST_STORAGE InstructionAccess
333         andis.  r5,r9,DSISR_SRR1_MATCH_32S@h /* Filter relevant SRR1 bits */
334         stw     r5, _DSISR(r11)
335         stw     r12, _DAR(r11)
336         prepare_transfer_to_handler
337         bl      do_page_fault
338         b       interrupt_return
339
340 /* External interrupt */
341         EXCEPTION(INTERRUPT_EXTERNAL, HardwareInterrupt, do_IRQ)
342
343 /* Alignment exception */
344         START_EXCEPTION(INTERRUPT_ALIGNMENT, Alignment)
345         EXCEPTION_PROLOG INTERRUPT_ALIGNMENT Alignment handle_dar_dsisr=1
346         prepare_transfer_to_handler
347         bl      alignment_exception
348         REST_NVGPRS(r1)
349         b       interrupt_return
350
351 /* Program check exception */
352         START_EXCEPTION(INTERRUPT_PROGRAM, ProgramCheck)
353         EXCEPTION_PROLOG INTERRUPT_PROGRAM ProgramCheck
354         prepare_transfer_to_handler
355         bl      program_check_exception
356         REST_NVGPRS(r1)
357         b       interrupt_return
358
359 /* Floating-point unavailable */
360         START_EXCEPTION(0x800, FPUnavailable)
361 #ifdef CONFIG_PPC_FPU
362 BEGIN_FTR_SECTION
363 /*
364  * Certain Freescale cores don't have a FPU and treat fp instructions
365  * as a FP Unavailable exception.  Redirect to illegal/emulation handling.
366  */
367         b       ProgramCheck
368 END_FTR_SECTION_IFSET(CPU_FTR_FPU_UNAVAILABLE)
369         EXCEPTION_PROLOG INTERRUPT_FP_UNAVAIL FPUnavailable
370         beq     1f
371         bl      load_up_fpu             /* if from user, just load it up */
372         b       fast_exception_return
373 1:      prepare_transfer_to_handler
374         bl      kernel_fp_unavailable_exception
375         b       interrupt_return
376 #else
377         b       ProgramCheck
378 #endif
379
380 /* Decrementer */
381         EXCEPTION(INTERRUPT_DECREMENTER, Decrementer, timer_interrupt)
382
383         EXCEPTION(0xa00, Trap_0a, unknown_exception)
384         EXCEPTION(0xb00, Trap_0b, unknown_exception)
385
386 /* System call */
387         START_EXCEPTION(INTERRUPT_SYSCALL, SystemCall)
388         SYSCALL_ENTRY   INTERRUPT_SYSCALL
389
390         EXCEPTION(INTERRUPT_TRACE, SingleStep, single_step_exception)
391         EXCEPTION(0xe00, Trap_0e, unknown_exception)
392
393 /*
394  * The Altivec unavailable trap is at 0x0f20.  Foo.
395  * We effectively remap it to 0x3000.
396  * We include an altivec unavailable exception vector even if
397  * not configured for Altivec, so that you can't panic a
398  * non-altivec kernel running on a machine with altivec just
399  * by executing an altivec instruction.
400  */
401         START_EXCEPTION(INTERRUPT_PERFMON, PerformanceMonitorTrap)
402         b       PerformanceMonitor
403
404         START_EXCEPTION(INTERRUPT_ALTIVEC_UNAVAIL, AltiVecUnavailableTrap)
405         b       AltiVecUnavailable
406
407         __HEAD
408 /*
409  * Handle TLB miss for instruction on 603/603e.
410  * Note: we get an alternate set of r0 - r3 to use automatically.
411  */
412         . = INTERRUPT_INST_TLB_MISS_603
413 InstructionTLBMiss:
414 /*
415  * r0:  userspace flag (later scratch)
416  * r1:  linux style pte ( later becomes ppc hardware pte )
417  * r2:  ptr to linux-style pte
418  * r3:  fault address
419  */
420         /* Get PTE (linux-style) and check access */
421         mfspr   r3,SPRN_IMISS
422 #ifdef CONFIG_MODULES
423         lis     r1, TASK_SIZE@h         /* check if kernel address */
424         cmplw   0,r1,r3
425 #endif
426         mfspr   r2, SPRN_SDR1
427         li      r1,_PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_EXEC
428         rlwinm  r2, r2, 28, 0xfffff000
429 #ifdef CONFIG_MODULES
430         li      r0, 3
431         bgt-    112f
432         lis     r2, (swapper_pg_dir - PAGE_OFFSET)@ha   /* if kernel address, use */
433         li      r0, 0
434         addi    r2, r2, (swapper_pg_dir - PAGE_OFFSET)@l        /* kernel page table */
435 #endif
436 112:    rlwimi  r2,r3,12,20,29          /* insert top 10 bits of address */
437         lwz     r2,0(r2)                /* get pmd entry */
438         rlwinm. r2,r2,0,0,19            /* extract address of pte page */
439         beq-    InstructionAddressInvalid       /* return if no mapping */
440         rlwimi  r2,r3,22,20,29          /* insert next 10 bits of address */
441         lwz     r2,0(r2)                /* get linux-style pte */
442         andc.   r1,r1,r2                /* check access & ~permission */
443         bne-    InstructionAddressInvalid /* return if access not permitted */
444         /* Convert linux-style PTE to low word of PPC-style PTE */
445 #ifdef CONFIG_MODULES
446         rlwimi  r2, r0, 0, 31, 31       /* userspace ? -> PP lsb */
447 #endif
448         ori     r1, r1, 0xe06           /* clear out reserved bits */
449         andc    r1, r2, r1              /* PP = user? 1 : 0 */
450 BEGIN_FTR_SECTION
451         rlwinm  r1,r1,0,~_PAGE_COHERENT /* clear M (coherence not required) */
452 END_FTR_SECTION_IFCLR(CPU_FTR_NEED_COHERENT)
453         mtspr   SPRN_RPA,r1
454         tlbli   r3
455         mfspr   r3,SPRN_SRR1            /* Need to restore CR0 */
456         mtcrf   0x80,r3
457         rfi
458 InstructionAddressInvalid:
459         mfspr   r3,SPRN_SRR1
460         rlwinm  r1,r3,9,6,6     /* Get load/store bit */
461
462         addis   r1,r1,0x2000
463         mtspr   SPRN_DSISR,r1   /* (shouldn't be needed) */
464         andi.   r2,r3,0xFFFF    /* Clear upper bits of SRR1 */
465         or      r2,r2,r1
466         mtspr   SPRN_SRR1,r2
467         mfspr   r1,SPRN_IMISS   /* Get failing address */
468         rlwinm. r2,r2,0,31,31   /* Check for little endian access */
469         rlwimi  r2,r2,1,30,30   /* change 1 -> 3 */
470         xor     r1,r1,r2
471         mtspr   SPRN_DAR,r1     /* Set fault address */
472         mfmsr   r0              /* Restore "normal" registers */
473         xoris   r0,r0,MSR_TGPR>>16
474         mtcrf   0x80,r3         /* Restore CR0 */
475         mtmsr   r0
476         b       InstructionAccess
477
478 /*
479  * Handle TLB miss for DATA Load operation on 603/603e
480  */
481         . = INTERRUPT_DATA_LOAD_TLB_MISS_603
482 DataLoadTLBMiss:
483 /*
484  * r0:  userspace flag (later scratch)
485  * r1:  linux style pte ( later becomes ppc hardware pte )
486  * r2:  ptr to linux-style pte
487  * r3:  fault address
488  */
489         /* Get PTE (linux-style) and check access */
490         mfspr   r3,SPRN_DMISS
491         lis     r1, TASK_SIZE@h         /* check if kernel address */
492         cmplw   0,r1,r3
493         mfspr   r2, SPRN_SDR1
494         li      r1, _PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_READ
495         rlwinm  r2, r2, 28, 0xfffff000
496         li      r0, 3
497         bgt-    112f
498         lis     r2, (swapper_pg_dir - PAGE_OFFSET)@ha   /* if kernel address, use */
499         li      r0, 0
500         addi    r2, r2, (swapper_pg_dir - PAGE_OFFSET)@l        /* kernel page table */
501 112:    rlwimi  r2,r3,12,20,29          /* insert top 10 bits of address */
502         lwz     r2,0(r2)                /* get pmd entry */
503         rlwinm. r2,r2,0,0,19            /* extract address of pte page */
504         beq-    DataAddressInvalid      /* return if no mapping */
505         rlwimi  r2,r3,22,20,29          /* insert next 10 bits of address */
506         lwz     r2,0(r2)                /* get linux-style pte */
507         andc.   r1,r1,r2                /* check access & ~permission */
508         bne-    DataAddressInvalid      /* return if access not permitted */
509         /* Convert linux-style PTE to low word of PPC-style PTE */
510         rlwinm  r1,r2,32-9,30,30        /* _PAGE_WRITE -> PP msb */
511         rlwimi  r2,r0,0,30,31           /* userspace ? -> PP */
512         rlwimi  r1,r2,32-3,24,24        /* _PAGE_WRITE -> _PAGE_DIRTY */
513         xori    r1,r1,_PAGE_DIRTY       /* clear dirty when not rw */
514         ori     r1,r1,0xe04             /* clear out reserved bits */
515         andc    r1,r2,r1                /* PP = user? rw? 1: 3: 0 */
516 BEGIN_FTR_SECTION
517         rlwinm  r1,r1,0,~_PAGE_COHERENT /* clear M (coherence not required) */
518 END_FTR_SECTION_IFCLR(CPU_FTR_NEED_COHERENT)
519         mtspr   SPRN_RPA,r1
520 BEGIN_MMU_FTR_SECTION
521         li      r0,1
522         mfspr   r1,SPRN_SPRG_603_LRU
523         rlwinm  r2,r3,20,27,31          /* Get Address bits 15:19 */
524         slw     r0,r0,r2
525         xor     r1,r0,r1
526         srw     r0,r1,r2
527         mtspr   SPRN_SPRG_603_LRU,r1
528         mfspr   r2,SPRN_SRR1
529         rlwimi  r2,r0,31-14,14,14
530         mtspr   SPRN_SRR1,r2
531         mtcrf   0x80,r2
532         tlbld   r3
533         rfi
534 MMU_FTR_SECTION_ELSE
535         mfspr   r2,SPRN_SRR1            /* Need to restore CR0 */
536         mtcrf   0x80,r2
537         tlbld   r3
538         rfi
539 ALT_MMU_FTR_SECTION_END_IFSET(MMU_FTR_NEED_DTLB_SW_LRU)
540 DataAddressInvalid:
541         mfspr   r3,SPRN_SRR1
542         rlwinm  r1,r3,9,6,6     /* Get load/store bit */
543         addis   r1,r1,0x2000
544         mtspr   SPRN_DSISR,r1
545         andi.   r2,r3,0xFFFF    /* Clear upper bits of SRR1 */
546         mtspr   SPRN_SRR1,r2
547         mfspr   r1,SPRN_DMISS   /* Get failing address */
548         rlwinm. r2,r2,0,31,31   /* Check for little endian access */
549         beq     20f             /* Jump if big endian */
550         xori    r1,r1,3
551 20:     mtspr   SPRN_DAR,r1     /* Set fault address */
552         mfmsr   r0              /* Restore "normal" registers */
553         xoris   r0,r0,MSR_TGPR>>16
554         mtcrf   0x80,r3         /* Restore CR0 */
555         mtmsr   r0
556         b       DataAccess
557
558 /*
559  * Handle TLB miss for DATA Store on 603/603e
560  */
561         . = INTERRUPT_DATA_STORE_TLB_MISS_603
562 DataStoreTLBMiss:
563 /*
564  * r0:  userspace flag (later scratch)
565  * r1:  linux style pte ( later becomes ppc hardware pte )
566  * r2:  ptr to linux-style pte
567  * r3:  fault address
568  */
569         /* Get PTE (linux-style) and check access */
570         mfspr   r3,SPRN_DMISS
571         lis     r1, TASK_SIZE@h         /* check if kernel address */
572         cmplw   0,r1,r3
573         mfspr   r2, SPRN_SDR1
574         li      r1, _PAGE_RW | _PAGE_DIRTY | _PAGE_PRESENT | _PAGE_ACCESSED
575         rlwinm  r2, r2, 28, 0xfffff000
576         li      r0, 3
577         bgt-    112f
578         lis     r2, (swapper_pg_dir - PAGE_OFFSET)@ha   /* if kernel address, use */
579         li      r0, 0
580         addi    r2, r2, (swapper_pg_dir - PAGE_OFFSET)@l        /* kernel page table */
581 112:    rlwimi  r2,r3,12,20,29          /* insert top 10 bits of address */
582         lwz     r2,0(r2)                /* get pmd entry */
583         rlwinm. r2,r2,0,0,19            /* extract address of pte page */
584         beq-    DataAddressInvalid      /* return if no mapping */
585         rlwimi  r2,r3,22,20,29          /* insert next 10 bits of address */
586         lwz     r2,0(r2)                /* get linux-style pte */
587         andc.   r1,r1,r2                /* check access & ~permission */
588         bne-    DataAddressInvalid      /* return if access not permitted */
589         /* Convert linux-style PTE to low word of PPC-style PTE */
590         rlwimi  r2,r0,0,31,31           /* userspace ? -> PP lsb */
591         li      r1,0xe06                /* clear out reserved bits & PP msb */
592         andc    r1,r2,r1                /* PP = user? 1: 0 */
593 BEGIN_FTR_SECTION
594         rlwinm  r1,r1,0,~_PAGE_COHERENT /* clear M (coherence not required) */
595 END_FTR_SECTION_IFCLR(CPU_FTR_NEED_COHERENT)
596         mtspr   SPRN_RPA,r1
597         mfspr   r2,SPRN_SRR1            /* Need to restore CR0 */
598         mtcrf   0x80,r2
599 BEGIN_MMU_FTR_SECTION
600         li      r0,1
601         mfspr   r1,SPRN_SPRG_603_LRU
602         rlwinm  r2,r3,20,27,31          /* Get Address bits 15:19 */
603         slw     r0,r0,r2
604         xor     r1,r0,r1
605         srw     r0,r1,r2
606         mtspr   SPRN_SPRG_603_LRU,r1
607         mfspr   r2,SPRN_SRR1
608         rlwimi  r2,r0,31-14,14,14
609         mtspr   SPRN_SRR1,r2
610         mtcrf   0x80,r2
611         tlbld   r3
612         rfi
613 MMU_FTR_SECTION_ELSE
614         mfspr   r2,SPRN_SRR1            /* Need to restore CR0 */
615         mtcrf   0x80,r2
616         tlbld   r3
617         rfi
618 ALT_MMU_FTR_SECTION_END_IFSET(MMU_FTR_NEED_DTLB_SW_LRU)
619
620 #ifndef CONFIG_ALTIVEC
621 #define altivec_assist_exception        unknown_exception
622 #endif
623
624 #ifndef CONFIG_TAU_INT
625 #define TAUException    unknown_async_exception
626 #endif
627
628         EXCEPTION(0x1300, Trap_13, instruction_breakpoint_exception)
629         EXCEPTION(0x1400, SMI, SMIException)
630         EXCEPTION(0x1500, Trap_15, unknown_exception)
631         EXCEPTION(0x1600, Trap_16, altivec_assist_exception)
632         EXCEPTION(0x1700, Trap_17, TAUException)
633         EXCEPTION(0x1800, Trap_18, unknown_exception)
634         EXCEPTION(0x1900, Trap_19, unknown_exception)
635         EXCEPTION(0x1a00, Trap_1a, unknown_exception)
636         EXCEPTION(0x1b00, Trap_1b, unknown_exception)
637         EXCEPTION(0x1c00, Trap_1c, unknown_exception)
638         EXCEPTION(0x1d00, Trap_1d, unknown_exception)
639         EXCEPTION(0x1e00, Trap_1e, unknown_exception)
640         EXCEPTION(0x1f00, Trap_1f, unknown_exception)
641         EXCEPTION(0x2000, RunMode, RunModeException)
642         EXCEPTION(0x2100, Trap_21, unknown_exception)
643         EXCEPTION(0x2200, Trap_22, unknown_exception)
644         EXCEPTION(0x2300, Trap_23, unknown_exception)
645         EXCEPTION(0x2400, Trap_24, unknown_exception)
646         EXCEPTION(0x2500, Trap_25, unknown_exception)
647         EXCEPTION(0x2600, Trap_26, unknown_exception)
648         EXCEPTION(0x2700, Trap_27, unknown_exception)
649         EXCEPTION(0x2800, Trap_28, unknown_exception)
650         EXCEPTION(0x2900, Trap_29, unknown_exception)
651         EXCEPTION(0x2a00, Trap_2a, unknown_exception)
652         EXCEPTION(0x2b00, Trap_2b, unknown_exception)
653         EXCEPTION(0x2c00, Trap_2c, unknown_exception)
654         EXCEPTION(0x2d00, Trap_2d, unknown_exception)
655         EXCEPTION(0x2e00, Trap_2e, unknown_exception)
656         EXCEPTION(0x2f00, Trap_2f, unknown_exception)
657
658         __HEAD
659         . = 0x3000
660
661 #ifdef CONFIG_PPC_BOOK3S_604
662 .macro save_regs_thread         thread
663         stw     r0, THR0(\thread)
664         stw     r3, THR3(\thread)
665         stw     r4, THR4(\thread)
666         stw     r5, THR5(\thread)
667         stw     r6, THR6(\thread)
668         stw     r8, THR8(\thread)
669         stw     r9, THR9(\thread)
670         mflr    r0
671         stw     r0, THLR(\thread)
672         mfctr   r0
673         stw     r0, THCTR(\thread)
674 .endm
675
676 .macro restore_regs_thread      thread
677         lwz     r0, THLR(\thread)
678         mtlr    r0
679         lwz     r0, THCTR(\thread)
680         mtctr   r0
681         lwz     r0, THR0(\thread)
682         lwz     r3, THR3(\thread)
683         lwz     r4, THR4(\thread)
684         lwz     r5, THR5(\thread)
685         lwz     r6, THR6(\thread)
686         lwz     r8, THR8(\thread)
687         lwz     r9, THR9(\thread)
688 .endm
689
690 hash_page_dsi:
691         save_regs_thread        r10
692         mfdsisr r3
693         mfdar   r4
694         mfsrr0  r5
695         mfsrr1  r9
696         rlwinm  r3, r3, 32 - 15, _PAGE_WRITE    /* DSISR_STORE -> _PAGE_WRITE */
697         ori     r3, r3, _PAGE_PRESENT | _PAGE_READ
698         bl      hash_page
699         mfspr   r10, SPRN_SPRG_THREAD
700         restore_regs_thread r10
701         b       .Lhash_page_dsi_cont
702
703 hash_page_isi:
704         mr      r11, r10
705         mfspr   r10, SPRN_SPRG_THREAD
706         save_regs_thread        r10
707         li      r3, _PAGE_PRESENT | _PAGE_EXEC
708         lwz     r4, SRR0(r10)
709         lwz     r9, SRR1(r10)
710         bl      hash_page
711         mfspr   r10, SPRN_SPRG_THREAD
712         restore_regs_thread r10
713         mr      r10, r11
714         b       .Lhash_page_isi_cont
715
716         .globl fast_hash_page_return
717 fast_hash_page_return:
718         andis.  r10, r9, SRR1_ISI_NOPT@h        /* Set on ISI, cleared on DSI */
719         mfspr   r10, SPRN_SPRG_THREAD
720         restore_regs_thread r10
721         bne     1f
722
723         /* DSI */
724         mtcr    r11
725         lwz     r11, THR11(r10)
726         mfspr   r10, SPRN_SPRG_SCRATCH2
727         rfi
728
729 1:      /* ISI */
730         mtcr    r11
731         mfspr   r11, SPRN_SPRG_SCRATCH1
732         mfspr   r10, SPRN_SPRG_SCRATCH0
733         rfi
734 #endif /* CONFIG_PPC_BOOK3S_604 */
735
736 #ifdef CONFIG_VMAP_STACK
737         vmap_stack_overflow_exception
738 #endif
739
740         __HEAD
741 AltiVecUnavailable:
742         EXCEPTION_PROLOG 0xf20 AltiVecUnavailable
743 #ifdef CONFIG_ALTIVEC
744         beq     1f
745         bl      load_up_altivec         /* if from user, just load it up */
746         b       fast_exception_return
747 #endif /* CONFIG_ALTIVEC */
748 1:      prepare_transfer_to_handler
749         bl      altivec_unavailable_exception
750         b       interrupt_return
751
752         __HEAD
753 PerformanceMonitor:
754         EXCEPTION_PROLOG 0xf00 PerformanceMonitor
755         prepare_transfer_to_handler
756         bl      performance_monitor_exception
757         b       interrupt_return
758
759
760         __HEAD
761 /*
762  * This code is jumped to from the startup code to copy
763  * the kernel image to physical address PHYSICAL_START.
764  */
765 relocate_kernel:
766         lis     r3,PHYSICAL_START@h     /* Destination base address */
767         li      r6,0                    /* Destination offset */
768         li      r5,0x4000               /* # bytes of memory to copy */
769         bl      copy_and_flush          /* copy the first 0x4000 bytes */
770         addi    r0,r3,4f@l              /* jump to the address of 4f */
771         mtctr   r0                      /* in copy and do the rest. */
772         bctr                            /* jump to the copy */
773 4:      lis     r5,_end-KERNELBASE@h
774         ori     r5,r5,_end-KERNELBASE@l
775         bl      copy_and_flush          /* copy the rest */
776         b       turn_on_mmu
777
778 /*
779  * Copy routine used to copy the kernel to start at physical address 0
780  * and flush and invalidate the caches as needed.
781  * r3 = dest addr, r4 = source addr, r5 = copy limit, r6 = start offset
782  * on exit, r3, r4, r5 are unchanged, r6 is updated to be >= r5.
783  */
784 _GLOBAL(copy_and_flush)
785         addi    r5,r5,-4
786         addi    r6,r6,-4
787 4:      li      r0,L1_CACHE_BYTES/4
788         mtctr   r0
789 3:      addi    r6,r6,4                 /* copy a cache line */
790         lwzx    r0,r6,r4
791         stwx    r0,r6,r3
792         bdnz    3b
793         dcbst   r6,r3                   /* write it to memory */
794         sync
795         icbi    r6,r3                   /* flush the icache line */
796         cmplw   0,r6,r5
797         blt     4b
798         sync                            /* additional sync needed on g4 */
799         isync
800         addi    r5,r5,4
801         addi    r6,r6,4
802         blr
803
804 #ifdef CONFIG_SMP
805         .globl __secondary_start_mpc86xx
806 __secondary_start_mpc86xx:
807         mfspr   r3, SPRN_PIR
808         stw     r3, __secondary_hold_acknowledge@l(0)
809         mr      r24, r3                 /* cpu # */
810         b       __secondary_start
811
812         .globl  __secondary_start_pmac_0
813 __secondary_start_pmac_0:
814         /* NB the entries for cpus 0, 1, 2 must each occupy 8 bytes. */
815         li      r24,0
816         b       1f
817         li      r24,1
818         b       1f
819         li      r24,2
820         b       1f
821         li      r24,3
822 1:
823         /* on powersurge, we come in here with IR=0 and DR=1, and DBAT 0
824            set to map the 0xf0000000 - 0xffffffff region */
825         mfmsr   r0
826         rlwinm  r0,r0,0,28,26           /* clear DR (0x10) */
827         mtmsr   r0
828         isync
829
830         .globl  __secondary_start
831 __secondary_start:
832         /* Copy some CPU settings from CPU 0 */
833         bl      __restore_cpu_setup
834
835         lis     r3,-KERNELBASE@h
836         mr      r4,r24
837         bl      call_setup_cpu          /* Call setup_cpu for this CPU */
838         lis     r3,-KERNELBASE@h
839         bl      init_idle_6xx
840
841         /* get current's stack and current */
842         lis     r2,secondary_current@ha
843         tophys(r2,r2)
844         lwz     r2,secondary_current@l(r2)
845         tophys(r1,r2)
846         lwz     r1,TASK_STACK(r1)
847
848         /* stack */
849         addi    r1,r1,THREAD_SIZE-STACK_FRAME_MIN_SIZE
850         li      r0,0
851         tophys(r3,r1)
852         stw     r0,0(r3)
853
854         /* load up the MMU */
855         bl      load_segment_registers
856         bl      load_up_mmu
857
858         /* ptr to phys current thread */
859         tophys(r4,r2)
860         addi    r4,r4,THREAD    /* phys address of our thread_struct */
861         mtspr   SPRN_SPRG_THREAD,r4
862 BEGIN_MMU_FTR_SECTION
863         lis     r4, (swapper_pg_dir - PAGE_OFFSET)@h
864         ori     r4, r4, (swapper_pg_dir - PAGE_OFFSET)@l
865         rlwinm  r4, r4, 4, 0xffff01ff
866         mtspr   SPRN_SDR1, r4
867 END_MMU_FTR_SECTION_IFCLR(MMU_FTR_HPTE_TABLE)
868
869         /* enable MMU and jump to start_secondary */
870         li      r4,MSR_KERNEL
871         lis     r3,start_secondary@h
872         ori     r3,r3,start_secondary@l
873         mtspr   SPRN_SRR0,r3
874         mtspr   SPRN_SRR1,r4
875         rfi
876 #endif /* CONFIG_SMP */
877
878 #ifdef CONFIG_KVM_BOOK3S_HANDLER
879 #include "../kvm/book3s_rmhandlers.S"
880 #endif
881
882 /*
883  * Load stuff into the MMU.  Intended to be called with
884  * IR=0 and DR=0.
885  */
886 SYM_FUNC_START_LOCAL(early_hash_table)
887         sync                    /* Force all PTE updates to finish */
888         isync
889         tlbia                   /* Clear all TLB entries */
890         sync                    /* wait for tlbia/tlbie to finish */
891         TLBSYNC                 /* ... on all CPUs */
892         /* Load the SDR1 register (hash table base & size) */
893         lis     r6, early_hash - PAGE_OFFSET@h
894         ori     r6, r6, 3       /* 256kB table */
895         mtspr   SPRN_SDR1, r6
896         blr
897 SYM_FUNC_END(early_hash_table)
898
899 SYM_FUNC_START_LOCAL(load_up_mmu)
900         sync                    /* Force all PTE updates to finish */
901         isync
902         tlbia                   /* Clear all TLB entries */
903         sync                    /* wait for tlbia/tlbie to finish */
904         TLBSYNC                 /* ... on all CPUs */
905 BEGIN_MMU_FTR_SECTION
906         /* Load the SDR1 register (hash table base & size) */
907         lis     r6,_SDR1@ha
908         tophys(r6,r6)
909         lwz     r6,_SDR1@l(r6)
910         mtspr   SPRN_SDR1,r6
911 END_MMU_FTR_SECTION_IFSET(MMU_FTR_HPTE_TABLE)
912
913 /* Load the BAT registers with the values set up by MMU_init. */
914         lis     r3,BATS@ha
915         addi    r3,r3,BATS@l
916         tophys(r3,r3)
917         LOAD_BAT(0,r3,r4,r5)
918         LOAD_BAT(1,r3,r4,r5)
919         LOAD_BAT(2,r3,r4,r5)
920         LOAD_BAT(3,r3,r4,r5)
921 BEGIN_MMU_FTR_SECTION
922         LOAD_BAT(4,r3,r4,r5)
923         LOAD_BAT(5,r3,r4,r5)
924         LOAD_BAT(6,r3,r4,r5)
925         LOAD_BAT(7,r3,r4,r5)
926 END_MMU_FTR_SECTION_IFSET(MMU_FTR_USE_HIGH_BATS)
927         blr
928 SYM_FUNC_END(load_up_mmu)
929
930 _GLOBAL(load_segment_registers)
931         li      r0, NUM_USER_SEGMENTS /* load up user segment register values */
932         mtctr   r0              /* for context 0 */
933 #ifdef CONFIG_PPC_KUEP
934         lis     r3, SR_NX@h     /* Kp = 0, Ks = 0, VSID = 0 */
935 #else
936         li      r3, 0           /* Kp = 0, Ks = 0, VSID = 0 */
937 #endif
938         li      r4, 0
939 3:      mtsrin  r3, r4
940         addi    r3, r3, 0x111   /* increment VSID */
941         addis   r4, r4, 0x1000  /* address of next segment */
942         bdnz    3b
943         li      r0, 16 - NUM_USER_SEGMENTS /* load up kernel segment registers */
944         mtctr   r0                      /* for context 0 */
945         rlwinm  r3, r3, 0, ~SR_NX       /* Nx = 0 */
946         rlwinm  r3, r3, 0, ~SR_KS       /* Ks = 0 */
947         oris    r3, r3, SR_KP@h         /* Kp = 1 */
948 3:      mtsrin  r3, r4
949         addi    r3, r3, 0x111   /* increment VSID */
950         addis   r4, r4, 0x1000  /* address of next segment */
951         bdnz    3b
952         blr
953
954 /*
955  * This is where the main kernel code starts.
956  */
957 start_here:
958         /* ptr to current */
959         lis     r2,init_task@h
960         ori     r2,r2,init_task@l
961         /* Set up for using our exception vectors */
962         /* ptr to phys current thread */
963         tophys(r4,r2)
964         addi    r4,r4,THREAD    /* init task's THREAD */
965         mtspr   SPRN_SPRG_THREAD,r4
966 BEGIN_MMU_FTR_SECTION
967         lis     r4, (swapper_pg_dir - PAGE_OFFSET)@h
968         ori     r4, r4, (swapper_pg_dir - PAGE_OFFSET)@l
969         rlwinm  r4, r4, 4, 0xffff01ff
970         mtspr   SPRN_SDR1, r4
971 END_MMU_FTR_SECTION_IFCLR(MMU_FTR_HPTE_TABLE)
972
973         /* stack */
974         lis     r1,init_thread_union@ha
975         addi    r1,r1,init_thread_union@l
976         li      r0,0
977         stwu    r0,THREAD_SIZE-STACK_FRAME_MIN_SIZE(r1)
978 /*
979  * Do early platform-specific initialization,
980  * and set up the MMU.
981  */
982 #ifdef CONFIG_KASAN
983         bl      kasan_early_init
984 #endif
985         li      r3,0
986         mr      r4,r31
987         bl      machine_init
988         bl      __save_cpu_setup
989         bl      MMU_init
990         bl      MMU_init_hw_patch
991
992 /*
993  * Go back to running unmapped so we can load up new values
994  * for SDR1 (hash table pointer) and the segment registers
995  * and change to using our exception vectors.
996  */
997         lis     r4,2f@h
998         ori     r4,r4,2f@l
999         tophys(r4,r4)
1000         li      r3,MSR_KERNEL & ~(MSR_IR|MSR_DR)
1001
1002         .align  4
1003         mtspr   SPRN_SRR0,r4
1004         mtspr   SPRN_SRR1,r3
1005         rfi
1006 /* Load up the kernel context */
1007 2:      bl      load_up_mmu
1008
1009 #ifdef CONFIG_BDI_SWITCH
1010         /* Add helper information for the Abatron bdiGDB debugger.
1011          * We do this here because we know the mmu is disabled, and
1012          * will be enabled for real in just a few instructions.
1013          */
1014         lis     r5, abatron_pteptrs@h
1015         ori     r5, r5, abatron_pteptrs@l
1016         stw     r5, 0xf0(0)     /* This much match your Abatron config */
1017         lis     r6, swapper_pg_dir@h
1018         ori     r6, r6, swapper_pg_dir@l
1019         tophys(r5, r5)
1020         stw     r6, 0(r5)
1021 #endif /* CONFIG_BDI_SWITCH */
1022
1023 /* Now turn on the MMU for real! */
1024         li      r4,MSR_KERNEL
1025         lis     r3,start_kernel@h
1026         ori     r3,r3,start_kernel@l
1027         mtspr   SPRN_SRR0,r3
1028         mtspr   SPRN_SRR1,r4
1029         rfi
1030
1031 /*
1032  * An undocumented "feature" of 604e requires that the v bit
1033  * be cleared before changing BAT values.
1034  *
1035  * Also, newer IBM firmware does not clear bat3 and 4 so
1036  * this makes sure it's done.
1037  *  -- Cort
1038  */
1039 SYM_FUNC_START_LOCAL(clear_bats)
1040         li      r10,0
1041
1042         mtspr   SPRN_DBAT0U,r10
1043         mtspr   SPRN_DBAT0L,r10
1044         mtspr   SPRN_DBAT1U,r10
1045         mtspr   SPRN_DBAT1L,r10
1046         mtspr   SPRN_DBAT2U,r10
1047         mtspr   SPRN_DBAT2L,r10
1048         mtspr   SPRN_DBAT3U,r10
1049         mtspr   SPRN_DBAT3L,r10
1050         mtspr   SPRN_IBAT0U,r10
1051         mtspr   SPRN_IBAT0L,r10
1052         mtspr   SPRN_IBAT1U,r10
1053         mtspr   SPRN_IBAT1L,r10
1054         mtspr   SPRN_IBAT2U,r10
1055         mtspr   SPRN_IBAT2L,r10
1056         mtspr   SPRN_IBAT3U,r10
1057         mtspr   SPRN_IBAT3L,r10
1058 BEGIN_MMU_FTR_SECTION
1059         /* Here's a tweak: at this point, CPU setup have
1060          * not been called yet, so HIGH_BAT_EN may not be
1061          * set in HID0 for the 745x processors. However, it
1062          * seems that doesn't affect our ability to actually
1063          * write to these SPRs.
1064          */
1065         mtspr   SPRN_DBAT4U,r10
1066         mtspr   SPRN_DBAT4L,r10
1067         mtspr   SPRN_DBAT5U,r10
1068         mtspr   SPRN_DBAT5L,r10
1069         mtspr   SPRN_DBAT6U,r10
1070         mtspr   SPRN_DBAT6L,r10
1071         mtspr   SPRN_DBAT7U,r10
1072         mtspr   SPRN_DBAT7L,r10
1073         mtspr   SPRN_IBAT4U,r10
1074         mtspr   SPRN_IBAT4L,r10
1075         mtspr   SPRN_IBAT5U,r10
1076         mtspr   SPRN_IBAT5L,r10
1077         mtspr   SPRN_IBAT6U,r10
1078         mtspr   SPRN_IBAT6L,r10
1079         mtspr   SPRN_IBAT7U,r10
1080         mtspr   SPRN_IBAT7L,r10
1081 END_MMU_FTR_SECTION_IFSET(MMU_FTR_USE_HIGH_BATS)
1082         blr
1083 SYM_FUNC_END(clear_bats)
1084
1085 _GLOBAL(update_bats)
1086         lis     r4, 1f@h
1087         ori     r4, r4, 1f@l
1088         tophys(r4, r4)
1089         mfmsr   r6
1090         mflr    r7
1091         li      r3, MSR_KERNEL & ~(MSR_IR | MSR_DR)
1092         rlwinm  r0, r6, 0, ~MSR_RI
1093         rlwinm  r0, r0, 0, ~MSR_EE
1094         mtmsr   r0
1095
1096         .align  4
1097         mtspr   SPRN_SRR0, r4
1098         mtspr   SPRN_SRR1, r3
1099         rfi
1100 1:      bl      clear_bats
1101         lis     r3, BATS@ha
1102         addi    r3, r3, BATS@l
1103         tophys(r3, r3)
1104         LOAD_BAT(0, r3, r4, r5)
1105         LOAD_BAT(1, r3, r4, r5)
1106         LOAD_BAT(2, r3, r4, r5)
1107         LOAD_BAT(3, r3, r4, r5)
1108 BEGIN_MMU_FTR_SECTION
1109         LOAD_BAT(4, r3, r4, r5)
1110         LOAD_BAT(5, r3, r4, r5)
1111         LOAD_BAT(6, r3, r4, r5)
1112         LOAD_BAT(7, r3, r4, r5)
1113 END_MMU_FTR_SECTION_IFSET(MMU_FTR_USE_HIGH_BATS)
1114         li      r3, MSR_KERNEL & ~(MSR_IR | MSR_DR | MSR_RI)
1115         mtmsr   r3
1116         mtspr   SPRN_SRR0, r7
1117         mtspr   SPRN_SRR1, r6
1118         rfi
1119
1120 SYM_FUNC_START_LOCAL(flush_tlbs)
1121         lis     r10, 0x40
1122 1:      addic.  r10, r10, -0x1000
1123         tlbie   r10
1124         bgt     1b
1125         sync
1126         blr
1127 SYM_FUNC_END(flush_tlbs)
1128
1129 SYM_FUNC_START_LOCAL(mmu_off)
1130         addi    r4, r3, __after_mmu_off - _start
1131         mfmsr   r3
1132         andi.   r0,r3,MSR_DR|MSR_IR             /* MMU enabled? */
1133         beqlr
1134         andc    r3,r3,r0
1135
1136         .align  4
1137         mtspr   SPRN_SRR0,r4
1138         mtspr   SPRN_SRR1,r3
1139         sync
1140         rfi
1141 SYM_FUNC_END(mmu_off)
1142
1143 /* We use one BAT to map up to 256M of RAM at _PAGE_OFFSET */
1144 SYM_FUNC_START_LOCAL(initial_bats)
1145         lis     r11,PAGE_OFFSET@h
1146         tophys(r8,r11)
1147 #ifdef CONFIG_SMP
1148         ori     r8,r8,0x12              /* R/W access, M=1 */
1149 #else
1150         ori     r8,r8,2                 /* R/W access */
1151 #endif /* CONFIG_SMP */
1152         ori     r11,r11,BL_256M<<2|0x2  /* set up BAT registers for 604 */
1153
1154         mtspr   SPRN_DBAT0L,r8          /* N.B. 6xx have valid */
1155         mtspr   SPRN_DBAT0U,r11         /* bit in upper BAT register */
1156         mtspr   SPRN_IBAT0L,r8
1157         mtspr   SPRN_IBAT0U,r11
1158         isync
1159         blr
1160 SYM_FUNC_END(initial_bats)
1161
1162 #ifdef CONFIG_BOOTX_TEXT
1163 SYM_FUNC_START_LOCAL(setup_disp_bat)
1164         /*
1165          * setup the display bat prepared for us in prom.c
1166          */
1167         mflr    r8
1168         bl      reloc_offset
1169         mtlr    r8
1170         addis   r8,r3,disp_BAT@ha
1171         addi    r8,r8,disp_BAT@l
1172         cmpwi   cr0,r8,0
1173         beqlr
1174         lwz     r11,0(r8)
1175         lwz     r8,4(r8)
1176         mtspr   SPRN_DBAT3L,r8
1177         mtspr   SPRN_DBAT3U,r11
1178         blr
1179 SYM_FUNC_END(setup_disp_bat)
1180 #endif /* CONFIG_BOOTX_TEXT */
1181
1182 #ifdef CONFIG_PPC_EARLY_DEBUG_CPM
1183 SYM_FUNC_START_LOCAL(setup_cpm_bat)
1184         lis     r8, 0xf000
1185         ori     r8, r8, 0x002a
1186         mtspr   SPRN_DBAT1L, r8
1187
1188         lis     r11, 0xf000
1189         ori     r11, r11, (BL_1M << 2) | 2
1190         mtspr   SPRN_DBAT1U, r11
1191
1192         blr
1193 SYM_FUNC_END(setup_cpm_bat)
1194 #endif
1195
1196 #ifdef CONFIG_PPC_EARLY_DEBUG_USBGECKO
1197 SYM_FUNC_START_LOCAL(setup_usbgecko_bat)
1198         /* prepare a BAT for early io */
1199 #if defined(CONFIG_GAMECUBE)
1200         lis     r8, 0x0c00
1201 #elif defined(CONFIG_WII)
1202         lis     r8, 0x0d00
1203 #else
1204 #error Invalid platform for USB Gecko based early debugging.
1205 #endif
1206         /*
1207          * The virtual address used must match the virtual address
1208          * associated to the fixmap entry FIX_EARLY_DEBUG_BASE.
1209          */
1210         lis     r11, 0xfffe     /* top 128K */
1211         ori     r8, r8, 0x002a  /* uncached, guarded ,rw */
1212         ori     r11, r11, 0x2   /* 128K, Vs=1, Vp=0 */
1213         mtspr   SPRN_DBAT1L, r8
1214         mtspr   SPRN_DBAT1U, r11
1215         blr
1216 SYM_FUNC_END(setup_usbgecko_bat)
1217 #endif
1218
1219         .data