1/*
2 * CDDL HEADER START
3 *
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.
7 *
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.
12 *
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]
18 *
19 * CDDL HEADER END
20 */
21/*
22 * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
23 * Use is subject to license terms.
24 */
25
26#pragma ident	"%Z%%M%	%I%	%E% SMI"
27
28#include <sys/asm_linkage.h>
29#include <sys/asm_misc.h>
30#include <sys/regset.h>
31#include <sys/psw.h>
32
33#if defined(__lint)
34
35#include <sys/types.h>
36#include <sys/thread.h>
37#include <sys/systm.h>
38#include <sys/lgrp.h>
39
40#else   /* __lint */
41
42#include <sys/pcb.h>
43#include <sys/trap.h>
44#include <sys/ftrace.h>
45#include <sys/traptrace.h>
46#include <sys/clock.h>
47#include <sys/panic.h>
48#include <sys/privregs.h>
49
50#include "assym.h"
51
52#endif	/* __lint */
53
54
55#if defined(__lint)
56
57hrtime_t
58get_hrtime(void)
59{ return (0); }
60
61hrtime_t
62get_hrestime(void)
63{
64	hrtime_t ts;
65
66	gethrestime((timespec_t *)&ts);
67	return (ts);
68}
69
70hrtime_t
71gethrvtime(void)
72{
73	klwp_t *lwp = ttolwp(curthread);
74	struct mstate *ms = &lwp->lwp_mstate;
75
76	return (gethrtime() - ms->ms_state_start + ms->ms_acct[LMS_USER]);
77}
78
79uint64_t
80getlgrp(void)
81{
82	return (((uint64_t)(curthread->t_lpl->lpl_lgrpid) << 32) |
83			curthread->t_cpu->cpu_id);
84}
85
86#else	/* __lint */
87
88/*
89 * XX64: We are assuming that libc continues to expect the 64-bit value being
90 * returned in %edx:%eax.  We further assume that it is safe to leave
91 * the top 32-bit intact in %rax as they will be ignored by libc.  In
92 * other words, if the 64-bit value is already in %rax, while we manually
93 * manufacture a 64-bit value in %edx:%eax by setting %edx to be the high
94 * 32 bits of %rax, we don't zero them out in %rax.
95 * The following amd64 versions will need to be changed if the above
96 * assumptions are not true.
97 */
98
99#if defined(__amd64)
100
101	.globl	gethrtimef
102	ENTRY_NP(get_hrtime)
103	FAST_INTR_PUSH
104	call	*gethrtimef(%rip)
105	movq	%rax, %rdx
106	shrq	$32, %rdx			/* high 32-bit in %edx */
107	FAST_INTR_POP
108	FAST_INTR_RETURN
109	SET_SIZE(get_hrtime)
110
111#elif defined(__i386)
112
113	.globl	gethrtimef
114	ENTRY_NP(get_hrtime)
115	FAST_INTR_PUSH
116	call	*gethrtimef
117	FAST_INTR_POP
118	FAST_INTR_RETURN
119	SET_SIZE(get_hrtime)
120
121#endif	/* __i386 */
122
123#if defined(__amd64)
124
125	.globl	gethrestimef
126	ENTRY_NP(get_hrestime)
127	FAST_INTR_PUSH
128	subq	$TIMESPEC_SIZE, %rsp
129	movq	%rsp, %rdi
130	call	*gethrestimef(%rip)
131	movl	(%rsp), %eax
132	movl	CLONGSIZE(%rsp), %edx
133	addq	$TIMESPEC_SIZE, %rsp
134	FAST_INTR_POP
135	FAST_INTR_RETURN
136	SET_SIZE(get_hrestime)
137
138#elif defined(__i386)
139
140	.globl	gethrestimef
141	ENTRY_NP(get_hrestime)
142	FAST_INTR_PUSH
143	subl	$TIMESPEC_SIZE, %esp
144	pushl	%esp
145	call	*gethrestimef
146	movl	_CONST(4 + 0)(%esp), %eax
147	movl	_CONST(4 + CLONGSIZE)(%esp), %edx
148	addl	$_CONST(4 + TIMESPEC_SIZE), %esp
149	FAST_INTR_POP
150	FAST_INTR_RETURN
151	SET_SIZE(get_hrestime)
152
153#endif	/* __i386 */
154
155#if defined(__amd64)
156
157	ENTRY_NP(gethrvtime)
158	FAST_INTR_PUSH
159	call	gethrtime_unscaled		/* get time since boot */
160	movq	%gs:CPU_LWP, %rcx		/* current lwp */
161	subq	LWP_MS_STATE_START(%rcx), %rax	/* - ms->ms_state_start */
162	addq	LWP_ACCT_USER(%rcx), %rax	/* add ms->ms_acct[LMS_USER] */
163	subq	$16, %rsp
164	movq	%rax, (%rsp)
165	movq	%rsp, %rdi
166	call	scalehrtime
167	movq	(%rsp), %rax
168	addq	$16, %rsp
169	movq	%rax, %rdx
170	shrq	$32, %rdx			/* high 32-bit in %rdx */
171	FAST_INTR_POP
172	FAST_INTR_RETURN
173	SET_SIZE(gethrvtime)
174
175#elif defined(__i386)
176
177	ENTRY_NP(gethrvtime)
178	FAST_INTR_PUSH
179	call	gethrtime_unscaled		/* get time since boot */
180	movl	%gs:CPU_LWP, %ecx		/* current lwp */
181	subl	LWP_MS_STATE_START(%ecx), %eax	/* - ms->ms_state_start */
182	sbbl	LWP_MS_STATE_START+4(%ecx), %edx
183	addl	LWP_ACCT_USER(%ecx), %eax	/* add ms->ms_acct[LMS_USER] */
184	adcl	LWP_ACCT_USER+4(%ecx), %edx
185	subl	$0x8, %esp
186	leal	(%esp), %ecx
187	movl	%eax, (%ecx)
188	movl	%edx, 4(%ecx)
189	pushl	%ecx
190	call	scalehrtime
191	popl	%ecx
192	movl	(%ecx), %eax
193	movl	4(%ecx), %edx
194	addl	$0x8, %esp
195	FAST_INTR_POP
196	FAST_INTR_RETURN
197	SET_SIZE(gethrvtime)
198
199#endif	/* __i386 */
200
201#if defined(__amd64)
202
203	ENTRY_NP(getlgrp)
204	FAST_INTR_PUSH
205	movq	%gs:CPU_THREAD, %rcx
206	movq	T_LPL(%rcx), %rcx
207	movl	LPL_LGRPID(%rcx), %edx
208	movl	%gs:CPU_ID, %eax
209	FAST_INTR_POP
210	FAST_INTR_RETURN
211	SET_SIZE(getlgrp)
212
213#elif defined(__i386)
214
215	ENTRY_NP(getlgrp)
216	FAST_INTR_PUSH
217	movl	%gs:CPU_THREAD, %ecx
218	movl	T_LPL(%ecx), %ecx
219	movl	LPL_LGRPID(%ecx), %edx
220	movl	%gs:CPU_ID, %eax
221	FAST_INTR_POP
222	FAST_INTR_RETURN
223	SET_SIZE(getlgrp)
224
225#endif	/* __i386 */
226
227#endif	/* __lint */
228