--- ipmitool-1.8.11/lib/dimm_spd.c 2009-02-25 15:38:52.000000000 -0500 +++ ipmitool-1.8.11-spdfix/lib/dimm_spd.c 2009-03-31 23:34:24.000000000 -0400 @@ -60,6 +60,37 @@ { 0x06, "DDR SGRAM" }, { 0x07, "DDR SDRAM" }, { 0x08, "DDR2 SDRAM" }, + { 0x09, "DDR2 SDRAM FB-DIMM" }, + { 0x0A, "DDR2 SDRAM FB-DIMM Probe" }, + { 0x0B, "DDR3 SDRAM" }, + { 0x00, NULL }, +}; + +const struct valstr ddr3_density_vals[] = +{ + { 0, "256 Mb" }, + { 1, "512 Mb" }, + { 2, "1 Gb" }, + { 3, "2 Gb" }, + { 4, "4 Gb" }, + { 5, "8 Gb" }, + { 6, "16 Gb" }, + { 0x00, NULL }, +}; + +const struct valstr ddr3_banks_vals[] = +{ + { 0, "3 (8 Banks)" }, + { 1, "4 (16 Banks)" }, + { 2, "5 (32 Banks)" }, + { 3, "6 (64 Banks)" }, + { 0x00, NULL }, +}; + +const struct valstr ddr3_ecc_vals[] = +{ + { 0, "0 bits" }, + { 1, "8 bits" }, { 0x00, NULL }, }; @@ -693,51 +724,128 @@ if (len < 92) return -1; /* we need first 91 bytes to do our thing */ - size = spd_data[5] * (spd_data[31] << 2); - printf(" Memory Size : %d MB\n", size); printf(" Memory Type : %s\n", val2str(spd_data[2], spd_memtype_vals)); - printf(" Voltage Intf : %s\n", - val2str(spd_data[8], spd_voltage_vals)); - printf(" Error Detect/Cor : %s\n", - val2str(spd_data[11], spd_config_vals)); - - /* handle jedec table bank continuation values */ - printf(" Manufacturer : "); - if (spd_data[64] != 0x7f) - printf("%s\n", - val2str(spd_data[64], jedec_id1_vals)); - else { - if (spd_data[65] != 0x7f) + + if (spd_data[2] == 0x0B) /* DDR3 SDRAM */ + { + int iPN; + char *pchPN = spd_data+128; + int sdram_cap = 0; + int pri_bus_width = 0; + int sdram_width = 0; + int ranks = 0; + int mem_size = 0; + + if (len < 148) + return -1; /* we need first 91 bytes to do our thing */ + + + sdram_cap = ldexp(256,(spd_data[4]&15)); + pri_bus_width = ldexp(8,(spd_data[8]&7)); + sdram_width = ldexp(4,(spd_data[7]&7)); + ranks = ldexp(1,((spd_data[7]&0x3F)>>3)); + mem_size = (sdram_cap/8) * (pri_bus_width/sdram_width) * ranks; + printf(" SDRAM Capacity : %d MB\n", sdram_cap ); + printf(" Memory Banks : %s\n", val2str(spd_data[4]>>4, ddr3_banks_vals)); + printf(" Primary Bus Width : %d bits\n", pri_bus_width ); + printf(" SDRAM Device Width : %d bits\n", sdram_width ); + printf(" Number of Ranks : %d\n", ranks ); + printf(" Memory size : %d MB\n", mem_size ); + + /* printf(" Memory Density : %s\n", val2str(spd_data[4]&15, ddr3_density_vals)); */ + printf(" 1.5 V Nominal Op : %s\n", (((spd_data[6]&1) != 0) ? "No":"Yes" ) ); + printf(" 1.35 V Nominal Op : %s\n", (((spd_data[6]&2) != 0) ? "No":"Yes" ) ); + printf(" 1.2X V Nominal Op : %s\n", (((spd_data[6]&4) != 0) ? "No":"Yes" ) ); + printf(" Error Detect/Cor : %s\n", val2str(spd_data[8]>>3, ddr3_ecc_vals)); + + printf(" Manufacturer : "); + switch (spd_data[117]&127) + { + case 0: + printf("%s\n", val2str(spd_data[118], jedec_id1_vals)); + break; + + case 1: + printf("%s\n", val2str(spd_data[118], jedec_id2_vals)); + break; + + case 2: + printf("%s\n", val2str(spd_data[118], jedec_id3_vals)); + break; + + case 3: + printf("%s\n", val2str(spd_data[118], jedec_id4_vals)); + break; + + case 4: + printf("%s\n", val2str(spd_data[118], jedec_id5_vals)); + break; + + default: + printf("%s\n", "JEDEC JEP106 update required" ); + + } + + printf(" Manufacture Date : year %c%c week %c%c\n", + '0'+(spd_data[120]>>4), '0'+(spd_data[120]&15), '0'+(spd_data[121]>>4), '0'+(spd_data[121]&15) ); + + printf(" Serial Number : %02x%02x%02x%02x\n", + spd_data[122], spd_data[123], spd_data[124], spd_data[125]); + + printf(" Part Number : "); + for (iPN=0; iPN < 19; iPN++) + { + printf( "%c", *pchPN++ ); + } + printf("\n"); + } + else + { + size = spd_data[5] * (spd_data[31] << 2); + printf(" Memory Size : %d MB\n", size); + printf(" Voltage Intf : %s\n", + val2str(spd_data[8], spd_voltage_vals)); + printf(" Error Detect/Cor : %s\n", + val2str(spd_data[11], spd_config_vals)); + + /* handle jedec table bank continuation values */ + printf(" Manufacturer : "); + if (spd_data[64] != 0x7f) printf("%s\n", - val2str(spd_data[65], jedec_id2_vals)); + val2str(spd_data[64], jedec_id1_vals)); else { - if (spd_data[66] != 0x7f) + if (spd_data[65] != 0x7f) printf("%s\n", - val2str(spd_data[66], jedec_id3_vals)); + val2str(spd_data[65], jedec_id2_vals)); else { - if (spd_data[67] != 0x7f) - printf("%s\n", - val2str(spd_data[67], - jedec_id4_vals)); - else + if (spd_data[66] != 0x7f) printf("%s\n", - val2str(spd_data[68], - jedec_id5_vals)); + val2str(spd_data[66], jedec_id3_vals)); + else { + if (spd_data[67] != 0x7f) + printf("%s\n", + val2str(spd_data[67], + jedec_id4_vals)); + else + printf("%s\n", + val2str(spd_data[68], + jedec_id5_vals)); + } } } - } - if (spd_data[73]) { - char part[19]; - memcpy(part, spd_data+73, 18); - part[18] = 0; - printf(" Part Number : %s\n", part); + if (spd_data[73]) { + char part[19]; + memcpy(part, spd_data+73, 18); + part[18] = 0; + printf(" Part Number : %s\n", part); + } + + printf(" Serial Number : %02x%02x%02x%02x\n", + spd_data[95], spd_data[96], spd_data[97], spd_data[98]); } - printf(" Serial Number : %02x%02x%02x%02x\n", - spd_data[95], spd_data[96], spd_data[97], spd_data[98]); - if (verbose) { printf("\n"); printbuf(spd_data, len, "SPD DATA");