]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/blame - arch/powerpc/kernel/head_8xx.S
powerpc/8xx: Remove cpu dependent macro instructions from head_8xx
[mirror_ubuntu-bionic-kernel.git] / arch / powerpc / kernel / head_8xx.S
CommitLineData
14cf11af 1/*
14cf11af
PM
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 */
21
e7039845 22#include <linux/init.h>
14cf11af
PM
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>
46f52210 32#include <asm/ptrace.h>
f86ef74e 33#include <asm/fixmap.h>
9445aa1a 34#include <asm/export.h>
14cf11af
PM
35
36/* Macro to make the code more readable. */
37#ifdef CONFIG_8xx_CPU6
d3e40262
LC
38#define SPRN_MI_TWC_ADDR 0x2b80
39#define SPRN_MI_RPN_ADDR 0x2d80
40#define SPRN_MD_TWC_ADDR 0x3b80
41#define SPRN_MD_RPN_ADDR 0x3d80
42
43#define MTSPR_CPU6(spr, reg, treg) \
44 li treg, spr##_ADDR; \
45 stw treg, 12(r0); \
46 lwz treg, 12(r0); \
47 mtspr spr, reg
14cf11af 48#else
d3e40262
LC
49#define MTSPR_CPU6(spr, reg, treg) \
50 mtspr spr, reg
14cf11af 51#endif
ac21951f 52
eeba1f7c
LC
53/* Macro to test if an address is a kernel address */
54#if CONFIG_TASK_SIZE <= 0x80000000 && CONFIG_PAGE_OFFSET >= 0x80000000
55#define IS_KERNEL(tmp, addr) \
56 andis. tmp, addr, 0x8000 /* Address >= 0x80000000 */
57#define BRANCH_UNLESS_KERNEL(label) beq label
58#else
59#define IS_KERNEL(tmp, addr) \
60 rlwinm tmp, addr, 16, 16, 31; \
61 cmpli cr0, tmp, PAGE_OFFSET >> 16
62#define BRANCH_UNLESS_KERNEL(label) blt label
63#endif
64
65
ac21951f
LC
66/*
67 * Value for the bits that have fixed value in RPN entries.
68 * Also used for tagging DAR for DTLBerror.
69 */
959d6173
LC
70#ifdef CONFIG_PPC_16K_PAGES
71#define RPN_PATTERN (0x00f0 | MD_SPS16K)
72#else
ac21951f 73#define RPN_PATTERN 0x00f0
959d6173 74#endif
ac21951f 75
4b914286
CL
76#define PAGE_SHIFT_512K 19
77#define PAGE_SHIFT_8M 23
78
e7039845 79 __HEAD
748a7683
KG
80_ENTRY(_stext);
81_ENTRY(_start);
14cf11af
PM
82
83/* MPC8xx
84 * This port was done on an MBX board with an 860. Right now I only
85 * support an ELF compressed (zImage) boot from EPPC-Bug because the
86 * code there loads up some registers before calling us:
87 * r3: ptr to board info data
88 * r4: initrd_start or if no initrd then 0
89 * r5: initrd_end - unused if r4 is 0
90 * r6: Start of command line string
91 * r7: End of command line string
92 *
93 * I decided to use conditional compilation instead of checking PVR and
94 * adding more processor specific branches around code I don't need.
95 * Since this is an embedded processor, I also appreciate any memory
96 * savings I can get.
97 *
98 * The MPC8xx does not have any BATs, but it supports large page sizes.
99 * We first initialize the MMU to support 8M byte pages, then load one
100 * entry into each of the instruction and data TLBs to map the first
101 * 8M 1:1. I also mapped an additional I/O space 1:1 so we can get to
102 * the "internal" processor registers before MMU_init is called.
103 *
14cf11af
PM
104 * -- Dan
105 */
106 .globl __start
107__start:
6dece0eb 108 mr r31,r3 /* save device tree ptr */
14cf11af
PM
109
110 /* We have to turn on the MMU right away so we get cache modes
111 * set correctly.
112 */
113 bl initial_mmu
114
115/* We now have the lower 8 Meg mapped into TLB entries, and the caches
116 * ready to work.
117 */
118
119turn_on_mmu:
120 mfmsr r0
121 ori r0,r0,MSR_DR|MSR_IR
122 mtspr SPRN_SRR1,r0
123 lis r0,start_here@h
124 ori r0,r0,start_here@l
125 mtspr SPRN_SRR0,r0
14cf11af
PM
126 rfi /* enables MMU */
127
128/*
129 * Exception entry code. This code runs with address translation
130 * turned off, i.e. using physical addresses.
131 * We assume sprg3 has the physical address of the current
132 * task's thread_struct.
133 */
134#define EXCEPTION_PROLOG \
92625d49 135 EXCEPTION_PROLOG_0; \
d5fd9d7d 136 mfcr r10; \
14cf11af
PM
137 EXCEPTION_PROLOG_1; \
138 EXCEPTION_PROLOG_2
139
92625d49
LC
140#define EXCEPTION_PROLOG_0 \
141 mtspr SPRN_SPRG_SCRATCH0,r10; \
d5fd9d7d 142 mtspr SPRN_SPRG_SCRATCH1,r11
92625d49 143
14cf11af
PM
144#define EXCEPTION_PROLOG_1 \
145 mfspr r11,SPRN_SRR1; /* check whether user or kernel */ \
146 andi. r11,r11,MSR_PR; \
147 tophys(r11,r1); /* use tophys(r1) if kernel */ \
148 beq 1f; \
ee43eb78 149 mfspr r11,SPRN_SPRG_THREAD; \
14cf11af
PM
150 lwz r11,THREAD_INFO-THREAD(r11); \
151 addi r11,r11,THREAD_SIZE; \
152 tophys(r11,r11); \
1531: subi r11,r11,INT_FRAME_SIZE /* alloc exc. frame */
154
155
156#define EXCEPTION_PROLOG_2 \
14cf11af
PM
157 stw r10,_CCR(r11); /* save registers */ \
158 stw r12,GPR12(r11); \
159 stw r9,GPR9(r11); \
ee43eb78 160 mfspr r10,SPRN_SPRG_SCRATCH0; \
14cf11af 161 stw r10,GPR10(r11); \
ee43eb78 162 mfspr r12,SPRN_SPRG_SCRATCH1; \
14cf11af
PM
163 stw r12,GPR11(r11); \
164 mflr r10; \
165 stw r10,_LINK(r11); \
166 mfspr r12,SPRN_SRR0; \
167 mfspr r9,SPRN_SRR1; \
168 stw r1,GPR1(r11); \
169 stw r1,0(r11); \
170 tovirt(r1,r11); /* set new kernel sp */ \
171 li r10,MSR_KERNEL & ~(MSR_IR|MSR_DR); /* can take exceptions */ \
0e9645df 172 mtmsr r10; \
14cf11af
PM
173 stw r0,GPR0(r11); \
174 SAVE_4GPRS(3, r11); \
175 SAVE_2GPRS(7, r11)
176
92625d49
LC
177/*
178 * Exception exit code.
179 */
180#define EXCEPTION_EPILOG_0 \
92625d49
LC
181 mfspr r10,SPRN_SPRG_SCRATCH0; \
182 mfspr r11,SPRN_SPRG_SCRATCH1
183
14cf11af
PM
184/*
185 * Note: code which follows this uses cr0.eq (set if from kernel),
186 * r11, r12 (SRR0), and r9 (SRR1).
187 *
188 * Note2: once we have set r1 we are in a position to take exceptions
189 * again, and we could thus set MSR:RI at that point.
190 */
191
192/*
193 * Exception vectors.
194 */
195#define EXCEPTION(n, label, hdlr, xfer) \
196 . = n; \
197label: \
198 EXCEPTION_PROLOG; \
199 addi r3,r1,STACK_FRAME_OVERHEAD; \
200 xfer(n, hdlr)
201
202#define EXC_XFER_TEMPLATE(n, hdlr, trap, copyee, tfer, ret) \
203 li r10,trap; \
d73e0c99 204 stw r10,_TRAP(r11); \
14cf11af
PM
205 li r10,MSR_KERNEL; \
206 copyee(r10, r9); \
207 bl tfer; \
208i##n: \
209 .long hdlr; \
210 .long ret
211
212#define COPY_EE(d, s) rlwimi d,s,0,16,16
213#define NOCOPY(d, s)
214
215#define EXC_XFER_STD(n, hdlr) \
216 EXC_XFER_TEMPLATE(n, hdlr, n, NOCOPY, transfer_to_handler_full, \
217 ret_from_except_full)
218
219#define EXC_XFER_LITE(n, hdlr) \
220 EXC_XFER_TEMPLATE(n, hdlr, n+1, NOCOPY, transfer_to_handler, \
221 ret_from_except)
222
223#define EXC_XFER_EE(n, hdlr) \
224 EXC_XFER_TEMPLATE(n, hdlr, n, COPY_EE, transfer_to_handler_full, \
225 ret_from_except_full)
226
227#define EXC_XFER_EE_LITE(n, hdlr) \
228 EXC_XFER_TEMPLATE(n, hdlr, n+1, COPY_EE, transfer_to_handler, \
229 ret_from_except)
230
231/* System reset */
f307939f 232 EXCEPTION(0x100, Reset, system_reset_exception, EXC_XFER_STD)
14cf11af
PM
233
234/* Machine check */
235 . = 0x200
236MachineCheck:
237 EXCEPTION_PROLOG
238 mfspr r4,SPRN_DAR
239 stw r4,_DAR(r11)
ac21951f 240 li r5,RPN_PATTERN
60e071fe 241 mtspr SPRN_DAR,r5 /* Tag DAR, to be used in DTLB Error */
14cf11af
PM
242 mfspr r5,SPRN_DSISR
243 stw r5,_DSISR(r11)
244 addi r3,r1,STACK_FRAME_OVERHEAD
dc1c1ca3 245 EXC_XFER_STD(0x200, machine_check_exception)
14cf11af
PM
246
247/* Data access exception.
749137a2 248 * This is "never generated" by the MPC8xx.
14cf11af
PM
249 */
250 . = 0x300
251DataAccess:
14cf11af
PM
252
253/* Instruction access exception.
7439b37e 254 * This is "never generated" by the MPC8xx.
14cf11af
PM
255 */
256 . = 0x400
257InstructionAccess:
14cf11af
PM
258
259/* External interrupt */
260 EXCEPTION(0x500, HardwareInterrupt, do_IRQ, EXC_XFER_LITE)
261
262/* Alignment exception */
263 . = 0x600
264Alignment:
265 EXCEPTION_PROLOG
266 mfspr r4,SPRN_DAR
267 stw r4,_DAR(r11)
ac21951f 268 li r5,RPN_PATTERN
60e071fe 269 mtspr SPRN_DAR,r5 /* Tag DAR, to be used in DTLB Error */
14cf11af
PM
270 mfspr r5,SPRN_DSISR
271 stw r5,_DSISR(r11)
272 addi r3,r1,STACK_FRAME_OVERHEAD
dc1c1ca3 273 EXC_XFER_EE(0x600, alignment_exception)
14cf11af
PM
274
275/* Program check exception */
dc1c1ca3 276 EXCEPTION(0x700, ProgramCheck, program_check_exception, EXC_XFER_STD)
14cf11af
PM
277
278/* No FPU on MPC8xx. This exception is not supposed to happen.
279*/
dc1c1ca3 280 EXCEPTION(0x800, FPUnavailable, unknown_exception, EXC_XFER_STD)
14cf11af
PM
281
282/* Decrementer */
283 EXCEPTION(0x900, Decrementer, timer_interrupt, EXC_XFER_LITE)
284
dc1c1ca3
SR
285 EXCEPTION(0xa00, Trap_0a, unknown_exception, EXC_XFER_EE)
286 EXCEPTION(0xb00, Trap_0b, unknown_exception, EXC_XFER_EE)
14cf11af
PM
287
288/* System call */
289 . = 0xc00
290SystemCall:
291 EXCEPTION_PROLOG
292 EXC_XFER_EE_LITE(0xc00, DoSyscall)
293
294/* Single step - not used on 601 */
dc1c1ca3
SR
295 EXCEPTION(0xd00, SingleStep, single_step_exception, EXC_XFER_STD)
296 EXCEPTION(0xe00, Trap_0e, unknown_exception, EXC_XFER_EE)
297 EXCEPTION(0xf00, Trap_0f, unknown_exception, EXC_XFER_EE)
14cf11af
PM
298
299/* On the MPC8xx, this is a software emulation interrupt. It occurs
300 * for all unimplemented and illegal instructions.
301 */
fbbcc3bb 302 EXCEPTION(0x1000, SoftEmu, program_check_exception, EXC_XFER_STD)
14cf11af
PM
303
304 . = 0x1100
305/*
306 * For the MPC8xx, this is a software tablewalk to load the instruction
cbc130f1
LC
307 * TLB. The task switch loads the M_TW register with the pointer to the first
308 * level table.
14cf11af
PM
309 * If we discover there is no second level table (value is zero) or if there
310 * is an invalid pte, we load that into the TLB, which causes another fault
311 * into the TLB Error interrupt where we can handle such problems.
312 * We have to use the MD_xxx registers for the tablewalk because the
313 * equivalent MI_xxx registers only perform the attribute functions.
314 */
90883a82
LC
315
316#ifdef CONFIG_8xx_CPU15
317#define INVALIDATE_ADJACENT_PAGES_CPU15(tmp, addr) \
318 addi tmp, addr, PAGE_SIZE; \
319 tlbie tmp; \
320 addi tmp, addr, -PAGE_SIZE; \
321 tlbie tmp
322#else
323#define INVALIDATE_ADJACENT_PAGES_CPU15(tmp, addr)
324#endif
325
14cf11af 326InstructionTLBMiss:
4b914286 327#if defined(CONFIG_8xx_CPU6) || defined(CONFIG_MODULES) || defined (CONFIG_DEBUG_PAGEALLOC) || defined (CONFIG_HUGETLB_PAGE)
b821c5fe 328 mtspr SPRN_SPRG_SCRATCH2, r3
14cf11af 329#endif
92625d49 330 EXCEPTION_PROLOG_0
75b82472
CL
331#ifdef CONFIG_PPC_8xx_PERF_EVENT
332 lis r10, (itlb_miss_counter - PAGE_OFFSET)@ha
333 lwz r11, (itlb_miss_counter - PAGE_OFFSET)@l(r10)
334 addi r11, r11, 1
335 stw r11, (itlb_miss_counter - PAGE_OFFSET)@l(r10)
336#endif
14cf11af
PM
337
338 /* If we are faulting a kernel address, we have to use the
339 * kernel page tables.
340 */
d1b9f814
CL
341 mfspr r10, SPRN_SRR0 /* Get effective address of fault */
342 INVALIDATE_ADJACENT_PAGES_CPU15(r11, r10)
4afb0be7
JT
343 /* Only modules will cause ITLB Misses as we always
344 * pin the first 8MB of kernel memory */
4b914286 345#if defined(CONFIG_MODULES) || defined (CONFIG_DEBUG_PAGEALLOC) || defined (CONFIG_HUGETLB_PAGE)
d1b9f814 346 mfcr r3
4b914286
CL
347#endif
348#if defined(CONFIG_MODULES) || defined (CONFIG_DEBUG_PAGEALLOC)
d1b9f814
CL
349 IS_KERNEL(r11, r10)
350#endif
fde5a905 351 mfspr r11, SPRN_M_TW /* Get level 1 table */
d1b9f814 352#if defined(CONFIG_MODULES) || defined (CONFIG_DEBUG_PAGEALLOC)
eeba1f7c 353 BRANCH_UNLESS_KERNEL(3f)
fde5a905 354 lis r11, (swapper_pg_dir-PAGE_OFFSET)@ha
14cf11af 3553:
4afb0be7 356#endif
17bb312f
LC
357 /* Insert level 1 index */
358 rlwimi r11, r10, 32 - ((PAGE_SHIFT - 2) << 1), (PAGE_SHIFT - 2) << 1, 29
fde5a905 359 lwz r11, (swapper_pg_dir-PAGE_OFFSET)@l(r11) /* Get the level 1 entry */
14cf11af 360
d1406803 361 /* Extract level 2 index */
17bb312f 362 rlwinm r10, r10, 32 - (PAGE_SHIFT - 2), 32 - PAGE_SHIFT, 29
4b914286
CL
363#ifdef CONFIG_HUGETLB_PAGE
364 mtcr r11
365 bt- 28, 10f /* bit 28 = Large page (8M) */
366 bt- 29, 20f /* bit 29 = Large page (8M or 512k) */
367#endif
e0a8e0d9
LC
368 rlwimi r10, r11, 0, 0, 32 - PAGE_SHIFT - 1 /* Add level 2 base */
369 lwz r10, 0(r10) /* Get the pte */
4b914286
CL
3704:
371#if defined(CONFIG_MODULES) || defined (CONFIG_DEBUG_PAGEALLOC) || defined (CONFIG_HUGETLB_PAGE)
372 mtcr r3
373#endif
e0a8e0d9 374 /* Insert the APG into the TWC from the Linux PTE. */
5b2753fc 375 rlwimi r11, r10, 0, 25, 26
e0a8e0d9
LC
376 /* Load the MI_TWC with the attributes for this "segment." */
377 MTSPR_CPU6(SPRN_MI_TWC, r11, r3) /* Set segment attributes */
14cf11af 378
4b914286
CL
379#if defined (CONFIG_HUGETLB_PAGE) && defined (CONFIG_PPC_4K_PAGES)
380 rlwimi r10, r11, 1, MI_SPS16K
381#endif
d069cb43 382#ifdef CONFIG_SWAP
5ddb75ce
LC
383 rlwinm r11, r10, 32-5, _PAGE_PRESENT
384 and r11, r11, r10
385 rlwimi r10, r11, 0, _PAGE_PRESENT
d069cb43 386#endif
5ddb75ce 387 li r11, RPN_PATTERN
14cf11af 388 /* The Linux PTE won't go exactly into the MMU TLB.
e0a8e0d9 389 * Software indicator bits 20-23 and 28 must be clear.
14cf11af
PM
390 * Software indicator bits 24, 25, 26, and 27 must be
391 * set. All other Linux PTE bits control the behavior
392 * of the MMU.
393 */
4b914286
CL
394#if defined (CONFIG_HUGETLB_PAGE) && defined (CONFIG_PPC_4K_PAGES)
395 rlwimi r10, r11, 0, 0x0ff0 /* Set 24-27, clear 20-23 */
396#else
e0a8e0d9 397 rlwimi r10, r11, 0, 0x0ff8 /* Set 24-27, clear 20-23,28 */
4b914286 398#endif
d3e40262 399 MTSPR_CPU6(SPRN_MI_RPN, r10, r3) /* Update TLB entry */
14cf11af 400
469d62be 401 /* Restore registers */
4b914286 402#if defined(CONFIG_8xx_CPU6) || defined(CONFIG_MODULES) || defined (CONFIG_DEBUG_PAGEALLOC) || defined (CONFIG_HUGETLB_PAGE)
b821c5fe 403 mfspr r3, SPRN_SPRG_SCRATCH2
14cf11af 404#endif
92625d49 405 EXCEPTION_EPILOG_0
14cf11af
PM
406 rfi
407
4b914286
CL
408#ifdef CONFIG_HUGETLB_PAGE
40910: /* 8M pages */
410#ifdef CONFIG_PPC_16K_PAGES
411 /* Extract level 2 index */
412 rlwinm r10, r10, 32 - (PAGE_SHIFT_8M - PAGE_SHIFT), 32 + PAGE_SHIFT_8M - (PAGE_SHIFT << 1), 29
413 /* Add level 2 base */
414 rlwimi r10, r11, 0, 0, 32 + PAGE_SHIFT_8M - (PAGE_SHIFT << 1) - 1
415#else
416 /* Level 2 base */
417 rlwinm r10, r11, 0, ~HUGEPD_SHIFT_MASK
418#endif
419 lwz r10, 0(r10) /* Get the pte */
420 rlwinm r11, r11, 0, 0xf
421 b 4b
422
42320: /* 512k pages */
424 /* Extract level 2 index */
425 rlwinm r10, r10, 32 - (PAGE_SHIFT_512K - PAGE_SHIFT), 32 + PAGE_SHIFT_512K - (PAGE_SHIFT << 1), 29
426 /* Add level 2 base */
427 rlwimi r10, r11, 0, 0, 32 + PAGE_SHIFT_512K - (PAGE_SHIFT << 1) - 1
428 lwz r10, 0(r10) /* Get the pte */
429 rlwinm r11, r11, 0, 0xf
430 b 4b
431#endif
432
14cf11af
PM
433 . = 0x1200
434DataStoreTLBMiss:
36eb1542 435 mtspr SPRN_SPRG_SCRATCH2, r3
92625d49 436 EXCEPTION_PROLOG_0
75b82472
CL
437#ifdef CONFIG_PPC_8xx_PERF_EVENT
438 lis r10, (dtlb_miss_counter - PAGE_OFFSET)@ha
439 lwz r11, (dtlb_miss_counter - PAGE_OFFSET)@l(r10)
440 addi r11, r11, 1
441 stw r11, (dtlb_miss_counter - PAGE_OFFSET)@l(r10)
442#endif
36eb1542 443 mfcr r3
14cf11af
PM
444
445 /* If we are faulting a kernel address, we have to use the
446 * kernel page tables.
447 */
36eb1542
CL
448 mfspr r10, SPRN_MD_EPN
449 rlwinm r10, r10, 16, 0xfff8
450 cmpli cr0, r10, PAGE_OFFSET@h
451 mfspr r11, SPRN_M_TW /* Get level 1 table */
452 blt+ 3f
62f64b49 453#ifndef CONFIG_PIN_TLB_IMMR
36eb1542 454 cmpli cr0, r10, VIRT_IMMR_BASE@h
bb7f3808 455#endif
36eb1542
CL
456_ENTRY(DTLBMiss_cmp)
457 cmpli cr7, r10, (PAGE_OFFSET + 0x1800000)@h
458 lis r11, (swapper_pg_dir-PAGE_OFFSET)@ha
62f64b49 459#ifndef CONFIG_PIN_TLB_IMMR
4badd43a
CL
460_ENTRY(DTLBMiss_jmp)
461 beq- DTLBMissIMMR
462#endif
36eb1542 463 blt cr7, DTLBMissLinear
14cf11af 4643:
bb7f3808 465 mfspr r10, SPRN_MD_EPN
2eb2fd95 466
17bb312f
LC
467 /* Insert level 1 index */
468 rlwimi r11, r10, 32 - ((PAGE_SHIFT - 2) << 1), (PAGE_SHIFT - 2) << 1, 29
fde5a905 469 lwz r11, (swapper_pg_dir-PAGE_OFFSET)@l(r11) /* Get the level 1 entry */
14cf11af
PM
470
471 /* We have a pte table, so load fetch the pte from the table.
472 */
33fb845a 473 /* Extract level 2 index */
d1406803 474 rlwinm r10, r10, 32 - (PAGE_SHIFT - 2), 32 - PAGE_SHIFT, 29
4b914286
CL
475#ifdef CONFIG_HUGETLB_PAGE
476 mtcr r11
477 bt- 28, 10f /* bit 28 = Large page (8M) */
478 bt- 29, 20f /* bit 29 = Large page (8M or 512k) */
479#endif
d1406803 480 rlwimi r10, r11, 0, 0, 32 - PAGE_SHIFT - 1 /* Add level 2 base */
14cf11af 481 lwz r10, 0(r10) /* Get the pte */
4b914286
CL
4824:
483 mtcr r3
14cf11af 484
e0a8e0d9
LC
485 /* Insert the Guarded flag and APG into the TWC from the Linux PTE.
486 * It is bit 26-27 of both the Linux PTE and the TWC (at least
14cf11af
PM
487 * I got that right :-). It will be better when we can put
488 * this into the Linux pgd/pmd and load it in the operation
489 * above.
490 */
e0a8e0d9 491 rlwimi r11, r10, 0, 26, 27
0c466169
JT
492 /* Insert the WriteThru flag into the TWC from the Linux PTE.
493 * It is bit 25 in the Linux PTE and bit 30 in the TWC
494 */
495 rlwimi r11, r10, 32-5, 30, 30
d3e40262 496 MTSPR_CPU6(SPRN_MD_TWC, r11, r3)
14cf11af 497
4b914286
CL
498 /* In 4k pages mode, SPS (bit 28) in RPN must match PS[1] (bit 29)
499 * In 16k pages mode, SPS is always 1 */
500#if defined (CONFIG_HUGETLB_PAGE) && defined (CONFIG_PPC_4K_PAGES)
501 rlwimi r10, r11, 1, MD_SPS16K
502#endif
fe11dc3f
JT
503 /* Both _PAGE_ACCESSED and _PAGE_PRESENT has to be set.
504 * We also need to know if the insn is a load/store, so:
505 * Clear _PAGE_PRESENT and load that which will
506 * trap into DTLB Error with store bit set accordinly.
507 */
508 /* PRESENT=0x1, ACCESSED=0x20
509 * r11 = ((r10 & PRESENT) & ((r10 & ACCESSED) >> 5));
510 * r10 = (r10 & ~PRESENT) | r11;
511 */
d069cb43 512#ifdef CONFIG_SWAP
990d89c6 513 rlwinm r11, r10, 32-5, _PAGE_PRESENT
fe11dc3f 514 and r11, r11, r10
990d89c6 515 rlwimi r10, r11, 0, _PAGE_PRESENT
d069cb43 516#endif
14cf11af 517 /* The Linux PTE won't go exactly into the MMU TLB.
fe11dc3f 518 * Software indicator bits 22 and 28 must be clear.
14cf11af
PM
519 * Software indicator bits 24, 25, 26, and 27 must be
520 * set. All other Linux PTE bits control the behavior
521 * of the MMU.
522 */
5ddb75ce 523 li r11, RPN_PATTERN
4b914286
CL
524#if defined (CONFIG_HUGETLB_PAGE) && defined (CONFIG_PPC_4K_PAGES)
525 rlwimi r10, r11, 0, 24, 27 /* Set 24-27 */
526#else
14cf11af 527 rlwimi r10, r11, 0, 24, 28 /* Set 24-27, clear 28 */
4b914286 528#endif
5b2753fc 529 rlwimi r10, r11, 0, 20, 20 /* clear 20 */
d3e40262 530 MTSPR_CPU6(SPRN_MD_RPN, r10, r3) /* Update TLB entry */
14cf11af 531
469d62be 532 /* Restore registers */
b821c5fe 533 mfspr r3, SPRN_SPRG_SCRATCH2
92625d49 534 mtspr SPRN_DAR, r11 /* Tag DAR */
92625d49 535 EXCEPTION_EPILOG_0
14cf11af
PM
536 rfi
537
4b914286
CL
538#ifdef CONFIG_HUGETLB_PAGE
53910: /* 8M pages */
540 /* Extract level 2 index */
541#ifdef CONFIG_PPC_16K_PAGES
542 rlwinm r10, r10, 32 - (PAGE_SHIFT_8M - PAGE_SHIFT), 32 + PAGE_SHIFT_8M - (PAGE_SHIFT << 1), 29
543 /* Add level 2 base */
544 rlwimi r10, r11, 0, 0, 32 + PAGE_SHIFT_8M - (PAGE_SHIFT << 1) - 1
545#else
546 /* Level 2 base */
547 rlwinm r10, r11, 0, ~HUGEPD_SHIFT_MASK
548#endif
549 lwz r10, 0(r10) /* Get the pte */
550 rlwinm r11, r11, 0, 0xf
551 b 4b
552
55320: /* 512k pages */
554 /* Extract level 2 index */
555 rlwinm r10, r10, 32 - (PAGE_SHIFT_512K - PAGE_SHIFT), 32 + PAGE_SHIFT_512K - (PAGE_SHIFT << 1), 29
556 /* Add level 2 base */
557 rlwimi r10, r11, 0, 0, 32 + PAGE_SHIFT_512K - (PAGE_SHIFT << 1) - 1
558 lwz r10, 0(r10) /* Get the pte */
559 rlwinm r11, r11, 0, 0xf
560 b 4b
561#endif
a372acfa 562
14cf11af
PM
563/* This is an instruction TLB error on the MPC8xx. This could be due
564 * to many reasons, such as executing guarded memory or illegal instruction
565 * addresses. There is nothing to do but handle a big time error fault.
566 */
567 . = 0x1300
568InstructionTLBError:
5ddb75ce 569 EXCEPTION_PROLOG
7439b37e 570 mr r4,r12
b4c001dc
BH
571 andis. r5,r9,DSISR_SRR1_MATCH_32S@h /* Filter relevant SRR1 bits */
572 andis. r10,r9,SRR1_ISI_NOPT@h
c51a6821
LC
573 beq+ 1f
574 tlbie r4
4ad8622d 575itlbie:
7439b37e 576 /* 0x400 is InstructionAccess exception, needed by bad_page_fault() */
c51a6821 5771: EXC_XFER_LITE(0x400, handle_page_fault)
14cf11af
PM
578
579/* This is the data TLB error on the MPC8xx. This could be due to
140a6a60
LC
580 * many reasons, including a dirty update to a pte. We bail out to
581 * a higher level function that can handle it.
14cf11af
PM
582 */
583 . = 0x1400
584DataTLBError:
92625d49 585 EXCEPTION_PROLOG_0
d5fd9d7d 586 mfcr r10
14cf11af 587
5bcbe24f 588 mfspr r11, SPRN_DAR
ac21951f 589 cmpwi cr0, r11, RPN_PATTERN
0a2ab51f 590 beq- FixupDAR /* must be a buggy dcbX, icbi insn. */
3e436403 591DARFixed:/* Return from dcbx instruction bug workaround */
6cde2b6f
LC
592 EXCEPTION_PROLOG_1
593 EXCEPTION_PROLOG_2
c51a6821
LC
594 mfspr r5,SPRN_DSISR
595 stw r5,_DSISR(r11)
749137a2 596 mfspr r4,SPRN_DAR
4915349b 597 andis. r10,r5,DSISR_NOHPTE@h
c51a6821
LC
598 beq+ 1f
599 tlbie r4
4ad8622d 600dtlbie:
c51a6821 6011: li r10,RPN_PATTERN
749137a2
LC
602 mtspr SPRN_DAR,r10 /* Tag DAR, to be used in DTLB Error */
603 /* 0x300 is DataAccess exception, needed by bad_page_fault() */
604 EXC_XFER_LITE(0x300, handle_page_fault)
14cf11af 605
dc1c1ca3
SR
606 EXCEPTION(0x1500, Trap_15, unknown_exception, EXC_XFER_EE)
607 EXCEPTION(0x1600, Trap_16, unknown_exception, EXC_XFER_EE)
608 EXCEPTION(0x1700, Trap_17, unknown_exception, EXC_XFER_EE)
609 EXCEPTION(0x1800, Trap_18, unknown_exception, EXC_XFER_EE)
610 EXCEPTION(0x1900, Trap_19, unknown_exception, EXC_XFER_EE)
611 EXCEPTION(0x1a00, Trap_1a, unknown_exception, EXC_XFER_EE)
612 EXCEPTION(0x1b00, Trap_1b, unknown_exception, EXC_XFER_EE)
14cf11af
PM
613
614/* On the MPC8xx, these next four traps are used for development
615 * support of breakpoints and such. Someday I will get around to
616 * using them.
617 */
4ad8622d
CL
618 . = 0x1c00
619DataBreakpoint:
620 EXCEPTION_PROLOG_0
621 mfcr r10
622 mfspr r11, SPRN_SRR0
623 cmplwi cr0, r11, (dtlbie - PAGE_OFFSET)@l
624 cmplwi cr7, r11, (itlbie - PAGE_OFFSET)@l
625 beq- cr0, 11f
626 beq- cr7, 11f
627 EXCEPTION_PROLOG_1
628 EXCEPTION_PROLOG_2
629 addi r3,r1,STACK_FRAME_OVERHEAD
630 mfspr r4,SPRN_BAR
631 stw r4,_DAR(r11)
632 mfspr r5,SPRN_DSISR
633 EXC_XFER_EE(0x1c00, do_break)
63411:
635 mtcr r10
636 EXCEPTION_EPILOG_0
637 rfi
638
75b82472
CL
639#ifdef CONFIG_PPC_8xx_PERF_EVENT
640 . = 0x1d00
641InstructionBreakpoint:
642 EXCEPTION_PROLOG_0
643 lis r10, (instruction_counter - PAGE_OFFSET)@ha
644 lwz r11, (instruction_counter - PAGE_OFFSET)@l(r10)
645 addi r11, r11, -1
646 stw r11, (instruction_counter - PAGE_OFFSET)@l(r10)
647 lis r10, 0xffff
648 ori r10, r10, 0x01
649 mtspr SPRN_COUNTA, r10
650 EXCEPTION_EPILOG_0
651 rfi
652#else
dc1c1ca3 653 EXCEPTION(0x1d00, Trap_1d, unknown_exception, EXC_XFER_EE)
75b82472 654#endif
dc1c1ca3
SR
655 EXCEPTION(0x1e00, Trap_1e, unknown_exception, EXC_XFER_EE)
656 EXCEPTION(0x1f00, Trap_1f, unknown_exception, EXC_XFER_EE)
14cf11af
PM
657
658 . = 0x2000
659
73a53206
CL
660/*
661 * Bottom part of DataStoreTLBMiss handlers for IMMR area and linear RAM.
662 * not enough space in the DataStoreTLBMiss area.
663 */
664DTLBMissIMMR:
36eb1542 665 mtcr r3
73a53206
CL
666 /* Set 512k byte guarded page and mark it valid */
667 li r10, MD_PS512K | MD_GUARDED | MD_SVALID
668 MTSPR_CPU6(SPRN_MD_TWC, r10, r11)
669 mfspr r10, SPRN_IMMR /* Get current IMMR */
670 rlwinm r10, r10, 0, 0xfff80000 /* Get 512 kbytes boundary */
671 ori r10, r10, 0xf0 | MD_SPS16K | _PAGE_SHARED | _PAGE_DIRTY | \
672 _PAGE_PRESENT | _PAGE_NO_CACHE
673 MTSPR_CPU6(SPRN_MD_RPN, r10, r11) /* Update TLB entry */
674
675 li r11, RPN_PATTERN
676 mtspr SPRN_DAR, r11 /* Tag DAR */
36eb1542 677 mfspr r3, SPRN_SPRG_SCRATCH2
73a53206
CL
678 EXCEPTION_EPILOG_0
679 rfi
680
681DTLBMissLinear:
36eb1542 682 mtcr r3
73a53206 683 /* Set 8M byte page and mark it valid */
36eb1542
CL
684 li r11, MD_PS8MEG | MD_SVALID
685 MTSPR_CPU6(SPRN_MD_TWC, r11, r3)
686 rlwinm r10, r10, 16, 0x0f800000 /* 8xx supports max 256Mb RAM */
73a53206
CL
687 ori r10, r10, 0xf0 | MD_SPS16K | _PAGE_SHARED | _PAGE_DIRTY | \
688 _PAGE_PRESENT
689 MTSPR_CPU6(SPRN_MD_RPN, r10, r11) /* Update TLB entry */
690
691 li r11, RPN_PATTERN
692 mtspr SPRN_DAR, r11 /* Tag DAR */
36eb1542 693 mfspr r3, SPRN_SPRG_SCRATCH2
73a53206
CL
694 EXCEPTION_EPILOG_0
695 rfi
696
0a2ab51f
JT
697/* This is the procedure to calculate the data EA for buggy dcbx,dcbi instructions
698 * by decoding the registers used by the dcbx instruction and adding them.
3e436403 699 * DAR is set to the calculated address.
0a2ab51f
JT
700 */
701 /* define if you don't want to use self modifying code */
702#define NO_SELF_MODIFYING_CODE
703FixupDAR:/* Entry point for dcbx workaround. */
5bcbe24f 704 mtspr SPRN_SPRG_SCRATCH2, r10
0a2ab51f
JT
705 /* fetch instruction from memory. */
706 mfspr r10, SPRN_SRR0
eeba1f7c 707 IS_KERNEL(r11, r10)
fde5a905 708 mfspr r11, SPRN_M_TW /* Get level 1 table */
eeba1f7c 709 BRANCH_UNLESS_KERNEL(3f)
bb7f3808
CL
710 rlwinm r11, r10, 16, 0xfff8
711_ENTRY(FixupDAR_cmp)
4ad27450 712 cmpli cr7, r11, (PAGE_OFFSET + 0x1800000)@h
36eb1542
CL
713 /* create physical page address from effective address */
714 tophys(r11, r10)
715 blt- cr7, 201f
fde5a905 716 lis r11, (swapper_pg_dir-PAGE_OFFSET)@ha
17bb312f
LC
717 /* Insert level 1 index */
7183: rlwimi r11, r10, 32 - ((PAGE_SHIFT - 2) << 1), (PAGE_SHIFT - 2) << 1, 29
fde5a905 719 lwz r11, (swapper_pg_dir-PAGE_OFFSET)@l(r11) /* Get the level 1 entry */
4b914286
CL
720 mtcr r11
721 bt 28,200f /* bit 28 = Large page (8M) */
722 bt 29,202f /* bit 29 = Large page (8M or 512K) */
17bb312f
LC
723 rlwinm r11, r11,0,0,19 /* Extract page descriptor page address */
724 /* Insert level 2 index */
725 rlwimi r11, r10, 32 - (PAGE_SHIFT - 2), 32 - PAGE_SHIFT, 29
726 lwz r11, 0(r11) /* Get the pte */
0a2ab51f 727 /* concat physical page address(r11) and page offset(r10) */
d1406803 728 rlwimi r11, r10, 0, 32 - PAGE_SHIFT, 31
a372acfa 729201: lwz r11,0(r11)
0a2ab51f
JT
730/* Check if it really is a dcbx instruction. */
731/* dcbt and dcbtst does not generate DTLB Misses/Errors,
732 * no need to include them here */
41cacac6
LC
733 xoris r10, r11, 0x7c00 /* check if major OP code is 31 */
734 rlwinm r10, r10, 0, 21, 5
0a2ab51f
JT
735 cmpwi cr0, r10, 2028 /* Is dcbz? */
736 beq+ 142f
737 cmpwi cr0, r10, 940 /* Is dcbi? */
738 beq+ 142f
739 cmpwi cr0, r10, 108 /* Is dcbst? */
740 beq+ 144f /* Fix up store bit! */
741 cmpwi cr0, r10, 172 /* Is dcbf? */
742 beq+ 142f
743 cmpwi cr0, r10, 1964 /* Is icbi? */
744 beq+ 142f
5bcbe24f
LC
745141: mfspr r10,SPRN_SPRG_SCRATCH2
746 b DARFixed /* Nope, go back to normal TLB processing */
0a2ab51f 747
4b914286
CL
748 /* concat physical page address(r11) and page offset(r10) */
749200:
750#ifdef CONFIG_PPC_16K_PAGES
751 rlwinm r11, r11, 0, 0, 32 + PAGE_SHIFT_8M - (PAGE_SHIFT << 1) - 1
752 rlwimi r11, r10, 32 - (PAGE_SHIFT_8M - 2), 32 + PAGE_SHIFT_8M - (PAGE_SHIFT << 1), 29
753#else
754 rlwinm r11, r10, 0, ~HUGEPD_SHIFT_MASK
755#endif
756 lwz r11, 0(r11) /* Get the pte */
757 /* concat physical page address(r11) and page offset(r10) */
758 rlwimi r11, r10, 0, 32 - PAGE_SHIFT_8M, 31
759 b 201b
760
761202:
762 rlwinm r11, r11, 0, 0, 32 + PAGE_SHIFT_512K - (PAGE_SHIFT << 1) - 1
763 rlwimi r11, r10, 32 - (PAGE_SHIFT_512K - 2), 32 + PAGE_SHIFT_512K - (PAGE_SHIFT << 1), 29
764 lwz r11, 0(r11) /* Get the pte */
765 /* concat physical page address(r11) and page offset(r10) */
766 rlwimi r11, r10, 0, 32 - PAGE_SHIFT_512K, 31
767 b 201b
768
0a2ab51f
JT
769144: mfspr r10, SPRN_DSISR
770 rlwinm r10, r10,0,7,5 /* Clear store bit for buggy dcbst insn */
771 mtspr SPRN_DSISR, r10
772142: /* continue, it was a dcbx, dcbi instruction. */
0a2ab51f
JT
773#ifndef NO_SELF_MODIFYING_CODE
774 andis. r10,r11,0x1f /* test if reg RA is r0 */
775 li r10,modified_instr@l
776 dcbtst r0,r10 /* touch for store */
777 rlwinm r11,r11,0,0,20 /* Zero lower 10 bits */
778 oris r11,r11,640 /* Transform instr. to a "add r10,RA,RB" */
779 ori r11,r11,532
780 stw r11,0(r10) /* store add/and instruction */
781 dcbf 0,r10 /* flush new instr. to memory. */
782 icbi 0,r10 /* invalidate instr. cache line */
92625d49
LC
783 mfspr r11, SPRN_SPRG_SCRATCH1 /* restore r11 */
784 mfspr r10, SPRN_SPRG_SCRATCH0 /* restore r10 */
0a2ab51f
JT
785 isync /* Wait until new instr is loaded from memory */
786modified_instr:
787 .space 4 /* this is where the add instr. is stored */
788 bne+ 143f
789 subf r10,r0,r10 /* r10=r10-r0, only if reg RA is r0 */
790143: mtdar r10 /* store faulting EA in DAR */
5bcbe24f 791 mfspr r10,SPRN_SPRG_SCRATCH2
0a2ab51f
JT
792 b DARFixed /* Go back to normal TLB handling */
793#else
794 mfctr r10
795 mtdar r10 /* save ctr reg in DAR */
796 rlwinm r10, r11, 24, 24, 28 /* offset into jump table for reg RB */
797 addi r10, r10, 150f@l /* add start of table */
798 mtctr r10 /* load ctr with jump address */
799 xor r10, r10, r10 /* sum starts at zero */
800 bctr /* jump into table */
801150:
802 add r10, r10, r0 ;b 151f
803 add r10, r10, r1 ;b 151f
804 add r10, r10, r2 ;b 151f
805 add r10, r10, r3 ;b 151f
806 add r10, r10, r4 ;b 151f
807 add r10, r10, r5 ;b 151f
808 add r10, r10, r6 ;b 151f
809 add r10, r10, r7 ;b 151f
810 add r10, r10, r8 ;b 151f
811 add r10, r10, r9 ;b 151f
812 mtctr r11 ;b 154f /* r10 needs special handling */
813 mtctr r11 ;b 153f /* r11 needs special handling */
814 add r10, r10, r12 ;b 151f
815 add r10, r10, r13 ;b 151f
816 add r10, r10, r14 ;b 151f
817 add r10, r10, r15 ;b 151f
818 add r10, r10, r16 ;b 151f
819 add r10, r10, r17 ;b 151f
820 add r10, r10, r18 ;b 151f
821 add r10, r10, r19 ;b 151f
822 add r10, r10, r20 ;b 151f
823 add r10, r10, r21 ;b 151f
824 add r10, r10, r22 ;b 151f
825 add r10, r10, r23 ;b 151f
826 add r10, r10, r24 ;b 151f
827 add r10, r10, r25 ;b 151f
828 add r10, r10, r26 ;b 151f
829 add r10, r10, r27 ;b 151f
830 add r10, r10, r28 ;b 151f
831 add r10, r10, r29 ;b 151f
832 add r10, r10, r30 ;b 151f
833 add r10, r10, r31
834151:
835 rlwinm. r11,r11,19,24,28 /* offset into jump table for reg RA */
836 beq 152f /* if reg RA is zero, don't add it */
837 addi r11, r11, 150b@l /* add start of table */
838 mtctr r11 /* load ctr with jump address */
839 rlwinm r11,r11,0,16,10 /* make sure we don't execute this more than once */
840 bctr /* jump into table */
841152:
842 mfdar r11
843 mtctr r11 /* restore ctr reg from DAR */
844 mtdar r10 /* save fault EA to DAR */
5bcbe24f 845 mfspr r10,SPRN_SPRG_SCRATCH2
0a2ab51f
JT
846 b DARFixed /* Go back to normal TLB handling */
847
848 /* special handling for r10,r11 since these are modified already */
92625d49 849153: mfspr r11, SPRN_SPRG_SCRATCH1 /* load r11 from SPRN_SPRG_SCRATCH1 */
111e32b2
LC
850 add r10, r10, r11 /* add it */
851 mfctr r11 /* restore r11 */
852 b 151b
92625d49 853154: mfspr r11, SPRN_SPRG_SCRATCH0 /* load r10 from SPRN_SPRG_SCRATCH0 */
111e32b2 854 add r10, r10, r11 /* add it */
0a2ab51f
JT
855 mfctr r11 /* restore r11 */
856 b 151b
857#endif
858
14cf11af
PM
859/*
860 * This is where the main kernel code starts.
861 */
862start_here:
863 /* ptr to current */
864 lis r2,init_task@h
865 ori r2,r2,init_task@l
866
867 /* ptr to phys current thread */
868 tophys(r4,r2)
869 addi r4,r4,THREAD /* init task's THREAD */
ee43eb78 870 mtspr SPRN_SPRG_THREAD,r4
14cf11af
PM
871
872 /* stack */
873 lis r1,init_thread_union@ha
874 addi r1,r1,init_thread_union@l
875 li r0,0
876 stwu r0,THREAD_SIZE-STACK_FRAME_OVERHEAD(r1)
877
878 bl early_init /* We have to do this with MMU on */
879
880/*
881 * Decide what sort of machine this is and initialize the MMU.
882 */
6dece0eb
SW
883 li r3,0
884 mr r4,r31
14cf11af
PM
885 bl machine_init
886 bl MMU_init
887
888/*
889 * Go back to running unmapped so we can load up new values
890 * and change to using our exception vectors.
891 * On the 8xx, all we have to do is invalidate the TLB to clear
892 * the old 8M byte TLB mappings and load the page table base register.
893 */
894 /* The right way to do this would be to track it down through
895 * init's THREAD like the context switch code does, but this is
896 * easier......until someone changes init's static structures.
897 */
fde5a905 898 lis r6, swapper_pg_dir@ha
14cf11af
PM
899 tophys(r6,r6)
900#ifdef CONFIG_8xx_CPU6
901 lis r4, cpu6_errata_word@h
902 ori r4, r4, cpu6_errata_word@l
cbc130f1 903 li r3, 0x3f80
14cf11af
PM
904 stw r3, 12(r4)
905 lwz r3, 12(r4)
906#endif
cbc130f1 907 mtspr SPRN_M_TW, r6
14cf11af
PM
908 lis r4,2f@h
909 ori r4,r4,2f@l
910 tophys(r4,r4)
911 li r3,MSR_KERNEL & ~(MSR_IR|MSR_DR)
912 mtspr SPRN_SRR0,r4
913 mtspr SPRN_SRR1,r3
914 rfi
915/* Load up the kernel context */
9162:
14cf11af
PM
917 tlbia /* Clear all TLB entries */
918 sync /* wait for tlbia/tlbie to finish */
14cf11af
PM
919
920 /* set up the PTE pointers for the Abatron bdiGDB.
921 */
922 tovirt(r6,r6)
923 lis r5, abatron_pteptrs@h
924 ori r5, r5, abatron_pteptrs@l
925 stw r5, 0xf0(r0) /* Must match your Abatron config file */
926 tophys(r5,r5)
927 stw r6, 0(r5)
928
929/* Now turn on the MMU for real! */
930 li r4,MSR_KERNEL
931 lis r3,start_kernel@h
932 ori r3,r3,start_kernel@l
933 mtspr SPRN_SRR0,r3
934 mtspr SPRN_SRR1,r4
935 rfi /* enable MMU and jump to start_kernel */
936
937/* Set up the initial MMU state so we can do the first level of
938 * kernel initialization. This maps the first 8 MBytes of memory 1:1
939 * virtual to physical. Also, set the cache mode since that is defined
940 * by TLB entries and perform any additional mapping (like of the IMMR).
941 * If configured to pin some TLBs, we pin the first 8 Mbytes of kernel,
f86ef74e 942 * 24 Mbytes of data, and the 512k IMMR space. Anything not covered by
14cf11af
PM
943 * these mappings is mapped by page tables.
944 */
945initial_mmu:
6264dbb9
CL
946 li r8, 0
947 mtspr SPRN_MI_CTR, r8 /* remove PINNED ITLB entries */
948 lis r10, MD_RESETVAL@h
949#ifndef CONFIG_8xx_COPYBACK
950 oris r10, r10, MD_WTDEF@h
951#endif
952 mtspr SPRN_MD_CTR, r10 /* remove PINNED DTLB entries */
953
14cf11af 954 tlbia /* Invalidate all TLB entries */
9f4f04ba
JT
955/* Always pin the first 8 MB ITLB to prevent ITLB
956 misses while mucking around with SRR0/SRR1 in asm
957*/
14cf11af
PM
958 lis r8, MI_RSV4I@h
959 ori r8, r8, 0x1c00
9f4f04ba 960
14cf11af
PM
961 mtspr SPRN_MI_CTR, r8 /* Set instruction MMU control */
962
963#ifdef CONFIG_PIN_TLB
6264dbb9 964 oris r10, r10, MD_RSV4I@h
14cf11af 965 mtspr SPRN_MD_CTR, r10 /* Set data TLB control */
6264dbb9 966#endif
14cf11af 967
4ad27450 968 /* Now map the lower 8 Meg into the ITLB. */
14cf11af
PM
969 lis r8, KERNELBASE@h /* Create vaddr for TLB */
970 ori r8, r8, MI_EVALID /* Mark it valid */
971 mtspr SPRN_MI_EPN, r8
5b2753fc 972 li r8, MI_PS8MEG | (2 << 5) /* Set 8M byte page, APG 2 */
14cf11af
PM
973 ori r8, r8, MI_SVALID /* Make it valid */
974 mtspr SPRN_MI_TWC, r8
14cf11af
PM
975 li r8, MI_BOOTINIT /* Create RPN for address 0 */
976 mtspr SPRN_MI_RPN, r8 /* Store TLB entry */
4ad27450 977
5b2753fc
LC
978 lis r8, MI_APG_INIT@h /* Set protection modes */
979 ori r8, r8, MI_APG_INIT@l
14cf11af 980 mtspr SPRN_MI_AP, r8
5b2753fc
LC
981 lis r8, MD_APG_INIT@h
982 ori r8, r8, MD_APG_INIT@l
14cf11af
PM
983 mtspr SPRN_MD_AP, r8
984
f86ef74e 985 /* Map a 512k page for the IMMR to get the processor
14cf11af
PM
986 * internal registers (among other things).
987 */
62f64b49
CL
988#ifdef CONFIG_PIN_TLB_IMMR
989 ori r10, r10, 0x1c00
990 mtspr SPRN_MD_CTR, r10
991
14cf11af 992 mfspr r9, 638 /* Get current IMMR */
f86ef74e 993 andis. r9, r9, 0xfff8 /* Get 512 kbytes boundary */
14cf11af 994
f86ef74e 995 lis r8, VIRT_IMMR_BASE@h /* Create vaddr for TLB */
14cf11af
PM
996 ori r8, r8, MD_EVALID /* Mark it valid */
997 mtspr SPRN_MD_EPN, r8
f86ef74e 998 li r8, MD_PS512K | MD_GUARDED /* Set 512k byte page */
14cf11af
PM
999 ori r8, r8, MD_SVALID /* Make it valid */
1000 mtspr SPRN_MD_TWC, r8
1001 mr r8, r9 /* Create paddr for TLB */
1002 ori r8, r8, MI_BOOTINIT|0x2 /* Inhibit cache -- Cort */
1003 mtspr SPRN_MD_RPN, r8
14cf11af
PM
1004#endif
1005
1006 /* Since the cache is enabled according to the information we
1007 * just loaded into the TLB, invalidate and enable the caches here.
1008 * We should probably check/set other modes....later.
1009 */
1010 lis r8, IDC_INVALL@h
1011 mtspr SPRN_IC_CST, r8
1012 mtspr SPRN_DC_CST, r8
1013 lis r8, IDC_ENABLE@h
1014 mtspr SPRN_IC_CST, r8
1015#ifdef CONFIG_8xx_COPYBACK
1016 mtspr SPRN_DC_CST, r8
1017#else
1018 /* For a debug option, I left this here to easily enable
1019 * the write through cache mode
1020 */
1021 lis r8, DC_SFWT@h
1022 mtspr SPRN_DC_CST, r8
1023 lis r8, IDC_ENABLE@h
1024 mtspr SPRN_DC_CST, r8
1025#endif
75b82472 1026 /* Disable debug mode entry on breakpoints */
4ad8622d 1027 mfspr r8, SPRN_DER
75b82472
CL
1028#ifdef CONFIG_PPC_8xx_PERF_EVENT
1029 rlwinm r8, r8, 0, ~0xc
1030#else
4ad8622d 1031 rlwinm r8, r8, 0, ~0x8
75b82472 1032#endif
4ad8622d 1033 mtspr SPRN_DER, r8
14cf11af
PM
1034 blr
1035
1036
14cf11af
PM
1037/*
1038 * We put a few things here that have to be page-aligned.
1039 * This stuff goes at the beginning of the data segment,
1040 * which is page-aligned.
1041 */
1042 .data
1043 .globl sdata
1044sdata:
1045 .globl empty_zero_page
d1406803 1046 .align PAGE_SHIFT
14cf11af 1047empty_zero_page:
d1406803 1048 .space PAGE_SIZE
9445aa1a 1049EXPORT_SYMBOL(empty_zero_page)
14cf11af
PM
1050
1051 .globl swapper_pg_dir
1052swapper_pg_dir:
d1406803 1053 .space PGD_TABLE_SIZE
14cf11af 1054
14cf11af
PM
1055/* Room for two PTE table poiners, usually the kernel and current user
1056 * pointer to their respective root page table (pgdir).
1057 */
1058abatron_pteptrs:
1059 .space 8
1060
1061#ifdef CONFIG_8xx_CPU6
1062 .globl cpu6_errata_word
1063cpu6_errata_word:
1064 .space 16
1065#endif
1066
75b82472
CL
1067#ifdef CONFIG_PPC_8xx_PERF_EVENT
1068 .globl itlb_miss_counter
1069itlb_miss_counter:
1070 .space 4
1071
1072 .globl dtlb_miss_counter
1073dtlb_miss_counter:
1074 .space 4
1075
1076 .globl instruction_counter
1077instruction_counter:
1078 .space 4
1079#endif