Hello community,

here is the log from the commit of package i2c-tools for openSUSE:Factory 
checked in at 2017-12-23 12:16:23
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/i2c-tools (Old)
 and      /work/SRC/openSUSE:Factory/.i2c-tools.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "i2c-tools"

Sat Dec 23 12:16:23 2017 rev:34 rq:557244 version:4.0

Changes:
--------
--- /work/SRC/openSUSE:Factory/i2c-tools/i2c-tools.changes      2017-11-14 
12:39:06.738693062 +0100
+++ /work/SRC/openSUSE:Factory/.i2c-tools.new/i2c-tools.changes 2017-12-23 
12:16:31.400251875 +0100
@@ -1,0 +2,14 @@
+Tue Dec 12 17:07:54 CET 2017 - [email protected]
+
+- build-tools-add-missing-dependencies.patch: Fix another random
+  failure of parallel builds.
+
+-------------------------------------------------------------------
+Wed Dec  6 16:01:02 CET 2017 - [email protected]
+
+- build-lib-add-missing-dependencies.patch: Fix random failure
+  of parallel builds.
+- decode-dimms-hackweek-DDR4.patch: Add DDR4 SDRAM memory support
+  to decode-dimms (Hackweek 0x10 project.)
+
+-------------------------------------------------------------------

New:
----
  build-lib-add-missing-dependencies.patch
  build-tools-add-missing-dependencies.patch
  decode-dimms-hackweek-DDR4.patch

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ i2c-tools.spec ++++++
--- /var/tmp/diff_new_pack.UrDkGJ/_old  2017-12-23 12:16:32.412202533 +0100
+++ /var/tmp/diff_new_pack.UrDkGJ/_new  2017-12-23 12:16:32.412202533 +0100
@@ -28,6 +28,9 @@
 Source0:        
https://www.kernel.org/pub/software/utils/i2c-tools/%{name}-%{version}.tar.xz
 Source1:        
https://www.kernel.org/pub/software/utils/i2c-tools/%{name}-%{version}.tar.sign
 Patch1:         i2cbusses-path-overflows.patch
+Patch2:         build-lib-add-missing-dependencies.patch
+Patch3:         decode-dimms-hackweek-DDR4.patch
+Patch4:         build-tools-add-missing-dependencies.patch
 BuildRoot:      %{_tmppath}/%{name}-%{version}-build
 ExcludeArch:    s390 s390x
 
@@ -60,6 +63,9 @@
 %prep
 %setup -q
 %patch1 -p1
+%patch2 -p1
+%patch3 -p1
+%patch4 -p1
 
 %build
 make %{?_smp_mflags} CFLAGS="$RPM_OPT_FLAGS" CC="%{__cc}" BUILD_STATIC_LIB:=0

++++++ build-lib-add-missing-dependencies.patch ++++++
From: Jean Delvare <[email protected]>
Date: Wed, 6 Dec 2017 09:55:04 +0100
Subject: lib/Module.mk: Add missing dependencies
Patch-mainline: yes
Git-commit: a6a59693066fd8da81f7107479df3e32a129247d

The lib symlinks lacked a dependency to the actual library file, so
parallel builds could run into a race and break.
---
 lib/Module.mk |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

--- a/lib/Module.mk
+++ b/lib/Module.mk
@@ -42,11 +42,11 @@ endif
 $(LIB_DIR)/$(LIB_SHLIBNAME): $(LIB_DIR)/smbus.o
        $(CC) -shared $(LDFLAGS) -Wl,--version-script=$(LIB_DIR)/libi2c.map 
-Wl,-soname,$(LIB_SHSONAME) -o $@ $^ -lc
 
-$(LIB_DIR)/$(LIB_SHSONAME):
+$(LIB_DIR)/$(LIB_SHSONAME): $(LIB_DIR)/$(LIB_SHLIBNAME)
        $(RM) $@
        $(LN) $(LIB_SHLIBNAME) $@
 
