Merge branch 'power' into release
[linux-2.6] / arch / powerpc / kernel / head_40x.S
1 /*
2  *    Copyright (c) 1995-1996 Gary Thomas <gdt@linuxppc.org>
3  *      Initial PowerPC version.
4  *    Copyright (c) 1996 Cort Dougan <cort@cs.nmt.edu>
5  *      Rewritten for PReP
6  *    Copyright (c) 1996 Paul Mackerras <paulus@cs.anu.edu.au>
7  *      Low-level exception handers, MMU support, and rewrite.
8  *    Copyright (c) 1997 Dan Malek <dmalek@jlc.net>
9  *      PowerPC 8xx modifications.
10  *    Copyright (c) 1998-1999 TiVo, Inc.
11  *      PowerPC 403GCX modifications.
12  *    Copyright (c) 1999 Grant Erickson <grant@lcse.umn.edu>
13  *      PowerPC 403GCX/405GP modifications.
14  *    Copyright 2000 MontaVista Software Inc.
15  *      PPC405 modifications
16  *      PowerPC 403GCX/405GP modifications.
17  *      Author: MontaVista Software, Inc.
18  *              frank_rowand@mvista.com or source@mvista.com
19  *              debbie_chu@mvista.com
20  *
21  *
22  *    Module name: head_4xx.S
23  *
24  *    Description:
25  *      Kernel execution entry point code.
26  *
27  *    This program is free software; you can redistribute it and/or
28  *    modify it under the terms of the GNU General Public License
29  *    as published by the Free Software Foundation; either version
30  *    2 of the License, or (at your option) any later version.
31  *
32  */
33
34 #include <asm/processor.h>
35 #include <asm/page.h>
36 #include <asm/mmu.h>
37 #include <asm/pgtable.h>
38 #include <asm/cputable.h>
39 #include <asm/thread_info.h>
40 #include <asm/ppc_asm.h>
41 #include <asm/asm-offsets.h>
42
43 /* As with the other PowerPC ports, it is expected that when code
44  * execution begins here, the following registers contain valid, yet
45  * optional, information:
46  *
47  *   r3 - Board info structure pointer (DRAM, frequency, MAC address, etc.)
48  *   r4 - Starting address of the init RAM disk
49  *   r5 - Ending address of the init RAM disk
50  *   r6 - Start of kernel command line string (e.g. "mem=96m")
51  *   r7 - End of kernel command line string
52  *
53  * This is all going to change RSN when we add bi_recs.......  -- Dan
54  */
55         .section        .text.head, "ax"
56 _ENTRY(_stext);
57 _ENTRY(_start);
58
59         /* Save parameters we are passed.
60         */
61         mr      r31,r3
62         mr      r30,r4
63         mr      r29,r5
64         mr      r28,r6
65         mr      r27,r7
66
67         /* We have to turn on the MMU right away so we get cache modes
68          * set correctly.
69          */
70         bl      initial_mmu
71
72 /* We now have the lower 16 Meg mapped into TLB entries, and the caches
73  * ready to work.
74  */
75 turn_on_mmu:
76         lis     r0,MSR_KERNEL@h
77         ori     r0,r0,MSR_KERNEL@l
78         mtspr   SPRN_SRR1,r0
79         lis     r0,start_here@h
80         ori     r0,r0,start_here@l
81         mtspr   SPRN_SRR0,r0
82         SYNC
83         rfi                             /* enables MMU */
84         b       .                       /* prevent prefetch past rfi */
85
86 /*
87  * This area is used for temporarily saving registers during the
88  * critical exception prolog.
89  */
90         . = 0xc0
91 crit_save:
92 _ENTRY(crit_r10)
93         .space  4
94 _ENTRY(crit_r11)
95         .space  4
96 _ENTRY(crit_srr0)
97         .space  4
98 _ENTRY(crit_srr1)
99         .space  4
100 _ENTRY(saved_ksp_limit)
101         .space  4
102
103 /*
104  * Exception vector entry code. This code runs with address translation
105  * turned off (i.e. using physical addresses). We assume SPRG3 has the
106  * physical address of the current task thread_struct.
107  * Note that we have to have decremented r1 before we write to any fields
108  * of the exception frame, since a critical interrupt could occur at any
109  * time, and it will write to the area immediately below the current r1.
110  */
111 #define NORMAL_EXCEPTION_PROLOG                                              \
112         mtspr   SPRN_SPRG0,r10;         /* save two registers to work with */\
113         mtspr   SPRN_SPRG1,r11;                                              \
114         mtspr   SPRN_SPRG2,r1;                                               \
115         mfcr    r10;                    /* save CR in r10 for now          */\
116         mfspr   r11,SPRN_SRR1;          /* check whether user or kernel    */\
117         andi.   r11,r11,MSR_PR;                                              \
118         beq     1f;                                                          \
119         mfspr   r1,SPRN_SPRG3;          /* if from user, start at top of   */\
120         lwz     r1,THREAD_INFO-THREAD(r1); /* this thread's kernel stack   */\
121         addi    r1,r1,THREAD_SIZE;                                           \
122 1:      subi    r1,r1,INT_FRAME_SIZE;   /* Allocate an exception frame     */\
123         tophys(r11,r1);                                                      \
124         stw     r10,_CCR(r11);          /* save various registers          */\
125         stw     r12,GPR12(r11);                                              \
126         stw     r9,GPR9(r11);                                                \
127         mfspr   r10,SPRN_SPRG0;                                              \
128         stw     r10,GPR10(r11);                                              \
129         mfspr   r12,SPRN_SPRG1;                                              \
130         stw     r12,GPR11(r11);                                              \
131         mflr    r10;                                                         \
132         stw     r10,_LINK(r11);                                              \
133         mfspr   r10,SPRN_SPRG2;                                              \
134         mfspr   r12,SPRN_SRR0;                                               \
135         stw     r10,GPR1(r11);                                               \
136         mfspr   r9,SPRN_SRR1;                                                \
137         stw     r10,0(r11);                                                  \
138         rlwinm  r9,r9,0,14,12;          /* clear MSR_WE (necessary?)       */\
139         stw     r0,GPR0(r11);                                                \
140         SAVE_4GPRS(3, r11);                                                  \
141         SAVE_2GPRS(7, r11)
142
143 /*
144  * Exception prolog for critical exceptions.  This is a little different
145  * from the normal exception prolog above since a critical exception
146  * can potentially occur at any point during normal exception processing.
147  * Thus we cannot use the same SPRG registers as the normal prolog above.
148  * Instead we use a couple of words of memory at low physical addresses.
149  * This is OK since we don't support SMP on these processors.
150  */
151 #define CRITICAL_EXCEPTION_PROLOG                                            \
152         stw     r10,crit_r10@l(0);      /* save two registers to work with */\
153         stw     r11,crit_r11@l(0);                                           \
154         mfcr    r10;                    /* save CR in r10 for now          */\
155         mfspr   r11,SPRN_SRR3;          /* check whether user or kernel    */\
156         andi.   r11,r11,MSR_PR;                                              \
157         lis     r11,critirq_ctx@ha;                                          \
158         tophys(r11,r11);                                                     \
159         lwz     r11,critirq_ctx@l(r11);                                      \
160         beq     1f;                                                          \
161         /* COMING FROM USER MODE */                                          \
162         mfspr   r11,SPRN_SPRG3;         /* if from user, start at top of   */\
163         lwz     r11,THREAD_INFO-THREAD(r11); /* this thread's kernel stack */\
164 1:      addi    r11,r11,THREAD_SIZE-INT_FRAME_SIZE; /* Alloc an excpt frm  */\
165         tophys(r11,r11);                                                     \
166         stw     r10,_CCR(r11);          /* save various registers          */\
167         stw     r12,GPR12(r11);                                              \
168         stw     r9,GPR9(r11);                                                \
169         mflr    r10;                                                         \
170         stw     r10,_LINK(r11);                                              \
171         mfspr   r12,SPRN_DEAR;          /* save DEAR and ESR in the frame  */\
172         stw     r12,_DEAR(r11);         /* since they may have had stuff   */\
173         mfspr   r9,SPRN_ESR;            /* in them at the point where the  */\
174         stw     r9,_ESR(r11);           /* exception was taken             */\
175         mfspr   r12,SPRN_SRR2;                                               \
176         stw     r1,GPR1(r11);                                                \
177         mfspr   r9,SPRN_SRR3;                                                \
178         stw     r1,0(r11);                                                   \
179         tovirt(r1,r11);                                                      \
180         rlwinm  r9,r9,0,14,12;          /* clear MSR_WE (necessary?)       */\
181         stw     r0,GPR0(r11);                                                \
182         SAVE_4GPRS(3, r11);                                                  \
183         SAVE_2GPRS(7, r11)
184
185         /*
186          * State at this point:
187          * r9 saved in stack frame, now saved SRR3 & ~MSR_WE
188          * r10 saved in crit_r10 and in stack frame, trashed
189          * r11 saved in crit_r11 and in stack frame,
190          *      now phys stack/exception frame pointer
191          * r12 saved in stack frame, now saved SRR2
192          * CR saved in stack frame, CR0.EQ = !SRR3.PR
193          * LR, DEAR, ESR in stack frame
194          * r1 saved in stack frame, now virt stack/excframe pointer
195          * r0, r3-r8 saved in stack frame
196          */
197
198 /*
199  * Exception vectors.
200  */
201 #define START_EXCEPTION(n, label)                                            \
202         . = n;                                                               \
203 label:
204
205 #define EXCEPTION(n, label, hdlr, xfer)                         \
206         START_EXCEPTION(n, label);                              \
207         NORMAL_EXCEPTION_PROLOG;                                \
208         addi    r3,r1,STACK_FRAME_OVERHEAD;                     \
209         xfer(n, hdlr)
210
211 #define CRITICAL_EXCEPTION(n, label, hdlr)                      \
212         START_EXCEPTION(n, label);                              \
213         CRITICAL_EXCEPTION_PROLOG;                              \
214         addi    r3,r1,STACK_FRAME_OVERHEAD;                     \
215         EXC_XFER_TEMPLATE(hdlr, n+2, (MSR_KERNEL & ~(MSR_ME|MSR_DE|MSR_CE)), \
216                           NOCOPY, crit_transfer_to_handler,     \
217                           ret_from_crit_exc)
218
219 #define EXC_XFER_TEMPLATE(hdlr, trap, msr, copyee, tfer, ret)   \
220         li      r10,trap;                                       \
221         stw     r10,_TRAP(r11);                                 \
222         lis     r10,msr@h;                                      \
223         ori     r10,r10,msr@l;                                  \
224         copyee(r10, r9);                                        \
225         bl      tfer;                                           \
226         .long   hdlr;                                           \
227         .long   ret
228
229 #define COPY_EE(d, s)           rlwimi d,s,0,16,16
230 #define NOCOPY(d, s)
231
232 #define EXC_XFER_STD(n, hdlr)           \
233         EXC_XFER_TEMPLATE(hdlr, n, MSR_KERNEL, NOCOPY, transfer_to_handler_full, \
234                           ret_from_except_full)
235
236 #define EXC_XFER_LITE(n, hdlr)          \
237         EXC_XFER_TEMPLATE(hdlr, n+1, MSR_KERNEL, NOCOPY, transfer_to_handler, \
238                           ret_from_except)
239
240 #define EXC_XFER_EE(n, hdlr)            \
241         EXC_XFER_TEMPLATE(hdlr, n, MSR_KERNEL, COPY_EE, transfer_to_handler_full, \
242                           ret_from_except_full)
243
244 #define EXC_XFER_EE_LITE(n, hdlr)       \
245         EXC_XFER_TEMPLATE(hdlr, n+1, MSR_KERNEL, COPY_EE, transfer_to_handler, \
246                           ret_from_except)
247
248
249 /*
250  * 0x0100 - Critical Interrupt Exception
251  */
252         CRITICAL_EXCEPTION(0x0100, CriticalInterrupt, unknown_exception)
253
254 /*
255  * 0x0200 - Machine Check Exception
256  */
257         CRITICAL_EXCEPTION(0x0200, MachineCheck, machine_check_exception)
258
259 /*
260  * 0x0300 - Data Storage Exception
261  * This happens for just a few reasons.  U0 set (but we don't do that),
262  * or zone protection fault (user violation, write to protected page).
263  * If this is just an update of modified status, we do that quickly
264  * and exit.  Otherwise, we call heavywight functions to do the work.
265  */
266         START_EXCEPTION(0x0300, DataStorage)
267         mtspr   SPRN_SPRG0, r10         /* Save some working registers */
268         mtspr   SPRN_SPRG1, r11
269 #ifdef CONFIG_403GCX
270         stw     r12, 0(r0)
271         stw     r9, 4(r0)
272         mfcr    r11
273         mfspr   r12, SPRN_PID
274         stw     r11, 8(r0)
275         stw     r12, 12(r0)
276 #else
277         mtspr   SPRN_SPRG4, r12
278         mtspr   SPRN_SPRG5, r9
279         mfcr    r11
280         mfspr   r12, SPRN_PID
281         mtspr   SPRN_SPRG7, r11
282         mtspr   SPRN_SPRG6, r12
283 #endif
284
285         /* First, check if it was a zone fault (which means a user
286         * tried to access a kernel or read-protected page - always
287         * a SEGV).  All other faults here must be stores, so no
288         * need to check ESR_DST as well. */
289         mfspr   r10, SPRN_ESR
290         andis.  r10, r10, ESR_DIZ@h
291         bne     2f
292
293         mfspr   r10, SPRN_DEAR          /* Get faulting address */
294
295         /* If we are faulting a kernel address, we have to use the
296          * kernel page tables.
297          */
298         lis     r11, PAGE_OFFSET@h
299         cmplw   r10, r11
300         blt+    3f
301         lis     r11, swapper_pg_dir@h
302         ori     r11, r11, swapper_pg_dir@l
303         li      r9, 0
304         mtspr   SPRN_PID, r9            /* TLB will have 0 TID */
305         b       4f
306
307         /* Get the PGD for the current thread.
308          */
309 3:
310         mfspr   r11,SPRN_SPRG3
311         lwz     r11,PGDIR(r11)
312 4:
313         tophys(r11, r11)
314         rlwimi  r11, r10, 12, 20, 29    /* Create L1 (pgdir/pmd) address */
315         lwz     r11, 0(r11)             /* Get L1 entry */
316         rlwinm. r12, r11, 0, 0, 19      /* Extract L2 (pte) base address */
317         beq     2f                      /* Bail if no table */
318
319         rlwimi  r12, r10, 22, 20, 29    /* Compute PTE address */
320         lwz     r11, 0(r12)             /* Get Linux PTE */
321
322         andi.   r9, r11, _PAGE_RW       /* Is it writeable? */
323         beq     2f                      /* Bail if not */
324
325         /* Update 'changed'.
326         */
327         ori     r11, r11, _PAGE_DIRTY|_PAGE_ACCESSED|_PAGE_HWWRITE
328         stw     r11, 0(r12)             /* Update Linux page table */
329
330         /* Most of the Linux PTE is ready to load into the TLB LO.
331          * We set ZSEL, where only the LS-bit determines user access.
332          * We set execute, because we don't have the granularity to
333          * properly set this at the page level (Linux problem).
334          * If shared is set, we cause a zero PID->TID load.
335          * Many of these bits are software only.  Bits we don't set
336          * here we (properly should) assume have the appropriate value.
337          */
338         li      r12, 0x0ce2
339         andc    r11, r11, r12           /* Make sure 20, 21 are zero */
340
341         /* find the TLB index that caused the fault.  It has to be here.
342         */
343         tlbsx   r9, 0, r10
344
345         tlbwe   r11, r9, TLB_DATA               /* Load TLB LO */
346
347         /* Done...restore registers and get out of here.
348         */
349 #ifdef CONFIG_403GCX
350         lwz     r12, 12(r0)
351         lwz     r11, 8(r0)
352         mtspr   SPRN_PID, r12
353         mtcr    r11
354         lwz     r9, 4(r0)
355         lwz     r12, 0(r0)
356 #else
357         mfspr   r12, SPRN_SPRG6
358         mfspr   r11, SPRN_SPRG7
359         mtspr   SPRN_PID, r12
360         mtcr    r11
361         mfspr   r9, SPRN_SPRG5
362         mfspr   r12, SPRN_SPRG4
363 #endif
364         mfspr   r11, SPRN_SPRG1
365         mfspr   r10, SPRN_SPRG0
366         PPC405_ERR77_SYNC
367         rfi                     /* Should sync shadow TLBs */
368         b       .               /* prevent prefetch past rfi */
369
370 2:
371         /* The bailout.  Restore registers to pre-exception conditions
372          * and call the heavyweights to help us out.
373          */
374 #ifdef CONFIG_403GCX
375         lwz     r12, 12(r0)
376         lwz     r11, 8(r0)
377         mtspr   SPRN_PID, r12
378         mtcr    r11
379         lwz     r9, 4(r0)
380         lwz     r12, 0(r0)
381 #else
382         mfspr   r12, SPRN_SPRG6
383         mfspr   r11, SPRN_SPRG7
384         mtspr   SPRN_PID, r12
385         mtcr    r11
386         mfspr   r9, SPRN_SPRG5
387         mfspr   r12, SPRN_SPRG4
388 #endif
389         mfspr   r11, SPRN_SPRG1
390         mfspr   r10, SPRN_SPRG0
391         b       DataAccess
392
393 /*
394  * 0x0400 - Instruction Storage Exception
395  * This is caused by a fetch from non-execute or guarded pages.
396  */
397         START_EXCEPTION(0x0400, InstructionAccess)
398         NORMAL_EXCEPTION_PROLOG
399         mr      r4,r12                  /* Pass SRR0 as arg2 */
400         li      r5,0                    /* Pass zero as arg3 */
401         EXC_XFER_EE_LITE(0x400, handle_page_fault)
402
403 /* 0x0500 - External Interrupt Exception */
404         EXCEPTION(0x0500, HardwareInterrupt, do_IRQ, EXC_XFER_LITE)
405
406 /* 0x0600 - Alignment Exception */
407         START_EXCEPTION(0x0600, Alignment)
408         NORMAL_EXCEPTION_PROLOG
409         mfspr   r4,SPRN_DEAR            /* Grab the DEAR and save it */
410         stw     r4,_DEAR(r11)
411         addi    r3,r1,STACK_FRAME_OVERHEAD
412         EXC_XFER_EE(0x600, alignment_exception)
413
414 /* 0x0700 - Program Exception */
415         START_EXCEPTION(0x0700, ProgramCheck)
416         NORMAL_EXCEPTION_PROLOG
417         mfspr   r4,SPRN_ESR             /* Grab the ESR and save it */
418         stw     r4,_ESR(r11)
419         addi    r3,r1,STACK_FRAME_OVERHEAD
420         EXC_XFER_STD(0x700, program_check_exception)
421
422         EXCEPTION(0x0800, Trap_08, unknown_exception, EXC_XFER_EE)
423         EXCEPTION(0x0900, Trap_09, unknown_exception, EXC_XFER_EE)
424         EXCEPTION(0x0A00, Trap_0A, unknown_exception, EXC_XFER_EE)
425         EXCEPTION(0x0B00, Trap_0B, unknown_exception, EXC_XFER_EE)
426
427 /* 0x0C00 - System Call Exception */
428         START_EXCEPTION(0x0C00, SystemCall)
429         NORMAL_EXCEPTION_PROLOG
430         EXC_XFER_EE_LITE(0xc00, DoSyscall)
431
432         EXCEPTION(0x0D00, Trap_0D, unknown_exception, EXC_XFER_EE)
433         EXCEPTION(0x0E00, Trap_0E, unknown_exception, EXC_XFER_EE)
434         EXCEPTION(0x0F00, Trap_0F, unknown_exception, EXC_XFER_EE)
435
436 /* 0x1000 - Programmable Interval Timer (PIT) Exception */
437         START_EXCEPTION(0x1000, Decrementer)
438         NORMAL_EXCEPTION_PROLOG
439         lis     r0,TSR_PIS@h
440         mtspr   SPRN_TSR,r0             /* Clear the PIT exception */
441         addi    r3,r1,STACK_FRAME_OVERHEAD
442         EXC_XFER_LITE(0x1000, timer_interrupt)
443
444 #if 0
445 /* NOTE:
446  * FIT and WDT handlers are not implemented yet.
447  */
448
449 /* 0x1010 - Fixed Interval Timer (FIT) Exception
450 */
451         STND_EXCEPTION(0x1010,  FITException,           unknown_exception)
452
453 /* 0x1020 - Watchdog Timer (WDT) Exception
454 */
455 #ifdef CONFIG_BOOKE_WDT
456         CRITICAL_EXCEPTION(0x1020, WDTException, WatchdogException)
457 #else
458         CRITICAL_EXCEPTION(0x1020, WDTException, unknown_exception)
459 #endif
460 #endif
461
462 /* 0x1100 - Data TLB Miss Exception
463  * As the name implies, translation is not in the MMU, so search the
464  * page tables and fix it.  The only purpose of this function is to
465  * load TLB entries from the page table if they exist.
466  */
467         START_EXCEPTION(0x1100, DTLBMiss)
468         mtspr   SPRN_SPRG0, r10         /* Save some working registers */
469         mtspr   SPRN_SPRG1, r11
470 #ifdef CONFIG_403GCX
471         stw     r12, 0(r0)
472         stw     r9, 4(r0)
473         mfcr    r11
474         mfspr   r12, SPRN_PID
475         stw     r11, 8(r0)
476         stw     r12, 12(r0)
477 #else
478         mtspr   SPRN_SPRG4, r12
479         mtspr   SPRN_SPRG5, r9
480         mfcr    r11
481         mfspr   r12, SPRN_PID
482         mtspr   SPRN_SPRG7, r11
483         mtspr   SPRN_SPRG6, r12
484 #endif
485         mfspr   r10, SPRN_DEAR          /* Get faulting address */
486
487         /* If we are faulting a kernel address, we have to use the
488          * kernel page tables.
489          */
490         lis     r11, PAGE_OFFSET@h
491         cmplw   r10, r11
492         blt+    3f
493         lis     r11, swapper_pg_dir@h
494         ori     r11, r11, swapper_pg_dir@l
495         li      r9, 0
496         mtspr   SPRN_PID, r9            /* TLB will have 0 TID */
497         b       4f
498
499         /* Get the PGD for the current thread.
500          */
501 3:
502         mfspr   r11,SPRN_SPRG3
503         lwz     r11,PGDIR(r11)
504 4:
505         tophys(r11, r11)
506         rlwimi  r11, r10, 12, 20, 29    /* Create L1 (pgdir/pmd) address */
507         lwz     r12, 0(r11)             /* Get L1 entry */
508         andi.   r9, r12, _PMD_PRESENT   /* Check if it points to a PTE page */
509         beq     2f                      /* Bail if no table */
510
511         rlwimi  r12, r10, 22, 20, 29    /* Compute PTE address */
512         lwz     r11, 0(r12)             /* Get Linux PTE */
513         andi.   r9, r11, _PAGE_PRESENT
514         beq     5f
515
516         ori     r11, r11, _PAGE_ACCESSED
517         stw     r11, 0(r12)
518
519         /* Create TLB tag.  This is the faulting address plus a static
520          * set of bits.  These are size, valid, E, U0.
521         */
522         li      r12, 0x00c0
523         rlwimi  r10, r12, 0, 20, 31
524
525         b       finish_tlb_load
526
527 2:      /* Check for possible large-page pmd entry */
528         rlwinm. r9, r12, 2, 22, 24
529         beq     5f
530
531         /* Create TLB tag.  This is the faulting address, plus a static
532          * set of bits (valid, E, U0) plus the size from the PMD.
533          */
534         ori     r9, r9, 0x40
535         rlwimi  r10, r9, 0, 20, 31
536         mr      r11, r12
537
538         b       finish_tlb_load
539
540 5:
541         /* The bailout.  Restore registers to pre-exception conditions
542          * and call the heavyweights to help us out.
543          */
544 #ifdef CONFIG_403GCX
545         lwz     r12, 12(r0)
546         lwz     r11, 8(r0)
547         mtspr   SPRN_PID, r12
548         mtcr    r11
549         lwz     r9, 4(r0)
550         lwz     r12, 0(r0)
551 #else
552         mfspr   r12, SPRN_SPRG6
553         mfspr   r11, SPRN_SPRG7
554         mtspr   SPRN_PID, r12
555         mtcr    r11
556         mfspr   r9, SPRN_SPRG5
557         mfspr   r12, SPRN_SPRG4
558 #endif
559         mfspr   r11, SPRN_SPRG1
560         mfspr   r10, SPRN_SPRG0
561         b       DataAccess
562
563 /* 0x1200 - Instruction TLB Miss Exception
564  * Nearly the same as above, except we get our information from different
565  * registers and bailout to a different point.
566  */
567         START_EXCEPTION(0x1200, ITLBMiss)
568         mtspr   SPRN_SPRG0, r10         /* Save some working registers */
569         mtspr   SPRN_SPRG1, r11
570 #ifdef CONFIG_403GCX
571         stw     r12, 0(r0)
572         stw     r9, 4(r0)
573         mfcr    r11
574         mfspr   r12, SPRN_PID
575         stw     r11, 8(r0)
576         stw     r12, 12(r0)
577 #else
578         mtspr   SPRN_SPRG4, r12
579         mtspr   SPRN_SPRG5, r9
580         mfcr    r11
581         mfspr   r12, SPRN_PID
582         mtspr   SPRN_SPRG7, r11
583         mtspr   SPRN_SPRG6, r12
584 #endif
585         mfspr   r10, SPRN_SRR0          /* Get faulting address */
586
587         /* If we are faulting a kernel address, we have to use the
588          * kernel page tables.
589          */
590         lis     r11, PAGE_OFFSET@h
591         cmplw   r10, r11
592         blt+    3f
593         lis     r11, swapper_pg_dir@h
594         ori     r11, r11, swapper_pg_dir@l
595         li      r9, 0
596         mtspr   SPRN_PID, r9            /* TLB will have 0 TID */
597         b       4f
598
599         /* Get the PGD for the current thread.
600          */
601 3:
602         mfspr   r11,SPRN_SPRG3
603         lwz     r11,PGDIR(r11)
604 4:
605         tophys(r11, r11)
606         rlwimi  r11, r10, 12, 20, 29    /* Create L1 (pgdir/pmd) address */
607         lwz     r12, 0(r11)             /* Get L1 entry */
608         andi.   r9, r12, _PMD_PRESENT   /* Check if it points to a PTE page */
609         beq     2f                      /* Bail if no table */
610
611         rlwimi  r12, r10, 22, 20, 29    /* Compute PTE address */
612         lwz     r11, 0(r12)             /* Get Linux PTE */
613         andi.   r9, r11, _PAGE_PRESENT
614         beq     5f
615
616         ori     r11, r11, _PAGE_ACCESSED
617         stw     r11, 0(r12)
618
619         /* Create TLB tag.  This is the faulting address plus a static
620          * set of bits.  These are size, valid, E, U0.
621         */
622         li      r12, 0x00c0
623         rlwimi  r10, r12, 0, 20, 31
624
625         b       finish_tlb_load
626
627 2:      /* Check for possible large-page pmd entry */
628         rlwinm. r9, r12, 2, 22, 24
629         beq     5f
630
631         /* Create TLB tag.  This is the faulting address, plus a static
632          * set of bits (valid, E, U0) plus the size from the PMD.
633          */
634         ori     r9, r9, 0x40
635         rlwimi  r10, r9, 0, 20, 31
636         mr      r11, r12
637
638         b       finish_tlb_load
639
640 5:
641         /* The bailout.  Restore registers to pre-exception conditions
642          * and call the heavyweights to help us out.
643          */
644 #ifdef CONFIG_403GCX
645         lwz     r12, 12(r0)
646         lwz     r11, 8(r0)
647         mtspr   SPRN_PID, r12
648         mtcr    r11
649         lwz     r9, 4(r0)
650         lwz     r12, 0(r0)
651 #else
652         mfspr   r12, SPRN_SPRG6
653         mfspr   r11, SPRN_SPRG7
654         mtspr   SPRN_PID, r12
655         mtcr    r11
656         mfspr   r9, SPRN_SPRG5
657         mfspr   r12, SPRN_SPRG4
658 #endif
659         mfspr   r11, SPRN_SPRG1
660         mfspr   r10, SPRN_SPRG0
661         b       InstructionAccess
662
663         EXCEPTION(0x1300, Trap_13, unknown_exception, EXC_XFER_EE)
664         EXCEPTION(0x1400, Trap_14, unknown_exception, EXC_XFER_EE)
665         EXCEPTION(0x1500, Trap_15, unknown_exception, EXC_XFER_EE)
666         EXCEPTION(0x1600, Trap_16, unknown_exception, EXC_XFER_EE)
667 #ifdef CONFIG_IBM405_ERR51
668         /* 405GP errata 51 */
669         START_EXCEPTION(0x1700, Trap_17)
670         b DTLBMiss
671 #else
672         EXCEPTION(0x1700, Trap_17, unknown_exception, EXC_XFER_EE)
673 #endif
674         EXCEPTION(0x1800, Trap_18, unknown_exception, EXC_XFER_EE)
675         EXCEPTION(0x1900, Trap_19, unknown_exception, EXC_XFER_EE)
676         EXCEPTION(0x1A00, Trap_1A, unknown_exception, EXC_XFER_EE)
677         EXCEPTION(0x1B00, Trap_1B, unknown_exception, EXC_XFER_EE)
678         EXCEPTION(0x1C00, Trap_1C, unknown_exception, EXC_XFER_EE)
679         EXCEPTION(0x1D00, Trap_1D, unknown_exception, EXC_XFER_EE)
680         EXCEPTION(0x1E00, Trap_1E, unknown_exception, EXC_XFER_EE)
681         EXCEPTION(0x1F00, Trap_1F, unknown_exception, EXC_XFER_EE)
682
683 /* Check for a single step debug exception while in an exception
684  * handler before state has been saved.  This is to catch the case
685  * where an instruction that we are trying to single step causes
686  * an exception (eg ITLB/DTLB miss) and thus the first instruction of
687  * the exception handler generates a single step debug exception.
688  *
689  * If we get a debug trap on the first instruction of an exception handler,
690  * we reset the MSR_DE in the _exception handler's_ MSR (the debug trap is
691  * a critical exception, so we are using SPRN_CSRR1 to manipulate the MSR).
692  * The exception handler was handling a non-critical interrupt, so it will
693  * save (and later restore) the MSR via SPRN_SRR1, which will still have
694  * the MSR_DE bit set.
695  */
696         /* 0x2000 - Debug Exception */
697         START_EXCEPTION(0x2000, DebugTrap)
698         CRITICAL_EXCEPTION_PROLOG
699
700         /*
701          * If this is a single step or branch-taken exception in an
702          * exception entry sequence, it was probably meant to apply to
703          * the code where the exception occurred (since exception entry
704          * doesn't turn off DE automatically).  We simulate the effect
705          * of turning off DE on entry to an exception handler by turning
706          * off DE in the SRR3 value and clearing the debug status.
707          */
708         mfspr   r10,SPRN_DBSR           /* check single-step/branch taken */
709         andis.  r10,r10,DBSR_IC@h
710         beq+    2f
711
712         andi.   r10,r9,MSR_IR|MSR_PR    /* check supervisor + MMU off */
713         beq     1f                      /* branch and fix it up */
714
715         mfspr   r10,SPRN_SRR2           /* Faulting instruction address */
716         cmplwi  r10,0x2100
717         bgt+    2f                      /* address above exception vectors */
718
719         /* here it looks like we got an inappropriate debug exception. */
720 1:      rlwinm  r9,r9,0,~MSR_DE         /* clear DE in the SRR3 value */
721         lis     r10,DBSR_IC@h           /* clear the IC event */
722         mtspr   SPRN_DBSR,r10
723         /* restore state and get out */
724         lwz     r10,_CCR(r11)
725         lwz     r0,GPR0(r11)
726         lwz     r1,GPR1(r11)
727         mtcrf   0x80,r10
728         mtspr   SPRN_SRR2,r12
729         mtspr   SPRN_SRR3,r9
730         lwz     r9,GPR9(r11)
731         lwz     r12,GPR12(r11)
732         lwz     r10,crit_r10@l(0)
733         lwz     r11,crit_r11@l(0)
734         PPC405_ERR77_SYNC
735         rfci
736         b       .
737
738         /* continue normal handling for a critical exception... */
739 2:      mfspr   r4,SPRN_DBSR
740         addi    r3,r1,STACK_FRAME_OVERHEAD
741         EXC_XFER_TEMPLATE(DebugException, 0x2002, \
742                 (MSR_KERNEL & ~(MSR_ME|MSR_DE|MSR_CE)), \
743                 NOCOPY, crit_transfer_to_handler, ret_from_crit_exc)
744
745 /*
746  * The other Data TLB exceptions bail out to this point
747  * if they can't resolve the lightweight TLB fault.
748  */
749 DataAccess:
750         NORMAL_EXCEPTION_PROLOG
751         mfspr   r5,SPRN_ESR             /* Grab the ESR, save it, pass arg3 */
752         stw     r5,_ESR(r11)
753         mfspr   r4,SPRN_DEAR            /* Grab the DEAR, save it, pass arg2 */
754         EXC_XFER_EE_LITE(0x300, handle_page_fault)
755
756 /* Other PowerPC processors, namely those derived from the 6xx-series
757  * have vectors from 0x2100 through 0x2F00 defined, but marked as reserved.
758  * However, for the 4xx-series processors these are neither defined nor
759  * reserved.
760  */
761
762         /* Damn, I came up one instruction too many to fit into the
763          * exception space :-).  Both the instruction and data TLB
764          * miss get to this point to load the TLB.
765          *      r10 - TLB_TAG value
766          *      r11 - Linux PTE
767          *      r12, r9 - avilable to use
768          *      PID - loaded with proper value when we get here
769          *      Upon exit, we reload everything and RFI.
770          * Actually, it will fit now, but oh well.....a common place
771          * to load the TLB.
772          */
773 tlb_4xx_index:
774         .long   0
775 finish_tlb_load:
776         /* load the next available TLB index.
777         */
778         lwz     r9, tlb_4xx_index@l(0)
779         addi    r9, r9, 1
780         andi.   r9, r9, (PPC40X_TLB_SIZE-1)
781         stw     r9, tlb_4xx_index@l(0)
782
783 6:
784         /*
785          * Clear out the software-only bits in the PTE to generate the
786          * TLB_DATA value.  These are the bottom 2 bits of the RPM, the
787          * top 3 bits of the zone field, and M.
788          */
789         li      r12, 0x0ce2
790         andc    r11, r11, r12
791
792         tlbwe   r11, r9, TLB_DATA               /* Load TLB LO */
793         tlbwe   r10, r9, TLB_TAG                /* Load TLB HI */
794
795         /* Done...restore registers and get out of here.
796         */
797 #ifdef CONFIG_403GCX
798         lwz     r12, 12(r0)
799         lwz     r11, 8(r0)
800         mtspr   SPRN_PID, r12
801         mtcr    r11
802         lwz     r9, 4(r0)
803         lwz     r12, 0(r0)
804 #else
805         mfspr   r12, SPRN_SPRG6
806         mfspr   r11, SPRN_SPRG7
807         mtspr   SPRN_PID, r12
808         mtcr    r11
809         mfspr   r9, SPRN_SPRG5
810         mfspr   r12, SPRN_SPRG4
811 #endif
812         mfspr   r11, SPRN_SPRG1
813         mfspr   r10, SPRN_SPRG0
814         PPC405_ERR77_SYNC
815         rfi                     /* Should sync shadow TLBs */
816         b       .               /* prevent prefetch past rfi */
817
818 /* extern void giveup_fpu(struct task_struct *prev)
819  *
820  * The PowerPC 4xx family of processors do not have an FPU, so this just
821  * returns.
822  */
823 _ENTRY(giveup_fpu)
824         blr
825
826 /* This is where the main kernel code starts.
827  */
828 start_here:
829
830         /* ptr to current */
831         lis     r2,init_task@h
832         ori     r2,r2,init_task@l
833
834         /* ptr to phys current thread */
835         tophys(r4,r2)
836         addi    r4,r4,THREAD    /* init task's THREAD */
837         mtspr   SPRN_SPRG3,r4
838
839         /* stack */
840         lis     r1,init_thread_union@ha
841         addi    r1,r1,init_thread_union@l
842         li      r0,0
843         stwu    r0,THREAD_SIZE-STACK_FRAME_OVERHEAD(r1)
844
845         bl      early_init      /* We have to do this with MMU on */
846
847 /*
848  * Decide what sort of machine this is and initialize the MMU.
849  */
850         mr      r3,r31
851         mr      r4,r30
852         mr      r5,r29
853         mr      r6,r28
854         mr      r7,r27
855         bl      machine_init
856         bl      MMU_init
857
858 /* Go back to running unmapped so we can load up new values
859  * and change to using our exception vectors.
860  * On the 4xx, all we have to do is invalidate the TLB to clear
861  * the old 16M byte TLB mappings.
862  */
863         lis     r4,2f@h
864         ori     r4,r4,2f@l
865         tophys(r4,r4)
866         lis     r3,(MSR_KERNEL & ~(MSR_IR|MSR_DR))@h
867         ori     r3,r3,(MSR_KERNEL & ~(MSR_IR|MSR_DR))@l
868         mtspr   SPRN_SRR0,r4
869         mtspr   SPRN_SRR1,r3
870         rfi
871         b       .               /* prevent prefetch past rfi */
872
873 /* Load up the kernel context */
874 2:
875         sync                    /* Flush to memory before changing TLB */
876         tlbia
877         isync                   /* Flush shadow TLBs */
878
879         /* set up the PTE pointers for the Abatron bdiGDB.
880         */
881         lis     r6, swapper_pg_dir@h
882         ori     r6, r6, swapper_pg_dir@l
883         lis     r5, abatron_pteptrs@h
884         ori     r5, r5, abatron_pteptrs@l
885         stw     r5, 0xf0(r0)    /* Must match your Abatron config file */
886         tophys(r5,r5)
887         stw     r6, 0(r5)
888
889 /* Now turn on the MMU for real! */
890         lis     r4,MSR_KERNEL@h
891         ori     r4,r4,MSR_KERNEL@l
892         lis     r3,start_kernel@h
893         ori     r3,r3,start_kernel@l
894         mtspr   SPRN_SRR0,r3
895         mtspr   SPRN_SRR1,r4
896         rfi                     /* enable MMU and jump to start_kernel */
897         b       .               /* prevent prefetch past rfi */
898
899 /* Set up the initial MMU state so we can do the first level of
900  * kernel initialization.  This maps the first 16 MBytes of memory 1:1
901  * virtual to physical and more importantly sets the cache mode.
902  */
903 initial_mmu:
904         tlbia                   /* Invalidate all TLB entries */
905         isync
906
907         /* We should still be executing code at physical address 0x0000xxxx
908          * at this point. However, start_here is at virtual address
909          * 0xC000xxxx. So, set up a TLB mapping to cover this once
910          * translation is enabled.
911          */
912
913         lis     r3,KERNELBASE@h         /* Load the kernel virtual address */
914         ori     r3,r3,KERNELBASE@l
915         tophys(r4,r3)                   /* Load the kernel physical address */
916
917         iccci   r0,r3                   /* Invalidate the i-cache before use */
918
919         /* Load the kernel PID.
920         */
921         li      r0,0
922         mtspr   SPRN_PID,r0
923         sync
924
925         /* Configure and load two entries into TLB slots 62 and 63.
926          * In case we are pinning TLBs, these are reserved in by the
927          * other TLB functions.  If not reserving, then it doesn't
928          * matter where they are loaded.
929          */
930         clrrwi  r4,r4,10                /* Mask off the real page number */
931         ori     r4,r4,(TLB_WR | TLB_EX) /* Set the write and execute bits */
932
933         clrrwi  r3,r3,10                /* Mask off the effective page number */
934         ori     r3,r3,(TLB_VALID | TLB_PAGESZ(PAGESZ_16M))
935
936         li      r0,63                    /* TLB slot 63 */
937
938         tlbwe   r4,r0,TLB_DATA          /* Load the data portion of the entry */
939         tlbwe   r3,r0,TLB_TAG           /* Load the tag portion of the entry */
940
941 #if defined(CONFIG_SERIAL_TEXT_DEBUG) && defined(SERIAL_DEBUG_IO_BASE)
942
943         /* Load a TLB entry for the UART, so that ppc4xx_progress() can use
944          * the UARTs nice and early.  We use a 4k real==virtual mapping. */
945
946         lis     r3,SERIAL_DEBUG_IO_BASE@h
947         ori     r3,r3,SERIAL_DEBUG_IO_BASE@l
948         mr      r4,r3
949         clrrwi  r4,r4,12
950         ori     r4,r4,(TLB_WR|TLB_I|TLB_M|TLB_G)
951
952         clrrwi  r3,r3,12
953         ori     r3,r3,(TLB_VALID | TLB_PAGESZ(PAGESZ_4K))
954
955         li      r0,0                    /* TLB slot 0 */
956         tlbwe   r4,r0,TLB_DATA
957         tlbwe   r3,r0,TLB_TAG
958 #endif /* CONFIG_SERIAL_DEBUG_TEXT && SERIAL_DEBUG_IO_BASE */
959
960         isync
961
962         /* Establish the exception vector base
963         */
964         lis     r4,KERNELBASE@h         /* EVPR only uses the high 16-bits */
965         tophys(r0,r4)                   /* Use the physical address */
966         mtspr   SPRN_EVPR,r0
967
968         blr
969
970 _GLOBAL(abort)
971         mfspr   r13,SPRN_DBCR0
972         oris    r13,r13,DBCR0_RST_SYSTEM@h
973         mtspr   SPRN_DBCR0,r13
974
975 _GLOBAL(set_context)
976
977 #ifdef CONFIG_BDI_SWITCH
978         /* Context switch the PTE pointer for the Abatron BDI2000.
979          * The PGDIR is the second parameter.
980          */
981         lis     r5, KERNELBASE@h
982         lwz     r5, 0xf0(r5)
983         stw     r4, 0x4(r5)
984 #endif
985         sync
986         mtspr   SPRN_PID,r3
987         isync                           /* Need an isync to flush shadow */
988                                         /* TLBs after changing PID */
989         blr
990
991 /* We put a few things here that have to be page-aligned. This stuff
992  * goes at the beginning of the data segment, which is page-aligned.
993  */
994         .data
995         .align  12
996         .globl  sdata
997 sdata:
998         .globl  empty_zero_page
999 empty_zero_page:
1000         .space  4096
1001         .globl  swapper_pg_dir
1002 swapper_pg_dir:
1003         .space  PGD_TABLE_SIZE
1004
1005 /* Room for two PTE pointers, usually the kernel and current user pointers
1006  * to their respective root page table.
1007  */
1008 abatron_pteptrs:
1009         .space  8