PPC fixes for SMP; also fix the stack overflow detection, remove
[opensuse:kernel.git] / arch / ppc / kernel / head.S
1 /*
2  * BK Id: %F% %I% %G% %U% %#%
3  */
4 /*
5  *  PowerPC version 
6  *    Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
7  *
8  *  Rewritten by Cort Dougan (cort@cs.nmt.edu) for PReP
9  *    Copyright (C) 1996 Cort Dougan <cort@cs.nmt.edu>
10  *  Adapted for Power Macintosh by Paul Mackerras.
11  *  Low-level exception handlers and MMU support
12  *  rewritten by Paul Mackerras.
13  *    Copyright (C) 1996 Paul Mackerras.
14  *  MPC8xx modifications Copyright (C) 1997 Dan Malek (dmalek@jlc.net).
15  *  Amiga/APUS changes by Jesper Skov (jskov@cygnus.co.uk).
16  *
17  *  This file contains the low-level support and setup for the
18  *  PowerPC platform, including trap and interrupt dispatch.
19  *  (The PPC 8xx embedded CPUs use head_8xx.S instead.)
20  *
21  *  This program is free software; you can redistribute it and/or
22  *  modify it under the terms of the GNU General Public License
23  *  as published by the Free Software Foundation; either version
24  *  2 of the License, or (at your option) any later version.
25  *
26  */
27
28 #include <linux/config.h>
29 #include <asm/processor.h>
30 #include <asm/page.h>
31 #include <asm/mmu.h>
32 #include <asm/pgtable.h>
33 #include <asm/cputable.h>
34 #include <asm/cache.h>
35 #include <asm/thread_info.h>
36 #include <asm/ppc_asm.h>
37 #include "ppc_defs.h"
38
39 #ifdef CONFIG_APUS
40 #include <asm/amigappc.h>
41 #endif
42
43 #ifdef CONFIG_PPC64BRIDGE
44 #define LOAD_BAT(n, reg, RA, RB)        \
45         ld      RA,(n*32)+0(reg);       \
46         ld      RB,(n*32)+8(reg);       \
47         mtspr   IBAT##n##U,RA;          \
48         mtspr   IBAT##n##L,RB;          \
49         ld      RA,(n*32)+16(reg);      \
50         ld      RB,(n*32)+24(reg);      \
51         mtspr   DBAT##n##U,RA;          \
52         mtspr   DBAT##n##L,RB;          \
53
54 #else /* CONFIG_PPC64BRIDGE */
55
56 /* 601 only have IBAT; cr0.eq is set on 601 when using this macro */
57 #define LOAD_BAT(n, reg, RA, RB)        \
58         /* see the comment for clear_bats() -- Cort */ \
59         li      RA,0;                   \
60         mtspr   IBAT##n##U,RA;          \
61         mtspr   DBAT##n##U,RA;          \
62         lwz     RA,(n*16)+0(reg);       \
63         lwz     RB,(n*16)+4(reg);       \
64         mtspr   IBAT##n##U,RA;          \
65         mtspr   IBAT##n##L,RB;          \
66         beq     1f;                     \
67         lwz     RA,(n*16)+8(reg);       \
68         lwz     RB,(n*16)+12(reg);      \
69         mtspr   DBAT##n##U,RA;          \
70         mtspr   DBAT##n##L,RB;          \
71 1:
72 #endif /* CONFIG_PPC64BRIDGE */  
73
74         .text
75         .stabs  "arch/ppc/kernel/",N_SO,0,0,0f
76         .stabs  "head.S",N_SO,0,0,0f
77 0:
78         .globl  _stext
79 _stext:
80
81 /*
82  * _start is defined this way because the XCOFF loader in the OpenFirmware
83  * on the powermac expects the entry point to be a procedure descriptor.
84  */
85         .text
86         .globl  _start
87 _start:
88         /* 
89          * These are here for legacy reasons, the kernel used to
90          * need to look like a coff function entry for the pmac
91          * but we're always started by some kind of bootloader now.
92          *  -- Cort
93          */
94         nop     /* used by __secondary_hold on prep (mtx) and chrp smp */
95         nop     /* used by __secondary_hold on prep (mtx) and chrp smp */
96         nop
97
98 /* PMAC
99  * Enter here with the kernel text, data and bss loaded starting at
100  * 0, running with virtual == physical mapping.
101  * r5 points to the prom entry point (the client interface handler
102  * address).  Address translation is turned on, with the prom
103  * managing the hash table.  Interrupts are disabled.  The stack
104  * pointer (r1) points to just below the end of the half-meg region
105  * from 0x380000 - 0x400000, which is mapped in already.
106  *
107  * If we are booted from MacOS via BootX, we enter with the kernel
108  * image loaded somewhere, and the following values in registers:
109  *  r3: 'BooX' (0x426f6f58)
110  *  r4: virtual address of boot_infos_t
111  *  r5: 0
112  *
113  * APUS
114  *   r3: 'APUS'
115  *   r4: physical address of memory base
116  *   Linux/m68k style BootInfo structure at &_end.
117  *
118  * PREP
119  * This is jumped to on prep systems right after the kernel is relocated
120  * to its proper place in memory by the boot loader.  The expected layout
121  * of the regs is:
122  *   r3: ptr to residual data
123  *   r4: initrd_start or if no initrd then 0
124  *   r5: initrd_end - unused if r4 is 0
125  *   r6: Start of command line string
126  *   r7: End of command line string
127  *
128  * This just gets a minimal mmu environment setup so we can call
129  * start_here() to do the real work.
130  * -- Cort
131  */
132
133         .globl  __start
134 __start:
135 /*
136  * We have to do any OF calls before we map ourselves to KERNELBASE,
137  * because OF may have I/O devices mapped into that area
138  * (particularly on CHRP).
139  */
140         mr      r31,r3                  /* save parameters */
141         mr      r30,r4
142         mr      r29,r5
143         mr      r28,r6
144         mr      r27,r7
145         li      r24,0                   /* cpu # */
146 /*
147  * early_init() does the early machine identification and does
148  * the necessary low-level setup and clears the BSS
149  *  -- Cort <cort@fsmlabs.com>
150  */ 
151         bl      early_init
152
153 #ifdef CONFIG_APUS
154 /* On APUS the __va/__pa constants need to be set to the correct 
155  * values before continuing. 
156  */
157         mr      r4,r30
158         bl      fix_mem_constants
159 #endif /* CONFIG_APUS */
160
161 /* Switch MMU off, clear BATs and flush TLB. At this point, r3 contains
162  * the physical address we are running at, returned by early_init()
163  */
164         bl      mmu_off
165 __after_mmu_off:
166         bl      clear_bats
167         bl      flush_tlbs
168
169         bl      initial_bats
170 #if !defined(CONFIG_APUS) && defined(CONFIG_BOOTX_TEXT)
171         bl      setup_disp_bat
172 #endif
173
174 #ifndef CONFIG_APUS
175 /*
176  * We need to run with _start at physical address 0.
177  * On CHRP, we are loaded at 0x10000 since OF on CHRP uses
178  * the exception vectors at 0 (and therefore this copy
179  * overwrites OF's exception vectors with our own).
180  * If the MMU is already turned on, we copy stuff to KERNELBASE,
181  * otherwise we copy it to 0.
182  */
183         bl      reloc_offset
184         mr      r26,r3
185         addis   r4,r3,KERNELBASE@h      /* current address of _start */
186         cmpwi   0,r4,0                  /* are we already running at 0? */
187         bne     relocate_kernel
188 #endif /* CONFIG_APUS */
189 /*
190  * we now have the 1st 16M of ram mapped with the bats.
191  * prep needs the mmu to be turned on here, but pmac already has it on.
192  * this shouldn't bother the pmac since it just gets turned on again
193  * as we jump to our code at KERNELBASE. -- Cort
194  * Actually no, pmac doesn't have it on any more. BootX enters with MMU
195  * off, and in other cases, we now turn it off before changing BATs above.
196  */
197 turn_on_mmu:
198         mfmsr   r0
199         ori     r0,r0,MSR_DR|MSR_IR
200         mtspr   SRR1,r0
201         lis     r0,start_here@h
202         ori     r0,r0,start_here@l
203         mtspr   SRR0,r0
204         SYNC
205         RFI                             /* enables MMU */
206
207 /*
208  * We need __secondary_hold as a place to hold the other cpus on
209  * an SMP machine, even when we are running a UP kernel.
210  */
211         . = 0xc0                        /* for prep bootloader */
212         li      r3,1                    /* MTX only has 1 cpu */
213         .globl  __secondary_hold
214 __secondary_hold:
215         /* tell the master we're here */
216         stw     r3,4(0)
217 #ifdef CONFIG_SMP
218 100:    lwz     r4,0(0)
219         /* wait until we're told to start */
220         cmpw    0,r4,r3
221         bne     100b
222         /* our cpu # was at addr 0 - go */
223         mr      r24,r3                  /* cpu # */
224         b       __secondary_start
225 #else
226         b       .
227 #endif /* CONFIG_SMP */
228
229 /*
230  * Exception entry code.  This code runs with address translation
231  * turned off, i.e. using physical addresses.
232  * We assume sprg3 has the physical address of the current
233  * task's thread_struct.
234  */
235 #define EXCEPTION_PROLOG        \
236         mtspr   SPRG0,r20;      \
237         mtspr   SPRG1,r21;      \
238         mfcr    r20;            \
239         mfspr   r21,SPRG2;              /* exception stack to use from */ \
240         cmpwi   0,r21,0;                /* user mode or RTAS */ \
241         bne     1f;             \
242         tophys(r21,r1);                 /* use tophys(kernel sp) otherwise */ \
243         subi    r21,r21,INT_FRAME_SIZE; /* alloc exc. frame */\
244 1:      CLR_TOP32(r21);         \
245         stw     r20,_CCR(r21);          /* save registers */ \
246         stw     r22,GPR22(r21); \
247         stw     r23,GPR23(r21); \
248         mfspr   r20,SPRG0;      \
249         stw     r20,GPR20(r21); \
250         mfspr   r22,SPRG1;      \
251         stw     r22,GPR21(r21); \
252         mflr    r20;            \
253         stw     r20,_LINK(r21); \
254         mfctr   r22;            \
255         stw     r22,_CTR(r21);  \
256         mfspr   r20,XER;        \
257         stw     r20,_XER(r21);  \
258         mfspr   r22,SRR0;       \
259         mfspr   r23,SRR1;       \
260         stw     r0,GPR0(r21);   \
261         stw     r1,GPR1(r21);   \
262         stw     r2,GPR2(r21);   \
263         stw     r1,0(r21);      \
264         tovirt(r1,r21);                 /* set new kernel sp */ \
265         SAVE_4GPRS(3, r21);     \
266         SAVE_GPR(7, r21);
267 /*
268  * Note: code which follows this uses cr0.eq (set if from kernel),
269  * r21, r22 (SRR0), and r23 (SRR1).
270  */
271
272 /*
273  * Exception vectors.
274  */
275 #define STD_EXCEPTION(n, label, hdlr)           \
276         . = n;                                  \
277 label:                                          \
278         EXCEPTION_PROLOG;                       \
279         addi    r3,r1,STACK_FRAME_OVERHEAD;     \
280         li      r20,MSR_KERNEL;                 \
281         bl      transfer_to_handler;            \
282 i##n:                                           \
283         .long   hdlr;                           \
284         .long   ret_from_except
285
286 /* System reset */
287 /* core99 pmac starts the seconary here by changing the vector, and
288    putting it back to what it was (UnknownException) when done.  */
289 #if defined(CONFIG_GEMINI) && defined(CONFIG_SMP)
290         . = 0x100
291         b       __secondary_start_gemini
292 #else
293         STD_EXCEPTION(0x100, Reset, UnknownException)
294 #endif
295
296 /* Machine check */
297         STD_EXCEPTION(0x200, MachineCheck, MachineCheckException)
298
299 /* Data access exception. */
300         . = 0x300
301 #ifdef CONFIG_PPC64BRIDGE
302         b       DataAccess
303 DataAccessCont:
304 #else
305 DataAccess:
306         EXCEPTION_PROLOG
307 #endif /* CONFIG_PPC64BRIDGE */
308         mfspr   r20,DSISR
309         andis.  r0,r20,0xa470           /* weird error? */
310         bne     1f                      /* if not, try to put a PTE */
311         mfspr   r4,DAR                  /* into the hash table */
312         rlwinm  r3,r20,32-15,21,21      /* DSISR_STORE -> _PAGE_RW */
313         bl      hash_page
314 1:      stw     r20,_DSISR(r21)
315         mr      r5,r20
316         mfspr   r4,DAR
317         stw     r4,_DAR(r21)
318         addi    r3,r1,STACK_FRAME_OVERHEAD
319         li      r20,MSR_KERNEL
320         rlwimi  r20,r23,0,16,16         /* copy EE bit from saved MSR */
321         bl      transfer_to_handler
322 i0x300:
323         .long   do_page_fault
324         .long   ret_from_except
325
326 #ifdef CONFIG_PPC64BRIDGE
327 /* SLB fault on data access. */
328         . = 0x380
329         b       DataSegment
330 DataSegmentCont:
331         mfspr   r4,DAR
332         stw     r4,_DAR(r21)
333         addi    r3,r1,STACK_FRAME_OVERHEAD
334         li      r20,MSR_KERNEL
335         rlwimi  r20,r23,0,16,16         /* copy EE bit from saved MSR */
336         bl      transfer_to_handler
337         .long   UnknownException
338         .long   ret_from_except
339 #endif /* CONFIG_PPC64BRIDGE */
340
341 /* Instruction access exception. */
342         . = 0x400
343 #ifdef CONFIG_PPC64BRIDGE
344         b       InstructionAccess
345 InstructionAccessCont:
346 #else
347 InstructionAccess:
348         EXCEPTION_PROLOG
349 #endif /* CONFIG_PPC64BRIDGE */
350         andis.  r0,r23,0x4000           /* no pte found? */
351         beq     1f                      /* if so, try to put a PTE */
352         li      r3,0                    /* into the hash table */
353         mr      r4,r22                  /* SRR0 is fault address */
354         bl      hash_page
355 1:      addi    r3,r1,STACK_FRAME_OVERHEAD
356         mr      r4,r22
357         mr      r5,r23
358         li      r20,MSR_KERNEL
359         rlwimi  r20,r23,0,16,16         /* copy EE bit from saved MSR */
360         bl      transfer_to_handler
361 i0x400:
362         .long   do_page_fault
363         .long   ret_from_except
364
365 #ifdef CONFIG_PPC64BRIDGE
366 /* SLB fault on instruction access. */
367         . = 0x480
368         b       InstructionSegment
369 InstructionSegmentCont:
370         addi    r3,r1,STACK_FRAME_OVERHEAD
371         li      r20,MSR_KERNEL
372         rlwimi  r20,r23,0,16,16         /* copy EE bit from saved MSR */
373         bl      transfer_to_handler
374         .long   UnknownException
375         .long   ret_from_except
376 #endif /* CONFIG_PPC64BRIDGE */
377
378 /* External interrupt */
379         . = 0x500;
380 HardwareInterrupt:
381         EXCEPTION_PROLOG;
382         addi    r3,r1,STACK_FRAME_OVERHEAD
383         li      r20,MSR_KERNEL
384         li      r4,0
385         bl      transfer_to_handler
386         .globl do_IRQ_intercept
387 do_IRQ_intercept:
388         .long   do_IRQ;
389         .long   ret_from_intercept
390
391 /* Alignment exception */
392         . = 0x600
393 Alignment:
394         EXCEPTION_PROLOG
395         mfspr   r4,DAR
396         stw     r4,_DAR(r21)
397         mfspr   r5,DSISR
398         stw     r5,_DSISR(r21)
399         addi    r3,r1,STACK_FRAME_OVERHEAD
400         li      r20,MSR_KERNEL
401         rlwimi  r20,r23,0,16,16         /* copy EE bit from saved MSR */
402         bl      transfer_to_handler
403 i0x600:
404         .long   AlignmentException
405         .long   ret_from_except
406
407 /* Program check exception */
408         . = 0x700
409 ProgramCheck:
410         EXCEPTION_PROLOG
411         addi    r3,r1,STACK_FRAME_OVERHEAD
412         li      r20,MSR_KERNEL
413         rlwimi  r20,r23,0,16,16         /* copy EE bit from saved MSR */
414         bl      transfer_to_handler
415 i0x700:
416         .long   ProgramCheckException
417         .long   ret_from_except
418
419 /* Floating-point unavailable */
420         . = 0x800
421 FPUnavailable:
422         EXCEPTION_PROLOG
423         bne     load_up_fpu             /* if from user, just load it up */
424         li      r20,MSR_KERNEL
425         bl      transfer_to_handler     /* if from kernel, take a trap */
426 i0x800:
427         .long   KernelFP
428         .long   ret_from_except
429
430         . = 0x900
431 Decrementer:
432         EXCEPTION_PROLOG
433         addi    r3,r1,STACK_FRAME_OVERHEAD
434         li      r20,MSR_KERNEL
435         bl      transfer_to_handler
436         .globl timer_interrupt_intercept
437 timer_interrupt_intercept:
438         .long   timer_interrupt
439         .long   ret_from_intercept
440
441         STD_EXCEPTION(0xa00, Trap_0a, UnknownException)
442         STD_EXCEPTION(0xb00, Trap_0b, UnknownException)
443
444 /* System call */
445         . = 0xc00
446 SystemCall:
447         EXCEPTION_PROLOG
448         stw     r3,ORIG_GPR3(r21)
449         li      r20,MSR_KERNEL
450         rlwimi  r20,r23,0,16,16         /* copy EE bit from saved MSR */
451         bl      transfer_to_handler
452         .long   DoSyscall
453         .long   ret_from_except
454
455 /* Single step - not used on 601 */
456         STD_EXCEPTION(0xd00, SingleStep, SingleStepException)
457         STD_EXCEPTION(0xe00, Trap_0e, UnknownException)
458
459 /*
460  * The Altivec unavailable trap is at 0x0f20.  Foo.
461  * We effectively remap it to 0x3000.
462  */
463         . = 0xf00
464         b       Trap_0f
465 trap_0f_cont:
466         addi    r3,r1,STACK_FRAME_OVERHEAD
467         li      r20,MSR_KERNEL
468         bl      transfer_to_handler
469         .long   UnknownException
470         .long   ret_from_except
471
472         . = 0xf20
473 #ifdef CONFIG_ALTIVEC
474         b       AltiVecUnavailable
475 #endif
476 Trap_0f:
477         EXCEPTION_PROLOG
478         b       trap_0f_cont
479
480 /*
481  * Handle TLB miss for instruction on 603/603e.
482  * Note: we get an alternate set of r0 - r3 to use automatically.
483  */
484         . = 0x1000
485 InstructionTLBMiss:
486 /*
487  * r0:  stored ctr
488  * r1:  linux style pte ( later becomes ppc hardware pte )
489  * r2:  ptr to linux-style pte
490  * r3:  scratch
491  */
492         mfctr   r0
493         /* Get PTE (linux-style) and check access */
494         mfspr   r3,IMISS
495         lis     r1,KERNELBASE@h         /* check if kernel address */
496         cmplw   0,r3,r1
497         mfspr   r2,SPRG3
498         li      r1,_PAGE_USER|_PAGE_PRESENT /* low addresses tested as user */
499         lwz     r2,PGDIR(r2)
500         blt+    112f
501         lis     r2,swapper_pg_dir@ha    /* if kernel address, use */
502         addi    r2,r2,swapper_pg_dir@l  /* kernel page table */
503         mfspr   r1,SRR1                 /* and MSR_PR bit from SRR1 */
504         rlwinm  r1,r1,32-12,29,29       /* shift MSR_PR to _PAGE_USER posn */
505 112:    tophys(r2,r2)
506         rlwimi  r2,r3,12,20,29          /* insert top 10 bits of address */
507         lwz     r2,0(r2)                /* get pmd entry */
508         rlwinm. r2,r2,0,0,19            /* extract address of pte page */
509         beq-    InstructionAddressInvalid       /* return if no mapping */
510         tophys(r2,r2)
511         rlwimi  r2,r3,22,20,29          /* insert next 10 bits of address */
512         lwz     r3,0(r2)                /* get linux-style pte */
513         andc.   r1,r1,r3                /* check access & ~permission */
514         bne-    InstructionAddressInvalid /* return if access not permitted */
515         ori     r3,r3,_PAGE_ACCESSED    /* set _PAGE_ACCESSED in pte */
516         /*
517          * NOTE! We are assuming this is not an SMP system, otherwise
518          * we would need to update the pte atomically with lwarx/stwcx.
519          */
520         stw     r3,0(r2)                /* update PTE (accessed bit) */
521         /* Convert linux-style PTE to low word of PPC-style PTE */
522         rlwinm  r1,r3,32-10,31,31       /* _PAGE_RW -> PP lsb */
523         rlwinm  r2,r3,32-7,31,31        /* _PAGE_DIRTY -> PP lsb */
524         and     r1,r1,r2                /* writable if _RW and _DIRTY */
525         rlwimi  r3,r3,32-1,30,30        /* _PAGE_USER -> PP msb */
526         rlwimi  r3,r3,32-1,31,31        /* _PAGE_USER -> PP lsb */
527         ori     r1,r1,0xe14             /* clear out reserved bits and M */
528         andc    r1,r3,r1                /* PP = user? (rw&dirty? 2: 3): 0 */
529         mtspr   RPA,r1
530         mfspr   r3,IMISS
531         tlbli   r3
532         mfspr   r3,SRR1         /* Need to restore CR0 */
533         mtcrf   0x80,r3
534         rfi
535 InstructionAddressInvalid:
536         mfspr   r3,SRR1
537         rlwinm  r1,r3,9,6,6     /* Get load/store bit */
538
539         addis   r1,r1,0x2000
540         mtspr   DSISR,r1        /* (shouldn't be needed) */
541         mtctr   r0              /* Restore CTR */
542         andi.   r2,r3,0xFFFF    /* Clear upper bits of SRR1 */
543         or      r2,r2,r1
544         mtspr   SRR1,r2
545         mfspr   r1,IMISS        /* Get failing address */
546         rlwinm. r2,r2,0,31,31   /* Check for little endian access */
547         rlwimi  r2,r2,1,30,30   /* change 1 -> 3 */
548         xor     r1,r1,r2
549         mtspr   DAR,r1          /* Set fault address */
550         mfmsr   r0              /* Restore "normal" registers */
551         xoris   r0,r0,MSR_TGPR>>16
552         mtcrf   0x80,r3         /* Restore CR0 */
553         mtmsr   r0
554         b       InstructionAccess
555
556 /*
557  * Handle TLB miss for DATA Load operation on 603/603e
558  */
559         . = 0x1100
560 DataLoadTLBMiss:
561 /*
562  * r0:  stored ctr
563  * r1:  linux style pte ( later becomes ppc hardware pte )
564  * r2:  ptr to linux-style pte
565  * r3:  scratch
566  */
567         mfctr   r0
568         /* Get PTE (linux-style) and check access */
569         mfspr   r3,DMISS
570         lis     r1,KERNELBASE@h         /* check if kernel address */
571         cmplw   0,r3,r1
572         mfspr   r2,SPRG3
573         li      r1,_PAGE_USER|_PAGE_PRESENT /* low addresses tested as user */
574         lwz     r2,PGDIR(r2)
575         blt+    112f
576         lis     r2,swapper_pg_dir@ha    /* if kernel address, use */
577         addi    r2,r2,swapper_pg_dir@l  /* kernel page table */
578         mfspr   r1,SRR1                 /* and MSR_PR bit from SRR1 */
579         rlwinm  r1,r1,32-12,29,29       /* shift MSR_PR to _PAGE_USER posn */
580 112:    tophys(r2,r2)
581         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         tophys(r2,r2)
586         rlwimi  r2,r3,22,20,29          /* insert next 10 bits of address */
587         lwz     r3,0(r2)                /* get linux-style pte */
588         andc.   r1,r1,r3                /* check access & ~permission */
589         bne-    DataAddressInvalid      /* return if access not permitted */
590         ori     r3,r3,_PAGE_ACCESSED    /* set _PAGE_ACCESSED in pte */
591         /*
592          * NOTE! We are assuming this is not an SMP system, otherwise
593          * we would need to update the pte atomically with lwarx/stwcx.
594          */
595         stw     r3,0(r2)                /* update PTE (accessed bit) */
596         /* Convert linux-style PTE to low word of PPC-style PTE */
597         rlwinm  r1,r3,32-10,31,31       /* _PAGE_RW -> PP lsb */
598         rlwinm  r2,r3,32-7,31,31        /* _PAGE_DIRTY -> PP lsb */
599         and     r1,r1,r2                /* writable if _RW and _DIRTY */
600         rlwimi  r3,r3,32-1,30,30        /* _PAGE_USER -> PP msb */
601         rlwimi  r3,r3,32-1,31,31        /* _PAGE_USER -> PP lsb */
602         ori     r1,r1,0xe14             /* clear out reserved bits and M */
603         andc    r1,r3,r1                /* PP = user? (rw&dirty? 2: 3): 0 */
604         mtspr   RPA,r1
605         mfspr   r3,DMISS
606         tlbld   r3
607         mfspr   r3,SRR1         /* Need to restore CR0 */
608         mtcrf   0x80,r3
609         rfi
610 DataAddressInvalid:
611         mfspr   r3,SRR1
612         rlwinm  r1,r3,9,6,6     /* Get load/store bit */
613         addis   r1,r1,0x2000
614         mtspr   DSISR,r1
615         mtctr   r0              /* Restore CTR */
616         andi.   r2,r3,0xFFFF    /* Clear upper bits of SRR1 */
617         mtspr   SRR1,r2
618         mfspr   r1,DMISS        /* Get failing address */
619         rlwinm. r2,r2,0,31,31   /* Check for little endian access */
620         beq     20f             /* Jump if big endian */
621         xori    r1,r1,3
622 20:     mtspr   DAR,r1          /* Set fault address */
623         mfmsr   r0              /* Restore "normal" registers */
624         xoris   r0,r0,MSR_TGPR>>16
625         mtcrf   0x80,r3         /* Restore CR0 */
626         mtmsr   r0
627         b       DataAccess
628
629 /*
630  * Handle TLB miss for DATA Store on 603/603e
631  */
632         . = 0x1200
633 DataStoreTLBMiss:
634 /*
635  * r0:  stored ctr
636  * r1:  linux style pte ( later becomes ppc hardware pte )
637  * r2:  ptr to linux-style pte
638  * r3:  scratch
639  */
640         mfctr   r0
641         /* Get PTE (linux-style) and check access */
642         mfspr   r3,DMISS
643         lis     r1,KERNELBASE@h         /* check if kernel address */
644         cmplw   0,r3,r1
645         mfspr   r2,SPRG3
646         li      r1,_PAGE_RW|_PAGE_USER|_PAGE_PRESENT /* access flags */
647         lwz     r2,PGDIR(r2)
648         blt+    112f
649         lis     r2,swapper_pg_dir@ha    /* if kernel address, use */
650         addi    r2,r2,swapper_pg_dir@l  /* kernel page table */
651         mfspr   r1,SRR1                 /* and MSR_PR bit from SRR1 */
652         rlwinm  r1,r1,32-12,29,29       /* shift MSR_PR to _PAGE_USER posn */
653 112:    tophys(r2,r2)
654         rlwimi  r2,r3,12,20,29          /* insert top 10 bits of address */
655         lwz     r2,0(r2)                /* get pmd entry */
656         rlwinm. r2,r2,0,0,19            /* extract address of pte page */
657         beq-    DataAddressInvalid      /* return if no mapping */
658         tophys(r2,r2)
659         rlwimi  r2,r3,22,20,29          /* insert next 10 bits of address */
660         lwz     r3,0(r2)                /* get linux-style pte */
661         andc.   r1,r1,r3                /* check access & ~permission */
662         bne-    DataAddressInvalid      /* return if access not permitted */
663         ori     r3,r3,_PAGE_ACCESSED|_PAGE_DIRTY
664         /*
665          * NOTE! We are assuming this is not an SMP system, otherwise
666          * we would need to update the pte atomically with lwarx/stwcx.
667          */
668         stw     r3,0(r2)                /* update PTE (accessed/dirty bits) */
669         /* Convert linux-style PTE to low word of PPC-style PTE */
670         rlwimi  r3,r3,32-1,30,30        /* _PAGE_USER -> PP msb */
671         li      r1,0xe15                /* clear out reserved bits and M */
672         andc    r1,r3,r1                /* PP = user? 2: 0 */
673         mtspr   RPA,r1
674         mfspr   r3,DMISS
675         tlbld   r3
676         mfspr   r3,SRR1         /* Need to restore CR0 */
677         mtcrf   0x80,r3
678         rfi
679
680         STD_EXCEPTION(0x1300, Trap_13, InstructionBreakpoint)
681         STD_EXCEPTION(0x1400, SMI, SMIException)
682         STD_EXCEPTION(0x1500, Trap_15, UnknownException)
683         STD_EXCEPTION(0x1600, Trap_16, UnknownException)
684         STD_EXCEPTION(0x1700, Trap_17, TAUException)
685         STD_EXCEPTION(0x1800, Trap_18, UnknownException)
686         STD_EXCEPTION(0x1900, Trap_19, UnknownException)
687         STD_EXCEPTION(0x1a00, Trap_1a, UnknownException)
688         STD_EXCEPTION(0x1b00, Trap_1b, UnknownException)
689         STD_EXCEPTION(0x1c00, Trap_1c, UnknownException)
690         STD_EXCEPTION(0x1d00, Trap_1d, UnknownException)
691         STD_EXCEPTION(0x1e00, Trap_1e, UnknownException)
692         STD_EXCEPTION(0x1f00, Trap_1f, UnknownException)
693         STD_EXCEPTION(0x2000, RunMode, RunModeException)
694         STD_EXCEPTION(0x2100, Trap_21, UnknownException)
695         STD_EXCEPTION(0x2200, Trap_22, UnknownException)
696         STD_EXCEPTION(0x2300, Trap_23, UnknownException)
697         STD_EXCEPTION(0x2400, Trap_24, UnknownException)
698         STD_EXCEPTION(0x2500, Trap_25, UnknownException)
699         STD_EXCEPTION(0x2600, Trap_26, UnknownException)
700         STD_EXCEPTION(0x2700, Trap_27, UnknownException)
701         STD_EXCEPTION(0x2800, Trap_28, UnknownException)
702         STD_EXCEPTION(0x2900, Trap_29, UnknownException)
703         STD_EXCEPTION(0x2a00, Trap_2a, UnknownException)
704         STD_EXCEPTION(0x2b00, Trap_2b, UnknownException)
705         STD_EXCEPTION(0x2c00, Trap_2c, UnknownException)
706         STD_EXCEPTION(0x2d00, Trap_2d, UnknownException)
707         STD_EXCEPTION(0x2e00, Trap_2e, UnknownException)
708         STD_EXCEPTION(0x2f00, Trap_2f, UnknownException)
709
710         . = 0x3000
711
712 #ifdef CONFIG_ALTIVEC
713 AltiVecUnavailable:
714         EXCEPTION_PROLOG
715         bne     load_up_altivec         /* if from user, just load it up */
716         li      r20,MSR_KERNEL
717         bl      transfer_to_handler     /* if from kernel, take a trap */
718         .long   KernelAltiVec
719         .long   ret_from_except
720 #endif /* CONFIG_ALTIVEC */
721
722 #ifdef CONFIG_PPC64BRIDGE
723 DataAccess:
724         EXCEPTION_PROLOG
725         b       DataAccessCont
726 InstructionAccess:
727         EXCEPTION_PROLOG
728         b       InstructionAccessCont
729 DataSegment:
730         EXCEPTION_PROLOG
731         b       DataSegmentCont
732 InstructionSegment:
733         EXCEPTION_PROLOG
734         b       InstructionSegmentCont
735 #endif /* CONFIG_PPC64BRIDGE */
736
737 /*
738  * This task wants to use the FPU now.
739  * On UP, disable FP for the task which had the FPU previously,
740  * and save its floating-point registers in its thread_struct.
741  * Load up this task's FP registers from its thread_struct,
742  * enable the FPU for the current task and return to the task.
743  */
744 load_up_fpu:
745         mfmsr   r5
746         ori     r5,r5,MSR_FP
747 #ifdef CONFIG_PPC64BRIDGE
748         clrldi  r5,r5,1                 /* turn off 64-bit mode */
749 #endif /* CONFIG_PPC64BRIDGE */
750         SYNC
751         MTMSRD(r5)                      /* enable use of fpu now */
752         isync
753 /*
754  * For SMP, we don't do lazy FPU switching because it just gets too
755  * horrendously complex, especially when a task switches from one CPU
756  * to another.  Instead we call giveup_fpu in switch_to.
757  */
758 #ifndef CONFIG_SMP
759         tophys(r6,0)                    /* get __pa constant */
760         addis   r3,r6,last_task_used_math@ha
761         lwz     r4,last_task_used_math@l(r3)
762         cmpi    0,r4,0
763         beq     1f
764         add     r4,r4,r6
765         addi    r4,r4,THREAD            /* want last_task_used_math->thread */
766         SAVE_32FPRS(0, r4)
767         mffs    fr0
768         stfd    fr0,THREAD_FPSCR-4(r4)
769         lwz     r5,PT_REGS(r4)
770         add     r5,r5,r6
771         lwz     r4,_MSR-STACK_FRAME_OVERHEAD(r5)
772         li      r20,MSR_FP|MSR_FE0|MSR_FE1
773         andc    r4,r4,r20               /* disable FP for previous task */
774         stw     r4,_MSR-STACK_FRAME_OVERHEAD(r5)
775 1:
776 #endif /* CONFIG_SMP */
777         /* enable use of FP after return */
778         mfspr   r5,SPRG3                /* current task's THREAD (phys) */
779         lwz     r4,THREAD_FPEXC_MODE(r5)
780         ori     r23,r23,MSR_FP          /* enable FP for current */
781         or      r23,r23,r4
782         lfd     fr0,THREAD_FPSCR-4(r5)
783         mtfsf   0xff,fr0
784         REST_32FPRS(0, r5)
785 #ifndef CONFIG_SMP
786         subi    r4,r5,THREAD
787         sub     r4,r4,r6
788         stw     r4,last_task_used_math@l(r3)
789 #endif /* CONFIG_SMP */
790         /* restore registers and return */
791         lwz     r3,_CCR(r21)
792         lwz     r4,_LINK(r21)
793         mtcrf   0xff,r3
794         mtlr    r4
795         REST_GPR(1, r21)
796         REST_4GPRS(3, r21)
797         /* we haven't used ctr or xer */
798         mtspr   SRR1,r23
799         mtspr   SRR0,r22
800         REST_GPR(20, r21)
801         REST_2GPRS(22, r21)
802         lwz     r21,GPR21(r21)
803         SYNC
804         RFI
805
806 /*
807  * FP unavailable trap from kernel - print a message, but let
808  * the task use FP in the kernel until it returns to user mode.
809  */
810 KernelFP:
811         lwz     r3,_MSR(r1)
812         ori     r3,r3,MSR_FP
813         stw     r3,_MSR(r1)             /* enable use of FP after return */
814         lis     r3,86f@h
815         ori     r3,r3,86f@l
816         mr      r4,r2                   /* current */
817         lwz     r5,_NIP(r1)
818         bl      printk
819         b       ret_from_except
820 86:     .string "floating point used in kernel (task=%p, pc=%x)\n"
821         .align  4
822
823 #ifdef CONFIG_ALTIVEC
824 /* Note that the AltiVec support is closely modeled after the FP
825  * support.  Changes to one are likely to be applicable to the
826  * other!  */
827 load_up_altivec:
828 /*
829  * Disable AltiVec for the task which had AltiVec previously,
830  * and save its AltiVec registers in its thread_struct.
831  * Enables AltiVec for use in the kernel on return.
832  * On SMP we know the AltiVec units are free, since we give it up every
833  * switch.  -- Kumar
834  */
835         mfmsr   r5
836         oris    r5,r5,MSR_VEC@h
837         mtmsr   r5                      /* enable use of AltiVec now */
838         isync
839 /*
840  * For SMP, we don't do lazy AltiVec switching because it just gets too
841  * horrendously complex, especially when a task switches from one CPU
842  * to another.  Instead we call giveup_altivec in switch_to.
843  */
844 #ifndef CONFIG_SMP
845 #ifndef CONFIG_APUS
846         lis     r6,-KERNELBASE@h
847 #else
848         lis     r6,CYBERBASEp@h
849         lwz     r6,0(r6)
850 #endif
851         addis   r3,r6,last_task_used_altivec@ha
852         lwz     r4,last_task_used_altivec@l(r3)
853         cmpi    0,r4,0
854         beq     1f
855         add     r4,r4,r6
856         addi    r4,r4,THREAD    /* want THREAD of last_task_used_altivec */
857         SAVE_32VR(0,r20,r4)
858         MFVSCR(vr0)
859         li      r20,THREAD_VSCR
860         STVX(vr0,r20,r4)
861         lwz     r5,PT_REGS(r4)
862         add     r5,r5,r6
863         lwz     r4,_MSR-STACK_FRAME_OVERHEAD(r5)
864         lis     r20,MSR_VEC@h
865         andc    r4,r4,r20       /* disable altivec for previous task */
866         stw     r4,_MSR-STACK_FRAME_OVERHEAD(r5)
867 1:
868 #endif /* CONFIG_SMP */
869         /* enable use of AltiVec after return */
870         oris    r23,r23,MSR_VEC@h
871         mfspr   r5,SPRG3                /* current task's THREAD (phys) */
872         li      r20,THREAD_VSCR
873         LVX(vr0,r20,r5)
874         MTVSCR(vr0)
875         REST_32VR(0,r20,r5)
876 #ifndef CONFIG_SMP
877         subi    r4,r5,THREAD
878         sub     r4,r4,r6
879         stw     r4,last_task_used_altivec@l(r3)
880 #endif /* CONFIG_SMP */
881         /* restore registers and return */
882         lwz     r3,_CCR(r21)
883         lwz     r4,_LINK(r21)
884         mtcrf   0xff,r3
885         mtlr    r4
886         REST_GPR(1, r21)
887         REST_4GPRS(3, r21)
888         /* we haven't used ctr or xer */
889         mtspr   SRR1,r23
890         mtspr   SRR0,r22
891         REST_GPR(20, r21)
892         REST_2GPRS(22, r21)
893         lwz     r21,GPR21(r21)
894         SYNC
895         RFI
896
897 /*
898  * AltiVec unavailable trap from kernel - print a message, but let
899  * the task use AltiVec in the kernel until it returns to user mode.
900  */
901 KernelAltiVec:
902         lwz     r3,_MSR(r1)
903         oris    r3,r3,MSR_VEC@h
904         stw     r3,_MSR(r1)     /* enable use of AltiVec after return */
905         lis     r3,87f@h
906         ori     r3,r3,87f@l
907         mr      r4,r2           /* current */
908         lwz     r5,_NIP(r1)
909         bl      printk
910         b       ret_from_except
911 87:     .string "AltiVec used in kernel  (task=%p, pc=%x)  \n"
912         .align  4
913
914 /*
915  * giveup_altivec(tsk)
916  * Disable AltiVec for the task given as the argument,
917  * and save the AltiVec registers in its thread_struct.
918  * Enables AltiVec for use in the kernel on return.
919  */
920
921         .globl  giveup_altivec
922 giveup_altivec:
923         mfmsr   r5
924         oris    r5,r5,MSR_VEC@h
925         SYNC
926         mtmsr   r5                      /* enable use of AltiVec now */
927         isync
928         cmpi    0,r3,0
929         beqlr-                          /* if no previous owner, done */
930         addi    r3,r3,THREAD            /* want THREAD of task */
931         lwz     r5,PT_REGS(r3)
932         cmpi    0,r5,0
933         SAVE_32VR(0, r4, r3)
934         MFVSCR(vr0)
935         li      r4,THREAD_VSCR
936         STVX(vr0, r4, r3)
937         beq     1f
938         lwz     r4,_MSR-STACK_FRAME_OVERHEAD(r5)
939         lis     r3,MSR_VEC@h
940         andc    r4,r4,r3                /* disable AltiVec for previous task */
941         stw     r4,_MSR-STACK_FRAME_OVERHEAD(r5)
942 1:
943 #ifndef CONFIG_SMP
944         li      r5,0
945         lis     r4,last_task_used_altivec@ha
946         stw     r5,last_task_used_altivec@l(r4)
947 #endif /* CONFIG_SMP */
948         blr
949 #endif /* CONFIG_ALTIVEC */
950
951 /*
952  * giveup_fpu(tsk)
953  * Disable FP for the task given as the argument,
954  * and save the floating-point registers in its thread_struct.
955  * Enables the FPU for use in the kernel on return.
956  */
957         .globl  giveup_fpu
958 giveup_fpu:
959         mfmsr   r5
960         ori     r5,r5,MSR_FP
961         SYNC_601
962         ISYNC_601
963         mtmsr   r5                      /* enable use of fpu now */
964         SYNC_601
965         isync
966         cmpi    0,r3,0
967         beqlr-                          /* if no previous owner, done */
968         addi    r3,r3,THREAD            /* want THREAD of task */
969         lwz     r5,PT_REGS(r3)
970         cmpi    0,r5,0
971         SAVE_32FPRS(0, r3)
972         mffs    fr0
973         stfd    fr0,THREAD_FPSCR-4(r3)
974         beq     1f
975         lwz     r4,_MSR-STACK_FRAME_OVERHEAD(r5)
976         li      r3,MSR_FP|MSR_FE0|MSR_FE1
977         andc    r4,r4,r3                /* disable FP for previous task */
978         stw     r4,_MSR-STACK_FRAME_OVERHEAD(r5)
979 1:
980 #ifndef CONFIG_SMP
981         li      r5,0
982         lis     r4,last_task_used_math@ha
983         stw     r5,last_task_used_math@l(r4)
984 #endif /* CONFIG_SMP */
985         blr
986
987 /*
988  * This code is jumped to from the startup code to copy
989  * the kernel image to physical address 0.
990  */
991 relocate_kernel:
992         addis   r9,r26,klimit@ha        /* fetch klimit */
993         lwz     r25,klimit@l(r9)
994         addis   r25,r25,-KERNELBASE@h
995         li      r3,0                    /* Destination base address */
996         li      r6,0                    /* Destination offset */
997         li      r5,0x4000               /* # bytes of memory to copy */
998         bl      copy_and_flush          /* copy the first 0x4000 bytes */
999         addi    r0,r3,4f@l              /* jump to the address of 4f */
1000         mtctr   r0                      /* in copy and do the rest. */
1001         bctr                            /* jump to the copy */
1002 4:      mr      r5,r25
1003         bl      copy_and_flush          /* copy the rest */
1004         b       turn_on_mmu
1005
1006 /*
1007  * Copy routine used to copy the kernel to start at physical address 0
1008  * and flush and invalidate the caches as needed.
1009  * r3 = dest addr, r4 = source addr, r5 = copy limit, r6 = start offset
1010  * on exit, r3, r4, r5 are unchanged, r6 is updated to be >= r5.
1011  */
1012 copy_and_flush:
1013         addi    r5,r5,-4
1014         addi    r6,r6,-4
1015 4:      li      r0,L1_CACHE_LINE_SIZE/4
1016         mtctr   r0
1017 3:      addi    r6,r6,4                 /* copy a cache line */
1018         lwzx    r0,r6,r4
1019         stwx    r0,r6,r3
1020         bdnz    3b
1021         dcbst   r6,r3                   /* write it to memory */
1022         sync
1023         icbi    r6,r3                   /* flush the icache line */
1024         cmplw   0,r6,r5
1025         blt     4b
1026         sync                            /* additional sync needed on g4 */
1027         isync
1028         addi    r5,r5,4
1029         addi    r6,r6,4
1030         blr
1031
1032 #ifdef CONFIG_APUS
1033 /*
1034  * On APUS the physical base address of the kernel is not known at compile
1035  * time, which means the __pa/__va constants used are incorrect. In the
1036  * __init section is recorded the virtual addresses of instructions using
1037  * these constants, so all that has to be done is fix these before
1038  * continuing the kernel boot.
1039  *
1040  * r4 = The physical address of the kernel base.
1041  */
1042 fix_mem_constants:
1043         mr      r10,r4
1044         addis   r10,r10,-KERNELBASE@h    /* virt_to_phys constant */
1045         neg     r11,r10                  /* phys_to_virt constant */
1046
1047         lis     r12,__vtop_table_begin@h
1048         ori     r12,r12,__vtop_table_begin@l
1049         add     r12,r12,r10              /* table begin phys address */
1050         lis     r13,__vtop_table_end@h
1051         ori     r13,r13,__vtop_table_end@l
1052         add     r13,r13,r10              /* table end phys address */
1053         subi    r12,r12,4
1054         subi    r13,r13,4
1055 1:      lwzu    r14,4(r12)               /* virt address of instruction */
1056         add     r14,r14,r10              /* phys address of instruction */
1057         lwz     r15,0(r14)               /* instruction, now insert top */
1058         rlwimi  r15,r10,16,16,31         /* half of vp const in low half */
1059         stw     r15,0(r14)               /* of instruction and restore. */
1060         dcbst   r0,r14                   /* write it to memory */
1061         sync
1062         icbi    r0,r14                   /* flush the icache line */
1063         cmpw    r12,r13
1064         bne     1b
1065         sync                            /* additional sync needed on g4 */
1066         isync
1067
1068 /*
1069  * Map the memory where the exception handlers will
1070  * be copied to when hash constants have been patched.  
1071  */
1072 #ifdef CONFIG_APUS_FAST_EXCEPT
1073         lis     r8,0xfff0
1074 #else
1075         lis     r8,0
1076 #endif
1077         ori     r8,r8,0x2               /* 128KB, supervisor */
1078         mtspr   DBAT3U,r8
1079         mtspr   DBAT3L,r8
1080
1081         lis     r12,__ptov_table_begin@h
1082         ori     r12,r12,__ptov_table_begin@l
1083         add     r12,r12,r10              /* table begin phys address */
1084         lis     r13,__ptov_table_end@h
1085         ori     r13,r13,__ptov_table_end@l
1086         add     r13,r13,r10              /* table end phys address */
1087         subi    r12,r12,4
1088         subi    r13,r13,4
1089 1:      lwzu    r14,4(r12)               /* virt address of instruction */
1090         add     r14,r14,r10              /* phys address of instruction */
1091         lwz     r15,0(r14)               /* instruction, now insert top */
1092         rlwimi  r15,r11,16,16,31         /* half of pv const in low half*/
1093         stw     r15,0(r14)               /* of instruction and restore. */
1094         dcbst   r0,r14                   /* write it to memory */
1095         sync
1096         icbi    r0,r14                   /* flush the icache line */
1097         cmpw    r12,r13
1098         bne     1b
1099
1100         sync                            /* additional sync needed on g4 */
1101         isync                           /* No speculative loading until now */
1102         blr
1103
1104 /***********************************************************************
1105  *  Please note that on APUS the exception handlers are located at the
1106  *  physical address 0xfff0000. For this reason, the exception handlers
1107  *  cannot use relative branches to access the code below.
1108  ***********************************************************************/
1109 #endif /* CONFIG_APUS */
1110
1111 #ifdef CONFIG_SMP
1112 #ifdef CONFIG_GEMINI
1113         .globl  __secondary_start_gemini
1114 __secondary_start_gemini:
1115         mfspr   r4,HID0
1116         ori     r4,r4,HID0_ICFI
1117         li      r3,0
1118         ori     r3,r3,HID0_ICE
1119         andc    r4,r4,r3
1120         mtspr   HID0,r4
1121         sync
1122         bl      gemini_prom_init
1123         b       __secondary_start
1124 #endif /* CONFIG_GEMINI */
1125         .globl  __secondary_start_psurge
1126 __secondary_start_psurge:
1127         li      r24,1                   /* cpu # */
1128         b       __secondary_start_psurge99
1129         .globl  __secondary_start_psurge2
1130 __secondary_start_psurge2:
1131         li      r24,2                   /* cpu # */
1132         b       __secondary_start_psurge99
1133         .globl  __secondary_start_psurge3
1134 __secondary_start_psurge3:
1135         li      r24,3                   /* cpu # */
1136         b       __secondary_start_psurge99
1137 __secondary_start_psurge99:
1138         /* we come in here with IR=0 and DR=1, and DBAT 0
1139            set to map the 0xf0000000 - 0xffffffff region */
1140         mfmsr   r0
1141         rlwinm  r0,r0,0,28,26           /* clear DR (0x10) */
1142         SYNC
1143         mtmsr   r0
1144         isync
1145
1146         .globl  __secondary_start
1147 __secondary_start:
1148 #ifdef CONFIG_PPC64BRIDGE
1149         mfmsr   r0
1150         clrldi  r0,r0,1         /* make sure it's in 32-bit mode */
1151         SYNC
1152         MTMSRD(r0)
1153         isync
1154 #endif
1155
1156         lis     r3,-KERNELBASE@h
1157         mr      r4,r24
1158         bl      identify_cpu
1159         bl      call_setup_cpu          /* Call setup_cpu for this CPU */
1160
1161         /* get current_thread_info and current */
1162         lis     r1,secondary_ti@ha
1163         tophys(r1,r1)
1164         lwz     r1,secondary_ti@l(r1)
1165         tophys(r2,r1)
1166         lwz     r2,TI_TASK(r2)
1167
1168         /* stack */
1169         addi    r1,r1,THREAD_SIZE-STACK_FRAME_OVERHEAD
1170         li      r0,0
1171         tophys(r3,r1)
1172         stw     r0,0(r3)
1173
1174         /* load up the MMU */
1175         bl      load_up_mmu
1176
1177         /* ptr to phys current thread */
1178         tophys(r4,r2)
1179         addi    r4,r4,THREAD    /* phys address of our thread_struct */
1180         CLR_TOP32(r4)
1181         mtspr   SPRG3,r4
1182         li      r3,0
1183         mtspr   SPRG2,r3        /* 0 => r1 has kernel sp */
1184
1185         /* enable MMU and jump to start_secondary */
1186         li      r4,MSR_KERNEL
1187         lis     r3,start_secondary@h
1188         ori     r3,r3,start_secondary@l
1189         mtspr   SRR0,r3
1190         mtspr   SRR1,r4
1191         SYNC
1192         RFI
1193 #endif /* CONFIG_SMP */
1194
1195 /*
1196  * Enable caches and 604-specific features if necessary.
1197  */
1198 _GLOBAL(__setup_cpu_601)
1199         blr
1200 _GLOBAL(__setup_cpu_603)
1201         b       setup_common_caches
1202 _GLOBAL(__setup_cpu_604)
1203         mflr    r4
1204         bl      setup_common_caches
1205         bl      setup_604_hid0
1206         mtlr    r4
1207         blr
1208 _GLOBAL(__setup_cpu_750)
1209         mflr    r4
1210         bl      setup_common_caches
1211         bl      setup_750_7400_hid0
1212         mtlr    r4
1213         blr
1214 _GLOBAL(__setup_cpu_7400)
1215         mflr    r4
1216         bl      setup_common_caches
1217         bl      setup_750_7400_hid0
1218         mtlr    r4
1219         blr
1220 _GLOBAL(__setup_cpu_7410)
1221         mflr    r4
1222         bl      setup_common_caches
1223         bl      setup_750_7400_hid0
1224         li      r3,0
1225         mtspr   SPRN_L2CR2,r3
1226         mtlr    r4
1227         blr
1228 _GLOBAL(__setup_cpu_7450)
1229         mflr    r4
1230         bl      setup_common_caches
1231         bl      setup_7450_hid0
1232         mtlr    r4
1233         blr
1234 _GLOBAL(__setup_cpu_power3)
1235         blr
1236 _GLOBAL(__setup_cpu_generic)
1237         blr
1238
1239 /* Enable caches for 603's, 604, 750 & 7400 */
1240 setup_common_caches:
1241         mfspr   r11,HID0
1242         andi.   r0,r11,HID0_DCE
1243         ori     r11,r11,HID0_ICE|HID0_DCE
1244         ori     r8,r11,HID0_ICFI
1245         bne     1f                      /* don't invalidate the D-cache */
1246         ori     r8,r8,HID0_DCI          /* unless it wasn't enabled */
1247 1:      sync
1248         mtspr   HID0,r8                 /* enable and invalidate caches */
1249         sync
1250         mtspr   HID0,r11                /* enable caches */
1251         sync
1252         isync
1253         blr
1254
1255 /* 604, 604e, 604ev, ...
1256  * Enable superscalar execution & branch history table
1257  */
1258 setup_604_hid0:
1259         mfspr   r11,HID0
1260         ori     r11,r11,HID0_SIED|HID0_BHTE
1261         ori     r8,r11,HID0_BTCD
1262         sync
1263         mtspr   HID0,r8         /* flush branch target address cache */
1264         sync                    /* on 604e/604r */
1265         mtspr   HID0,r11
1266         sync
1267         isync
1268         blr
1269
1270 /* 740/750/7400/7410
1271  * Enable Store Gathering (SGE), Address Brodcast (ABE),
1272  * Branch History Table (BHTE), Branch Target ICache (BTIC)
1273  * Dynamic Power Management (DPM), Speculative (SPD)
1274  * Clear Instruction cache throttling (ICTC)
1275  */
1276 setup_750_7400_hid0:
1277         mfspr   r11,HID0
1278         ori     r11,r11,HID0_SGE | HID0_ABE | HID0_BHTE | HID0_BTIC
1279         oris    r11,r11,HID0_DPM@h      /* enable dynamic power mgmt */
1280         li      r3,HID0_SPD
1281         andc    r11,r11,r3              /* clear SPD: enable speculative */
1282         li      r3,0
1283         mtspr   ICTC,r3                 /* Instruction Cache Throttling off */
1284         isync
1285         mtspr   HID0,r11
1286         sync
1287         isync
1288         blr
1289
1290 /* 7450
1291  * Enable Store Gathering (SGE), Branch Folding (FOLD)
1292  * Branch History Table (BHTE), Branch Target ICache (BTIC)
1293  * Dynamic Power Management (DPM), Speculative (SPD)
1294  * Ensure our data cache instructions really operate.
1295  * Timebase has to be running or we wouldn't have made it here,
1296  * just ensure we don't disable it.
1297  * Clear Instruction cache throttling (ICTC)
1298  */
1299 setup_7450_hid0:
1300         /* We check for the presence of an L3 cache setup by
1301          * the firmware. If any, we disable DOZE capability
1302          */
1303         mfspr   r11,SPRN_L3CR
1304         andis.  r11,r11,L3CR_L3E@h
1305         beq     1f
1306         li      r7,CPU_FTR_CAN_DOZE
1307         lwz     r6,CPU_SPEC_FEATURES(r5)
1308         andc    r6,r6,r7
1309         stw     r6,CPU_SPEC_FEATURES(r5)
1310 1:      
1311         mfspr   r11,HID0
1312
1313         /* All of the bits we have to set.....
1314         */
1315         ori     r11,r11,HID0_SGE | HID0_FOLD | HID0_BHTE | HID0_BTIC
1316         oris    r11,r11,HID0_DPM@h      /* enable dynamic power mgmt */
1317
1318         /* All of the bits we have to clear....
1319         */
1320         li      r3,HID0_SPD | HID0_NOPDST | HID0_NOPTI
1321         andc    r11,r11,r3              /* clear SPD: enable speculative */
1322         li      r3,0
1323
1324         mtspr   ICTC,r3                 /* Instruction Cache Throttling off */
1325         isync
1326         mtspr   HID0,r11
1327         sync
1328         isync
1329         blr
1330
1331 /*
1332  * Load stuff into the MMU.  Intended to be called with
1333  * IR=0 and DR=0.
1334  */
1335 load_up_mmu:
1336         /* Load the SDR1 register (hash table base & size) */
1337         lis     r6,_SDR1@ha
1338         tophys(r6,r6)
1339         lwz     r6,_SDR1@l(r6)
1340         mtspr   SDR1,r6
1341 #ifdef CONFIG_PPC64BRIDGE
1342         /* clear the ASR so we only use the pseudo-segment registers. */
1343         li      r6,0
1344         mtasr   r6
1345 #endif /* CONFIG_PPC64BRIDGE */
1346         li      r0,16           /* load up segment register values */
1347         mtctr   r0              /* for context 0 */
1348         lis     r3,0x2000       /* Ku = 1, VSID = 0 */
1349         li      r4,0
1350 3:      mtsrin  r3,r4
1351         addi    r3,r3,0x111     /* increment VSID */
1352         addis   r4,r4,0x1000    /* address of next segment */
1353         bdnz    3b
1354 /* Load the BAT registers with the values set up by MMU_init.
1355    MMU_init takes care of whether we're on a 601 or not. */
1356         mfpvr   r3
1357         srwi    r3,r3,16
1358         cmpwi   r3,1
1359         lis     r3,BATS@ha
1360         addi    r3,r3,BATS@l
1361         tophys(r3,r3)
1362         LOAD_BAT(0,r3,r4,r5)
1363         LOAD_BAT(1,r3,r4,r5)
1364         LOAD_BAT(2,r3,r4,r5)
1365         LOAD_BAT(3,r3,r4,r5)
1366         blr
1367
1368 /*
1369  * This is where the main kernel code starts.
1370  */
1371 start_here:
1372         /* Call setup_cpu for CPU 0 */
1373         li      r3,0            /* data offset */
1374         li      r24,0           /* cpu# */
1375         bl      call_setup_cpu
1376
1377         /* ptr to current */
1378         lis     r2,init_task@h
1379         ori     r2,r2,init_task@l
1380         /* Set up for using our exception vectors */
1381         /* ptr to phys current thread */
1382         tophys(r4,r2)
1383         addi    r4,r4,THREAD    /* init task's THREAD */
1384         CLR_TOP32(r4)
1385         mtspr   SPRG3,r4
1386         li      r3,0
1387         mtspr   SPRG2,r3        /* 0 => r1 has kernel sp */
1388
1389         /* stack */
1390         lis     r1,init_thread_union@ha
1391         addi    r1,r1,init_thread_union@l
1392         li      r0,0
1393         stwu    r0,THREAD_SIZE-STACK_FRAME_OVERHEAD(r1)
1394 /*
1395  * Do early bootinfo parsing, platform-specific initialization,
1396  * and set up the MMU.
1397  */
1398         mr      r3,r31
1399         mr      r4,r30
1400         mr      r5,r29
1401         mr      r6,r28
1402         mr      r7,r27
1403         bl      machine_init
1404         bl      MMU_init
1405
1406 #ifdef CONFIG_APUS
1407         /* Copy exception code to exception vector base on APUS. */
1408         lis     r4,KERNELBASE@h
1409 #ifdef CONFIG_APUS_FAST_EXCEPT
1410         lis     r3,0xfff0               /* Copy to 0xfff00000 */
1411 #else
1412         lis     r3,0                    /* Copy to 0x00000000 */
1413 #endif
1414         li      r5,0x4000               /* # bytes of memory to copy */
1415         li      r6,0
1416         bl      copy_and_flush          /* copy the first 0x4000 bytes */
1417 #endif  /* CONFIG_APUS */
1418
1419 /*
1420  * Go back to running unmapped so we can load up new values
1421  * for SDR1 (hash table pointer) and the segment registers
1422  * and change to using our exception vectors.
1423  */
1424         lis     r4,2f@h
1425         ori     r4,r4,2f@l
1426         tophys(r4,r4)
1427         li      r3,MSR_KERNEL & ~(MSR_IR|MSR_DR)
1428         FIX_SRR1(r3,r5)
1429         mtspr   SRR0,r4
1430         mtspr   SRR1,r3
1431         SYNC
1432         RFI
1433 /* Load up the kernel context */
1434 2:
1435         sync                    /* Force all PTE updates to finish */
1436         ISYNC_601
1437         tlbia                   /* Clear all TLB entries */
1438         sync                    /* wait for tlbia/tlbie to finish */
1439         TLBSYNC                 /* ... on all CPUs */
1440
1441         bl      load_up_mmu
1442
1443         /* Add helper information for the Abatron bdiGDB debugger.
1444          * We do this here because we know the mmu is disabled, and
1445          * will be enabled for real in just a few instructions.
1446          */
1447         lis     r5, abatron_pteptrs@h
1448         ori     r5, r5, abatron_pteptrs@l
1449         stw     r5, 0xf0(r0)    /* This much match your Abatron config */
1450         lis     r6, swapper_pg_dir@h
1451         ori     r6, r6, swapper_pg_dir@l
1452         tophys(r5, r5)
1453         stw     r6, 0(r5)
1454
1455 /* Now turn on the MMU for real! */
1456         li      r4,MSR_KERNEL
1457         FIX_SRR1(r4,r5)
1458         lis     r3,start_kernel@h
1459         ori     r3,r3,start_kernel@l
1460         mtspr   SRR0,r3
1461         mtspr   SRR1,r4
1462         SYNC
1463         RFI
1464
1465 /*
1466  * Set up the segment registers for a new context.
1467  */
1468 _GLOBAL(set_context)
1469         mulli   r3,r3,897       /* multiply context by skew factor */
1470         rlwinm  r3,r3,4,8,27    /* VSID = (context & 0xfffff) << 4 */
1471         addis   r3,r3,0x6000    /* Set Ks, Ku bits */
1472         li      r0,NUM_USER_SEGMENTS
1473         mtctr   r0
1474
1475 #ifdef CONFIG_BDI_SWITCH
1476         /* Context switch the PTE pointer for the Abatron BDI2000.
1477          * The PGDIR is passed as second argument.
1478          */
1479         lis     r5, KERNELBASE@h
1480         lwz     r5, 0xf0(r5)
1481         stw     r4, 0x4(r5)
1482 #endif
1483         li      r4,0
1484 3:
1485 #ifdef CONFIG_PPC64BRIDGE
1486         slbie   r4
1487 #endif /* CONFIG_PPC64BRIDGE */
1488         mtsrin  r3,r4
1489         addi    r3,r3,0x111     /* next VSID */
1490         rlwinm  r3,r3,0,8,3     /* clear out any overflow from VSID field */
1491         addis   r4,r4,0x1000    /* address of next segment */
1492         bdnz    3b
1493         SYNC_601
1494         isync
1495         blr
1496
1497 /* 
1498  * An undocumented "feature" of 604e requires that the v bit
1499  * be cleared before changing BAT values.
1500  *
1501  * Also, newer IBM firmware does not clear bat3 and 4 so
1502  * this makes sure it's done.
1503  *  -- Cort 
1504  */
1505 clear_bats:
1506         li      r20,0
1507         mfspr   r9,PVR
1508         rlwinm  r9,r9,16,16,31          /* r9 = 1 for 601, 4 for 604 */
1509         cmpwi   r9, 1
1510         beq     1f
1511
1512         mtspr   DBAT0U,r20
1513         mtspr   DBAT0L,r20
1514         mtspr   DBAT1U,r20
1515         mtspr   DBAT1L,r20
1516         mtspr   DBAT2U,r20
1517         mtspr   DBAT2L,r20
1518         mtspr   DBAT3U,r20
1519         mtspr   DBAT3L,r20
1520 1:
1521         mtspr   IBAT0U,r20
1522         mtspr   IBAT0L,r20
1523         mtspr   IBAT1U,r20
1524         mtspr   IBAT1L,r20
1525         mtspr   IBAT2U,r20
1526         mtspr   IBAT2L,r20
1527         mtspr   IBAT3U,r20
1528         mtspr   IBAT3L,r20
1529         blr
1530
1531 flush_tlbs:
1532         lis     r20, 0x40
1533 1:      addic.  r20, r20, -0x1000
1534         tlbie   r20
1535         blt     1b
1536         sync
1537         blr
1538
1539 mmu_off:
1540         addi    r4, r3, __after_mmu_off - _start
1541         mfmsr   r3
1542         andi.   r0,r3,MSR_DR|MSR_IR             /* MMU enabled? */
1543         beqlr
1544         andc    r3,r3,r0
1545         mtspr   SRR0,r4
1546         mtspr   SRR1,r3
1547         sync
1548         RFI
1549
1550 /*
1551  * Use the first pair of BAT registers to map the 1st 16MB
1552  * of RAM to KERNELBASE.  From this point on we can't safely
1553  * call OF any more.
1554  */
1555 initial_bats:
1556         lis     r11,KERNELBASE@h
1557 #ifndef CONFIG_PPC64BRIDGE
1558         mfspr   r9,PVR
1559         rlwinm  r9,r9,16,16,31          /* r9 = 1 for 601, 4 for 604 */
1560         cmpi    0,r9,1
1561         bne     4f
1562         ori     r11,r11,4               /* set up BAT registers for 601 */
1563         li      r8,0x7f                 /* valid, block length = 8MB */
1564         oris    r9,r11,0x800000@h       /* set up BAT reg for 2nd 8M */
1565         oris    r10,r8,0x800000@h       /* set up BAT reg for 2nd 8M */
1566         mtspr   IBAT0U,r11              /* N.B. 601 has valid bit in */
1567         mtspr   IBAT0L,r8               /* lower BAT register */
1568         mtspr   IBAT1U,r9
1569         mtspr   IBAT1L,r10
1570         isync
1571         blr
1572 #endif /* CONFIG_PPC64BRIDGE */
1573
1574 4:      tophys(r8,r11)
1575 #ifdef CONFIG_SMP
1576         ori     r8,r8,0x12              /* R/W access, M=1 */
1577 #else
1578         ori     r8,r8,2                 /* R/W access */
1579 #endif /* CONFIG_SMP */
1580 #ifdef CONFIG_APUS
1581         ori     r11,r11,BL_8M<<2|0x2    /* set up 8MB BAT registers for 604 */
1582 #else
1583         ori     r11,r11,BL_256M<<2|0x2  /* set up BAT registers for 604 */
1584 #endif /* CONFIG_APUS */
1585
1586 #ifdef CONFIG_PPC64BRIDGE
1587         /* clear out the high 32 bits in the BAT */
1588         clrldi  r11,r11,32
1589         clrldi  r8,r8,32
1590 #endif /* CONFIG_PPC64BRIDGE */
1591         mtspr   DBAT0L,r8               /* N.B. 6xx (not 601) have valid */
1592         mtspr   DBAT0U,r11              /* bit in upper BAT register */
1593         mtspr   IBAT0L,r8
1594         mtspr   IBAT0U,r11
1595         isync
1596         blr
1597
1598 #if !defined(CONFIG_APUS) && defined(CONFIG_BOOTX_TEXT)
1599 setup_disp_bat:
1600         /*
1601          * setup the display bat prepared for us in prom.c
1602          */
1603         mflr    r8
1604         bl      reloc_offset
1605         mtlr    r8
1606         addis   r8,r3,disp_BAT@ha
1607         addi    r8,r8,disp_BAT@l
1608         lwz     r11,0(r8)
1609         lwz     r8,4(r8)
1610         mfspr   r9,PVR
1611         rlwinm  r9,r9,16,16,31          /* r9 = 1 for 601, 4 for 604 */
1612         cmpi    0,r9,1
1613         beq     1f
1614         mtspr   DBAT3L,r8
1615         mtspr   DBAT3U,r11
1616         blr
1617 1:      mtspr   IBAT3L,r8
1618         mtspr   IBAT3U,r11
1619         blr
1620
1621 #endif /* !defined(CONFIG_APUS) && defined(CONFIG_BOOTX_TEXT) */
1622
1623 #ifdef CONFIG_8260
1624 /* Jump into the system reset for the rom.
1625  * We first disable the MMU, and then jump to the ROM reset address.
1626  *
1627  * r3 is the board info structure, r4 is the location for starting.
1628  * I use this for building a small kernel that can load other kernels,
1629  * rather than trying to write or rely on a rom monitor that can tftp load.
1630  */
1631        .globl  m8260_gorom
1632 m8260_gorom:
1633         mfmsr   r0
1634         rlwinm  r0,r0,0,17,15   /* clear MSR_EE in r0 */
1635         sync
1636         mtmsr   r0
1637         sync
1638         mfspr   r11, HID0
1639         lis     r10, 0
1640         ori     r10,r10,HID0_ICE|HID0_DCE
1641         andc    r11, r11, r10
1642         mtspr   HID0, r11
1643         isync
1644         li      r5, MSR_
1645         lis     r6,2f@h
1646         addis   r6,r6,-KERNELBASE@h
1647         ori     r6,r6,2f@l
1648         mtspr   SRR0,r6
1649         mtspr   SRR1,r5
1650         isync
1651         sync
1652         rfi
1653 2:
1654         mtlr    r4
1655         blr
1656 #endif
1657
1658
1659 /*
1660  * We put a few things here that have to be page-aligned.
1661  * This stuff goes at the beginning of the data segment,
1662  * which is page-aligned.
1663  */
1664         .data
1665         .globl  sdata
1666 sdata:
1667         .globl  empty_zero_page
1668 empty_zero_page:
1669         .space  4096
1670
1671         .globl  swapper_pg_dir
1672 swapper_pg_dir:
1673         .space  4096
1674
1675 /*
1676  * This space gets a copy of optional info passed to us by the bootstrap
1677  * Used to pass parameters into the kernel like root=/dev/sda1, etc.
1678  */
1679         .globl  cmd_line
1680 cmd_line:
1681         .space  512
1682
1683         .globl intercept_table
1684 intercept_table:
1685         .long 0, 0, i0x200, i0x300, i0x400, 0, i0x600, i0x700
1686         .long i0x800, 0, 0, 0, 0, i0xd00, 0, 0
1687         .long 0, 0, 0, i0x1300, 0, 0, 0, 0
1688         .long 0, 0, 0, 0, 0, 0, 0, 0
1689         .long 0, 0, 0, 0, 0, 0, 0, 0
1690         .long 0, 0, 0, 0, 0, 0, 0, 0
1691
1692 /* Room for two PTE pointers, usually the kernel and current user pointers
1693  * to their respective root page table.
1694  */
1695 abatron_pteptrs:
1696         .space  8