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]));
}
}