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 57 hrtime_t 58 get_hrtime(void) 59 { return (0); } 60 61 hrtime_t 62 get_hrestime(void) 63 { 64 hrtime_t ts; 65 66 gethrestime((timespec_t *)&ts); 67 return (ts); 68 } 69 70 hrtime_t 71 gethrvtime(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 79 uint64_t 80 getlgrp(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 */