-$(LIB_DIR)/$(LIB_SHBASENAME):
+$(LIB_DIR)/$(LIB_SHBASENAME): $(LIB_DIR)/$(LIB_SHLIBNAME)
        $(RM) $@
        $(LN) $(LIB_SHLIBNAME) $@
 
++++++ build-tools-add-missing-dependencies.patch ++++++
From: Jean Delvare <[email protected]>
Date: Thu, 14 Dec 2017 08:52:26 +0100
Subject: tools/Module.mk: Add missing dependencies
Patch-mainline: yes
Git-commit: 08b0d67ba7eceb862cb17f52eb1911e9579726ea

Better build the library before building the tools which link against
it, otherwise parallel builds could run into a race and break.
---
 lib/Module.mk   |    7 +++++++
 tools/Module.mk |   10 +++++-----
 2 files changed, 12 insertions(+), 5 deletions(-)

--- a/lib/Module.mk
+++ b/lib/Module.mk
@@ -35,6 +35,13 @@ LIB_TARGETS  += $(LIB_STLIBNAME)
 LIB_OBJECTS    += smbus.ao
 endif
 
+# Library file to link against (static or dynamic)
+ifeq ($(USE_STATIC_LIB),1)
+LIB_DEPS       := $(LIB_DIR)/$(LIB_STLIBNAME)
+else
+LIB_DEPS       := $(LIB_DIR)/$(LIB_SHBASENAME)
+endif
+
 #
 # Libraries
 #
--- a/tools/Module.mk
+++ b/tools/Module.mk
@@ -24,19 +24,19 @@ TOOLS_TARGETS       := i2cdetect i2cdump i2cse
 # Programs
 #
 
-$(TOOLS_DIR)/i2cdetect: $(TOOLS_DIR)/i2cdetect.o $(TOOLS_DIR)/i2cbusses.o
+$(TOOLS_DIR)/i2cdetect: $(TOOLS_DIR)/i2cdetect.o $(TOOLS_DIR)/i2cbusses.o 
$(LIB_DEPS)
        $(CC) $(LDFLAGS) -o $@ $^ $(TOOLS_LDFLAGS)
 
-$(TOOLS_DIR)/i2cdump: $(TOOLS_DIR)/i2cdump.o $(TOOLS_DIR)/i2cbusses.o 
$(TOOLS_DIR)/util.o
+$(TOOLS_DIR)/i2cdump: $(TOOLS_DIR)/i2cdump.o $(TOOLS_DIR)/i2cbusses.o 
$(TOOLS_DIR)/util.o $(LIB_DEPS)
        $(CC) $(LDFLAGS) -o $@ $^ $(TOOLS_LDFLAGS)
 
-$(TOOLS_DIR)/i2cset: $(TOOLS_DIR)/i2cset.o $(TOOLS_DIR)/i2cbusses.o 
$(TOOLS_DIR)/util.o
+$(TOOLS_DIR)/i2cset: $(TOOLS_DIR)/i2cset.o $(TOOLS_DIR)/i2cbusses.o 
$(TOOLS_DIR)/util.o $(LIB_DEPS)
        $(CC) $(LDFLAGS) -o $@ $^ $(TOOLS_LDFLAGS)
 
-$(TOOLS_DIR)/i2cget: $(TOOLS_DIR)/i2cget.o $(TOOLS_DIR)/i2cbusses.o 
$(TOOLS_DIR)/util.o
+$(TOOLS_DIR)/i2cget: $(TOOLS_DIR)/i2cget.o $(TOOLS_DIR)/i2cbusses.o 
$(TOOLS_DIR)/util.o $(LIB_DEPS)
        $(CC) $(LDFLAGS) -o $@ $^ $(TOOLS_LDFLAGS)
 
-$(TOOLS_DIR)/i2ctransfer: $(TOOLS_DIR)/i2ctransfer.o $(TOOLS_DIR)/i2cbusses.o 
$(TOOLS_DIR)/util.o
+$(TOOLS_DIR)/i2ctransfer: $(TOOLS_DIR)/i2ctransfer.o $(TOOLS_DIR)/i2cbusses.o 
$(TOOLS_DIR)/util.o $(LIB_DEPS)
        $(CC) $(LDFLAGS) -o $@ $^ $(TOOLS_LDFLAGS)
 
 #
