Merge tag 'locks-v3.16-2' of git://git.samba.org/jlayton/linux
[linux/fpc-iii.git] / arch / powerpc / kernel / head_8xx.S
blob7ee876d2adb57c6cc1e78d1d3204ab240238c02d
1 /*
2  *  PowerPC version
3  *    Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
4  *  Rewritten by Cort Dougan (cort@cs.nmt.edu) for PReP
5  *    Copyright (C) 1996 Cort Dougan <cort@cs.nmt.edu>
6  *  Low-level exception handlers and MMU support
7  *  rewritten by Paul Mackerras.
8  *    Copyright (C) 1996 Paul Mackerras.
9  *  MPC8xx modifications by Dan Malek
10  *    Copyright (C) 1997 Dan Malek (dmalek@jlc.net).
11  *
12  *  This file contains low-level support and setup for PowerPC 8xx
13  *  embedded processors, including trap and interrupt dispatch.
14  *
15  *  This program is free software; you can redistribute it and/or
16  *  modify it under the terms of the GNU General Public License
17  *  as published by the Free Software Foundation; either version
18  *  2 of the License, or (at your option) any later version.
19  *
20  */
22 #include <linux/init.h>
23 #include <asm/processor.h>
24 #include <asm/page.h>
25 #include <asm/mmu.h>
26 #include <asm/cache.h>
27 #include <asm/pgtable.h>
28 #include <asm/cputable.h>
29 #include <asm/thread_info.h>
30 #include <asm/ppc_asm.h>
31 #include <asm/asm-offsets.h>
32 #include <asm/ptrace.h>
34 /* Macro to make the code more readable. */
35 #ifdef CONFIG_8xx_CPU6
36 #define DO_8xx_CPU6(val, reg)   \
37         li      reg, val;       \
38         stw     reg, 12(r0);    \
39         lwz     reg, 12(r0);
40 #else
41 #define DO_8xx_CPU6(val, reg)
42 #endif
43         __HEAD
44 _ENTRY(_stext);
45 _ENTRY(_start);
47 /* MPC8xx
48  * This port was done on an MBX board with an 860.  Right now I only
49  * support an ELF compressed (zImage) boot from EPPC-Bug because the
50  * code there loads up some registers before calling us:
51  *   r3: ptr to board info data
52  *   r4: initrd_start or if no initrd then 0
53  *   r5: initrd_end - unused if r4 is 0
54  *   r6: Start of command line string
55  *   r7: End of command line string
56  *
57  * I decided to use conditional compilation instead of checking PVR and
58  * adding more processor specific branches around code I don't need.
59  * Since this is an embedded processor, I also appreciate any memory
60  * savings I can get.
61  *
62  * The MPC8xx does not have any BATs, but it supports large page sizes.
63  * We first initialize the MMU to support 8M byte pages, then load one
64  * entry into each of the instruction and data TLBs to map the first
65  * 8M 1:1.  I also mapped an additional I/O space 1:1 so we can get to
66  * the "internal" processor registers before MMU_init is called.
67  *
68  * The TLB code currently contains a major hack.  Since I use the condition
69  * code register, I have to save and restore it.  I am out of registers, so
70  * I just store it in memory location 0 (the TLB handlers are not reentrant).
71  * To avoid making any decisions, I need to use the "segment" valid bit
72  * in the first level table, but that would require many changes to the
73  * Linux page directory/table functions that I don't want to do right now.
74  *
75  *      -- Dan
76  */
77         .globl  __start
78 __start:
79         mr      r31,r3                  /* save device tree ptr */
81         /* We have to turn on the MMU right away so we get cache modes
82          * set correctly.
83          */
84         bl      initial_mmu
86 /* We now have the lower 8 Meg mapped into TLB entries, and the caches
87  * ready to work.
88  */
90 turn_on_mmu:
91         mfmsr   r0
92         ori     r0,r0,MSR_DR|MSR_IR
93         mtspr   SPRN_SRR1,r0
94         lis     r0,start_here@h
95         ori     r0,r0,start_here@l
96         mtspr   SPRN_SRR0,r0
97         SYNC
98         rfi                             /* enables MMU */
101  * Exception entry code.  This code runs with address translation
102  * turned off, i.e. using physical addresses.
103  * We assume sprg3 has the physical address of the current
104  * task's thread_struct.
105  */
106 #define EXCEPTION_PROLOG        \
107         mtspr   SPRN_SPRG_SCRATCH0,r10; \
108         mtspr   SPRN_SPRG_SCRATCH1,r11; \
109         mfcr    r10;            \
110         EXCEPTION_PROLOG_1;     \
111         EXCEPTION_PROLOG_2
113 #define EXCEPTION_PROLOG_1      \
114         mfspr   r11,SPRN_SRR1;          /* check whether user or kernel */ \
115         andi.   r11,r11,MSR_PR; \
116         tophys(r11,r1);                 /* use tophys(r1) if kernel */ \
117         beq     1f;             \
118         mfspr   r11,SPRN_SPRG_THREAD;   \
119         lwz     r11,THREAD_INFO-THREAD(r11);    \
120         addi    r11,r11,THREAD_SIZE;    \
121         tophys(r11,r11);        \
122 1:      subi    r11,r11,INT_FRAME_SIZE  /* alloc exc. frame */
125 #define EXCEPTION_PROLOG_2      \
126         CLR_TOP32(r11);         \
127         stw     r10,_CCR(r11);          /* save registers */ \
128         stw     r12,GPR12(r11); \
129         stw     r9,GPR9(r11);   \
130         mfspr   r10,SPRN_SPRG_SCRATCH0; \
131         stw     r10,GPR10(r11); \
132         mfspr   r12,SPRN_SPRG_SCRATCH1; \
133         stw     r12,GPR11(r11); \
134         mflr    r10;            \
135         stw     r10,_LINK(r11); \
136         mfspr   r12,SPRN_SRR0;  \
137         mfspr   r9,SPRN_SRR1;   \
138         stw     r1,GPR1(r11);   \
139         stw     r1,0(r11);      \
140         tovirt(r1,r11);                 /* set new kernel sp */ \
141         li      r10,MSR_KERNEL & ~(MSR_IR|MSR_DR); /* can take exceptions */ \
142         MTMSRD(r10);                    /* (except for mach check in rtas) */ \
143         stw     r0,GPR0(r11);   \
144         SAVE_4GPRS(3, r11);     \
145         SAVE_2GPRS(7, r11)
148  * Note: code which follows this uses cr0.eq (set if from kernel),
149  * r11, r12 (SRR0), and r9 (SRR1).
151  * Note2: once we have set r1 we are in a position to take exceptions
152  * again, and we could thus set MSR:RI at that point.
153  */
156  * Exception vectors.
157  */
158 #define EXCEPTION(n, label, hdlr, xfer)         \
159         . = n;                                  \
160 label:                                          \
161         EXCEPTION_PROLOG;                       \
162         addi    r3,r1,STACK_FRAME_OVERHEAD;     \
163         xfer(n, hdlr)
165 #define EXC_XFER_TEMPLATE(n, hdlr, trap, copyee, tfer, ret)     \
166         li      r10,trap;                                       \
167         stw     r10,_TRAP(r11);                                 \
168         li      r10,MSR_KERNEL;                                 \
169         copyee(r10, r9);                                        \
170         bl      tfer;                                           \
171 i##n:                                                           \
172         .long   hdlr;                                           \
173         .long   ret
175 #define COPY_EE(d, s)           rlwimi d,s,0,16,16
176 #define NOCOPY(d, s)
178 #define EXC_XFER_STD(n, hdlr)           \
179         EXC_XFER_TEMPLATE(n, hdlr, n, NOCOPY, transfer_to_handler_full, \
180                           ret_from_except_full)
182 #define EXC_XFER_LITE(n, hdlr)          \
183         EXC_XFER_TEMPLATE(n, hdlr, n+1, NOCOPY, transfer_to_handler, \
184                           ret_from_except)
186 #define EXC_XFER_EE(n, hdlr)            \
187         EXC_XFER_TEMPLATE(n, hdlr, n, COPY_EE, transfer_to_handler_full, \
188                           ret_from_except_full)
190 #define EXC_XFER_EE_LITE(n, hdlr)       \
191         EXC_XFER_TEMPLATE(n, hdlr, n+1, COPY_EE, transfer_to_handler, \
192                           ret_from_except)
194 /* System reset */
195         EXCEPTION(0x100, Reset, unknown_exception, EXC_XFER_STD)
197 /* Machine check */
198         . = 0x200
199 MachineCheck:
200         EXCEPTION_PROLOG
201         mfspr r4,SPRN_DAR
202         stw r4,_DAR(r11)
203         li r5,0x00f0
204         mtspr SPRN_DAR,r5       /* Tag DAR, to be used in DTLB Error */
205         mfspr r5,SPRN_DSISR
206         stw r5,_DSISR(r11)
207         addi r3,r1,STACK_FRAME_OVERHEAD
208         EXC_XFER_STD(0x200, machine_check_exception)
210 /* Data access exception.
211  * This is "never generated" by the MPC8xx.  We jump to it for other
212  * translation errors.
213  */
214         . = 0x300
215 DataAccess:
216         EXCEPTION_PROLOG
217         mfspr   r10,SPRN_DSISR
218         stw     r10,_DSISR(r11)
219         mr      r5,r10
220         mfspr   r4,SPRN_DAR
221         li      r10,0x00f0
222         mtspr   SPRN_DAR,r10    /* Tag DAR, to be used in DTLB Error */
223         EXC_XFER_LITE(0x300, handle_page_fault)
225 /* Instruction access exception.
226  * This is "never generated" by the MPC8xx.  We jump to it for other
227  * translation errors.
228  */
229         . = 0x400
230 InstructionAccess:
231         EXCEPTION_PROLOG
232         mr      r4,r12
233         mr      r5,r9
234         EXC_XFER_LITE(0x400, handle_page_fault)
236 /* External interrupt */
237         EXCEPTION(0x500, HardwareInterrupt, do_IRQ, EXC_XFER_LITE)
239 /* Alignment exception */
240         . = 0x600
241 Alignment:
242         EXCEPTION_PROLOG
243         mfspr   r4,SPRN_DAR
244         stw     r4,_DAR(r11)
245         li      r5,0x00f0
246         mtspr   SPRN_DAR,r5     /* Tag DAR, to be used in DTLB Error */
247         mfspr   r5,SPRN_DSISR
248         stw     r5,_DSISR(r11)
249         addi    r3,r1,STACK_FRAME_OVERHEAD
250         EXC_XFER_EE(0x600, alignment_exception)
252 /* Program check exception */
253         EXCEPTION(0x700, ProgramCheck, program_check_exception, EXC_XFER_STD)
255 /* No FPU on MPC8xx.  This exception is not supposed to happen.
257         EXCEPTION(0x800, FPUnavailable, unknown_exception, EXC_XFER_STD)
259 /* Decrementer */
260         EXCEPTION(0x900, Decrementer, timer_interrupt, EXC_XFER_LITE)
262         EXCEPTION(0xa00, Trap_0a, unknown_exception, EXC_XFER_EE)
263         EXCEPTION(0xb00, Trap_0b, unknown_exception, EXC_XFER_EE)
265 /* System call */
266         . = 0xc00
267 SystemCall:
268         EXCEPTION_PROLOG
269         EXC_XFER_EE_LITE(0xc00, DoSyscall)
271 /* Single step - not used on 601 */
272         EXCEPTION(0xd00, SingleStep, single_step_exception, EXC_XFER_STD)
273         EXCEPTION(0xe00, Trap_0e, unknown_exception, EXC_XFER_EE)
274         EXCEPTION(0xf00, Trap_0f, unknown_exception, EXC_XFER_EE)
276 /* On the MPC8xx, this is a software emulation interrupt.  It occurs
277  * for all unimplemented and illegal instructions.
278  */
279         EXCEPTION(0x1000, SoftEmu, SoftwareEmulation, EXC_XFER_STD)
281         . = 0x1100
283  * For the MPC8xx, this is a software tablewalk to load the instruction
284  * TLB.  It is modelled after the example in the Motorola manual.  The task
285  * switch loads the M_TWB register with the pointer to the first level table.
286  * If we discover there is no second level table (value is zero) or if there
287  * is an invalid pte, we load that into the TLB, which causes another fault
288  * into the TLB Error interrupt where we can handle such problems.
289  * We have to use the MD_xxx registers for the tablewalk because the
290  * equivalent MI_xxx registers only perform the attribute functions.
291  */
292 InstructionTLBMiss:
293 #ifdef CONFIG_8xx_CPU6
294         stw     r3, 8(r0)
295 #endif
296         DO_8xx_CPU6(0x3f80, r3)
297         mtspr   SPRN_M_TW, r10  /* Save a couple of working registers */
298         mfcr    r10
299 #ifdef CONFIG_8xx_CPU6
300         stw     r10, 0(r0)
301         stw     r11, 4(r0)
302 #else
303         mtspr   SPRN_DAR, r10
304         mtspr   SPRN_SPRG2, r11
305 #endif
306         mfspr   r10, SPRN_SRR0  /* Get effective address of fault */
307 #ifdef CONFIG_8xx_CPU15
308         addi    r11, r10, 0x1000
309         tlbie   r11
310         addi    r11, r10, -0x1000
311         tlbie   r11
312 #endif
313         DO_8xx_CPU6(0x3780, r3)
314         mtspr   SPRN_MD_EPN, r10        /* Have to use MD_EPN for walk, MI_EPN can't */
315         mfspr   r10, SPRN_M_TWB /* Get level 1 table entry address */
317         /* If we are faulting a kernel address, we have to use the
318          * kernel page tables.
319          */
320 #ifdef CONFIG_MODULES
321         /* Only modules will cause ITLB Misses as we always
322          * pin the first 8MB of kernel memory */
323         andi.   r11, r10, 0x0800        /* Address >= 0x80000000 */
324         beq     3f
325         lis     r11, swapper_pg_dir@h
326         ori     r11, r11, swapper_pg_dir@l
327         rlwimi  r10, r11, 0, 2, 19
329 #endif
330         lwz     r11, 0(r10)     /* Get the level 1 entry */
331         rlwinm. r10, r11,0,0,19 /* Extract page descriptor page address */
332         beq     2f              /* If zero, don't try to find a pte */
334         /* We have a pte table, so load the MI_TWC with the attributes
335          * for this "segment."
336          */
337         ori     r11,r11,1               /* Set valid bit */
338         DO_8xx_CPU6(0x2b80, r3)
339         mtspr   SPRN_MI_TWC, r11        /* Set segment attributes */
340         DO_8xx_CPU6(0x3b80, r3)
341         mtspr   SPRN_MD_TWC, r11        /* Load pte table base address */
342         mfspr   r11, SPRN_MD_TWC        /* ....and get the pte address */
343         lwz     r10, 0(r11)     /* Get the pte */
345 #ifdef CONFIG_SWAP
346         andi.   r11, r10, _PAGE_ACCESSED | _PAGE_PRESENT
347         cmpwi   cr0, r11, _PAGE_ACCESSED | _PAGE_PRESENT
348         bne-    cr0, 2f
349 #endif
350         /* The Linux PTE won't go exactly into the MMU TLB.
351          * Software indicator bits 21 and 28 must be clear.
352          * Software indicator bits 24, 25, 26, and 27 must be
353          * set.  All other Linux PTE bits control the behavior
354          * of the MMU.
355          */
356         li      r11, 0x00f0
357         rlwimi  r10, r11, 0, 0x07f8     /* Set 24-27, clear 21-23,28 */
358         DO_8xx_CPU6(0x2d80, r3)
359         mtspr   SPRN_MI_RPN, r10        /* Update TLB entry */
361         /* Restore registers */
362 #ifndef CONFIG_8xx_CPU6
363         mfspr   r10, SPRN_DAR
364         mtcr    r10
365         mtspr   SPRN_DAR, r11   /* Tag DAR */
366         mfspr   r11, SPRN_SPRG2
367 #else
368         lwz     r11, 0(r0)
369         mtcr    r11
370         lwz     r11, 4(r0)
371         lwz     r3, 8(r0)
372 #endif
373         mfspr   r10, SPRN_M_TW
374         rfi
376         mfspr   r11, SPRN_SRR1
377         /* clear all error bits as TLB Miss
378          * sets a few unconditionally
379         */
380         rlwinm  r11, r11, 0, 0xffff
381         mtspr   SPRN_SRR1, r11
383         /* Restore registers */
384 #ifndef CONFIG_8xx_CPU6
385         mfspr   r10, SPRN_DAR
386         mtcr    r10
387         li      r11, 0x00f0
388         mtspr   SPRN_DAR, r11   /* Tag DAR */
389         mfspr   r11, SPRN_SPRG2
390 #else
391         lwz     r11, 0(r0)
392         mtcr    r11
393         lwz     r11, 4(r0)
394         lwz     r3, 8(r0)
395 #endif
396         mfspr   r10, SPRN_M_TW
397         b       InstructionAccess
399         . = 0x1200
400 DataStoreTLBMiss:
401 #ifdef CONFIG_8xx_CPU6
402         stw     r3, 8(r0)
403 #endif
404         DO_8xx_CPU6(0x3f80, r3)
405         mtspr   SPRN_M_TW, r10  /* Save a couple of working registers */
406         mfcr    r10
407 #ifdef CONFIG_8xx_CPU6
408         stw     r10, 0(r0)
409         stw     r11, 4(r0)
410 #else
411         mtspr   SPRN_DAR, r10
412         mtspr   SPRN_SPRG2, r11
413 #endif
414         mfspr   r10, SPRN_M_TWB /* Get level 1 table entry address */
416         /* If we are faulting a kernel address, we have to use the
417          * kernel page tables.
418          */
419         andi.   r11, r10, 0x0800
420         beq     3f
421         lis     r11, swapper_pg_dir@h
422         ori     r11, r11, swapper_pg_dir@l
423         rlwimi  r10, r11, 0, 2, 19
425         lwz     r11, 0(r10)     /* Get the level 1 entry */
426         rlwinm. r10, r11,0,0,19 /* Extract page descriptor page address */
427         beq     2f              /* If zero, don't try to find a pte */
429         /* We have a pte table, so load fetch the pte from the table.
430          */
431         ori     r11, r11, 1     /* Set valid bit in physical L2 page */
432         DO_8xx_CPU6(0x3b80, r3)
433         mtspr   SPRN_MD_TWC, r11        /* Load pte table base address */
434         mfspr   r10, SPRN_MD_TWC        /* ....and get the pte address */
435         lwz     r10, 0(r10)     /* Get the pte */
437         /* Insert the Guarded flag into the TWC from the Linux PTE.
438          * It is bit 27 of both the Linux PTE and the TWC (at least
439          * I got that right :-).  It will be better when we can put
440          * this into the Linux pgd/pmd and load it in the operation
441          * above.
442          */
443         rlwimi  r11, r10, 0, 27, 27
444         /* Insert the WriteThru flag into the TWC from the Linux PTE.
445          * It is bit 25 in the Linux PTE and bit 30 in the TWC
446          */
447         rlwimi  r11, r10, 32-5, 30, 30
448         DO_8xx_CPU6(0x3b80, r3)
449         mtspr   SPRN_MD_TWC, r11
451         /* Both _PAGE_ACCESSED and _PAGE_PRESENT has to be set.
452          * We also need to know if the insn is a load/store, so:
453          * Clear _PAGE_PRESENT and load that which will
454          * trap into DTLB Error with store bit set accordinly.
455          */
456         /* PRESENT=0x1, ACCESSED=0x20
457          * r11 = ((r10 & PRESENT) & ((r10 & ACCESSED) >> 5));
458          * r10 = (r10 & ~PRESENT) | r11;
459          */
460 #ifdef CONFIG_SWAP
461         rlwinm  r11, r10, 32-5, _PAGE_PRESENT
462         and     r11, r11, r10
463         rlwimi  r10, r11, 0, _PAGE_PRESENT
464 #endif
465         /* Honour kernel RO, User NA */
466         /* 0x200 == Extended encoding, bit 22 */
467         rlwimi  r10, r10, 32-2, 0x200 /* Copy USER to bit 22, 0x200 */
468         /* r11 =  (r10 & _PAGE_RW) >> 1 */
469         rlwinm  r11, r10, 32-1, 0x200
470         or      r10, r11, r10
471         /* invert RW and 0x200 bits */
472         xori    r10, r10, _PAGE_RW | 0x200
474         /* The Linux PTE won't go exactly into the MMU TLB.
475          * Software indicator bits 22 and 28 must be clear.
476          * Software indicator bits 24, 25, 26, and 27 must be
477          * set.  All other Linux PTE bits control the behavior
478          * of the MMU.
479          */
480 2:      li      r11, 0x00f0
481         rlwimi  r10, r11, 0, 24, 28     /* Set 24-27, clear 28 */
482         DO_8xx_CPU6(0x3d80, r3)
483         mtspr   SPRN_MD_RPN, r10        /* Update TLB entry */
485         /* Restore registers */
486 #ifndef CONFIG_8xx_CPU6
487         mfspr   r10, SPRN_DAR
488         mtcr    r10
489         mtspr   SPRN_DAR, r11   /* Tag DAR */
490         mfspr   r11, SPRN_SPRG2
491 #else
492         mtspr   SPRN_DAR, r11   /* Tag DAR */
493         lwz     r11, 0(r0)
494         mtcr    r11
495         lwz     r11, 4(r0)
496         lwz     r3, 8(r0)
497 #endif
498         mfspr   r10, SPRN_M_TW
499         rfi
501 /* This is an instruction TLB error on the MPC8xx.  This could be due
502  * to many reasons, such as executing guarded memory or illegal instruction
503  * addresses.  There is nothing to do but handle a big time error fault.
504  */
505         . = 0x1300
506 InstructionTLBError:
507         b       InstructionAccess
509 /* This is the data TLB error on the MPC8xx.  This could be due to
510  * many reasons, including a dirty update to a pte.  We can catch that
511  * one here, but anything else is an error.  First, we track down the
512  * Linux pte.  If it is valid, write access is allowed, but the
513  * page dirty bit is not set, we will set it and reload the TLB.  For
514  * any other case, we bail out to a higher level function that can
515  * handle it.
516  */
517         . = 0x1400
518 DataTLBError:
519 #ifdef CONFIG_8xx_CPU6
520         stw     r3, 8(r0)
521 #endif
522         DO_8xx_CPU6(0x3f80, r3)
523         mtspr   SPRN_M_TW, r10  /* Save a couple of working registers */
524         mfcr    r10
525         stw     r10, 0(r0)
526         stw     r11, 4(r0)
528         mfspr   r10, SPRN_DAR
529         cmpwi   cr0, r10, 0x00f0
530         beq-    FixupDAR        /* must be a buggy dcbX, icbi insn. */
531 DARFixed:/* Return from dcbx instruction bug workaround, r10 holds value of DAR */
532         mfspr   r10, SPRN_M_TW  /* Restore registers */
533         lwz     r11, 0(r0)
534         mtcr    r11
535         lwz     r11, 4(r0)
536 #ifdef CONFIG_8xx_CPU6
537         lwz     r3, 8(r0)
538 #endif
539         b       DataAccess
541         EXCEPTION(0x1500, Trap_15, unknown_exception, EXC_XFER_EE)
542         EXCEPTION(0x1600, Trap_16, unknown_exception, EXC_XFER_EE)
543         EXCEPTION(0x1700, Trap_17, unknown_exception, EXC_XFER_EE)
544         EXCEPTION(0x1800, Trap_18, unknown_exception, EXC_XFER_EE)
545         EXCEPTION(0x1900, Trap_19, unknown_exception, EXC_XFER_EE)
546         EXCEPTION(0x1a00, Trap_1a, unknown_exception, EXC_XFER_EE)
547         EXCEPTION(0x1b00, Trap_1b, unknown_exception, EXC_XFER_EE)
549 /* On the MPC8xx, these next four traps are used for development
550  * support of breakpoints and such.  Someday I will get around to
551  * using them.
552  */
553         EXCEPTION(0x1c00, Trap_1c, unknown_exception, EXC_XFER_EE)
554         EXCEPTION(0x1d00, Trap_1d, unknown_exception, EXC_XFER_EE)
555         EXCEPTION(0x1e00, Trap_1e, unknown_exception, EXC_XFER_EE)
556         EXCEPTION(0x1f00, Trap_1f, unknown_exception, EXC_XFER_EE)
558         . = 0x2000
560 /* This is the procedure to calculate the data EA for buggy dcbx,dcbi instructions
561  * by decoding the registers used by the dcbx instruction and adding them.
562  * DAR is set to the calculated address and r10 also holds the EA on exit.
563  */
564  /* define if you don't want to use self modifying code */
565 #define NO_SELF_MODIFYING_CODE
566 FixupDAR:/* Entry point for dcbx workaround. */
567         /* fetch instruction from memory. */
568         mfspr   r10, SPRN_SRR0
569         andis.  r11, r10, 0x8000        /* Address >= 0x80000000 */
570         DO_8xx_CPU6(0x3780, r3)
571         mtspr   SPRN_MD_EPN, r10
572         mfspr   r11, SPRN_M_TWB /* Get level 1 table entry address */
573         beq-    3f              /* Branch if user space */
574         lis     r11, (swapper_pg_dir-PAGE_OFFSET)@h
575         ori     r11, r11, (swapper_pg_dir-PAGE_OFFSET)@l
576         rlwimi  r11, r10, 32-20, 0xffc /* r11 = r11&~0xffc|(r10>>20)&0xffc */
577 3:      lwz     r11, 0(r11)     /* Get the level 1 entry */
578         DO_8xx_CPU6(0x3b80, r3)
579         mtspr   SPRN_MD_TWC, r11        /* Load pte table base address */
580         mfspr   r11, SPRN_MD_TWC        /* ....and get the pte address */
581         lwz     r11, 0(r11)     /* Get the pte */
582         /* concat physical page address(r11) and page offset(r10) */
583         rlwimi  r11, r10, 0, 20, 31
584         lwz     r11,0(r11)
585 /* Check if it really is a dcbx instruction. */
586 /* dcbt and dcbtst does not generate DTLB Misses/Errors,
587  * no need to include them here */
588         srwi    r10, r11, 26    /* check if major OP code is 31 */
589         cmpwi   cr0, r10, 31
590         bne-    141f
591         rlwinm  r10, r11, 0, 21, 30
592         cmpwi   cr0, r10, 2028  /* Is dcbz? */
593         beq+    142f
594         cmpwi   cr0, r10, 940   /* Is dcbi? */
595         beq+    142f
596         cmpwi   cr0, r10, 108   /* Is dcbst? */
597         beq+    144f            /* Fix up store bit! */
598         cmpwi   cr0, r10, 172   /* Is dcbf? */
599         beq+    142f
600         cmpwi   cr0, r10, 1964  /* Is icbi? */
601         beq+    142f
602 141:    mfspr   r10, SPRN_DAR   /* r10 must hold DAR at exit */
603         b       DARFixed        /* Nope, go back to normal TLB processing */
605 144:    mfspr   r10, SPRN_DSISR
606         rlwinm  r10, r10,0,7,5  /* Clear store bit for buggy dcbst insn */
607         mtspr   SPRN_DSISR, r10
608 142:    /* continue, it was a dcbx, dcbi instruction. */
609 #ifdef CONFIG_8xx_CPU6
610         lwz     r3, 8(r0)       /* restore r3 from memory */
611 #endif
612 #ifndef NO_SELF_MODIFYING_CODE
613         andis.  r10,r11,0x1f    /* test if reg RA is r0 */
614         li      r10,modified_instr@l
615         dcbtst  r0,r10          /* touch for store */
616         rlwinm  r11,r11,0,0,20  /* Zero lower 10 bits */
617         oris    r11,r11,640     /* Transform instr. to a "add r10,RA,RB" */
618         ori     r11,r11,532
619         stw     r11,0(r10)      /* store add/and instruction */
620         dcbf    0,r10           /* flush new instr. to memory. */
621         icbi    0,r10           /* invalidate instr. cache line */
622         lwz     r11, 4(r0)      /* restore r11 from memory */
623         mfspr   r10, SPRN_M_TW  /* restore r10 from M_TW */
624         isync                   /* Wait until new instr is loaded from memory */
625 modified_instr:
626         .space  4               /* this is where the add instr. is stored */
627         bne+    143f
628         subf    r10,r0,r10      /* r10=r10-r0, only if reg RA is r0 */
629 143:    mtdar   r10             /* store faulting EA in DAR */
630         b       DARFixed        /* Go back to normal TLB handling */
631 #else
632         mfctr   r10
633         mtdar   r10                     /* save ctr reg in DAR */
634         rlwinm  r10, r11, 24, 24, 28    /* offset into jump table for reg RB */
635         addi    r10, r10, 150f@l        /* add start of table */
636         mtctr   r10                     /* load ctr with jump address */
637         xor     r10, r10, r10           /* sum starts at zero */
638         bctr                            /* jump into table */
639 150:
640         add     r10, r10, r0    ;b      151f
641         add     r10, r10, r1    ;b      151f
642         add     r10, r10, r2    ;b      151f
643         add     r10, r10, r3    ;b      151f
644         add     r10, r10, r4    ;b      151f
645         add     r10, r10, r5    ;b      151f
646         add     r10, r10, r6    ;b      151f
647         add     r10, r10, r7    ;b      151f
648         add     r10, r10, r8    ;b      151f
649         add     r10, r10, r9    ;b      151f
650         mtctr   r11     ;b      154f    /* r10 needs special handling */
651         mtctr   r11     ;b      153f    /* r11 needs special handling */
652         add     r10, r10, r12   ;b      151f
653         add     r10, r10, r13   ;b      151f
654         add     r10, r10, r14   ;b      151f
655         add     r10, r10, r15   ;b      151f
656         add     r10, r10, r16   ;b      151f
657         add     r10, r10, r17   ;b      151f
658         add     r10, r10, r18   ;b      151f
659         add     r10, r10, r19   ;b      151f
660         add     r10, r10, r20   ;b      151f
661         add     r10, r10, r21   ;b      151f
662         add     r10, r10, r22   ;b      151f
663         add     r10, r10, r23   ;b      151f
664         add     r10, r10, r24   ;b      151f
665         add     r10, r10, r25   ;b      151f
666         add     r10, r10, r26   ;b      151f
667         add     r10, r10, r27   ;b      151f
668         add     r10, r10, r28   ;b      151f
669         add     r10, r10, r29   ;b      151f
670         add     r10, r10, r30   ;b      151f
671         add     r10, r10, r31
672 151:
673         rlwinm. r11,r11,19,24,28        /* offset into jump table for reg RA */
674         beq     152f                    /* if reg RA is zero, don't add it */
675         addi    r11, r11, 150b@l        /* add start of table */
676         mtctr   r11                     /* load ctr with jump address */
677         rlwinm  r11,r11,0,16,10         /* make sure we don't execute this more than once */
678         bctr                            /* jump into table */
679 152:
680         mfdar   r11
681         mtctr   r11                     /* restore ctr reg from DAR */
682         mtdar   r10                     /* save fault EA to DAR */
683         b       DARFixed                /* Go back to normal TLB handling */
685         /* special handling for r10,r11 since these are modified already */
686 153:    lwz     r11, 4(r0)      /* load r11 from memory */
687         b       155f
688 154:    mfspr   r11, SPRN_M_TW  /* load r10 from M_TW */
689 155:    add     r10, r10, r11   /* add it */
690         mfctr   r11             /* restore r11 */
691         b       151b
692 #endif
695  * This is where the main kernel code starts.
696  */
697 start_here:
698         /* ptr to current */
699         lis     r2,init_task@h
700         ori     r2,r2,init_task@l
702         /* ptr to phys current thread */
703         tophys(r4,r2)
704         addi    r4,r4,THREAD    /* init task's THREAD */
705         mtspr   SPRN_SPRG_THREAD,r4
707         /* stack */
708         lis     r1,init_thread_union@ha
709         addi    r1,r1,init_thread_union@l
710         li      r0,0
711         stwu    r0,THREAD_SIZE-STACK_FRAME_OVERHEAD(r1)
713         bl      early_init      /* We have to do this with MMU on */
716  * Decide what sort of machine this is and initialize the MMU.
717  */
718         li      r3,0
719         mr      r4,r31
720         bl      machine_init
721         bl      MMU_init
724  * Go back to running unmapped so we can load up new values
725  * and change to using our exception vectors.
726  * On the 8xx, all we have to do is invalidate the TLB to clear
727  * the old 8M byte TLB mappings and load the page table base register.
728  */
729         /* The right way to do this would be to track it down through
730          * init's THREAD like the context switch code does, but this is
731          * easier......until someone changes init's static structures.
732          */
733         lis     r6, swapper_pg_dir@h
734         ori     r6, r6, swapper_pg_dir@l
735         tophys(r6,r6)
736 #ifdef CONFIG_8xx_CPU6
737         lis     r4, cpu6_errata_word@h
738         ori     r4, r4, cpu6_errata_word@l
739         li      r3, 0x3980
740         stw     r3, 12(r4)
741         lwz     r3, 12(r4)
742 #endif
743         mtspr   SPRN_M_TWB, r6
744         lis     r4,2f@h
745         ori     r4,r4,2f@l
746         tophys(r4,r4)
747         li      r3,MSR_KERNEL & ~(MSR_IR|MSR_DR)
748         mtspr   SPRN_SRR0,r4
749         mtspr   SPRN_SRR1,r3
750         rfi
751 /* Load up the kernel context */
753         SYNC                    /* Force all PTE updates to finish */
754         tlbia                   /* Clear all TLB entries */
755         sync                    /* wait for tlbia/tlbie to finish */
756         TLBSYNC                 /* ... on all CPUs */
758         /* set up the PTE pointers for the Abatron bdiGDB.
759         */
760         tovirt(r6,r6)
761         lis     r5, abatron_pteptrs@h
762         ori     r5, r5, abatron_pteptrs@l
763         stw     r5, 0xf0(r0)    /* Must match your Abatron config file */
764         tophys(r5,r5)
765         stw     r6, 0(r5)
767 /* Now turn on the MMU for real! */
768         li      r4,MSR_KERNEL
769         lis     r3,start_kernel@h
770         ori     r3,r3,start_kernel@l
771         mtspr   SPRN_SRR0,r3
772         mtspr   SPRN_SRR1,r4
773         rfi                     /* enable MMU and jump to start_kernel */
775 /* Set up the initial MMU state so we can do the first level of
776  * kernel initialization.  This maps the first 8 MBytes of memory 1:1
777  * virtual to physical.  Also, set the cache mode since that is defined
778  * by TLB entries and perform any additional mapping (like of the IMMR).
779  * If configured to pin some TLBs, we pin the first 8 Mbytes of kernel,
780  * 24 Mbytes of data, and the 8M IMMR space.  Anything not covered by
781  * these mappings is mapped by page tables.
782  */
783 initial_mmu:
784         tlbia                   /* Invalidate all TLB entries */
785 /* Always pin the first 8 MB ITLB to prevent ITLB
786    misses while mucking around with SRR0/SRR1 in asm
788         lis     r8, MI_RSV4I@h
789         ori     r8, r8, 0x1c00
791         mtspr   SPRN_MI_CTR, r8 /* Set instruction MMU control */
793 #ifdef CONFIG_PIN_TLB
794         lis     r10, (MD_RSV4I | MD_RESETVAL)@h
795         ori     r10, r10, 0x1c00
796         mr      r8, r10
797 #else
798         lis     r10, MD_RESETVAL@h
799 #endif
800 #ifndef CONFIG_8xx_COPYBACK
801         oris    r10, r10, MD_WTDEF@h
802 #endif
803         mtspr   SPRN_MD_CTR, r10        /* Set data TLB control */
805         /* Now map the lower 8 Meg into the TLBs.  For this quick hack,
806          * we can load the instruction and data TLB registers with the
807          * same values.
808          */
809         lis     r8, KERNELBASE@h        /* Create vaddr for TLB */
810         ori     r8, r8, MI_EVALID       /* Mark it valid */
811         mtspr   SPRN_MI_EPN, r8
812         mtspr   SPRN_MD_EPN, r8
813         li      r8, MI_PS8MEG           /* Set 8M byte page */
814         ori     r8, r8, MI_SVALID       /* Make it valid */
815         mtspr   SPRN_MI_TWC, r8
816         mtspr   SPRN_MD_TWC, r8
817         li      r8, MI_BOOTINIT         /* Create RPN for address 0 */
818         mtspr   SPRN_MI_RPN, r8         /* Store TLB entry */
819         mtspr   SPRN_MD_RPN, r8
820         lis     r8, MI_Kp@h             /* Set the protection mode */
821         mtspr   SPRN_MI_AP, r8
822         mtspr   SPRN_MD_AP, r8
824         /* Map another 8 MByte at the IMMR to get the processor
825          * internal registers (among other things).
826          */
827 #ifdef CONFIG_PIN_TLB
828         addi    r10, r10, 0x0100
829         mtspr   SPRN_MD_CTR, r10
830 #endif
831         mfspr   r9, 638                 /* Get current IMMR */
832         andis.  r9, r9, 0xff80          /* Get 8Mbyte boundary */
834         mr      r8, r9                  /* Create vaddr for TLB */
835         ori     r8, r8, MD_EVALID       /* Mark it valid */
836         mtspr   SPRN_MD_EPN, r8
837         li      r8, MD_PS8MEG           /* Set 8M byte page */
838         ori     r8, r8, MD_SVALID       /* Make it valid */
839         mtspr   SPRN_MD_TWC, r8
840         mr      r8, r9                  /* Create paddr for TLB */
841         ori     r8, r8, MI_BOOTINIT|0x2 /* Inhibit cache -- Cort */
842         mtspr   SPRN_MD_RPN, r8
844 #ifdef CONFIG_PIN_TLB
845         /* Map two more 8M kernel data pages.
846         */
847         addi    r10, r10, 0x0100
848         mtspr   SPRN_MD_CTR, r10
850         lis     r8, KERNELBASE@h        /* Create vaddr for TLB */
851         addis   r8, r8, 0x0080          /* Add 8M */
852         ori     r8, r8, MI_EVALID       /* Mark it valid */
853         mtspr   SPRN_MD_EPN, r8
854         li      r9, MI_PS8MEG           /* Set 8M byte page */
855         ori     r9, r9, MI_SVALID       /* Make it valid */
856         mtspr   SPRN_MD_TWC, r9
857         li      r11, MI_BOOTINIT        /* Create RPN for address 0 */
858         addis   r11, r11, 0x0080        /* Add 8M */
859         mtspr   SPRN_MD_RPN, r11
861         addi    r10, r10, 0x0100
862         mtspr   SPRN_MD_CTR, r10
864         addis   r8, r8, 0x0080          /* Add 8M */
865         mtspr   SPRN_MD_EPN, r8
866         mtspr   SPRN_MD_TWC, r9
867         addis   r11, r11, 0x0080        /* Add 8M */
868         mtspr   SPRN_MD_RPN, r11
869 #endif
871         /* Since the cache is enabled according to the information we
872          * just loaded into the TLB, invalidate and enable the caches here.
873          * We should probably check/set other modes....later.
874          */
875         lis     r8, IDC_INVALL@h
876         mtspr   SPRN_IC_CST, r8
877         mtspr   SPRN_DC_CST, r8
878         lis     r8, IDC_ENABLE@h
879         mtspr   SPRN_IC_CST, r8
880 #ifdef CONFIG_8xx_COPYBACK
881         mtspr   SPRN_DC_CST, r8
882 #else
883         /* For a debug option, I left this here to easily enable
884          * the write through cache mode
885          */
886         lis     r8, DC_SFWT@h
887         mtspr   SPRN_DC_CST, r8
888         lis     r8, IDC_ENABLE@h
889         mtspr   SPRN_DC_CST, r8
890 #endif
891         blr
895  * Set up to use a given MMU context.
896  * r3 is context number, r4 is PGD pointer.
898  * We place the physical address of the new task page directory loaded
899  * into the MMU base register, and set the ASID compare register with
900  * the new "context."
901  */
902 _GLOBAL(set_context)
904 #ifdef CONFIG_BDI_SWITCH
905         /* Context switch the PTE pointer for the Abatron BDI2000.
906          * The PGDIR is passed as second argument.
907          */
908         lis     r5, KERNELBASE@h
909         lwz     r5, 0xf0(r5)
910         stw     r4, 0x4(r5)
911 #endif
913 #ifdef CONFIG_8xx_CPU6
914         lis     r6, cpu6_errata_word@h
915         ori     r6, r6, cpu6_errata_word@l
916         tophys  (r4, r4)
917         li      r7, 0x3980
918         stw     r7, 12(r6)
919         lwz     r7, 12(r6)
920         mtspr   SPRN_M_TWB, r4               /* Update MMU base address */
921         li      r7, 0x3380
922         stw     r7, 12(r6)
923         lwz     r7, 12(r6)
924         mtspr   SPRN_M_CASID, r3             /* Update context */
925 #else
926         mtspr   SPRN_M_CASID,r3         /* Update context */
927         tophys  (r4, r4)
928         mtspr   SPRN_M_TWB, r4          /* and pgd */
929 #endif
930         SYNC
931         blr
933 #ifdef CONFIG_8xx_CPU6
934 /* It's here because it is unique to the 8xx.
935  * It is important we get called with interrupts disabled.  I used to
936  * do that, but it appears that all code that calls this already had
937  * interrupt disabled.
938  */
939         .globl  set_dec_cpu6
940 set_dec_cpu6:
941         lis     r7, cpu6_errata_word@h
942         ori     r7, r7, cpu6_errata_word@l
943         li      r4, 0x2c00
944         stw     r4, 8(r7)
945         lwz     r4, 8(r7)
946         mtspr   22, r3          /* Update Decrementer */
947         SYNC
948         blr
949 #endif
952  * We put a few things here that have to be page-aligned.
953  * This stuff goes at the beginning of the data segment,
954  * which is page-aligned.
955  */
956         .data
957         .globl  sdata
958 sdata:
959         .globl  empty_zero_page
960 empty_zero_page:
961         .space  4096
963         .globl  swapper_pg_dir
964 swapper_pg_dir:
965         .space  4096
967 /* Room for two PTE table poiners, usually the kernel and current user
968  * pointer to their respective root page table (pgdir).
969  */
970 abatron_pteptrs:
971         .space  8
973 #ifdef CONFIG_8xx_CPU6
974         .globl  cpu6_errata_word
975 cpu6_errata_word:
976         .space  16
977 #endif