1 /*- 2 * SPDX-License-Identifier: BSD-2-Clause 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-2023 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 31 /* 32 * This driver is a super-set of the now-deleted jedec_ts(4), and most of the 33 * code for reading and reporting the temperature is either based on that driver, 34 * or copied from it verbatim. 35 */ 36 37 #include <sys/param.h> 38 #include <sys/kernel.h> 39 #include <sys/bus.h> 40 #include <sys/endian.h> 41 #include <sys/malloc.h> 42 #include <sys/module.h> 43 #include <sys/sysctl.h> 44 #include <sys/systm.h> 45 46 #include <dev/jedec_dimm/jedec_dimm.h> 47 #include <dev/smbus/smbconf.h> 48 #include <dev/smbus/smbus.h> 49 50 #include "smbus_if.h" 51 52 struct jedec_dimm_softc { 53 device_t dev; 54 device_t smbus; 55 uint8_t spd_addr; /* SMBus address of the SPD EEPROM. */ 56 uint8_t tsod_addr; /* Address of the Thermal Sensor On DIMM */ 57 uint8_t mfg_year; 58 uint8_t mfg_week; 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 */ 76 const 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 145 static int jedec_dimm_adjust_offset(struct jedec_dimm_softc *sc, 146 uint16_t orig_offset, uint16_t *new_offset, bool *page_changed); 147 148 static int jedec_dimm_attach(device_t dev); 149 150 static int jedec_dimm_capacity(struct jedec_dimm_softc *sc, enum dram_type type, 151 uint32_t *capacity_mb); 152 153 static int jedec_dimm_detach(device_t dev); 154 155 static int jedec_dimm_dump(struct jedec_dimm_softc *sc, enum dram_type type); 156 157 static int jedec_dimm_field_to_str(struct jedec_dimm_softc *sc, char *dst, 158 size_t dstsz, uint16_t offset, uint16_t len, bool ascii); 159 160 static int jedec_dimm_mfg_date(struct jedec_dimm_softc *sc, enum dram_type type, 161 uint8_t *year, uint8_t *week); 162 163 static int jedec_dimm_probe(device_t dev); 164 165 static int jedec_dimm_readw_be(struct jedec_dimm_softc *sc, uint8_t reg, 166 uint16_t *val); 167 168 static int jedec_dimm_reset_page0(struct jedec_dimm_softc *sc); 169 170 static int jedec_dimm_temp_sysctl(SYSCTL_HANDLER_ARGS); 171 172 static const char *jedec_dimm_tsod_match(uint16_t vid, uint16_t did); 173 174 175 /** 176 * The DDR4 SPD information is spread across two 256-byte pages, but the 177 * offsets in the spec are absolute, not per-page. If a given offset is on the 178 * second page, we need to change to that page and adjust the offset to be 179 * relative to that page. 180 * 181 * @author rpokala 182 * 183 * @param[in] sc 184 * Instance-specific context data 185 * 186 * @param[in] orig_offset 187 * The original value of the offset, before any adjustment is made. 188 * 189 * @param[out] new_offset 190 * The offset to actually read from, adjusted if needed. 191 * 192 * @param[out] page_changed 193 * Whether or not the page was actually changed, and the offset adjusted. 194 * *If 'true', caller must call reset_page0() before itself returning.* 195 */ 196 static int 197 jedec_dimm_adjust_offset(struct jedec_dimm_softc *sc, uint16_t orig_offset, 198 uint16_t *new_offset, bool *page_changed) 199 { 200 int rc; 201 202 /* Don't change the offset, or indicate that the page has been changed, 203 * until the page has actually been changed. 204 */ 205 *new_offset = orig_offset; 206 *page_changed = false; 207 208 /* Change to the proper page. Offsets [0, 255] are in page0; offsets 209 * [256, 511] are in page1. 210 */ 211 if (orig_offset < JEDEC_SPD_PAGE_SIZE) { 212 /* Within page0; no adjustment or page-change required. */ 213 rc = 0; 214 goto out; 215 } else if (orig_offset >= (2 * JEDEC_SPD_PAGE_SIZE)) { 216 /* Outside of expected range. */ 217 rc = EINVAL; 218 device_printf(sc->dev, "invalid offset 0x%04x\n", orig_offset); 219 goto out; 220 } 221 222 /* 'orig_offset' is in page1. Switch to that page, and adjust 223 * 'new_offset' accordingly if successful. 224 * 225 * For the page-change operation, only the DTI and LSA matter; the 226 * offset and write-value are ignored, so just use 0. 227 */ 228 rc = smbus_writeb(sc->smbus, (JEDEC_DTI_PAGE | JEDEC_LSA_PAGE_SET1), 229 0, 0); 230 if (rc != 0) { 231 device_printf(sc->dev, 232 "unable to change page for offset 0x%04x: %d\n", 233 orig_offset, rc); 234 goto out; 235 } 236 *page_changed = true; 237 *new_offset = orig_offset - JEDEC_SPD_PAGE_SIZE; 238 239 out: 240 return (rc); 241 } 242 243 /** 244 * device_attach() method. Read the DRAM type, use that to determine the offsets 245 * and lengths of the asset string fields. Calculate the capacity. If a TSOD is 246 * present, figure out exactly what it is, and update the device description. 247 * If all of that was successful, create the sysctls for the DIMM. If an 248 * optional slotid has been hinted, create a sysctl for that too. 249 * 250 * @author rpokala 251 * 252 * @param[in,out] dev 253 * Device being attached. 254 */ 255 static int 256 jedec_dimm_attach(device_t dev) 257 { 258 uint8_t byte; 259 uint16_t devid; 260 uint16_t partnum_len; 261 uint16_t partnum_offset; 262 uint16_t serial_len; 263 uint16_t serial_offset; 264 uint16_t tsod_present_offset; 265 uint16_t vendorid; 266 bool tsod_present; 267 int rc; 268 enum dram_type type; 269 struct jedec_dimm_softc *sc; 270 struct sysctl_ctx_list *ctx; 271 struct sysctl_oid *oid; 272 struct sysctl_oid_list *children; 273 const char *tsod_match; 274 const char *slotid_str; 275 276 sc = device_get_softc(dev); 277 ctx = device_get_sysctl_ctx(dev); 278 oid = device_get_sysctl_tree(dev); 279 children = SYSCTL_CHILDREN(oid); 280 281 bzero(sc, sizeof(*sc)); 282 sc->dev = dev; 283 sc->smbus = device_get_parent(dev); 284 sc->spd_addr = smbus_get_addr(dev); 285 286 /* The TSOD address has a different DTI from the SPD address, but shares 287 * the LSA bits. 288 */ 289 sc->tsod_addr = JEDEC_DTI_TSOD | (sc->spd_addr & 0x0f); 290 291 /* Read the DRAM type, and set the various offsets and lengths. */ 292 rc = smbus_readb(sc->smbus, sc->spd_addr, SPD_OFFSET_DRAM_TYPE, &byte); 293 if (rc != 0) { 294 device_printf(dev, "failed to read dram_type: %d\n", rc); 295 goto out; 296 } 297 type = (enum dram_type) byte; 298 switch (type) { 299 case DRAM_TYPE_DDR3_SDRAM: 300 (void) snprintf(sc->type_str, sizeof(sc->type_str), "DDR3"); 301 partnum_len = SPD_LEN_DDR3_PARTNUM; 302 partnum_offset = SPD_OFFSET_DDR3_PARTNUM; 303 serial_len = SPD_LEN_DDR3_SERIAL; 304 serial_offset = SPD_OFFSET_DDR3_SERIAL; 305 tsod_present_offset = SPD_OFFSET_DDR3_TSOD_PRESENT; 306 break; 307 case DRAM_TYPE_DDR4_SDRAM: 308 (void) snprintf(sc->type_str, sizeof(sc->type_str), "DDR4"); 309 partnum_len = SPD_LEN_DDR4_PARTNUM; 310 partnum_offset = SPD_OFFSET_DDR4_PARTNUM; 311 serial_len = SPD_LEN_DDR4_SERIAL; 312 serial_offset = SPD_OFFSET_DDR4_SERIAL; 313 tsod_present_offset = SPD_OFFSET_DDR4_TSOD_PRESENT; 314 break; 315 default: 316 device_printf(dev, "unsupported dram_type 0x%02x\n", type); 317 rc = EINVAL; 318 goto out; 319 } 320 321 if (bootverbose) { 322 /* bootverbose debuggery is best-effort, so ignore the rc. */ 323 (void) jedec_dimm_dump(sc, type); 324 } 325 326 /* Read all the required info from the SPD. If any of it fails, error 327 * out without creating the sysctls. 328 */ 329 rc = jedec_dimm_capacity(sc, type, &sc->capacity_mb); 330 if (rc != 0) { 331 goto out; 332 } 333 334 rc = jedec_dimm_mfg_date(sc, type, &sc->mfg_year, &sc->mfg_week); 335 if (rc != 0) { 336 goto out; 337 } 338 339 rc = jedec_dimm_field_to_str(sc, sc->part_str, sizeof(sc->part_str), 340 partnum_offset, partnum_len, true); 341 if (rc != 0) { 342 goto out; 343 } 344 345 rc = jedec_dimm_field_to_str(sc, sc->serial_str, sizeof(sc->serial_str), 346 serial_offset, serial_len, false); 347 if (rc != 0) { 348 goto out; 349 } 350 351 /* The MSBit of the TSOD-presence byte reports whether or not the TSOD 352 * is in fact present. (While DDR3 and DDR4 don't explicitly require a 353 * TSOD, essentially all DDR3 and DDR4 DIMMs include one.) But, as 354 * discussed in [PR 235944], it turns out that some DIMMs claim to have 355 * a TSOD when they actually don't. (Or maybe the firmware blocks it?) 356 * <sigh> 357 * If the SPD data says the TSOD is present, try to read manufacturer 358 * and device info from it to confirm that it's a valid TSOD device. 359 * If the data is unreadable, just continue as if the TSOD isn't there. 360 * If the data was read successfully, see if it is a known TSOD device; 361 * it's okay if it isn't (tsod_match == NULL). 362 */ 363 rc = smbus_readb(sc->smbus, sc->spd_addr, tsod_present_offset, &byte); 364 if (rc != 0) { 365 device_printf(dev, "failed to read TSOD-present byte: %d\n", 366 rc); 367 goto out; 368 } 369 if (byte & 0x80) { 370 tsod_present = true; 371 rc = jedec_dimm_readw_be(sc, TSOD_REG_MANUFACTURER, &vendorid); 372 if (rc != 0) { 373 device_printf(dev, 374 "failed to read TSOD Manufacturer ID\n"); 375 rc = 0; 376 goto no_tsod; 377 } 378 rc = jedec_dimm_readw_be(sc, TSOD_REG_DEV_REV, &devid); 379 if (rc != 0) { 380 device_printf(dev, "failed to read TSOD Device ID\n"); 381 rc = 0; 382 goto no_tsod; 383 } 384 385 tsod_match = jedec_dimm_tsod_match(vendorid, devid); 386 if (bootverbose) { 387 if (tsod_match == NULL) { 388 device_printf(dev, 389 "Unknown TSOD Manufacturer and Device IDs," 390 " 0x%x and 0x%x\n", vendorid, devid); 391 } else { 392 device_printf(dev, 393 "TSOD: %s\n", tsod_match); 394 } 395 } 396 } else { 397 no_tsod: 398 tsod_match = NULL; 399 tsod_present = false; 400 } 401 402 SYSCTL_ADD_STRING(ctx, children, OID_AUTO, "type", 403 CTLFLAG_RD | CTLFLAG_MPSAFE, sc->type_str, 0, 404 "DIMM type"); 405 406 SYSCTL_ADD_UINT(ctx, children, OID_AUTO, "capacity", 407 CTLFLAG_RD | CTLFLAG_MPSAFE, NULL, sc->capacity_mb, 408 "DIMM capacity (MB)"); 409 410 SYSCTL_ADD_STRING(ctx, children, OID_AUTO, "part", 411 CTLFLAG_RD | CTLFLAG_MPSAFE, sc->part_str, 0, 412 "DIMM Part Number"); 413 414 SYSCTL_ADD_STRING(ctx, children, OID_AUTO, "serial", 415 CTLFLAG_RD | CTLFLAG_MPSAFE, sc->serial_str, 0, 416 "DIMM Serial Number"); 417 418 SYSCTL_ADD_U8(ctx, children, OID_AUTO, "mfg_year", 419 CTLFLAG_RD | CTLFLAG_MPSAFE, NULL, sc->mfg_year, 420 "DIMM manufacturing year (20xx)"); 421 422 SYSCTL_ADD_U8(ctx, children, OID_AUTO, "mfg_week", 423 CTLFLAG_RD | CTLFLAG_MPSAFE, NULL, sc->mfg_week, 424 "DIMM manufacturing week"); 425 426 /* Create the temperature sysctl IFF the TSOD is present and valid */ 427 if (tsod_present && (tsod_match != NULL)) { 428 SYSCTL_ADD_PROC(ctx, children, OID_AUTO, "temp", 429 CTLTYPE_INT | CTLFLAG_RD | CTLFLAG_MPSAFE, dev, 0, 430 jedec_dimm_temp_sysctl, "IK", "DIMM temperature (deg C)"); 431 } 432 433 /* If a "slotid" was hinted, add the sysctl for it. */ 434 if (resource_string_value(device_get_name(dev), device_get_unit(dev), 435 "slotid", &slotid_str) == 0) { 436 if (slotid_str != NULL) { 437 sc->slotid_str = strdup(slotid_str, M_DEVBUF); 438 SYSCTL_ADD_STRING(ctx, children, OID_AUTO, "slotid", 439 CTLFLAG_RD | CTLFLAG_MPSAFE, sc->slotid_str, 0, 440 "DIMM Slot Identifier"); 441 } 442 } 443 444 /* If a TSOD type string or a slotid are present, add them to the 445 * device description. 446 */ 447 if ((tsod_match != NULL) || (sc->slotid_str != NULL)) { 448 device_set_descf(dev, "%s%s%s%s%s%s", 449 device_get_desc(dev), 450 (tsod_match ? " w/ " : ""), 451 (tsod_match ? tsod_match : ""), 452 (sc->slotid_str ? " (" : ""), 453 (sc->slotid_str ? sc->slotid_str : ""), 454 (sc->slotid_str ? ")" : "")); 455 } 456 457 out: 458 return (rc); 459 } 460 461 /** 462 * Calculate the capacity of a DIMM. Both DDR3 and DDR4 encode "geometry" 463 * information in various SPD bytes. The standards documents codify everything 464 * in look-up tables, but it's trivial to reverse-engineer the the formulas for 465 * most of them. Unless otherwise noted, the same formulas apply for both DDR3 466 * and DDR4. The SPD offsets of where the data comes from are different between 467 * the two types, because having them be the same would be too easy. 468 * 469 * @author rpokala 470 * 471 * @param[in] sc 472 * Instance-specific context data 473 * 474 * @param[in] dram_type 475 * The locations of the data used to calculate the capacity depends on the 476 * type of the DIMM. 477 * 478 * @param[out] capacity_mb 479 * The calculated capacity, in MB 480 */ 481 static int 482 jedec_dimm_capacity(struct jedec_dimm_softc *sc, enum dram_type type, 483 uint32_t *capacity_mb) 484 { 485 uint8_t bus_width_byte; 486 uint8_t bus_width_offset; 487 uint8_t dimm_ranks_byte; 488 uint8_t dimm_ranks_offset; 489 uint8_t sdram_capacity_byte; 490 uint8_t sdram_capacity_offset; 491 uint8_t sdram_pkg_type_byte; 492 uint8_t sdram_pkg_type_offset; 493 uint8_t sdram_width_byte; 494 uint8_t sdram_width_offset; 495 uint32_t bus_width; 496 uint32_t dimm_ranks; 497 uint32_t sdram_capacity; 498 uint32_t sdram_pkg_type; 499 uint32_t sdram_width; 500 int rc; 501 502 switch (type) { 503 case DRAM_TYPE_DDR3_SDRAM: 504 bus_width_offset = SPD_OFFSET_DDR3_BUS_WIDTH; 505 dimm_ranks_offset = SPD_OFFSET_DDR3_DIMM_RANKS; 506 sdram_capacity_offset = SPD_OFFSET_DDR3_SDRAM_CAPACITY; 507 sdram_width_offset = SPD_OFFSET_DDR3_SDRAM_WIDTH; 508 break; 509 case DRAM_TYPE_DDR4_SDRAM: 510 bus_width_offset = SPD_OFFSET_DDR4_BUS_WIDTH; 511 dimm_ranks_offset = SPD_OFFSET_DDR4_DIMM_RANKS; 512 sdram_capacity_offset = SPD_OFFSET_DDR4_SDRAM_CAPACITY; 513 sdram_pkg_type_offset = SPD_OFFSET_DDR4_SDRAM_PKG_TYPE; 514 sdram_width_offset = SPD_OFFSET_DDR4_SDRAM_WIDTH; 515 break; 516 default: 517 __assert_unreachable(); 518 } 519 520 rc = smbus_readb(sc->smbus, sc->spd_addr, bus_width_offset, 521 &bus_width_byte); 522 if (rc != 0) { 523 device_printf(sc->dev, "failed to read bus_width: %d\n", rc); 524 goto out; 525 } 526 527 rc = smbus_readb(sc->smbus, sc->spd_addr, dimm_ranks_offset, 528 &dimm_ranks_byte); 529 if (rc != 0) { 530 device_printf(sc->dev, "failed to read dimm_ranks: %d\n", rc); 531 goto out; 532 } 533 534 rc = smbus_readb(sc->smbus, sc->spd_addr, sdram_capacity_offset, 535 &sdram_capacity_byte); 536 if (rc != 0) { 537 device_printf(sc->dev, "failed to read sdram_capacity: %d\n", 538 rc); 539 goto out; 540 } 541 542 rc = smbus_readb(sc->smbus, sc->spd_addr, sdram_width_offset, 543 &sdram_width_byte); 544 if (rc != 0) { 545 device_printf(sc->dev, "failed to read sdram_width: %d\n", rc); 546 goto out; 547 } 548 549 /* The "SDRAM Package Type" is only needed for DDR4 DIMMs. */ 550 if (type == DRAM_TYPE_DDR4_SDRAM) { 551 rc = smbus_readb(sc->smbus, sc->spd_addr, sdram_pkg_type_offset, 552 &sdram_pkg_type_byte); 553 if (rc != 0) { 554 device_printf(sc->dev, 555 "failed to read sdram_pkg_type: %d\n", rc); 556 goto out; 557 } 558 } 559 560 /* "Primary bus width, in bits" is in bits [2:0]. */ 561 bus_width_byte &= 0x07; 562 if (bus_width_byte <= 3) { 563 bus_width = 1 << bus_width_byte; 564 bus_width *= 8; 565 } else { 566 device_printf(sc->dev, "invalid bus width info\n"); 567 rc = EINVAL; 568 goto out; 569 } 570 571 /* "Number of ranks per DIMM" is in bits [5:3]. Values 4-7 are only 572 * valid for DDR4. 573 */ 574 dimm_ranks_byte >>= 3; 575 dimm_ranks_byte &= 0x07; 576 if (dimm_ranks_byte <= 7) { 577 dimm_ranks = dimm_ranks_byte + 1; 578 } else { 579 device_printf(sc->dev, "invalid DIMM Rank info\n"); 580 rc = EINVAL; 581 goto out; 582 } 583 if ((dimm_ranks_byte >= 4) && (type != DRAM_TYPE_DDR4_SDRAM)) { 584 device_printf(sc->dev, "invalid DIMM Rank info\n"); 585 rc = EINVAL; 586 goto out; 587 } 588 589 /* "Total SDRAM capacity per die, in Mb" is in bits [3:0]. There are two 590 * different formulas, for values 0-7 and for values 8-9. Also, values 591 * 7-9 are only valid for DDR4. 592 */ 593 sdram_capacity_byte &= 0x0f; 594 if (sdram_capacity_byte <= 7) { 595 sdram_capacity = 1 << sdram_capacity_byte; 596 sdram_capacity *= 256; 597 } else if (sdram_capacity_byte <= 9) { 598 sdram_capacity = 12 << (sdram_capacity_byte - 8); 599 sdram_capacity *= 1024; 600 } else { 601 device_printf(sc->dev, "invalid SDRAM capacity info\n"); 602 rc = EINVAL; 603 goto out; 604 } 605 if ((sdram_capacity_byte >= 7) && (type != DRAM_TYPE_DDR4_SDRAM)) { 606 device_printf(sc->dev, "invalid SDRAM capacity info\n"); 607 rc = EINVAL; 608 goto out; 609 } 610 611 /* "SDRAM device width" is in bits [2:0]. */ 612 sdram_width_byte &= 0x7; 613 if (sdram_width_byte <= 3) { 614 sdram_width = 1 << sdram_width_byte; 615 sdram_width *= 4; 616 } else { 617 device_printf(sc->dev, "invalid SDRAM width info\n"); 618 rc = EINVAL; 619 goto out; 620 } 621 622 /* DDR4 has something called "3DS", which is indicated by [1:0] = 2; 623 * when that is the case, the die count is encoded in [6:4], and 624 * dimm_ranks is multiplied by it. 625 */ 626 if ((type == DRAM_TYPE_DDR4_SDRAM) && 627 ((sdram_pkg_type_byte & 0x3) == 2)) { 628 sdram_pkg_type_byte >>= 4; 629 sdram_pkg_type_byte &= 0x07; 630 sdram_pkg_type = sdram_pkg_type_byte + 1; 631 dimm_ranks *= sdram_pkg_type; 632 } 633 634 /* Finally, assemble the actual capacity. The formula is the same for 635 * both DDR3 and DDR4. 636 */ 637 *capacity_mb = sdram_capacity / 8 * bus_width / sdram_width * 638 dimm_ranks; 639 640 out: 641 return (rc); 642 } 643 644 /** 645 * device_detach() method. If we allocated sc->slotid_str, free it. Even if we 646 * didn't allocate, free it anyway; free(NULL) is safe. 647 * 648 * @author rpokala 649 * 650 * @param[in,out] dev 651 * Device being detached. 652 */ 653 static int 654 jedec_dimm_detach(device_t dev) 655 { 656 struct jedec_dimm_softc *sc; 657 658 sc = device_get_softc(dev); 659 free(sc->slotid_str, M_DEVBUF); 660 661 return (0); 662 } 663 664 /** 665 * Read and dump the entire SPD contents. 666 * 667 * @author rpokala 668 * 669 * @param[in] sc 670 * Instance-specific context data 671 * 672 * @param[in] dram_type 673 * The length of data which needs to be read and dumped differs based on 674 * the type of the DIMM. 675 */ 676 static int 677 jedec_dimm_dump(struct jedec_dimm_softc *sc, enum dram_type type) 678 { 679 int i; 680 int rc; 681 bool page_changed; 682 uint8_t bytes[512]; 683 684 page_changed = false; 685 686 for (i = 0; i < 256; i++) { 687 rc = smbus_readb(sc->smbus, sc->spd_addr, i, &bytes[i]); 688 if (rc != 0) { 689 device_printf(sc->dev, 690 "unable to read page0:0x%02x: %d\n", i, rc); 691 goto out; 692 } 693 } 694 695 /* The DDR4 SPD is 512 bytes, but SMBus only allows for 8-bit offsets. 696 * JEDEC gets around this by defining the "PAGE" DTI and LSAs. 697 */ 698 if (type == DRAM_TYPE_DDR4_SDRAM) { 699 page_changed = true; 700 rc = smbus_writeb(sc->smbus, 701 (JEDEC_DTI_PAGE | JEDEC_LSA_PAGE_SET1), 0, 0); 702 if (rc != 0) { 703 /* Some SPD devices (or SMBus controllers?) claim the 704 * page-change command failed when it actually 705 * succeeded. Log a message but soldier on. 706 */ 707 device_printf(sc->dev, "unable to change page: %d\n", 708 rc); 709 } 710 /* Add 256 to the store location, because we're in the second 711 * page. 712 */ 713 for (i = 0; i < 256; i++) { 714 rc = smbus_readb(sc->smbus, sc->spd_addr, i, 715 &bytes[256 + i]); 716 if (rc != 0) { 717 device_printf(sc->dev, 718 "unable to read page1:0x%02x: %d\n", i, rc); 719 goto out; 720 } 721 } 722 } 723 724 /* Display the data in a nice hexdump format, with byte offsets. */ 725 hexdump(bytes, (page_changed ? 512 : 256), NULL, 0); 726 727 out: 728 if (page_changed) { 729 int rc2; 730 731 rc2 = jedec_dimm_reset_page0(sc); 732 if ((rc2 != 0) && (rc == 0)) { 733 rc = rc2; 734 } 735 } 736 737 return (rc); 738 } 739 740 /** 741 * Read a specified range of bytes from the SPD, convert them to a string, and 742 * store them in the provided buffer. Some SPD fields are space-padded ASCII, 743 * and some are just a string of bits that we want to convert to a hex string. 744 * 745 * @author rpokala 746 * 747 * @param[in] sc 748 * Instance-specific context data 749 * 750 * @param[out] dst 751 * The output buffer to populate 752 * 753 * @param[in] dstsz 754 * The size of the output buffer 755 * 756 * @param[in] offset 757 * The starting offset of the field within the SPD 758 * 759 * @param[in] len 760 * The length in bytes of the field within the SPD 761 * 762 * @param[in] ascii 763 * Is the field a sequence of ASCII characters? If not, it is binary data 764 * which should be converted to characters. 765 */ 766 static int 767 jedec_dimm_field_to_str(struct jedec_dimm_softc *sc, char *dst, size_t dstsz, 768 uint16_t offset, uint16_t len, bool ascii) 769 { 770 uint8_t byte; 771 uint16_t new_offset; 772 int i; 773 int rc; 774 bool page_changed; 775 776 rc = jedec_dimm_adjust_offset(sc, offset, &new_offset, &page_changed); 777 if (rc != 0) { 778 goto out; 779 } 780 781 /* Sanity-check (adjusted) offset and length; everything must be within 782 * the same page. 783 */ 784 if (new_offset >= JEDEC_SPD_PAGE_SIZE) { 785 rc = EINVAL; 786 device_printf(sc->dev, "invalid offset 0x%04x\n", new_offset); 787 goto out; 788 } 789 if ((new_offset + len) >= JEDEC_SPD_PAGE_SIZE) { 790 rc = EINVAL; 791 device_printf(sc->dev, 792 "(new_offset + len) would cross page (0x%04x + 0x%04x)\n", 793 new_offset, len); 794 goto out; 795 } 796 797 /* Sanity-check the destination string length. If we're dealing with 798 * ASCII chars, then the destination must be at least the same length; 799 * otherwise, it must be *twice* the length, because each byte must 800 * be converted into two nybble characters. 801 * 802 * And, of course, there needs to be an extra byte for the terminator. 803 */ 804 if (ascii) { 805 if (dstsz < (len + 1)) { 806 rc = EINVAL; 807 device_printf(sc->dev, 808 "destination too short (%u < %u)\n", 809 (uint16_t) dstsz, (len + 1)); 810 goto out; 811 } 812 } else { 813 if (dstsz < ((2 * len) + 1)) { 814 rc = EINVAL; 815 device_printf(sc->dev, 816 "destination too short (%u < %u)\n", 817 (uint16_t) dstsz, ((2 * len) + 1)); 818 goto out; 819 } 820 } 821 822 /* Read a byte at a time. */ 823 for (i = 0; i < len; i++) { 824 rc = smbus_readb(sc->smbus, sc->spd_addr, (new_offset + i), 825 &byte); 826 if (rc != 0) { 827 device_printf(sc->dev, 828 "failed to read byte at 0x%02x: %d\n", 829 (new_offset + i), rc); 830 goto out; 831 } 832 if (ascii) { 833 /* chars can be copied directly. */ 834 dst[i] = byte; 835 } else { 836 /* Raw bytes need to be converted to a two-byte hex 837 * string, plus the terminator. 838 */ 839 (void) snprintf(&dst[(2 * i)], 3, "%02x", byte); 840 } 841 } 842 843 /* If we're dealing with ASCII, convert trailing spaces to NULs. */ 844 if (ascii) { 845 for (i = dstsz - 1; i > 0; i--) { 846 if (dst[i] == ' ') { 847 dst[i] = 0; 848 } else if (dst[i] == 0) { 849 continue; 850 } else { 851 break; 852 } 853 } 854 } 855 856 out: 857 if (page_changed) { 858 int rc2; 859 860 rc2 = jedec_dimm_reset_page0(sc); 861 if ((rc2 != 0) && (rc == 0)) { 862 rc = rc2; 863 } 864 } 865 866 return (rc); 867 } 868 869 /** 870 * Both DDR3 and DDR4 encode manufacturing date as a one-byte BCD-encoded 871 * year (offset from 2000) and a one-byte BCD-encoded week within that year. 872 * The SPD offsets are different between the two types. 873 * 874 * @author rpokala 875 * 876 * @param[in] sc 877 * Instance-specific context data 878 * 879 * @param[in] dram_type 880 * The locations of the manufacturing date depends on the type of the DIMM. 881 * 882 * @param[out] year 883 * The manufacturing year, offset from 2000 884 * 885 * @param[out] week 886 * The manufacturing week within the year 887 */ 888 static int 889 jedec_dimm_mfg_date(struct jedec_dimm_softc *sc, enum dram_type type, 890 uint8_t *year, uint8_t *week) 891 { 892 uint8_t year_bcd; 893 uint8_t week_bcd; 894 uint16_t year_offset; 895 uint16_t week_offset; 896 bool page_changed; 897 int rc; 898 899 switch (type) { 900 case DRAM_TYPE_DDR3_SDRAM: 901 year_offset = SPD_OFFSET_DDR3_MOD_MFG_YEAR; 902 week_offset = SPD_OFFSET_DDR3_MOD_MFG_WEEK; 903 break; 904 case DRAM_TYPE_DDR4_SDRAM: 905 year_offset = SPD_OFFSET_DDR4_MOD_MFG_YEAR; 906 week_offset = SPD_OFFSET_DDR4_MOD_MFG_WEEK; 907 break; 908 default: 909 __assert_unreachable(); 910 } 911 912 /* Change to the proper page. Offsets [0, 255] are in page0; offsets 913 * [256, 512] are in page1. 914 * 915 * *The page must be reset to page0 before returning.* 916 * 917 * For the page-change operation, only the DTI and LSA matter; the 918 * offset and write-value are ignored, so use just 0. 919 * 920 * Mercifully, JEDEC defined the fields such that all of the 921 * manufacturing-related ones are on the same page, so we don't need to 922 * worry about that complication. 923 */ 924 if (year_offset < JEDEC_SPD_PAGE_SIZE) { 925 page_changed = false; 926 } else if (year_offset < (2 * JEDEC_SPD_PAGE_SIZE)) { 927 page_changed = true; 928 rc = smbus_writeb(sc->smbus, 929 (JEDEC_DTI_PAGE | JEDEC_LSA_PAGE_SET1), 0, 0); 930 if (rc != 0) { 931 device_printf(sc->dev, 932 "unable to change page for offset 0x%04x: %d\n", 933 year_offset, rc); 934 } 935 /* Adjust the offset to account for the page change. */ 936 year_offset -= JEDEC_SPD_PAGE_SIZE; 937 week_offset -= JEDEC_SPD_PAGE_SIZE; 938 } else { 939 device_printf(sc->dev, "invalid offset 0x%04x\n", year_offset); 940 rc = EINVAL; 941 page_changed = false; 942 goto out; 943 } 944 945 rc = smbus_readb(sc->smbus, sc->spd_addr, year_offset, &year_bcd); 946 if (rc != 0) { 947 device_printf(sc->dev, "failed to read mfg year: %d\n", rc); 948 goto out; 949 } 950 951 rc = smbus_readb(sc->smbus, sc->spd_addr, week_offset, &week_bcd); 952 if (rc != 0) { 953 device_printf(sc->dev, "failed to read mfg week: %d\n", rc); 954 goto out; 955 } 956 957 /* Convert from one-byte BCD to one-byte integer. */ 958 *year = (((year_bcd & 0xf0) >> 4) * 10) + (year_bcd & 0x0f); 959 *week = (((week_bcd & 0xf0) >> 4) * 10) + (week_bcd & 0x0f); 960 961 out: 962 if (page_changed) { 963 int rc2; 964 /* Switch back to page0 before returning. */ 965 rc2 = smbus_writeb(sc->smbus, 966 (JEDEC_DTI_PAGE | JEDEC_LSA_PAGE_SET0), 0, 0); 967 if (rc2 != 0) { 968 device_printf(sc->dev, 969 "unable to restore page for offset 0x%04x: %d\n", 970 year_offset, rc2); 971 } 972 } 973 974 return (rc); 975 } 976 977 /** 978 * device_probe() method. Validate the address that was given as a hint, and 979 * display an error if it's bogus. Make sure that we're dealing with one of the 980 * SPD versions that we can handle. 981 * 982 * @author rpokala 983 * 984 * @param[in] dev 985 * Device being probed. 986 */ 987 static int 988 jedec_dimm_probe(device_t dev) 989 { 990 uint8_t addr; 991 uint8_t byte; 992 int rc; 993 enum dram_type type; 994 device_t smbus; 995 996 smbus = device_get_parent(dev); 997 addr = smbus_get_addr(dev); 998 999 /* Don't bother if this isn't an SPD address, or if the LSBit is set. */ 1000 if (((addr & 0xf0) != JEDEC_DTI_SPD) || 1001 ((addr & 0x01) != 0)) { 1002 device_printf(dev, 1003 "invalid \"addr\" hint; address must start with \"0x%x\"," 1004 " and the least-significant bit must be 0\n", 1005 JEDEC_DTI_SPD); 1006 rc = ENXIO; 1007 goto out; 1008 } 1009 1010 /* Try to read the DRAM_TYPE from the SPD. */ 1011 rc = smbus_readb(smbus, addr, SPD_OFFSET_DRAM_TYPE, &byte); 1012 if (rc != 0) { 1013 device_printf(dev, "failed to read dram_type\n"); 1014 goto out; 1015 } 1016 1017 /* This driver currently only supports DDR3 and DDR4 SPDs. */ 1018 type = (enum dram_type) byte; 1019 switch (type) { 1020 case DRAM_TYPE_DDR3_SDRAM: 1021 rc = BUS_PROBE_DEFAULT; 1022 device_set_desc(dev, "DDR3 DIMM"); 1023 break; 1024 case DRAM_TYPE_DDR4_SDRAM: 1025 rc = BUS_PROBE_DEFAULT; 1026 device_set_desc(dev, "DDR4 DIMM"); 1027 break; 1028 default: 1029 rc = ENXIO; 1030 break; 1031 } 1032 1033 out: 1034 return (rc); 1035 } 1036 1037 /** 1038 * SMBus specifies little-endian byte order, but it looks like the TSODs use 1039 * big-endian. Read and convert. 1040 * 1041 * @author avg 1042 * 1043 * @param[in] sc 1044 * Instance-specific context data 1045 * 1046 * @param[in] reg 1047 * The register number to read. 1048 * 1049 * @param[out] val 1050 * Pointer to populate with the value read. 1051 */ 1052 static int 1053 jedec_dimm_readw_be(struct jedec_dimm_softc *sc, uint8_t reg, uint16_t *val) 1054 { 1055 int rc; 1056 1057 rc = smbus_readw(sc->smbus, sc->tsod_addr, reg, val); 1058 if (rc != 0) { 1059 goto out; 1060 } 1061 *val = be16toh(*val); 1062 1063 out: 1064 return (rc); 1065 } 1066 1067 /** 1068 * Reset to the default condition of operating on page0. This must be called 1069 * after a previous operation changed to page1. 1070 * 1071 * @author rpokala 1072 * 1073 * @param[in] sc 1074 * Instance-specific context data 1075 */ 1076 static int 1077 jedec_dimm_reset_page0(struct jedec_dimm_softc *sc) 1078 { 1079 int rc; 1080 1081 /* For the page-change operation, only the DTI and LSA matter; the 1082 * offset and write-value are ignored, so just use 0. 1083 */ 1084 rc = smbus_writeb(sc->smbus, (JEDEC_DTI_PAGE | JEDEC_LSA_PAGE_SET0), 1085 0, 0); 1086 if (rc != 0) { 1087 device_printf(sc->dev, "unable to restore page: %d\n", rc); 1088 } 1089 1090 return (rc); 1091 } 1092 1093 /** 1094 * Read the temperature data from the TSOD and convert it to the deciKelvin 1095 * value that the sysctl expects. 1096 * 1097 * @author avg 1098 */ 1099 static int 1100 jedec_dimm_temp_sysctl(SYSCTL_HANDLER_ARGS) 1101 { 1102 uint16_t val; 1103 int rc; 1104 int temp; 1105 device_t dev = arg1; 1106 struct jedec_dimm_softc *sc; 1107 1108 sc = device_get_softc(dev); 1109 1110 rc = jedec_dimm_readw_be(sc, TSOD_REG_TEMPERATURE, &val); 1111 if (rc != 0) { 1112 goto out; 1113 } 1114 1115 /* The three MSBits are flags, and the next bit is a sign bit. */ 1116 temp = val & 0xfff; 1117 if ((val & 0x1000) != 0) 1118 temp = -temp; 1119 /* Each step is 0.0625 degrees, so convert to 1000ths of a degree C. */ 1120 temp *= 625; 1121 /* ... and then convert to 1000ths of a Kelvin */ 1122 temp += 2731500; 1123 /* As a practical matter, few (if any) TSODs are more accurate than 1124 * about a tenth of a degree, so round accordingly. This correlates with 1125 * the "IK" formatting used for this sysctl. 1126 */ 1127 temp = (temp + 500) / 1000; 1128 1129 rc = sysctl_handle_int(oidp, &temp, 0, req); 1130 1131 out: 1132 return (rc); 1133 } 1134 1135 /** 1136 * Check the TSOD's Vendor ID and Device ID against the list of known TSOD 1137 * devices. Return the description, or NULL if this doesn't look like a valid 1138 * TSOD. 1139 * 1140 * @author avg 1141 * 1142 * @param[in] vid 1143 * The Vendor ID of the TSOD device 1144 * 1145 * @param[in] did 1146 * The Device ID of the TSOD device 1147 * 1148 * @return 1149 * The description string, or NULL for a failure to match. 1150 */ 1151 static const char * 1152 jedec_dimm_tsod_match(uint16_t vid, uint16_t did) 1153 { 1154 const struct jedec_dimm_tsod_dev *d; 1155 int i; 1156 1157 for (i = 0; i < nitems(known_tsod_devices); i++) { 1158 d = &known_tsod_devices[i]; 1159 if ((vid == d->vendor_id) && ((did >> 8) == d->device_id)) { 1160 return (d->description); 1161 } 1162 } 1163 1164 /* If no matches for a specific device, then check for a generic 1165 * TSE2004av-compliant device. 1166 */ 1167 if ((did >> 8) == 0x22) { 1168 return ("TSE2004av compliant TSOD"); 1169 } 1170 1171 return (NULL); 1172 } 1173 1174 static device_method_t jedec_dimm_methods[] = { 1175 /* Methods from the device interface */ 1176 DEVMETHOD(device_probe, jedec_dimm_probe), 1177 DEVMETHOD(device_attach, jedec_dimm_attach), 1178 DEVMETHOD(device_detach, jedec_dimm_detach), 1179 DEVMETHOD_END 1180 }; 1181 1182 static driver_t jedec_dimm_driver = { 1183 .name = "jedec_dimm", 1184 .methods = jedec_dimm_methods, 1185 .size = sizeof(struct jedec_dimm_softc), 1186 }; 1187 1188 DRIVER_MODULE(jedec_dimm, smbus, jedec_dimm_driver, 0, 0); 1189 MODULE_DEPEND(jedec_dimm, smbus, SMBUS_MINVER, SMBUS_PREFVER, SMBUS_MAXVER); 1190 MODULE_VERSION(jedec_dimm, 1); 1191 1192 /* vi: set ts=8 sw=4 sts=8 noet: */ 1193