6910795 Use the invariant %stick for sun4v system tick
[unleashed.git] / usr / src / uts / sun4v / ml / mach_subr_asm.s
blob89830cb98805c2a12d42901f55034fe838293b87
1 /*
2 * CDDL HEADER START
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
19 * CDDL HEADER END
22 * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
26 * General machine architecture & implementation specific
27 * assembly language routines.
29 #if defined(lint)
30 #include <sys/types.h>
31 #include <sys/t_lock.h>
32 #else /* lint */
33 #include "assym.h"
34 #endif /* lint */
36 #define CPU_MODULE /* need it for NSEC_SHIFT used by NATIVE_TIME_TO_NSEC() */
38 #include <sys/asm_linkage.h>
39 #include <sys/machsystm.h>
40 #include <sys/machthread.h>
41 #include <sys/machclock.h>
42 #include <sys/privregs.h>
43 #include <sys/cmpregs.h>
44 #include <sys/clock.h>
45 #include <sys/fpras.h>
46 #include <sys/soft_state.h>
48 #if defined(lint)
50 uint64_t
51 ultra_gettick(void)
52 { return (0); }
54 #else /* lint */
57 * This isn't the routine you're looking for.
59 * The routine simply returns the value of %tick on the *current* processor.
60 * Most of the time, gettick() [which in turn maps to %stick on platforms
61 * that have different CPU %tick rates] is what you want.
64 ENTRY(ultra_gettick)
65 RD_TICK(%o0,%o1,%o2,__LINE__)
66 retl
67 nop
68 SET_SIZE(ultra_gettick)
70 #endif /* lint */
72 #if defined(lint)
73 /* ARGSUSED */
74 void
75 set_mmfsa_scratchpad(caddr_t vaddr)
76 { }
78 #else /* lint */
80 ENTRY(set_mmfsa_scratchpad)
81 stxa %o0, [%g0]ASI_SCRATCHPAD
82 retl
83 nop
84 SET_SIZE(set_mmfsa_scratchpad)
85 #endif /* lint */
87 #if defined(lint)
88 caddr_t
89 get_mmfsa_scratchpad()
90 { return (0); }
92 #else /* lint */
94 ENTRY(get_mmfsa_scratchpad)
95 ldxa [%g0]ASI_SCRATCHPAD, %o0
96 retl
97 nop
98 SET_SIZE(get_mmfsa_scratchpad)
99 #endif /* lint */
103 #if defined(lint)
104 /* ARGSUSED */
105 void
106 cpu_intrq_unregister_powerdown(uint64_t doneflag_va)
109 #else /* lint */
112 * Called from a x-trap at tl1 must use %g1 as arg
113 * and save/restore %o0-%o5 after hypervisor calls
116 ENTRY(cpu_intrq_unregister_powerdown)
118 CPU_ADDR(%g2, %g3)
119 add %g2, CPU_MCPU, %g2
121 * Save %o regs
123 mov %o0, %g3
124 mov %o1, %g4
125 mov %o2, %g5
126 mov %o5, %g6
128 ldx [%g2 + MCPU_CPU_Q_BASE], %o1
129 mov INTR_CPU_Q, %o0
130 call hv_cpu_qconf
131 mov %g0, %o2
133 ldx [%g2 + MCPU_DEV_Q_BASE], %o1
134 mov INTR_DEV_Q, %o0
135 call hv_cpu_qconf
136 mov %g0, %o2
138 ldx [%g2 + MCPU_RQ_BASE], %o1
139 mov CPU_RQ, %o0
140 call hv_cpu_qconf
141 mov %g0, %o2
143 ldx [%g2 + MCPU_NRQ_BASE], %o1
144 mov CPU_NRQ, %o0
145 call hv_cpu_qconf
146 mov %g0, %o2
149 * set done flag to 0
151 stub %g0, [%g1]
154 * Restore %o regs
156 mov %g3, %o0
157 mov %g4, %o1
158 mov %g5, %o2
159 mov %g6, %o5
162 * This CPU is on its way out. Spin here
163 * until the DR unconfigure code stops it.
164 * Returning would put it back in the OS
165 * where it might grab resources like locks,
166 * causing some nastiness to occur.
169 ba,a 0b
171 SET_SIZE(cpu_intrq_unregister_powerdown)
172 #endif /* lint */
175 #if defined(lint)
176 /* ARGSUSED */
178 getprocessorid(void)
179 { return (0); }
181 #else /* lint */
184 * Get the processor ID.
185 * === MID reg as specified in 15dec89 sun4u spec, sec 5.4.3
188 ENTRY(getprocessorid)
189 CPU_INDEX(%o0, %o1)
190 retl
192 SET_SIZE(getprocessorid)
194 #endif /* lint */
196 #if defined(lint) || defined(__lint)
198 /* ARGSUSED */
199 hrtime_t
200 tick2ns(hrtime_t tick, uint_t cpuid)
201 { return 0; }
203 #else /* lint */
205 ENTRY_NP(tick2ns)
207 ! Use nsec_scale for sun4v which is based on %stick
209 NATIVE_TIME_TO_NSEC(%o0, %o2, %o3)
210 retl
212 SET_SIZE(tick2ns)
214 #endif /* lint */
216 #if defined(lint)
218 /* ARGSUSED */
219 void
220 set_cmp_error_steering(void)
223 #else /* lint */
225 ENTRY(set_cmp_error_steering)
226 retl
228 SET_SIZE(set_cmp_error_steering)
230 #endif /* lint */
232 #if defined(lint)
234 /* ARGSUSED */
235 uint64_t
236 ultra_getver(void)
238 return (0);
241 #else /* lint */
243 ENTRY(ultra_getver)
244 retl
245 mov -1, %o0 ! XXXQ no version available
246 SET_SIZE(ultra_getver)
248 #endif /* lint */
250 #if defined(lint)
253 fpras_chkfn_type1(void)
254 { return 0; }
256 #else /* lint */
259 * Check instructions using just the AX pipelines, designed by
260 * C.B. Liaw of PNP.
262 * This function must match a struct fpras_chkfn and must be
263 * block aligned. A zero return means all was well. These
264 * instructions are chosen to be sensitive to bit corruptions
265 * on the fpras rewrite, so if a bit corruption still produces
266 * a valid instruction we should still get an incorrect result
267 * here. This function is never called directly - it is copied
268 * into per-cpu and per-operation buffers; it must therefore
269 * be absolutely position independent. If an illegal instruction
270 * is encountered then the trap handler trampolines to the final
271 * three instructions of this function.
273 * We want two instructions that are complements of one another,
274 * and which can perform a calculation with a known result.
276 * SETHI:
278 * | 0 0 | rd | 1 0 0 | imm22 |
279 * 31 30 29 25 24 22 21 0
281 * ADDCCC with two source registers:
283 * | 1 0 | rd | 0 1 1 0 0 0 | rs1 | 0 | - | rs2 |
284 * 31 30 29 25 24 19 18 14 13 12 5 4 0
286 * We can choose rd and imm2 of the SETHI and rd, rs1 and rs2 of
287 * the ADDCCC to obtain instructions that are complements in all but
288 * bit 30.
290 * Registers are numbered as follows:
292 * r[31] %i7
293 * r[30] %i6
294 * r[29] %i5
295 * r[28] %i4
296 * r[27] %i3
297 * r[26] %i2
298 * r[25] %i1
299 * r[24] %i0
300 * r[23] %l7
301 * r[22] %l6
302 * r[21] %l5
303 * r[20] %l4
304 * r[19] %l3
305 * r[18] %l2
306 * r[17] %l1
307 * r[16] %l0
308 * r[15] %o7
309 * r[14] %o6
310 * r[13] %o5
311 * r[12] %o4
312 * r[11] %o3
313 * r[10] %o2
314 * r[9] %o1
315 * r[8] %o0
316 * r[7] %g7
317 * r[6] %g6
318 * r[5] %g5
319 * r[4] %g4
320 * r[3] %g3
321 * r[2] %g2
322 * r[1] %g1
323 * r[0] %g0
325 * For register r[n], register r[31-n] is the complement. We must
326 * avoid use of %i6/%i7 and %o6/%o7 as well as %g7. Clearly we need
327 * to use a local or input register as one half of the pair, which
328 * requires us to obtain our own register window or take steps
329 * to preserve any local or input we choose to use. We choose
330 * %o1 as rd for the SETHI, so rd of the ADDCCC must be %l6.
331 * We'll use %o1 as rs1 and %l6 as rs2 of the ADDCCC, which then
332 * requires that imm22 be 0b111 10110 1 11111111 01001 or 0x3dbfe9,
333 * or %hi(0xf6ffa400). This determines the value of the constant
334 * CBV2 below.
336 * The constant CBV1 is chosen such that an initial subcc %g0, CBV1
337 * will set the carry bit and every addccc thereafter will continue
338 * to generate a carry. Other values are possible for CBV1 - this
339 * is just one that works this way.
341 * Finally CBV3 is the expected answer when we perform our repeated
342 * calculations on CBV1 and CBV2 - it is not otherwise specially
343 * derived. If this result is not obtained then a corruption has
344 * occured during the FPRAS_REWRITE of one of the two blocks of
345 * 16 instructions. A corruption could also result in an illegal
346 * instruction or other unexpected trap - we catch illegal
347 * instruction traps in the PC range and trampoline to the
348 * last instructions of the function to return a failure indication.
352 #define CBV1 0xc11
353 #define CBV2 0xf6ffa400
354 #define CBV3 0x66f9d800
355 #define CBR1 %o1
356 #define CBR2 %l6
357 #define CBO2 %o2
358 #define SETHI_CBV2_CBR1 sethi %hi(CBV2), CBR1
359 #define ADDCCC_CBR1_CBR2_CBR2 addccc CBR1, CBR2, CBR2
361 .align 64
362 ENTRY_NP(fpras_chkfn_type1)
363 mov CBR2, CBO2 ! 1, preserve CBR2 of (callers) window
364 mov FPRAS_OK, %o0 ! 2, default return value
365 ba,pt %icc, 1f ! 3
366 subcc %g0, CBV1, CBR2 ! 4
367 ! 5 - 16
368 .align 64
369 1: SETHI_CBV2_CBR1 ! 1
370 ADDCCC_CBR1_CBR2_CBR2 ! 2
371 SETHI_CBV2_CBR1 ! 3
372 ADDCCC_CBR1_CBR2_CBR2 ! 4
373 SETHI_CBV2_CBR1 ! 5
374 ADDCCC_CBR1_CBR2_CBR2 ! 6
375 SETHI_CBV2_CBR1 ! 7
376 ADDCCC_CBR1_CBR2_CBR2 ! 8
377 SETHI_CBV2_CBR1 ! 9
378 ADDCCC_CBR1_CBR2_CBR2 ! 10
379 SETHI_CBV2_CBR1 ! 11
380 ADDCCC_CBR1_CBR2_CBR2 ! 12
381 SETHI_CBV2_CBR1 ! 13
382 ADDCCC_CBR1_CBR2_CBR2 ! 14
383 SETHI_CBV2_CBR1 ! 15
384 ADDCCC_CBR1_CBR2_CBR2 ! 16
386 ADDCCC_CBR1_CBR2_CBR2 ! 1
387 SETHI_CBV2_CBR1 ! 2
388 ADDCCC_CBR1_CBR2_CBR2 ! 3
389 SETHI_CBV2_CBR1 ! 4
390 ADDCCC_CBR1_CBR2_CBR2 ! 5
391 SETHI_CBV2_CBR1 ! 6
392 ADDCCC_CBR1_CBR2_CBR2 ! 7
393 SETHI_CBV2_CBR1 ! 8
394 ADDCCC_CBR1_CBR2_CBR2 ! 9
395 SETHI_CBV2_CBR1 ! 10
396 ADDCCC_CBR1_CBR2_CBR2 ! 11
397 SETHI_CBV2_CBR1 ! 12
398 ADDCCC_CBR1_CBR2_CBR2 ! 13
399 SETHI_CBV2_CBR1 ! 14
400 ADDCCC_CBR1_CBR2_CBR2 ! 15
401 SETHI_CBV2_CBR1 ! 16
403 addc CBR1, CBR2, CBR2 ! 1
404 sethi %hi(CBV3), CBR1 ! 2
405 cmp CBR1, CBR2 ! 3
406 movnz %icc, FPRAS_BADCALC, %o0! 4, how detected
407 retl ! 5
408 mov CBO2, CBR2 ! 6, restore borrowed register
409 .skip 4*(13-7+1) ! 7 - 13
411 ! illegal instr'n trap comes here
413 mov CBO2, CBR2 ! 14, restore borrowed register
414 retl ! 15
415 mov FPRAS_BADTRAP, %o0 ! 16, how detected
416 SET_SIZE(fpras_chkfn_type1)
417 #endif /* lint */
419 #if defined(lint)
420 char soft_state_message_strings[SOLARIS_SOFT_STATE_MSG_CNT][SSM_SIZE];
421 #else /* lint */
422 .seg ".data"
423 .global soft_state_message_strings
425 .align SSM_SIZE
426 soft_state_message_strings:
427 .asciz SOLARIS_SOFT_STATE_BOOT_MSG_STR
428 .align SSM_SIZE
429 .asciz SOLARIS_SOFT_STATE_RUN_MSG_STR
430 .align SSM_SIZE
431 .asciz SOLARIS_SOFT_STATE_HALT_MSG_STR
432 .align SSM_SIZE
433 .asciz SOLARIS_SOFT_STATE_POWER_MSG_STR
434 .align SSM_SIZE
435 .asciz SOLARIS_SOFT_STATE_PANIC_MSG_STR
436 .align SSM_SIZE
437 .asciz SOLARIS_SOFT_STATE_REBOOT_MSG_STR
438 .align SSM_SIZE
439 .asciz SOLARIS_SOFT_STATE_DEBUG_MSG_STR
440 .align SSM_SIZE
441 .skip SSM_SIZE /* saved message */
442 .nword 0
444 .seg ".text"
445 #endif /* lint */