]> git.saurik.com Git - apple/xnu.git/blob - osfmk/i386/commpage/commpage_gettimeofday.s
xnu-792.10.96.tar.gz
[apple/xnu.git] / osfmk / i386 / commpage / commpage_gettimeofday.s
1 /*
2 * Copyright (c) 2003-2006 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * The contents of this file constitute Original Code as defined in and
7 * are subject to the Apple Public Source License Version 1.1 (the
8 * "License"). You may not use this file except in compliance with the
9 * License. Please obtain a copy of the License at
10 * http://www.apple.com/publicsource and read it before using this file.
11 *
12 * This Original Code and all software distributed under the License are
13 * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
14 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
15 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
17 * License for the specific language governing rights and limitations
18 * under the License.
19 *
20 * @APPLE_LICENSE_HEADER_END@
21 */
22
23 #include <sys/appleapiopts.h>
24 #include <machine/cpu_capabilities.h>
25 #include <machine/commpage.h>
26
27 #define NSEC_PER_SEC 1000*1000*1000
28 #define NSEC_PER_USEC 1000
29
30 .text
31 .align 2, 0x90
32
33 Lgettimeofday:
34 push %ebp
35 mov %esp,%ebp
36 push %esi
37 push %edi
38 push %ebx
39
40 0:
41 cmp $0,_COMM_PAGE_TIMEENABLE
42 je 4f
43 mov _COMM_PAGE_TIMEBASE,%esi
44 mov _COMM_PAGE_TIMEBASE+4,%edi
45 mov _COMM_PAGE_TIMESTAMP,%ebx
46
47 mov $ _COMM_PAGE_NANOTIME,%eax
48 call *%eax /* get ns in %edx:%eax */
49
50 cmp _COMM_PAGE_TIMEBASE,%esi
51 jne 0b
52 cmp _COMM_PAGE_TIMEBASE+4,%edi
53 jne 0b
54 cmp $0,_COMM_PAGE_TIMEENABLE
55 je 4f
56
57 mov $ NSEC_PER_SEC,%ecx
58 sub %esi,%eax
59 sbb %edi,%edx
60 div %ecx
61 add %eax,%ebx
62
63 mov $ NSEC_PER_USEC,%ecx
64 mov %edx,%eax
65 xor %edx,%edx
66 div %ecx
67
68 mov 8(%ebp),%ecx
69 mov %ebx,(%ecx)
70 mov %eax,4(%ecx)
71 xor %eax,%eax
72
73 3:
74 pop %ebx
75 pop %edi
76 pop %esi
77 pop %ebp
78 ret
79 4: /* fail */
80 movl $1,%eax
81 jmp 3b
82
83 COMMPAGE_DESCRIPTOR(gettimeofday,_COMM_PAGE_GETTIMEOFDAY,0,0)
84
85
86 .code64
87 .text
88 .align 2, 0x90
89
90 Lgettimeofday_64: // %rdi = ptr to timeval
91 pushq %rbp // set up a frame for backtraces
92 movq %rsp,%rbp
93 movq %rdi,%r9 // save ptr to timeval
94 movq $_COMM_PAGE_32_TO_64(_COMM_PAGE_TIMEBASE),%r10
95 0:
96 cmpl $0,_TIMEENABLE(%r10) // is data valid? (test _COMM_PAGE_TIMEENABLE)
97 jz 4f // no
98 movq _TIMEBASE(%r10),%r11 // get _COMM_PAGE_TIMEBASE
99 movq $_COMM_PAGE_32_TO_64(_COMM_PAGE_NANOTIME),%rax
100 call *%rax // get %rax <- nanotime(), preserving %r9, %r10 and %r11
101 movl _TIMESTAMP(%r10),%r8d // get _COMM_PAGE_TIMESTAMP
102 cmpq _TIMEBASE(%r10),%r11 // has _COMM_PAGE_TIMEBASE changed?
103 jne 0b // loop until we have consistent data
104 cmpl $0,_TIMEENABLE(%r10) // is data valid? (test _COMM_PAGE_TIMEENABLE)
105 jz 4f // no
106
107 movl $ NSEC_PER_SEC,%ecx
108 subq %r11,%rax // generate nanoseconds since timestamp
109 movq %rax,%rdx
110 shrq $32,%rdx // get high half of delta in %edx
111 divl %ecx // %eax <- seconds since timestamp, %edx <- nanoseconds
112 addl %eax,%r8d // add seconds elapsed to timestamp seconds
113
114 movl $ NSEC_PER_USEC,%ecx
115 movl %edx,%eax
116 xorl %edx,%edx
117 divl %ecx // divide residual ns by 1000 to get residual us in %eax
118
119 movq %r8,(%r9) // store 64-bit seconds into timeval
120 movl %eax,8(%r9) // store 32-bit useconds into timeval
121 xorl %eax,%eax // return 0 for success
122 3:
123 popq %rbp
124 ret
125 4: // fail
126 movl $1,%eax
127 jmp 3b
128
129 COMMPAGE_DESCRIPTOR(gettimeofday_64,_COMM_PAGE_GETTIMEOFDAY,0,0)