1 /* $OpenBSD: spdmem.c,v 1.7 2019/12/21 12:33:03 kettenis 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_DDR4_SPDLEN_128 0x01 /* SPD EEPROM Sizes */
69 #define SPDMEM_DDR4_SPDLEN_256 0x02
70 #define SPDMEM_DDR4_SPDLEN_384 0x03
71 #define SPDMEM_DDR4_SPDLEN_512 0x04
72 #define SPDMEM_DDR4_SPDLEN_MASK 0x0f /* Bits 4 - 6 */
73
74 #define SPDMEM_SPDCRC_116 0x80 /* CRC Bytes covered */
75 #define SPDMEM_SPDCRC_125 0x00
76 #define SPDMEM_SPDCRC_MASK 0x80 /* Bit 7 */
77
78 /* possible values for the memory type */
79 #define SPDMEM_MEMTYPE_FPM 0x01
80 #define SPDMEM_MEMTYPE_EDO 0x02
81 #define SPDMEM_MEMTYPE_PIPE_NIBBLE 0x03
82 #define SPDMEM_MEMTYPE_SDRAM 0x04
83 #define SPDMEM_MEMTYPE_ROM 0x05
84 #define SPDMEM_MEMTYPE_DDRSGRAM 0x06
85 #define SPDMEM_MEMTYPE_DDRSDRAM 0x07
86 #define SPDMEM_MEMTYPE_DDR2SDRAM 0x08
87 #define SPDMEM_MEMTYPE_FBDIMM 0x09
88 #define SPDMEM_MEMTYPE_FBDIMM_PROBE 0x0a
89 #define SPDMEM_MEMTYPE_DDR3SDRAM 0x0b
90 #define SPDMEM_MEMTYPE_DDR4SDRAM 0x0c
91 /* 0xd reserved */
92 #define SPDMEM_MEMTYPE_DDR4ESDRAM 0x0e
93 #define SPDMEM_MEMTYPE_LPDDR3SDRAM 0x0f
94 #define SPDMEM_MEMTYPE_LPDDR4SDRAM 0x10
95 #define SPDMEM_MEMTYPE_LPDDR4XSDRAM 0x11
96 #define SPDMEM_MEMTYPE_DDR5SDRAM 0x12
97 #define SPDMEM_MEMTYPE_LPDDR5SDRAM 0x13
98
99 #define SPDMEM_MEMTYPE_NONE 0xff
100
101 #define SPDMEM_MEMTYPE_DIRECT_RAMBUS 0x01
102 #define SPDMEM_MEMTYPE_RAMBUS 0x11
103
104 /* possible values for the supply voltage */
105 #define SPDMEM_VOLTAGE_TTL_5V 0x00
106 #define SPDMEM_VOLTAGE_TTL_LV 0x01
107 #define SPDMEM_VOLTAGE_HSTTL_1_5V 0x02
108 #define SPDMEM_VOLTAGE_SSTL_3_3V 0x03
109 #define SPDMEM_VOLTAGE_SSTL_2_5V 0x04
110 #define SPDMEM_VOLTAGE_SSTL_1_8V 0x05
111
112 /* possible values for module configuration */
113 #define SPDMEM_MODCONFIG_PARITY 0x01
114 #define SPDMEM_MODCONFIG_ECC 0x02
115
116 /* for DDR2, module configuration is a bit-mask field */
117 #define SPDMEM_MODCONFIG_HAS_DATA_PARITY 0x01
118 #define SPDMEM_MODCONFIG_HAS_DATA_ECC 0x02
119 #define SPDMEM_MODCONFIG_HAS_ADDR_CMD_PARITY 0x04
120
121 /* possible values for the refresh field */
122 #define SPDMEM_REFRESH_STD 0x00
123 #define SPDMEM_REFRESH_QUARTER 0x01
124 #define SPDMEM_REFRESH_HALF 0x02
125 #define SPDMEM_REFRESH_TWOX 0x03
126 #define SPDMEM_REFRESH_FOURX 0x04
127 #define SPDMEM_REFRESH_EIGHTX 0x05
128 #define SPDMEM_REFRESH_SELFREFRESH 0x80
129
130 /* superset types */
131 #define SPDMEM_SUPERSET_ESDRAM 0x01
132 #define SPDMEM_SUPERSET_DDR_ESDRAM 0x02
133 #define SPDMEM_SUPERSET_EDO_PEM 0x03
134 #define SPDMEM_SUPERSET_SDR_PEM 0x04
135
136 /* FPM and EDO DIMMS */
137 #define SPDMEM_FPM_ROWS 0x00
138 #define SPDMEM_FPM_COLS 0x01
139 #define SPDMEM_FPM_BANKS 0x02
140 #define SPDMEM_FPM_CONFIG 0x08
141 #define SPDMEM_FPM_REFRESH 0x09
142 #define SPDMEM_FPM_SUPERSET 0x0c
143
144 /* PC66/PC100/PC133 SDRAM */
145 #define SPDMEM_SDR_ROWS 0x00
146 #define SPDMEM_SDR_COLS 0x01
147 #define SPDMEM_SDR_BANKS 0x02
148 #define SPDMEM_SDR_CYCLE 0x06
149 #define SPDMEM_SDR_BANKS_PER_CHIP 0x0e
150 #define SPDMEM_SDR_MOD_ATTRIB 0x12
151 #define SPDMEM_SDR_SUPERSET 0x1d
152
153 #define SPDMEM_SDR_FREQUENCY 126
154 #define SPDMEM_SDR_CAS 127
155 #define SPDMEM_SDR_FREQ_66 0x66
156 #define SPDMEM_SDR_FREQ_100 0x64
157 #define SPDMEM_SDR_FREQ_133 0x85
158 #define SPDMEM_SDR_CAS2 (1 << 1)
159 #define SPDMEM_SDR_CAS3 (1 << 2)
160
161 /* Rambus Direct DRAM */
162 #define SPDMEM_RDR_MODULE_TYPE 0x00
163 #define SPDMEM_RDR_ROWS_COLS 0x01
164 #define SPDMEM_RDR_BANK 0x02
165
166 #define SPDMEM_RDR_TYPE_RIMM 1
167 #define SPDMEM_RDR_TYPE_SORIMM 2
168 #define SPDMEM_RDR_TYPE_EMBED 3
169 #define SPDMEM_RDR_TYPE_RIMM32 4
170
171 /* Dual Data Rate SDRAM */
172 #define SPDMEM_DDR_ROWS 0x00
173 #define SPDMEM_DDR_COLS 0x01
174 #define SPDMEM_DDR_RANKS 0x02
175 #define SPDMEM_DDR_DATAWIDTH 0x03
176 #define SPDMEM_DDR_VOLTAGE 0x05
177 #define SPDMEM_DDR_CYCLE 0x06
178 #define SPDMEM_DDR_REFRESH 0x09
179 #define SPDMEM_DDR_BANKS_PER_CHIP 0x0e
180 #define SPDMEM_DDR_CAS 0x0f
181 #define SPDMEM_DDR_MOD_ATTRIB 0x12
182 #define SPDMEM_DDR_SUPERSET 0x1d
183
184 #define SPDMEM_DDR_ATTRIB_REG (1 << 1)
185
186 /* Dual Data Rate 2 SDRAM */
187 #define SPDMEM_DDR2_ROWS 0x00
188 #define SPDMEM_DDR2_COLS 0x01
189 #define SPDMEM_DDR2_RANKS 0x02
190 #define SPDMEM_DDR2_DATAWIDTH 0x03
191 #define SPDMEM_DDR2_VOLTAGE 0x05
192 #define SPDMEM_DDR2_CYCLE 0x06
193 #define SPDMEM_DDR2_DIMMTYPE 0x11
194 #define SPDMEM_DDR2_RANK_DENSITY 0x1c
195
196 #define SPDMEM_DDR2_TYPE_REGMASK ((1 << 4) | (1 << 0))
197 #define SPDMEM_DDR2_SODIMM (1 << 2)
198 #define SPDMEM_DDR2_MICRO_DIMM (1 << 3)
199 #define SPDMEM_DDR2_MINI_RDIMM (1 << 4)
200 #define SPDMEM_DDR2_MINI_UDIMM (1 << 5)
201
202 /* DDR2 FB-DIMM SDRAM */
203 #define SPDMEM_FBDIMM_ADDR 0x01
204 #define SPDMEM_FBDIMM_RANKS 0x04
205 #define SPDMEM_FBDIMM_MTB_DIVIDEND 0x06
206 #define SPDMEM_FBDIMM_MTB_DIVISOR 0x07
207 #define SPDMEM_FBDIMM_PROTO 0x4e
208
209 #define SPDMEM_FBDIMM_RANKS_WIDTH 0x07
210 #define SPDMEM_FBDIMM_ADDR_BANKS 0x02
211 #define SPDMEM_FBDIMM_ADDR_COL 0x0c
212 #define SPDMEM_FBDIMM_ADDR_COL_SHIFT 2
213 #define SPDMEM_FBDIMM_ADDR_ROW 0xe0
214 #define SPDMEM_FBDIMM_ADDR_ROW_SHIFT 5
215 #define SPDMEM_FBDIMM_PROTO_ECC (1 << 1)
216
217
218 /* Dual Data Rate 3 SDRAM */
219 #define SPDMEM_DDR3_MODTYPE 0x00
220 #define SPDMEM_DDR3_DENSITY 0x01
221 #define SPDMEM_DDR3_MOD_ORG 0x04
222 #define SPDMEM_DDR3_DATAWIDTH 0x05
223 #define SPDMEM_DDR3_MTB_DIVIDEND 0x07
224 #define SPDMEM_DDR3_MTB_DIVISOR 0x08
225 #define SPDMEM_DDR3_TCKMIN 0x09
226 #define SPDMEM_DDR3_THERMAL 0x1d
227
228 #define SPDMEM_DDR3_DENSITY_CAPMASK 0x0f
229 #define SPDMEM_DDR3_MOD_ORG_CHIPWIDTH_MASK 0x07
230 #define SPDMEM_DDR3_MOD_ORG_BANKS_SHIFT 3
231 #define SPDMEM_DDR3_MOD_ORG_BANKS_MASK 0x07
232 #define SPDMEM_DDR3_DATAWIDTH_ECCMASK (1 << 3)
233 #define SPDMEM_DDR3_DATAWIDTH_PRIMASK 0x07
234 #define SPDMEM_DDR3_THERMAL_PRESENT (1 << 7)
235
236 #define SPDMEM_DDR3_RDIMM 0x01
237 #define SPDMEM_DDR3_UDIMM 0x02
238 #define SPDMEM_DDR3_SODIMM 0x03
239 #define SPDMEM_DDR3_MICRO_DIMM 0x04
240 #define SPDMEM_DDR3_MINI_RDIMM 0x05
241 #define SPDMEM_DDR3_MINI_UDIMM 0x06
242
243 /* Dual Data Rate 4 SDRAM */
244 #define SPDMEM_DDR4_MODTYPE 0x00
245 #define SPDMEM_DDR4_DENSITY 0x01
246 #define SPDMEM_DDR4_PACK_TYPE 0x03
247 #define SPDMEM_DDR4_MOD_ORG 0x09
248 #define SPDMEM_DDR4_DATAWIDTH 0x0a
249 #define SPDMEM_DDR4_THERMAL 0x0b
250 #define SPDMEM_DDR4_TCKMIN_MTB 0x0f
251 #define SPDMEM_DDR4_TCKMIN_FTB 0x7d /* not offset by 3 */
252
253 #define SPDMEM_DDR4_DENSITY_CAPMASK 0x0f
254 #define SPDMEM_DDR4_PACK_TYPE_SIG_LOAD_MASK 0x03
255 #define SPDMEM_DDR4_PACK_TYPE_SIG_SINGLE_LOAD 0x02
256 #define SPDMEM_DDR4_PACK_TYPE_DIE_COUNT_SHIFT 4
257 #define SPDMEM_DDR4_PACK_TYPE_DIE_COUNT_MASK 0x07
258 #define SPDMEM_DDR4_MOD_ORG_CHIPWIDTH_MASK 0x07
259 #define SPDMEM_DDR4_MOD_ORG_BANKS_SHIFT 3
260 #define SPDMEM_DDR4_MOD_ORG_BANKS_MASK 0x07
261 #define SPDMEM_DDR4_DATAWIDTH_ECCMASK (1 << 3)
262 #define SPDMEM_DDR4_DATAWIDTH_PRIMASK 0x07
263 #define SPDMEM_DDR4_THERMAL_PRESENT (1 << 7)
264
265 #define SPDMEM_DDR4_RDIMM 0x01
266 #define SPDMEM_DDR4_UDIMM 0x02
267 #define SPDMEM_DDR4_SODIMM 0x03
268 #define SPDMEM_DDR4_LRDIMM 0x04
269 #define SPDMEM_DDR4_MINI_RDIMM 0x05
270 #define SPDMEM_DDR4_MINI_UDIMM 0x06
271 #define SPDMEM_DDR4_LP_DIMM 0x07
272 #define SPDMEM_DDR4_72B_SO_RDIMM 0x08
273 #define SPDMEM_DDR4_72B_SO_UDIMM 0x09
274 #define SPDMEM_DDR4_16B_SO_DIMM 0x0c
275 #define SPDMEM_DDR4_32B_SO_DIMM 0x0d
276 #define SPDMEM_DDR4_NON_DIMM 0x0e
277 #define SPDMEM_DDR4_MODTYPE_MASK 0x0f
278 #define SPDMEM_DDR4_MODTYPE_HYBRID 0x80
279
280 static const uint8_t ddr2_cycle_tenths[] = {
281 0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 25, 33, 66, 75, 0, 0
282 };
283
284 #define SPDMEM_TYPE_MAXLEN 16
285
286 uint16_t spdmem_crc16(struct spdmem_softc *, int);
287 static inline
288 uint8_t spdmem_read(struct spdmem_softc *, uint8_t);
289 void spdmem_sdram_decode(struct spdmem_softc *, struct spdmem *);
290 void spdmem_rdr_decode(struct spdmem_softc *, struct spdmem *);
291 void spdmem_ddr_decode(struct spdmem_softc *, struct spdmem *);
292 void spdmem_ddr2_decode(struct spdmem_softc *, struct spdmem *);
293 void spdmem_fbdimm_decode(struct spdmem_softc *, struct spdmem *);
294 void spdmem_ddr3_decode(struct spdmem_softc *, struct spdmem *);
295
296 struct cfdriver spdmem_cd = {
297 NULL, "spdmem", DV_DULL
298 };
299
300 #define IS_RAMBUS_TYPE (s->sm_len < 4)
301
302 static const char *spdmem_basic_types[] = {
303 "unknown",
304 "FPM",
305 "EDO",
306 "Pipelined Nibble",
307 "SDRAM",
308 "ROM",
309 "DDR SGRAM",
310 "DDR SDRAM",
311 "DDR2 SDRAM",
312 "DDR2 SDRAM FB-DIMM",
313 "DDR2 SDRAM FB-DIMM Probe",
314 "DDR3 SDRAM",
315 "DDR4 SDRAM",
316 "unknown",
317 "DDR4E SDRAM",
318 "LPDDR3 SDRAM",
319 "LPDDR4 SDRAM",
320 "LPDDR4X SDRAM",
321 "DDR5 SDRAM",
322 "LPDDR5 SDRAM"
323 };
324
325 static const char *spdmem_superset_types[] = {
326 "unknown",
327 "ESDRAM",
328 "DDR ESDRAM",
329 "PEM EDO",
330 "PEM SDRAM"
331 };
332
333 static const char *spdmem_parity_types[] = {
334 "non-parity",
335 "data parity",
336 "ECC",
337 "data parity and ECC",
338 "cmd/addr parity",
339 "cmd/addr/data parity",
340 "cmd/addr parity, data ECC",
341 "cmd/addr/data parity, data ECC"
342 };
343
344 static inline uint8_t
spdmem_read(struct spdmem_softc * sc,uint8_t reg)345 spdmem_read(struct spdmem_softc *sc, uint8_t reg)
346 {
347 return (*sc->sc_read)(sc, reg);
348 }
349
350 /* CRC functions used for certain memory types */
351 uint16_t
spdmem_crc16(struct spdmem_softc * sc,int count)352 spdmem_crc16(struct spdmem_softc *sc, int count)
353 {
354 uint16_t crc;
355 int i, j;
356 uint8_t val;
357 crc = 0;
358 for (j = 0; j <= count; j++) {
359 val = spdmem_read(sc, j);
360 crc = crc ^ val << 8;
361 for (i = 0; i < 8; ++i)
362 if (crc & 0x8000)
363 crc = crc << 1 ^ 0x1021;
364 else
365 crc = crc << 1;
366 }
367 return (crc & 0xFFFF);
368 }
369
370 void
spdmem_sdram_decode(struct spdmem_softc * sc,struct spdmem * s)371 spdmem_sdram_decode(struct spdmem_softc *sc, struct spdmem *s)
372 {
373 const char *type;
374 int dimm_size, p_clk;
375 int num_banks, per_chip;
376 uint8_t rows, cols;
377
378 type = spdmem_basic_types[s->sm_type];
379
380 if (s->sm_data[SPDMEM_SDR_SUPERSET] == SPDMEM_SUPERSET_SDR_PEM)
381 type = spdmem_superset_types[SPDMEM_SUPERSET_SDR_PEM];
382 if (s->sm_data[SPDMEM_SDR_SUPERSET] == SPDMEM_SUPERSET_ESDRAM)
383 type = spdmem_superset_types[SPDMEM_SUPERSET_ESDRAM];
384
385 num_banks = s->sm_data[SPDMEM_SDR_BANKS];
386 per_chip = s->sm_data[SPDMEM_SDR_BANKS_PER_CHIP];
387 rows = s->sm_data[SPDMEM_SDR_ROWS] & 0x0f;
388 cols = s->sm_data[SPDMEM_SDR_COLS] & 0x0f;
389 dimm_size = (1 << (rows + cols - 17)) * num_banks * per_chip;
390
391 if (dimm_size > 0) {
392 if (dimm_size < 1024)
393 printf(" %dMB", dimm_size);
394 else
395 printf(" %dGB", dimm_size / 1024);
396 }
397
398 printf(" %s", type);
399
400 if (s->sm_data[SPDMEM_DDR_MOD_ATTRIB] & SPDMEM_DDR_ATTRIB_REG)
401 printf(" registered");
402
403 if (s->sm_data[SPDMEM_FPM_CONFIG] < 8)
404 printf(" %s",
405 spdmem_parity_types[s->sm_data[SPDMEM_FPM_CONFIG]]);
406
407 p_clk = 66;
408 if (s->sm_len >= 128) {
409 switch (spdmem_read(sc, SPDMEM_SDR_FREQUENCY)) {
410 case SPDMEM_SDR_FREQ_100:
411 case SPDMEM_SDR_FREQ_133:
412 /* We need to check ns to decide here */
413 if (s->sm_data[SPDMEM_SDR_CYCLE] < 0x80)
414 p_clk = 133;
415 else
416 p_clk = 100;
417 break;
418 case SPDMEM_SDR_FREQ_66:
419 default:
420 p_clk = 66;
421 break;
422 }
423 }
424 printf(" PC%d", p_clk);
425
426 /* Print CAS latency */
427 if (s->sm_len < 128)
428 return;
429 if (spdmem_read(sc, SPDMEM_SDR_CAS) & SPDMEM_SDR_CAS2)
430 printf("CL2");
431 else if (spdmem_read(sc, SPDMEM_SDR_CAS) & SPDMEM_SDR_CAS3)
432 printf("CL3");
433 }
434
435 void
spdmem_rdr_decode(struct spdmem_softc * sc,struct spdmem * s)436 spdmem_rdr_decode(struct spdmem_softc *sc, struct spdmem *s)
437 {
438 int rimm_size;
439 uint8_t row_bits, col_bits, bank_bits;
440
441 row_bits = s->sm_data[SPDMEM_RDR_ROWS_COLS] >> 4;
442 col_bits = s->sm_data[SPDMEM_RDR_ROWS_COLS] & 0x0f;
443 bank_bits = s->sm_data[SPDMEM_RDR_BANK] & 0x07;
444
445 /* subtracting 13 here is a cheaper way of dividing by 8k later */
446 rimm_size = 1 << (row_bits + col_bits + bank_bits - 13);
447
448 if (rimm_size < 1024)
449 printf(" %dMB ", rimm_size);
450 else
451 printf(" %dGB ", rimm_size / 1024);
452
453 switch(s->sm_data[SPDMEM_RDR_MODULE_TYPE]) {
454 case SPDMEM_RDR_TYPE_RIMM:
455 printf("RIMM");
456 break;
457 case SPDMEM_RDR_TYPE_SORIMM:
458 printf("SO-RIMM");
459 break;
460 case SPDMEM_RDR_TYPE_EMBED:
461 printf("Embedded Rambus");
462 break;
463 case SPDMEM_RDR_TYPE_RIMM32:
464 printf("RIMM32");
465 break;
466 }
467 }
468
469 void
spdmem_ddr_decode(struct spdmem_softc * sc,struct spdmem * s)470 spdmem_ddr_decode(struct spdmem_softc *sc, struct spdmem *s)
471 {
472 const char *type;
473 int dimm_size, cycle_time, d_clk, p_clk, bits;
474 int i, num_banks, per_chip;
475 uint8_t config, rows, cols, cl;
476
477 type = spdmem_basic_types[s->sm_type];
478
479 if (s->sm_data[SPDMEM_DDR_SUPERSET] == SPDMEM_SUPERSET_DDR_ESDRAM)
480 type = spdmem_superset_types[SPDMEM_SUPERSET_DDR_ESDRAM];
481
482 num_banks = s->sm_data[SPDMEM_SDR_BANKS];
483 per_chip = s->sm_data[SPDMEM_SDR_BANKS_PER_CHIP];
484 rows = s->sm_data[SPDMEM_SDR_ROWS] & 0x0f;
485 cols = s->sm_data[SPDMEM_SDR_COLS] & 0x0f;
486 dimm_size = (1 << (rows + cols - 17)) * num_banks * per_chip;
487
488 if (dimm_size > 0) {
489 if (dimm_size < 1024)
490 printf(" %dMB", dimm_size);
491 else
492 printf(" %dGB", dimm_size / 1024);
493 }
494
495 printf(" %s", type);
496
497 if (s->sm_data[SPDMEM_DDR_MOD_ATTRIB] & SPDMEM_DDR_ATTRIB_REG)
498 printf(" registered");
499
500 if (s->sm_data[SPDMEM_FPM_CONFIG] < 8)
501 printf(" %s",
502 spdmem_parity_types[s->sm_data[SPDMEM_FPM_CONFIG]]);
503
504 /* cycle_time is expressed in units of 0.01 ns */
505 cycle_time = (s->sm_data[SPDMEM_DDR_CYCLE] >> 4) * 100 +
506 (s->sm_data[SPDMEM_DDR_CYCLE] & 0x0f) * 10;
507
508 if (cycle_time != 0) {
509 /*
510 * cycle time is scaled by a factor of 100 to avoid using
511 * floating point. Calculate memory speed as the number
512 * of cycles per microsecond.
513 * DDR uses dual-pumped clock
514 */
515 d_clk = 100 * 1000 * 2;
516 config = s->sm_data[SPDMEM_FPM_CONFIG];
517 bits = s->sm_data[SPDMEM_DDR_DATAWIDTH] |
518 (s->sm_data[SPDMEM_DDR_DATAWIDTH + 1] << 8);
519 if (config == 1 || config == 2)
520 bits -= 8;
521
522 d_clk /= cycle_time;
523 p_clk = d_clk * bits / 8;
524 if ((p_clk % 100) >= 50)
525 p_clk += 50;
526 p_clk -= p_clk % 100;
527 printf(" PC%d", p_clk);
528 }
529
530 /* Print CAS latency */
531 for (i = 6; i >= 0; i--) {
532 if (s->sm_data[SPDMEM_DDR_CAS] & (1 << i)) {
533 cl = ((i * 10) / 2) + 10;
534 printf("CL%d.%d", cl / 10, cl % 10);
535 break;
536 }
537 }
538 }
539
540 void
spdmem_ddr2_decode(struct spdmem_softc * sc,struct spdmem * s)541 spdmem_ddr2_decode(struct spdmem_softc *sc, struct spdmem *s)
542 {
543 const char *type;
544 int dimm_size, cycle_time, d_clk, p_clk, bits;
545 int i, num_ranks, density;
546 uint8_t config;
547
548 type = spdmem_basic_types[s->sm_type];
549
550 num_ranks = (s->sm_data[SPDMEM_DDR2_RANKS] & 0x7) + 1;
551 density = (s->sm_data[SPDMEM_DDR2_RANK_DENSITY] & 0xf0) |
552 ((s->sm_data[SPDMEM_DDR2_RANK_DENSITY] & 0x0f) << 8);
553 dimm_size = num_ranks * density * 4;
554
555 if (dimm_size > 0) {
556 if (dimm_size < 1024)
557 printf(" %dMB", dimm_size);
558 else
559 printf(" %dGB", dimm_size / 1024);
560 }
561
562 printf(" %s", type);
563
564 if (s->sm_data[SPDMEM_DDR2_DIMMTYPE] & SPDMEM_DDR2_TYPE_REGMASK)
565 printf(" registered");
566
567 if (s->sm_data[SPDMEM_FPM_CONFIG] < 8)
568 printf(" %s",
569 spdmem_parity_types[s->sm_data[SPDMEM_FPM_CONFIG]]);
570
571 /* cycle_time is expressed in units of 0.01 ns */
572 cycle_time = (s->sm_data[SPDMEM_DDR2_CYCLE] >> 4) * 100 +
573 ddr2_cycle_tenths[(s->sm_data[SPDMEM_DDR2_CYCLE] & 0x0f)];
574
575 if (cycle_time != 0) {
576 /*
577 * cycle time is scaled by a factor of 100 to avoid using
578 * floating point. Calculate memory speed as the number
579 * of cycles per microsecond.
580 * DDR2 uses quad-pumped clock
581 */
582 d_clk = 100 * 1000 * 4;
583 config = s->sm_data[SPDMEM_FPM_CONFIG];
584 bits = s->sm_data[SPDMEM_DDR2_DATAWIDTH];
585 if ((config & 0x03) != 0)
586 bits -= 8;
587 d_clk /= cycle_time;
588 d_clk = (d_clk + 1) / 2;
589 p_clk = d_clk * bits / 8;
590 p_clk -= p_clk % 100;
591 printf(" PC2-%d", p_clk);
592 }
593
594 /* Print CAS latency */
595 for (i = 7; i >= 2; i--) {
596 if (s->sm_data[SPDMEM_DDR_CAS] & (1 << i)) {
597 printf("CL%d", i);
598 break;
599 }
600 }
601
602 switch (s->sm_data[SPDMEM_DDR2_DIMMTYPE]) {
603 case SPDMEM_DDR2_SODIMM:
604 printf(" SO-DIMM");
605 break;
606 case SPDMEM_DDR2_MICRO_DIMM:
607 printf(" Micro-DIMM");
608 break;
609 case SPDMEM_DDR2_MINI_RDIMM:
610 case SPDMEM_DDR2_MINI_UDIMM:
611 printf(" Mini-DIMM");
612 break;
613 }
614 }
615
616 void
spdmem_fbdimm_decode(struct spdmem_softc * sc,struct spdmem * s)617 spdmem_fbdimm_decode(struct spdmem_softc *sc, struct spdmem *s)
618 {
619 int dimm_size, cycle_time, d_clk, p_clk, bits;
620 uint8_t rows, cols, dividend, divisor;
621 /*
622 * FB-DIMM is very much like DDR3
623 */
624
625 cols = (s->sm_data[SPDMEM_FBDIMM_ADDR] & SPDMEM_FBDIMM_ADDR_COL) >>
626 SPDMEM_FBDIMM_ADDR_COL_SHIFT;
627 rows = (s->sm_data[SPDMEM_FBDIMM_ADDR] & SPDMEM_FBDIMM_ADDR_ROW) >>
628 SPDMEM_FBDIMM_ADDR_ROW_SHIFT;
629 dimm_size = rows + 12 + cols + 9 - 20 - 3;
630
631 if (dimm_size < 1024)
632 printf(" %dMB", dimm_size);
633 else
634 printf(" %dGB", dimm_size / 1024);
635
636 dividend = s->sm_data[SPDMEM_FBDIMM_MTB_DIVIDEND];
637 divisor = s->sm_data[SPDMEM_FBDIMM_MTB_DIVISOR];
638
639 cycle_time = (1000 * dividend + (divisor / 2)) / divisor;
640
641 if (cycle_time != 0) {
642 /*
643 * cycle time is scaled by a factor of 1000 to avoid using
644 * floating point. Calculate memory speed as the number
645 * of cycles per microsecond.
646 */
647 d_clk = 1000 * 1000;
648
649 /* DDR2 FB-DIMM uses a dual-pumped clock */
650 d_clk *= 2;
651 bits = 1 << ((s->sm_data[SPDMEM_FBDIMM_RANKS] &
652 SPDMEM_FBDIMM_RANKS_WIDTH) + 2);
653
654 p_clk = (d_clk * bits) / 8 / cycle_time;
655 p_clk -= p_clk % 100;
656 printf(" PC2-%d", p_clk);
657 }
658 }
659
660 void
spdmem_ddr3_decode(struct spdmem_softc * sc,struct spdmem * s)661 spdmem_ddr3_decode(struct spdmem_softc *sc, struct spdmem *s)
662 {
663 const char *type;
664 int dimm_size, cycle_time, d_clk, p_clk, bits;
665 uint8_t mtype, chipsize, dividend, divisor;
666 uint8_t datawidth, chipwidth, physbanks;
667
668 type = spdmem_basic_types[s->sm_type];
669
670 chipsize = s->sm_data[SPDMEM_DDR3_DENSITY] &
671 SPDMEM_DDR3_DENSITY_CAPMASK;
672 datawidth = s->sm_data[SPDMEM_DDR3_DATAWIDTH] &
673 SPDMEM_DDR3_DATAWIDTH_PRIMASK;
674 chipwidth = s->sm_data[SPDMEM_DDR3_MOD_ORG] &
675 SPDMEM_DDR3_MOD_ORG_CHIPWIDTH_MASK;
676 physbanks = (s->sm_data[SPDMEM_DDR3_MOD_ORG] >>
677 SPDMEM_DDR3_MOD_ORG_BANKS_SHIFT) & SPDMEM_DDR3_MOD_ORG_BANKS_MASK;
678
679 dimm_size = (chipsize + 28 - 20) - 3 + (datawidth + 3) -
680 (chipwidth + 2);
681 dimm_size = (1 << dimm_size) * (physbanks + 1);
682
683 if (dimm_size < 1024)
684 printf(" %dMB", dimm_size);
685 else
686 printf(" %dGB", dimm_size / 1024);
687
688 printf(" %s", type);
689
690 mtype = s->sm_data[SPDMEM_DDR3_MODTYPE];
691 if (mtype == SPDMEM_DDR3_RDIMM || mtype == SPDMEM_DDR3_MINI_RDIMM)
692 printf(" registered");
693
694 if (s->sm_data[SPDMEM_DDR3_DATAWIDTH] & SPDMEM_DDR3_DATAWIDTH_ECCMASK)
695 printf(" ECC");
696
697 dividend = s->sm_data[SPDMEM_DDR3_MTB_DIVIDEND];
698 divisor = s->sm_data[SPDMEM_DDR3_MTB_DIVISOR];
699 cycle_time = (1000 * dividend + (divisor / 2)) / divisor;
700 cycle_time *= s->sm_data[SPDMEM_DDR3_TCKMIN];
701
702 if (cycle_time != 0) {
703 /*
704 * cycle time is scaled by a factor of 1000 to avoid using
705 * floating point. Calculate memory speed as the number
706 * of cycles per microsecond.
707 * DDR3 uses a dual-pumped clock
708 */
709 d_clk = 1000 * 1000;
710 d_clk *= 2;
711 bits = 1 << ((s->sm_data[SPDMEM_DDR3_DATAWIDTH] &
712 SPDMEM_DDR3_DATAWIDTH_PRIMASK) + 3);
713 /*
714 * Calculate p_clk first, since for DDR3 we need maximum
715 * significance. DDR3 rating is not rounded to a multiple
716 * of 100. This results in cycle_time of 1.5ns displayed
717 * as p_clk PC3-10666 (d_clk DDR3-1333)
718 */
719 p_clk = (d_clk * bits) / 8 / cycle_time;
720 p_clk -= (p_clk % 100);
721 d_clk = ((d_clk + cycle_time / 2) ) / cycle_time;
722 printf(" PC3-%d", p_clk);
723 }
724
725 switch (s->sm_data[SPDMEM_DDR3_MODTYPE]) {
726 case SPDMEM_DDR3_SODIMM:
727 printf(" SO-DIMM");
728 break;
729 case SPDMEM_DDR3_MICRO_DIMM:
730 printf(" Micro-DIMM");
731 break;
732 case SPDMEM_DDR3_MINI_RDIMM:
733 case SPDMEM_DDR3_MINI_UDIMM:
734 printf(" Mini-DIMM");
735 break;
736 }
737
738 if (s->sm_data[SPDMEM_DDR3_THERMAL] & SPDMEM_DDR3_THERMAL_PRESENT)
739 printf(" with thermal sensor");
740 }
741
742 void
spdmem_ddr4_decode(struct spdmem_softc * sc,struct spdmem * s)743 spdmem_ddr4_decode(struct spdmem_softc *sc, struct spdmem *s)
744 {
745 static const int ddr4_chipsize[16] = { 256, 512, 1024, 2048, 4096,
746 8 * 1024, 16 * 1024, 32 * 1024, 12 * 1024, 24 * 1024,
747 3 * 1024, 6 * 1024, 18 * 1024 };
748 const char *type;
749 int dimm_size, cycle_time, d_clk, p_clk, bits;
750 uint8_t mtype, chipsize, mtb;
751 int8_t ftb;
752 uint8_t datawidth, chipwidth, physbanks, diecount = 0;
753
754 type = spdmem_basic_types[s->sm_type];
755
756 chipsize = s->sm_data[SPDMEM_DDR4_DENSITY] &
757 SPDMEM_DDR4_DENSITY_CAPMASK;
758 datawidth = s->sm_data[SPDMEM_DDR4_DATAWIDTH] &
759 SPDMEM_DDR4_DATAWIDTH_PRIMASK;
760 chipwidth = s->sm_data[SPDMEM_DDR4_MOD_ORG] &
761 SPDMEM_DDR4_MOD_ORG_CHIPWIDTH_MASK;
762 physbanks = (s->sm_data[SPDMEM_DDR4_MOD_ORG] >>
763 SPDMEM_DDR4_MOD_ORG_BANKS_SHIFT) & SPDMEM_DDR4_MOD_ORG_BANKS_MASK;
764
765 if ((s->sm_data[SPDMEM_DDR4_PACK_TYPE] &
766 SPDMEM_DDR4_PACK_TYPE_SIG_LOAD_MASK) ==
767 SPDMEM_DDR4_PACK_TYPE_SIG_SINGLE_LOAD) {
768 diecount = (s->sm_data[SPDMEM_DDR4_PACK_TYPE] >>
769 SPDMEM_DDR4_PACK_TYPE_DIE_COUNT_SHIFT) &
770 SPDMEM_DDR4_PACK_TYPE_DIE_COUNT_MASK;
771 }
772
773 dimm_size = (datawidth + 3) - (chipwidth + 2);
774 dimm_size = (ddr4_chipsize[chipsize] / 8) * (1 << dimm_size) *
775 (physbanks + 1) * (diecount + 1);
776
777 if (dimm_size < 1024)
778 printf(" %dMB", dimm_size);
779 else
780 printf(" %dGB", dimm_size / 1024);
781
782 printf(" %s", type);
783
784 mtype = s->sm_data[SPDMEM_DDR4_MODTYPE];
785 if (mtype & SPDMEM_DDR4_MODTYPE_HYBRID)
786 printf(" hybrid");
787 mtype &= SPDMEM_DDR4_MODTYPE_MASK;
788 if (mtype == SPDMEM_DDR4_RDIMM || mtype == SPDMEM_DDR4_MINI_RDIMM ||
789 mtype == SPDMEM_DDR4_72B_SO_RDIMM)
790 printf(" registered");
791 if (mtype == SPDMEM_DDR4_72B_SO_UDIMM ||
792 mtype == SPDMEM_DDR4_72B_SO_RDIMM)
793 printf(" 72-bit");
794 if (mtype == SPDMEM_DDR4_32B_SO_DIMM)
795 printf(" 32-bit");
796 if (mtype == SPDMEM_DDR4_16B_SO_DIMM)
797 printf(" 16-bit");
798
799 if (s->sm_data[SPDMEM_DDR4_DATAWIDTH] & SPDMEM_DDR4_DATAWIDTH_ECCMASK)
800 printf(" ECC");
801
802 mtb = s->sm_data[SPDMEM_DDR4_TCKMIN_MTB];
803 /* SPDMEM_DDR4_TCKMIN_FTB (addr 125) is outside of s->sm_data */
804 ftb = spdmem_read(sc, SPDMEM_DDR4_TCKMIN_FTB);
805 cycle_time = mtb * 125 + ftb; /* in ps */
806
807 if (cycle_time != 0) {
808 /*
809 * cycle time is scaled by a factor of 1000 to avoid using
810 * floating point. Calculate memory speed as the number
811 * of cycles per microsecond.
812 * DDR4 uses a dual-pumped clock
813 */
814 d_clk = 1000 * 1000;
815 d_clk *= 2;
816 bits = 1 << ((s->sm_data[SPDMEM_DDR4_DATAWIDTH] &
817 SPDMEM_DDR4_DATAWIDTH_PRIMASK) + 3);
818
819 p_clk = (d_clk * bits) / 8 / cycle_time;
820 p_clk -= (p_clk % 100);
821 printf(" PC4-%d", p_clk);
822 }
823
824 switch (s->sm_data[SPDMEM_DDR4_MODTYPE] & SPDMEM_DDR4_MODTYPE_MASK) {
825 case SPDMEM_DDR4_SODIMM:
826 case SPDMEM_DDR4_72B_SO_RDIMM:
827 case SPDMEM_DDR4_72B_SO_UDIMM:
828 case SPDMEM_DDR4_16B_SO_DIMM:
829 case SPDMEM_DDR4_32B_SO_DIMM:
830 printf(" SO-DIMM");
831 break;
832 case SPDMEM_DDR4_LRDIMM:
833 printf(" LR-DIMM");
834 break;
835 case SPDMEM_DDR4_MINI_RDIMM:
836 case SPDMEM_DDR4_MINI_UDIMM:
837 printf(" Mini-DIMM");
838 break;
839 case SPDMEM_DDR4_LP_DIMM:
840 printf(" LP-DIMM");
841 break;
842 case SPDMEM_DDR4_NON_DIMM:
843 printf(" non-DIMM solution");
844 break;
845 }
846
847 if (s->sm_data[SPDMEM_DDR4_THERMAL] & SPDMEM_DDR4_THERMAL_PRESENT)
848 printf(" with thermal sensor");
849 }
850
851 int
spdmem_probe(struct spdmem_softc * sc)852 spdmem_probe(struct spdmem_softc *sc)
853 {
854 uint8_t i, val, type;
855 int cksum = 0;
856 int spd_len, spd_crc_cover;
857 uint16_t crc_calc, crc_spd;
858
859 type = spdmem_read(sc, 2);
860 /* For older memory types, validate the checksum over 1st 63 bytes */
861 if (type <= SPDMEM_MEMTYPE_DDR2SDRAM) {
862 for (i = 0; i < 63; i++)
863 cksum += spdmem_read(sc, i);
864
865 val = spdmem_read(sc, 63);
866
867 if (cksum == 0 || (cksum & 0xff) != val) {
868 return 0;
869 } else
870 return 1;
871 }
872
873 /* For DDR3 and FBDIMM, verify the CRC */
874 else if (type <= SPDMEM_MEMTYPE_DDR3SDRAM) {
875 spd_len = spdmem_read(sc, 0);
876 if (spd_len & SPDMEM_SPDCRC_116)
877 spd_crc_cover = 116;
878 else
879 spd_crc_cover = 125;
880 switch (spd_len & SPDMEM_SPDLEN_MASK) {
881 case SPDMEM_SPDLEN_128:
882 spd_len = 128;
883 break;
884 case SPDMEM_SPDLEN_176:
885 spd_len = 176;
886 break;
887 case SPDMEM_SPDLEN_256:
888 spd_len = 256;
889 break;
890 default:
891 return 0;
892 }
893 calc_crc:
894 if (spd_crc_cover > spd_len)
895 return 0;
896 crc_calc = spdmem_crc16(sc, spd_crc_cover);
897 crc_spd = spdmem_read(sc, 127) << 8;
898 crc_spd |= spdmem_read(sc, 126);
899 if (crc_calc != crc_spd) {
900 return 0;
901 }
902 return 1;
903 } else if (type <= SPDMEM_MEMTYPE_LPDDR4SDRAM) {
904 spd_len = spdmem_read(sc, 0);
905 spd_crc_cover = 125;
906 switch (spd_len & SPDMEM_DDR4_SPDLEN_MASK) {
907 case SPDMEM_DDR4_SPDLEN_128:
908 spd_len = 128;
909 break;
910 case SPDMEM_DDR4_SPDLEN_256:
911 spd_len = 256;
912 break;
913 case SPDMEM_DDR4_SPDLEN_384:
914 spd_len = 384;
915 break;
916 case SPDMEM_DDR4_SPDLEN_512:
917 spd_len = 512;
918 break;
919 default:
920 return 0;
921 }
922 goto calc_crc;
923 }
924
925 return 0;
926 }
927
928 void
spdmem_attach_common(struct spdmem_softc * sc)929 spdmem_attach_common(struct spdmem_softc *sc)
930 {
931 struct spdmem *s = &(sc->sc_spd_data);
932 int i;
933
934 /* All SPD have at least 64 bytes of data including checksum */
935 for (i = 0; i < 64; i++) {
936 ((uint8_t *)s)[i] = spdmem_read(sc, i);
937 }
938
939 /*
940 * Decode and print SPD contents
941 */
942 if (s->sm_len < 4) {
943 if (s->sm_type == SPDMEM_MEMTYPE_DIRECT_RAMBUS)
944 spdmem_rdr_decode(sc, s);
945 else
946 printf(" no decode method for Rambus memory");
947 } else {
948 switch(s->sm_type) {
949 case SPDMEM_MEMTYPE_EDO:
950 case SPDMEM_MEMTYPE_SDRAM:
951 spdmem_sdram_decode(sc, s);
952 break;
953 case SPDMEM_MEMTYPE_DDRSDRAM:
954 spdmem_ddr_decode(sc, s);
955 break;
956 case SPDMEM_MEMTYPE_DDR2SDRAM:
957 spdmem_ddr2_decode(sc, s);
958 break;
959 case SPDMEM_MEMTYPE_FBDIMM:
960 case SPDMEM_MEMTYPE_FBDIMM_PROBE:
961 spdmem_fbdimm_decode(sc, s);
962 break;
963 case SPDMEM_MEMTYPE_DDR3SDRAM:
964 spdmem_ddr3_decode(sc, s);
965 break;
966 case SPDMEM_MEMTYPE_DDR4SDRAM:
967 case SPDMEM_MEMTYPE_DDR4ESDRAM:
968 case SPDMEM_MEMTYPE_LPDDR3SDRAM:
969 case SPDMEM_MEMTYPE_LPDDR4SDRAM:
970 spdmem_ddr4_decode(sc, s);
971 break;
972 case SPDMEM_MEMTYPE_NONE:
973 printf(" no EEPROM found");
974 break;
975 default:
976 if (s->sm_type <= SPDMEM_MEMTYPE_LPDDR5SDRAM)
977 printf(" no decode method for %s memory",
978 spdmem_basic_types[s->sm_type]);
979 else
980 printf(" unknown memory type %d", s->sm_type);
981 break;
982 }
983 }
984
985 printf("\n");
986 }
987