ia64/xen-unstable

view extras/mini-os/time.c @ 922:fc5ae656dd1e

bitkeeper revision 1.582.1.2 (3fafc1a8WtDmHzijhEouIqSThPp1nA)

xen_netwatch.c:
Fixes to xen_netwatch.
author kaf24@scramble.cl.cam.ac.uk
date Mon Nov 10 16:49:44 2003 +0000 (2003-11-10)
parents b147d210dca8
children aadd0dc51c45
line source
1 /* -*- Mode:C; c-basic-offset:4; tab-width:4 -*-
2 ****************************************************************************
3 * (C) 2003 - Rolf Neugebauer - Intel Research Cambridge
4 ****************************************************************************
5 *
6 * File: time.c
7 * Author: Rolf Neugebauer (neugebar@dcs.gla.ac.uk)
8 * Changes:
9 *
10 * Date: Jul 2003
11 *
12 * Environment: Xen Minimal OS
13 * Description: Simple time and timer functions
14 *
15 ****************************************************************************
16 * $Id: c-insert.c,v 1.7 2002/11/08 16:04:34 rn Exp $
17 ****************************************************************************
18 * Permission is hereby granted, free of charge, to any person obtaining a copy
19 * of this software and associated documentation files (the "Software"), to
20 * deal in the Software without restriction, including without limitation the
21 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
22 * sell copies of the Software, and to permit persons to whom the Software is
23 * furnished to do so, subject to the following conditions:
24 *
25 * The above copyright notice and this permission notice shall be included in
26 * all copies or substantial portions of the Software.
27 *
28 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
29 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
30 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
31 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
32 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
33 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
34 * DEALINGS IN THE SOFTWARE.
35 */
38 #include <os.h>
39 #include <types.h>
40 #include <hypervisor.h>
41 #include <events.h>
42 #include <time.h>
43 #include <lib.h>
45 /************************************************************************
46 * Time functions
47 *************************************************************************/
49 static unsigned int rdtsc_bitshift;
50 static u32 st_scale_f; /* convert ticks -> usecs */
51 static u32 st_scale_i; /* convert ticks -> usecs */
53 /* These are peridically updated in shared_info, and then copied here. */
54 static u32 shadow_tsc_stamp;
55 static s64 shadow_system_time;
56 static u32 shadow_time_version;
57 static struct timeval shadow_tv;
59 #ifndef rmb
60 #define rmb() __asm__ __volatile__ ("lock; addl $0,0(%%esp)": : :"memory")
61 #endif
63 #define HANDLE_USEC_OVERFLOW(_tv) \
64 do { \
65 while ( (_tv).tv_usec >= 1000000 ) \
66 { \
67 (_tv).tv_usec -= 1000000; \
68 (_tv).tv_sec++; \
69 } \
70 } while ( 0 )
72 static void get_time_values_from_xen(void)
73 {
74 do {
75 shadow_time_version = HYPERVISOR_shared_info->time_version2;
76 rmb();
77 shadow_tv.tv_sec = HYPERVISOR_shared_info->wc_sec;
78 shadow_tv.tv_usec = HYPERVISOR_shared_info->wc_usec;
79 shadow_tsc_stamp = HYPERVISOR_shared_info->tsc_timestamp;
80 shadow_system_time = HYPERVISOR_shared_info->system_time;
81 rmb();
82 }
83 while ( shadow_time_version != HYPERVISOR_shared_info->time_version1 );
84 }
87 #define TIME_VALUES_UP_TO_DATE \
88 (shadow_time_version == HYPERVISOR_shared_info->time_version2)
91 static inline unsigned long get_time_delta_usecs(void)
92 {
93 s32 delta_tsc;
94 u32 low;
95 u64 delta, tsc;
97 rdtscll(tsc);
98 low = (u32)(tsc >> rdtsc_bitshift);
99 delta_tsc = (s32)(low - shadow_tsc_stamp);
100 if ( unlikely(delta_tsc < 0) ) delta_tsc = 0;
101 delta = ((u64)delta_tsc * st_scale_f);
102 delta >>= 32;
103 delta += ((u64)delta_tsc * st_scale_i);
105 return (unsigned long)delta;
106 }
109 void gettimeofday(struct timeval *tv)
110 {
111 struct timeval _tv;
113 do {
114 get_time_values_from_xen();
115 _tv.tv_usec = get_time_delta_usecs();
116 _tv.tv_sec = shadow_tv.tv_sec;
117 _tv.tv_usec += shadow_tv.tv_usec;
118 }
119 while ( unlikely(!TIME_VALUES_UP_TO_DATE) );
121 HANDLE_USEC_OVERFLOW(_tv);
122 *tv = _tv;
123 }
126 static void timer_handler(int ev, struct pt_regs *regs)
127 {
128 static int i;
129 struct timeval tv;
131 i++;
132 if (i >= 1000) {
133 gettimeofday(&tv);
134 printf("T(s=%ld us=%ld)\n", tv.tv_sec, tv.tv_usec);
135 i = 0;
136 }
137 }
140 void init_time(void)
141 {
142 u64 __cpu_khz, cpu_freq, scale;
143 unsigned long cpu_khz;
145 __cpu_khz = HYPERVISOR_shared_info->cpu_freq;
146 cpu_khz = (u32) (__cpu_khz/1000);
148 rdtsc_bitshift = HYPERVISOR_shared_info->rdtsc_bitshift;
149 cpu_freq = HYPERVISOR_shared_info->cpu_freq;
151 scale = 1000000LL << (32 + rdtsc_bitshift);
152 scale /= cpu_freq;
154 st_scale_f = scale & 0xffffffff;
155 st_scale_i = scale >> 32;
157 printk("Xen reported: %lu.%03lu MHz processor.\n",
158 cpu_khz / 1000, cpu_khz % 1000);
160 add_ev_action(EV_TIMER, &timer_handler);
161 enable_ev_action(EV_TIMER);
162 enable_hypervisor_event(EV_TIMER);
164 }