The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/Documentation/hpet.txt

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1                 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 <http://www.intel.com/technology/architecture/hpetspec.htm>.
    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 <stdio.h>
   21 #include <stdlib.h>
   22 #include <unistd.h>
   23 #include <fcntl.h>
   24 #include <string.h>
   25 #include <memory.h>
   26 #include <malloc.h>
   27 #include <time.h>
   28 #include <ctype.h>
   29 #include <sys/types.h>
   30 #include <sys/wait.h>
   31 #include <signal.h>
   32 #include <fcntl.h>
   33 #include <errno.h>
   34 #include <sys/time.h>
   35 #include <linux/hpet.h>
   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 <sys/poll.h>
   45 #include <sys/ioctl.h>
   46 #include <signal.h>
   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.

Cache object: 9441064716961524e923933510b7395c


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.