@@ -2278,6 +2278,48 @@ sub decode_ddr4_mfg_data($)
sprintf("0x%02X", $bytes->[349]));
}
+# Parameter: EEPROM bytes 0-639 (using 512-554)
+sub decode_ddr5_mfg_data($)
+{
+ my $bytes = shift;
+
+ prints("Manufacturer Data");
+
+ printl("Module Manufacturer",
+ manufacturer_ddr3($bytes->[512], $bytes->[513]));
+
+ printl_cond(spd_written(@{$bytes}[552..553]),
+ "DRAM Manufacturer",
+ manufacturer_ddr3($bytes->[552], $bytes->[553]));
+
+ printl_mfg_location_code($bytes->[514]);
+
+ printl_cond(spd_written(@{$bytes}[515..516]),
+ "Manufacturing Date",
+ manufacture_date($bytes->[515], $bytes->[516]));
+
+ printl_mfg_assembly_serial(@{$bytes}[517..520]);
+
+ printl("Part Number", part_number(@{$bytes}[521..550]));
+
+ printl_cond(spd_written(@{$bytes}[551]),
+ "Revision Code",
+ sprintf("0x%02X", $bytes->[551]));
+
+ if ($bytes->[554] != 0xff) {
+ # DRAM Stepping may be a number or an uppercase ASCII letter
+ # 0x00-0xfe is valid, 0xff is invalid
+ my $stepping = $bytes->[554];
+ if ($stepping < 0x41 || $stepping > 0x5a) {
+ printl("DRAM Stepping",
+ sprintf("0x%02X", $stepping));
+ } else {
+ printl("DRAM Stepping",
+ sprintf("%c", $stepping));
+ }
+ }
+}
+
# Parameter: EEPROM bytes 0-127 (using 64-98)
sub decode_manufacturing_information($)
{
@@ -2828,6 +2870,15 @@ for $current (0 .. $#dimm) {
} elsif (!$use_hexdump && $dimm[$current]->{driver} ne "ee1004") {
print STDERR "HINT: You should be using the ee1004 driver instead of the $dimm[$current]->{driver} driver\n";
}
+ } elsif ($type eq "DDR5 SDRAM" ||
+ $type eq "LPDDR5 SDRAM" ||
+ $type eq "DDR5 NVDIMM-P" ||
+ $type eq "LPDDR5X SDRAM") {
+ if (@bytes >= 640) {
+ # Decode DDR5-specific manufacturing data in bytes
+ # 512-639
+ decode_ddr5_mfg_data(\@bytes);
+ }
} else {
# Decode next 35 bytes (64-98, common to most
# memory types)