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