Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/samples/timers/hpet_example.c
26278 views
1
// SPDX-License-Identifier: GPL-2.0
2
#include <stdio.h>
3
#include <stdlib.h>
4
#include <unistd.h>
5
#include <fcntl.h>
6
#include <string.h>
7
#include <memory.h>
8
#include <malloc.h>
9
#include <time.h>
10
#include <ctype.h>
11
#include <sys/types.h>
12
#include <sys/wait.h>
13
#include <signal.h>
14
#include <errno.h>
15
#include <sys/time.h>
16
#include <linux/hpet.h>
17
18
19
extern void hpet_open_close(int, const char **);
20
extern void hpet_info(int, const char **);
21
extern void hpet_poll(int, const char **);
22
extern void hpet_fasync(int, const char **);
23
extern void hpet_read(int, const char **);
24
25
#include <sys/poll.h>
26
#include <sys/ioctl.h>
27
28
struct hpet_command {
29
char *command;
30
void (*func)(int argc, const char ** argv);
31
} hpet_command[] = {
32
{
33
"open-close",
34
hpet_open_close
35
},
36
{
37
"info",
38
hpet_info
39
},
40
{
41
"poll",
42
hpet_poll
43
},
44
{
45
"fasync",
46
hpet_fasync
47
},
48
};
49
50
int
51
main(int argc, const char ** argv)
52
{
53
unsigned int i;
54
55
argc--;
56
argv++;
57
58
if (!argc) {
59
fprintf(stderr, "-hpet: requires command\n");
60
return -1;
61
}
62
63
64
for (i = 0; i < (sizeof (hpet_command) / sizeof (hpet_command[0])); i++)
65
if (!strcmp(argv[0], hpet_command[i].command)) {
66
argc--;
67
argv++;
68
fprintf(stderr, "-hpet: executing %s\n",
69
hpet_command[i].command);
70
hpet_command[i].func(argc, argv);
71
return 0;
72
}
73
74
fprintf(stderr, "do_hpet: command %s not implemented\n", argv[0]);
75
76
return -1;
77
}
78
79
void
80
hpet_open_close(int argc, const char **argv)
81
{
82
int fd;
83
84
if (argc != 1) {
85
fprintf(stderr, "hpet_open_close: device-name\n");
86
return;
87
}
88
89
fd = open(argv[0], O_RDONLY);
90
if (fd < 0)
91
fprintf(stderr, "hpet_open_close: open failed\n");
92
else
93
close(fd);
94
95
return;
96
}
97
98
void
99
hpet_info(int argc, const char **argv)
100
{
101
struct hpet_info info;
102
int fd;
103
104
if (argc != 1) {
105
fprintf(stderr, "hpet_info: device-name\n");
106
return;
107
}
108
109
fd = open(argv[0], O_RDONLY);
110
if (fd < 0) {
111
fprintf(stderr, "hpet_info: open of %s failed\n", argv[0]);
112
return;
113
}
114
115
if (ioctl(fd, HPET_INFO, &info) < 0) {
116
fprintf(stderr, "hpet_info: failed to get info\n");
117
goto out;
118
}
119
120
fprintf(stderr, "hpet_info: hi_irqfreq 0x%lx hi_flags 0x%lx ",
121
info.hi_ireqfreq, info.hi_flags);
122
fprintf(stderr, "hi_hpet %d hi_timer %d\n",
123
info.hi_hpet, info.hi_timer);
124
125
out:
126
close(fd);
127
return;
128
}
129
130
void
131
hpet_poll(int argc, const char **argv)
132
{
133
unsigned long freq;
134
int iterations, i, fd;
135
struct pollfd pfd;
136
struct hpet_info info;
137
struct timeval stv, etv;
138
struct timezone tz;
139
long usec;
140
141
if (argc != 3) {
142
fprintf(stderr, "hpet_poll: device-name freq iterations\n");
143
return;
144
}
145
146
freq = atoi(argv[1]);
147
iterations = atoi(argv[2]);
148
149
fd = open(argv[0], O_RDONLY);
150
151
if (fd < 0) {
152
fprintf(stderr, "hpet_poll: open of %s failed\n", argv[0]);
153
return;
154
}
155
156
if (ioctl(fd, HPET_IRQFREQ, freq) < 0) {
157
fprintf(stderr, "hpet_poll: HPET_IRQFREQ failed\n");
158
goto out;
159
}
160
161
if (ioctl(fd, HPET_INFO, &info) < 0) {
162
fprintf(stderr, "hpet_poll: failed to get info\n");
163
goto out;
164
}
165
166
fprintf(stderr, "hpet_poll: info.hi_flags 0x%lx\n", info.hi_flags);
167
168
if (info.hi_flags && (ioctl(fd, HPET_EPI, 0) < 0)) {
169
fprintf(stderr, "hpet_poll: HPET_EPI failed\n");
170
goto out;
171
}
172
173
if (ioctl(fd, HPET_IE_ON, 0) < 0) {
174
fprintf(stderr, "hpet_poll, HPET_IE_ON failed\n");
175
goto out;
176
}
177
178
pfd.fd = fd;
179
pfd.events = POLLIN;
180
181
for (i = 0; i < iterations; i++) {
182
pfd.revents = 0;
183
gettimeofday(&stv, &tz);
184
if (poll(&pfd, 1, -1) < 0)
185
fprintf(stderr, "hpet_poll: poll failed\n");
186
else {
187
long data;
188
189
gettimeofday(&etv, &tz);
190
usec = stv.tv_sec * 1000000 + stv.tv_usec;
191
usec = (etv.tv_sec * 1000000 + etv.tv_usec) - usec;
192
193
fprintf(stderr,
194
"hpet_poll: expired time = 0x%lx\n", usec);
195
196
fprintf(stderr, "hpet_poll: revents = 0x%x\n",
197
pfd.revents);
198
199
if (read(fd, &data, sizeof(data)) != sizeof(data)) {
200
fprintf(stderr, "hpet_poll: read failed\n");
201
}
202
else
203
fprintf(stderr, "hpet_poll: data 0x%lx\n",
204
data);
205
}
206
}
207
208
out:
209
close(fd);
210
return;
211
}
212
213
static int hpet_sigio_count;
214
215
static void
216
hpet_sigio(int val)
217
{
218
fprintf(stderr, "hpet_sigio: called\n");
219
hpet_sigio_count++;
220
}
221
222
void
223
hpet_fasync(int argc, const char **argv)
224
{
225
unsigned long freq;
226
int iterations, i, fd, value;
227
sig_t oldsig;
228
struct hpet_info info;
229
230
hpet_sigio_count = 0;
231
fd = -1;
232
233
if ((oldsig = signal(SIGIO, hpet_sigio)) == SIG_ERR) {
234
fprintf(stderr, "hpet_fasync: failed to set signal handler\n");
235
return;
236
}
237
238
if (argc != 3) {
239
fprintf(stderr, "hpet_fasync: device-name freq iterations\n");
240
goto out;
241
}
242
243
fd = open(argv[0], O_RDONLY);
244
245
if (fd < 0) {
246
fprintf(stderr, "hpet_fasync: failed to open %s\n", argv[0]);
247
return;
248
}
249
250
251
if ((fcntl(fd, F_SETOWN, getpid()) == 1) ||
252
((value = fcntl(fd, F_GETFL)) == 1) ||
253
(fcntl(fd, F_SETFL, value | O_ASYNC) == 1)) {
254
fprintf(stderr, "hpet_fasync: fcntl failed\n");
255
goto out;
256
}
257
258
freq = atoi(argv[1]);
259
iterations = atoi(argv[2]);
260
261
if (ioctl(fd, HPET_IRQFREQ, freq) < 0) {
262
fprintf(stderr, "hpet_fasync: HPET_IRQFREQ failed\n");
263
goto out;
264
}
265
266
if (ioctl(fd, HPET_INFO, &info) < 0) {
267
fprintf(stderr, "hpet_fasync: failed to get info\n");
268
goto out;
269
}
270
271
fprintf(stderr, "hpet_fasync: info.hi_flags 0x%lx\n", info.hi_flags);
272
273
if (info.hi_flags && (ioctl(fd, HPET_EPI, 0) < 0)) {
274
fprintf(stderr, "hpet_fasync: HPET_EPI failed\n");
275
goto out;
276
}
277
278
if (ioctl(fd, HPET_IE_ON, 0) < 0) {
279
fprintf(stderr, "hpet_fasync, HPET_IE_ON failed\n");
280
goto out;
281
}
282
283
for (i = 0; i < iterations; i++) {
284
(void) pause();
285
fprintf(stderr, "hpet_fasync: count = %d\n", hpet_sigio_count);
286
}
287
288
out:
289
signal(SIGIO, oldsig);
290
291
if (fd >= 0)
292
close(fd);
293
294
return;
295
}
296
297