++++++ decode-dimms-hackweek-DDR4.patch ++++++
From: Jean Delvare <[email protected]>
Subject: decode-dimms: Add support for DDR4 SDRAM memory
Patch-mainline: yes
Git-commit: f91ab551fa73e4fe831122fb390ac2166e66af67
Git-commit: 56149a6f847933aa6c51392bfe9d513cbc0e443d
Git-commit: 9ae51c4a4f8e1e1836470ac7e5fec9c7f6df8ce6
Git-commit: 52cd6c60d6db0e39f00a67f5931c06cccb63e178
Git-commit: eea0b508aaefd687ed559992cece05608418c605
Git-commit: 84da8192c7c409f37c1906b60ef166c58aafc847

This is my hackweek 0x10 project:
Add support for DDR4 SDRAM memory modules to decode-dimms

* Add preliminary DDR4 support
* Decode size and timings of DDR4
* Decode misc parameters of DDR4
* Decode physical characteristics of DDR4
* Documentation update for DDR4
* Verify the CRC of DDR4 data block 1
---
 eeprom/decode-dimms   |  326 ++++++++++++++++++++++++++++++++++++++++++++++++--
 eeprom/decode-dimms.1 |    7 -
 2 files changed, 320 insertions(+), 13 deletions(-)

--- a/eeprom/decode-dimms
+++ b/eeprom/decode-dimms
@@ -5,7 +5,7 @@
 # Copyright 1998, 1999 Philip Edelbrock <[email protected]>
 # modified by Christian Zuckschwerdt <[email protected]>
 # modified by Burkart Lingner <[email protected]>
-# Copyright (C) 2005-2013  Jean Delvare <[email protected]>
+# Copyright (C) 2005-2017  Jean Delvare <[email protected]>
 #
 #    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
@@ -1404,6 +1404,7 @@ sub ddr3_mtb_ftb($$$$)
        return $byte1 * $mtb + $byte2 * $ftb / 1000;
 }
 
+# Also works for DDR4
 sub ddr3_reference_card($$)
 {
        my ($rrc, $ext) = @_;
@@ -1702,6 +1703,251 @@ sub decode_ddr3_sdram($)
 
 }
 
