]> git.saurik.com Git - apple/xnu.git/blame - osfmk/i386/commpage/commpage_mach_absolute_time.s
xnu-792.17.14.tar.gz
[apple/xnu.git] / osfmk / i386 / commpage / commpage_mach_absolute_time.s
CommitLineData
de355530 1/*
8f6c56a5 2 * Copyright (c) 2003 Apple Computer, Inc. All rights reserved.
de355530 3 *
8f6c56a5 4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
de355530 5 *
8f6c56a5
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 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
8ad349bb 24 * limitations under the License.
8f6c56a5
A
25 *
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
de355530 27 */
de355530 28
55e303ae
A
29#include <sys/appleapiopts.h>
30#include <machine/cpu_capabilities.h>
31#include <machine/commpage.h>
91447636
A
32#include <i386/asm.h>
33
34#include <assym.s>
55e303ae
A
35
36 .text
37 .align 2, 0x90
38
39Lmach_absolute_time:
8f6c56a5 40
55e303ae
A
41 int $0x3
42 ret
43
8f6c56a5 44 COMMPAGE_DESCRIPTOR(mach_absolute_time,_COMM_PAGE_ABSOLUTE_TIME,1,0)
91447636 45
91447636 46
8f6c56a5 47Lnanotime:
c0fea474 48
8f6c56a5
A
49 pushl %ebx
50 pushl %esi
51 pushl %edi
52 pushl %ebp
53 movl $(_COMM_PAGE_NANOTIME_INFO), %esi
54
55 /*
56 * The nanotime info consists of:
57 * - base_tsc 64-bit timestamp register value
58 * - base_ns 64-bit corresponding nanosecond uptime value
59 * - scale 32-bit current scale multiplier
60 * - shift 32-bit current shift divider
61 * - check_tsc 64-bit timestamp check value
62 *
63 * This enables an timestamp register's value, tsc, to be converted
64 * into a nanosecond nanotime value, ns:
65 *
66 * ns = base_ns + ((tsc - base_tsc) * scale >> shift)
67 *
68 * The kernel updates this every tick or whenever a performance
69 * speed-step changes the scaling. To avoid locking, a duplicated
70 * sequence counting scheme is used. The base_tsc value is updated
71 * whenever the info starts to be changed, and check_tsc is updated
72 * to the same value at the end of the update. The regularity of
73 * update ensures that (tsc - base_tsc) is a 32-bit quantity.
74 * When a conversion is performed, we read base_tsc before we start
75 * and check_tsc at the end -- if there's a mis-match we repeat.
76 * It's sufficient to compare only the low-order 32-bits.
77 */
5d5c5d0d 78
91447636 791:
8f6c56a5
A
80 //
81 // Read nanotime info and stash in registers.
82 //
83 movl NANOTIME_BASE_TSC(%esi), %ebx // ebx := lo(base_tsc)
84 movl NANOTIME_BASE_NS(%esi), %ebp
85 movl NANOTIME_BASE_NS+4(%esi), %edi // edi:ebp := base_ns
86 movl NANOTIME_SHIFT(%esi), %ecx // ecx := shift
87 //
88 // Read timestamp register (tsc) and calculate delta.
89 //
90 rdtsc // edx:eax := tsc
91 subl %ebx, %eax // eax := (tsc - base_tsc)
92 movl NANOTIME_SCALE(%esi), %edx // edx := shift
93 //
94 // Check for consistency and re-read if necessary.
95 //
96 cmpl NANOTIME_CHECK_TSC(%esi), %ebx
91447636 97 jne 1b
8f6c56a5
A
98
99 //
100 // edx:eax := ((tsc - base_tsc) * scale)
101 //
102 mull %edx
103
104 //
105 // eax := ((tsc - base_tsc) * scale >> shift)
106 //
107 shrdl %cl, %edx, %eax
108 andb $32, %cl
109 cmovnel %edx, %eax // %eax := %edx if shift == 32
110 xorl %edx, %edx
111
112 //
113 // Add base_ns:
114 // edx:eax = (base_ns + ((tsc - base_tsc) * scale >> shift))
115 //
116 addl %ebp, %eax
117 adcl %edi, %edx
118
119 popl %ebp
120 popl %edi
121 popl %esi
122 popl %ebx
91447636
A
123 ret
124
8f6c56a5 125 COMMPAGE_DESCRIPTOR(nanotime,_COMM_PAGE_NANOTIME,1,0)