aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sparc64/kernel/head.S
diff options
context:
space:
mode:
Diffstat (limited to 'arch/sparc64/kernel/head.S')
-rw-r--r--arch/sparc64/kernel/head.S96
1 files changed, 88 insertions, 8 deletions
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