+# Return combined time in ns
+sub ddr4_mtb_ftb($$$$)
+{
+       my ($byte1, $byte2, $mtb, $ftb) = @_;
+
+       # byte1 is unsigned in ps, but byte2 is signed in ps
+       $byte2 -= 0x100 if $byte2 & 0x80;
+
+       return ($byte1 * $mtb + $byte2 * $ftb) / 1000;
+}
+
+# Rounded per DDR4 specifications
+sub ddr4_core_timings($$$$$)
+{
+       my ($cas, $ctime, $trcd, $trp, $tras) = @_;
+
+       return $cas . "-" . ceil($trcd/$ctime - 0.025) .
+                     "-" . ceil($trp/$ctime - 0.025) .
+                     "-" . ceil($tras/$ctime - 0.025);
+}
+
+use constant DDR4_UNBUFFERED   => 1;
+use constant DDR4_REGISTERED   => 2;
+use constant DDR4_LOAD_REDUCED => 4;
+
+# Parameter: EEPROM bytes 0-383 (using 1-255)
+sub decode_ddr4_sdram($)
+{
+       my $bytes = shift;
+       my ($ctime, $ctime_max);
+       my ($ftb, $mtb);
+       my $ii;
+
+       my @module_types = (
+               { type => "Extended type",      },
+               { type => "RDIMM",              family => DDR4_REGISTERED },
+               { type => "UDIMM",              family => DDR4_UNBUFFERED },
+               { type => "SO-DIMM",            family => DDR4_UNBUFFERED },
+               { type => "LRDIMM",             family => DDR4_LOAD_REDUCED },
+               { type => "Mini-RDIMM",         family => DDR4_REGISTERED },
+               { type => "Mini-UDIMM",         family => DDR4_UNBUFFERED },
+               { type => "Reserved (0x07)",    },
+               { type => "72b-SO-RDIMM",       family => DDR4_REGISTERED },
+               { type => "72b-SO-UDIMM",       family => DDR4_UNBUFFERED },
+               { type => "Reserved (0x0A)",    },
+               { type => "Reserved (0x0B)",    },
+               { type => "16b-SO-DIMM",        family => DDR4_UNBUFFERED },
+               { type => "32b-SO-DIMM",        family => DDR4_UNBUFFERED },
+               { type => "Reserved (0x0E)",    },
+               { type => "No base memory",     },
+       );
+
+# SPD revision
+       printl_cond($bytes->[1] != 0xff, "SPD Revision",
+                   ($bytes->[1] >> 4) . "." . ($bytes->[1] & 0xf));
+
+       printl("Module Type", $module_types[$bytes->[3] & 0x0f]->{type});
+
+# CRC of block 1
+       my $crc_calc = calculate_crc($bytes, 128, 126);
+       my $crc_spd = ($bytes->[255] << 8) | $bytes->[254];
+       my $crc_block_1_ok = $crc_calc == $crc_spd;
+       printl("EEPROM CRC of bytes 128-253", $crc_block_1_ok ?
+               sprintf("OK (0x\%04X)", $crc_calc) :
+               sprintf("Bad\n(found 0x\%04X, calculated 0x\%04X)",
+                       $crc_spd, $crc_calc));
+
+# time bases
+       if (($bytes->[17] & 0x03) != 0x00 || ($bytes->[17] & 0xc0) != 0x00) {
+               print STDERR "Unknown time base values, can't decode\n";
+               return;
+       }
+       $ftb = 1;       # ps
+       $mtb = 125;     # ps
+
+# speed
+       prints("Memory Characteristics");
+
+       $ctime = ddr4_mtb_ftb($bytes->[18], $bytes->[125], $mtb, $ftb);
+       $ctime_max = ddr4_mtb_ftb($bytes->[19], $bytes->[124], $mtb, $ftb);
+
+       my $ddrclk = 2 * (1000 / $ctime);
+       my $tbits = 8 << ($bytes->[13] & 7);
+       my $pcclk = int ($ddrclk * $tbits / 8);
+       # Round down to comply with Jedec
+       $pcclk = $pcclk - ($pcclk % 100);
+       $ddrclk = int ($ddrclk);
+       printl("Maximum module speed", "$ddrclk MHz (PC4-${pcclk})");
+
+# Size computation
+       my $sdram_width = 4 << ($bytes->[12] & 0x07);
+       my $ranks = (($bytes->[12] >> 3) & 0x07) + 1;
+       my $signal_loading = $bytes->[6] & 0x03;
+       my $die_count = (($bytes->[6] >> 4) & 0x07) + 1;
+       my $cap = (256 << ($bytes->[4] & 0x0f)) / 8;
+       $cap *= (8 << ($bytes->[13] & 0x07)) / $sdram_width;
+       $cap *= $ranks;
+       $cap *= $die_count if $signal_loading == 0x02;          # 3DS
+       printl("Size", $cap . " MB");
+
+       printl("Banks x Rows x Columns x Bits",
+              join(' x ', (1 << ($bytes->[4] >> 6)) * (4 << (($bytes->[4] >> 
4) & 0x03)),
+                          ((($bytes->[5] >> 3) & 7) + 12),
+                          ( ($bytes->[5]       & 7) +  9),
+                          (8 << ($bytes->[13] & 0x07))));
+
+       printl("SDRAM Device Width", "$sdram_width bits");
+       printl("Ranks", $ranks);
+       printl_cond($ranks > 1, "Rank Mix",
+                   $bytes->[12] & 0x40 ? "Asymmetrical" : "Symmetrical");
+       printl_cond($bytes->[13] & 0x18, "Bus Width Extension", ($bytes->[13] & 
0x18)." bits");
+
+       my $taa;
+       my $trcd;
+       my $trp;
+       my $tras;
+
+       $taa  = ddr4_mtb_ftb($bytes->[24], $bytes->[123], $mtb, $ftb);
+       $trcd = ddr4_mtb_ftb($bytes->[25], $bytes->[122], $mtb, $ftb);
+       $trp  = ddr4_mtb_ftb($bytes->[26], $bytes->[121], $mtb, $ftb);
+       $tras = ((($bytes->[27] & 0x0f) << 8) + $bytes->[28]) * $mtb / 1000;
+
+       printl("AA-RCD-RP-RAS (cycles)",
+              ddr4_core_timings(ceil($taa/$ctime - 0.025), $ctime,
+                                $trcd, $trp, $tras));
+
+# latencies
+       my %cas;
+       my $cas_sup = ($bytes->[23] << 24) + ($bytes->[22] << 16) +
+                     ($bytes->[21] << 8) + $bytes->[20];
+       my $base_cas = $bytes->[23] & 0x80 ? 23 : 7;
+
+       for ($ii = 0; $ii < 30; $ii++) {
+               if ($cas_sup & (1 << $ii)) {
+                       $cas{$base_cas + $ii}++;
+               }
+       }
+       printl("Supported CAS Latencies", cas_latencies(keys %cas));
+
+# standard DDR4 speeds
+       prints("Timings at Standard Speeds");
+       foreach my $ctime_at_speed (15/24, 15/22, 15/20, 15/18, 15/16, 15/14, 
15/12) {
+               my $best_cas = 0;
+
+               # Find min CAS latency at this speed
+               for ($ii = 29; $ii >= 0; $ii--) {
+                       next unless ($cas_sup & (1 << $ii));
+                       if (ceil($taa/$ctime_at_speed - 0.025) <= $base_cas + 
$ii) {
+                               $best_cas = $base_cas + $ii;
+                       }
+               }
+
+               printl_cond($best_cas && $ctime_at_speed >= $ctime
+                                     && $ctime_at_speed <= $ctime_max,
+                           "AA-RCD-RP-RAS (cycles)" . as_ddr(4, 
$ctime_at_speed),
+                           ddr4_core_timings($best_cas, $ctime_at_speed,
+                                            $trcd, $trp, $tras));
+       }
+
+# more timing information
+       prints("Timing Parameters");
+
+       printl("Minimum Cycle Time (tCKmin)", tns3($ctime));
+       printl("Maximum Cycle Time (tCKmax)", tns3($ctime_max));
+       printl("Minimum CAS Latency Time (tAA)", tns3($taa));
+       printl("Minimum RAS to CAS Delay (tRCD)", tns3($trcd));
+       printl("Minimum Row Precharge Delay (tRP)", tns3($trp));
+       printl("Minimum Active to Precharge Delay (tRAS)", tns3($tras));
+       printl("Minimum Active to Auto-Refresh Delay (tRC)",
+               tns3(ddr4_mtb_ftb((($bytes->[27] & 0xf0) << 4) + $bytes->[29],
+                                 $bytes->[120], $mtb, $ftb)));
+       printl("Minimum Recovery Delay (tRFC1)",
+               tns3((($bytes->[31] << 8) + $bytes->[30]) * $mtb / 1000));
+       printl("Minimum Recovery Delay (tRFC2)",
+               tns3((($bytes->[33] << 8) + $bytes->[32]) * $mtb / 1000));
+       printl("Minimum Recovery Delay (tRFC4)",
+               tns3((($bytes->[35] << 8) + $bytes->[34]) * $mtb / 1000));
+       printl("Minimum Four Activate Window Delay (tFAW)",
+               tns3(((($bytes->[36] & 0x0f) << 8) + $bytes->[37]) * $mtb / 
1000));
+       printl("Minimum Row Active to Row Active Delay (tRRD_S)",
+               tns3(ddr4_mtb_ftb($bytes->[38], $bytes->[119], $mtb, $ftb)));
+       printl("Minimum Row Active to Row Active Delay (tRRD_L)",
+               tns3(ddr4_mtb_ftb($bytes->[39], $bytes->[118], $mtb, $ftb)));
+       printl("Minimum CAS to CAS Delay (tCCD_L)",
+               tns3(ddr4_mtb_ftb($bytes->[40], $bytes->[117], $mtb, $ftb)));
+
+       # Optional?
+       my $twr = ((($bytes->[41] & 0x0f) << 8) + $bytes->[42]) * $mtb / 1000;
+       printl_cond($twr, "Minimum Write Recovery Time (tWR)", tns3($twr));
+       my $twtr = ((($bytes->[43] & 0x0f) << 8) + $bytes->[44]) * $mtb / 1000;
+       printl_cond($twtr, "Minimum Write to Read Time (tWTR_S)", tns3($twtr));
+       $twtr = ((($bytes->[43] & 0xf0) << 4) + $bytes->[45]) * $mtb / 1000;
+       printl_cond($twtr, "Minimum Write to Read Time (tWTR_L)", tns3($twtr));
+
+# miscellaneous stuff
+       prints("Other Information");
+
+       my $package_type = ($bytes->[6] & 0x80) == 0x00 ? "Monolithic" :
+                          $signal_loading == 0x01 ? "Multi-load stack" :
+                          $signal_loading == 0x02 ? "3DS" : "Unknown";
+       $package_type .= sprintf(" (%u dies)", $die_count) if $die_count >= 2;
+       printl("Package Type", $package_type);
+
+       my @mac = ("Untested",
+                  "700 K", "600 K", "500 K", "400 K", "300 K", "200 K",
+                  undef, "Unlimited");
+       my $mac = $bytes->[7] & 0x0f;
+       printl_cond(defined $mac[$mac], "Maximum Activate Count", $mac[$mac]);
+
+       my $ppr = $bytes->[9] >> 6;
+       printl("Post Package Repair",
+              $ppr == 0x00 ? "Not supported" :
+              $ppr == 0x01 ? "One row per bank group" : "Unknown");
+       printl_cond($ppr != 0x00, "Soft PPR", $bytes->[9] & 0x20 ?
+                   "Supported" : "Not Supported");
+
+       printl("Module Nominal Voltage",
+              $bytes->[11] & 0x01 ? "1.2 V" :
+              $bytes->[11] & 0x02 ? "Unknown (1.2 V endurant)" : "Unknown");
+
+       printl("Thermal Sensor",
+              $bytes->[14] & 0x80 ? "TSE2004 compliant" : "No");
+
+# type-specific settings
+       return unless $crc_block_1_ok || $opt_igncheck;
+
+       if ($module_types[$bytes->[3] & 0x0f]->{family} == DDR4_UNBUFFERED ||
+           $module_types[$bytes->[3] & 0x0f]->{family} == DDR4_REGISTERED ||
+           $module_types[$bytes->[3] & 0x0f]->{family} == DDR4_LOAD_REDUCED) {
+               prints("Physical Characteristics");
+
+               my $height = $bytes->[128] & 0x1f;
+               printl("Module Height",
+                      $height == 0x00 ? "15 mm or less" :
+                      $height == 0x1f ? "more than 45 mm" :
+                      sprintf("%u mm", $height + 15));
+               printl("Module Thickness",
+                      sprintf("%d mm front, %d mm back",
+                              ($bytes->[129] & 0x0f) + 1,
+                              (($bytes->[129] >> 4) & 15) + 1));
+               printl("Module Reference Card",
+                      ddr3_reference_card($bytes->[130], $bytes->[128]));
+       }
+}
+
 # Parameter: EEPROM bytes 0-127 (using 4-5)
 sub decode_direct_rambus($)
 {
@@ -1747,6 +1993,10 @@ sub decode_rambus($)
        "DDR SDRAM"     => \&decode_ddr_sdram,
        "DDR2 SDRAM"    => \&decode_ddr2_sdram,
        "DDR3 SDRAM"    => \&decode_ddr3_sdram,
+       "DDR4 SDRAM"    => \&decode_ddr4_sdram,
+       "DDR4E SDRAM"   => \&decode_ddr4_sdram,
+       "LPDDR4 SDRAM"  => \&decode_ddr4_sdram,
+       "LPDDR4X SDRAM" => \&decode_ddr4_sdram,
        "Direct Rambus" => \&decode_direct_rambus,
        "Rambus"        => \&decode_rambus,
 );
