Hi,

Here's a small patch for the decode-dimms script to make it work on OS X. Instead of device nodes, the EEPROM content can be read with the ioreg(8) command there.

Tested on a G5 iMac and a G4 PowerBook, both running OS X 10.4.11.

Regards,
Michael

--
Message composed with
VIM - Vi IMproved 7.2 (2008 Aug 9, compiled Jan 10 2009 20:59:41)
--- decode-dimms.orig   2009-05-13 12:16:44.000000000 +0200
+++ decode-dimms        2009-05-14 21:36:57.000000000 +0200
@@ -47,6 +47,8 @@
 use constant LITTLEENDIAN      => "little-endian";
 use constant BIGENDIAN         => "big-endian";
 
+use constant DARWIN                    => $^O eq "darwin";
+
 $revision = '$Revision$ ($Date$)';
 $revision =~ s/\$\w+: (.*?) \$/$1/g;
 $revision =~ s/ \([^()]*\)//;
@@ -1549,25 +1551,28 @@
 {
        my ($offset, $size, $dimm_i) = @_;
        my @bytes;
+       my $dimm_file = $dimm_i->{file};
        if ($use_hexdump) {
-               @bytes = read_hexdump($dimm_i);
+               @bytes = read_hexdump($dimm_file);
                return @bytes[$offset..($offset + $size - 1)];
+       } elsif (DARWIN) {
+               return @{$dimm_i->{bytes}}[$offset..($offset + $size - 1)];
        } elsif ($use_sysfs) {
                # Kernel 2.6 with sysfs
-               sysopen(HANDLE, "$dimm_i/eeprom", O_RDONLY)
-                       or die "Cannot open $dimm_i/eeprom";
+               sysopen(HANDLE, "$dimm_file/eeprom", O_RDONLY)
+                       or die "Cannot open $dimm_file/eeprom";
                binmode HANDLE;
                sysseek(HANDLE, $offset, SEEK_SET)
-                       or die "Cannot seek $dimm_i/eeprom";
+                       or die "Cannot seek $dimm_file/eeprom";
                sysread(HANDLE, my $eeprom, $size)
-                       or die "Cannot read $dimm_i/eeprom";
+                       or die "Cannot read $dimm_file/eeprom";
                close HANDLE;
                @bytes = unpack("C*", $eeprom);
        } else {
                # Kernel 2.4 with procfs
                for my $i (0 .. ($size-1)/16) {
                        my $hexoff = sprintf('%02x', $offset + $i * 16);
-                       push @bytes, split(" ", `cat $dimm_i/$hexoff`);
+                       push @bytes, split(" ", `cat $dimm_file/$hexoff`);
                }
        }
        return @bytes;
@@ -1700,7 +1705,29 @@
 {
        my ($dir, $file, @files);
 
-       if ($use_sysfs) {
+       if (DARWIN) {
+               # On OS X we query the I/O registry to get the EEPROM data
+               my (@dimm_info, @slot_names);
+
+               open IOREG, "ioreg -n memory -w 0 -p IODeviceTree |"
+                       or die "Cannot read device tree: $!";
+               while(<IOREG>) {
+                       if(m/"dimm-info"\s*=\s*<(.*)>/) {
+                               @dimm_info = unpack "(a256)*", $1;
+                       } elsif(m/"slot-names"\s*=\s*<[\da-fA-F]{8}(.*)>/) {
+                               @slot_names = split(/\0/, pack("H*", $1));
+                       }
+               }
+               close IOREG;
+               foreach my $i (0..$#dimm_info) {
+                       my @bytes = unpack("C*", pack("H*", $dimm_info[$i]));
+                       push @files, {
+                               file => $slot_names[$i],
+                               eeprom => $slot_names[$i],
+                               bytes => \...@bytes }
+               }
+               return @files;
+       } elsif ($use_sysfs) {
                $dir = '/sys/bus/i2c/drivers/eeprom';
        } else {
                $dir = '/proc/sys/dev/sensors';
@@ -1735,7 +1762,7 @@
 @dimm = get_dimm_list() unless $use_hexdump;
 
 for my $i (0 .. $#dimm) {
-       my @bytes = readspd(0, 128, $dimm[$i]->{file});
+       my @bytes = readspd(0, 128, $dimm[$i]);
        $dimm[$i]->{bytes} = \...@bytes;
        $dimm[$i]->{is_rambus} = $bytes[0] < 4;         # Simple heuristic
        if ($dimm[$i]->{is_rambus} || $bytes[2] < 9) {
@@ -1801,8 +1828,7 @@
                # read it now.  DDR3 will need this data.
                if ($spd_used > @bytes) {
                        push (@bytes,
-                             readspd(@bytes, $spd_used - @bytes,
-                                     $dimm[$current]->{file}));
+                             readspd(@bytes, $spd_used - @bytes, 
$dimm[$current]));
                }
        }
 

Reply via email to