Back to index

glibc  2.9
Functions
get_clockfreq.c File Reference
#include <ctype.h>
#include <fcntl.h>
#include <string.h>
#include <unistd.h>
#include <dirent.h>
#include <stdlib.h>
#include <sys/ioctl.h>
#include <libc-internal.h>
#include <asm/openpromio.h>
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Functions

static hp_timing_t __get_clockfreq_via_cpuinfo (void)
static hp_timing_t __get_clockfreq_via_proc_openprom (void)
static hp_timing_t __get_clockfreq_via_dev_openprom (void)
hp_timing_t __get_clockfreq (void)

Function Documentation

Definition at line 211 of file get_clockfreq.c.

{
  static hp_timing_t result;

  /* If this function was called before, we know the result.  */
  if (result != 0)
    return result;

  /* We first read the information from the /proc/cpuinfo file.
     It contains at least one line like
       Cpu0ClkTick         : 000000002cb41780
     We search for this line and convert the number in an integer.  */
  result = __get_clockfreq_via_cpuinfo ();
  if (result != 0)
    return result;

  /* If that did not work, try to find an OpenPROM node
     with device_type equal to 'cpu' using /dev/openprom
     and fetch the clock-frequency property from there.  */
  result = __get_clockfreq_via_dev_openprom ();
  if (result != 0)
    return result;

  /* Finally, try the same lookup as above but using /proc/openprom.  */
  result = __get_clockfreq_via_proc_openprom ();

  return result;
}

Here is the call graph for this function:

static hp_timing_t __get_clockfreq_via_cpuinfo ( void  ) [static]

Definition at line 31 of file get_clockfreq.c.

{
  hp_timing_t result;
  int fd;

  result = 0;

  fd = open ("/proc/cpuinfo", O_RDONLY);
  if (fd != -1)
    {
      char buf[8192];
      ssize_t n;

      n = read (fd, buf, sizeof buf);
      if (n > 0)
       {
         char *mhz = memmem (buf, n, "Cpu0ClkTck", 7);

         if (mhz != NULL)
           {
             char *endp = buf + n;

             /* Search for the beginning of the string.  */
             while (mhz < endp
                   && (*mhz < '0' || *mhz > '9')
                   && (*mhz < 'a' || *mhz > 'f')
                   && *mhz != '\n')
              ++mhz;

             while (mhz < endp && *mhz != '\n')
              {
                if ((*mhz >= '0' && *mhz <= '9') ||
                    (*mhz >= 'a' && *mhz <= 'f'))
                  {
                    result <<= 4;
                    if (*mhz >= '0' && *mhz <= '9')
                     result += *mhz - '0';
                    else
                     result += (*mhz - 'a') + 10;
                  }
                ++mhz;
              }
           }
       }

      close (fd);
    }

  return result;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static hp_timing_t __get_clockfreq_via_dev_openprom ( void  ) [static]

Definition at line 159 of file get_clockfreq.c.

{
  hp_timing_t result;
  int obp_dev_fd;

  result = 0;

  obp_dev_fd = open ("/dev/openprom", O_RDONLY);
  if (obp_dev_fd != -1)
    {
      char obp_buf[8192];
      struct openpromio *obp_cmd = (struct openpromio *)obp_buf;
      int ret;

      obp_cmd->oprom_size =
       sizeof (obp_buf) - sizeof (unsigned int);
      *(int *) obp_cmd->oprom_array = 0;
      ret = ioctl (obp_dev_fd, OPROMCHILD, (char *) obp_cmd);
      if (ret == 0)
       {
         int cur_node = *(int *) obp_cmd->oprom_array;

         while (cur_node != 0 && cur_node != -1)
           {
             obp_cmd->oprom_size = sizeof (obp_buf) - sizeof (unsigned int);
             strcpy (obp_cmd->oprom_array, "device_type");
             ret = ioctl (obp_dev_fd, OPROMGETPROP, (char *) obp_cmd);
             if (ret == 0
                && strncmp (obp_cmd->oprom_array, "cpu", 3) == 0)
              {
                obp_cmd->oprom_size = (sizeof (obp_buf)
                                    - sizeof (unsigned int));
                strcpy (obp_cmd->oprom_array, "clock-frequency");
                ret = ioctl (obp_dev_fd, OPROMGETPROP, (char *) obp_cmd);
                if (ret == 0)
                  result =
                    (hp_timing_t) *(unsigned int *) obp_cmd->oprom_array;
              }
             obp_cmd->oprom_size = sizeof (obp_buf) - sizeof (unsigned int);
             *(int *) obp_cmd->oprom_array = cur_node;
             ret = ioctl (obp_dev_fd, OPROMNEXT, (char *) obp_cmd);
             if (ret < 0)
              break;
             cur_node = *(int *)obp_cmd->oprom_array;
           }
       }
    }

  return result;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static hp_timing_t __get_clockfreq_via_proc_openprom ( void  ) [static]

Definition at line 83 of file get_clockfreq.c.

{
  hp_timing_t result;
  int obp_fd;

  result = 0;

  obp_fd = open ("/proc/openprom", O_RDONLY);
  if (obp_fd != -1)
    {
      unsigned long int buf[4096 / sizeof (unsigned long int)];
      struct dirent *dirp = (struct dirent *) buf;
      off_t dbase = (off_t) 0;
      ssize_t len;

      while ((len = getdirentries (obp_fd, (char *) dirp,
                               sizeof (buf), &dbase)) > 0)
       {
         struct dirent *this_dirp = dirp;

         while (len > 0)
           {
             char node[strlen ("/proc/openprom/")
                     + _D_ALLOC_NAMLEN (this_dirp)
                     + strlen ("/clock-frequency")];
             char *prop;
             int fd;

             /* Note that
                 strlen("/clock-frequency") > strlen("/device_type")
             */
             __stpcpy (prop = __stpcpy (__stpcpy (node, "/proc/openprom/"),
                                    this_dirp->d_name),
                     "/device_type");
             fd = open (node, O_RDONLY);
             if (fd != -1)
              {
                char type_string[128];
                int ret;

                ret = read (fd, type_string, sizeof (type_string));
                if (ret > 0 && strncmp (type_string, "'cpu'", 5) == 0)
                  {
                    int clkfreq_fd;

                    __stpcpy (prop, "/clock-frequency");
                    clkfreq_fd = open (node, O_RDONLY);
                    if (fd != -1)
                     {
                       if (read (clkfreq_fd, type_string,
                                sizeof (type_string)) > 0)
                         result = (hp_timing_t)
                           strtoull (type_string, NULL, 16);
                       close (clkfreq_fd);
                     }
                  }
                close (fd);
              }

             if (result != 0)
              break;

             len -= this_dirp->d_reclen;
             this_dirp = (struct dirent *)
              ((char *) this_dirp + this_dirp->d_reclen);
           }
         if (result != 0)
           break;
       }
      close (obp_fd);
    }

  return result;
}

Here is the call graph for this function:

Here is the caller graph for this function: