OpenCores
URL https://opencores.org/ocsvn/or1k_soc_on_altera_embedded_dev_kit/or1k_soc_on_altera_embedded_dev_kit/trunk

Subversion Repositories or1k_soc_on_altera_embedded_dev_kit

[/] [or1k_soc_on_altera_embedded_dev_kit/] [trunk/] [linux-2.6/] [linux-2.6.24/] [Documentation/] [hpet.txt] - Blame information for rev 3

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 3 xianfeng
                High Precision Event Timer Driver for Linux
2
 
3
The High Precision Event Timer (HPET) hardware is the future replacement
4
for the 8254 and Real Time Clock (RTC) periodic timer functionality.
5
Each HPET can have up to 32 timers.  It is possible to configure the
6
first two timers as legacy replacements for 8254 and RTC periodic timers.
7
A specification done by Intel and Microsoft can be found at
8
.
9
 
10
The driver supports detection of HPET driver allocation and initialization
11
of the HPET before the driver module_init routine is called.  This enables
12
platform code which uses timer 0 or 1 as the main timer to intercept HPET
13
initialization.  An example of this initialization can be found in
14
arch/i386/kernel/time_hpet.c.
15
 
16
The driver provides two APIs which are very similar to the API found in
17
the rtc.c driver.  There is a user space API and a kernel space API.
18
An example user space program is provided below.
19
 
20
#include 
21
#include 
22
#include 
23
#include 
24
#include 
25
#include 
26
#include 
27
#include 
28
#include 
29
#include 
30
#include 
31
#include 
32
#include 
33
#include 
34
#include 
35
#include 
36
 
37
 
38
extern void hpet_open_close(int, const char **);
39
extern void hpet_info(int, const char **);
40
extern void hpet_poll(int, const char **);
41
extern void hpet_fasync(int, const char **);
42
extern void hpet_read(int, const char **);
43
 
44
#include 
45
#include 
46
#include 
47
 
48
struct hpet_command {
49
        char            *command;
50
        void            (*func)(int argc, const char ** argv);
51
} hpet_command[] = {
52
        {
53
                "open-close",
54
                hpet_open_close
55
        },
56
        {
57
                "info",
58
                hpet_info
59
        },
60
        {
61
                "poll",
62
                hpet_poll
63
        },
64
        {
65
                "fasync",
66
                hpet_fasync
67
        },
68
};
69
 
70
int
71
main(int argc, const char ** argv)
72
{
73
        int     i;
74
 
75
        argc--;
76
        argv++;
77
 
78
        if (!argc) {
79
                fprintf(stderr, "-hpet: requires command\n");
80
                return -1;
81
        }
82
 
83
 
84
        for (i = 0; i < (sizeof (hpet_command) / sizeof (hpet_command[0])); i++)
85
                if (!strcmp(argv[0], hpet_command[i].command)) {
86
                        argc--;
87
                        argv++;
88
                        fprintf(stderr, "-hpet: executing %s\n",
89
                                hpet_command[i].command);
90
                        hpet_command[i].func(argc, argv);
91
                        return 0;
92
                }
93
 
94
        fprintf(stderr, "do_hpet: command %s not implemented\n", argv[0]);
95
 
96
        return -1;
97
}
98
 
99
void
100
hpet_open_close(int argc, const char **argv)
101
{
102
        int     fd;
103
 
104
        if (argc != 1) {
105
                fprintf(stderr, "hpet_open_close: device-name\n");
106
                return;
107
        }
108
 
109
        fd = open(argv[0], O_RDONLY);
110
        if (fd < 0)
111
                fprintf(stderr, "hpet_open_close: open failed\n");
112
        else
113
                close(fd);
114
 
115
        return;
116
}
117
 
118
void
119
hpet_info(int argc, const char **argv)
120
{
121
}
122
 
