aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@g5.osdl.org>2005-10-06 17:16:07 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2005-10-06 17:16:07 -0400
commitdce32c781b1c026863a254fe8123dd78c59ad984 (patch)
tree9714c0629b036e9844d6c394d3373f1462eed8b7 /arch
parentc0758146adbe39514e75ac860ce7e49f865c2297 (diff)
parent9ad98c5b4461e7dfa3754963200993a68825eab4 (diff)
Merge master.kernel.org:/pub/scm/linux/kernel/git/davem/sparc-2.6
Diffstat (limited to 'arch')
-rw-r--r--arch/sparc/Kconfig56
-rw-r--r--arch/sparc64/kernel/entry.S43
-rw-r--r--arch/sparc64/kernel/etrap.S51
-rw-r--r--arch/sparc64/kernel/head.S33
-rw-r--r--arch/sparc64/kernel/rtrap.S23
-rw-r--r--arch/sparc64/kernel/setup.c8
-rw-r--r--arch/sparc64/kernel/trampoline.S15
-rw-r--r--arch/sparc64/kernel/winfixup.S33
-rw-r--r--arch/sparc64/mm/init.c182
9 files changed, 103 insertions, 341 deletions
diff --git a/arch/sparc/Kconfig b/arch/sparc/Kconfig
index aba05394d30a..6537445dac0e 100644
--- a/arch/sparc/Kconfig
+++ b/arch/sparc/Kconfig
@@ -25,62 +25,6 @@ source "init/Kconfig"
25 25
26menu "General machine setup" 26menu "General machine setup"
27 27
28config VT
29 bool
30 select INPUT
31 default y
32 ---help---
33 If you say Y here, you will get support for terminal devices with
34 display and keyboard devices. These are called "virtual" because you
35 can run several virtual terminals (also called virtual consoles) on
36 one physical terminal. This is rather useful, for example one
37 virtual terminal can collect system messages and warnings, another
38 one can be used for a text-mode user session, and a third could run
39 an X session, all in parallel. Switching between virtual terminals
40 is done with certain key combinations, usually Alt-<function key>.
41
42 The setterm command ("man setterm") can be used to change the
43 properties (such as colors or beeping) of a virtual terminal. The
44 man page console_codes(4) ("man console_codes") contains the special
45 character sequences that can be used to change those properties
46 directly. The fonts used on virtual terminals can be changed with
47 the setfont ("man setfont") command and the key bindings are defined
48 with the loadkeys ("man loadkeys") command.
49
50 You need at least one virtual terminal device in order to make use
51 of your keyboard and monitor. Therefore, only people configuring an
52 embedded system would want to say N here in order to save some
53 memory; the only way to log into such a system is then via a serial
54 or network connection.
55
56 If unsure, say Y, or else you won't be able to do much with your new
57 shiny Linux system :-)
58
59config VT_CONSOLE
60 bool
61 default y
62 ---help---
63 The system console is the device which receives all kernel messages
64 and warnings and which allows logins in single user mode. If you
65 answer Y here, a virtual terminal (the device used to interact with
66 a physical terminal) can be used as system console. This is the most
67 common mode of operations, so you should say Y here unless you want
68 the kernel messages be output only to a serial port (in which case
69 you should say Y to "Console on serial port", below).
70
71 If you do say Y here, by default the currently visible virtual
72 terminal (/dev/tty0) will be used as system console. You can change
73 that with a kernel command line option such as "console=tty3" which
74 would use the third virtual terminal as system console. (Try "man
75 bootparam" or see the documentation of your boot loader (lilo or
76 loadlin) about how to pass options to the kernel at boot time.)
77
78 If unsure, say Y.
79
80config HW_CONSOLE
81 bool
82 default y
83
84config SMP 28config SMP
85 bool "Symmetric multi-processing support (does not work on sun4/sun4c)" 29 bool "Symmetric multi-processing support (does not work on sun4/sun4c)"
86 depends on BROKEN 30 depends on BROKEN
diff --git a/arch/sparc64/kernel/entry.S b/arch/sparc64/kernel/entry.S
index 2879b1072921..f685035dbdb8 100644
--- a/arch/sparc64/kernel/entry.S
+++ b/arch/sparc64/kernel/entry.S
@@ -97,8 +97,8 @@ do_fpdis:
97 faddd %f0, %f2, %f4 97 faddd %f0, %f2, %f4
98 fmuld %f0, %f2, %f6 98 fmuld %f0, %f2, %f6
99 ldxa [%g3] ASI_DMMU, %g5 99 ldxa [%g3] ASI_DMMU, %g5
100cplus_fptrap_insn_1: 100 sethi %hi(sparc64_kern_sec_context), %g2
101 sethi %hi(0), %g2 101 ldx [%g2 + %lo(sparc64_kern_sec_context)], %g2
102 stxa %g2, [%g3] ASI_DMMU 102 stxa %g2, [%g3] ASI_DMMU
103 membar #Sync 103 membar #Sync
104 add %g6, TI_FPREGS + 0xc0, %g2 104 add %g6, TI_FPREGS + 0xc0, %g2
@@ -126,8 +126,8 @@ cplus_fptrap_insn_1:
126 fzero %f34 126 fzero %f34
127 ldxa [%g3] ASI_DMMU, %g5 127 ldxa [%g3] ASI_DMMU, %g5
128 add %g6, TI_FPREGS, %g1 128 add %g6, TI_FPREGS, %g1
129cplus_fptrap_insn_2: 129 sethi %hi(sparc64_kern_sec_context), %g2
130 sethi %hi(0), %g2 130 ldx [%g2 + %lo(sparc64_kern_sec_context)], %g2
131 stxa %g2, [%g3] ASI_DMMU 131 stxa %g2, [%g3] ASI_DMMU
132 membar #Sync 132 membar #Sync
133 add %g6, TI_FPREGS + 0x40, %g2 133 add %g6, TI_FPREGS + 0x40, %g2
@@ -153,8 +153,8 @@ cplus_fptrap_insn_2:
1533: mov SECONDARY_CONTEXT, %g3 1533: mov SECONDARY_CONTEXT, %g3
154 add %g6, TI_FPREGS, %g1 154 add %g6, TI_FPREGS, %g1
155 ldxa [%g3] ASI_DMMU, %g5 155 ldxa [%g3] ASI_DMMU, %g5
156cplus_fptrap_insn_3: 156 sethi %hi(sparc64_kern_sec_context), %g2
157 sethi %hi(0), %g2 157 ldx [%g2 + %lo(sparc64_kern_sec_context)], %g2
158 stxa %g2, [%g3] ASI_DMMU 158 stxa %g2, [%g3] ASI_DMMU
159 membar #Sync 159 membar #Sync
160 mov 0x40, %g2 160 mov 0x40, %g2
@@ -319,8 +319,8 @@ do_fptrap_after_fsr:
319 stx %g3, [%g6 + TI_GSR] 319 stx %g3, [%g6 + TI_GSR]
320 mov SECONDARY_CONTEXT, %g3 320 mov SECONDARY_CONTEXT, %g3
321 ldxa [%g3] ASI_DMMU, %g5 321 ldxa [%g3] ASI_DMMU, %g5
322cplus_fptrap_insn_4: 322 sethi %hi(sparc64_kern_sec_context), %g2
323 sethi %hi(0), %g2 323 ldx [%g2 + %lo(sparc64_kern_sec_context)], %g2
324 stxa %g2, [%g3] ASI_DMMU 324 stxa %g2, [%g3] ASI_DMMU
325 membar #Sync 325 membar #Sync
326 add %g6, TI_FPREGS, %g2 326 add %g6, TI_FPREGS, %g2
@@ -341,33 +341,6 @@ cplus_fptrap_insn_4:
341 ba,pt %xcc, etrap 341 ba,pt %xcc, etrap
342 wr %g0, 0, %fprs 342 wr %g0, 0, %fprs
343 343
344cplus_fptrap_1:
345 sethi %hi(CTX_CHEETAH_PLUS_CTX0), %g2
346
347 .globl cheetah_plus_patch_fpdis
348cheetah_plus_patch_fpdis:
349 /* We configure the dTLB512_0 for 4MB pages and the
350 * dTLB512_1 for 8K pages when in context zero.
351 */
352 sethi %hi(cplus_fptrap_1), %o0
353 lduw [%o0 + %lo(cplus_fptrap_1)], %o1
354
355 set cplus_fptrap_insn_1, %o2
356 stw %o1, [%o2]
357 flush %o2
358 set cplus_fptrap_insn_2, %o2
359 stw %o1, [%o2]
360 flush %o2
361 set cplus_fptrap_insn_3, %o2
362 stw %o1, [%o2]
363 flush %o2
364 set cplus_fptrap_insn_4, %o2
365 stw %o1, [%o2]
366 flush %o2
367
368 retl
369 nop
370
371 /* The registers for cross calls will be: 344 /* The registers for cross calls will be:
372 * 345 *
373 * DATA 0: [low 32-bits] Address of function to call, jmp to this 346 * DATA 0: [low 32-bits] Address of function to call, jmp to this
diff --git a/arch/sparc64/kernel/etrap.S b/arch/sparc64/kernel/etrap.S
index 50d2af1d98ae..0d8eba21111b 100644
--- a/arch/sparc64/kernel/etrap.S
+++ b/arch/sparc64/kernel/etrap.S
@@ -68,12 +68,8 @@ etrap_irq:
68 68
69 wrpr %g3, 0, %otherwin 69 wrpr %g3, 0, %otherwin
70 wrpr %g2, 0, %wstate 70 wrpr %g2, 0, %wstate
71cplus_etrap_insn_1: 71 sethi %hi(sparc64_kern_pri_context), %g2
72 sethi %hi(0), %g3 72 ldx [%g2 + %lo(sparc64_kern_pri_context)], %g3
73 sllx %g3, 32, %g3
74cplus_etrap_insn_2:
75 sethi %hi(0), %g2
76 or %g3, %g2, %g3
77 stxa %g3, [%l4] ASI_DMMU 73 stxa %g3, [%l4] ASI_DMMU
78 flush %l6 74 flush %l6
79 wr %g0, ASI_AIUS, %asi 75 wr %g0, ASI_AIUS, %asi
@@ -215,12 +211,8 @@ scetrap: rdpr %pil, %g2
215 mov PRIMARY_CONTEXT, %l4 211 mov PRIMARY_CONTEXT, %l4
216 wrpr %g3, 0, %otherwin 212 wrpr %g3, 0, %otherwin
217 wrpr %g2, 0, %wstate 213 wrpr %g2, 0, %wstate
218cplus_etrap_insn_3: 214 sethi %hi(sparc64_kern_pri_context), %g2
219 sethi %hi(0), %g3 215 ldx [%g2 + %lo(sparc64_kern_pri_context)], %g3
220 sllx %g3, 32, %g3
221cplus_etrap_insn_4:
222 sethi %hi(0), %g2
223 or %g3, %g2, %g3
224 stxa %g3, [%l4] ASI_DMMU 216 stxa %g3, [%l4] ASI_DMMU
225 flush %l6 217 flush %l6
226 218
@@ -264,38 +256,3 @@ cplus_etrap_insn_4:
264 256
265#undef TASK_REGOFF 257#undef TASK_REGOFF
266#undef ETRAP_PSTATE1 258#undef ETRAP_PSTATE1
267
268cplus_einsn_1:
269 sethi %uhi(CTX_CHEETAH_PLUS_NUC), %g3
270cplus_einsn_2:
271 sethi %hi(CTX_CHEETAH_PLUS_CTX0), %g2
272
273 .globl cheetah_plus_patch_etrap
274cheetah_plus_patch_etrap:
275 /* We configure the dTLB512_0 for 4MB pages and the
276 * dTLB512_1 for 8K pages when in context zero.
277 */
278 sethi %hi(cplus_einsn_1), %o0
279 sethi %hi(cplus_etrap_insn_1), %o2
280 lduw [%o0 + %lo(cplus_einsn_1)], %o1
281 or %o2, %lo(cplus_etrap_insn_1), %o2
282 stw %o1, [%o2]
283 flush %o2
284 sethi %hi(cplus_etrap_insn_3), %o2
285 or %o2, %lo(cplus_etrap_insn_3), %o2
286 stw %o1, [%o2]
287 flush %o2
288
289 sethi %hi(cplus_einsn_2), %o0
290 sethi %hi(cplus_etrap_insn_2), %o2
291 lduw [%o0 + %lo(cplus_einsn_2)], %o1
292 or %o2, %lo(cplus_etrap_insn_2), %o2
293 stw %o1, [%o2]
294 flush %o2
295 sethi %hi(cplus_etrap_insn_4), %o2
296 or %o2, %lo(cplus_etrap_insn_4), %o2
297 stw %o1, [%o2]
298 flush %o2
299
300 retl
301 nop
diff --git a/arch/sparc64/kernel/head.S b/arch/sparc64/kernel/head.S
index 89406f9649a9..24340496cdd3 100644
--- a/arch/sparc64/kernel/head.S
+++ b/arch/sparc64/kernel/head.S
@@ -325,23 +325,7 @@ cheetah_tlb_fixup:
3251: sethi %hi(tlb_type), %g1 3251: sethi %hi(tlb_type), %g1
326 stw %g2, [%g1 + %lo(tlb_type)] 326 stw %g2, [%g1 + %lo(tlb_type)]
327 327
328 BRANCH_IF_CHEETAH_PLUS_OR_FOLLOWON(g1,g7,1f) 328 /* Patch copy/page operations to cheetah optimized versions. */
329 ba,pt %xcc, 2f
330 nop
331
3321: /* Patch context register writes to support nucleus page
333 * size correctly.
334 */
335 call cheetah_plus_patch_etrap
336 nop
337 call cheetah_plus_patch_rtrap
338 nop
339 call cheetah_plus_patch_fpdis
340 nop
341 call cheetah_plus_patch_winfixup
342 nop
343
3442: /* Patch copy/page operations to cheetah optimized versions. */
345 call cheetah_patch_copyops 329 call cheetah_patch_copyops
346 nop 330 nop
347 call cheetah_patch_copy_page 331 call cheetah_patch_copy_page
@@ -484,20 +468,13 @@ spitfire_vpte_base:
484 call prom_set_trap_table 468 call prom_set_trap_table
485 sethi %hi(sparc64_ttable_tl0), %o0 469 sethi %hi(sparc64_ttable_tl0), %o0
486 470
487 BRANCH_IF_CHEETAH_PLUS_OR_FOLLOWON(g2,g3,1f) 471 /* Start using proper page size encodings in ctx register. */
488 ba,pt %xcc, 2f 472 sethi %hi(sparc64_kern_pri_context), %g3
489 nop 473 ldx [%g3 + %lo(sparc64_kern_pri_context)], %g2
490
4911: /* Start using proper page size encodings in ctx register. */
492 sethi %uhi(CTX_CHEETAH_PLUS_NUC), %g3
493 mov PRIMARY_CONTEXT, %g1 474 mov PRIMARY_CONTEXT, %g1
494 sllx %g3, 32, %g3 475 stxa %g2, [%g1] ASI_DMMU
495 sethi %hi(CTX_CHEETAH_PLUS_CTX0), %g2
496 or %g3, %g2, %g3
497 stxa %g3, [%g1] ASI_DMMU
498 membar #Sync 476 membar #Sync
499 477
5002:
501 rdpr %pstate, %o1 478 rdpr %pstate, %o1
502 or %o1, PSTATE_IE, %o1 479 or %o1, PSTATE_IE, %o1
503 wrpr %o1, 0, %pstate 480 wrpr %o1, 0, %pstate
diff --git a/arch/sparc64/kernel/rtrap.S b/arch/sparc64/kernel/rtrap.S
index fafd227735fa..ecfb42a69a44 100644
--- a/arch/sparc64/kernel/rtrap.S
+++ b/arch/sparc64/kernel/rtrap.S
@@ -256,9 +256,8 @@ rt_continue: ldx [%sp + PTREGS_OFF + PT_V9_G1], %g1
256 brnz,pn %l3, kern_rtt 256 brnz,pn %l3, kern_rtt
257 mov PRIMARY_CONTEXT, %l7 257 mov PRIMARY_CONTEXT, %l7
258 ldxa [%l7 + %l7] ASI_DMMU, %l0 258 ldxa [%l7 + %l7] ASI_DMMU, %l0
259cplus_rtrap_insn_1: 259 sethi %hi(sparc64_kern_pri_nuc_bits), %l1
260 sethi %hi(0), %l1 260 ldx [%l1 + %lo(sparc64_kern_pri_nuc_bits)], %l1
261 sllx %l1, 32, %l1
262 or %l0, %l1, %l0 261 or %l0, %l1, %l0
263 stxa %l0, [%l7] ASI_DMMU 262 stxa %l0, [%l7] ASI_DMMU
264 flush %g6 263 flush %g6
@@ -345,21 +344,3 @@ kern_fpucheck: ldub [%g6 + TI_FPDEPTH], %l5
345 wr %g0, FPRS_DU, %fprs 344 wr %g0, FPRS_DU, %fprs
346 ba,pt %xcc, rt_continue 345 ba,pt %xcc, rt_continue
347 stb %l5, [%g6 + TI_FPDEPTH] 346 stb %l5, [%g6 + TI_FPDEPTH]
348
349cplus_rinsn_1:
350 sethi %uhi(CTX_CHEETAH_PLUS_NUC), %l1
351
352 .globl cheetah_plus_patch_rtrap
353cheetah_plus_patch_rtrap:
354 /* We configure the dTLB512_0 for 4MB pages and the
355 * dTLB512_1 for 8K pages when in context zero.
356 */
357 sethi %hi(cplus_rinsn_1), %o0
358 sethi %hi(cplus_rtrap_insn_1), %o2
359 lduw [%o0 + %lo(cplus_rinsn_1)], %o1
360 or %o2, %lo(cplus_rtrap_insn_1), %o2
361 stw %o1, [%o2]
362 flush %o2
363
364 retl
365 nop
diff --git a/arch/sparc64/kernel/setup.c b/arch/sparc64/kernel/setup.c
index 4c9c8f241748..c1f34237cdf2 100644
--- a/arch/sparc64/kernel/setup.c
+++ b/arch/sparc64/kernel/setup.c
@@ -187,17 +187,13 @@ int prom_callback(long *args)
187 } 187 }
188 188
189 if ((va >= KERNBASE) && (va < (KERNBASE + (4 * 1024 * 1024)))) { 189 if ((va >= KERNBASE) && (va < (KERNBASE + (4 * 1024 * 1024)))) {
190 unsigned long kernel_pctx = 0; 190 extern unsigned long sparc64_kern_pri_context;
191
192 if (tlb_type == cheetah_plus)
193 kernel_pctx |= (CTX_CHEETAH_PLUS_NUC |
194 CTX_CHEETAH_PLUS_CTX0);
195 191
196 /* Spitfire Errata #32 workaround */ 192 /* Spitfire Errata #32 workaround */
197 __asm__ __volatile__("stxa %0, [%1] %2\n\t" 193 __asm__ __volatile__("stxa %0, [%1] %2\n\t"
198 "flush %%g6" 194 "flush %%g6"
199 : /* No outputs */ 195 : /* No outputs */
200 : "r" (kernel_pctx), 196 : "r" (sparc64_kern_pri_context),
201 "r" (PRIMARY_CONTEXT), 197 "r" (PRIMARY_CONTEXT),
202 "i" (ASI_DMMU)); 198 "i" (ASI_DMMU));
203 199
diff --git a/arch/sparc64/kernel/trampoline.S b/arch/sparc64/kernel/trampoline.S
index 89f2fcfcd662..9478551cb020 100644
--- a/arch/sparc64/kernel/trampoline.S
+++ b/arch/sparc64/kernel/trampoline.S
@@ -336,20 +336,13 @@ do_unlock:
336 call init_irqwork_curcpu 336 call init_irqwork_curcpu
337 nop 337 nop
338 338
339 BRANCH_IF_CHEETAH_PLUS_OR_FOLLOWON(g2,g3,1f) 339 /* Start using proper page size encodings in ctx register. */
340 ba,pt %xcc, 2f 340 sethi %hi(sparc64_kern_pri_context), %g3
341 nop 341 ldx [%g3 + %lo(sparc64_kern_pri_context)], %g2
342
3431: /* Start using proper page size encodings in ctx register. */
344 sethi %uhi(CTX_CHEETAH_PLUS_NUC), %g3
345 mov PRIMARY_CONTEXT, %g1 342 mov PRIMARY_CONTEXT, %g1
346 sllx %g3, 32, %g3 343 stxa %g2, [%g1] ASI_DMMU
347 sethi %hi(CTX_CHEETAH_PLUS_CTX0), %g2
348 or %g3, %g2, %g3
349 stxa %g3, [%g1] ASI_DMMU
350 membar #Sync 344 membar #Sync
351 345
3522:
353 rdpr %pstate, %o1 346 rdpr %pstate, %o1
354 or %o1, PSTATE_IE, %o1 347 or %o1, PSTATE_IE, %o1
355 wrpr %o1, 0, %pstate 348 wrpr %o1, 0, %pstate
diff --git a/arch/sparc64/kernel/winfixup.S b/arch/sparc64/kernel/winfixup.S
index 99c809a1e5ac..39160926267b 100644
--- a/arch/sparc64/kernel/winfixup.S
+++ b/arch/sparc64/kernel/winfixup.S
@@ -16,23 +16,14 @@
16 .text 16 .text
17 17
18set_pcontext: 18set_pcontext:
19cplus_winfixup_insn_1: 19 sethi %hi(sparc64_kern_pri_context), %l1
20 sethi %hi(0), %l1 20 ldx [%l1 + %lo(sparc64_kern_pri_context)], %l1
21 mov PRIMARY_CONTEXT, %g1 21 mov PRIMARY_CONTEXT, %g1
22 sllx %l1, 32, %l1
23cplus_winfixup_insn_2:
24 sethi %hi(0), %g2
25 or %l1, %g2, %l1
26 stxa %l1, [%g1] ASI_DMMU 22 stxa %l1, [%g1] ASI_DMMU
27 flush %g6 23 flush %g6
28 retl 24 retl
29 nop 25 nop
30 26
31cplus_wfinsn_1:
32 sethi %uhi(CTX_CHEETAH_PLUS_NUC), %l1
33cplus_wfinsn_2:
34 sethi %hi(CTX_CHEETAH_PLUS_CTX0), %g2
35
36 .align 32 27 .align 32
37 28
38 /* Here are the rules, pay attention. 29 /* Here are the rules, pay attention.
@@ -395,23 +386,3 @@ window_dax_from_user_common:
395 add %sp, PTREGS_OFF, %o0 386 add %sp, PTREGS_OFF, %o0
396 ba,pt %xcc, rtrap 387 ba,pt %xcc, rtrap
397 clr %l6 388 clr %l6
398
399
400 .globl cheetah_plus_patch_winfixup
401cheetah_plus_patch_winfixup:
402 sethi %hi(cplus_wfinsn_1), %o0
403 sethi %hi(cplus_winfixup_insn_1), %o2
404 lduw [%o0 + %lo(cplus_wfinsn_1)], %o1
405 or %o2, %lo(cplus_winfixup_insn_1), %o2
406 stw %o1, [%o2]
407 flush %o2
408
409 sethi %hi(cplus_wfinsn_2), %o0
410 sethi %hi(cplus_winfixup_insn_2), %o2
411 lduw [%o0 + %lo(cplus_wfinsn_2)], %o1
412 or %o2, %lo(cplus_winfixup_insn_2), %o2
413 stw %o1, [%o2]
414 flush %o2
415
416 retl
417 nop
diff --git a/arch/sparc64/mm/init.c b/arch/sparc64/mm/init.c
index 5db50524f20d..0d2e967c7200 100644
--- a/arch/sparc64/mm/init.c
+++ b/arch/sparc64/mm/init.c
@@ -133,6 +133,12 @@ extern unsigned int sparc_ramdisk_size;
133 133
134struct page *mem_map_zero __read_mostly; 134struct page *mem_map_zero __read_mostly;
135 135
136unsigned int sparc64_highest_unlocked_tlb_ent __read_mostly;
137
138unsigned long sparc64_kern_pri_context __read_mostly;
139unsigned long sparc64_kern_pri_nuc_bits __read_mostly;
140unsigned long sparc64_kern_sec_context __read_mostly;
141
136int bigkernel = 0; 142int bigkernel = 0;
137 143
138/* XXX Tune this... */ 144/* XXX Tune this... */
@@ -362,6 +368,7 @@ struct linux_prom_translation {
362 unsigned long data; 368 unsigned long data;
363}; 369};
364static struct linux_prom_translation prom_trans[512] __initdata; 370static struct linux_prom_translation prom_trans[512] __initdata;
371static unsigned int prom_trans_ents __initdata;
365 372
366extern unsigned long prom_boot_page; 373extern unsigned long prom_boot_page;
367extern void prom_remap(unsigned long physpage, unsigned long virtpage, int mmu_ihandle); 374extern void prom_remap(unsigned long physpage, unsigned long virtpage, int mmu_ihandle);
@@ -375,57 +382,7 @@ unsigned long kern_locked_tte_data;
375unsigned long prom_pmd_phys __read_mostly; 382unsigned long prom_pmd_phys __read_mostly;
376unsigned int swapper_pgd_zero __read_mostly; 383unsigned int swapper_pgd_zero __read_mostly;
377 384
378/* Allocate power-of-2 aligned chunks from the end of the 385static pmd_t *prompmd __read_mostly;
379 * kernel image. Return physical address.
380 */
381static inline unsigned long early_alloc_phys(unsigned long size)
382{
383 unsigned long base;
384
385 BUILD_BUG_ON(size & (size - 1));
386
387 kern_size = (kern_size + (size - 1)) & ~(size - 1);
388 base = kern_base + kern_size;
389 kern_size += size;
390
391 return base;
392}
393
394static inline unsigned long load_phys32(unsigned long pa)
395{
396 unsigned long val;
397
398 __asm__ __volatile__("lduwa [%1] %2, %0"
399 : "=&r" (val)
400 : "r" (pa), "i" (ASI_PHYS_USE_EC));
401
402 return val;
403}
404
405static inline unsigned long load_phys64(unsigned long pa)
406{
407 unsigned long val;
408
409 __asm__ __volatile__("ldxa [%1] %2, %0"
410 : "=&r" (val)
411 : "r" (pa), "i" (ASI_PHYS_USE_EC));
412
413 return val;
414}
415
416static inline void store_phys32(unsigned long pa, unsigned long val)
417{
418 __asm__ __volatile__("stwa %0, [%1] %2"
419 : /* no outputs */
420 : "r" (val), "r" (pa), "i" (ASI_PHYS_USE_EC));
421}
422
423static inline void store_phys64(unsigned long pa, unsigned long val)
424{
425 __asm__ __volatile__("stxa %0, [%1] %2"
426 : /* no outputs */
427 : "r" (val), "r" (pa), "i" (ASI_PHYS_USE_EC));
428}
429 386
430#define BASE_PAGE_SIZE 8192 387#define BASE_PAGE_SIZE 8192
431 388
@@ -435,34 +392,28 @@ static inline void store_phys64(unsigned long pa, unsigned long val)
435 */ 392 */
436unsigned long prom_virt_to_phys(unsigned long promva, int *error) 393unsigned long prom_virt_to_phys(unsigned long promva, int *error)
437{ 394{
438 unsigned long pmd_phys = (prom_pmd_phys + 395 pmd_t *pmdp = prompmd + ((promva >> 23) & 0x7ff);
439 ((promva >> 23) & 0x7ff) * sizeof(pmd_t)); 396 pte_t *ptep;
440 unsigned long pte_phys;
441 pmd_t pmd_ent;
442 pte_t pte_ent;
443 unsigned long base; 397 unsigned long base;
444 398
445 pmd_val(pmd_ent) = load_phys32(pmd_phys); 399 if (pmd_none(*pmdp)) {
446 if (pmd_none(pmd_ent)) {
447 if (error) 400 if (error)
448 *error = 1; 401 *error = 1;
449 return 0; 402 return 0;
450 } 403 }
451 404 ptep = (pte_t *)__pmd_page(*pmdp) + ((promva >> 13) & 0x3ff);
452 pte_phys = (unsigned long)pmd_val(pmd_ent) << 11UL; 405 if (!pte_present(*ptep)) {
453 pte_phys += ((promva >> 13) & 0x3ff) * sizeof(pte_t);
454 pte_val(pte_ent) = load_phys64(pte_phys);
455 if (!pte_present(pte_ent)) {
456 if (error) 406 if (error)
457 *error = 1; 407 *error = 1;
458 return 0; 408 return 0;
459 } 409 }
460 if (error) { 410 if (error) {
461 *error = 0; 411 *error = 0;
462 return pte_val(pte_ent); 412 return pte_val(*ptep);
463 } 413 }
464 base = pte_val(pte_ent) & _PAGE_PADDR; 414 base = pte_val(*ptep) & _PAGE_PADDR;
465 return (base + (promva & (BASE_PAGE_SIZE - 1))); 415
416 return base + (promva & (BASE_PAGE_SIZE - 1));
466} 417}
467 418
468/* The obp translations are saved based on 8k pagesize, since obp can 419/* The obp translations are saved based on 8k pagesize, since obp can
@@ -475,25 +426,20 @@ static void __init build_obp_range(unsigned long start, unsigned long end, unsig
475 unsigned long vaddr; 426 unsigned long vaddr;
476 427
477 for (vaddr = start; vaddr < end; vaddr += BASE_PAGE_SIZE) { 428 for (vaddr = start; vaddr < end; vaddr += BASE_PAGE_SIZE) {
478 unsigned long val, pte_phys, pmd_phys; 429 unsigned long val;
479 pmd_t pmd_ent; 430 pmd_t *pmd;
480 int i; 431 pte_t *pte;
481
482 pmd_phys = (prom_pmd_phys +
483 (((vaddr >> 23) & 0x7ff) * sizeof(pmd_t)));
484 pmd_val(pmd_ent) = load_phys32(pmd_phys);
485 if (pmd_none(pmd_ent)) {
486 pte_phys = early_alloc_phys(BASE_PAGE_SIZE);
487
488 for (i = 0; i < BASE_PAGE_SIZE / sizeof(pte_t); i++)
489 store_phys64(pte_phys+i*sizeof(pte_t),0);
490 432
491 pmd_val(pmd_ent) = pte_phys >> 11UL; 433 pmd = prompmd + ((vaddr >> 23) & 0x7ff);
492 store_phys32(pmd_phys, pmd_val(pmd_ent)); 434 if (pmd_none(*pmd)) {
435 pte = __alloc_bootmem(BASE_PAGE_SIZE, BASE_PAGE_SIZE,
436 PAGE_SIZE);
437 if (!pte)
438 prom_halt();
439 memset(pte, 0, BASE_PAGE_SIZE);
440 pmd_set(pmd, pte);
493 } 441 }
494 442 pte = (pte_t *) __pmd_page(*pmd) + ((vaddr >> 13) & 0x3ff);
495 pte_phys = (unsigned long)pmd_val(pmd_ent) << 11UL;
496 pte_phys += (((vaddr >> 13) & 0x3ff) * sizeof(pte_t));
497 443
498 val = data; 444 val = data;
499 445
@@ -501,7 +447,8 @@ static void __init build_obp_range(unsigned long start, unsigned long end, unsig
501 if (tlb_type == spitfire) 447 if (tlb_type == spitfire)
502 val &= ~0x0003fe0000000000UL; 448 val &= ~0x0003fe0000000000UL;
503 449
504 store_phys64(pte_phys, val | _PAGE_MODIFIED); 450 set_pte_at(&init_mm, vaddr, pte,
451 __pte(val | _PAGE_MODIFIED));
505 452
506 data += BASE_PAGE_SIZE; 453 data += BASE_PAGE_SIZE;
507 } 454 }
@@ -514,13 +461,17 @@ static inline int in_obp_range(unsigned long vaddr)
514} 461}
515 462
516#define OBP_PMD_SIZE 2048 463#define OBP_PMD_SIZE 2048
517static void __init build_obp_pgtable(int prom_trans_ents) 464static void __init build_obp_pgtable(void)
518{ 465{
519 unsigned long i; 466 unsigned long i;
520 467
521 prom_pmd_phys = early_alloc_phys(OBP_PMD_SIZE); 468 prompmd = __alloc_bootmem(OBP_PMD_SIZE, OBP_PMD_SIZE, PAGE_SIZE);
522 for (i = 0; i < OBP_PMD_SIZE; i += 4) 469 if (!prompmd)
523 store_phys32(prom_pmd_phys + i, 0); 470 prom_halt();
471
472 memset(prompmd, 0, OBP_PMD_SIZE);
473
474 prom_pmd_phys = __pa(prompmd);
524 475
525 for (i = 0; i < prom_trans_ents; i++) { 476 for (i = 0; i < prom_trans_ents; i++) {
526 unsigned long start, end; 477 unsigned long start, end;
@@ -540,7 +491,7 @@ static void __init build_obp_pgtable(int prom_trans_ents)
540/* Read OBP translations property into 'prom_trans[]'. 491/* Read OBP translations property into 'prom_trans[]'.
541 * Return the number of entries. 492 * Return the number of entries.
542 */ 493 */
543static int __init read_obp_translations(void) 494static void __init read_obp_translations(void)
544{ 495{
545 int n, node; 496 int n, node;
546 497
@@ -561,8 +512,10 @@ static int __init read_obp_translations(void)
561 prom_printf("prom_mappings: Couldn't get property.\n"); 512 prom_printf("prom_mappings: Couldn't get property.\n");
562 prom_halt(); 513 prom_halt();
563 } 514 }
515
564 n = n / sizeof(struct linux_prom_translation); 516 n = n / sizeof(struct linux_prom_translation);
565 return n; 517
518 prom_trans_ents = n;
566} 519}
567 520
568static void __init remap_kernel(void) 521static void __init remap_kernel(void)
@@ -582,28 +535,38 @@ static void __init remap_kernel(void)
582 prom_dtlb_load(tlb_ent, tte_data, tte_vaddr); 535 prom_dtlb_load(tlb_ent, tte_data, tte_vaddr);
583 prom_itlb_load(tlb_ent, tte_data, tte_vaddr); 536 prom_itlb_load(tlb_ent, tte_data, tte_vaddr);
584 if (bigkernel) { 537 if (bigkernel) {
585 prom_dtlb_load(tlb_ent - 1, 538 tlb_ent -= 1;
539 prom_dtlb_load(tlb_ent,
586 tte_data + 0x400000, 540 tte_data + 0x400000,
587 tte_vaddr + 0x400000); 541 tte_vaddr + 0x400000);
588 prom_itlb_load(tlb_ent - 1, 542 prom_itlb_load(tlb_ent,
589 tte_data + 0x400000, 543 tte_data + 0x400000,
590 tte_vaddr + 0x400000); 544 tte_vaddr + 0x400000);
591 } 545 }
546 sparc64_highest_unlocked_tlb_ent = tlb_ent - 1;
547 if (tlb_type == cheetah_plus) {
548 sparc64_kern_pri_context = (CTX_CHEETAH_PLUS_CTX0 |
549 CTX_CHEETAH_PLUS_NUC);
550 sparc64_kern_pri_nuc_bits = CTX_CHEETAH_PLUS_NUC;
551 sparc64_kern_sec_context = CTX_CHEETAH_PLUS_CTX0;
552 }
592} 553}
593 554
594static void __init inherit_prom_mappings(void)
595{
596 int n;
597 555
598 n = read_obp_translations(); 556static void __init inherit_prom_mappings_pre(void)
599 build_obp_pgtable(n); 557{
558 read_obp_translations();
600 559
601 /* Now fixup OBP's idea about where we really are mapped. */ 560 /* Now fixup OBP's idea about where we really are mapped. */
602 prom_printf("Remapping the kernel... "); 561 prom_printf("Remapping the kernel... ");
603 remap_kernel(); 562 remap_kernel();
604 563
605 prom_printf("done.\n"); 564 prom_printf("done.\n");
565}
606 566
567static void __init inherit_prom_mappings_post(void)
568{
569 build_obp_pgtable();
607 register_prom_callbacks(); 570 register_prom_callbacks();
608} 571}
609 572
@@ -788,8 +751,8 @@ void inherit_locked_prom_mappings(int save_p)
788 } 751 }
789 } 752 }
790 if (tlb_type == spitfire) { 753 if (tlb_type == spitfire) {
791 int high = SPITFIRE_HIGHEST_LOCKED_TLBENT - bigkernel; 754 int high = sparc64_highest_unlocked_tlb_ent;
792 for (i = 0; i < high; i++) { 755 for (i = 0; i <= high; i++) {
793 unsigned long data; 756 unsigned long data;
794 757
795 /* Spitfire Errata #32 workaround */ 758 /* Spitfire Errata #32 workaround */
@@ -877,9 +840,9 @@ void inherit_locked_prom_mappings(int save_p)
877 } 840 }
878 } 841 }
879 } else if (tlb_type == cheetah || tlb_type == cheetah_plus) { 842 } else if (tlb_type == cheetah || tlb_type == cheetah_plus) {
880 int high = CHEETAH_HIGHEST_LOCKED_TLBENT - bigkernel; 843 int high = sparc64_highest_unlocked_tlb_ent;
881 844
882 for (i = 0; i < high; i++) { 845 for (i = 0; i <= high; i++) {
883 unsigned long data; 846 unsigned long data;
884 847
885 data = cheetah_get_ldtlb_data(i); 848 data = cheetah_get_ldtlb_data(i);
@@ -1556,8 +1519,7 @@ void __init paging_init(void)
1556 1519
1557 swapper_pgd_zero = pgd_val(swapper_pg_dir[0]); 1520 swapper_pgd_zero = pgd_val(swapper_pg_dir[0]);
1558 1521
1559 /* Inherit non-locked OBP mappings. */ 1522 inherit_prom_mappings_pre();
1560 inherit_prom_mappings();
1561 1523
1562 /* Ok, we can use our TLB miss and window trap handlers safely. 1524 /* Ok, we can use our TLB miss and window trap handlers safely.
1563 * We need to do a quick peek here to see if we are on StarFire 1525 * We need to do a quick peek here to see if we are on StarFire
@@ -1568,15 +1530,23 @@ void __init paging_init(void)
1568 extern void setup_tba(int); 1530 extern void setup_tba(int);
1569 setup_tba(this_is_starfire); 1531 setup_tba(this_is_starfire);
1570 } 1532 }
1571
1572 inherit_locked_prom_mappings(1);
1573
1574 __flush_tlb_all(); 1533 __flush_tlb_all();
1575 1534
1535 /* Everything from this point forward, until we are done with
1536 * inherit_prom_mappings_post(), must complete successfully
1537 * without calling into the firmware. The firwmare page tables
1538 * have not been built, but we are running on the Linux kernel's
1539 * trap table.
1540 */
1541
1576 /* Setup bootmem... */ 1542 /* Setup bootmem... */
1577 pages_avail = 0; 1543 pages_avail = 0;
1578 last_valid_pfn = end_pfn = bootmem_init(&pages_avail); 1544 last_valid_pfn = end_pfn = bootmem_init(&pages_avail);
1579 1545
1546 inherit_prom_mappings_post();
1547
1548 inherit_locked_prom_mappings(1);
1549
1580#ifdef CONFIG_DEBUG_PAGEALLOC 1550#ifdef CONFIG_DEBUG_PAGEALLOC
1581 kernel_physical_mapping_init(); 1551 kernel_physical_mapping_init();
1582#endif 1552#endif