diff options
author | David S. Miller <davem@sunset.davemloft.net> | 2006-02-09 05:52:44 -0500 |
---|---|---|
committer | David S. Miller <davem@sunset.davemloft.net> | 2006-03-20 04:12:03 -0500 |
commit | d82ace7dc4073b090a55b9740700e32b9a9ae302 (patch) | |
tree | d5aa8e10664b05bbfe31eacf95e2066c03cab102 /arch/sparc64 | |
parent | 1d2f1f90a1e004b0c1b8a73ed4394a93f09104b3 (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>
Diffstat (limited to 'arch/sparc64')
-rw-r--r-- | arch/sparc64/kernel/cpu.c | 6 | ||||
-rw-r--r-- | arch/sparc64/kernel/head.S | 96 | ||||
-rw-r--r-- | arch/sparc64/kernel/irq.c | 78 | ||||
-rw-r--r-- | arch/sparc64/kernel/setup.c | 9 | ||||
-rw-r--r-- | arch/sparc64/kernel/trampoline.S | 62 | ||||
-rw-r--r-- | arch/sparc64/kernel/us2e_cpufreq.c | 3 | ||||
-rw-r--r-- | arch/sparc64/kernel/us3_cpufreq.c | 3 | ||||
-rw-r--r-- | arch/sparc64/mm/init.c | 58 | ||||
-rw-r--r-- | arch/sparc64/prom/init.c | 20 | ||||
-rw-r--r-- | arch/sparc64/prom/tree.c | 9 |
10 files changed, 264 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 | ||
105 | prom_peer_name: | ||
106 | .asciz "peer" | ||
107 | prom_compatible_name: | ||
108 | .asciz "compatible" | ||
104 | prom_finddev_name: | 109 | prom_finddev_name: |
105 | .asciz "finddevice" | 110 | .asciz "finddevice" |
106 | prom_chosen_path: | 111 | prom_chosen_path: |
@@ -117,7 +122,13 @@ prom_map_name: | |||
117 | .asciz "map" | 122 | .asciz "map" |
118 | prom_unmap_name: | 123 | prom_unmap_name: |
119 | .asciz "unmap" | 124 | .asciz "unmap" |
125 | prom_sun4v_name: | ||
126 | .asciz "SUNW,sun4v" | ||
120 | .align 4 | 127 | .align 4 |
128 | prom_root_compatible: | ||
129 | .skip 64 | ||
130 | prom_root_node: | ||
131 | .word 0 | ||
121 | prom_mmu_ihandle_cache: | 132 | prom_mmu_ihandle_cache: |
122 | .word 0 | 133 | .word 0 |
123 | prom_boot_mapped_pc: | 134 | prom_boot_mapped_pc: |
@@ -129,8 +140,54 @@ prom_boot_mapping_phys_high: | |||
129 | .xword 0 | 140 | .xword 0 |
130 | prom_boot_mapping_phys_low: | 141 | prom_boot_mapping_phys_low: |
131 | .xword 0 | 142 | .xword 0 |
143 | is_sun4v: | ||
144 | .word 0 | ||
132 | 1: | 145 | 1: |
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 | ||
241 | sparc64_boot_after_remap: | 298 | sparc64_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 | ||
304 | 1: 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 | |||
318 | 2: | ||
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 | */ | ||
334 | niagara_tlb_fixup: | 410 | niagara_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 | |||
349 | cheetah_tlb_fixup: | 428 | cheetah_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: | |||
34 | sparc64_cpu_startup: | 35 | sparc64_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 | ||
77 | niagara_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 | |||
267 | niagara_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 | |||
309 | after_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 | ||
517 | static 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 | |||
517 | static void __init remap_kernel(void) | 540 | static 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; | |||
18 | unsigned int prom_rev, prom_prev; | 18 | unsigned 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. */ |
21 | int prom_root_node; | ||
22 | int prom_stdin, prom_stdout; | 21 | int prom_stdin, prom_stdout; |
23 | int prom_chosen_node; | 22 | int 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 | ||