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#include <sys/pcb.h> 33#include <sys/trap.h> 34#include <sys/ftrace.h> 35#include <sys/traptrace.h> 36#include <sys/clock.h> 37#include <sys/panic.h> 38#include <sys/privregs.h> 39 40#include "assym.h" 41 42 43/* 44 * XX64: We are assuming that libc continues to expect the 64-bit value being 45 * returned in %edx:%eax. We further assume that it is safe to leave 46 * the top 32-bit intact in %rax as they will be ignored by libc. In 47 * other words, if the 64-bit value is already in %rax, while we manually 48 * manufacture a 64-bit value in %edx:%eax by setting %edx to be the high 49 * 32 bits of %rax, we don't zero them out in %rax. 50 * The following amd64 versions will need to be changed if the above 51 * assumptions are not true. 52 */ 53 54 .globl gethrtimef 55 ENTRY_NP(get_hrtime) 56 FAST_INTR_PUSH 57 movq gethrtimef(%rip), %rax 58 INDIRECT_CALL_REG(rax) 59 movq %rax, %rdx 60 shrq $32, %rdx /* high 32-bit in %edx */ 61 FAST_INTR_POP 62 FAST_INTR_RETURN 63 SET_SIZE(get_hrtime) 64 65 .globl gethrestimef 66 ENTRY_NP(get_hrestime) 67 FAST_INTR_PUSH 68 subq $TIMESPEC_SIZE, %rsp 69 movq %rsp, %rdi 70 movq gethrestimef(%rip), %rax 71 INDIRECT_CALL_REG(rax) 72 movl (%rsp), %eax 73 movl CLONGSIZE(%rsp), %edx 74 addq $TIMESPEC_SIZE, %rsp 75 FAST_INTR_POP 76 FAST_INTR_RETURN 77 SET_SIZE(get_hrestime) 78 79 /* 80 * In C this is 81 * 82 * klwp_t *lwp = ttolwp(curthread); 83 * struct mstate *ms = &lwp->lwp_mstate; 84 * return (gethrtime() - ms->ms_state_start + ms->ms_acct[LMS_USER]); 85 */ 86 ENTRY_NP(gethrvtime) 87 FAST_INTR_PUSH 88 call gethrtime_unscaled /* get time since boot */ 89 movq %gs:CPU_LWP, %rcx /* current lwp */ 90 subq LWP_MS_STATE_START(%rcx), %rax /* - ms->ms_state_start */ 91 addq LWP_ACCT_USER(%rcx), %rax /* add ms->ms_acct[LMS_USER] */ 92 subq $16, %rsp 93 movq %rax, (%rsp) 94 movq %rsp, %rdi 95 call scalehrtime 96 movq (%rsp), %rax 97 addq $16, %rsp 98 movq %rax, %rdx 99 shrq $32, %rdx /* high 32-bit in %rdx */ 100 FAST_INTR_POP 101 FAST_INTR_RETURN 102 SET_SIZE(gethrvtime) 103 104 /* 105 * In C this is: 106 * 107 * return (((uint64_t)(curthread->t_lpl->lpl_lgrpid) << 32) | 108 * curthread->t_cpu->cpu_id); 109 */ 110 ENTRY_NP(getlgrp) 111 FAST_INTR_PUSH 112 movq %gs:CPU_THREAD, %rcx 113 movq T_LPL(%rcx), %rcx 114 movl LPL_LGRPID(%rcx), %edx 115 movl %gs:CPU_ID, %eax 116 FAST_INTR_POP 117 FAST_INTR_RETURN 118 SET_SIZE(getlgrp) 119 120