1/* 2 * Copyright (c) 2010 Apple Inc. All rights reserved. 3 * 4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ 5 * 6 * This file contains Original Code and/or Modifications of Original Code 7 * as defined in and that are subject to the Apple Public Source License 8 * Version 2.0 (the 'License'). You may not use this file except in 9 * compliance with the License. The rights granted to you under the License 10 * may not be used to create, or enable the creation or redistribution of, 11 * unlawful or unlicensed copies of an Apple operating system, or to 12 * circumvent, violate, or enable the circumvention or violation of, any 13 * terms of an Apple operating system software license agreement. 14 * 15 * Please obtain a copy of the License at 16 * http://www.opensource.apple.com/apsl/ and read it before using this file. 17 * 18 * The Original Code and all software distributed under the License are 19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 23 * Please see the License for the specific language governing rights and 24 * limitations under the License. 25 * 26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ 27 */ 28/* 29 * @OSF_COPYRIGHT@ 30 */ 31/* 32 * @APPLE_FREE_COPYRIGHT@ 33 */ 34/* 35 * File: rtclock_asm_native.h 36 * Purpose: Native routines for reading nanotime 37 */ 38 39#ifndef _PAL_RTCLOCK_ASM_NATIVE_H_ 40#define _PAL_RTCLOCK_ASM_NATIVE_H_ 41 42 43#if defined(__i386__) 44/* 45 * Assembly snippet included in exception handlers and rtc_nanotime_read() 46 * %edi points to nanotime info struct 47 * %edx:%eax returns nanotime 48 */ 49#define PAL_RTC_NANOTIME_READ_FAST() \ 500: movl RNT_GENERATION(%edi),%esi /* being updated? */ ; \ 51 testl %esi,%esi ; \ 52 jz 0b /* wait until done */ ; \ 53 lfence ; \ 54 rdtsc ; \ 55 lfence ; \ 56 subl RNT_TSC_BASE(%edi),%eax ; \ 57 sbbl RNT_TSC_BASE+4(%edi),%edx /* tsc - tsc_base */ ; \ 58 movl RNT_SCALE(%edi),%ecx /* * scale factor */ ; \ 59 movl %edx,%ebx ; \ 60 mull %ecx ; \ 61 movl %ebx,%eax ; \ 62 movl %edx,%ebx ; \ 63 mull %ecx ; \ 64 addl %ebx,%eax ; \ 65 adcl $0,%edx ; \ 66 addl RNT_NS_BASE(%edi),%eax /* + ns_base */ ; \ 67 adcl RNT_NS_BASE+4(%edi),%edx ; \ 68 cmpl RNT_GENERATION(%edi),%esi /* check for update */ ; \ 69 jne 0b /* do it all again */ 70 71#elif defined(__x86_64__) 72 73/* 74 * Assembly snippet included in exception handlers and rtc_nanotime_read() 75 * 76 * 77 * Warning! There are several copies of this code in the trampolines found in 78 * osfmk/x86_64/idt64.s, coming from the various TIMER macros in rtclock_asm.h. 79 * They're all kept in sync by using the RTC_NANOTIME_READ() macro. 80 * 81 * The algorithm we use is: 82 * 83 * ns = ((((rdtsc - rnt_tsc_base)<<rnt_shift)*rnt_tsc_scale) / 2**32) + rnt_ns_base; 84 * 85 * rnt_shift, a constant computed during initialization, is the smallest value for which: 86 * 87 * (tscFreq << rnt_shift) > SLOW_TSC_THRESHOLD 88 * 89 * Where SLOW_TSC_THRESHOLD is about 10e9. Since most processor's tscFreqs are greater 90 * than 1GHz, rnt_shift is usually 0. rnt_tsc_scale is also a 32-bit constant: 91 * 92 * rnt_tsc_scale = (10e9 * 2**32) / (tscFreq << rnt_shift); 93 * 94 * %rdi points to nanotime info struct. 95 * %rax returns nanotime 96 */ 97#define PAL_RTC_NANOTIME_READ_FAST() \ 980: movl RNT_GENERATION(%rdi),%esi ; \ 99 test %esi,%esi /* info updating? */ ; \ 100 jz 0b /* - wait if so */ ; \ 101 lfence ; \ 102 rdtsc ; \ 103 lfence ; \ 104 shlq $32,%rdx ; \ 105 movl RNT_SHIFT(%rdi),%ecx ; \ 106 orq %rdx,%rax /* %rax := tsc */ ; \ 107 subq RNT_TSC_BASE(%rdi),%rax /* tsc - tsc_base */ ; \ 108 shlq %cl,%rax ; \ 109 movl RNT_SCALE(%rdi),%ecx ; \ 110 mulq %rcx /* delta * scale */ ; \ 111 shrdq $32,%rdx,%rax /* %rdx:%rax >>= 32 */ ; \ 112 addq RNT_NS_BASE(%rdi),%rax /* add ns_base */ ; \ 113 cmpl RNT_GENERATION(%rdi),%esi /* repeat if changed */ ; \ 114 jne 0b 115 116#endif /* !defined(x86_64) */ 117 118 119#endif /* _PAL_RTCLOCK_ASM_NATIVE_H_ */ 120