]>
git.saurik.com Git - apple/xnu.git/blob - osfmk/i386/rtclock_asm.h
2 * Copyright (c) 2004-2012 Apple Inc. All rights reserved.
4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
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.
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
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.
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
32 * @APPLE_FREE_COPYRIGHT@
36 * Purpose: Assembly routines for handling the machine dependent
40 #ifndef _I386_RTCLOCK_H_
41 #define _I386_RTCLOCK_H_
43 #include <i386/pal_rtclock_asm.h>
46 * Nanotime returned in %rax.
47 * Computed from tsc based on the scale factor and an implicit 32 bit shift.
48 * This code must match what _rtc_nanotime_read does in
49 * machine_routines_asm.s. Failure to do so can
50 * result in "weird" timing results.
52 * Uses: %rsi, %rdi, %rdx, %rcx
55 movq %gs:CPU_NANOTIME,%rdi ; \
56 PAL_RTC_NANOTIME_READ_FAST()
59 * Add 64-bit delta in register reg to timer pointed to by register treg.
61 #define TIMER_UPDATE(treg,reg,offset) \
62 addq reg,(offset)+TIMER_ALL(treg) /* add timer */
65 * Add time delta to old timer and start new.
66 * Uses: %rsi, %rdi, %rdx, %rcx, %rax
68 #define TIMER_EVENT(old,new) \
69 NANOTIME /* %rax := nanosecs */ ; \
70 movq %rax,%rsi /* save timestamp */ ; \
71 movq %gs:CPU_ACTIVE_THREAD,%rcx /* get thread */ ; \
72 subq (old##_TIMER)+TIMER_TSTAMP(%rcx),%rax /* compute elapsed */; \
73 TIMER_UPDATE(%rcx,%rax,old##_TIMER) /* update timer */ ; \
74 leaq (new##_TIMER)(%rcx),%rcx /* point to new timer */ ; \
75 movq %rsi,TIMER_TSTAMP(%rcx) /* set timestamp */ ; \
76 movq %gs:CPU_PROCESSOR,%rdx /* get processor */ ; \
77 movq %rcx,THREAD_TIMER(%rdx) /* set current timer */ ; \
78 movq %rsi,%rax /* restore timestamp */ ; \
79 subq (old##_STATE)+TIMER_TSTAMP(%rdx),%rax /* compute elapsed */; \
80 TIMER_UPDATE(%rdx,%rax,old##_STATE) /* update timer */ ; \
81 leaq (new##_STATE)(%rdx),%rcx /* point to new state */ ; \
82 movq %rcx,CURRENT_STATE(%rdx) /* set current state */ ; \
83 movq %rsi,TIMER_TSTAMP(%rcx) /* set timestamp */
86 * Update time on user trap entry.
87 * Uses: %rsi, %rdi, %rdx, %rcx, %rax
89 #define TIME_TRAP_UENTRY TIMER_EVENT(USER,SYSTEM)
92 * update time on user trap exit.
93 * Uses: %rsi, %rdi, %rdx, %rcx, %rax
95 #define TIME_TRAP_UEXIT TIMER_EVENT(SYSTEM,USER)
98 * update time on interrupt entry.
99 * Uses: %rsi, %rdi, %rdx, %rcx, %rax
100 * Saves processor state info on stack.
102 #define TIME_INT_ENTRY \
103 NANOTIME /* %rax := nanosecs */ ; \
104 movq %rax,%gs:CPU_INT_EVENT_TIME /* save in cpu data */ ; \
105 movq %rax,%rsi /* save timestamp */ ; \
106 movq %gs:CPU_PROCESSOR,%rdx /* get processor */ ; \
107 movq THREAD_TIMER(%rdx),%rcx /* get current timer */ ; \
108 subq TIMER_TSTAMP(%rcx),%rax /* compute elapsed */ ; \
109 TIMER_UPDATE(%rcx,%rax,0) /* update timer */ ; \
110 movq KERNEL_TIMER(%rdx),%rcx /* get kernel timer */ ; \
111 movq %rsi,TIMER_TSTAMP(%rcx) /* set timestamp */ ; \
112 movq %rsi,%rax /* restore timestamp */ ; \
113 movq CURRENT_STATE(%rdx),%rcx /* get current state */ ; \
114 pushq %rcx /* save state */ ; \
115 subq TIMER_TSTAMP(%rcx),%rax /* compute elapsed */ ; \
116 TIMER_UPDATE(%rcx,%rax,0) /* update timer */ ; \
117 leaq IDLE_STATE(%rdx),%rax /* get idle state */ ; \
118 cmpq %rax,%rcx /* compare current */ ; \
119 je 0f /* skip if equal */ ; \
120 leaq SYSTEM_STATE(%rdx),%rcx /* get system state */ ; \
121 movq %rcx,CURRENT_STATE(%rdx) /* set current state */ ; \
122 0: movq %rsi,TIMER_TSTAMP(%rcx) /* set timestamp */
125 * update time on interrupt exit.
126 * Uses: %rsi, %rdi, %rdx, %rcx, %rax
127 * Restores processor state info from stack.
129 #define TIME_INT_EXIT \
130 NANOTIME /* %rax := nanosecs */ ; \
131 movq %rax,%rsi /* save timestamp */ ; \
132 movq %gs:CPU_PROCESSOR,%rdx /* get processor */ ; \
133 movq KERNEL_TIMER(%rdx),%rcx /* get kernel timer */ ; \
134 subq TIMER_TSTAMP(%rcx),%rax /* compute elapsed */ ; \
135 TIMER_UPDATE(%rcx,%rax,0) /* update timer */ ; \
136 movq THREAD_TIMER(%rdx),%rcx /* interrupted timer */ ; \
137 movq %rsi,TIMER_TSTAMP(%rcx) /* set timestamp */ ; \
138 movq %rsi,%rax /* restore timestamp */ ; \
139 movq CURRENT_STATE(%rdx),%rcx /* get current state */ ; \
140 subq TIMER_TSTAMP(%rcx),%rax /* compute elapsed */ ; \
141 TIMER_UPDATE(%rcx,%rax,0) /* update timer */ ; \
142 popq %rcx /* restore state */ ; \
143 movq %rcx,CURRENT_STATE(%rdx) /* set current state */ ; \
144 movq %rsi,TIMER_TSTAMP(%rcx) /* set timestamp */ ; \
145 movq $0,%gs:CPU_INT_EVENT_TIME /* clear interrupt entry time */
149 * Check for vtimers for task.
150 * task_reg is register pointing to current task
151 * thread_reg is register pointing to current thread
153 #define TASK_VTIMER_CHECK(task_reg,thread_reg) \
154 cmpl $0,TASK_VTIMERS(task_reg) ; \
156 orl $(AST_BSD),%gs:CPU_PENDING_AST /* Set pending AST */ ; \
158 orl $(AST_BSD),TH_AST(thread_reg) /* Set thread AST */ ; \
161 #endif /* _I386_RTCLOCK_H_ */