Back to index

lshw  02.16
Classes | Defines | Typedefs | Functions | Variables
device-tree.cc File Reference
#include "version.h"
#include "device-tree.h"
#include "osutils.h"
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <dirent.h>

Go to the source code of this file.

Classes

struct  dimminfo
struct  pmac_mb_def

Defines

#define DIMMINFOSIZE   0x80
#define DEVICETREE   "/proc/device-tree"

Typedefs

typedef __uint8_t dimminfo_buf [DIMMINFOSIZE]

Functions

 __ID ("@(#) $Id: device-tree.cc 2433 2012-01-10 22:01:30Z lyonel $")
static unsigned long get_long (const string &path)
static vector< string > get_strings (const string &path, unsigned int offset=0)
static void scan_devtree_root (hwNode &core)
static void scan_devtree_bootrom (hwNode &core)
static string cpubusinfo (int cpu)
static void scan_devtree_cpu (hwNode &core)
static void scan_devtree_memory (hwNode &core)
static bool get_apple_model (hwNode &n)
static void fix_serial_number (hwNode &n)
bool scan_device_tree (hwNode &n)

Variables

static struct pmac_mb_def []

Class Documentation

struct dimminfo

Definition at line 29 of file device-tree.cc.

Class Members
char serial
__uint16_t version1
__uint16_t version2
__uint8_t version3
struct pmac_mb_def

Definition at line 397 of file device-tree.cc.

Class Members
const char * icon
const char * model
const char * modelname

Define Documentation

#define DEVICETREE   "/proc/device-tree"

Definition at line 36 of file device-tree.cc.

#define DIMMINFOSIZE   0x80

Definition at line 26 of file device-tree.cc.


Typedef Documentation

typedef __uint8_t dimminfo_buf[DIMMINFOSIZE]

Definition at line 27 of file device-tree.cc.


Function Documentation

__ID ( "@(#) $Id: device-tree.cc 2433 2012-01-10 22:01:30Z lyonel $"  )
static string cpubusinfo ( int  cpu) [static]

Definition at line 163 of file device-tree.cc.

{
  char buffer[20];

  snprintf(buffer, sizeof(buffer), "cpu@%d", cpu);

  return string(buffer);
}

Here is the caller graph for this function:

static void fix_serial_number ( hwNode n) [static]

Definition at line 500 of file device-tree.cc.

{
  string serial = n.getSerial();

  if(serial.find('\0')==string::npos) return;     // nothing to do

  n.setSerial(hw::strip(serial.substr(13)) + hw::strip(serial.substr(0,13)));
}

Here is the call graph for this function:

Here is the caller graph for this function:

static bool get_apple_model ( hwNode n) [static]

Definition at line 482 of file device-tree.cc.

