diff --git a/prog/eeprom/decode-dimms.pl b/prog/eeprom/decode-dimms.pl index 0600ad6a..ea0068cc 100755 --- a/prog/eeprom/decode-dimms.pl +++ b/prog/eeprom/decode-dimms.pl @@ -2,6 +2,7 @@ # # Copyright 1998, 1999 Philip Edelbrock # modified by Christian Zuckschwerdt +# modified by Burkart Lingner # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -29,6 +30,8 @@ # miscellaneous formatting enhancements and bug fixes # clearer HTML output (original patch by Nick Kurshev ) # stop decoding on checksum error by default (--checksum option forces) +# Version 0.8 2005-06-20 Burkart Lingner +# adapted to Kernel 2.6's /sys filesystem # # # EEPROM data decoding for SDRAM DIMM modules. @@ -115,6 +118,47 @@ sub printh ($) # print header w/ given text } } +sub readspd16 ($$) { # reads 16 bytes from SPD-EEPROM + my ($offset, $dimm_i) = @_; + if (-e "/sys/bus/i2c/drivers/eeprom") { + # Kernel 2.6 with sysfs + open (HANDLE, "/sys/bus/i2c/drivers/eeprom/$dimm_i/eeprom") + or die "Cannot open /sys/bus/i2c/drivers/eeprom/$dimm_i/eeprom"; + binmode HANDLE; + seek (HANDLE, $offset, 0); + read (HANDLE, my $eeprom, 16); + close HANDLE; + my @bytes = (); + for my $i ( 0 .. 15 ) { + $_ = ord substr($eeprom, $i, 1); + push(@bytes, $_); + } + return @bytes; + } else { + # Kernel 2.4 with procfs + if ($offset == 0) { # bytes 0..15 + $_=`cat /proc/sys/dev/sensors/$dimm_i/00`; + } elsif ($offset == 16) { # bytes 16..31 + $_=`cat /proc/sys/dev/sensors/$dimm_i/10`; + } elsif ($offset == 32) { # bytes 32..47 + $_=`cat /proc/sys/dev/sensors/$dimm_i/20`; + } elsif ($offset == 48) { # bytes 48..63 + $_=`cat /proc/sys/dev/sensors/$dimm_i/30`; + } elsif ($offset == 64) { # bytes 64..79 + $_=`cat /proc/sys/dev/sensors/$dimm_i/40`; + } elsif ($offset == 80) { # bytes 80..95 + $_=`cat /proc/sys/dev/sensors/$dimm_i/50`; + } elsif ($offset == 96) { # bytes 96..111 + $_=`cat /proc/sys/dev/sensors/$dimm_i/60`; + } elsif ($offset == 112) { # bytes 112..127 + $_=`cat /proc/sys/dev/sensors/$dimm_i/70`; + } else { # illegal offset + $_='255 'x15 . '255'; + } + return split(" "); + } +} + for (@ARGV) { if (/-h/) { print "Usage: $0 [-f|-b|-h]\n\n", @@ -142,34 +186,39 @@ if ($opt_body) printh ' PC DIMM Serial Presence Detect Tester/Decoder -By Philip Edelbrock, Christian Zuckschwerdt and others +By Philip Edelbrock, Christian Zuckschwerdt, Burkart Lingner and others Version 2.6.6 '; my $dimm_count=0; -$_=`ls /proc/sys/dev/sensors/`; +if (-e "/sys/bus/i2c/drivers/eeprom") { $_=`ls /sys/bus/i2c/drivers/eeprom`; } +else { $_=`ls /proc/sys/dev/sensors/`; } my @dimm_list=split(); for my $i ( 0 .. $#dimm_list ) { $_=$dimm_list[$i]; - if (/^eeprom-/) { + if ((-e "/sys/bus/i2c/drivers/eeprom" && /^\d+-\d+$/) || /^eeprom-/) { my $dimm_checksum=0; $dimm_count += 1; print "

" if $opt_html; - printl2 "Decoding EEPROM" , " /proc/sys/dev/sensors/$dimm_list[$i]"; + if (-e "/sys/bus/i2c/drivers/eeprom") { + printl2 "Decoding EEPROM", "/sys/bus/i2c/drivers/eeprom/$dimm_list[$i]"; + } else { + printl2 "Decoding EEPROM", "/proc/sys/dev/sensors/$dimm_list[$i]"; + } print "
" if $opt_html; print "\n" if $opt_html; - if (/^[^-]+-[^-]+-[^-]+-([^-]+)$/) { + if ((-e "/sys/bus/i2c/drivers/eeprom" && /^[^-]+-([^-]+)$/) + || /^[^-]+-[^-]+-[^-]+-([^-]+)$/) { my $dimm_num=$1 - 49; printl "Guessing DIMM is in", "bank $dimm_num"; } # Decode first 16 bytes prints "The Following is Required Data and is Applicable to all DIMM Types"; - $_=`cat /proc/sys/dev/sensors/$dimm_list[$i]/00`; - my @bytes=split(" "); + my @bytes = readspd16(0, $dimm_list[$i]); for my $j ( 0 .. 15 ) { $dimm_checksum = $dimm_checksum + $bytes[$j]; } printl "# of bytes written to SDRAM EEPROM",$bytes[0]; @@ -274,8 +323,7 @@ for my $i ( 0 .. $#dimm_list ) { prints "The Following Apply to SDRAM DIMMs ONLY"; # Decode next 16 bytes - $_=`cat /proc/sys/dev/sensors/$dimm_list[$i]/10`; - @bytes=split(" "); + @bytes = readspd16(16, $dimm_list[$i]); for my $j ( 0 .. 15 ) { $dimm_checksum = $dimm_checksum + $bytes[$j]; } $l = "Burst lengths supported"; @@ -425,8 +473,7 @@ for my $i ( 0 .. $#dimm_list ) { # Decode next 16 bytes (32-47) - $_=`cat /proc/sys/dev/sensors/$dimm_list[$i]/20`; - @bytes=split(" "); + @bytes = readspd16(32, $dimm_list[$i]); for my $j ( 0 .. 15 ) { $dimm_checksum = $dimm_checksum + $bytes[$j]; } prints "The Following are Proposed and Apply to SDRAM DIMMs"; @@ -449,8 +496,7 @@ for my $i ( 0 .. $#dimm_list ) { # That's it for the lower part of an SDRAM EEPROM's memory! # Decode next 16 bytes (48-63) - $_=`cat /proc/sys/dev/sensors/$dimm_list[$i]/30`; - @bytes=split(" "); + @bytes = readspd16(48, $dimm_list[$i]); for my $j ( 0 .. 14 ) { $dimm_checksum = $dimm_checksum + $bytes[$j]; } printl "SPD Revision code ", sprintf("%x", $bytes[14]); @@ -462,8 +508,7 @@ for my $i ( 0 .. $#dimm_list ) { if($bytes[15]==$dimm_checksum || $opt_igncheck) { # Decode next 16 bytes (64-79) - $_=`cat /proc/sys/dev/sensors/$dimm_list[$i]/40`; - @bytes=split(" "); + @bytes = readspd16(64, $dimm_list[$i]); $l = "Manufacturer's JEDEC ID Code"; $temp = sprintf("0x%.2X%.2X%.2X%.2X%.2X%.2X%.2X%.2X\n",$bytes[0],$bytes[1],$bytes[2],$bytes[3],$bytes[4],$bytes[5],$bytes[6],$bytes[7]); @@ -478,8 +523,8 @@ for my $i ( 0 .. $#dimm_list ) { $l = "Manufacurer's Part Number"; # Decode next 16 bytes (80-95) - $_=`cat /proc/sys/dev/sensors/$dimm_list[$i]/50`; - my @bytes2 = split ' '; + my @bytes2= readspd16(80, $dimm_list[$i]); + $temp = pack("c18",$bytes[9],$bytes[10],$bytes[11],$bytes[12],$bytes[13],$bytes[14],$bytes[15], $bytes2[0],$bytes2[1],$bytes2[2],$bytes2[3],$bytes2[4],$bytes2[5],$bytes2[6],$bytes2[7],$bytes2[8],$bytes2[9],$bytes2[10]); printl $l, $temp; @@ -494,13 +539,11 @@ for my $i ( 0 .. $#dimm_list ) { $l = "Assembly Serial Number"; # Decode next 16 bytes (96-111) - $_=`cat /proc/sys/dev/sensors/$dimm_list[$i]/60`; - @bytes=split(" "); + @bytes = readspd16(96, $dimm_list[$i]); $temp = sprintf("0x%.2X%.2X%.2X%.2X\n",$bytes2[15],$bytes[0],$bytes[1],$bytes[2]); # Decode next 16 bytes (112-127) - $_=`cat /proc/sys/dev/sensors/$dimm_list[$i]/70`; - @bytes=split(" "); + @bytes = readspd16(112, $dimm_list[$i]); $l = "Intel Specification for Frequency"; if ($bytes[14] == 102) { printl $l, "66MHz\n"; }