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