* [RFC V4 0/3] add decode command (SPD EEPROM data decoder) @ 2015-07-02 8:50 Alexander Smirnov 2015-07-02 8:50 ` [RFC V4 1/3] common: move DDR_SPD to common/Kconfig Alexander Smirnov ` (2 more replies) 0 siblings, 3 replies; 7+ messages in thread From: Alexander Smirnov @ 2015-07-02 8:50 UTC (permalink / raw) To: Sascha Hauer; +Cc: barebox, Alexander Smirnov Alexander Smirnov (3): common: move DDR_SPD to common/Kconfig ddr_spd: add routune for printing SPD contents in human readable format add decode command (SPD EEPROM data decoder) arch/ppc/mach-mpc85xx/Kconfig | 4 - arch/ppc/mach-mpc85xx/Makefile | 3 +- commands/Kconfig | 7 + commands/Makefile | 1 + commands/decode.c | 63 +++++++++ common/Kconfig | 4 + common/ddr_spd.c | 290 +++++++++++++++++++++++++++++++++++++++++ include/ddr_spd.h | 1 + 8 files changed, 368 insertions(+), 5 deletions(-) create mode 100644 commands/decode.c -- 2.1.4 _______________________________________________ barebox mailing list barebox@lists.infradead.org http://lists.infradead.org/mailman/listinfo/barebox ^ permalink raw reply [flat|nested] 7+ messages in thread
* [RFC V4 1/3] common: move DDR_SPD to common/Kconfig 2015-07-02 8:50 [RFC V4 0/3] add decode command (SPD EEPROM data decoder) Alexander Smirnov @ 2015-07-02 8:50 ` Alexander Smirnov 2015-07-02 8:50 ` [RFC V4 2/3] ddr_spd: add routune for printing SPD contents in human readable format Alexander Smirnov 2015-07-02 8:50 ` [RFC V4 3/3] add decode command (SPD EEPROM data decoder) Alexander Smirnov 2 siblings, 0 replies; 7+ messages in thread From: Alexander Smirnov @ 2015-07-02 8:50 UTC (permalink / raw) To: Sascha Hauer; +Cc: barebox, Alexander Smirnov This patch makes it possible to use ddr_spd-related routines in any arch not only in ppc. Signed-off-by: Alexander Smirnov <alllecs@yandex.ru> --- arch/ppc/mach-mpc85xx/Kconfig | 4 ---- arch/ppc/mach-mpc85xx/Makefile | 3 ++- common/Kconfig | 4 ++++ 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/arch/ppc/mach-mpc85xx/Kconfig b/arch/ppc/mach-mpc85xx/Kconfig index e29be9c..aa518b9 100644 --- a/arch/ppc/mach-mpc85xx/Kconfig +++ b/arch/ppc/mach-mpc85xx/Kconfig @@ -81,10 +81,6 @@ config P1022 config MPC8544 bool -config DDR_SPD - bool - select CRC16 - config FSL_DDR2 bool diff --git a/arch/ppc/mach-mpc85xx/Makefile b/arch/ppc/mach-mpc85xx/Makefile index 3e64617..de4f5ef 100644 --- a/arch/ppc/mach-mpc85xx/Makefile +++ b/arch/ppc/mach-mpc85xx/Makefile @@ -9,5 +9,6 @@ obj-y += fsl_i2c.o obj-$(CONFIG_MP) += mp.o obj-$(CONFIG_OFTREE) += fdt.o obj-$(CONFIG_DRIVER_NET_GIANFAR) += eth-devices.o -obj-$(CONFIG_DDR_SPD) += ../ddr-8xxx/ +obj-$(CONFIG_FSL_DDR2) += ../ddr-8xxx/ +obj-$(CONFIG_FSL_DDR3) += ../ddr-8xxx/ extra-y += barebox.lds diff --git a/common/Kconfig b/common/Kconfig index 983d305..9c3628e 100644 --- a/common/Kconfig +++ b/common/Kconfig @@ -951,3 +951,7 @@ endmenu config HAS_DEBUG_LL bool + +config DDR_SPD + bool + select CRC16 -- 2.1.4 _______________________________________________ barebox mailing list barebox@lists.infradead.org http://lists.infradead.org/mailman/listinfo/barebox ^ permalink raw reply [flat|nested] 7+ messages in thread
* [RFC V4 2/3] ddr_spd: add routune for printing SPD contents in human readable format 2015-07-02 8:50 [RFC V4 0/3] add decode command (SPD EEPROM data decoder) Alexander Smirnov 2015-07-02 8:50 ` [RFC V4 1/3] common: move DDR_SPD to common/Kconfig Alexander Smirnov @ 2015-07-02 8:50 ` Alexander Smirnov 2015-07-02 9:09 ` Antony Pavlov 2015-07-03 4:17 ` Sascha Hauer 2015-07-02 8:50 ` [RFC V4 3/3] add decode command (SPD EEPROM data decoder) Alexander Smirnov 2 siblings, 2 replies; 7+ messages in thread From: Alexander Smirnov @ 2015-07-02 8:50 UTC (permalink / raw) To: Sascha Hauer; +Cc: barebox, Alexander Smirnov Signed-off-by: Alexander Smirnov <alllecs@yandex.ru> --- common/ddr_spd.c | 290 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ include/ddr_spd.h | 1 + 2 files changed, 291 insertions(+) diff --git a/common/ddr_spd.c b/common/ddr_spd.c index ea0b529..6757d58 100644 --- a/common/ddr_spd.c +++ b/common/ddr_spd.c @@ -61,3 +61,293 @@ 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) * 10 / 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; +} + +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; + + ctime = ddr2_sdram_ctime(s->clk_cycle); + ddrclk = 2 * (1000 / ctime) * 100; + 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)) / ctime * 100; + trp = ((s->trp >> 2) + ((s->trp & 3) * 0.25)) / ctime * 100; + 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("%-50s %s (0x%0X)\n", "EEPROM Checksum of bytes 0-62", + sum, s->cksum); + printf("%-50s %d\n", "# of bytes written to SDRAM EEPROM", + s->info_size); + printf("%-50s %d\n", "Total number of bytes in EEPROM", + 1 << (s->chip_size)); + + if (s->mem_type < ARRAY_SIZE(type_list)) + printf("%-50s %s\n", "Fundamental Memory type", + type_list[s->mem_type]); + else + printf("%-50s (%02x)\n", "Warning: unknown memory type", + s->mem_type); + + printf("%-50s %x.%x\n", "SPD Revision", s->spd_rev >> 4, + s->spd_rev & 0x0f); + if (s->mem_type != SPD_MEMTYPE_DDR2) { + printf("Can't dump extended information for non-DDR2 memory\n"); + return; + } + + printf("\n---=== Memory Characteristics ===---\n"); + printf("%-50s %d MHz (PC2-%d)\n", "Maximum module speed", + ddrclk, pcclk); + if (i_i > 0 && i_i <= 12 && k > 0) + printf("%-50s %d MB\n", "Size", (1 << i_i) * k); + else + printf("%-50s INVALID: %02x %02x %02x %02x\n", "Size", + s->nrow_addr, s->ncol_addr, s->mod_ranks, s->nbanks); + + printf("%-50s %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("%-50s %d\n", "Ranks", (s->mod_ranks & 0x7) + 1); + printf("%-50s %d bits\n", "SDRAM Device Width", s->primw); + + if (s->mod_ranks >> 5 < ARRAY_SIZE(heights)) + printf("%-50s %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("%-50s %s\n", "Module Type", + ddr2_module_types[fls(s->dimm_type) - 1]); + else + printf("Error module type\n"); + + printf("%-50s ", "DRAM Package "); + if ((s->mod_ranks & 0x10) == 1) + printf("Stack\n"); + else + printf("Planar\n"); + if (s->voltage < 7) + printf("%-50s %s\n", "Voltage Interface Level", + sdram_voltage_interface_level[s->voltage]); + else + printf("Error Voltage Interface Level\n"); + + printf("%-50s ", "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("%-50s Reduced (%s us) %s\n", "Refresh Rate", + refresh[s->refresh & 0x7f], ref); + printf("%-50s %d, %d\n", "Supported Burst Lengths", + s->burstl & 4, s->burstl & 8); + + printf("%-50s %dT\n", "Supported CAS Latencies (tCL)", highestCAS); + printf("%-50s %d-%d-%d-%d as DDR2-%d\n", "tCL-tRCD-tRP-tRAS", + highestCAS, trcd, trp, tras, ddrclk); + printf("%-50s %d.%d ns at CAS %d\n", "Minimum Cycle Time", x, y, + highestCAS); + printf("%-50s 0.%d%d ns at CAS %d\n", "Maximum Access Time", + (s->clk_access >> 4), (s->clk_access & 0xf), highestCAS); + printf("%-50s %d ns\n", "Maximum Cycle Time (tCK max)", + (s->tckmax >> 4) + (s->tckmax & 0x0f)); + + printf("\n---=== Timing Parameters ===---\n"); + printf("%-50s 0.%d ns\n", + "Address/Command Setup Time Before Clock (tIS)", + funct(s->ca_setup)); + printf("%-50s 0.%d ns\n", "Address/Command Hold Time After Clock (tIH)", + funct(s->ca_hold)); + printf("%-50s 0.%d%d ns\n", "Data Input Setup Time Before Strobe (tDS)", + s->data_setup >> 4, s->data_setup & 0xf); + printf("%-50s 0.%d%d ns\n", "Data Input Hold Time After Strobe (tDH)", + s->data_hold >> 4, s->data_hold & 0xf); + + printf("%-50s %d.%d ns\n", "Minimum Row Precharge Delay (tRP)", + integ(s->trp), des(s->trp)); + printf("%-50s %d.%d ns\n", + "Minimum Row Active to Row Active Delay (tRRD)", + integ(s->trrd), des(s->trrd)); + printf("%-50s %d.%d ns\n", "Minimum RAS# to CAS# Delay (tRCD)", + integ(s->trcd), des(s->trcd)); + printf("%-50s %d ns\n", "Minimum RAS# Pulse Width (tRAS)", + ((s->tras & 0xfc) + (s->tras & 0x3))); + printf("%-50s %d.%d ns\n", "Write Recovery Time (tWR)", + integ(s->twr), des(s->twr)); + printf("%-50s %d.%d ns\n", "Minimum Write to Read CMD Delay (tWTR)", + integ(s->twtr), des(s->twtr)); + printf("%-50s %d.%d ns\n", + "Minimum Read to Pre-charge CMD Delay (tRTP)", + integ(s->trtp), des(s->trtp)); + printf("%-50s %d ns\n", "Minimum Active to Auto-refresh Delay (tRC)", + s->trc); + printf("%-50s %d ns\n", "Minimum Recovery Delay (tRFC)", s->trfc); + printf("%-50s 0.%d ns\n", "Maximum DQS to DQ Skew (tDQSQ)", s->tdqsq); + printf("%-50s 0.%d ns\n", "Maximum Read Data Hold Skew (tQHS)", + s->tqhs); + + printf("\n---=== Manufacturing Information ===---\n"); + + printf("%-50s", "Manufacturer JEDEC ID"); + for (i = 64; i < 72; i++) + printf(" %02x", record[i]); + + printf("\n"); + if (s->mloc) + printf("%-50s 0x%02x\n", "Manufacturing Location Code", + s->mloc); + + printf("%-50s ", "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("%-50s 20%d-W%d\n", "Manufacturing Date", record[93], + record[94]); + printf("%-50s 0x", "Assembly Serial Number"); + for (i = 95; i < 99; i++) + printf("%02X", record[i]); +} 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] 7+ messages in thread
* Re: [RFC V4 2/3] ddr_spd: add routune for printing SPD contents in human readable format 2015-07-02 8:50 ` [RFC V4 2/3] ddr_spd: add routune for printing SPD contents in human readable format Alexander Smirnov @ 2015-07-02 9:09 ` Antony Pavlov 2015-07-03 4:17 ` Sascha Hauer 1 sibling, 0 replies; 7+ messages in thread From: Antony Pavlov @ 2015-07-02 9:09 UTC (permalink / raw) To: Alexander Smirnov; +Cc: barebox On Thu, 2 Jul 2015 11:50:16 +0300 Alexander Smirnov <alllecs@yandex.ru> wrote: > Signed-off-by: Alexander Smirnov <alllecs@yandex.ru> > --- > common/ddr_spd.c | 290 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ > include/ddr_spd.h | 1 + > 2 files changed, 291 insertions(+) > > diff --git a/common/ddr_spd.c b/common/ddr_spd.c > index ea0b529..6757d58 100644 > --- a/common/ddr_spd.c > +++ b/common/ddr_spd.c > @@ -61,3 +61,293 @@ 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) * 10 / 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; > +} > + > +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; > + > + ctime = ddr2_sdram_ctime(s->clk_cycle); > + ddrclk = 2 * (1000 / ctime) * 100; > + 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)) / ctime * 100; > + trp = ((s->trp >> 2) + ((s->trp & 3) * 0.25)) / ctime * 100; > + 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"; > + Please check mem_type here too. You use ddr2_spd_checksum_pass() for any type memory. > + printf("---=== SPD EEPROM Information ===---\n"); > + printf("%-50s %s (0x%0X)\n", "EEPROM Checksum of bytes 0-62", > + sum, s->cksum); > + printf("%-50s %d\n", "# of bytes written to SDRAM EEPROM", > + s->info_size); > + printf("%-50s %d\n", "Total number of bytes in EEPROM", > + 1 << (s->chip_size)); > + > + if (s->mem_type < ARRAY_SIZE(type_list)) > + printf("%-50s %s\n", "Fundamental Memory type", > + type_list[s->mem_type]); > + else > + printf("%-50s (%02x)\n", "Warning: unknown memory type", > + s->mem_type); > + > + printf("%-50s %x.%x\n", "SPD Revision", s->spd_rev >> 4, > + s->spd_rev & 0x0f); > + if (s->mem_type != SPD_MEMTYPE_DDR2) { > + printf("Can't dump extended information for non-DDR2 memory\n"); > + return; > + } > + > + printf("\n---=== Memory Characteristics ===---\n"); > + printf("%-50s %d MHz (PC2-%d)\n", "Maximum module speed", > + ddrclk, pcclk); > + if (i_i > 0 && i_i <= 12 && k > 0) > + printf("%-50s %d MB\n", "Size", (1 << i_i) * k); > + else > + printf("%-50s INVALID: %02x %02x %02x %02x\n", "Size", > + s->nrow_addr, s->ncol_addr, s->mod_ranks, s->nbanks); > + > + printf("%-50s %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("%-50s %d\n", "Ranks", (s->mod_ranks & 0x7) + 1); > + printf("%-50s %d bits\n", "SDRAM Device Width", s->primw); > + > + if (s->mod_ranks >> 5 < ARRAY_SIZE(heights)) > + printf("%-50s %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("%-50s %s\n", "Module Type", > + ddr2_module_types[fls(s->dimm_type) - 1]); > + else > + printf("Error module type\n"); > + > + printf("%-50s ", "DRAM Package "); > + if ((s->mod_ranks & 0x10) == 1) > + printf("Stack\n"); > + else > + printf("Planar\n"); > + if (s->voltage < 7) use ARRAY_SIZE here -- Best regards, Antony Pavlov _______________________________________________ barebox mailing list barebox@lists.infradead.org http://lists.infradead.org/mailman/listinfo/barebox ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [RFC V4 2/3] ddr_spd: add routune for printing SPD contents in human readable format 2015-07-02 8:50 ` [RFC V4 2/3] ddr_spd: add routune for printing SPD contents in human readable format Alexander Smirnov 2015-07-02 9:09 ` Antony Pavlov @ 2015-07-03 4:17 ` Sascha Hauer 1 sibling, 0 replies; 7+ messages in thread From: Sascha Hauer @ 2015-07-03 4:17 UTC (permalink / raw) To: Alexander Smirnov; +Cc: barebox In the patch subject: s/routune/routine/ Sascha On Thu, Jul 02, 2015 at 11:50:16AM +0300, Alexander Smirnov wrote: > Signed-off-by: Alexander Smirnov <alllecs@yandex.ru> > --- > common/ddr_spd.c | 290 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ > include/ddr_spd.h | 1 + > 2 files changed, 291 insertions(+) > > diff --git a/common/ddr_spd.c b/common/ddr_spd.c > index ea0b529..6757d58 100644 > --- a/common/ddr_spd.c > +++ b/common/ddr_spd.c > @@ -61,3 +61,293 @@ 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) * 10 / 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; > +} > + > +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; > + > + ctime = ddr2_sdram_ctime(s->clk_cycle); > + ddrclk = 2 * (1000 / ctime) * 100; > + 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)) / ctime * 100; > + trp = ((s->trp >> 2) + ((s->trp & 3) * 0.25)) / ctime * 100; > + 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("%-50s %s (0x%0X)\n", "EEPROM Checksum of bytes 0-62", > + sum, s->cksum); > + printf("%-50s %d\n", "# of bytes written to SDRAM EEPROM", > + s->info_size); > + printf("%-50s %d\n", "Total number of bytes in EEPROM", > + 1 << (s->chip_size)); > + > + if (s->mem_type < ARRAY_SIZE(type_list)) > + printf("%-50s %s\n", "Fundamental Memory type", > + type_list[s->mem_type]); > + else > + printf("%-50s (%02x)\n", "Warning: unknown memory type", > + s->mem_type); > + > + printf("%-50s %x.%x\n", "SPD Revision", s->spd_rev >> 4, > + s->spd_rev & 0x0f); > + if (s->mem_type != SPD_MEMTYPE_DDR2) { > + printf("Can't dump extended information for non-DDR2 memory\n"); > + return; > + } > + > + printf("\n---=== Memory Characteristics ===---\n"); > + printf("%-50s %d MHz (PC2-%d)\n", "Maximum module speed", > + ddrclk, pcclk); > + if (i_i > 0 && i_i <= 12 && k > 0) > + printf("%-50s %d MB\n", "Size", (1 << i_i) * k); > + else > + printf("%-50s INVALID: %02x %02x %02x %02x\n", "Size", > + s->nrow_addr, s->ncol_addr, s->mod_ranks, s->nbanks); > + > + printf("%-50s %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("%-50s %d\n", "Ranks", (s->mod_ranks & 0x7) + 1); > + printf("%-50s %d bits\n", "SDRAM Device Width", s->primw); > + > + if (s->mod_ranks >> 5 < ARRAY_SIZE(heights)) > + printf("%-50s %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("%-50s %s\n", "Module Type", > + ddr2_module_types[fls(s->dimm_type) - 1]); > + else > + printf("Error module type\n"); > + > + printf("%-50s ", "DRAM Package "); > + if ((s->mod_ranks & 0x10) == 1) > + printf("Stack\n"); > + else > + printf("Planar\n"); > + if (s->voltage < 7) > + printf("%-50s %s\n", "Voltage Interface Level", > + sdram_voltage_interface_level[s->voltage]); > + else > + printf("Error Voltage Interface Level\n"); > + > + printf("%-50s ", "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("%-50s Reduced (%s us) %s\n", "Refresh Rate", > + refresh[s->refresh & 0x7f], ref); > + printf("%-50s %d, %d\n", "Supported Burst Lengths", > + s->burstl & 4, s->burstl & 8); > + > + printf("%-50s %dT\n", "Supported CAS Latencies (tCL)", highestCAS); > + printf("%-50s %d-%d-%d-%d as DDR2-%d\n", "tCL-tRCD-tRP-tRAS", > + highestCAS, trcd, trp, tras, ddrclk); > + printf("%-50s %d.%d ns at CAS %d\n", "Minimum Cycle Time", x, y, > + highestCAS); > + printf("%-50s 0.%d%d ns at CAS %d\n", "Maximum Access Time", > + (s->clk_access >> 4), (s->clk_access & 0xf), highestCAS); > + printf("%-50s %d ns\n", "Maximum Cycle Time (tCK max)", > + (s->tckmax >> 4) + (s->tckmax & 0x0f)); > + > + printf("\n---=== Timing Parameters ===---\n"); > + printf("%-50s 0.%d ns\n", > + "Address/Command Setup Time Before Clock (tIS)", > + funct(s->ca_setup)); > + printf("%-50s 0.%d ns\n", "Address/Command Hold Time After Clock (tIH)", > + funct(s->ca_hold)); > + printf("%-50s 0.%d%d ns\n", "Data Input Setup Time Before Strobe (tDS)", > + s->data_setup >> 4, s->data_setup & 0xf); > + printf("%-50s 0.%d%d ns\n", "Data Input Hold Time After Strobe (tDH)", > + s->data_hold >> 4, s->data_hold & 0xf); > + > + printf("%-50s %d.%d ns\n", "Minimum Row Precharge Delay (tRP)", > + integ(s->trp), des(s->trp)); > + printf("%-50s %d.%d ns\n", > + "Minimum Row Active to Row Active Delay (tRRD)", > + integ(s->trrd), des(s->trrd)); > + printf("%-50s %d.%d ns\n", "Minimum RAS# to CAS# Delay (tRCD)", > + integ(s->trcd), des(s->trcd)); > + printf("%-50s %d ns\n", "Minimum RAS# Pulse Width (tRAS)", > + ((s->tras & 0xfc) + (s->tras & 0x3))); > + printf("%-50s %d.%d ns\n", "Write Recovery Time (tWR)", > + integ(s->twr), des(s->twr)); > + printf("%-50s %d.%d ns\n", "Minimum Write to Read CMD Delay (tWTR)", > + integ(s->twtr), des(s->twtr)); > + printf("%-50s %d.%d ns\n", > + "Minimum Read to Pre-charge CMD Delay (tRTP)", > + integ(s->trtp), des(s->trtp)); > + printf("%-50s %d ns\n", "Minimum Active to Auto-refresh Delay (tRC)", > + s->trc); > + printf("%-50s %d ns\n", "Minimum Recovery Delay (tRFC)", s->trfc); > + printf("%-50s 0.%d ns\n", "Maximum DQS to DQ Skew (tDQSQ)", s->tdqsq); > + printf("%-50s 0.%d ns\n", "Maximum Read Data Hold Skew (tQHS)", > + s->tqhs); > + > + printf("\n---=== Manufacturing Information ===---\n"); > + > + printf("%-50s", "Manufacturer JEDEC ID"); > + for (i = 64; i < 72; i++) > + printf(" %02x", record[i]); > + > + printf("\n"); > + if (s->mloc) > + printf("%-50s 0x%02x\n", "Manufacturing Location Code", > + s->mloc); > + > + printf("%-50s ", "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("%-50s 20%d-W%d\n", "Manufacturing Date", record[93], > + record[94]); > + printf("%-50s 0x", "Assembly Serial Number"); > + for (i = 95; i < 99; i++) > + printf("%02X", record[i]); > +} > 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 > > -- Pengutronix e.K. | | Industrial Linux Solutions | http://www.pengutronix.de/ | Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 | Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 | _______________________________________________ barebox mailing list barebox@lists.infradead.org http://lists.infradead.org/mailman/listinfo/barebox ^ permalink raw reply [flat|nested] 7+ messages in thread
* [RFC V4 3/3] add decode command (SPD EEPROM data decoder) 2015-07-02 8:50 [RFC V4 0/3] add decode command (SPD EEPROM data decoder) Alexander Smirnov 2015-07-02 8:50 ` [RFC V4 1/3] common: move DDR_SPD to common/Kconfig Alexander Smirnov 2015-07-02 8:50 ` [RFC V4 2/3] ddr_spd: add routune for printing SPD contents in human readable format Alexander Smirnov @ 2015-07-02 8:50 ` Alexander Smirnov 2015-07-03 4:16 ` Sascha Hauer 2 siblings, 1 reply; 7+ messages in thread From: Alexander Smirnov @ 2015-07-02 8:50 UTC (permalink / raw) To: Sascha Hauer; +Cc: barebox, Alexander Smirnov decode-dimms perl script is used as prototype (see https://github.com/groeck/i2c-tools/blob/master/eeprom/decode-dimms). Here is a sample decode output: barebox@barebox sandbox:/ decode env/crucial_pc2-6400_ddr2 Decoding EEPROM: env/crucial_pc2-6400_ddr2 ---=== SPD EEPROM Information ===--- EEPROM Checksum of bytes 0-62 OK (0xCA) Total number of bytes in EEPROM 256 Fundamental Memory type DDR2 SDRAM SPD Revision 1.3 ---=== Memory Characteristics ===--- Maximum module speed 800 MHz (PC2-6400) Size 1024 MB Banks x Rows x Columns x Bits 8 x 14 x 10 x 64 Ranks 1 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.0 ns Minimum Row Active to Row Active Delay (tRRD) 7.5 ns Minimum RAS# to CAS# Delay (tRCD) 15.0 ns Minimum RAS# Pulse Width (tRAS) 45 ns Write Recovery Time (tWR) 15.0 ns Minimum Write to Read CMD Delay (tWTR) 7.5 ns Minimum Read to Pre-charge CMD Delay (tRTP) 7.5 ns Minimum Active to Auto-refresh Delay (tRC) 60 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 7f 7f 7f 7f 9b 00 00 Part Number CT12864AC800.M8FM8 Manufacturing Date 2014-W24 Assembly Serial Number 0x00000000 TODOs: * Timing Parameters section output format is slightly differ from decode-dimms' format; * supports only DDR2 SPD EEPROM. Signed-off-by: Alexander Smirnov <alllecs@yandex.ru> --- commands/Kconfig | 7 +++++++ commands/Makefile | 1 + commands/decode.c | 63 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 71 insertions(+) diff --git a/commands/Kconfig b/commands/Kconfig index bb6674e..9230873 100644 --- a/commands/Kconfig +++ b/commands/Kconfig @@ -2102,6 +2102,13 @@ config CMD_STATE depends on STATE prompt "state" +config CMD_DECODE + tristate + prompt "decode" + select DDR_SPD + help + decode spd eeprom + # end Miscellaneous commands endmenu diff --git a/commands/Makefile b/commands/Makefile index 3698347..71cd877 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_DECODE) += decode.o diff --git a/commands/decode.c b/commands/decode.c new file mode 100644 index 0000000..4fc9c99 --- /dev/null +++ b/commands/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> + * + * Originally from https://github.com/groeck/i2c-tools/blob/master/eeprom/decode-dimms + */ + +#include <common.h> +#include <command.h> +#include <libfile.h> +#include <malloc.h> +#include <ddr_spd.h> + +static int do_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(decode) +BAREBOX_CMD_HELP_TEXT("Not enough or more than one argument to continue.") +BAREBOX_CMD_HELP_END + +BAREBOX_CMD_START(decode) + .cmd = do_decode, + BAREBOX_CMD_HELP(cmd_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] 7+ messages in thread
* Re: [RFC V4 3/3] add decode command (SPD EEPROM data decoder) 2015-07-02 8:50 ` [RFC V4 3/3] add decode command (SPD EEPROM data decoder) Alexander Smirnov @ 2015-07-03 4:16 ` Sascha Hauer 0 siblings, 0 replies; 7+ messages in thread From: Sascha Hauer @ 2015-07-03 4:16 UTC (permalink / raw) To: Alexander Smirnov; +Cc: barebox On Thu, Jul 02, 2015 at 11:50:17AM +0300, Alexander Smirnov wrote: > decode-dimms perl script is used as prototype > (see https://github.com/groeck/i2c-tools/blob/master/eeprom/decode-dimms). > > Here is a sample decode output: > > barebox@barebox sandbox:/ decode env/crucial_pc2-6400_ddr2 > Decoding EEPROM: env/crucial_pc2-6400_ddr2 > > ---=== SPD EEPROM Information ===--- > EEPROM Checksum of bytes 0-62 OK (0xCA) > Total number of bytes in EEPROM 256 > Fundamental Memory type DDR2 SDRAM > SPD Revision 1.3 > > ---=== Memory Characteristics ===--- > Maximum module speed 800 MHz (PC2-6400) > Size 1024 MB > Banks x Rows x Columns x Bits 8 x 14 x 10 x 64 > Ranks 1 > 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.0 ns > Minimum Row Active to Row Active Delay (tRRD) 7.5 ns > Minimum RAS# to CAS# Delay (tRCD) 15.0 ns > Minimum RAS# Pulse Width (tRAS) 45 ns > Write Recovery Time (tWR) 15.0 ns > Minimum Write to Read CMD Delay (tWTR) 7.5 ns > Minimum Read to Pre-charge CMD Delay (tRTP) 7.5 ns > Minimum Active to Auto-refresh Delay (tRC) 60 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 7f 7f 7f 7f 9b 00 00 > Part Number CT12864AC800.M8FM8 > Manufacturing Date 2014-W24 > Assembly Serial Number 0x00000000 > > TODOs: > > * Timing Parameters section output format is slightly > differ from decode-dimms' format; > * supports only DDR2 SPD EEPROM. > > Signed-off-by: Alexander Smirnov <alllecs@yandex.ru> > --- > commands/Kconfig | 7 +++++++ > commands/Makefile | 1 + > commands/decode.c | 63 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ > 3 files changed, 71 insertions(+) > > diff --git a/commands/Kconfig b/commands/Kconfig > index bb6674e..9230873 100644 > --- a/commands/Kconfig > +++ b/commands/Kconfig > @@ -2102,6 +2102,13 @@ config CMD_STATE > depends on STATE > prompt "state" > > +config CMD_DECODE > + tristate > + prompt "decode" > + select DDR_SPD > + help > + decode spd eeprom > + > # end Miscellaneous commands > endmenu > > diff --git a/commands/Makefile b/commands/Makefile > index 3698347..71cd877 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_DECODE) += decode.o > diff --git a/commands/decode.c b/commands/decode.c > new file mode 100644 > index 0000000..4fc9c99 > --- /dev/null > +++ b/commands/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> > + * > + * Originally from https://github.com/groeck/i2c-tools/blob/master/eeprom/decode-dimms This comment is probably better fitted above the actual decoding code. > + */ > + > +#include <common.h> > +#include <command.h> > +#include <libfile.h> > +#include <malloc.h> > +#include <ddr_spd.h> > + > +static int do_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(decode) > +BAREBOX_CMD_HELP_TEXT("Not enough or more than one argument to continue.") Some information would be nice here. Something like: BAREBOX_CMD_HELP_TEXT("Decode a SPD EEPROM and print contents in human readable form") > +BAREBOX_CMD_HELP_END > + > +BAREBOX_CMD_START(decode) > + .cmd = do_decode, BAREBOX_CMD_DESC("Decode SPD EEPROM") BAREBOX_CMD_OPTS("FILE") The name of the command is too generic. How about spd_decode? I think it's time to remove the RFC tag from the patches because they seem to be nearly ready for inclusion. Sascha -- Pengutronix e.K. | | Industrial Linux Solutions | http://www.pengutronix.de/ | Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 | Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 | _______________________________________________ barebox mailing list barebox@lists.infradead.org http://lists.infradead.org/mailman/listinfo/barebox ^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2015-07-03 4:17 UTC | newest] Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2015-07-02 8:50 [RFC V4 0/3] add decode command (SPD EEPROM data decoder) Alexander Smirnov 2015-07-02 8:50 ` [RFC V4 1/3] common: move DDR_SPD to common/Kconfig Alexander Smirnov 2015-07-02 8:50 ` [RFC V4 2/3] ddr_spd: add routune for printing SPD contents in human readable format Alexander Smirnov 2015-07-02 9:09 ` Antony Pavlov 2015-07-03 4:17 ` Sascha Hauer 2015-07-02 8:50 ` [RFC V4 3/3] add decode command (SPD EEPROM data decoder) Alexander Smirnov 2015-07-03 4:16 ` Sascha Hauer
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox