Changeset 5543 for i2c-tools/trunk

Show
Ignore:
Timestamp:
12/09/08 14:06:41 (3 years ago)
Author:
khali
Message:

Move checksum to a separate function. Handle CRC of FB-DIMM and DDR3
SDRAM memory modules. Based on an original patch from Paul Goyette.

Location:
i2c-tools/trunk
Files:
2 modified

Legend:

Unmodified
Added
Removed
  • i2c-tools/trunk/CHANGES

    r5533 r5543  
    33 
    44SVN 
     5  decode-dimms: Handle CRC of FB-DIMM and DDR3 SDRAM memory modules 
    56  i2c-stub-from-dump: Use udev settle to speed up initialization 
    67 
  • i2c-tools/trunk/eeprom/decode-dimms

    r5542 r5543  
    12221222} 
    12231223 
     1224# Returns the (total, used) number of bytes in the EEPROM, 
     1225# assuming it is an SPD EEPROM. 
     1226sub spd_sizes($) 
     1227{ 
     1228        my $bytes = shift; 
     1229 
     1230        if ($bytes->[2] >= 9) { 
     1231                # For FB-DIMM and newer, decode number of bytes written 
     1232                my $spd_len = ($bytes->[0] >> 4) & 7; 
     1233                my $size = 64 << ($bytes->[0] & 15); 
     1234                if ($spd_len == 0) { 
     1235                        return ($size, 128); 
     1236                } elsif ($spd_len == 1) { 
     1237                        return ($size, 176); 
     1238                } elsif ($spd_len == 2) { 
     1239                        return ($size, 256); 
     1240                } else { 
     1241                        return (64, 64); 
     1242                } 
     1243        } else { 
     1244                my $size; 
     1245                if ($bytes->[1] <= 14) { 
     1246                        $size = 1 << $bytes->[1]; 
     1247                } elsif ($bytes->[1] == 0) { 
     1248                        $size = "RFU"; 
     1249                } else { $size = "ERROR!" } 
     1250 
     1251                return ($size, ($bytes->[0] < 64) ? 64 : $bytes->[0]); 
     1252        } 
     1253} 
     1254 
    12241255sub readspd($$) # reads bytes from SPD-EEPROM 
    12251256{ 
     
    12481279} 
    12491280 
     1281# Calculate and verify checksum of first 63 bytes 
     1282sub checksum($) 
     1283{ 
     1284        my $bytes = shift; 
     1285        my $dimm_checksum = 0; 
     1286        local $_; 
     1287 
     1288        $dimm_checksum += $bytes->[$_] foreach (0 .. 62); 
     1289        $dimm_checksum &= 0xff; 
     1290 
     1291        return ("EEPROM Checksum of bytes 0-62", 
     1292                ($bytes->[63] == $dimm_checksum) ? 1 : 0, 
     1293                sprintf('0x%02X', $bytes->[63]), 
     1294                sprintf('0x%02X', $dimm_checksum)); 
     1295} 
     1296 
     1297# Calculate and verify CRC 
     1298sub check_crc($) 
     1299{ 
     1300        my $bytes = shift; 
     1301        my $crc = 0; 
     1302        my $crc_cover = $bytes->[0] & 0x80 ? 116 : 125; 
     1303        my $crc_ptr = 0; 
     1304        my $crc_bit; 
     1305 
     1306        while ($crc_ptr <= $crc_cover) { 
     1307                $crc = $crc ^ ($bytes->[$crc_ptr] << 8); 
     1308                for ($crc_bit = 0; $crc_bit < 8; $crc_bit++) { 
     1309                        if ($crc & 0x8000) { 
     1310                                $crc = ($crc << 1) ^ 0x1021; 
     1311                        } else { 
     1312                                $crc = $crc << 1 
     1313                        } 
     1314                } 
     1315                $crc_ptr++; 
     1316        } 
     1317        $crc &= 0xffff; 
     1318 
     1319        my $dimm_crc = ($bytes->[127] << 8) | $bytes->[126]; 
     1320        return ("EEPROM CRC of bytes 0-$crc_cover", 
     1321                ($dimm_crc == $crc) ? 1 : 0, 
     1322                sprintf("0x%04X", $dimm_crc), 
     1323                sprintf("0x%04X", $crc)); 
     1324} 
     1325 
    12501326# Parse command-line 
    12511327foreach (@ARGV) { 
     
    13341410         || $use_hexdump) { 
    13351411                my @bytes = readspd(128, $dimm_list[$i]); 
    1336                 my $dimm_checksum = 0; 
    1337                 $dimm_checksum += $bytes[$_] foreach (0 .. 62); 
    1338                 $dimm_checksum &= 0xff; 
    1339  
    1340                 next unless $bytes[63] == $dimm_checksum || $opt_igncheck; 
     1412                my ($spd_size, $spd_used) = spd_sizes(\@bytes); 
     1413                my ($l, $chk_valid, $chk_spd, $chk_calc); 
     1414                if ($bytes[2] < 9) { 
     1415                        ($l, $chk_valid, $chk_spd, $chk_calc) = 
     1416                                checksum(\@bytes); 
     1417                } else { 
     1418                        ($l, $chk_valid, $chk_spd, $chk_calc) = 
     1419                                check_crc(\@bytes); 
     1420                } 
     1421 
     1422                next unless $chk_valid || $opt_igncheck; 
    13411423                $dimm_count++; 
    13421424 
     
    13591441                prints "SPD EEPROM Information"; 
    13601442 
    1361                 my $l = "EEPROM Checksum of bytes 0-62"; 
    1362                 printl $l, ($bytes[63] == $dimm_checksum ? 
    1363                         sprintf("OK (0x%.2X)", $bytes[63]): 
    1364                         sprintf("Bad\n(found 0x%.2X, calculated 0x%.2X)\n", 
    1365                                 $bytes[63], $dimm_checksum)); 
     1443                printl $l, ($chk_valid ? 
     1444                        sprintf("OK (%s)", $chk_calc) : 
     1445                        sprintf("Bad\n(found %s, calculated %s)\n", 
     1446                                $chk_spd, $chk_calc)); 
    13661447 
    13671448                # Simple heuristic to detect Rambus 
     
    13751456                        printl "SPD Revision", $temp; 
    13761457                } else { 
    1377                         printl "# of bytes written to SDRAM EEPROM", 
    1378                                $bytes[0]; 
     1458                        printl "# of bytes written to SDRAM EEPROM", $spd_used; 
    13791459                } 
    13801460 
    13811461                $l = "Total number of bytes in EEPROM"; 
    1382                 if ($bytes[1] <= 14) { 
    1383                         printl $l, 2**$bytes[1]; 
    1384                 } elsif ($bytes[1] == 0) { 
    1385                         printl $l, "RFU"; 
    1386                 } else { printl $l, "ERROR!"; } 
     1462                printl $l, $spd_size; 
    13871463 
    13881464                $l = "Fundamental Memory type"; 
    1389                 my $type = "Unknown"; 
     1465                my $type = sprintf("Unknown (0x%02x)", $bytes[2]); 
    13901466                if ($is_rambus) { 
    13911467                        if ($bytes[2] == 1) { $type = "Direct Rambus"; } 
    13921468                        elsif ($bytes[2] == 17) { $type = "Rambus"; } 
    13931469                } else { 
    1394                         if ($bytes[2] == 1) { $type = "FPM DRAM"; } 
    1395                         elsif ($bytes[2] == 2) { $type = "EDO"; } 
    1396                         elsif ($bytes[2] == 3) { $type = "Pipelined Nibble"; } 
    1397                         elsif ($bytes[2] == 4) { $type = "SDR SDRAM"; } 
    1398                         elsif ($bytes[2] == 5) { $type = "Multiplexed ROM"; } 
    1399                         elsif ($bytes[2] == 6) { $type = "DDR SGRAM"; } 
    1400                         elsif ($bytes[2] == 7) { $type = "DDR SDRAM"; } 
    1401                         elsif ($bytes[2] == 8) { $type = "DDR2 SDRAM"; } 
     1470                        my @type_list = ( 
     1471                                "Reserved", "FPM DRAM",         # 0, 1 
     1472                                "EDO", "Pipelined Nibble",      # 2, 3 
     1473                                "SDR SDRAM", "Multiplexed ROM", # 4, 5 
     1474                                "DDR SGRAM", "DDR SDRAM",       # 6, 7 
     1475                                "DDR2 SDRAM", "FB-DIMM",        # 8, 9 
     1476                                "FB-DIMM Probe", "DDR3 SDRAM",  # 10, 11 
     1477                        ); 
     1478                        if ($bytes[2] < @type_list) { 
     1479                                $type = $type_list[$bytes[2]]; 
     1480                        } 
    14021481                } 
    14031482                printl $l, $type;