1 /* $OpenBSD: spdmem.c,v 1.3 2011/04/19 21:55:25 chl Exp $ */ 2 /* $NetBSD: spdmem.c,v 1.3 2007/09/20 23:09:59 xtraeme Exp $ */ 3 4 /* 5 * Copyright (c) 2007 Jonathan Gray <jsg@openbsd.org> 6 * 7 * Permission to use, copy, modify, and distribute this software for any 8 * purpose with or without fee is hereby granted, provided that the above 9 * copyright notice and this permission notice appear in all copies. 10 * 11 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 12 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 13 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 14 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 15 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 16 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 17 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 18 */ 19 20 /* 21 * Copyright (c) 2007 Nicolas Joly 22 * Copyright (c) 2007 Paul Goyette 23 * Copyright (c) 2007 Tobias Nygren 24 * All rights reserved. 25 * 26 * Redistribution and use in source and binary forms, with or without 27 * modification, are permitted provided that the following conditions 28 * are met: 29 * 1. Redistributions of source code must retain the above copyright 30 * notice, this list of conditions and the following disclaimer. 31 * 2. Redistributions in binary form must reproduce the above copyright 32 * notice, this list of conditions and the following disclaimer in the 33 * documentation and/or other materials provided with the distribution. 34 * 3. The name of the author may not be used to endorse or promote products 35 * derived from this software without specific prior written permission. 36 * 37 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS 38 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 39 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 40 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 41 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 42 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 43 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 44 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 45 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 46 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 47 * POSSIBILITY OF SUCH DAMAGE. 48 */ 49 50 /* 51 * Serial Presence Detect (SPD) memory identification 52 */ 53 54 #include <sys/param.h> 55 #include <sys/systm.h> 56 #include <sys/device.h> 57 58 #include <dev/spdmemvar.h> 59 60 /* Encodings of the size used/total byte for certain memory types */ 61 #define SPDMEM_SPDSIZE_MASK 0x0F /* SPD EEPROM Size */ 62 63 #define SPDMEM_SPDLEN_128 0x00 /* SPD EEPROM Sizes */ 64 #define SPDMEM_SPDLEN_176 0x10 65 #define SPDMEM_SPDLEN_256 0x20 66 #define SPDMEM_SPDLEN_MASK 0x70 /* Bits 4 - 6 */ 67 68 #define SPDMEM_SPDCRC_116 0x80 /* CRC Bytes covered */ 69 #define SPDMEM_SPDCRC_125 0x00 70 #define SPDMEM_SPDCRC_MASK 0x80 /* Bit 7 */ 71 72 73 /* possible values for the memory type */ 74 #define SPDMEM_MEMTYPE_FPM 0x01 75 #define SPDMEM_MEMTYPE_EDO 0x02 76 #define SPDMEM_MEMTYPE_PIPE_NIBBLE 0x03 77 #define SPDMEM_MEMTYPE_SDRAM 0x04 78 #define SPDMEM_MEMTYPE_ROM 0x05 79 #define SPDMEM_MEMTYPE_DDRSGRAM 0x06 80 #define SPDMEM_MEMTYPE_DDRSDRAM 0x07 81 #define SPDMEM_MEMTYPE_DDR2SDRAM 0x08 82 #define SPDMEM_MEMTYPE_FBDIMM 0x09 83 #define SPDMEM_MEMTYPE_FBDIMM_PROBE 0x0a 84 #define SPDMEM_MEMTYPE_DDR3SDRAM 0x0b 85 #define SPDMEM_MEMTYPE_NONE 0xff 86 87 #define SPDMEM_MEMTYPE_DIRECT_RAMBUS 0x01 88 #define SPDMEM_MEMTYPE_RAMBUS 0x11 89 90 /* possible values for the supply voltage */ 91 #define SPDMEM_VOLTAGE_TTL_5V 0x00 92 #define SPDMEM_VOLTAGE_TTL_LV 0x01 93 #define SPDMEM_VOLTAGE_HSTTL_1_5V 0x02 94 #define SPDMEM_VOLTAGE_SSTL_3_3V 0x03 95 #define SPDMEM_VOLTAGE_SSTL_2_5V 0x04 96 #define SPDMEM_VOLTAGE_SSTL_1_8V 0x05 97 98 /* possible values for module configuration */ 99 #define SPDMEM_MODCONFIG_PARITY 0x01 100 #define SPDMEM_MODCONFIG_ECC 0x02 101 102 /* for DDR2, module configuration is a bit-mask field */ 103 #define SPDMEM_MODCONFIG_HAS_DATA_PARITY 0x01 104 #define SPDMEM_MODCONFIG_HAS_DATA_ECC 0x02 105 #define SPDMEM_MODCONFIG_HAS_ADDR_CMD_PARITY 0x04 106 107 /* possible values for the refresh field */ 108 #define SPDMEM_REFRESH_STD 0x00 109 #define SPDMEM_REFRESH_QUARTER 0x01 110 #define SPDMEM_REFRESH_HALF 0x02 111 #define SPDMEM_REFRESH_TWOX 0x03 112 #define SPDMEM_REFRESH_FOURX 0x04 113 #define SPDMEM_REFRESH_EIGHTX 0x05 114 #define SPDMEM_REFRESH_SELFREFRESH 0x80 115 116 /* superset types */ 117 #define SPDMEM_SUPERSET_ESDRAM 0x01 118 #define SPDMEM_SUPERSET_DDR_ESDRAM 0x02 119 #define SPDMEM_SUPERSET_EDO_PEM 0x03 120 #define SPDMEM_SUPERSET_SDR_PEM 0x04 121 122 /* FPM and EDO DIMMS */ 123 #define SPDMEM_FPM_ROWS 0x00 124 #define SPDMEM_FPM_COLS 0x01 125 #define SPDMEM_FPM_BANKS 0x02 126 #define SPDMEM_FPM_CONFIG 0x08 127 #define SPDMEM_FPM_REFRESH 0x09 128 #define SPDMEM_FPM_SUPERSET 0x0c 129 130 /* PC66/PC100/PC133 SDRAM */ 131 #define SPDMEM_SDR_ROWS 0x00 132 #define SPDMEM_SDR_COLS 0x01 133 #define SPDMEM_SDR_BANKS 0x02 134 #define SPDMEM_SDR_CYCLE 0x06 135 #define SPDMEM_SDR_BANKS_PER_CHIP 0x0e 136 #define SPDMEM_SDR_MOD_ATTRIB 0x12 137 #define SPDMEM_SDR_SUPERSET 0x1d 138 139 #define SPDMEM_SDR_FREQUENCY 126 140 #define SPDMEM_SDR_CAS 127 141 #define SPDMEM_SDR_FREQ_66 0x66 142 #define SPDMEM_SDR_FREQ_100 0x64 143 #define SPDMEM_SDR_FREQ_133 0x85 144 #define SPDMEM_SDR_CAS2 (1 << 1) 145 #define SPDMEM_SDR_CAS3 (1 << 2) 146 147 /* Rambus Direct DRAM */ 148 #define SPDMEM_RDR_MODULE_TYPE 0x00 149 #define SPDMEM_RDR_ROWS_COLS 0x01 150 #define SPDMEM_RDR_BANK 0x02 151 152 #define SPDMEM_RDR_TYPE_RIMM 1 153 #define SPDMEM_RDR_TYPE_SORIMM 2 154 #define SPDMEM_RDR_TYPE_EMBED 3 155 #define SPDMEM_RDR_TYPE_RIMM32 4 156 157 /* Dual Data Rate SDRAM */ 158 #define SPDMEM_DDR_ROWS 0x00 159 #define SPDMEM_DDR_COLS 0x01 160 #define SPDMEM_DDR_RANKS 0x02 161 #define SPDMEM_DDR_DATAWIDTH 0x03 162 #define SPDMEM_DDR_VOLTAGE 0x05 163 #define SPDMEM_DDR_CYCLE 0x06 164 #define SPDMEM_DDR_REFRESH 0x09 165 #define SPDMEM_DDR_BANKS_PER_CHIP 0x0e 166 #define SPDMEM_DDR_CAS 0x0f 167 #define SPDMEM_DDR_MOD_ATTRIB 0x12 168 #define SPDMEM_DDR_SUPERSET 0x1d 169 170 #define SPDMEM_DDR_ATTRIB_REG (1 << 1) 171 172 /* Dual Data Rate 2 SDRAM */ 173 #define SPDMEM_DDR2_ROWS 0x00 174 #define SPDMEM_DDR2_COLS 0x01 175 #define SPDMEM_DDR2_RANKS 0x02 176 #define SPDMEM_DDR2_DATAWIDTH 0x03 177 #define SPDMEM_DDR2_VOLTAGE 0x05 178 #define SPDMEM_DDR2_CYCLE 0x06 179 #define SPDMEM_DDR2_DIMMTYPE 0x11 180 #define SPDMEM_DDR2_RANK_DENSITY 0x1c 181 182 #define SPDMEM_DDR2_TYPE_REGMASK ((1 << 4) | (1 << 0)) 183 #define SPDMEM_DDR2_SODIMM (1 << 2) 184 #define SPDMEM_DDR2_MICRO_DIMM (1 << 3) 185 #define SPDMEM_DDR2_MINI_RDIMM (1 << 4) 186 #define SPDMEM_DDR2_MINI_UDIMM (1 << 5) 187 188 /* DDR2 FB-DIMM SDRAM */ 189 #define SPDMEM_FBDIMM_ADDR 0x01 190 #define SPDMEM_FBDIMM_RANKS 0x04 191 #define SPDMEM_FBDIMM_MTB_DIVIDEND 0x06 192 #define SPDMEM_FBDIMM_MTB_DIVISOR 0x07 193 #define SPDMEM_FBDIMM_PROTO 0x4e 194 195 #define SPDMEM_FBDIMM_RANKS_WIDTH 0x07 196 #define SPDMEM_FBDIMM_ADDR_BANKS 0x02 197 #define SPDMEM_FBDIMM_ADDR_COL 0x0c 198 #define SPDMEM_FBDIMM_ADDR_COL_SHIFT 2 199 #define SPDMEM_FBDIMM_ADDR_ROW 0xe0 200 #define SPDMEM_FBDIMM_ADDR_ROW_SHIFT 5 201 #define SPDMEM_FBDIMM_PROTO_ECC (1 << 1) 202 203 204 /* Dual Data Rate 3 SDRAM */ 205 #define SPDMEM_DDR3_MODTYPE 0x00 206 #define SPDMEM_DDR3_DENSITY 0x01 207 #define SPDMEM_DDR3_MOD_ORG 0x04 208 #define SPDMEM_DDR3_DATAWIDTH 0x05 209 #define SPDMEM_DDR3_MTB_DIVIDEND 0x07 210 #define SPDMEM_DDR3_MTB_DIVISOR 0x08 211 #define SPDMEM_DDR3_TCKMIN 0x09 212 #define SPDMEM_DDR3_THERMAL 0x1d 213 214 #define SPDMEM_DDR3_DENSITY_CAPMASK 0x0f 215 #define SPDMEM_DDR3_MOD_ORG_CHIPWIDTH_MASK 0x07 216 #define SPDMEM_DDR3_MOD_ORG_BANKS_SHIFT 3 217 #define SPDMEM_DDR3_MOD_ORG_BANKS_MASK 0x07 218 #define SPDMEM_DDR3_DATAWIDTH_ECCMASK (1 << 3) 219 #define SPDMEM_DDR3_DATAWIDTH_PRIMASK 0x07 220 #define SPDMEM_DDR3_THERMAL_PRESENT (1 << 7) 221 222 #define SPDMEM_DDR3_RDIMM 0x01 223 #define SPDMEM_DDR3_UDIMM 0x02 224 #define SPDMEM_DDR3_SODIMM 0x03 225 #define SPDMEM_DDR3_MICRO_DIMM 0x04 226 #define SPDMEM_DDR3_MINI_RDIMM 0x05 227 #define SPDMEM_DDR3_MINI_UDIMM 0x06 228 229 static const uint8_t ddr2_cycle_tenths[] = { 230 0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 25, 33, 66, 75, 0, 0 231 }; 232 233 #define SPDMEM_TYPE_MAXLEN 16 234 235 uint16_t spdmem_crc16(struct spdmem_softc *, int); 236 static inline 237 uint8_t spdmem_read(struct spdmem_softc *, uint8_t); 238 void spdmem_sdram_decode(struct spdmem_softc *, struct spdmem *); 239 void spdmem_rdr_decode(struct spdmem_softc *, struct spdmem *); 240 void spdmem_ddr_decode(struct spdmem_softc *, struct spdmem *); 241 void spdmem_ddr2_decode(struct spdmem_softc *, struct spdmem *); 242 void spdmem_fbdimm_decode(struct spdmem_softc *, struct spdmem *); 243 void spdmem_ddr3_decode(struct spdmem_softc *, struct spdmem *); 244 245 struct cfdriver spdmem_cd = { 246 NULL, "spdmem", DV_DULL 247 }; 248 249 #define IS_RAMBUS_TYPE (s->sm_len < 4) 250 251 static const char *spdmem_basic_types[] = { 252 "unknown", 253 "FPM", 254 "EDO", 255 "Pipelined Nibble", 256 "SDRAM", 257 "ROM", 258 "DDR SGRAM", 259 "DDR SDRAM", 260 "DDR2 SDRAM", 261 "DDR2 SDRAM FB-DIMM", 262 "DDR2 SDRAM FB-DIMM Probe", 263 "DDR3 SDRAM" 264 }; 265 266 static const char *spdmem_superset_types[] = { 267 "unknown", 268 "ESDRAM", 269 "DDR ESDRAM", 270 "PEM EDO", 271 "PEM SDRAM" 272 }; 273 274 static const char *spdmem_parity_types[] = { 275 "non-parity", 276 "data parity", 277 "ECC", 278 "data parity and ECC", 279 "cmd/addr parity", 280 "cmd/addr/data parity", 281 "cmd/addr parity, data ECC", 282 "cmd/addr/data parity, data ECC" 283 }; 284 285 static inline uint8_t 286 spdmem_read(struct spdmem_softc *sc, uint8_t reg) 287 { 288 return (*sc->sc_read)(sc, reg); 289 } 290 291 /* CRC functions used for certain memory types */ 292 uint16_t 293 spdmem_crc16(struct spdmem_softc *sc, int count) 294 { 295 uint16_t crc; 296 int i, j; 297 uint8_t val; 298 crc = 0; 299 for (j = 0; j <= count; j++) { 300 val = spdmem_read(sc, j); 301 crc = crc ^ val << 8; 302 for (i = 0; i < 8; ++i) 303 if (crc & 0x8000) 304 crc = crc << 1 ^ 0x1021; 305 else 306 crc = crc << 1; 307 } 308 return (crc & 0xFFFF); 309 } 310 311 void 312 spdmem_sdram_decode(struct spdmem_softc *sc, struct spdmem *s) 313 { 314 const char *type; 315 int dimm_size, p_clk; 316 int num_banks, per_chip; 317 uint8_t rows, cols; 318 319 type = spdmem_basic_types[s->sm_type]; 320 321 if (s->sm_data[SPDMEM_SDR_SUPERSET] == SPDMEM_SUPERSET_SDR_PEM) 322 type = spdmem_superset_types[SPDMEM_SUPERSET_SDR_PEM]; 323 if (s->sm_data[SPDMEM_SDR_SUPERSET] == SPDMEM_SUPERSET_ESDRAM) 324 type = spdmem_superset_types[SPDMEM_SUPERSET_ESDRAM]; 325 326 num_banks = s->sm_data[SPDMEM_SDR_BANKS]; 327 per_chip = s->sm_data[SPDMEM_SDR_BANKS_PER_CHIP]; 328 rows = s->sm_data[SPDMEM_SDR_ROWS] & 0x0f; 329 cols = s->sm_data[SPDMEM_SDR_COLS] & 0x0f; 330 dimm_size = (1 << (rows + cols - 17)) * num_banks * per_chip; 331 332 if (dimm_size > 0) { 333 if (dimm_size < 1024) 334 printf(" %dMB", dimm_size); 335 else 336 printf(" %dGB", dimm_size / 1024); 337 } 338 339 printf(" %s", type); 340 341 if (s->sm_data[SPDMEM_DDR_MOD_ATTRIB] & SPDMEM_DDR_ATTRIB_REG) 342 printf(" registered"); 343 344 if (s->sm_data[SPDMEM_FPM_CONFIG] < 8) 345 printf(" %s", 346 spdmem_parity_types[s->sm_data[SPDMEM_FPM_CONFIG]]); 347 348 p_clk = 66; 349 if (s->sm_len >= 128) { 350 switch (spdmem_read(sc, SPDMEM_SDR_FREQUENCY)) { 351 case SPDMEM_SDR_FREQ_100: 352 case SPDMEM_SDR_FREQ_133: 353 /* We need to check ns to decide here */ 354 if (s->sm_data[SPDMEM_SDR_CYCLE] < 0x80) 355 p_clk = 133; 356 else 357 p_clk = 100; 358 break; 359 case SPDMEM_SDR_FREQ_66: 360 default: 361 p_clk = 66; 362 break; 363 } 364 } 365 printf(" PC%d", p_clk); 366 367 /* Print CAS latency */ 368 if (s->sm_len < 128) 369 return; 370 if (spdmem_read(sc, SPDMEM_SDR_CAS) & SPDMEM_SDR_CAS2) 371 printf("CL2"); 372 else if (spdmem_read(sc, SPDMEM_SDR_CAS) & SPDMEM_SDR_CAS3) 373 printf("CL3"); 374 } 375 376 void 377 spdmem_rdr_decode(struct spdmem_softc *sc, struct spdmem *s) 378 { 379 int rimm_size; 380 uint8_t row_bits, col_bits, bank_bits; 381 382 row_bits = s->sm_data[SPDMEM_RDR_ROWS_COLS] >> 4; 383 col_bits = s->sm_data[SPDMEM_RDR_ROWS_COLS] & 0x0f; 384 bank_bits = s->sm_data[SPDMEM_RDR_BANK] & 0x07; 385 386 /* subtracting 13 here is a cheaper way of dividing by 8k later */ 387 rimm_size = 1 << (row_bits + col_bits + bank_bits - 13); 388 389 if (rimm_size < 1024) 390 printf(" %dMB ", rimm_size); 391 else 392 printf(" %dGB ", rimm_size / 1024); 393 394 switch(s->sm_data[SPDMEM_RDR_MODULE_TYPE]) { 395 case SPDMEM_RDR_TYPE_RIMM: 396 printf("RIMM"); 397 break; 398 case SPDMEM_RDR_TYPE_SORIMM: 399 printf("SO-RIMM"); 400 break; 401 case SPDMEM_RDR_TYPE_EMBED: 402 printf("Embedded Rambus"); 403 break; 404 case SPDMEM_RDR_TYPE_RIMM32: 405 printf("RIMM32"); 406 break; 407 } 408 } 409 410 void 411 spdmem_ddr_decode(struct spdmem_softc *sc, struct spdmem *s) 412 { 413 const char *type; 414 int dimm_size, cycle_time, d_clk, p_clk, bits; 415 int i, num_banks, per_chip; 416 uint8_t config, rows, cols, cl; 417 418 type = spdmem_basic_types[s->sm_type]; 419 420 if (s->sm_data[SPDMEM_DDR_SUPERSET] == SPDMEM_SUPERSET_DDR_ESDRAM) 421 type = spdmem_superset_types[SPDMEM_SUPERSET_DDR_ESDRAM]; 422 423 num_banks = s->sm_data[SPDMEM_SDR_BANKS]; 424 per_chip = s->sm_data[SPDMEM_SDR_BANKS_PER_CHIP]; 425 rows = s->sm_data[SPDMEM_SDR_ROWS] & 0x0f; 426 cols = s->sm_data[SPDMEM_SDR_COLS] & 0x0f; 427 dimm_size = (1 << (rows + cols - 17)) * num_banks * per_chip; 428 429 if (dimm_size > 0) { 430 if (dimm_size < 1024) 431 printf(" %dMB", dimm_size); 432 else 433 printf(" %dGB", dimm_size / 1024); 434 } 435 436 printf(" %s", type); 437 438 if (s->sm_data[SPDMEM_DDR_MOD_ATTRIB] & SPDMEM_DDR_ATTRIB_REG) 439 printf(" registered"); 440 441 if (s->sm_data[SPDMEM_FPM_CONFIG] < 8) 442 printf(" %s", 443 spdmem_parity_types[s->sm_data[SPDMEM_FPM_CONFIG]]); 444 445 /* cycle_time is expressed in units of 0.01 ns */ 446 cycle_time = (s->sm_data[SPDMEM_DDR_CYCLE] >> 4) * 100 + 447 (s->sm_data[SPDMEM_DDR_CYCLE] & 0x0f) * 10; 448 449 if (cycle_time != 0) { 450 /* 451 * cycle time is scaled by a factor of 100 to avoid using 452 * floating point. Calculate memory speed as the number 453 * of cycles per microsecond. 454 * DDR uses dual-pumped clock 455 */ 456 d_clk = 100 * 1000 * 2; 457 config = s->sm_data[SPDMEM_FPM_CONFIG]; 458 bits = s->sm_data[SPDMEM_DDR_DATAWIDTH] | 459 (s->sm_data[SPDMEM_DDR_DATAWIDTH + 1] << 8); 460 if (config == 1 || config == 2) 461 bits -= 8; 462 463 d_clk /= cycle_time; 464 p_clk = d_clk * bits / 8; 465 if ((p_clk % 100) >= 50) 466 p_clk += 50; 467 p_clk -= p_clk % 100; 468 printf(" PC%d", p_clk); 469 } 470 471 /* Print CAS latency */ 472 for (i = 6; i >= 0; i--) { 473 if (s->sm_data[SPDMEM_DDR_CAS] & (1 << i)) { 474 cl = ((i * 10) / 2) + 10; 475 printf("CL%d.%d", cl / 10, cl % 10); 476 break; 477 } 478 } 479 } 480 481 void 482 spdmem_ddr2_decode(struct spdmem_softc *sc, struct spdmem *s) 483 { 484 const char *type; 485 int dimm_size, cycle_time, d_clk, p_clk, bits; 486 int i, num_ranks, density; 487 uint8_t config; 488 489 type = spdmem_basic_types[s->sm_type]; 490 491 num_ranks = (s->sm_data[SPDMEM_DDR2_RANKS] & 0x7) + 1; 492 density = (s->sm_data[SPDMEM_DDR2_RANK_DENSITY] & 0xf0) | 493 ((s->sm_data[SPDMEM_DDR2_RANK_DENSITY] & 0x0f) << 8); 494 dimm_size = num_ranks * density * 4; 495 496 if (dimm_size > 0) { 497 if (dimm_size < 1024) 498 printf(" %dMB", dimm_size); 499 else 500 printf(" %dGB", dimm_size / 1024); 501 } 502 503 printf(" %s", type); 504 505 if (s->sm_data[SPDMEM_DDR2_DIMMTYPE] & SPDMEM_DDR2_TYPE_REGMASK) 506 printf(" registered"); 507 508 if (s->sm_data[SPDMEM_FPM_CONFIG] < 8) 509 printf(" %s", 510 spdmem_parity_types[s->sm_data[SPDMEM_FPM_CONFIG]]); 511 512 /* cycle_time is expressed in units of 0.01 ns */ 513 cycle_time = (s->sm_data[SPDMEM_DDR2_CYCLE] >> 4) * 100 + 514 ddr2_cycle_tenths[(s->sm_data[SPDMEM_DDR2_CYCLE] & 0x0f)]; 515 516 if (cycle_time != 0) { 517 /* 518 * cycle time is scaled by a factor of 100 to avoid using 519 * floating point. Calculate memory speed as the number 520 * of cycles per microsecond. 521 * DDR2 uses quad-pumped clock 522 */ 523 d_clk = 100 * 1000 * 4; 524 config = s->sm_data[SPDMEM_FPM_CONFIG]; 525 bits = s->sm_data[SPDMEM_DDR2_DATAWIDTH]; 526 if ((config & 0x03) != 0) 527 bits -= 8; 528 d_clk /= cycle_time; 529 d_clk = (d_clk + 1) / 2; 530 p_clk = d_clk * bits / 8; 531 p_clk -= p_clk % 100; 532 printf(" PC2-%d", p_clk); 533 } 534 535 /* Print CAS latency */ 536 for (i = 5; i >= 2; i--) { 537 if (s->sm_data[SPDMEM_DDR_CAS] & (i << i)) { 538 printf("CL%d", i); 539 break; 540 } 541 } 542 543 switch (s->sm_data[SPDMEM_DDR2_DIMMTYPE]) { 544 case SPDMEM_DDR2_SODIMM: 545 printf(" SO-DIMM"); 546 break; 547 case SPDMEM_DDR2_MICRO_DIMM: 548 printf(" Micro-DIMM"); 549 break; 550 case SPDMEM_DDR2_MINI_RDIMM: 551 case SPDMEM_DDR2_MINI_UDIMM: 552 printf(" Mini-DIMM"); 553 break; 554 } 555 } 556 557 void 558 spdmem_fbdimm_decode(struct spdmem_softc *sc, struct spdmem *s) 559 { 560 int dimm_size, cycle_time, d_clk, p_clk, bits; 561 uint8_t rows, cols, dividend, divisor; 562 /* 563 * FB-DIMM is very much like DDR3 564 */ 565 566 cols = (s->sm_data[SPDMEM_FBDIMM_ADDR] & SPDMEM_FBDIMM_ADDR_COL) >> 567 SPDMEM_FBDIMM_ADDR_COL_SHIFT; 568 rows = (s->sm_data[SPDMEM_FBDIMM_ADDR] & SPDMEM_FBDIMM_ADDR_ROW) >> 569 SPDMEM_FBDIMM_ADDR_ROW_SHIFT; 570 dimm_size = rows + 12 + cols + 9 - 20 - 3; 571 572 if (dimm_size < 1024) 573 printf(" %dMB", dimm_size); 574 else 575 printf(" %dGB", dimm_size / 1024); 576 577 dividend = s->sm_data[SPDMEM_FBDIMM_MTB_DIVIDEND]; 578 divisor = s->sm_data[SPDMEM_FBDIMM_MTB_DIVISOR]; 579 580 cycle_time = (1000 * dividend + (divisor / 2)) / divisor; 581 582 if (cycle_time != 0) { 583 /* 584 * cycle time is scaled by a factor of 1000 to avoid using 585 * floating point. Calculate memory speed as the number 586 * of cycles per microsecond. 587 */ 588 d_clk = 1000 * 1000; 589 590 /* DDR2 FB-DIMM uses a dual-pumped clock */ 591 d_clk *= 2; 592 bits = 1 << ((s->sm_data[SPDMEM_FBDIMM_RANKS] & 593 SPDMEM_FBDIMM_RANKS_WIDTH) + 2); 594 595 p_clk = (d_clk * bits) / 8 / cycle_time; 596 d_clk = ((d_clk + cycle_time / 2) ) / cycle_time; 597 p_clk -= p_clk % 100; 598 printf(" PC2-%d", p_clk); 599 } 600 } 601 602 void 603 spdmem_ddr3_decode(struct spdmem_softc *sc, struct spdmem *s) 604 { 605 const char *type; 606 int dimm_size, cycle_time, d_clk, p_clk, bits; 607 uint8_t mtype, chipsize, dividend, divisor; 608 uint8_t datawidth, chipwidth, physbanks; 609 610 type = spdmem_basic_types[s->sm_type]; 611 612 chipsize = s->sm_data[SPDMEM_DDR3_DENSITY] & 613 SPDMEM_DDR3_DENSITY_CAPMASK; 614 datawidth = s->sm_data[SPDMEM_DDR3_DATAWIDTH] & 615 SPDMEM_DDR3_DATAWIDTH_PRIMASK; 616 chipwidth = s->sm_data[SPDMEM_DDR3_MOD_ORG] & 617 SPDMEM_DDR3_MOD_ORG_CHIPWIDTH_MASK; 618 physbanks = (s->sm_data[SPDMEM_DDR3_MOD_ORG] >> 619 SPDMEM_DDR3_MOD_ORG_BANKS_SHIFT) & SPDMEM_DDR3_MOD_ORG_BANKS_MASK; 620 621 dimm_size = (chipsize + 28 - 20) - 3 + (datawidth + 3) - 622 (chipwidth + 2); 623 dimm_size = (1 << dimm_size) * (physbanks + 1); 624 625 if (dimm_size < 1024) 626 printf(" %dMB", dimm_size); 627 else 628 printf(" %dGB", dimm_size / 1024); 629 630 printf(" %s", type); 631 632 mtype = s->sm_data[SPDMEM_DDR3_MODTYPE]; 633 if (mtype == SPDMEM_DDR3_RDIMM || mtype == SPDMEM_DDR3_MINI_RDIMM) 634 printf(" registered"); 635 636 if (s->sm_data[SPDMEM_DDR3_DATAWIDTH] & SPDMEM_DDR3_DATAWIDTH_ECCMASK) 637 printf(" ECC"); 638 639 dividend = s->sm_data[SPDMEM_DDR3_MTB_DIVIDEND]; 640 divisor = s->sm_data[SPDMEM_DDR3_MTB_DIVISOR]; 641 cycle_time = (1000 * dividend + (divisor / 2)) / divisor; 642 cycle_time *= s->sm_data[SPDMEM_DDR3_TCKMIN]; 643 644 if (cycle_time != 0) { 645 /* 646 * cycle time is scaled by a factor of 1000 to avoid using 647 * floating point. Calculate memory speed as the number 648 * of cycles per microsecond. 649 * DDR3 uses a dual-pumped clock 650 */ 651 d_clk = 1000 * 1000; 652 d_clk *= 2; 653 bits = 1 << ((s->sm_data[SPDMEM_DDR3_DATAWIDTH] & 654 SPDMEM_DDR3_DATAWIDTH_PRIMASK) + 3); 655 /* 656 * Calculate p_clk first, since for DDR3 we need maximum 657 * significance. DDR3 rating is not rounded to a multiple 658 * of 100. This results in cycle_time of 1.5ns displayed 659 * as p_clk PC3-10666 (d_clk DDR3-1333) 660 */ 661 p_clk = (d_clk * bits) / 8 / cycle_time; 662 p_clk -= (p_clk % 100); 663 d_clk = ((d_clk + cycle_time / 2) ) / cycle_time; 664 printf(" PC3-%d", p_clk); 665 } 666 667 switch (s->sm_data[SPDMEM_DDR3_MODTYPE]) { 668 case SPDMEM_DDR3_SODIMM: 669 printf(" SO-DIMM"); 670 break; 671 case SPDMEM_DDR3_MICRO_DIMM: 672 printf(" Micro-DIMM"); 673 break; 674 case SPDMEM_DDR3_MINI_RDIMM: 675 case SPDMEM_DDR3_MINI_UDIMM: 676 printf(" Mini-DIMM"); 677 break; 678 } 679 680 if (s->sm_data[SPDMEM_DDR3_THERMAL] & SPDMEM_DDR3_THERMAL_PRESENT) 681 printf(" with thermal sensor"); 682 } 683 684 int 685 spdmem_probe(struct spdmem_softc *sc) 686 { 687 uint8_t i, val, type; 688 int cksum = 0; 689 int spd_len, spd_crc_cover; 690 uint16_t crc_calc, crc_spd; 691 692 type = spdmem_read(sc, 2); 693 /* For older memory types, validate the checksum over 1st 63 bytes */ 694 if (type <= SPDMEM_MEMTYPE_DDR2SDRAM) { 695 for (i = 0; i < 63; i++) 696 cksum += spdmem_read(sc, i); 697 698 val = spdmem_read(sc, 63); 699 700 if (cksum == 0 || (cksum & 0xff) != val) { 701 return 0; 702 } else 703 return 1; 704 } 705 706 /* For DDR3 and FBDIMM, verify the CRC */ 707 else if (type <= SPDMEM_MEMTYPE_DDR3SDRAM) { 708 spd_len = spdmem_read(sc, 0); 709 if (spd_len & SPDMEM_SPDCRC_116) 710 spd_crc_cover = 116; 711 else 712 spd_crc_cover = 125; 713 switch (spd_len & SPDMEM_SPDLEN_MASK) { 714 case SPDMEM_SPDLEN_128: 715 spd_len = 128; 716 break; 717 case SPDMEM_SPDLEN_176: 718 spd_len = 176; 719 break; 720 case SPDMEM_SPDLEN_256: 721 spd_len = 256; 722 break; 723 default: 724 return 0; 725 } 726 if (spd_crc_cover > spd_len) 727 return 0; 728 crc_calc = spdmem_crc16(sc, spd_crc_cover); 729 crc_spd = spdmem_read(sc, 127) << 8; 730 crc_spd |= spdmem_read(sc, 126); 731 if (crc_calc != crc_spd) { 732 return 0; 733 } 734 return 1; 735 } 736 737 return 0; 738 } 739 740 void 741 spdmem_attach_common(struct spdmem_softc *sc) 742 { 743 struct spdmem *s = &(sc->sc_spd_data); 744 int i; 745 746 /* All SPD have at least 64 bytes of data including checksum */ 747 for (i = 0; i < 64; i++) { 748 ((uint8_t *)s)[i] = spdmem_read(sc, i); 749 } 750 751 /* 752 * Decode and print SPD contents 753 */ 754 if (s->sm_len < 4) { 755 if (s->sm_type == SPDMEM_MEMTYPE_DIRECT_RAMBUS) 756 spdmem_rdr_decode(sc, s); 757 else 758 printf(" no decode method for Rambus memory"); 759 } else { 760 switch(s->sm_type) { 761 case SPDMEM_MEMTYPE_EDO: 762 case SPDMEM_MEMTYPE_SDRAM: 763 spdmem_sdram_decode(sc, s); 764 break; 765 case SPDMEM_MEMTYPE_DDRSDRAM: 766 spdmem_ddr_decode(sc, s); 767 break; 768 case SPDMEM_MEMTYPE_DDR2SDRAM: 769 spdmem_ddr2_decode(sc, s); 770 break; 771 case SPDMEM_MEMTYPE_FBDIMM: 772 case SPDMEM_MEMTYPE_FBDIMM_PROBE: 773 spdmem_fbdimm_decode(sc, s); 774 break; 775 case SPDMEM_MEMTYPE_DDR3SDRAM: 776 spdmem_ddr3_decode(sc, s); 777 break; 778 case SPDMEM_MEMTYPE_NONE: 779 printf(" no EEPROM found"); 780 break; 781 default: 782 if (s->sm_type <= 10) 783 printf(" no decode method for %s memory", 784 spdmem_basic_types[s->sm_type]); 785 else 786 printf(" unknown memory type %d", s->sm_type); 787 break; 788 } 789 } 790 791 printf("\n"); 792 } 793