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