0001
0002
0003
0004
0005
0006
0007
0008
0009 #include <linux/pgtable.h>
0010 #include <asm/head.h>
0011 #include <asm/asi.h>
0012 #include <asm/lsu.h>
0013 #include <asm/dcr.h>
0014 #include <asm/dcu.h>
0015 #include <asm/pstate.h>
0016 #include <asm/page.h>
0017 #include <asm/spitfire.h>
0018 #include <asm/processor.h>
0019 #include <asm/thread_info.h>
0020 #include <asm/mmu.h>
0021 #include <asm/hypervisor.h>
0022 #include <asm/cpudata.h>
0023
0024 .data
0025 .align 8
0026 call_method:
0027 .asciz "call-method"
0028 .align 8
0029 itlb_load:
0030 .asciz "SUNW,itlb-load"
0031 .align 8
0032 dtlb_load:
0033 .asciz "SUNW,dtlb-load"
0034
0035 #define TRAMP_STACK_SIZE 1024
0036 .align 16
0037 tramp_stack:
0038 .skip TRAMP_STACK_SIZE
0039
0040 .align 8
0041 .globl sparc64_cpu_startup, sparc64_cpu_startup_end
0042 sparc64_cpu_startup:
0043 BRANCH_IF_SUN4V(g1, niagara_startup)
0044 BRANCH_IF_CHEETAH_BASE(g1, g5, cheetah_startup)
0045 BRANCH_IF_CHEETAH_PLUS_OR_FOLLOWON(g1, g5, cheetah_plus_startup)
0046
0047 ba,pt %xcc, spitfire_startup
0048 nop
0049
0050 cheetah_plus_startup:
0051
0052 ba,pt %xcc, cheetah_generic_startup
0053 nop
0054
0055 cheetah_startup:
0056 mov DCR_BPE | DCR_RPE | DCR_SI | DCR_IFPOE | DCR_MS, %g1
0057 wr %g1, %asr18
0058
0059 sethi %uhi(DCU_ME|DCU_RE|DCU_HPE|DCU_SPE|DCU_SL|DCU_WE), %g5
0060 or %g5, %ulo(DCU_ME|DCU_RE|DCU_HPE|DCU_SPE|DCU_SL|DCU_WE), %g5
0061 sllx %g5, 32, %g5
0062 or %g5, DCU_DM | DCU_IM | DCU_DC | DCU_IC, %g5
0063 stxa %g5, [%g0] ASI_DCU_CONTROL_REG
0064 membar #Sync
0065
0066
0067 cheetah_generic_startup:
0068 mov TSB_EXTENSION_P, %g3
0069 stxa %g0, [%g3] ASI_DMMU
0070 stxa %g0, [%g3] ASI_IMMU
0071 membar #Sync
0072
0073 mov TSB_EXTENSION_S, %g3
0074 stxa %g0, [%g3] ASI_DMMU
0075 membar #Sync
0076
0077 mov TSB_EXTENSION_N, %g3
0078 stxa %g0, [%g3] ASI_DMMU
0079 stxa %g0, [%g3] ASI_IMMU
0080 membar #Sync
0081
0082
0083 niagara_startup:
0084
0085 sethi %hi(0x80000000), %g5
0086 sllx %g5, 32, %g5
0087 wr %g5, %asr25
0088
0089 ba,pt %xcc, startup_continue
0090 nop
0091
0092 spitfire_startup:
0093 mov (LSU_CONTROL_IC | LSU_CONTROL_DC | LSU_CONTROL_IM | LSU_CONTROL_DM), %g1
0094 stxa %g1, [%g0] ASI_LSU_CONTROL
0095 membar #Sync
0096
0097 startup_continue:
0098 mov %o0, %l0
0099 BRANCH_IF_SUN4V(g1, niagara_lock_tlb)
0100
0101 sethi %hi(0x80000000), %g2
0102 sllx %g2, 32, %g2
0103 wr %g2, 0, %tick_cmpr
0104
0105
0106
0107
0108 sethi %hi(prom_entry_lock), %g2
0109 1: ldstub [%g2 + %lo(prom_entry_lock)], %g1
0110 brnz,pn %g1, 1b
0111 nop
0112
0113
0114
0115
0116 sethi %hi(tramp_stack), %g1
0117 or %g1, %lo(tramp_stack), %g1
0118 add %g1, TRAMP_STACK_SIZE, %g1
0119 sub %g1, STACKFRAME_SZ + STACK_BIAS + 256, %sp
0120 flushw
0121
0122
0123
0124
0125
0126
0127
0128
0129 sethi %hi(KERNBASE), %l3
0130 sethi %hi(kern_locked_tte_data), %l4
0131 ldx [%l4 + %lo(kern_locked_tte_data)], %l4
0132 clr %l5
0133 sethi %hi(num_kernel_image_mappings), %l6
0134 lduw [%l6 + %lo(num_kernel_image_mappings)], %l6
0135
0136 mov 15, %l7
0137 BRANCH_IF_ANY_CHEETAH(g1,g5,2f)
0138
0139 mov 63, %l7
0140 2:
0141
0142 3:
0143
0144 sethi %hi(call_method), %g2
0145 or %g2, %lo(call_method), %g2
0146 stx %g2, [%sp + 2047 + 128 + 0x00]
0147 mov 5, %g2
0148 stx %g2, [%sp + 2047 + 128 + 0x08]
0149 mov 1, %g2
0150 stx %g2, [%sp + 2047 + 128 + 0x10]
0151 sethi %hi(itlb_load), %g2
0152 or %g2, %lo(itlb_load), %g2
0153 stx %g2, [%sp + 2047 + 128 + 0x18]
0154 sethi %hi(prom_mmu_ihandle_cache), %g2
0155 lduw [%g2 + %lo(prom_mmu_ihandle_cache)], %g2
0156 stx %g2, [%sp + 2047 + 128 + 0x20]
0157
0158
0159 sllx %l5, 22, %g1
0160
0161 add %l3, %g1, %g2
0162 stx %g2, [%sp + 2047 + 128 + 0x28] ! VADDR
0163 add %l4, %g1, %g2
0164 stx %g2, [%sp + 2047 + 128 + 0x30] ! TTE
0165
0166
0167 sub %l7, %l5, %g2
0168 stx %g2, [%sp + 2047 + 128 + 0x38]
0169
0170 sethi %hi(p1275buf), %g2
0171 or %g2, %lo(p1275buf), %g2
0172 ldx [%g2 + 0x08], %o1
0173 call %o1
0174 add %sp, (2047 + 128), %o0
0175
0176
0177 sethi %hi(call_method), %g2
0178 or %g2, %lo(call_method), %g2
0179 stx %g2, [%sp + 2047 + 128 + 0x00]
0180 mov 5, %g2
0181 stx %g2, [%sp + 2047 + 128 + 0x08]
0182 mov 1, %g2
0183 stx %g2, [%sp + 2047 + 128 + 0x10]
0184 sethi %hi(dtlb_load), %g2
0185 or %g2, %lo(dtlb_load), %g2
0186 stx %g2, [%sp + 2047 + 128 + 0x18]
0187 sethi %hi(prom_mmu_ihandle_cache), %g2
0188 lduw [%g2 + %lo(prom_mmu_ihandle_cache)], %g2
0189 stx %g2, [%sp + 2047 + 128 + 0x20]
0190
0191
0192 sllx %l5, 22, %g1
0193
0194 add %l3, %g1, %g2
0195 stx %g2, [%sp + 2047 + 128 + 0x28] ! VADDR
0196 add %l4, %g1, %g2
0197 stx %g2, [%sp + 2047 + 128 + 0x30] ! TTE
0198
0199
0200 sub %l7, %l5, %g2
0201 stx %g2, [%sp + 2047 + 128 + 0x38]
0202
0203 sethi %hi(p1275buf), %g2
0204 or %g2, %lo(p1275buf), %g2
0205 ldx [%g2 + 0x08], %o1
0206 call %o1
0207 add %sp, (2047 + 128), %o0
0208
0209 add %l5, 1, %l5
0210 cmp %l5, %l6
0211 bne,pt %xcc, 3b
0212 nop
0213
0214 sethi %hi(prom_entry_lock), %g2
0215 stb %g0, [%g2 + %lo(prom_entry_lock)]
0216
0217 ba,pt %xcc, after_lock_tlb
0218 nop
0219
0220 niagara_lock_tlb:
0221 sethi %hi(KERNBASE), %l3
0222 sethi %hi(kern_locked_tte_data), %l4
0223 ldx [%l4 + %lo(kern_locked_tte_data)], %l4
0224 clr %l5
0225 sethi %hi(num_kernel_image_mappings), %l6
0226 lduw [%l6 + %lo(num_kernel_image_mappings)], %l6
0227
0228 1:
0229 mov HV_FAST_MMU_MAP_PERM_ADDR, %o5
0230 sllx %l5, 22, %g2
0231 add %l3, %g2, %o0
0232 clr %o1
0233 add %l4, %g2, %o2
0234 mov HV_MMU_IMMU, %o3
0235 ta HV_FAST_TRAP
0236
0237 mov HV_FAST_MMU_MAP_PERM_ADDR, %o5
0238 sllx %l5, 22, %g2
0239 add %l3, %g2, %o0
0240 clr %o1
0241 add %l4, %g2, %o2
0242 mov HV_MMU_DMMU, %o3
0243 ta HV_FAST_TRAP
0244
0245 add %l5, 1, %l5
0246 cmp %l5, %l6
0247 bne,pt %xcc, 1b
0248 nop
0249
0250 after_lock_tlb:
0251 wrpr %g0, (PSTATE_PRIV | PSTATE_PEF), %pstate
0252 wr %g0, 0, %fprs
0253
0254 wr %g0, ASI_P, %asi
0255
0256 mov PRIMARY_CONTEXT, %g7
0257
0258 661: stxa %g0, [%g7] ASI_DMMU
0259 .section .sun4v_1insn_patch, "ax"
0260 .word 661b
0261 stxa %g0, [%g7] ASI_MMU
0262 .previous
0263
0264 membar #Sync
0265 mov SECONDARY_CONTEXT, %g7
0266
0267 661: stxa %g0, [%g7] ASI_DMMU
0268 .section .sun4v_1insn_patch, "ax"
0269 .word 661b
0270 stxa %g0, [%g7] ASI_MMU
0271 .previous
0272
0273 membar #Sync
0274
0275
0276
0277
0278
0279
0280
0281
0282
0283
0284 sethi %hi(tramp_stack), %g1
0285 or %g1, %lo(tramp_stack), %g1
0286 add %g1, TRAMP_STACK_SIZE, %g1
0287 sub %g1, STACKFRAME_SZ + STACK_BIAS + 256, %sp
0288 mov 0, %fp
0289
0290
0291 set 0xdeadbeef, %g4
0292 set 0xdeadbeef, %g5
0293 set 0xdeadbeef, %g6
0294
0295 call init_irqwork_curcpu
0296 nop
0297
0298 sethi %hi(tlb_type), %g3
0299 lduw [%g3 + %lo(tlb_type)], %g2
0300 cmp %g2, 3
0301 bne,pt %icc, 1f
0302 nop
0303
0304 call hard_smp_processor_id
0305 nop
0306
0307 call sun4v_register_mondo_queues
0308 nop
0309
0310 1: call init_cur_cpu_trap
0311 ldx [%l0], %o0
0312
0313
0314 sethi %hi(sparc64_kern_pri_context), %g3
0315 ldx [%g3 + %lo(sparc64_kern_pri_context)], %g2
0316 mov PRIMARY_CONTEXT, %g1
0317
0318 661: stxa %g2, [%g1] ASI_DMMU
0319 .section .sun4v_1insn_patch, "ax"
0320 .word 661b
0321 stxa %g2, [%g1] ASI_MMU
0322 .previous
0323
0324 membar #Sync
0325
0326 wrpr %g0, 0, %wstate
0327
0328 sethi %hi(prom_entry_lock), %g2
0329 1: ldstub [%g2 + %lo(prom_entry_lock)], %g1
0330 brnz,pn %g1, 1b
0331 nop
0332
0333
0334
0335
0336
0337 sethi %hi(init_thread_union), %g6
0338 or %g6, %lo(init_thread_union), %g6
0339
0340 sethi %hi(is_sun4v), %o0
0341 lduw [%o0 + %lo(is_sun4v)], %o0
0342 brz,pt %o0, 2f
0343 nop
0344
0345 TRAP_LOAD_TRAP_BLOCK(%g2, %g3)
0346 add %g2, TRAP_PER_CPU_FAULT_INFO, %g2
0347 stxa %g2, [%g0] ASI_SCRATCHPAD
0348
0349
0350
0351
0352
0353 sethi %hi(KERNBASE), %g3
0354 sub %g2, %g3, %g2
0355 sethi %hi(kern_base), %g3
0356 ldx [%g3 + %lo(kern_base)], %g3
0357 add %g2, %g3, %o1
0358 sethi %hi(sparc64_ttable_tl0), %o0
0359
0360 set prom_set_trap_table_name, %g2
0361 stx %g2, [%sp + 2047 + 128 + 0x00]
0362 mov 2, %g2
0363 stx %g2, [%sp + 2047 + 128 + 0x08]
0364 mov 0, %g2
0365 stx %g2, [%sp + 2047 + 128 + 0x10]
0366 stx %o0, [%sp + 2047 + 128 + 0x18]
0367 stx %o1, [%sp + 2047 + 128 + 0x20]
0368 sethi %hi(p1275buf), %g2
0369 or %g2, %lo(p1275buf), %g2
0370 ldx [%g2 + 0x08], %o1
0371 call %o1
0372 add %sp, (2047 + 128), %o0
0373
0374 ba,pt %xcc, 3f
0375 nop
0376
0377 2: sethi %hi(sparc64_ttable_tl0), %o0
0378 set prom_set_trap_table_name, %g2
0379 stx %g2, [%sp + 2047 + 128 + 0x00]
0380 mov 1, %g2
0381 stx %g2, [%sp + 2047 + 128 + 0x08]
0382 mov 0, %g2
0383 stx %g2, [%sp + 2047 + 128 + 0x10]
0384 stx %o0, [%sp + 2047 + 128 + 0x18]
0385 sethi %hi(p1275buf), %g2
0386 or %g2, %lo(p1275buf), %g2
0387 ldx [%g2 + 0x08], %o1
0388 call %o1
0389 add %sp, (2047 + 128), %o0
0390
0391 3: sethi %hi(prom_entry_lock), %g2
0392 stb %g0, [%g2 + %lo(prom_entry_lock)]
0393
0394 ldx [%l0], %g6
0395 ldx [%g6 + TI_TASK], %g4
0396
0397 mov 1, %g5
0398 sllx %g5, THREAD_SHIFT, %g5
0399 sub %g5, (STACKFRAME_SZ + STACK_BIAS), %g5
0400 add %g6, %g5, %sp
0401
0402 rdpr %pstate, %o1
0403 or %o1, PSTATE_IE, %o1
0404 wrpr %o1, 0, %pstate
0405
0406 call smp_callin
0407 nop
0408
0409 call cpu_panic
0410 nop
0411 1: b,a,pt %xcc, 1b
0412
0413 .align 8
0414 sparc64_cpu_startup_end: