aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid S. Miller <davem@sunset.davemloft.net>2006-02-09 05:52:44 -0500
committerDavid S. Miller <davem@sunset.davemloft.net>2006-03-20 04:12:03 -0500
commitd82ace7dc4073b090a55b9740700e32b9a9ae302 (patch)
treed5aa8e10664b05bbfe31eacf95e2066c03cab102
parent1d2f1f90a1e004b0c1b8a73ed4394a93f09104b3 (diff)
[SPARC64]: Detect sun4v early in boot process.
We look for "SUNW,sun4v" in the 'compatible' property of the root OBP device tree node. Protect every %ver register access, to make sure it is not touched on sun4v, as %ver is hyperprivileged there. Lock kernel TLB entries using hypervisor calls instead of calls into OBP. Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--arch/sparc64/kernel/cpu.c6
-rw-r--r--arch/sparc64/kernel/head.S96
-rw-r--r--arch/sparc64/kernel/irq.c78
-rw-r--r--arch/sparc64/kernel/setup.c9
-rw-r--r--arch/sparc64/kernel/trampoline.S62
-rw-r--r--arch/sparc64/kernel/us2e_cpufreq.c3
-rw-r--r--arch/sparc64/kernel/us3_cpufreq.c3
-rw-r--r--arch/sparc64/mm/init.c58
-rw-r--r--arch/sparc64/prom/init.c20
-rw-r--r--arch/sparc64/prom/tree.c9
-rw-r--r--include/asm-sparc64/head.h6
-rw-r--r--include/asm-sparc64/oplib.h3
12 files changed, 273 insertions, 80 deletions
diff --git a/arch/sparc64/kernel/cpu.c b/arch/sparc64/kernel/cpu.c
index 00eed88ef2e8..c7a4fb397024 100644
--- a/arch/sparc64/kernel/cpu.c
+++ b/arch/sparc64/kernel/cpu.c
@@ -71,6 +71,12 @@ void __init cpu_probe(void)
71 unsigned long ver, fpu_vers, manuf, impl, fprs; 71 unsigned long ver, fpu_vers, manuf, impl, fprs;
72 int i; 72 int i;
73 73
74 if (tlb_type == hypervisor) {
75 sparc_cpu_type = "UltraSparc T1 (Niagara)";
76 sparc_fpu_type = "UltraSparc T1 integrated FPU";
77 return;
78 }
79
74 fprs = fprs_read(); 80 fprs = fprs_read();
75 fprs_write(FPRS_FEF); 81 fprs_write(FPRS_FEF);
76 __asm__ __volatile__ ("rdpr %%ver, %0; stx %%fsr, [%1]" 82 __asm__ __volatile__ ("rdpr %%ver, %0; stx %%fsr, [%1]"
diff --git a/arch/sparc64/kernel/head.S b/arch/sparc64/kernel/head.S
index 01980014aead..d048f0dfd423 100644
--- a/arch/sparc64/kernel/head.S
+++ b/arch/sparc64/kernel/head.S
@@ -95,12 +95,17 @@ sparc64_boot:
95 wrpr %g1, 0x0, %pstate 95 wrpr %g1, 0x0, %pstate
96 ba,a,pt %xcc, 1f 96 ba,a,pt %xcc, 1f
97 97
98 .globl prom_finddev_name, prom_chosen_path 98 .globl prom_finddev_name, prom_chosen_path, prom_root_node
99 .globl prom_getprop_name, prom_mmu_name 99 .globl prom_getprop_name, prom_mmu_name, prom_peer_name
100 .globl prom_callmethod_name, prom_translate_name 100 .globl prom_callmethod_name, prom_translate_name, prom_root_compatible
101 .globl prom_map_name, prom_unmap_name, prom_mmu_ihandle_cache 101 .globl prom_map_name, prom_unmap_name, prom_mmu_ihandle_cache
102 .globl prom_boot_mapped_pc, prom_boot_mapping_mode 102 .globl prom_boot_mapped_pc, prom_boot_mapping_mode
103 .globl prom_boot_mapping_phys_high, prom_boot_mapping_phys_low 103 .globl prom_boot_mapping_phys_high, prom_boot_mapping_phys_low
104 .globl is_sun4v
105prom_peer_name:
106 .asciz "peer"
107prom_compatible_name:
108 .asciz "compatible"
104prom_finddev_name: 109prom_finddev_name:
105 .asciz "finddevice" 110 .asciz "finddevice"
106prom_chosen_path: 111prom_chosen_path:
@@ -117,7 +122,13 @@ prom_map_name:
117 .asciz "map" 122 .asciz "map"
118prom_unmap_name: 123prom_unmap_name:
119 .asciz "unmap" 124 .asciz "unmap"
125prom_sun4v_name:
126 .asciz "SUNW,sun4v"
120 .align 4 127 .align 4
128prom_root_compatible:
129 .skip 64
130prom_root_node:
131 .word 0
121prom_mmu_ihandle_cache: 132prom_mmu_ihandle_cache:
122 .word 0 133 .word 0
123prom_boot_mapped_pc: 134prom_boot_mapped_pc:
@@ -129,8 +140,54 @@ prom_boot_mapping_phys_high:
129 .xword 0 140 .xword 0
130prom_boot_mapping_phys_low: 141prom_boot_mapping_phys_low:
131 .xword 0 142 .xword 0
143is_sun4v:
144 .word 0
1321: 1451:
133 rd %pc, %l0 146 rd %pc, %l0
147
148 mov (1b - prom_peer_name), %l1
149 sub %l0, %l1, %l1
150 mov 0, %l2
151
152 /* prom_root_node = prom_peer(0) */
153 stx %l1, [%sp + 2047 + 128 + 0x00] ! service, "peer"
154 mov 1, %l3
155 stx %l3, [%sp + 2047 + 128 + 0x08] ! num_args, 1
156 stx %l3, [%sp + 2047 + 128 + 0x10] ! num_rets, 1
157 stx %l2, [%sp + 2047 + 128 + 0x18] ! arg1, 0
158 stx %g0, [%sp + 2047 + 128 + 0x20] ! ret1
159 call %l7
160 add %sp, (2047 + 128), %o0 ! argument array
161
162 ldx [%sp + 2047 + 128 + 0x20], %l4 ! prom root node
163 mov (1b - prom_root_node), %l1
164 sub %l0, %l1, %l1
165 stw %l4, [%l1]
166
167 mov (1b - prom_getprop_name), %l1
168 mov (1b - prom_compatible_name), %l2
169 mov (1b - prom_root_compatible), %l5
170 sub %l0, %l1, %l1
171 sub %l0, %l2, %l2
172 sub %l0, %l5, %l5
173
174 /* prom_getproperty(prom_root_node, "compatible",
175 * &prom_root_compatible, 64)
176 */
177 stx %l1, [%sp + 2047 + 128 + 0x00] ! service, "getprop"
178 mov 4, %l3
179 stx %l3, [%sp + 2047 + 128 + 0x08] ! num_args, 4
180 mov 1, %l3
181 stx %l3, [%sp + 2047 + 128 + 0x10] ! num_rets, 1
182 stx %l4, [%sp + 2047 + 128 + 0x18] ! arg1, prom_root_node
183 stx %l2, [%sp + 2047 + 128 + 0x20] ! arg2, "compatible"
184 stx %l5, [%sp + 2047 + 128 + 0x28] ! arg3, &prom_root_compatible
185 mov 64, %l3
186 stx %l3, [%sp + 2047 + 128 + 0x30] ! arg4, size
187 stx %g0, [%sp + 2047 + 128 + 0x38] ! ret1
188 call %l7
189 add %sp, (2047 + 128), %o0 ! argument array
190
134 mov (1b - prom_finddev_name), %l1 191 mov (1b - prom_finddev_name), %l1
135 mov (1b - prom_chosen_path), %l2 192 mov (1b - prom_chosen_path), %l2
136 mov (1b - prom_boot_mapped_pc), %l3 193 mov (1b - prom_boot_mapped_pc), %l3
@@ -239,6 +296,27 @@ prom_boot_mapping_phys_low:
239 add %sp, (192 + 128), %sp 296 add %sp, (192 + 128), %sp
240 297
241sparc64_boot_after_remap: 298sparc64_boot_after_remap:
299 sethi %hi(prom_root_compatible), %g1
300 or %g1, %lo(prom_root_compatible), %g1
301 sethi %hi(prom_sun4v_name), %g7
302 or %g7, %lo(prom_sun4v_name), %g7
303 mov 10, %g3
3041: ldub [%g7], %g2
305 ldub [%g1], %g4
306 cmp %g2, %g4
307 bne,pn %icc, 2f
308 add %g7, 1, %g7
309 subcc %g3, 1, %g3
310 bne,pt %xcc, 1b
311 add %g1, 1, %g1
312
313 sethi %hi(is_sun4v), %g1
314 or %g1, %lo(is_sun4v), %g1
315 mov 1, %g7
316 stw %g7, [%g1]
317
3182:
319 BRANCH_IF_SUN4V(g1, jump_to_sun4u_init)
242 BRANCH_IF_CHEETAH_BASE(g1,g7,cheetah_boot) 320 BRANCH_IF_CHEETAH_BASE(g1,g7,cheetah_boot)
243 BRANCH_IF_CHEETAH_PLUS_OR_FOLLOWON(g1,g7,cheetah_plus_boot) 321 BRANCH_IF_CHEETAH_PLUS_OR_FOLLOWON(g1,g7,cheetah_plus_boot)
244 ba,pt %xcc, spitfire_boot 322 ba,pt %xcc, spitfire_boot
@@ -323,14 +401,12 @@ sun4u_init:
323 401
324 membar #Sync 402 membar #Sync
325 403
326 BRANCH_IF_ANY_CHEETAH(g1,g7,cheetah_tlb_fixup) 404 BRANCH_IF_SUN4V(g1, niagara_tlb_fixup)
405 BRANCH_IF_ANY_CHEETAH(g1, g7, cheetah_tlb_fixup)
327 406
328 ba,pt %xcc, spitfire_tlb_fixup 407 ba,pt %xcc, spitfire_tlb_fixup
329 nop 408 nop
330 409
331 /* XXX Nothing branches to here yet, when %ver register indicates
332 * XXX Niagara we should do this.
333 */
334niagara_tlb_fixup: 410niagara_tlb_fixup:
335 mov 3, %g2 /* Set TLB type to hypervisor. */ 411 mov 3, %g2 /* Set TLB type to hypervisor. */
336 sethi %hi(tlb_type), %g1 412 sethi %hi(tlb_type), %g1
@@ -346,6 +422,9 @@ niagara_tlb_fixup:
346 call hypervisor_patch_cachetlbops 422 call hypervisor_patch_cachetlbops
347 nop 423 nop
348 424
425 ba,pt %xcc, tlb_fixup_done
426 nop
427
349cheetah_tlb_fixup: 428cheetah_tlb_fixup:
350 mov 2, %g2 /* Set TLB type to cheetah+. */ 429 mov 2, %g2 /* Set TLB type to cheetah+. */
351 BRANCH_IF_CHEETAH_PLUS_OR_FOLLOWON(g1,g7,1f) 430 BRANCH_IF_CHEETAH_PLUS_OR_FOLLOWON(g1,g7,1f)
@@ -464,7 +543,8 @@ setup_trap_table:
464 sllx %o2, 32, %o2 543 sllx %o2, 32, %o2
465 wr %o2, 0, %tick_cmpr 544 wr %o2, 0, %tick_cmpr
466 545
467 BRANCH_IF_ANY_CHEETAH(o2,o3,1f) 546 BRANCH_IF_SUN4V(o2, 1f)
547 BRANCH_IF_ANY_CHEETAH(o2, o3, 1f)
468 548
469 ba,pt %xcc, 2f 549 ba,pt %xcc, 2f
470 nop 550 nop
diff --git a/arch/sparc64/kernel/irq.c b/arch/sparc64/kernel/irq.c
index c80d2531ec46..1f6455503f24 100644
--- a/arch/sparc64/kernel/irq.c
+++ b/arch/sparc64/kernel/irq.c
@@ -150,47 +150,53 @@ void enable_irq(unsigned int irq)
150 150
151 preempt_disable(); 151 preempt_disable();
152 152
153 if (tlb_type == cheetah || tlb_type == cheetah_plus) { 153 if (tlb_type == hypervisor) {
154 unsigned long ver; 154 /* XXX SUN4V: implement me... XXX */
155 155 } else {
156 __asm__ ("rdpr %%ver, %0" : "=r" (ver)); 156 if (tlb_type == cheetah || tlb_type == cheetah_plus) {
157 if ((ver >> 32) == __JALAPENO_ID || 157 unsigned long ver;
158 (ver >> 32) == __SERRANO_ID) { 158
159 /* We set it to our JBUS ID. */ 159 __asm__ ("rdpr %%ver, %0" : "=r" (ver));
160 if ((ver >> 32) == __JALAPENO_ID ||
161 (ver >> 32) == __SERRANO_ID) {
162 /* We set it to our JBUS ID. */
163 __asm__ __volatile__("ldxa [%%g0] %1, %0"
164 : "=r" (tid)
165 : "i" (ASI_JBUS_CONFIG));
166 tid = ((tid & (0x1fUL<<17)) << 9);
167 tid &= IMAP_TID_JBUS;
168 } else {
169 /* We set it to our Safari AID. */
170 __asm__ __volatile__("ldxa [%%g0] %1, %0"
171 : "=r" (tid)
172 : "i"(ASI_SAFARI_CONFIG));
173 tid = ((tid & (0x3ffUL<<17)) << 9);
174 tid &= IMAP_AID_SAFARI;
175 }
176 } else if (this_is_starfire == 0) {
177 /* We set it to our UPA MID. */
160 __asm__ __volatile__("ldxa [%%g0] %1, %0" 178 __asm__ __volatile__("ldxa [%%g0] %1, %0"
161 : "=r" (tid) 179 : "=r" (tid)
162 : "i" (ASI_JBUS_CONFIG)); 180 : "i" (ASI_UPA_CONFIG));
163 tid = ((tid & (0x1fUL<<17)) << 9); 181 tid = ((tid & UPA_CONFIG_MID) << 9);
164 tid &= IMAP_TID_JBUS; 182 tid &= IMAP_TID_UPA;
165 } else { 183 } else {
166 /* We set it to our Safari AID. */ 184 tid = (starfire_translate(imap,
167 __asm__ __volatile__("ldxa [%%g0] %1, %0" 185 smp_processor_id()) << 26);
168 : "=r" (tid) 186 tid &= IMAP_TID_UPA;
169 : "i" (ASI_SAFARI_CONFIG));
170 tid = ((tid & (0x3ffUL<<17)) << 9);
171 tid &= IMAP_AID_SAFARI;
172 } 187 }
173 } else if (this_is_starfire == 0) {
174 /* We set it to our UPA MID. */
175 __asm__ __volatile__("ldxa [%%g0] %1, %0"
176 : "=r" (tid)
177 : "i" (ASI_UPA_CONFIG));
178 tid = ((tid & UPA_CONFIG_MID) << 9);
179 tid &= IMAP_TID_UPA;
180 } else {
181 tid = (starfire_translate(imap, smp_processor_id()) << 26);
182 tid &= IMAP_TID_UPA;
183 }
184 188
185 /* NOTE NOTE NOTE, IGN and INO are read-only, IGN is a product 189 /* NOTE NOTE NOTE, IGN and INO are read-only, IGN is a product
186 * of this SYSIO's preconfigured IGN in the SYSIO Control 190 * of this SYSIO's preconfigured IGN in the SYSIO Control
187 * Register, the hardware just mirrors that value here. 191 * Register, the hardware just mirrors that value here.
188 * However for Graphics and UPA Slave devices the full 192 * However for Graphics and UPA Slave devices the full
189 * IMAP_INR field can be set by the programmer here. 193 * IMAP_INR field can be set by the programmer here.
190 * 194 *
191 * Things like FFB can now be handled via the new IRQ mechanism. 195 * Things like FFB can now be handled via the new IRQ
192 */ 196 * mechanism.
193 upa_writel(tid | IMAP_VALID, imap); 197 */
198 upa_writel(tid | IMAP_VALID, imap);
199 }
194 200
195 preempt_enable(); 201 preempt_enable();
196} 202}
diff --git a/arch/sparc64/kernel/setup.c b/arch/sparc64/kernel/setup.c
index 2d64320d3a4d..7f02c8f71df6 100644
--- a/arch/sparc64/kernel/setup.c
+++ b/arch/sparc64/kernel/setup.c
@@ -504,9 +504,12 @@ static void __init per_cpu_patch(void)
504 if (tlb_type == spitfire && !this_is_starfire) 504 if (tlb_type == spitfire && !this_is_starfire)
505 return; 505 return;
506 506
507 __asm__ ("rdpr %%ver, %0" : "=r" (ver)); 507 is_jbus = 0;
508 is_jbus = ((ver >> 32) == __JALAPENO_ID || 508 if (tlb_type != hypervisor) {
509 (ver >> 32) == __SERRANO_ID); 509 __asm__ ("rdpr %%ver, %0" : "=r" (ver));
510 is_jbus = ((ver >> 32) == __JALAPENO_ID ||
511 (ver >> 32) == __SERRANO_ID);
512 }
510 513
511 p = &__cpuid_patch; 514 p = &__cpuid_patch;
512 while (p < &__cpuid_patch_end) { 515 while (p < &__cpuid_patch_end) {
diff --git a/arch/sparc64/kernel/trampoline.S b/arch/sparc64/kernel/trampoline.S
index fbf844f84a49..ffa8b79632cf 100644
--- a/arch/sparc64/kernel/trampoline.S
+++ b/arch/sparc64/kernel/trampoline.S
@@ -16,6 +16,7 @@
16#include <asm/processor.h> 16#include <asm/processor.h>
17#include <asm/thread_info.h> 17#include <asm/thread_info.h>
18#include <asm/mmu.h> 18#include <asm/mmu.h>
19#include <asm/hypervisor.h>
19 20
20 .data 21 .data
21 .align 8 22 .align 8
@@ -34,8 +35,9 @@ dtlb_load:
34sparc64_cpu_startup: 35sparc64_cpu_startup:
35 flushw 36 flushw
36 37
37 BRANCH_IF_CHEETAH_BASE(g1,g5,cheetah_startup) 38 BRANCH_IF_SUN4V(g1, niagara_startup)
38 BRANCH_IF_CHEETAH_PLUS_OR_FOLLOWON(g1,g5,cheetah_plus_startup) 39 BRANCH_IF_CHEETAH_BASE(g1, g5, cheetah_startup)
40 BRANCH_IF_CHEETAH_PLUS_OR_FOLLOWON(g1, g5, cheetah_plus_startup)
39 41
40 ba,pt %xcc, spitfire_startup 42 ba,pt %xcc, spitfire_startup
41 nop 43 nop
@@ -70,7 +72,9 @@ cheetah_generic_startup:
70 stxa %g0, [%g3] ASI_DMMU 72 stxa %g0, [%g3] ASI_DMMU
71 stxa %g0, [%g3] ASI_IMMU 73 stxa %g0, [%g3] ASI_IMMU
72 membar #Sync 74 membar #Sync
75 /* fallthru */
73 76
77niagara_startup:
74 /* Disable STICK_INT interrupts. */ 78 /* Disable STICK_INT interrupts. */
75 sethi %hi(0x80000000), %g5 79 sethi %hi(0x80000000), %g5
76 sllx %g5, 32, %g5 80 sllx %g5, 32, %g5
@@ -91,6 +95,8 @@ startup_continue:
91 sllx %g2, 32, %g2 95 sllx %g2, 32, %g2
92 wr %g2, 0, %tick_cmpr 96 wr %g2, 0, %tick_cmpr
93 97
98 BRANCH_IF_SUN4V(g1, niagara_lock_tlb)
99
94 /* Call OBP by hand to lock KERNBASE into i/d tlbs. 100 /* Call OBP by hand to lock KERNBASE into i/d tlbs.
95 * We lock 2 consequetive entries if we are 'bigkernel'. 101 * We lock 2 consequetive entries if we are 'bigkernel'.
96 */ 102 */
@@ -142,8 +148,7 @@ startup_continue:
142 148
143 sethi %hi(bigkernel), %g2 149 sethi %hi(bigkernel), %g2
144 lduw [%g2 + %lo(bigkernel)], %g2 150 lduw [%g2 + %lo(bigkernel)], %g2
145 cmp %g2, 0 151 brz,pt %g2, do_dtlb
146 be,pt %icc, do_dtlb
147 nop 152 nop
148 153
149 sethi %hi(call_method), %g2 154 sethi %hi(call_method), %g2
@@ -214,8 +219,7 @@ do_dtlb:
214 219
215 sethi %hi(bigkernel), %g2 220 sethi %hi(bigkernel), %g2
216 lduw [%g2 + %lo(bigkernel)], %g2 221 lduw [%g2 + %lo(bigkernel)], %g2
217 cmp %g2, 0 222 brz,pt %g2, do_unlock
218 be,pt %icc, do_unlock
219 nop 223 nop
220 224
221 sethi %hi(call_method), %g2 225 sethi %hi(call_method), %g2
@@ -257,6 +261,52 @@ do_unlock:
257 stb %g0, [%g2 + %lo(prom_entry_lock)] 261 stb %g0, [%g2 + %lo(prom_entry_lock)]
258 membar #StoreStore | #StoreLoad 262 membar #StoreStore | #StoreLoad
259 263
264 ba,pt %xcc, after_lock_tlb
265 nop
266
267niagara_lock_tlb:
268 mov HV_FAST_MMU_MAP_PERM_ADDR, %o0
269 sethi %hi(KERNBASE), %o1
270 clr %o2
271 sethi %hi(kern_locked_tte_data), %o3
272 ldx [%o3 + %lo(kern_locked_tte_data)], %o3
273 mov HV_MMU_IMMU, %o4
274 ta HV_FAST_TRAP
275
276 mov HV_FAST_MMU_MAP_PERM_ADDR, %o0
277 sethi %hi(KERNBASE), %o1
278 clr %o2
279 sethi %hi(kern_locked_tte_data), %o3
280 ldx [%o3 + %lo(kern_locked_tte_data)], %o3
281 mov HV_MMU_DMMU, %o4
282 ta HV_FAST_TRAP
283
284 sethi %hi(bigkernel), %g2
285 lduw [%g2 + %lo(bigkernel)], %g2
286 brz,pt %g2, after_lock_tlb
287 nop
288
289 mov HV_FAST_MMU_MAP_PERM_ADDR, %o0
290 sethi %hi(KERNBASE + 0x400000), %o1
291 clr %o2
292 sethi %hi(kern_locked_tte_data), %o3
293 ldx [%o3 + %lo(kern_locked_tte_data)], %o3
294 sethi %hi(0x400000), %o4
295 add %o3, %o4, %o3
296 mov HV_MMU_IMMU, %o4
297 ta HV_FAST_TRAP
298
299 mov HV_FAST_MMU_MAP_PERM_ADDR, %o0
300 sethi %hi(KERNBASE + 0x400000), %o1
301 clr %o2
302 sethi %hi(kern_locked_tte_data), %o3
303 ldx [%o3 + %lo(kern_locked_tte_data)], %o3
304 sethi %hi(0x400000), %o4
305 add %o3, %o4, %o3
306 mov HV_MMU_DMMU, %o4
307 ta HV_FAST_TRAP
308
309after_lock_tlb:
260 mov %l1, %sp 310 mov %l1, %sp
261 flushw 311 flushw
262 312
diff --git a/arch/sparc64/kernel/us2e_cpufreq.c b/arch/sparc64/kernel/us2e_cpufreq.c
index b35dc8dc995a..669fb83dd4f5 100644
--- a/arch/sparc64/kernel/us2e_cpufreq.c
+++ b/arch/sparc64/kernel/us2e_cpufreq.c
@@ -346,6 +346,9 @@ static int __init us2e_freq_init(void)
346 unsigned long manuf, impl, ver; 346 unsigned long manuf, impl, ver;
347 int ret; 347 int ret;
348 348
349 if (tlb_type != spitfire)
350 return -ENODEV;
351
349 __asm__("rdpr %%ver, %0" : "=r" (ver)); 352 __asm__("rdpr %%ver, %0" : "=r" (ver));
350 manuf = ((ver >> 48) & 0xffff); 353 manuf = ((ver >> 48) & 0xffff);
351 impl = ((ver >> 32) & 0xffff); 354 impl = ((ver >> 32) & 0xffff);
diff --git a/arch/sparc64/kernel/us3_cpufreq.c b/arch/sparc64/kernel/us3_cpufreq.c
index 6d1f9a3c464f..a912c45bdc05 100644
--- a/arch/sparc64/kernel/us3_cpufreq.c
+++ b/arch/sparc64/kernel/us3_cpufreq.c
@@ -203,6 +203,9 @@ static int __init us3_freq_init(void)
203 unsigned long manuf, impl, ver; 203 unsigned long manuf, impl, ver;
204 int ret; 204 int ret;
205 205
206 if (tlb_type != cheetah && tlb_type != cheetah_plus)
207 return -ENODEV;
208
206 __asm__("rdpr %%ver, %0" : "=r" (ver)); 209 __asm__("rdpr %%ver, %0" : "=r" (ver));
207 manuf = ((ver >> 48) & 0xffff); 210 manuf = ((ver >> 48) & 0xffff);
208 impl = ((ver >> 32) & 0xffff); 211 impl = ((ver >> 32) & 0xffff);
diff --git a/arch/sparc64/mm/init.c b/arch/sparc64/mm/init.c
index 6504d6eb5372..e602b857071a 100644
--- a/arch/sparc64/mm/init.c
+++ b/arch/sparc64/mm/init.c
@@ -514,6 +514,29 @@ static void __init read_obp_translations(void)
514 } 514 }
515} 515}
516 516
517static void __init hypervisor_tlb_lock(unsigned long vaddr,
518 unsigned long pte,
519 unsigned long mmu)
520{
521 register unsigned long func asm("%o0");
522 register unsigned long arg0 asm("%o1");
523 register unsigned long arg1 asm("%o2");
524 register unsigned long arg2 asm("%o3");
525 register unsigned long arg3 asm("%o4");
526
527 func = HV_FAST_MMU_MAP_PERM_ADDR;
528 arg0 = vaddr;
529 arg1 = 0;
530 arg2 = pte;
531 arg3 = mmu;
532 __asm__ __volatile__("ta 0x80"
533 : "=&r" (func), "=&r" (arg0),
534 "=&r" (arg1), "=&r" (arg2),
535 "=&r" (arg3)
536 : "0" (func), "1" (arg0), "2" (arg1),
537 "3" (arg2), "4" (arg3));
538}
539
517static void __init remap_kernel(void) 540static void __init remap_kernel(void)
518{ 541{
519 unsigned long phys_page, tte_vaddr, tte_data; 542 unsigned long phys_page, tte_vaddr, tte_data;
@@ -527,19 +550,30 @@ static void __init remap_kernel(void)
527 550
528 kern_locked_tte_data = tte_data; 551 kern_locked_tte_data = tte_data;
529 552
530 /* Now lock us into the TLBs via OBP. */ 553 /* Now lock us into the TLBs via Hypervisor or OBP. */
531 prom_dtlb_load(tlb_ent, tte_data, tte_vaddr); 554 if (tlb_type == hypervisor) {
532 prom_itlb_load(tlb_ent, tte_data, tte_vaddr); 555 hypervisor_tlb_lock(tte_vaddr, tte_data, HV_MMU_DMMU);
533 if (bigkernel) { 556 hypervisor_tlb_lock(tte_vaddr, tte_data, HV_MMU_IMMU);
534 tlb_ent -= 1; 557 if (bigkernel) {
535 prom_dtlb_load(tlb_ent, 558 tte_vaddr += 0x400000;
536 tte_data + 0x400000, 559 tte_data += 0x400000;
537 tte_vaddr + 0x400000); 560 hypervisor_tlb_lock(tte_vaddr, tte_data, HV_MMU_DMMU);
538 prom_itlb_load(tlb_ent, 561 hypervisor_tlb_lock(tte_vaddr, tte_data, HV_MMU_IMMU);
539 tte_data + 0x400000, 562 }
540 tte_vaddr + 0x400000); 563 } else {
564 prom_dtlb_load(tlb_ent, tte_data, tte_vaddr);
565 prom_itlb_load(tlb_ent, tte_data, tte_vaddr);
566 if (bigkernel) {
567 tlb_ent -= 1;
568 prom_dtlb_load(tlb_ent,
569 tte_data + 0x400000,
570 tte_vaddr + 0x400000);
571 prom_itlb_load(tlb_ent,
572 tte_data + 0x400000,
573 tte_vaddr + 0x400000);
574 }
575 sparc64_highest_unlocked_tlb_ent = tlb_ent - 1;
541 } 576 }
542 sparc64_highest_unlocked_tlb_ent = tlb_ent - 1;
543 if (tlb_type == cheetah_plus) { 577 if (tlb_type == cheetah_plus) {
544 sparc64_kern_pri_context = (CTX_CHEETAH_PLUS_CTX0 | 578 sparc64_kern_pri_context = (CTX_CHEETAH_PLUS_CTX0 |
545 CTX_CHEETAH_PLUS_NUC); 579 CTX_CHEETAH_PLUS_NUC);
diff --git a/arch/sparc64/prom/init.c b/arch/sparc64/prom/init.c
index f3cc2d8578b2..095755e428a6 100644
--- a/arch/sparc64/prom/init.c
+++ b/arch/sparc64/prom/init.c
@@ -18,7 +18,6 @@ enum prom_major_version prom_vers;
18unsigned int prom_rev, prom_prev; 18unsigned int prom_rev, prom_prev;
19 19
20/* The root node of the prom device tree. */ 20/* The root node of the prom device tree. */
21int prom_root_node;
22int prom_stdin, prom_stdout; 21int prom_stdin, prom_stdout;
23int prom_chosen_node; 22int prom_chosen_node;
24 23
@@ -41,26 +40,22 @@ void __init prom_init(void *cif_handler, void *cif_stack)
41 40
42 prom_cif_init(cif_handler, cif_stack); 41 prom_cif_init(cif_handler, cif_stack);
43 42
44 prom_root_node = prom_getsibling(0);
45 if((prom_root_node == 0) || (prom_root_node == -1))
46 prom_halt();
47
48 prom_chosen_node = prom_finddevice(prom_chosen_path); 43 prom_chosen_node = prom_finddevice(prom_chosen_path);
49 if (!prom_chosen_node || prom_chosen_node == -1) 44 if (!prom_chosen_node || prom_chosen_node == -1)
50 prom_halt(); 45 prom_halt();
51 46
52 prom_stdin = prom_getint (prom_chosen_node, "stdin"); 47 prom_stdin = prom_getint(prom_chosen_node, "stdin");
53 prom_stdout = prom_getint (prom_chosen_node, "stdout"); 48 prom_stdout = prom_getint(prom_chosen_node, "stdout");
54 49
55 node = prom_finddevice("/openprom"); 50 node = prom_finddevice("/openprom");
56 if (!node || node == -1) 51 if (!node || node == -1)
57 prom_halt(); 52 prom_halt();
58 53
59 prom_getstring (node, "version", buffer, sizeof (buffer)); 54 prom_getstring(node, "version", buffer, sizeof (buffer));
60 55
61 prom_printf ("\n"); 56 prom_printf("\n");
62 57
63 if (strncmp (buffer, "OBP ", 4)) 58 if (strncmp(buffer, "OBP ", 4))
64 goto strange_version; 59 goto strange_version;
65 60
66 /* 61 /*
@@ -70,7 +65,7 @@ void __init prom_init(void *cif_handler, void *cif_stack)
70 * accordingly. -spot 65 * accordingly. -spot
71 */ 66 */
72 67
73 if (strncmp (buffer, "OBP ", 5)) 68 if (strncmp(buffer, "OBP ", 5))
74 bufadjust = 4; 69 bufadjust = 4;
75 else 70 else
76 bufadjust = 5; 71 bufadjust = 5;
@@ -87,7 +82,8 @@ void __init prom_init(void *cif_handler, void *cif_stack)
87 prom_rev = ints[1]; 82 prom_rev = ints[1];
88 prom_prev = (ints[0] << 16) | (ints[1] << 8) | ints[2]; 83 prom_prev = (ints[0] << 16) | (ints[1] << 8) | ints[2];
89 84
90 printk ("PROMLIB: Sun IEEE Boot Prom %s\n", buffer + bufadjust); 85 printk("PROMLIB: Sun IEEE Boot Prom %s\n", buffer + bufadjust);
86 printk("PROMLIB: Root node compatible: %s\n", prom_root_compatible);
91 87
92 /* Initialization successful. */ 88 /* Initialization successful. */
93 return; 89 return;
diff --git a/arch/sparc64/prom/tree.c b/arch/sparc64/prom/tree.c
index b1ff9e87dcc6..49075abd7cbc 100644
--- a/arch/sparc64/prom/tree.c
+++ b/arch/sparc64/prom/tree.c
@@ -51,7 +51,7 @@ prom_getparent(int node)
51__inline__ int 51__inline__ int
52__prom_getsibling(int node) 52__prom_getsibling(int node)
53{ 53{
54 return p1275_cmd ("peer", P1275_INOUT(1, 1), node); 54 return p1275_cmd(prom_peer_name, P1275_INOUT(1, 1), node);
55} 55}
56 56
57__inline__ int 57__inline__ int
@@ -59,9 +59,12 @@ prom_getsibling(int node)
59{ 59{
60 int sibnode; 60 int sibnode;
61 61
62 if(node == -1) return 0; 62 if (node == -1)
63 return 0;
63 sibnode = __prom_getsibling(node); 64 sibnode = __prom_getsibling(node);
64 if(sibnode == -1) return 0; 65 if (sibnode == -1)
66 return 0;
67
65 return sibnode; 68 return sibnode;
66} 69}
67 70
diff --git a/include/asm-sparc64/head.h b/include/asm-sparc64/head.h
index ff76c0981b63..c4ac3e87aa50 100644
--- a/include/asm-sparc64/head.h
+++ b/include/asm-sparc64/head.h
@@ -24,6 +24,12 @@
24#define PANTHER_IMPL 0x0019 /* Ultra-IV+ */ 24#define PANTHER_IMPL 0x0019 /* Ultra-IV+ */
25#define SERRANO_IMPL 0x0022 /* Ultra-IIIi+ */ 25#define SERRANO_IMPL 0x0022 /* Ultra-IIIi+ */
26 26
27#define BRANCH_IF_SUN4V(tmp1,label) \
28 sethi %hi(is_sun4v), %tmp1; \
29 lduw [%tmp1 + %lo(is_sun4v)], %tmp1; \
30 brnz,pn %tmp1, label; \
31 nop
32
27#define BRANCH_IF_CHEETAH_BASE(tmp1,tmp2,label) \ 33#define BRANCH_IF_CHEETAH_BASE(tmp1,tmp2,label) \
28 rdpr %ver, %tmp1; \ 34 rdpr %ver, %tmp1; \
29 sethi %hi(__CHEETAH_ID), %tmp2; \ 35 sethi %hi(__CHEETAH_ID), %tmp2; \
diff --git a/include/asm-sparc64/oplib.h b/include/asm-sparc64/oplib.h
index 3c59b2693fb9..2ea545b931b0 100644
--- a/include/asm-sparc64/oplib.h
+++ b/include/asm-sparc64/oplib.h
@@ -39,6 +39,9 @@ extern int prom_stdin, prom_stdout;
39extern int prom_chosen_node; 39extern int prom_chosen_node;
40 40
41/* Helper values and strings in arch/sparc64/kernel/head.S */ 41/* Helper values and strings in arch/sparc64/kernel/head.S */
42extern const char prom_peer_name[];
43extern const char prom_compatible_name[];
44extern const char prom_root_compatible[];
42extern const char prom_finddev_name[]; 45extern const char prom_finddev_name[];
43extern const char prom_chosen_path[]; 46extern const char prom_chosen_path[];
44extern const char prom_getprop_name[]; 47extern const char prom_getprop_name[];