@@ -1819,6 +2069,35 @@ sub decode_ddr3_mfg_data($)
                    sprintf("0x%02X%02X", $bytes->[146], $bytes->[147]));
 }
 
+# Parameter: EEPROM bytes 0-383 (using 320-351)
+sub decode_ddr4_mfg_data($)
+{
+       my $bytes = shift;
+
+       prints("Manufacturer Data");
+
+       printl("Module Manufacturer",
+              manufacturer_ddr3($bytes->[320], $bytes->[321]));
+
+       printl_cond(spd_written(@{$bytes}[350..351]),
+                   "DRAM Manufacturer",
+                   manufacturer_ddr3($bytes->[350], $bytes->[351]));
+
+       printl_mfg_location_code($bytes->[322]);
+
+       printl_cond(spd_written(@{$bytes}[323..324]),
+                   "Manufacturing Date",
+                   manufacture_date($bytes->[323], $bytes->[324]));
+
+       printl_mfg_assembly_serial(@{$bytes}[325..328]);
+
+       printl("Part Number", part_number(@{$bytes}[329..348]));
+
+       printl_cond(spd_written(@{$bytes}[349]),
+                   "Revision Code",
+                   sprintf("0x%02X", $bytes->[349]));
+}
+
 # Parameter: EEPROM bytes 0-127 (using 64-98)
 sub decode_manufacturing_information($)
 {
@@ -1941,8 +2220,14 @@ sub read_hexdump($)
 sub spd_sizes($)
 {
        my $bytes = shift;
+       my $type = $bytes->[2];
 
-       if ($bytes->[2] >= 9) {
+       if ($type == 12 || $type == 14 || $type == 16 || $type == 17) {
+               # DDR4
+               my $spd_len = 256 * (($bytes->[0] >> 4) & 7);
+               my $used = 128 * ($bytes->[0] & 15);
+               return ($spd_len, $used);
+       } elsif ($type >= 9) {
                # For FB-DIMM and newer, decode number of bytes written
                my $spd_len = ($bytes->[0] >> 4) & 7;
                my $size = 64 << ($bytes->[0] & 15);
@@ -2014,15 +2299,14 @@ sub checksum($)
 }
 
 # Calculate and verify CRC
-sub check_crc($)
+sub calculate_crc($$$)
 {
-       my $bytes = shift;
+       my ($bytes, $start, $len) = @_;
        my $crc = 0;
-       my $crc_cover = $bytes->[0] & 0x80 ? 116 : 125;
-       my $crc_ptr = 0;
+       my $crc_ptr = $start;
        my $crc_bit;
 
-       while ($crc_ptr <= $crc_cover) {
+       while ($crc_ptr < $start + $len) {
                $crc = $crc ^ ($bytes->[$crc_ptr] << 8);
                for ($crc_bit = 0; $crc_bit < 8; $crc_bit++) {
                        if ($crc & 0x8000) {
@@ -2033,7 +2317,15 @@ sub check_crc($)
                }
                $crc_ptr++;
        }
-       $crc &= 0xffff;
+
+       return $crc & 0xffff;
+}
+
+sub check_crc($)
+{
+       my $bytes = shift;
+       my $crc_cover = $bytes->[0] & 0x80 ? 116 : 125;
+       my $crc = calculate_crc($bytes, 0, $crc_cover + 1);
 
        my $dimm_crc = ($bytes->[127] << 8) | $bytes->[126];
        return ("EEPROM CRC of bytes 0-$crc_cover",
@@ -2136,7 +2428,9 @@ sub get_dimm_list
        my (@dirs, $dir, $opened, $file, @files);
 
        if ($use_sysfs) {
-               @dirs = ('/sys/bus/i2c/drivers/eeprom', 
'/sys/bus/i2c/drivers/at24');
+               @dirs = ('/sys/bus/i2c/drivers/eeprom',
+                        '/sys/bus/i2c/drivers/at24',
+                        '/sys/bus/i2c/drivers/ee1004');        # DDR4
        } else {
                @dirs = ('/proc/sys/dev/sensors');
        }
@@ -2154,7 +2448,9 @@ sub get_dimm_list
                                # or spd (driver at24)
                                my $attr = sysfs_device_attribute("$dir/$file", 
"name");
                                next unless defined $attr &&
-                                           ($attr eq "eeprom" || $attr eq 
"spd");
+                                           ($attr eq "eeprom" ||
+                                            $attr eq "spd" ||
+                                            $attr eq "ee1004");        # DDR4
                        } else {
                                next unless $file =~ /^eeprom-/;
                        }
@@ -2285,6 +2581,9 @@ for $current (0 .. $#dimm) {
                        "DDR SGRAM", "DDR SDRAM",       # 6, 7
                        "DDR2 SDRAM", "FB-DIMM",        # 8, 9
                        "FB-DIMM Probe", "DDR3 SDRAM",  # 10, 11
+                       "DDR4 SDRAM", "Reserved",       # 12, 13
+                       "DDR4E SDRAM", "LPDDR3 SDRAM",  # 14, 15
+                       "LPDDR4 SDRAM", "LPDDR4X SDRAM", # 16, 17
                );
                if ($bytes[2] < @type_list) {
                        $type = $type_list[$bytes[2]];
@@ -2300,6 +2599,13 @@ for $current (0 .. $#dimm) {
                # Decode DDR3-specific manufacturing data in bytes
                # 117-149
                decode_ddr3_mfg_data(\@bytes)
+       } elsif ($type eq "DDR4 SDRAM" ||
+                $type eq "DDR4E SDRAM" ||
+                $type eq "LPDDR4 SDRAM" ||
+                $type eq "LPDDR4X SDRAM") {
+               # Decode DDR4-specific manufacturing data in bytes
+               # 320-383
+               decode_ddr4_mfg_data(\@bytes)
        } else {
                # Decode next 35 bytes (64-98, common to most
                # memory types)
--- a/eeprom/decode-dimms.1
+++ b/eeprom/decode-dimms.1
@@ -1,6 +1,7 @@
 .\"
 .\"  decode-dimms.1 - manpage for the i2c-tools/decode-dimms utility
 .\"  Copyright (C) 2013  Jaromir Capik
+.\"  Copyright (C) 2017  Jean Delvare
 .\"
 .\"  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
@@ -16,7 +17,7 @@
 .\"  with this program; if not, write to the Free Software Foundation, Inc.,
 .\"  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 .\"
-.TH decode-dimms 1 "Oct 2013" "i2c-tools" "User Commands"
+.TH decode-dimms 1 "Nov 2017" "i2c-tools" "User Commands"
 .SH NAME
 decode-dimms \- decode the information found in memory module SPD EEPROMs
 .SH SYNOPSIS
@@ -31,8 +32,8 @@ The purpose of the
 .B decode-dimms
 tool is to decode the information found in memory module SPD EEPROMs.
 The SPD data is read either from the running system or dump files.
-In the former case, the tool requires either the eeprom kernel module
-or the at24 kernel module to be loaded.
+In the former case, the tool requires a kernel module to be loaded:
+eeprom, at24 or ee1004 (for DDR4 SDRAM.)
 .SH PARAMETERS
 .TP
 .B \-f, --format


Reply via email to