1 /*-
2  * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
3  *
4  * Authors: Ravi Pokala ([email protected]), Andriy Gapon ([email protected])
5  *
6  * Copyright (c) 2016 Andriy Gapon <[email protected]>
7  * Copyright (c) 2018 Panasas
8  * All rights reserved.
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions
12  * are met:
13  * 1. Redistributions of source code must retain the above copyright
14  *    notice, this list of conditions and the following disclaimer.
15  * 2. Redistributions in binary form must reproduce the above copyright
16  *    notice, this list of conditions and the following disclaimer in the
17  *    documentation and/or other materials provided with the distribution.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
20  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
23  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29  * SUCH DAMAGE.
30  *
31  * $FreeBSD$
32  */
33 
34 /*
35  * This driver is a super-set of the now-deleted jedec_ts(4), and most of the
36  * code for reading and reporting the temperature is either based on that driver,
37  * or copied from it verbatim.
38  */
39 
40 #include <sys/param.h>
41 #include <sys/kernel.h>
42 #include <sys/bus.h>
43 #include <sys/endian.h>
44 #include <sys/malloc.h>
45 #include <sys/module.h>
46 #include <sys/sysctl.h>
47 #include <sys/systm.h>
48 
49 #include <dev/jedec_dimm/jedec_dimm.h>
50 #include <dev/smbus/smbconf.h>
51 #include <dev/smbus/smbus.h>
52 
53 #include "smbus_if.h"
54 
55 struct jedec_dimm_softc {
56 	device_t dev;
57 	device_t smbus;
58 	uint8_t spd_addr;	/* SMBus address of the SPD EEPROM. */
59 	uint8_t tsod_addr;	/* Address of the Thermal Sensor On DIMM */
60 	uint32_t capacity_mb;
61 	char type_str[5];
62 	char part_str[21]; /* 18 (DDR3) or 20 (DDR4) chars, plus terminator */
63 	char serial_str[9]; /* 4 bytes = 8 nybble characters, plus terminator */
64 	char *slotid_str; /* Optional DIMM slot identifier (silkscreen) */
65 };
66 
67 /* General Thermal Sensor on DIMM (TSOD) identification notes.
68  *
69  * The JEDEC TSE2004av specification defines the device ID that all compliant
70  * devices should use, but very few do in practice. Maybe that's because the
71  * earlier TSE2002av specification was rather vague about that.
72  * Rare examples are IDT TSE2004GB2B0 and Atmel AT30TSE004A, not sure if
73  * they are TSE2004av compliant by design or by accident.
74  * Also, the specification mandates that PCI SIG manufacturer IDs are to be
75  * used, but in practice the JEDEC manufacturer IDs are often used.
76  */
77 const struct jedec_dimm_tsod_dev {
78 	uint16_t	vendor_id;
79 	uint8_t		device_id;
80 	const char	*description;
81 } known_tsod_devices[] = {
82 	/* Analog Devices ADT7408.
83 	 * http://www.analog.com/media/en/technical-documentation/data-sheets/ADT7408.pdf
84 	 */
85 	{ 0x11d4, 0x08, "Analog Devices TSOD" },
86 
87 	/* Atmel AT30TSE002B, AT30TSE004A.
88 	 * http://www.atmel.com/images/doc8711.pdf
89 	 * http://www.atmel.com/images/atmel-8868-dts-at30tse004a-datasheet.pdf
90 	 * Note how one chip uses the JEDEC Manufacturer ID while the other
91 	 * uses the PCI SIG one.
92 	 */
93 	{ 0x001f, 0x82, "Atmel TSOD" },
94 	{ 0x1114, 0x22, "Atmel TSOD" },
95 
96 	/* Integrated Device Technology (IDT) TS3000B3A, TSE2002B3C,
97 	 * TSE2004GB2B0 chips and their variants.
98 	 * http://www.idt.com/sites/default/files/documents/IDT_TSE2002B3C_DST_20100512_120303152056.pdf
99 	 * http://www.idt.com/sites/default/files/documents/IDT_TS3000B3A_DST_20101129_120303152013.pdf
100 	 * https://www.idt.com/document/dst/tse2004gb2b0-datasheet
101 	 */
102 	{ 0x00b3, 0x29, "IDT TSOD" },
103 	{ 0x00b3, 0x22, "IDT TSOD" },
104 
105 	/* Maxim Integrated MAX6604.
106 	 * Different document revisions specify different Device IDs.
107 	 * Document 19-3837; Rev 0; 10/05 has 0x3e00 while
108 	 * 19-3837; Rev 3; 10/11 has 0x5400.
109 	 * http://datasheets.maximintegrated.com/en/ds/MAX6604.pdf
110 	 */
111 	{ 0x004d, 0x3e, "Maxim Integrated TSOD" },
112 	{ 0x004d, 0x54, "Maxim Integrated TSOD" },
113 
114 	/* Microchip Technology MCP9805, MCP9843, MCP98242, MCP98243
115 	 * and their variants.
116 	 * http://ww1.microchip.com/downloads/en/DeviceDoc/21977b.pdf
117 	 * Microchip Technology EMC1501.
118 	 * http://ww1.microchip.com/downloads/en/DeviceDoc/00001605A.pdf
119 	 */
120 	{ 0x0054, 0x00, "Microchip TSOD" },
121 	{ 0x0054, 0x20, "Microchip TSOD" },
122 	{ 0x0054, 0x21, "Microchip TSOD" },
123 	{ 0x1055, 0x08, "Microchip TSOD" },
124 
125 	/* NXP Semiconductors SE97 and SE98.
126 	 * http://www.nxp.com/docs/en/data-sheet/SE97B.pdf
127 	 */
128 	{ 0x1131, 0xa1, "NXP TSOD" },
129 	{ 0x1131, 0xa2, "NXP TSOD" },
130 
131 	/* ON Semiconductor CAT34TS02 revisions B and C, CAT6095 and compatible.
132 	 * https://www.onsemi.com/pub/Collateral/CAT34TS02-D.PDF
133 	 * http://www.onsemi.com/pub/Collateral/CAT6095-D.PDF
134 	 */
135 	{ 0x1b09, 0x08, "ON Semiconductor TSOD" },
136 	{ 0x1b09, 0x0a, "ON Semiconductor TSOD" },
137 
138 	/* ST[Microelectronics] STTS424E02, STTS2002 and others.
139 	 * http://www.st.com/resource/en/datasheet/cd00157558.pdf
140 	 * http://www.st.com/resource/en/datasheet/stts2002.pdf
141 	 */
142 	{ 0x104a, 0x00, "ST Microelectronics TSOD" },
143 	{ 0x104a, 0x03, "ST Microelectronics TSOD" },
144 };
145 
146 static int jedec_dimm_attach(device_t dev);
147 
148 static int jedec_dimm_capacity(struct jedec_dimm_softc *sc, enum dram_type type,
149     uint32_t *capacity_mb);
150 
151 static int jedec_dimm_detach(device_t dev);
152 
153 static int jedec_dimm_dump(struct jedec_dimm_softc *sc, enum dram_type type);
154 
155 static int jedec_dimm_field_to_str(struct jedec_dimm_softc *sc, char *dst,
156     size_t dstsz, uint16_t offset, uint16_t len, bool ascii);
157 
158 static int jedec_dimm_probe(device_t dev);
159 
160 static int jedec_dimm_readw_be(struct jedec_dimm_softc *sc, uint8_t reg,
161     uint16_t *val);
162 
163 static int jedec_dimm_temp_sysctl(SYSCTL_HANDLER_ARGS);
164 
165 static const char *jedec_dimm_tsod_match(uint16_t vid, uint16_t did);
166 
167 
168 /**
169  * device_attach() method. Read the DRAM type, use that to determine the offsets
170  * and lengths of the asset string fields. Calculate the capacity. If a TSOD is
171  * present, figure out exactly what it is, and update the device description.
172  * If all of that was successful, create the sysctls for the DIMM. If an
173  * optional slotid has been hinted, create a sysctl for that too.
174  *
175  * @author rpokala
176  *
177  * @param[in,out] dev
178  *      Device being attached.
179  */
180 static int
jedec_dimm_attach(device_t dev)181 jedec_dimm_attach(device_t dev)
182 {
183 	uint8_t byte;
184 	uint16_t devid;
185 	uint16_t partnum_len;
186 	uint16_t partnum_offset;
187 	uint16_t serial_len;
188 	uint16_t serial_offset;
189 	uint16_t tsod_present_offset;
190 	uint16_t vendorid;
191 	bool tsod_present;
192 	int rc;
193 	int new_desc_len;
194 	enum dram_type type;
195 	struct jedec_dimm_softc *sc;
196 	struct sysctl_ctx_list *ctx;
197 	struct sysctl_oid *oid;
198 	struct sysctl_oid_list *children;
199 	const char *tsod_match;
200 	const char *slotid_str;
201 	char *new_desc;
202 
203 	sc = device_get_softc(dev);
204 	ctx = device_get_sysctl_ctx(dev);
205 	oid = device_get_sysctl_tree(dev);
206 	children = SYSCTL_CHILDREN(oid);
207 
208 	bzero(sc, sizeof(*sc));
209 	sc->dev = dev;
210 	sc->smbus = device_get_parent(dev);
211 	sc->spd_addr = smbus_get_addr(dev);
212 
213 	/* The TSOD address has a different DTI from the SPD address, but shares
214 	 * the LSA bits.
215 	 */
216 	sc->tsod_addr = JEDEC_DTI_TSOD | (sc->spd_addr & 0x0f);
217 
218 	/* Read the DRAM type, and set the various offsets and lengths. */
219 	rc = smbus_readb(sc->smbus, sc->spd_addr, SPD_OFFSET_DRAM_TYPE, &byte);
220 	if (rc != 0) {
221 		device_printf(dev, "failed to read dram_type: %d\n", rc);
222 		goto out;
223 	}
224 	type = (enum dram_type) byte;
225 	switch (type) {
226 	case DRAM_TYPE_DDR3_SDRAM:
227 		(void) snprintf(sc->type_str, sizeof(sc->type_str), "DDR3");
228 		partnum_len = SPD_LEN_DDR3_PARTNUM;
229 		partnum_offset = SPD_OFFSET_DDR3_PARTNUM;
230 		serial_len = SPD_LEN_DDR3_SERIAL;
231 		serial_offset = SPD_OFFSET_DDR3_SERIAL;
232 		tsod_present_offset = SPD_OFFSET_DDR3_TSOD_PRESENT;
233 		break;
234 	case DRAM_TYPE_DDR4_SDRAM:
235 		(void) snprintf(sc->type_str, sizeof(sc->type_str), "DDR4");
236 		partnum_len = SPD_LEN_DDR4_PARTNUM;
237 		partnum_offset = SPD_OFFSET_DDR4_PARTNUM;
238 		serial_len = SPD_LEN_DDR4_SERIAL;
239 		serial_offset = SPD_OFFSET_DDR4_SERIAL;
240 		tsod_present_offset = SPD_OFFSET_DDR4_TSOD_PRESENT;
241 		break;
242 	default:
243 		device_printf(dev, "unsupported dram_type 0x%02x\n", type);
244 		rc = EINVAL;
245 		goto out;
246 	}
247 
248 	if (bootverbose) {
249 		/* bootverbose debuggery is best-effort, so ignore the rc. */
250 		(void) jedec_dimm_dump(sc, type);
251 	}
252 
253 	/* Read all the required info from the SPD. If any of it fails, error
254 	 * out without creating the sysctls.
255 	 */
256 	rc = jedec_dimm_capacity(sc, type, &sc->capacity_mb);
257 	if (rc != 0) {
258 		goto out;
259 	}
260 
261 	rc = jedec_dimm_field_to_str(sc, sc->part_str, sizeof(sc->part_str),
262 	    partnum_offset, partnum_len, true);
263 	if (rc != 0) {
264 		goto out;
265 	}
266 
267 	rc = jedec_dimm_field_to_str(sc, sc->serial_str, sizeof(sc->serial_str),
268 	    serial_offset, serial_len, false);
269 	if (rc != 0) {
270 		goto out;
271 	}
272 
273 	/* The MSBit of the TSOD-presence byte reports whether or not the TSOD
274 	 * is in fact present. (While DDR3 and DDR4 don't explicitly require a
275 	 * TSOD, essentially all DDR3 and DDR4 DIMMs include one.) But, as
276 	 * discussed in [PR 235944], it turns out that some DIMMs claim to have
277 	 * a TSOD when they actually don't. (Or maybe the firmware blocks it?)
278 	 * <sigh>
279 	 * If the SPD data says the TSOD is present, try to read manufacturer
280 	 * and device info from it to confirm that it's a valid TSOD device.
281 	 * If the data is unreadable, just continue as if the TSOD isn't there.
282 	 * If the data was read successfully, see if it is a known TSOD device;
283 	 * it's okay if it isn't (tsod_match == NULL).
284 	 */
285 	rc = smbus_readb(sc->smbus, sc->spd_addr, tsod_present_offset, &byte);
286 	if (rc != 0) {
287 		device_printf(dev, "failed to read TSOD-present byte: %d\n",
288 		    rc);
289 		goto out;
290 	}
291 	if (byte & 0x80) {
292 		tsod_present = true;
293 		rc = jedec_dimm_readw_be(sc, TSOD_REG_MANUFACTURER, &vendorid);
294 		if (rc != 0) {
295 			device_printf(dev,
296 			    "failed to read TSOD Manufacturer ID\n");
297 			rc = 0;
298 			goto no_tsod;
299 		}
300 		rc = jedec_dimm_readw_be(sc, TSOD_REG_DEV_REV, &devid);
301 		if (rc != 0) {
302 			device_printf(dev, "failed to read TSOD Device ID\n");
303 			rc = 0;
304 			goto no_tsod;
305 		}
306 
307 		tsod_match = jedec_dimm_tsod_match(vendorid, devid);
308 		if (bootverbose) {
309 			if (tsod_match == NULL) {
310 				device_printf(dev,
311 				    "Unknown TSOD Manufacturer and Device IDs,"
312 				    " 0x%x and 0x%x\n", vendorid, devid);
313 			} else {
314 				device_printf(dev,
315 				    "TSOD: %s\n", tsod_match);
316 			}
317 		}
318 	} else {
319 no_tsod:
320 		tsod_match = NULL;
321 		tsod_present = false;
322 	}
323 
324 	SYSCTL_ADD_STRING(ctx, children, OID_AUTO, "type",
325 	    CTLFLAG_RD | CTLFLAG_MPSAFE, sc->type_str, 0,
326 	    "DIMM type");
327 
328 	SYSCTL_ADD_UINT(ctx, children, OID_AUTO, "capacity",
329 	    CTLFLAG_RD | CTLFLAG_MPSAFE, NULL, sc->capacity_mb,
330 	    "DIMM capacity (MB)");
331 
332 	SYSCTL_ADD_STRING(ctx, children, OID_AUTO, "part",
333 	    CTLFLAG_RD | CTLFLAG_MPSAFE, sc->part_str, 0,
334 	    "DIMM Part Number");
335 
336 	SYSCTL_ADD_STRING(ctx, children, OID_AUTO, "serial",
337 	    CTLFLAG_RD | CTLFLAG_MPSAFE, sc->serial_str, 0,
338 	    "DIMM Serial Number");
339 
340 	/* Create the temperature sysctl IFF the TSOD is present and valid */
341 	if (tsod_present && (tsod_match != NULL)) {
342 		SYSCTL_ADD_PROC(ctx, children, OID_AUTO, "temp",
343 		    CTLTYPE_INT | CTLFLAG_RD | CTLFLAG_MPSAFE, dev, 0,
344 		    jedec_dimm_temp_sysctl, "IK", "DIMM temperature (deg C)");
345 	}
346 
347 	/* If a "slotid" was hinted, add the sysctl for it. */
348 	if (resource_string_value(device_get_name(dev), device_get_unit(dev),
349 	    "slotid", &slotid_str) == 0) {
350 		if (slotid_str != NULL) {
351 			sc->slotid_str = strdup(slotid_str, M_DEVBUF);
352 			SYSCTL_ADD_STRING(ctx, children, OID_AUTO, "slotid",
353 			    CTLFLAG_RD | CTLFLAG_MPSAFE, sc->slotid_str, 0,
354 			    "DIMM Slot Identifier");
355 		}
356 	}
357 
358 	/* If a TSOD type string or a slotid are present, add them to the
359 	 * device description.
360 	 */
361 	if ((tsod_match != NULL) || (sc->slotid_str != NULL)) {
362 		new_desc_len = strlen(device_get_desc(dev));
363 		if (tsod_match != NULL) {
364 			new_desc_len += strlen(tsod_match);
365 			new_desc_len += 4; /* " w/ " */
366 		}
367 		if (sc->slotid_str != NULL) {
368 			new_desc_len += strlen(sc->slotid_str);
369 			new_desc_len += 3; /* space + parens */
370 		}
371 		new_desc_len++; /* terminator */
372 		new_desc = malloc(new_desc_len, M_TEMP, (M_WAITOK | M_ZERO));
373 		(void) snprintf(new_desc, new_desc_len, "%s%s%s%s%s%s",
374 		    device_get_desc(dev),
375 		    (tsod_match ? " w/ " : ""),
376 		    (tsod_match ? tsod_match : ""),
377 		    (sc->slotid_str ? " (" : ""),
378 		    (sc->slotid_str ? sc->slotid_str : ""),
379 		    (sc->slotid_str ? ")" : ""));
380 		device_set_desc_copy(dev, new_desc);
381 		free(new_desc, M_TEMP);
382 	}
383 
384 out:
385 	return (rc);
386 }
387 
388 /**
389  * Calculate the capacity of a DIMM. Both DDR3 and DDR4 encode "geometry"
390  * information in various SPD bytes. The standards documents codify everything
391  * in look-up tables, but it's trivial to reverse-engineer the the formulas for
392  * most of them. Unless otherwise noted, the same formulas apply for both DDR3
393  * and DDR4. The SPD offsets of where the data comes from are different between
394  * the two types, because having them be the same would be too easy.
395  *
396  * @author rpokala
397  *
398  * @param[in] sc
399  *      Instance-specific context data
400  *
401  * @param[in] dram_type
402  *      The locations of the data used to calculate the capacity depends on the
403  *      type of the DIMM.
404  *
405  * @param[out] capacity_mb
406  *      The calculated capacity, in MB
407  */
408 static int
jedec_dimm_capacity(struct jedec_dimm_softc * sc,enum dram_type type,uint32_t * capacity_mb)409 jedec_dimm_capacity(struct jedec_dimm_softc *sc, enum dram_type type,
410     uint32_t *capacity_mb)
411 {
412 	uint8_t bus_width_byte;
413 	uint8_t bus_width_offset;
414 	uint8_t dimm_ranks_byte;
415 	uint8_t dimm_ranks_offset;
416 	uint8_t sdram_capacity_byte;
417 	uint8_t sdram_capacity_offset;
418 	uint8_t sdram_pkg_type_byte;
419 	uint8_t sdram_pkg_type_offset;
420 	uint8_t sdram_width_byte;
421 	uint8_t sdram_width_offset;
422 	uint32_t bus_width;
423 	uint32_t dimm_ranks;
424 	uint32_t sdram_capacity;
425 	uint32_t sdram_pkg_type;
426 	uint32_t sdram_width;
427 	int rc;
428 
429 	switch (type) {
430 	case DRAM_TYPE_DDR3_SDRAM:
431 		bus_width_offset = SPD_OFFSET_DDR3_BUS_WIDTH;
432 		dimm_ranks_offset = SPD_OFFSET_DDR3_DIMM_RANKS;
433 		sdram_capacity_offset = SPD_OFFSET_DDR3_SDRAM_CAPACITY;
434 		sdram_width_offset = SPD_OFFSET_DDR3_SDRAM_WIDTH;
435 		break;
436 	case DRAM_TYPE_DDR4_SDRAM:
437 		bus_width_offset = SPD_OFFSET_DDR4_BUS_WIDTH;
438 		dimm_ranks_offset = SPD_OFFSET_DDR4_DIMM_RANKS;
439 		sdram_capacity_offset = SPD_OFFSET_DDR4_SDRAM_CAPACITY;
440 		sdram_pkg_type_offset = SPD_OFFSET_DDR4_SDRAM_PKG_TYPE;
441 		sdram_width_offset = SPD_OFFSET_DDR4_SDRAM_WIDTH;
442 		break;
443 	default:
444 		device_printf(sc->dev, "unsupported dram_type 0x%02x\n", type);
445 		rc = EINVAL;
446 		goto out;
447 	}
448 
449 	rc = smbus_readb(sc->smbus, sc->spd_addr, bus_width_offset,
450 	    &bus_width_byte);
451 	if (rc != 0) {
452 		device_printf(sc->dev, "failed to read bus_width: %d\n", rc);
453 		goto out;
454 	}
455 
456 	rc = smbus_readb(sc->smbus, sc->spd_addr, dimm_ranks_offset,
457 	    &dimm_ranks_byte);
458 	if (rc != 0) {
459 		device_printf(sc->dev, "failed to read dimm_ranks: %d\n", rc);
460 		goto out;
461 	}
462 
463 	rc = smbus_readb(sc->smbus, sc->spd_addr, sdram_capacity_offset,
464 	    &sdram_capacity_byte);
465 	if (rc != 0) {
466 		device_printf(sc->dev, "failed to read sdram_capacity: %d\n",
467 		    rc);
468 		goto out;
469 	}
470 
471 	rc = smbus_readb(sc->smbus, sc->spd_addr, sdram_width_offset,
472 	    &sdram_width_byte);
473 	if (rc != 0) {
474 		device_printf(sc->dev, "failed to read sdram_width: %d\n", rc);
475 		goto out;
476 	}
477 
478 	/* The "SDRAM Package Type" is only needed for DDR4 DIMMs. */
479 	if (type == DRAM_TYPE_DDR4_SDRAM) {
480 		rc = smbus_readb(sc->smbus, sc->spd_addr, sdram_pkg_type_offset,
481 		    &sdram_pkg_type_byte);
482 		if (rc != 0) {
483 			device_printf(sc->dev,
484 			    "failed to read sdram_pkg_type: %d\n", rc);
485 			goto out;
486 		}
487 	}
488 
489 	/* "Primary bus width, in bits" is in bits [2:0]. */
490 	bus_width_byte &= 0x07;
491 	if (bus_width_byte <= 3) {
492 		bus_width = 1 << bus_width_byte;
493 		bus_width *= 8;
494 	} else {
495 		device_printf(sc->dev, "invalid bus width info\n");
496 		rc = EINVAL;
497 		goto out;
498 	}
499 
500 	/* "Number of ranks per DIMM" is in bits [5:3]. Values 4-7 are only
501 	 * valid for DDR4.
502 	 */
503 	dimm_ranks_byte >>= 3;
504 	dimm_ranks_byte &= 0x07;
505 	if (dimm_ranks_byte <= 7) {
506 		dimm_ranks = dimm_ranks_byte + 1;
507 	} else {
508 		device_printf(sc->dev, "invalid DIMM Rank info\n");
509 		rc = EINVAL;
510 		goto out;
511 	}
512 	if ((dimm_ranks_byte >= 4) && (type != DRAM_TYPE_DDR4_SDRAM)) {
513 		device_printf(sc->dev, "invalid DIMM Rank info\n");
514 		rc = EINVAL;
515 		goto out;
516 	}
517 
518 	/* "Total SDRAM capacity per die, in Mb" is in bits [3:0]. There are two
519 	 * different formulas, for values 0-7 and for values 8-9. Also, values
520 	 * 7-9 are only valid for DDR4.
521 	 */
522 	sdram_capacity_byte &= 0x0f;
523 	if (sdram_capacity_byte <= 7) {
524 		sdram_capacity = 1 << sdram_capacity_byte;
525 		sdram_capacity *= 256;
526 	} else if (sdram_capacity_byte <= 9) {
527 		sdram_capacity = 12 << (sdram_capacity_byte - 8);
528 		sdram_capacity *= 1024;
529 	} else {
530 		device_printf(sc->dev, "invalid SDRAM capacity info\n");
531 		rc = EINVAL;
532 		goto out;
533 	}
534 	if ((sdram_capacity_byte >= 7) && (type != DRAM_TYPE_DDR4_SDRAM)) {
535 		device_printf(sc->dev, "invalid SDRAM capacity info\n");
536 		rc = EINVAL;
537 		goto out;
538 	}
539 
540 	/* "SDRAM device width" is in bits [2:0]. */
541 	sdram_width_byte &= 0x7;
542 	if (sdram_width_byte <= 3) {
543 		sdram_width = 1 << sdram_width_byte;
544 		sdram_width *= 4;
545 	} else {
546 		device_printf(sc->dev, "invalid SDRAM width info\n");
547 		rc = EINVAL;
548 		goto out;
549 	}
550 
551 	/* DDR4 has something called "3DS", which is indicated by [1:0] = 2;
552 	 * when that is the case, the die count is encoded in [6:4], and
553 	 * dimm_ranks is multiplied by it.
554 	 */
555 	if ((type == DRAM_TYPE_DDR4_SDRAM) &&
556 	    ((sdram_pkg_type_byte & 0x3) == 2)) {
557 		sdram_pkg_type_byte >>= 4;
558 		sdram_pkg_type_byte &= 0x07;
559 		sdram_pkg_type = sdram_pkg_type_byte + 1;
560 		dimm_ranks *= sdram_pkg_type;
561 	}
562 
563 	/* Finally, assemble the actual capacity. The formula is the same for
564 	 * both DDR3 and DDR4.
565 	 */
566 	*capacity_mb = sdram_capacity / 8 * bus_width / sdram_width *
567 	    dimm_ranks;
568 
569 out:
570 	return (rc);
571 }
572 
573 /**
574  * device_detach() method. If we allocated sc->slotid_str, free it. Even if we
575  *      didn't allocate, free it anyway; free(NULL) is safe.
576  *
577  * @author rpokala
578  *
579  * @param[in,out] dev
580  *      Device being detached.
581  */
582 static int
jedec_dimm_detach(device_t dev)583 jedec_dimm_detach(device_t dev)
584 {
585 	struct jedec_dimm_softc *sc;
586 
587 	sc = device_get_softc(dev);
588 	free(sc->slotid_str, M_DEVBUF);
589 
590 	return (0);
591 }
592 
593 /**
594  * Read and dump the entire SPD contents.
595  *
596  * @author rpokala
597  *
598  * @param[in] sc
599  *      Instance-specific context data
600  *
601  * @param[in] dram_type
602  *      The length of data which needs to be read and dumped differs based on
603  *      the type of the DIMM.
604  */
605 static int
jedec_dimm_dump(struct jedec_dimm_softc * sc,enum dram_type type)606 jedec_dimm_dump(struct jedec_dimm_softc *sc, enum dram_type type)
607 {
608 	int i;
609 	int rc;
610 	bool page_changed;
611 	uint8_t bytes[512];
612 
613 	page_changed = false;
614 
615 	for (i = 0; i < 256; i++) {
616 		rc = smbus_readb(sc->smbus, sc->spd_addr, i, &bytes[i]);
617 		if (rc != 0) {
618 			device_printf(sc->dev,
619 			    "unable to read page0:0x%02x: %d\n", i, rc);
620 			goto out;
621 		}
622 	}
623 
624 	/* The DDR4 SPD is 512 bytes, but SMBus only allows for 8-bit offsets.
625 	 * JEDEC gets around this by defining the "PAGE" DTI and LSAs.
626 	 */
627 	if (type == DRAM_TYPE_DDR4_SDRAM) {
628 		page_changed = true;
629 		rc = smbus_writeb(sc->smbus,
630 		    (JEDEC_DTI_PAGE | JEDEC_LSA_PAGE_SET1), 0, 0);
631 		if (rc != 0) {
632 			/* Some SPD devices (or SMBus controllers?) claim the
633 			 * page-change command failed when it actually
634 			 * succeeded. Log a message but soldier on.
635 			 */
636 			device_printf(sc->dev, "unable to change page: %d\n",
637 			    rc);
638 		}
639 		/* Add 256 to the store location, because we're in the second
640 		 * page.
641 		 */
642 		for (i = 0; i < 256; i++) {
643 			rc = smbus_readb(sc->smbus, sc->spd_addr, i,
644 			    &bytes[256 + i]);
645 			if (rc != 0) {
646 				device_printf(sc->dev,
647 				    "unable to read page1:0x%02x: %d\n", i, rc);
648 				goto out;
649 			}
650 		}
651 	}
652 
653 	/* Display the data in a nice hexdump format, with byte offsets. */
654 	hexdump(bytes, (page_changed ? 512 : 256), NULL, 0);
655 
656 out:
657 	if (page_changed) {
658 		int rc2;
659 		/* Switch back to page0 before returning. */
660 		rc2 = smbus_writeb(sc->smbus,
661 		    (JEDEC_DTI_PAGE | JEDEC_LSA_PAGE_SET0), 0, 0);
662 		if (rc2 != 0) {
663 			device_printf(sc->dev, "unable to restore page: %d\n",
664 			    rc2);
665 		}
666 	}
667 	return (rc);
668 }
669 
670 /**
671  * Read a specified range of bytes from the SPD, convert them to a string, and
672  * store them in the provided buffer. Some SPD fields are space-padded ASCII,
673  * and some are just a string of bits that we want to convert to a hex string.
674  *
675  * @author rpokala
676  *
677  * @param[in] sc
678  *      Instance-specific context data
679  *
680  * @param[out] dst
681  *      The output buffer to populate
682  *
683  * @param[in] dstsz
684  *      The size of the output buffer
685  *
686  * @param[in] offset
687  *      The starting offset of the field within the SPD
688  *
689  * @param[in] len
690  *      The length in bytes of the field within the SPD
691  *
692  * @param[in] ascii
693  *      Is the field a sequence of ASCII characters? If not, it is binary data
694  *      which should be converted to characters.
695  */
696 static int
jedec_dimm_field_to_str(struct jedec_dimm_softc * sc,char * dst,size_t dstsz,uint16_t offset,uint16_t len,bool ascii)697 jedec_dimm_field_to_str(struct jedec_dimm_softc *sc, char *dst, size_t dstsz,
698     uint16_t offset, uint16_t len, bool ascii)
699 {
700 	uint8_t byte;
701 	int i;
702 	int rc;
703 	bool page_changed;
704 
705 	/* Change to the proper page. Offsets [0, 255] are in page0; offsets
706 	 * [256, 512] are in page1.
707 	 *
708 	 * *The page must be reset to page0 before returning.*
709 	 *
710 	 * For the page-change operation, only the DTI and LSA matter; the
711 	 * offset and write-value are ignored, so use just 0.
712 	 *
713 	 * Mercifully, JEDEC defined the fields such that none of them cross
714 	 * pages, so we don't need to worry about that complication.
715 	 */
716 	if (offset < JEDEC_SPD_PAGE_SIZE) {
717 		page_changed = false;
718 	} else if (offset < (2 * JEDEC_SPD_PAGE_SIZE)) {
719 		page_changed = true;
720 		rc = smbus_writeb(sc->smbus,
721 		    (JEDEC_DTI_PAGE | JEDEC_LSA_PAGE_SET1), 0, 0);
722 		if (rc != 0) {
723 			device_printf(sc->dev,
724 			    "unable to change page for offset 0x%04x: %d\n",
725 			    offset, rc);
726 		}
727 		/* Adjust the offset to account for the page change. */
728 		offset -= JEDEC_SPD_PAGE_SIZE;
729 	} else {
730 		page_changed = false;
731 		rc = EINVAL;
732 		device_printf(sc->dev, "invalid offset 0x%04x\n", offset);
733 		goto out;
734 	}
735 
736 	/* Sanity-check (adjusted) offset and length; everything must be within
737 	 * the same page.
738 	 */
739 	if (offset >= JEDEC_SPD_PAGE_SIZE) {
740 		rc = EINVAL;
741 		device_printf(sc->dev, "invalid offset 0x%04x\n", offset);
742 		goto out;
743 	}
744 	if ((offset + len) >= JEDEC_SPD_PAGE_SIZE) {
745 		rc = EINVAL;
746 		device_printf(sc->dev,
747 		    "(offset + len) would cross page (0x%04x + 0x%04x)\n",
748 		    offset, len);
749 		goto out;
750 	}
751 
752 	/* Sanity-check the destination string length. If we're dealing with
753 	 * ASCII chars, then the destination must be at least the same length;
754 	 * otherwise, it must be *twice* the length, because each byte must
755 	 * be converted into two nybble characters.
756 	 *
757 	 * And, of course, there needs to be an extra byte for the terminator.
758 	 */
759 	if (ascii) {
760 		if (dstsz < (len + 1)) {
761 			rc = EINVAL;
762 			device_printf(sc->dev,
763 			    "destination too short (%u < %u)\n",
764 			    (uint16_t) dstsz, (len + 1));
765 			goto out;
766 		}
767 	} else {
768 		if (dstsz < ((2 * len) + 1)) {
769 			rc = EINVAL;
770 			device_printf(sc->dev,
771 			    "destination too short (%u < %u)\n",
772 			    (uint16_t) dstsz, ((2 * len) + 1));
773 			goto out;
774 		}
775 	}
776 
777 	/* Read a byte at a time. */
778 	for (i = 0; i < len; i++) {
779 		rc = smbus_readb(sc->smbus, sc->spd_addr, (offset + i), &byte);
780 		if (rc != 0) {
781 			device_printf(sc->dev,
782 			    "failed to read byte at 0x%02x: %d\n",
783 			    (offset + i), rc);
784 			goto out;
785 		}
786 		if (ascii) {
787 			/* chars can be copied directly. */
788 			dst[i] = byte;
789 		} else {
790 			/* Raw bytes need to be converted to a two-byte hex
791 			 * string, plus the terminator.
792 			 */
793 			(void) snprintf(&dst[(2 * i)], 3, "%02x", byte);
794 		}
795 	}
796 
797 	/* If we're dealing with ASCII, convert trailing spaces to NULs. */
798 	if (ascii) {
799 		for (i = dstsz; i > 0; i--) {
800 			if (dst[i] == ' ') {
801 				dst[i] = 0;
802 			} else if (dst[i] == 0) {
803 				continue;
804 			} else {
805 				break;
806 			}
807 		}
808 	}
809 
810 out:
811 	if (page_changed) {
812 		int rc2;
813 		/* Switch back to page0 before returning. */
814 		rc2 = smbus_writeb(sc->smbus,
815 		    (JEDEC_DTI_PAGE | JEDEC_LSA_PAGE_SET0), 0, 0);
816 		if (rc2 != 0) {
817 			device_printf(sc->dev,
818 			    "unable to restore page for offset 0x%04x: %d\n",
819 			    offset, rc2);
820 		}
821 	}
822 
823 	return (rc);
824 }
825 
826 /**
827  * device_probe() method. Validate the address that was given as a hint, and
828  * display an error if it's bogus. Make sure that we're dealing with one of the
829  * SPD versions that we can handle.
830  *
831  * @author rpokala
832  *
833  * @param[in] dev
834  *      Device being probed.
835  */
836 static int
jedec_dimm_probe(device_t dev)837 jedec_dimm_probe(device_t dev)
838 {
839 	uint8_t addr;
840 	uint8_t byte;
841 	int rc;
842 	enum dram_type type;
843 	device_t smbus;
844 
845 	smbus = device_get_parent(dev);
846 	addr = smbus_get_addr(dev);
847 
848 	/* Don't bother if this isn't an SPD address, or if the LSBit is set. */
849 	if (((addr & 0xf0) != JEDEC_DTI_SPD) ||
850 	    ((addr & 0x01) != 0)) {
851 		device_printf(dev,
852 		    "invalid \"addr\" hint; address must start with \"0x%x\","
853 		    " and the least-significant bit must be 0\n",
854 		    JEDEC_DTI_SPD);
855 		rc = ENXIO;
856 		goto out;
857 	}
858 
859 	/* Try to read the DRAM_TYPE from the SPD. */
860 	rc = smbus_readb(smbus, addr, SPD_OFFSET_DRAM_TYPE, &byte);
861 	if (rc != 0) {
862 		device_printf(dev, "failed to read dram_type\n");
863 		goto out;
864 	}
865 
866 	/* This driver currently only supports DDR3 and DDR4 SPDs. */
867 	type = (enum dram_type) byte;
868 	switch (type) {
869 	case DRAM_TYPE_DDR3_SDRAM:
870 		rc = BUS_PROBE_DEFAULT;
871 		device_set_desc(dev, "DDR3 DIMM");
872 		break;
873 	case DRAM_TYPE_DDR4_SDRAM:
874 		rc = BUS_PROBE_DEFAULT;
875 		device_set_desc(dev, "DDR4 DIMM");
876 		break;
877 	default:
878 		rc = ENXIO;
879 		break;
880 	}
881 
882 out:
883 	return (rc);
884 }
885 
886 /**
887  * SMBus specifies little-endian byte order, but it looks like the TSODs use
888  * big-endian. Read and convert.
889  *
890  * @author avg
891  *
892  * @param[in] sc
893  *      Instance-specific context data
894  *
895  * @param[in] reg
896  *      The register number to read.
897  *
898  * @param[out] val
899  *      Pointer to populate with the value read.
900  */
901 static int
jedec_dimm_readw_be(struct jedec_dimm_softc * sc,uint8_t reg,uint16_t * val)902 jedec_dimm_readw_be(struct jedec_dimm_softc *sc, uint8_t reg, uint16_t *val)
903 {
904 	int rc;
905 
906 	rc = smbus_readw(sc->smbus, sc->tsod_addr, reg, val);
907 	if (rc != 0) {
908 		goto out;
909 	}
910 	*val = be16toh(*val);
911 
912 out:
913 	return (rc);
914 }
915 
916 /**
917  * Read the temperature data from the TSOD and convert it to the deciKelvin
918  * value that the sysctl expects.
919  *
920  * @author avg
921  */
922 static int
jedec_dimm_temp_sysctl(SYSCTL_HANDLER_ARGS)923 jedec_dimm_temp_sysctl(SYSCTL_HANDLER_ARGS)
924 {
925 	uint16_t val;
926 	int rc;
927 	int temp;
928 	device_t dev = arg1;
929 	struct jedec_dimm_softc *sc;
930 
931 	sc = device_get_softc(dev);
932 
933 	rc = jedec_dimm_readw_be(sc, TSOD_REG_TEMPERATURE, &val);
934 	if (rc != 0) {
935 		goto out;
936 	}
937 
938 	/* The three MSBits are flags, and the next bit is a sign bit. */
939 	temp = val & 0xfff;
940 	if ((val & 0x1000) != 0)
941 		temp = -temp;
942 	/* Each step is 0.0625 degrees, so convert to 1000ths of a degree C. */
943 	temp *= 625;
944 	/* ... and then convert to 1000ths of a Kelvin */
945 	temp += 2731500;
946 	/* As a practical matter, few (if any) TSODs are more accurate than
947 	 * about a tenth of a degree, so round accordingly. This correlates with
948 	 * the "IK" formatting used for this sysctl.
949 	 */
950 	temp = (temp + 500) / 1000;
951 
952 	rc = sysctl_handle_int(oidp, &temp, 0, req);
953 
954 out:
955 	return (rc);
956 }
957 
958 /**
959  * Check the TSOD's Vendor ID and Device ID against the list of known TSOD
960  * devices. Return the description, or NULL if this doesn't look like a valid
961  * TSOD.
962  *
963  * @author avg
964  *
965  * @param[in] vid
966  *      The Vendor ID of the TSOD device
967  *
968  * @param[in] did
969  *      The Device ID of the TSOD device
970  *
971  * @return
972  *      The description string, or NULL for a failure to match.
973  */
974 static const char *
jedec_dimm_tsod_match(uint16_t vid,uint16_t did)975 jedec_dimm_tsod_match(uint16_t vid, uint16_t did)
976 {
977 	const struct jedec_dimm_tsod_dev *d;
978 	int i;
979 
980 	for (i = 0; i < nitems(known_tsod_devices); i++) {
981 		d = &known_tsod_devices[i];
982 		if ((vid == d->vendor_id) && ((did >> 8) == d->device_id)) {
983 			return (d->description);
984 		}
985 	}
986 
987 	/* If no matches for a specific device, then check for a generic
988 	 * TSE2004av-compliant device.
989 	 */
990 	if ((did >> 8) == 0x22) {
991 		return ("TSE2004av compliant TSOD");
992 	}
993 
994 	return (NULL);
995 }
996 
997 static device_method_t jedec_dimm_methods[] = {
998 	/* Methods from the device interface */
999 	DEVMETHOD(device_probe,		jedec_dimm_probe),
1000 	DEVMETHOD(device_attach,	jedec_dimm_attach),
1001 	DEVMETHOD(device_detach,	jedec_dimm_detach),
1002 	DEVMETHOD_END
1003 };
1004 
1005 static driver_t jedec_dimm_driver = {
1006 	.name = "jedec_dimm",
1007 	.methods = jedec_dimm_methods,
1008 	.size = sizeof(struct jedec_dimm_softc),
1009 };
1010 
1011 static devclass_t jedec_dimm_devclass;
1012 
1013 DRIVER_MODULE(jedec_dimm, smbus, jedec_dimm_driver, jedec_dimm_devclass, 0, 0);
1014 MODULE_DEPEND(jedec_dimm, smbus, SMBUS_MINVER, SMBUS_PREFVER, SMBUS_MAXVER);
1015 MODULE_VERSION(jedec_dimm, 1);
1016 
1017 /* vi: set ts=8 sw=4 sts=8 noet: */
1018