|
@ -372,19 +372,23 @@ sub real_printl($$) # print a line w/ label and values |
|
|
{ |
|
|
{ |
|
|
my ($label, @values) = @_; |
|
|
my ($label, @values) = @_; |
|
|
local $_; |
|
|
local $_; |
|
|
|
|
|
my $same_values = same_values(@values); |
|
|
|
|
|
|
|
|
|
|
|
# If all values are N/A, don't bother printing |
|
|
|
|
|
return if $values[0] eq "N/A" and $same_values; |
|
|
|
|
|
|
|
|
if ($opt_html) { |
|
|
if ($opt_html) { |
|
|
$label = html_encode($label); |
|
|
$label = html_encode($label); |
|
|
@values = map { html_encode($_) } @values; |
|
|
@values = map { html_encode($_) } @values; |
|
|
print "<tr><td valign=top>$label</td>"; |
|
|
print "<tr><td valign=top>$label</td>"; |
|
|
if ($opt_merge && same_values(@values)) { |
|
|
|
|
|
|
|
|
if ($opt_merge && $same_values) { |
|
|
print "<td colspan=".(scalar @values).">$values[0]</td>"; |
|
|
print "<td colspan=".(scalar @values).">$values[0]</td>"; |
|
|
} else { |
|
|
} else { |
|
|
print "<td>$_</td>" foreach @values; |
|
|
print "<td>$_</td>" foreach @values; |
|
|
} |
|
|
} |
|
|
print "</tr>\n"; |
|
|
print "</tr>\n"; |
|
|
} else { |
|
|
} else { |
|
|
if ($opt_merge && same_values(@values)) { |
|
|
|
|
|
|
|
|
if ($opt_merge && $same_values) { |
|
|
splice(@values, 1); |
|
|
splice(@values, 1); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
@ -473,6 +477,13 @@ sub printl($$) # print a line w/ label and value |
|
|
push @{$dimm[$current]->{output}}, \@output; |
|
|
push @{$dimm[$current]->{output}}, \@output; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
sub printl_cond($$$) # same as printl but conditional |
|
|
|
|
|
{ |
|
|
|
|
|
my ($cond, $label, $value) = @_; |
|
|
|
|
|
return unless $cond || $opt_side_by_side; |
|
|
|
|
|
printl($label, $cond ? $value : "N/A"); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
sub prints($) # print separator w/ given text |
|
|
sub prints($) # print separator w/ given text |
|
|
{ |
|
|
{ |
|
|
my @output = (\&real_prints, @_); |
|
|
my @output = (\&real_prints, @_); |
|
@ -523,7 +534,7 @@ sub decode_sdr_sdram($) |
|
|
if ($ii > 0 && $ii <= 12 && $k > 0) { |
|
|
if ($ii > 0 && $ii <= 12 && $k > 0) { |
|
|
printl("Size", ((1 << $ii) * $k) . " MB"); |
|
|
printl("Size", ((1 << $ii) * $k) . " MB"); |
|
|
} else { |
|
|
} else { |
|
|
printl("INVALID SIZE", $bytes->[3] . "," . $bytes->[4] . "," . |
|
|
|
|
|
|
|
|
printl("Size", "INVALID: " . $bytes->[3] . "," . $bytes->[4] . "," . |
|
|
$bytes->[5] . "," . $bytes->[17]); |
|
|
$bytes->[5] . "," . $bytes->[17]); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
@ -735,30 +746,24 @@ sub decode_sdr_sdram($) |
|
|
if ($bytes->[31] == 0) { $temp .= "(Undefined! -- None Reported!)\n"; } |
|
|
if ($bytes->[31] == 0) { $temp .= "(Undefined! -- None Reported!)\n"; } |
|
|
printl("Row Densities", $temp); |
|
|
printl("Row Densities", $temp); |
|
|
|
|
|
|
|
|
if (($bytes->[32] & 0xf) <= 9) { |
|
|
|
|
|
$temp = (($bytes->[32] & 0x7f) >> 4) + ($bytes->[32] & 0xf) * 0.1; |
|
|
$temp = (($bytes->[32] & 0x7f) >> 4) + ($bytes->[32] & 0xf) * 0.1; |
|
|
printl("Command and Address Signal Setup Time", |
|
|
|
|
|
|
|
|
printl_cond(($bytes->[32] & 0xf) <= 9, |
|
|
|
|
|
"Command and Address Signal Setup Time", |
|
|
(($bytes->[32] >> 7) ? -$temp : $temp) . " ns"); |
|
|
(($bytes->[32] >> 7) ? -$temp : $temp) . " ns"); |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if (($bytes->[33] & 0xf) <= 9) { |
|
|
|
|
|
$temp = (($bytes->[33] & 0x7f) >> 4) + ($bytes->[33] & 0xf) * 0.1; |
|
|
$temp = (($bytes->[33] & 0x7f) >> 4) + ($bytes->[33] & 0xf) * 0.1; |
|
|
printl("Command and Address Signal Hold Time", |
|
|
|
|
|
|
|
|
printl_cond(($bytes->[33] & 0xf) <= 9, |
|
|
|
|
|
"Command and Address Signal Hold Time", |
|
|
(($bytes->[33] >> 7) ? -$temp : $temp) . " ns"); |
|
|
(($bytes->[33] >> 7) ? -$temp : $temp) . " ns"); |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if (($bytes->[34] & 0xf) <= 9) { |
|
|
|
|
|
$temp = (($bytes->[34] & 0x7f) >> 4) + ($bytes->[34] & 0xf) * 0.1; |
|
|
$temp = (($bytes->[34] & 0x7f) >> 4) + ($bytes->[34] & 0xf) * 0.1; |
|
|
printl("Data Signal Setup Time", |
|
|
|
|
|
|
|
|
printl_cond(($bytes->[34] & 0xf) <= 9, "Data Signal Setup Time", |
|
|
(($bytes->[34] >> 7) ? -$temp : $temp) . " ns"); |
|
|
(($bytes->[34] >> 7) ? -$temp : $temp) . " ns"); |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if (($bytes->[35] & 0xf) <= 9) { |
|
|
|
|
|
$temp = (($bytes->[35] & 0x7f) >> 4) + ($bytes->[35] & 0xf) * 0.1; |
|
|
$temp = (($bytes->[35] & 0x7f) >> 4) + ($bytes->[35] & 0xf) * 0.1; |
|
|
printl("Data Signal Hold Time", |
|
|
|
|
|
|
|
|
printl_cond(($bytes->[35] & 0xf) <= 9, "Data Signal Hold Time", |
|
|
(($bytes->[35] >> 7) ? -$temp : $temp) . " ns"); |
|
|
(($bytes->[35] >> 7) ? -$temp : $temp) . " ns"); |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
# Parameter: EEPROM bytes 0-127 (using 3-62) |
|
|
# Parameter: EEPROM bytes 0-127 (using 3-62) |
|
|
sub decode_ddr_sdram($) |
|
|
sub decode_ddr_sdram($) |
|
@ -767,10 +772,8 @@ sub decode_ddr_sdram($) |
|
|
my $temp; |
|
|
my $temp; |
|
|
|
|
|
|
|
|
# SPD revision |
|
|
# SPD revision |
|
|
if ($bytes->[62] != 0xff) { |
|
|
|
|
|
printl("SPD Revision", ($bytes->[62] >> 4) . "." . |
|
|
|
|
|
($bytes->[62] & 0xf)); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
printl_cond($bytes->[62] != 0xff, "SPD Revision", |
|
|
|
|
|
($bytes->[62] >> 4) . "." . ($bytes->[62] & 0xf)); |
|
|
|
|
|
|
|
|
# speed |
|
|
# speed |
|
|
prints("Memory Characteristics"); |
|
|
prints("Memory Characteristics"); |
|
@ -797,7 +800,7 @@ sub decode_ddr_sdram($) |
|
|
if ($ii > 0 && $ii <= 12 && $k > 0) { |
|
|
if ($ii > 0 && $ii <= 12 && $k > 0) { |
|
|
printl("Size", ((1 << $ii) * $k) . " MB"); |
|
|
printl("Size", ((1 << $ii) * $k) . " MB"); |
|
|
} else { |
|
|
} else { |
|
|
printl("INVALID SIZE", $bytes->[3] . ", " . $bytes->[4] . ", " . |
|
|
|
|
|
|
|
|
printl("Size", "INVALID: " . $bytes->[3] . ", " . $bytes->[4] . ", " . |
|
|
$bytes->[5] . ", " . $bytes->[17]); |
|
|
$bytes->[5] . ", " . $bytes->[17]); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
@ -974,7 +977,7 @@ sub decode_ddr2_sdram($) |
|
|
if($ii > 0 && $ii <= 12 && $k > 0) { |
|
|
if($ii > 0 && $ii <= 12 && $k > 0) { |
|
|
printl("Size", ((1 << $ii) * $k) . " MB"); |
|
|
printl("Size", ((1 << $ii) * $k) . " MB"); |
|
|
} else { |
|
|
} else { |
|
|
printl("INVALID SIZE", $bytes->[3] . "," . $bytes->[4] . "," . |
|
|
|
|
|
|
|
|
printl("Size", "INVALID: " . $bytes->[3] . "," . $bytes->[4] . "," . |
|
|
$bytes->[5] . "," . $bytes->[17]); |
|
|
$bytes->[5] . "," . $bytes->[17]); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
@ -1276,7 +1279,7 @@ sub decode_direct_rambus($) |
|
|
if ($ii > 0 && $ii < 16) { |
|
|
if ($ii > 0 && $ii < 16) { |
|
|
printl("Size", (1 << $ii) . " MB"); |
|
|
printl("Size", (1 << $ii) . " MB"); |
|
|
} else { |
|
|
} else { |
|
|
printl("INVALID SIZE", sprintf("0x%02x, 0x%02x", |
|
|
|
|
|
|
|
|
printl("Size", sprintf("INVALID: 0x%02x, 0x%02x", |
|
|
$bytes->[4], $bytes->[5])); |
|
|
$bytes->[4], $bytes->[5])); |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
@ -1296,7 +1299,7 @@ sub decode_rambus($) |
|
|
if ($ii > 0 && $ii < 16) { |
|
|
if ($ii > 0 && $ii < 16) { |
|
|
printl("Size", (1 << $ii) . " MB"); |
|
|
printl("Size", (1 << $ii) . " MB"); |
|
|
} else { |
|
|
} else { |
|
|
printl("INVALID SIZE", sprintf("0x%02x, 0x%02x", |
|
|
|
|
|
|
|
|
printl("Size", "INVALID: " . sprintf("0x%02x, 0x%02x", |
|
|
$bytes->[3], $bytes->[5])); |
|
|
$bytes->[3], $bytes->[5])); |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
@ -1332,18 +1335,17 @@ sub printl_mfg_location_code($) |
|
|
my $code = shift; |
|
|
my $code = shift; |
|
|
my $letter = chr($code); |
|
|
my $letter = chr($code); |
|
|
|
|
|
|
|
|
return unless spd_written($code); |
|
|
|
|
|
# Try the location code as ASCII first, as earlier specifications |
|
|
# Try the location code as ASCII first, as earlier specifications |
|
|
# suggested this. As newer specifications don't mention it anymore, |
|
|
# suggested this. As newer specifications don't mention it anymore, |
|
|
# we still fall back to binary. |
|
|
# we still fall back to binary. |
|
|
printl("Manufacturing Location Code", |
|
|
|
|
|
|
|
|
printl_cond(spd_written($code), "Manufacturing Location Code", |
|
|
$letter =~ m/^[\w\d]$/ ? $letter : sprintf("0x%.2X", $code)); |
|
|
$letter =~ m/^[\w\d]$/ ? $letter : sprintf("0x%.2X", $code)); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
sub printl_mfg_assembly_serial(@) |
|
|
sub printl_mfg_assembly_serial(@) |
|
|
{ |
|
|
{ |
|
|
return unless spd_written(@_); |
|
|
|
|
|
printl("Assembly Serial Number", sprintf("0x%02X%02X%02X%02X", @_)); |
|
|
|
|
|
|
|
|
printl_cond(spd_written(@_), "Assembly Serial Number", |
|
|
|
|
|
sprintf("0x%02X%02X%02X%02X", @_)); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
# Parameter: EEPROM bytes 0-175 (using 117-149) |
|
|
# Parameter: EEPROM bytes 0-175 (using 117-149) |
|
@ -1392,21 +1394,17 @@ sub decode_manufacturing_information($) |
|
|
($temp, $extra) = manufacturer(@{$bytes}[64..71]); |
|
|
($temp, $extra) = manufacturer(@{$bytes}[64..71]); |
|
|
printl("Manufacturer", $temp); |
|
|
printl("Manufacturer", $temp); |
|
|
$temp = manufacturer_data(@{$extra}); |
|
|
$temp = manufacturer_data(@{$extra}); |
|
|
printl("Custom Manufacturer Data", $temp) if defined $temp; |
|
|
|
|
|
|
|
|
printl_cond(defined $temp, "Custom Manufacturer Data", $temp); |
|
|
|
|
|
|
|
|
printl_mfg_location_code($bytes->[72]); |
|
|
printl_mfg_location_code($bytes->[72]); |
|
|
|
|
|
|
|
|
printl("Part Number", part_number(@{$bytes}[73..90])); |
|
|
printl("Part Number", part_number(@{$bytes}[73..90])); |
|
|
|
|
|
|
|
|
if (spd_written(@{$bytes}[91..92])) { |
|
|
|
|
|
printl("Revision Code", |
|
|
|
|
|
|
|
|
printl_cond(spd_written(@{$bytes}[91..92]), "Revision Code", |
|
|
sprintf("0x%02X%02X", @{$bytes}[91..92])); |
|
|
sprintf("0x%02X%02X", @{$bytes}[91..92])); |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if (spd_written(@{$bytes}[93..94])) { |
|
|
|
|
|
printl("Manufacturing Date", |
|
|
|
|
|
|
|
|
printl_cond(spd_written(@{$bytes}[93..94]), "Manufacturing Date", |
|
|
manufacture_date($bytes->[93], $bytes->[94])); |
|
|
manufacture_date($bytes->[93], $bytes->[94])); |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
printl_mfg_assembly_serial(@{$bytes}[95..98]); |
|
|
printl_mfg_assembly_serial(@{$bytes}[95..98]); |
|
|
} |
|
|
} |
|
|