xref: /openbsd/sys/dev/spdmem.c (revision 898184e3)
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