* [PATCH 2/3] ddr_spd: add routine for printing DDR2 SPD contents in human-readable format
2015-07-03 15:58 [PATCH 0/3] add spd_decode command (SPD EEPROM data decoder) Alexander Smirnov
2015-07-03 15:58 ` [PATCH 1/3] common: move DDR_SPD to common/Kconfig Alexander Smirnov
@ 2015-07-03 15:58 ` Alexander Smirnov
2015-07-13 9:44 ` Sascha Hauer
2015-07-03 15:58 ` [PATCH 3/3] commands: add spd_decode command Alexander Smirnov
2015-07-06 11:37 ` [PATCH 0/3] add spd_decode command (SPD EEPROM data decoder) Sascha Hauer
3 siblings, 1 reply; 6+ messages in thread
From: Alexander Smirnov @ 2015-07-03 15:58 UTC (permalink / raw)
To: Sascha Hauer; +Cc: barebox, Alexander Smirnov
---=== SPD EEPROM Information ===---
EEPROM Checksum of bytes 0-62 OK (0xDF)
Total number of bytes in EEPROM 256
Fundamental Memory type DDR2 SDRAM
SPD Revision 1.2
---=== Memory Characteristics ===---
Maximum module speed 800 MHz (PC2-6400)
Size 2048 MB
Banks x Rows x Columns x Bits 8 x 14 x 10 x 64
Ranks 2
SDRAM Device Width 8 bits
Module Height 30.0 mm
Module Type SO-DIMM (67.6 mm)
DRAM Package Planar
Voltage Interface Level SSTL 1.8V
Module Configuration Type No Parity
Refresh Rate Reduced (7.8 us) - Self Refresh
Supported Burst Lengths 4, 8
Supported CAS Latencies (tCL) 6T
tCL-tRCD-tRP-tRAS 6-6-6-18 as DDR2-800
Minimum Cycle Time 2.5 ns at CAS 6
Maximum Access Time 0.40 ns at CAS 6
Maximum Cycle Time (tCK max) 8 ns
---=== Timing Parameters ===---
Address/Command Setup Time Before Clock (tIS) 0.17 ns
Address/Command Hold Time After Clock (tIH) 0.25 ns
Data Input Setup Time Before Strobe (tDS) 0.05 ns
Data Input Hold Time After Strobe (tDH) 0.12 ns
Minimum Row Precharge Delay (tRP) 15.00 ns
Minimum Row Active to Row Active Delay (tRRD) 7.50 ns
Minimum RAS# to CAS# Delay (tRCD) 15.00 ns
Minimum RAS# Pulse Width (tRAS) 45.00 ns
Write Recovery Time (tWR) 15.00 ns
Minimum Write to Read CMD Delay (tWTR) 7.50 ns
Minimum Read to Pre-charge CMD Delay (tRTP) 7.50 ns
Minimum Active to Auto-refresh Delay (tRC) 60.00 ns
Minimum Recovery Delay (tRFC) 127 ns
Maximum DQS to DQ Skew (tDQSQ) 0.20 ns
Maximum Read Data Hold Skew (tQHS) 0.30 ns
---=== Manufacturing Information ===---
Manufacturer JEDEC ID 7f 98 00 00 00 00 00 00
Manufacturing Location Code 0x05
Part Number
Manufacturing Date 2014-W47
Assembly Serial Number 0x43266892
Signed-off-by: Alexander Smirnov <alllecs@yandex.ru>
---
common/ddr_spd.c | 296 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
include/ddr_spd.h | 1 +
2 files changed, 297 insertions(+)
diff --git a/common/ddr_spd.c b/common/ddr_spd.c
index ea0b529..39f383b 100644
--- a/common/ddr_spd.c
+++ b/common/ddr_spd.c
@@ -61,3 +61,299 @@ uint32_t ddr3_spd_checksum_pass(const struct ddr3_spd_eeprom_s *spd)
return 0;
}
+
+static char *heights[] = {
+ "<25.4",
+ "25.4",
+ "25.4 - 30.0",
+ "30.0",
+ "30.5",
+ "> 30.5",
+};
+
+static char *sdram_voltage_interface_level[] = {
+ "TTL (5V tolerant)",
+ "LVTTL (not 5V tolerant)",
+ "HSTL 1.5V",
+ "SSTL 3.3V",
+ "SSTL 2.5V",
+ "SSTL 1.8V",
+};
+
+static char *ddr2_module_types[] = {
+ "RDIMM (133.35 mm)",
+ "UDIMM (133.25 mm)",
+ "SO-DIMM (67.6 mm)",
+ "Micro-DIMM (45.5 mm)",
+ "Mini-RDIMM (82.0 mm)",
+ "Mini-UDIMM (82.0 mm)",
+};
+
+static char *refresh[] = {
+ "15.625",
+ "3.9",
+ "7.8",
+ "31.3",
+ "62.5",
+ "125",
+};
+
+static char *type_list[] = {
+ "Reserved",
+ "FPM DRAM",
+ "EDO",
+ "Pipelined Nibble",
+ "SDR SDRAM",
+ "Multiplexed ROM",
+ "DDR SGRAM",
+ "DDR SDRAM",
+ [SPD_MEMTYPE_DDR2] = "DDR2 SDRAM",
+ "FB-DIMM",
+ "FB-DIMM Probe",
+ [SPD_MEMTYPE_DDR3] = "DDR3 SDRAM",
+};
+
+static int funct(uint8_t addr)
+{
+ int t;
+
+ t = ((addr >> 4) * 10 + (addr & 0xf));
+
+ return t;
+}
+
+static int des(uint8_t byte)
+{
+ int k;
+
+ k = (byte & 0x3) * 100 / 4;
+
+ return k;
+}
+
+static int integ(uint8_t byte)
+{
+ int k;
+
+ k = (byte >> 2);
+
+ return k;
+}
+
+static int ddr2_sdram_ctime(uint8_t byte)
+{
+ int ctime;
+
+ ctime = (byte >> 4) * 100;
+ if ((byte & 0xf) <= 9)
+ ctime += (byte & 0xf) * 10;
+ else if ((byte & 0xf) == 10)
+ ctime += 25;
+ else if ((byte & 0xf) == 11)
+ ctime += 33;
+ else if ((byte & 0xf) == 12)
+ ctime += 66;
+ else if ((byte & 0xf) == 13)
+ ctime += 75;
+
+ return ctime;
+}
+
+/*
+ * Based on
+ * https://github.com/groeck/i2c-tools/blob/master/eeprom/decode-dimms
+ */
+void ddr_spd_print(uint8_t *record)
+{
+ int highestCAS = 0;
+ int cas[256];
+ int i, i_i, k, x, y;
+ int ddrclk, tbits, pcclk;
+ int trcd, trp, tras;
+ int ctime;
+ uint8_t parity;
+ char *ref, *sum;
+ struct ddr2_spd_eeprom_s *s = (struct ddr2_spd_eeprom_s *)record;
+
+ if (s->mem_type != SPD_MEMTYPE_DDR2) {
+ printf("Can't dump information for non-DDR2 memory\n");
+ return;
+ }
+
+ ctime = ddr2_sdram_ctime(s->clk_cycle);
+ ddrclk = 2 * (100000 / ctime);
+ tbits = (s->res_7 << 8) + (s->dataw);
+ if ((s->config & 0x03) == 1)
+ tbits = tbits - 8;
+
+ pcclk = ddrclk * tbits / 8;
+ pcclk = pcclk - (pcclk % 100);
+ i_i = (s->nrow_addr & 0x0f) + (s->ncol_addr & 0x0f) - 17;
+ k = ((s->mod_ranks & 0x7) + 1) * s->nbanks;
+ trcd = ((s->trcd >> 2) + ((s->trcd & 3) * 0.25)) * 100 / ctime;
+ trp = ((s->trp >> 2) + ((s->trp & 3) * 0.25)) * 100 / ctime;
+ tras = s->tras * 100 / ctime ;
+ x = (int)(ctime / 100);
+ y = (ctime - (int)((ctime / 100) * 100)) / 10;
+
+ for (i_i = 2; i_i < 7; i_i++) {
+ if (s->cas_lat & 1 << i_i) {
+ highestCAS = i_i;
+ cas[highestCAS]++;
+ }
+ }
+
+ if (ddr2_spd_checksum_pass(s))
+ sum = "ERR";
+ else
+ sum = "OK";
+
+ printf("---=== SPD EEPROM Information ===---\n");
+ printf("%-48s %s (0x%02X)\n", "EEPROM Checksum of bytes 0-62",
+ sum, s->cksum);
+ printf("%-48s %d\n", "# of bytes written to SDRAM EEPROM",
+ s->info_size);
+ printf("%-48s %d\n", "Total number of bytes in EEPROM",
+ 1 << (s->chip_size));
+
+ if (s->mem_type < ARRAY_SIZE(type_list))
+ printf("%-48s %s\n", "Fundamental Memory type",
+ type_list[s->mem_type]);
+ else
+ printf("%-48s (%02x)\n", "Warning: unknown memory type",
+ s->mem_type);
+
+ printf("%-48s %x.%x\n", "SPD Revision", s->spd_rev >> 4,
+ s->spd_rev & 0x0f);
+
+ printf("\n---=== Memory Characteristics ===---\n");
+ printf("%-48s %d MHz (PC2-%d)\n", "Maximum module speed",
+ ddrclk, pcclk);
+ if (i_i > 0 && i_i <= 12 && k > 0)
+ printf("%-48s %d MB\n", "Size", (1 << i_i) * k);
+ else
+ printf("%-48s INVALID: %02x %02x %02x %02x\n", "Size",
+ s->nrow_addr, s->ncol_addr, s->mod_ranks, s->nbanks);
+
+ printf("%-48s %d x %d x %d x %d\n", "Banks x Rows x Columns x Bits",
+ s->nbanks, s->nrow_addr, s->ncol_addr, s->dataw);
+ printf("%-48s %d\n", "Ranks", (s->mod_ranks & 0x7) + 1);
+ printf("%-48s %d bits\n", "SDRAM Device Width", s->primw);
+
+ if (s->mod_ranks >> 5 < ARRAY_SIZE(heights))
+ printf("%-48s %s mm\n", "Module Height",
+ heights[s->mod_ranks >> 5]);
+ else
+ printf("Error height\n");
+
+ if ((fls(s->dimm_type) - 1) < ARRAY_SIZE(ddr2_module_types))
+ printf("%-48s %s\n", "Module Type",
+ ddr2_module_types[fls(s->dimm_type) - 1]);
+ else
+ printf("Error module type\n");
+
+ printf("%-48s ", "DRAM Package ");
+ if ((s->mod_ranks & 0x10) == 1)
+ printf("Stack\n");
+ else
+ printf("Planar\n");
+ if (s->voltage < ARRAY_SIZE(sdram_voltage_interface_level))
+ printf("%-48s %s\n", "Voltage Interface Level",
+ sdram_voltage_interface_level[s->voltage]);
+ else
+ printf("Error Voltage Interface Level\n");
+
+ printf("%-48s ", "Module Configuration Type ");
+
+ parity = s->config & 0x07;
+ if (parity == 0)
+ printf("No Parity\n");
+
+ if ((parity & 0x03) == 0x01)
+ printf("Data Parity\n");
+ if (parity & 0x02)
+ printf("Data ECC\n");
+
+ if (parity & 0x04)
+ printf("Address/Command Parity\n");
+
+ if ((s->refresh >> 7) == 1)
+ ref = "- Self Refresh";
+ else
+ ref = " ";
+
+ printf("%-48s Reduced (%s us) %s\n", "Refresh Rate",
+ refresh[s->refresh & 0x7f], ref);
+ printf("%-48s %d, %d\n", "Supported Burst Lengths",
+ s->burstl & 4, s->burstl & 8);
+
+ printf("%-48s %dT\n", "Supported CAS Latencies (tCL)", highestCAS);
+ printf("%-48s %d-%d-%d-%d as DDR2-%d\n", "tCL-tRCD-tRP-tRAS",
+ highestCAS, trcd, trp, tras, ddrclk);
+ printf("%-48s %d.%d ns at CAS %d\n", "Minimum Cycle Time", x, y,
+ highestCAS);
+ printf("%-48s 0.%d%d ns at CAS %d\n", "Maximum Access Time",
+ (s->clk_access >> 4), (s->clk_access & 0xf), highestCAS);
+ printf("%-48s %d ns\n", "Maximum Cycle Time (tCK max)",
+ (s->tckmax >> 4) + (s->tckmax & 0x0f));
+
+ printf("\n---=== Timing Parameters ===---\n");
+ printf("%-48s 0.%d ns\n",
+ "Address/Command Setup Time Before Clock (tIS)",
+ funct(s->ca_setup));
+ printf("%-48s 0.%d ns\n", "Address/Command Hold Time After Clock (tIH)",
+ funct(s->ca_hold));
+ printf("%-48s 0.%d%d ns\n", "Data Input Setup Time Before Strobe (tDS)",
+ s->data_setup >> 4, s->data_setup & 0xf);
+ printf("%-48s 0.%d%d ns\n", "Data Input Hold Time After Strobe (tDH)",
+ s->data_hold >> 4, s->data_hold & 0xf);
+
+ printf("%-48s %d.%02d ns\n", "Minimum Row Precharge Delay (tRP)",
+ integ(s->trp), des(s->trp));
+ printf("%-48s %d.%02d ns\n",
+ "Minimum Row Active to Row Active Delay (tRRD)",
+ integ(s->trrd), des(s->trrd));
+ printf("%-48s %d.%02d ns\n", "Minimum RAS# to CAS# Delay (tRCD)",
+ integ(s->trcd), des(s->trcd));
+ printf("%-48s %d.00 ns\n", "Minimum RAS# Pulse Width (tRAS)",
+ ((s->tras & 0xfc) + (s->tras & 0x3)));
+ printf("%-48s %d.%02d ns\n", "Write Recovery Time (tWR)",
+ integ(s->twr), des(s->twr));
+ printf("%-48s %d.%02d ns\n", "Minimum Write to Read CMD Delay (tWTR)",
+ integ(s->twtr), des(s->twtr));
+ printf("%-48s %d.%02d ns\n",
+ "Minimum Read to Pre-charge CMD Delay (tRTP)",
+ integ(s->trtp), des(s->trtp));
+ printf("%-48s %d.00 ns\n", "Minimum Active to Auto-refresh Delay (tRC)",
+ s->trc);
+ printf("%-48s %d ns\n", "Minimum Recovery Delay (tRFC)", s->trfc);
+ printf("%-48s 0.%d ns\n", "Maximum DQS to DQ Skew (tDQSQ)", s->tdqsq);
+ printf("%-48s 0.%d ns\n", "Maximum Read Data Hold Skew (tQHS)",
+ s->tqhs);
+
+ printf("\n---=== Manufacturing Information ===---\n");
+
+ printf("%-48s", "Manufacturer JEDEC ID");
+ for (i = 64; i < 72; i++)
+ printf(" %02x", record[i]);
+
+ printf("\n");
+ if (s->mloc)
+ printf("%-48s 0x%02x\n", "Manufacturing Location Code",
+ s->mloc);
+
+ printf("%-48s ", "Part Number");
+ for (i = 73; i < 91; i++) {
+ if (record[i] >= 32 && record[i] < 127)
+ printf("%c", record[i]);
+ else
+ printf("%d", record[i]);
+ }
+ printf("\n");
+ printf("%-48s 20%d-W%d\n", "Manufacturing Date", record[93],
+ record[94]);
+ printf("%-48s 0x", "Assembly Serial Number");
+ for (i = 95; i < 99; i++)
+ printf("%02X", record[i]);
+ printf("\n");
+}
diff --git a/include/ddr_spd.h b/include/ddr_spd.h
index fc03bac..01fe73c 100644
--- a/include/ddr_spd.h
+++ b/include/ddr_spd.h
@@ -228,6 +228,7 @@ struct ddr3_spd_eeprom_s {
uint8_t cust[80]; /* 176-255 Open for Customer Use */
};
+extern void ddr_spd_print(uint8_t *record);
extern uint32_t ddr3_spd_checksum_pass(const struct ddr3_spd_eeprom_s *spd);
extern uint32_t ddr2_spd_checksum_pass(const struct ddr2_spd_eeprom_s *spd);
--
2.1.4
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH 3/3] commands: add spd_decode command
2015-07-03 15:58 [PATCH 0/3] add spd_decode command (SPD EEPROM data decoder) Alexander Smirnov
2015-07-03 15:58 ` [PATCH 1/3] common: move DDR_SPD to common/Kconfig Alexander Smirnov
2015-07-03 15:58 ` [PATCH 2/3] ddr_spd: add routine for printing DDR2 SPD contents in human-readable format Alexander Smirnov
@ 2015-07-03 15:58 ` Alexander Smirnov
2015-07-06 11:37 ` [PATCH 0/3] add spd_decode command (SPD EEPROM data decoder) Sascha Hauer
3 siblings, 0 replies; 6+ messages in thread
From: Alexander Smirnov @ 2015-07-03 15:58 UTC (permalink / raw)
To: Sascha Hauer; +Cc: barebox, Alexander Smirnov
spd_decode command is used for decoding and printing
in human-readable format the information found
in memory module SPD EEPROMs.
There is the decode-dimms program from i2c-tools linux
package (see http://www.lm-sensors.org/wiki/I2CTools)
just for the same purpose.
Though spd_decode source code is based on decode-dimms
perl code there is a difference.
Timing Parameters section output format is slightly
differ from decode-dimms' format; to check the difference:
1. patch defaultenv-2-base/bin/init
--- a/defaultenv/defaultenv-2-base/bin/init
+++ b/defaultenv/defaultenv-2-base/bin/init
@@ -1,5 +1,8 @@
#!/bin/sh
+spd_decode /dev/spd
+reset
+
export PATH=/env/bin
global hostname
and compile sandbox barebox.
2. use this script to check decode-dimms vs spd_decode output:
NAME=$1
HEXNAME=${NAME}.hex
ADDR1=${NAME}_decode_perl
ADDR2=${NAME}_decode_c
if [ -z "$NAME" ]; then
echo "Enter the name of the binary file"
exit 1
fi
xxd ${NAME} ${HEXNAME}
${I2CTOOLS_PATH}/eeprom/decode-dimms -x ${HEXNAME} > ${ADDR1}
${BAREBOX_PATH}/barebox --image=spd=${NAME} | sed -n '1,13!p' > ${ADDR2}
diff -u -w ${ADDR1} ${ADDR2}
Sample script output fragment:
@@ -40,22 +18,11 @@
Module Configuration Type No Parity
Refresh Rate Reduced (7.8 us) - Self Refresh
Supported Burst Lengths 4, 8
-Supported CAS Latencies (tCL) 5T, 4T, 3T
+Supported CAS Latencies (tCL) 5T
tCL-tRCD-tRP-tRAS 5-5-5-15 as DDR2-666
- 4-4-4-12 as DDR2-533
- 3-3-3-9 as DDR2-400
-Minimum Cycle Time 3.00 ns at CAS 5 (tCK min)
- 3.75 ns at CAS 4
- 5.00 ns at CAS 3
-Maximum Access Time 0.45 ns at CAS 5 (tAC)
- 0.50 ns at CAS 4
- 0.60 ns at CAS 3
-Maximum Cycle Time (tCK max) 8.00 ns (DDR2-250)
-
----=== Timings at Standard Speeds ===---
-tCL-tRCD-tRP-tRAS as DDR2-666 5-5-5-15
-tCL-tRCD-tRP-tRAS as DDR2-533 4-4-4-12
-tCL-tRCD-tRP-tRAS as DDR2-400 3-3-3-9
+Minimum Cycle Time 3.0 ns at CAS 5
+Maximum Access Time 0.45 ns at CAS 5
+Maximum Cycle Time (tCK max) 8 ns
---=== Timing Parameters ===---
Address/Command Setup Time Before Clock (tIS) 0.20 ns
@@ -70,14 +37,14 @@
Minimum Write to Read CMD Delay (tWTR) 7.50 ns
Minimum Read to Pre-charge CMD Delay (tRTP) 7.50 ns
Minimum Active to Auto-refresh Delay (tRC) 60.00 ns
-Minimum Recovery Delay (tRFC) 127.50 ns
+Minimum Recovery Delay (tRFC) 127 ns
Maximum DQS to DQ Skew (tDQSQ) 0.24 ns
Maximum Read Data Hold Skew (tQHS) 0.34 ns
---=== Manufacturing Information ===---
-Manufacturer Undefined
+Manufacturer JEDEC ID ff ff ff ff ff ff ff ff
+Manufacturing Location Code 0xff
Part Number GU331G0AJEPR612L4C
-Revision Code 0x4200
-
-
-Number of SDRAM DIMMs detected and decoded: 1
+Manufacturing Date 200-W0
+Assembly Serial Number 0x00000000
+add spd backed by file images/undefined_pc2-5300_ddr2
Signed-off-by: Alexander Smirnov <alllecs@yandex.ru>
---
commands/Kconfig | 7 ++++++
commands/Makefile | 1 +
commands/spd_decode.c | 63 +++++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 71 insertions(+)
diff --git a/commands/Kconfig b/commands/Kconfig
index bb6674e..5571902 100644
--- a/commands/Kconfig
+++ b/commands/Kconfig
@@ -2102,6 +2102,13 @@ config CMD_STATE
depends on STATE
prompt "state"
+config CMD_SPD_DECODE
+ tristate
+ prompt "spd_decode"
+ select DDR_SPD
+ help
+ decode spd eeprom
+
# end Miscellaneous commands
endmenu
diff --git a/commands/Makefile b/commands/Makefile
index 3698347..13dbde5 100644
--- a/commands/Makefile
+++ b/commands/Makefile
@@ -112,3 +112,4 @@ obj-$(CONFIG_CMD_NV) += nv.o
obj-$(CONFIG_CMD_DEFAULTENV) += defaultenv.o
obj-$(CONFIG_CMD_STATE) += state.o
obj-$(CONFIG_CMD_DHCP) += dhcp.o
+obj-$(CONFIG_CMD_SPD_DECODE) += spd_decode.o
diff --git a/commands/spd_decode.c b/commands/spd_decode.c
new file mode 100644
index 0000000..2bedcf0
--- /dev/null
+++ b/commands/spd_decode.c
@@ -0,0 +1,63 @@
+/*
+ * This program is decoding and printing SPD contents
+ * in human readable format
+ * As an argument program, you must specify the file name.
+ *
+ * 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 the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ALTERA CORPORATION BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
+ * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Copyright (C) 2015 Alexander Smirnov <alllecs@yandex.ru>
+ */
+
+#include <common.h>
+#include <command.h>
+#include <libfile.h>
+#include <malloc.h>
+#include <ddr_spd.h>
+
+static int do_spd_decode(int argc, char *argv[])
+{
+ int ret;
+ size_t size;
+ void *data;
+
+ if (argc != 2)
+ return COMMAND_ERROR_USAGE;
+
+ ret = read_file_2(argv[1], &size, &data, 256);
+ if (ret && ret != -EFBIG) {
+ printf("unable to read %s: %s\n", argv[1], strerror(-ret));
+ return COMMAND_ERROR;
+ }
+
+ printf("Decoding EEPROM: %s\n\n", argv[1]);
+ ddr_spd_print(data);
+
+ free(data);
+
+ return 0;
+}
+
+BAREBOX_CMD_HELP_START(spd_decode)
+BAREBOX_CMD_HELP_TEXT("Decode a SPD EEPROM and print contents in human readable form")
+BAREBOX_CMD_HELP_END
+
+BAREBOX_CMD_START(spd_decode)
+ .cmd = do_spd_decode,
+ BAREBOX_CMD_DESC("Decode SPD EEPROM")
+ BAREBOX_CMD_OPTS("FILE")
+ BAREBOX_CMD_HELP(cmd_spd_decode_help)
+BAREBOX_CMD_END
--
2.1.4
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 6+ messages in thread