spdmem.c 21 KB

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