]> git.saurik.com Git - apple/xnu.git/blame - osfmk/i386/commpage/commpage_mach_absolute_time.s
xnu-792.12.6.tar.gz
[apple/xnu.git] / osfmk / i386 / commpage / commpage_mach_absolute_time.s
CommitLineData
de355530 1/*
8ad349bb 2 * Copyright (c) 2003 Apple Computer, Inc. All rights reserved.
de355530 3 *
8ad349bb 4 * @APPLE_LICENSE_OSREFERENCE_HEADER_START@
de355530 5 *
8ad349bb
A
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
10 * License may not be used to create, or enable the creation or
11 * redistribution of, unlawful or unlicensed copies of an Apple operating
12 * system, or to circumvent, violate, or enable the circumvention or
13 * violation of, any terms of an Apple operating system software license
14 * agreement.
15 *
16 * Please obtain a copy of the License at
17 * http://www.opensource.apple.com/apsl/ and read it before using this
18 * file.
19 *
20 * The Original Code and all software distributed under the License are
21 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
22 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
23 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
24 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
25 * Please see the License for the specific language governing rights and
26 * limitations under the License.
27 *
28 * @APPLE_LICENSE_OSREFERENCE_HEADER_END@
de355530 29 */
de355530 30
55e303ae
A
31#include <sys/appleapiopts.h>
32#include <machine/cpu_capabilities.h>
33#include <machine/commpage.h>
91447636
A
34#include <i386/asm.h>
35
36#include <assym.s>
55e303ae
A
37
38 .text
39 .align 2, 0x90
40
41Lmach_absolute_time:
8ad349bb 42
55e303ae
A
43 int $0x3
44 ret
45
8ad349bb 46 COMMPAGE_DESCRIPTOR(mach_absolute_time,_COMM_PAGE_ABSOLUTE_TIME,1,0)
91447636 47
91447636 48
8ad349bb 49Lnanotime:
91447636 50
8ad349bb
A
51 pushl %ebx
52 pushl %esi
53 pushl %edi
54 pushl %ebp
55 movl $(_COMM_PAGE_NANOTIME_INFO), %esi
56
57 /*
58 * The nanotime info consists of:
59 * - base_tsc 64-bit timestamp register value
60 * - base_ns 64-bit corresponding nanosecond uptime value
61 * - scale 32-bit current scale multiplier
62 * - shift 32-bit current shift divider
63 * - check_tsc 64-bit timestamp check value
64 *
65 * This enables an timestamp register's value, tsc, to be converted
66 * into a nanosecond nanotime value, ns:
67 *
68 * ns = base_ns + ((tsc - base_tsc) * scale >> shift)
69 *
70 * The kernel updates this every tick or whenever a performance
71 * speed-step changes the scaling. To avoid locking, a duplicated
72 * sequence counting scheme is used. The base_tsc value is updated
73 * whenever the info starts to be changed, and check_tsc is updated
74 * to the same value at the end of the update. The regularity of
75 * update ensures that (tsc - base_tsc) is a 32-bit quantity.
76 * When a conversion is performed, we read base_tsc before we start
77 * and check_tsc at the end -- if there's a mis-match we repeat.
78 * It's sufficient to compare only the low-order 32-bits.
79 */
c0fea474 80
91447636 811:
8ad349bb
A
82 //
83 // Read nanotime info and stash in registers.
84 //
85 movl NANOTIME_BASE_TSC(%esi), %ebx // ebx := lo(base_tsc)
86 movl NANOTIME_BASE_NS(%esi), %ebp
87 movl NANOTIME_BASE_NS+4(%esi), %edi // edi:ebp := base_ns
88 movl NANOTIME_SHIFT(%esi), %ecx // ecx := shift
89 //
90 // Read timestamp register (tsc) and calculate delta.
91 //
92 rdtsc // edx:eax := tsc
93 subl %ebx, %eax // eax := (tsc - base_tsc)
94 movl NANOTIME_SCALE(%esi), %edx // edx := shift
95 //
96 // Check for consistency and re-read if necessary.
97 //
98 cmpl NANOTIME_CHECK_TSC(%esi), %ebx
91447636 99 jne 1b
8ad349bb
A
100
101 //
102 // edx:eax := ((tsc - base_tsc) * scale)
103 //
104 mull %edx
105
106 //
107 // eax := ((tsc - base_tsc) * scale >> shift)
108 //
109 shrdl %cl, %edx, %eax
110 andb $32, %cl
111 cmovnel %edx, %eax // %eax := %edx if shift == 32
112 xorl %edx, %edx
113
114 //
115 // Add base_ns:
116 // edx:eax = (base_ns + ((tsc - base_tsc) * scale >> shift))
117 //
118 addl %ebp, %eax
119 adcl %edi, %edx
120
121 popl %ebp
122 popl %edi
123 popl %esi
124 popl %ebx
91447636
A
125 ret
126
8ad349bb 127 COMMPAGE_DESCRIPTOR(nanotime,_COMM_PAGE_NANOTIME,1,0)