{
  string model = n.getProduct();
  if (model == "")
    return false;

  for (unsigned int i = 0; i < sizeof(pmac_mb_defs) / sizeof(pmac_mb_def);
    i++)
  if (model == pmac_mb_defs[i].model)
  {
    n.setProduct(pmac_mb_defs[i].modelname);
    n.addHint("icon", string(pmac_mb_defs[i].icon));
  }

  return false;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static unsigned long get_long ( const string &  path) [static]

Definition at line 38 of file device-tree.cc.

{
  unsigned long result = 0;
  int fd = open(path.c_str(), O_RDONLY);

  if (fd >= 0)
  {
    if(read(fd, &result, sizeof(result)) != sizeof(result))
      result = 0;

    close(fd);
  }

  return result;
}

Here is the caller graph for this function:

static vector< string > get_strings ( const string &  path,
unsigned int  offset = 0 
) [static]

Definition at line 55 of file device-tree.cc.

{
  vector < string > result;
  char *strings = NULL;
  char *curstring = NULL;

  int fd = open(path.c_str(), O_RDONLY);

  if (fd >= 0)
  {
    struct stat buf;

    if (fstat(fd, &buf) == 0)
    {
      strings = (char *) malloc(buf.st_size + 1);
      if (strings)
      {
        memset(strings, 0, buf.st_size + 1);
        if(read(fd, strings, buf.st_size) == buf.st_size)
        {
          curstring = strings + offset;

          while (strlen(curstring))
          {
            result.push_back(string(curstring));
            curstring += strlen(curstring) + 1;
          }
        }

        free(strings);
      }
    }

    close(fd);
  }

  return result;
}

Here is the caller graph for this function:

bool scan_device_tree ( hwNode n)

Definition at line 510 of file device-tree.cc.

{
  hwNode *core = n.getChild("core");

  if (!exists(DEVICETREE))
    return false;

  if (!core)
  {
    n.addChild(hwNode("core", hw::bus));
    core = n.getChild("core");
  }

  n.setProduct(get_string(DEVICETREE "/model"));
  n.addHint("icon", string("motherboard"));

  n.setSerial(get_string(DEVICETREE "/serial-number"));
  if (n.getSerial() == "")
    n.setSerial(get_string(DEVICETREE "/system-id"));
  fix_serial_number(n);

  n.setVendor(get_string(DEVICETREE "/copyright"));

  get_apple_model(n);

  if (core)
  {
    core->addHint("icon", string("board"));
    scan_devtree_root(*core);
    scan_devtree_bootrom(*core);
    scan_devtree_memory(*core);
    scan_devtree_cpu(*core);
    core->addCapability(get_string(DEVICETREE "/compatible"));
  }

  return true;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void scan_devtree_bootrom ( hwNode core) [static]

Definition at line 102 of file device-tree.cc.

{
  if (exists(DEVICETREE "/rom/boot-rom"))
  {
    hwNode bootrom("firmware",
      hw::memory);
    string upgrade = "";
    unsigned long base = 0;
    unsigned long size = 0;

    bootrom.setProduct(get_string(DEVICETREE "/rom/boot-rom/model"));
    bootrom.setDescription("BootROM");
    bootrom.
      setVersion(get_string(DEVICETREE "/rom/boot-rom/BootROM-version"));

    if ((upgrade =
      get_string(DEVICETREE "/rom/boot-rom/write-characteristic")) != "")
    {
      bootrom.addCapability("upgrade");
      bootrom.addCapability(upgrade);
    }

    int fd = open(DEVICETREE "/rom/boot-rom/reg", O_RDONLY);
    if (fd >= 0)
    {
      if(read(fd, &base, sizeof(base)) == sizeof(base))
      {
        if(read(fd, &size, sizeof(size)) != sizeof(size))
          size = 0;
      }
      else
        base = 0;

      bootrom.setPhysId(base);
      bootrom.setSize(size);
      close(fd);
    }

    bootrom.claim();
//bootrom.setLogicalName(DEVICETREE "/rom");
    core.addChild(bootrom);
  }

  if (exists(DEVICETREE "/openprom"))
  {
    hwNode openprom("firmware",
      hw::memory);

    openprom.setProduct(get_string(DEVICETREE "/openprom/model"));

    if (exists(DEVICETREE "/openprom/supports-bootinfo"))
      openprom.addCapability("bootinfo");

//openprom.setLogicalName(DEVICETREE "/openprom");
    openprom.setLogicalName(DEVICETREE);
    openprom.claim();
    core.addChild(openprom);
  }
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void scan_devtree_cpu ( hwNode core) [static]

Definition at line 173 of file device-tree.cc.

{
  struct dirent **namelist;
  int n;
  int currentcpu=0;

  pushd(DEVICETREE "/cpus");
  n = scandir(".", &namelist, selectdir, alphasort);
  popd();
  if (n < 0)
    return;
  else
  {
    for (int i = 0; i < n; i++)
    {
      string basepath =
        string(DEVICETREE "/cpus/") + string(namelist[i]->d_name);
      unsigned long version = 0;
      hwNode cpu("cpu",
        hw::processor);
      struct dirent **cachelist;
      int ncache;

      if (hw::strip(get_string(basepath + "/device_type")) != "cpu")
        break;                                    // oops, not a CPU!

      cpu.setProduct(get_string(basepath + "/name"));
      cpu.setDescription("CPU");
      cpu.claim();
      cpu.setBusInfo(cpubusinfo(currentcpu++));
      cpu.setSize(get_long(basepath + "/clock-frequency"));
      cpu.setClock(get_long(basepath + "/bus-frequency"));
      if (exists(basepath + "/altivec"))
        cpu.addCapability("altivec");

      version = get_long(basepath + "/cpu-version");
      if (version != 0)
      {
        int minor = version & 0x00ff;
        int major = (version & 0xff00) >> 8;
        char buffer[20];

        snprintf(buffer, sizeof(buffer), "%lx.%d.%d",
          (version & 0xffff0000) >> 16, major, minor);
        cpu.setVersion(buffer);

      }
      if (hw::strip(get_string(basepath + "/state")) != "running")
        cpu.disable();

      if (exists(basepath + "/performance-monitor"))
        cpu.addCapability("performance-monitor");

      if (exists(basepath + "/d-cache-size"))
      {
        hwNode cache("cache",
          hw::memory);

        cache.setDescription("L1 Cache");
        cache.setSize(get_long(basepath + "/d-cache-size"));
        if (cache.getSize() > 0)
          cpu.addChild(cache);
      }

      pushd(basepath);
      ncache = scandir(".", &cachelist, selectdir, alphasort);
      popd();
      if (ncache > 0)
      {
        for (int j = 0; j < ncache; j++)
        {
          hwNode cache("cache",
            hw::memory);
          string cachebase = basepath + "/" + cachelist[j]->d_name;

          if (hw::strip(get_string(cachebase + "/device_type")) != "cache" &&
            hw::strip(get_string(cachebase + "/device_type")) != "l2-cache")
            break;                                // oops, not a cache!

          cache.setDescription("L2 Cache");
          cache.setSize(get_long(cachebase + "/d-cache-size"));
          cache.setClock(get_long(cachebase + "/clock-frequency"));

          if (exists(cachebase + "/cache-unified"))
            cache.setDescription(cache.getDescription() + " (unified)");
          else
          {
            hwNode icache = cache;
            cache.setDescription(cache.getDescription() + " (data)");
            icache.setDescription(icache.getDescription() + " (instruction)");
            icache.setSize(get_long(cachebase + "/i-cache-size"));

            if (icache.getSize() > 0)
              cpu.addChild(icache);
          }

          if (cache.getSize() > 0)
            cpu.addChild(cache);

          free(cachelist[j]);
        }
        free(cachelist);
      }

      core.addChild(cpu);

      free(namelist[i]);
    }
    free(namelist);
  }
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void scan_devtree_memory ( hwNode core) [static]

Definition at line 286 of file device-tree.cc.

{
  int currentmc = -1;                             // current memory controller
  hwNode *memory = core.getChild("memory");

  while (true)
  {
    char buffer[10];
    string mcbase;
    vector < string > slotnames;
    vector < string > dimmtypes;
    vector < string > dimmspeeds;
    string reg;
    string dimminfo;

    snprintf(buffer, sizeof(buffer), "%d", currentmc);
    if (currentmc >= 0)
      mcbase = string(DEVICETREE "/memory@") + string(buffer);
    else
      mcbase = string(DEVICETREE "/memory");
    slotnames =
      get_strings(mcbase + string("/slot-names"), sizeof(unsigned long));
    dimmtypes = get_strings(mcbase + string("/dimm-types"));
    dimmspeeds = get_strings(mcbase + string("/dimm-speeds"));
    reg = mcbase + string("/reg");
    dimminfo = mcbase + string("/dimm-info");

    if (slotnames.size() == 0)
    {
      if (currentmc < 0)
      {
        currentmc++;
        continue;
      }
      else
        break;
    }

    if (!memory || (currentmc > 0))
    {
      memory = core.addChild(hwNode("memory", hw::memory));
    }

    if (memory)
    {
      int fd = open(dimminfo.c_str(), O_RDONLY);
      int fd2 = open(reg.c_str(), O_RDONLY);

      if (fd2 >= 0)
      {
        for (unsigned int i = 0; i < slotnames.size(); i++)
        {
          unsigned long base = 0;
          unsigned long size = 0;
          hwNode bank("bank",
            hw::memory);

          if(read(fd2, &base, sizeof(base)) == sizeof(base))
          {
            if(read(fd2, &size, sizeof(size)) != sizeof(size))
              size = 0;
          }
          else
            base = 0;

          if (fd >= 0)
          {
            dimminfo_buf dimminfo;

            if (read(fd, &dimminfo, sizeof(dimminfo)) > 0)
            {
              if (size > 0)
              {
                char dimmversion[20];
                snprintf(dimmversion, sizeof(dimmversion),
                  "%02X%02X,%02X %02X,%02X", dimminfo[0x5b],
                  dimminfo[0x5c], dimminfo[0x5d], dimminfo[0x5e],
                  dimminfo[0x48]);
                bank.setSerial(string((char *) &dimminfo + 0x49, 18));
                bank.setVersion(dimmversion);
              }
            }
          }

          if(size>0)
            bank.addHint("icon", string("memory"));
          bank.setDescription("Memory bank");
          bank.setSlot(slotnames[i]);
//bank.setPhysId(base);
          if (i < dimmtypes.size())
            bank.setDescription(dimmtypes[i]);
          if (i < dimmspeeds.size())
            bank.setProduct(hw::strip(dimmspeeds[i]));
          bank.setSize(size);
          memory->addChild(bank);
        }
        close(fd2);
      }

      if (fd >= 0)
        close(fd);
      currentmc++;
    }
    else
      break;

    memory = NULL;
  }
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void scan_devtree_root ( hwNode core) [static]

Definition at line 96 of file device-tree.cc.

{
  core.setClock(get_long(DEVICETREE "/clock-frequency"));
}

Here is the call graph for this function:

Here is the caller graph for this function:


Variable Documentation

struct pmac_mb_def[] [static]

Definition at line 404 of file device-tree.cc.