forked from SDL-Hercules-390/hyperion
-
Notifications
You must be signed in to change notification settings - Fork 0
/
clock.h
140 lines (114 loc) · 4.53 KB
/
clock.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
/* CLOCK.H (c) Copyright Jan Jaeger, 2000-2009 */
/* TOD Clock functions */
// $Id$
//
// $Log$
// Revision 1.28 2007/12/11 15:03:10 rbowler
// Fix untab columns
//
// Revision 1.27 2007/12/10 23:12:02 gsmith
// Tweaks to OPTION_MIPS_COUNTING processing
//
// Revision 1.26 2007/11/21 22:55:49 fish
// (untab)
//
// Revision 1.25 2007/06/23 00:04:04 ivan
// Update copyright notices to include current year (2007)
//
// Revision 1.24 2006/12/08 09:43:18 jj
// Add CVS message log
//
#if !defined(_CLOCK_C_)
#define _CLOCK_EXTERN extern
#else
#undef _CLOCK_EXTERN
#define _CLOCK_EXTERN
#endif
#if !defined(_CLOCK_H_)
#define _CLOCK_H_
/* Clock Steering Registers */
typedef struct _CSR {
U64 start_time;
S64 base_offset;
S32 fine_s_rate;
S32 gross_s_rate;
} CSR;
void csr_reset(void); /* Reset cs registers */
void set_tod_steering(double); /* Set steering rate */
double get_tod_steering(void); /* Get steering rate */
U64 update_tod_clock(void); /* Update the TOD clock */
void update_cpu_timer(void); /* Update the CPU timer */
void set_tod_epoch(S64); /* Set TOD epoch */
void adjust_tod_epoch(S64); /* Adjust TOD epoch */
S64 get_tod_epoch(void); /* Get TOD epoch */
U64 hw_clock(void); /* Get hardware clock */
S64 cpu_timer(REGS *); /* Retrieve CPU timer */
void set_cpu_timer(REGS *, S64); /* Set CPU timer */
S32 int_timer(REGS *); /* Get interval timer */
void set_int_timer(REGS *, S32); /* Set interval timer */
U64 tod_clock(REGS *); /* Get TOD clock */
void set_tod_clock(U64); /* Set TOD clock */
int chk_int_timer(REGS *); /* Check int_timer pending */
int clock_hsuspend(void *file); /* Hercules suspend */
int clock_hresume(void *file); /* Hercules resume */
static __inline__ U64 host_tod(void)
{
struct timeval tv;
gettimeofday (&tv, NULL);
return (U64)tv.tv_sec*1000000 + tv.tv_usec;
}
#endif
DLL_EXPORT void ARCH_DEP(store_int_timer) (REGS *);
void ARCH_DEP(store_int_timer_nolock) (REGS *);
DLL_EXPORT void ARCH_DEP(fetch_int_timer) (REGS *);
void ARCH_DEP(set_gross_s_rate) (REGS *);
void ARCH_DEP(set_fine_s_rate) (REGS *);
void ARCH_DEP(set_tod_offset) (REGS *);
void ARCH_DEP(adjust_tod_offset) (REGS *);
void ARCH_DEP(query_physical_clock) (REGS *);
void ARCH_DEP(query_steering_information) (REGS *);
void ARCH_DEP(query_tod_offset) (REGS *);
void ARCH_DEP(query_available_functions) (REGS *);
_CLOCK_EXTERN U64 tod_value; /* Bits 0-7 TOD clock epoch */
/* Bits b-63 TOD bits 0-55 */
_CLOCK_EXTERN S64 tod_epoch; /* Bits 0-7 TOD clock epoch */
/* Bits 8-63 offset bits 0-55*/
_CLOCK_EXTERN U64 hw_tod; /* Hardware clock */
#define SECONDS_IN_SEVENTY_YEARS ((70*365 + 17) * 86400ULL)
#define TOD_4YEARS (1461*24*60*60*16000000LL)
#define TOD_LYEAR (366*24*60*60*16000000LL)
#define TOD_YEAR (365*24*60*60*16000000LL)
#define TOD_DAY (24*60*60*16000000LL)
#define TOD_HOUR (60*60*16000000LL)
#define TOD_MIN (60*16000000LL)
#define TOD_SEC (16000000LL)
#define TOD_USEC (16LL)
#define ITIMER_TO_TOD(_units) \
((S64)(625*((S64)(_units))/3))
#define TOD_TO_ITIMER(_units) \
((S32)(3*(_units)/625))
#define TOD_CLOCK(_regs) \
(tod_value + (_regs)->tod_epoch)
#define CPU_TIMER(_regs) \
((S64)((_regs)->cpu_timer - hw_tod))
#define INT_TIMER(_regs) \
((S32)TOD_TO_ITIMER((S64)((_regs)->int_timer - hw_tod)))
#define ITIMER_ACCESS(_addr, _len) \
(unlikely(unlikely((_addr) < 84) && (((_addr) + (_len)) >= 80)))
#undef ITIMER_UPDATE
#undef ITIMER_SYNC
#if defined(FEATURE_INTERVAL_TIMER)
#define ITIMER_UPDATE(_addr, _len, _regs) \
do { \
if( ITIMER_ACCESS((_addr), (_len)) ) \
ARCH_DEP(fetch_int_timer) ((_regs)); \
} while(0)
#define ITIMER_SYNC(_addr, _len, _regs) \
do { \
if( ITIMER_ACCESS((_addr), (_len)) ) \
ARCH_DEP(store_int_timer) ((_regs)); \
} while (0)
#else
#define ITIMER_UPDATE(_addr, _len, _regs)
#define ITIMER_SYNC(_addr, _len, _regs)
#endif