123
void
124
hpet_poll(int argc, const char **argv)
125
{
126
        unsigned long           freq;
127
        int                     iterations, i, fd;
128
        struct pollfd           pfd;
129
        struct hpet_info        info;
130
        struct timeval          stv, etv;
131
        struct timezone         tz;
132
        long                    usec;
133
 
134
        if (argc != 3) {
135
                fprintf(stderr, "hpet_poll: device-name freq iterations\n");
136
                return;
137
        }
138
 
139
        freq = atoi(argv[1]);
140
        iterations = atoi(argv[2]);
141
 
142
        fd = open(argv[0], O_RDONLY);
143
 
144
        if (fd < 0) {
145
                fprintf(stderr, "hpet_poll: open of %s failed\n", argv[0]);
146
                return;
147
        }
148
 
149
        if (ioctl(fd, HPET_IRQFREQ, freq) < 0) {
150
                fprintf(stderr, "hpet_poll: HPET_IRQFREQ failed\n");
151
                goto out;
152
        }
153
 
154
        if (ioctl(fd, HPET_INFO, &info) < 0) {
155
                fprintf(stderr, "hpet_poll: failed to get info\n");
156
                goto out;
157
        }
158
 
159
        fprintf(stderr, "hpet_poll: info.hi_flags 0x%lx\n", info.hi_flags);
160
 
161
        if (info.hi_flags && (ioctl(fd, HPET_EPI, 0) < 0)) {
162
                fprintf(stderr, "hpet_poll: HPET_EPI failed\n");
163
                goto out;
164
        }
165
 
166
        if (ioctl(fd, HPET_IE_ON, 0) < 0) {
167
                fprintf(stderr, "hpet_poll, HPET_IE_ON failed\n");
168
                goto out;
169
        }
170
 
171
        pfd.fd = fd;
172
        pfd.events = POLLIN;
173
 
174
        for (i = 0; i < iterations; i++) {
175
                pfd.revents = 0;
176
                gettimeofday(&stv, &tz);
177
                if (poll(&pfd, 1, -1) < 0)
178
                        fprintf(stderr, "hpet_poll: poll failed\n");
179
                else {
180
                        long    data;
181
 
182
                        gettimeofday(&etv, &tz);
183
                        usec = stv.tv_sec * 1000000 + stv.tv_usec;
184
                        usec = (etv.tv_sec * 1000000 + etv.tv_usec) - usec;
185
 
186
                        fprintf(stderr,
187
                                "hpet_poll: expired time = 0x%lx\n", usec);
188
 
189
                        fprintf(stderr, "hpet_poll: revents = 0x%x\n",
190
                                pfd.revents);
191
 
192
                        if (read(fd, &data, sizeof(data)) != sizeof(data)) {
193
                                fprintf(stderr, "hpet_poll: read failed\n");
194
                        }
195
                        else
196
                                fprintf(stderr, "hpet_poll: data 0x%lx\n",
197
                                        data);
198
                }
199
        }
200
 
201
out:
202
        close(fd);
203
        return;
204
}
205
 
206
static int hpet_sigio_count;
207
 
208
static void
209
hpet_sigio(int val)
210
{
211
        fprintf(stderr, "hpet_sigio: called\n");
212
        hpet_sigio_count++;
213
}
214
 
215
void
216
hpet_fasync(int argc, const char **argv)
217
{
218
        unsigned long           freq;
219
        int                     iterations, i, fd, value;
220
        sig_t                   oldsig;
221
        struct hpet_info        info;
222
 
223
        hpet_sigio_count = 0;
224
        fd = -1;
225
 
226
        if ((oldsig = signal(SIGIO, hpet_sigio)) == SIG_ERR) {
227
                fprintf(stderr, "hpet_fasync: failed to set signal handler\n");
228
                return;
229
        }
230
 
231
        if (argc != 3) {
232
                fprintf(stderr, "hpet_fasync: device-name freq iterations\n");
233
                goto out;
234
        }
235
 
236
        fd = open(argv[0], O_RDONLY);
237
 
238
        if (fd < 0) {
239
                fprintf(stderr, "hpet_fasync: failed to open %s\n", argv[0]);
240
                return;
241
        }
242
 
243
 
244
        if ((fcntl(fd, F_SETOWN, getpid()) == 1) ||
245
                ((value = fcntl(fd, F_GETFL)) == 1) ||
246
                (fcntl(fd, F_SETFL, value | O_ASYNC) == 1)) {
247
                fprintf(stderr, "hpet_fasync: fcntl failed\n");
248
                goto out;
249
        }
250
 
251
        freq = atoi(argv[1]);
252
        iterations = atoi(argv[2]);
253
 
254
        if (ioctl(fd, HPET_IRQFREQ, freq) < 0) {
255
                fprintf(stderr, "hpet_fasync: HPET_IRQFREQ failed\n");
256
                goto out;
257
        }
258
 
259
        if (ioctl(fd, HPET_INFO, &info) < 0) {
260
                fprintf(stderr, "hpet_fasync: failed to get info\n");
261
                goto out;
262
        }
263
 
264
        fprintf(stderr, "hpet_fasync: info.hi_flags 0x%lx\n", info.hi_flags);
265
 
266
        if (info.hi_flags && (ioctl(fd, HPET_EPI, 0) < 0)) {
267
                fprintf(stderr, "hpet_fasync: HPET_EPI failed\n");
268
                goto out;
269
        }
270
 
271
        if (ioctl(fd, HPET_IE_ON, 0) < 0) {
272
                fprintf(stderr, "hpet_fasync, HPET_IE_ON failed\n");
273
                goto out;
274
        }
275
 
276
        for (i = 0; i < iterations; i++) {
277
                (void) pause();
278
                fprintf(stderr, "hpet_fasync: count = %d\n", hpet_sigio_count);
279
        }
280
 
281
out:
282
        signal(SIGIO, oldsig);
283
 
284
        if (fd >= 0)
285
                close(fd);
286
 
287
        return;
288
}
289
 
290
The kernel API has three interfaces exported from the driver:
291
 
292
        hpet_register(struct hpet_task *tp, int periodic)
293
        hpet_unregister(struct hpet_task *tp)
294
        hpet_control(struct hpet_task *tp, unsigned int cmd, unsigned long arg)
295
 
296
The kernel module using this interface fills in the ht_func and ht_data
297
members of the hpet_task structure before calling hpet_register.
298
hpet_control simply vectors to the hpet_ioctl routine and has the same
299
commands and respective arguments as the user API.  hpet_unregister
300
is used to terminate usage of the HPET timer reserved by hpet_register.

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.