1 1.38 nakayama /* $NetBSD: spdmem.c,v 1.38 2022/02/02 22:43:14 nakayama Exp $ */ 2 1.1 pgoyette 3 1.1 pgoyette /* 4 1.1 pgoyette * Copyright (c) 2007 Nicolas Joly 5 1.1 pgoyette * Copyright (c) 2007 Paul Goyette 6 1.1 pgoyette * Copyright (c) 2007 Tobias Nygren 7 1.1 pgoyette * All rights reserved. 8 1.1 pgoyette * 9 1.1 pgoyette * Redistribution and use in source and binary forms, with or without 10 1.1 pgoyette * modification, are permitted provided that the following conditions 11 1.1 pgoyette * are met: 12 1.1 pgoyette * 1. Redistributions of source code must retain the above copyright 13 1.1 pgoyette * notice, this list of conditions and the following disclaimer. 14 1.1 pgoyette * 2. Redistributions in binary form must reproduce the above copyright 15 1.1 pgoyette * notice, this list of conditions and the following disclaimer in the 16 1.1 pgoyette * documentation and/or other materials provided with the distribution. 17 1.1 pgoyette * 3. The name of the author may not be used to endorse or promote products 18 1.1 pgoyette * derived from this software without specific prior written permission. 19 1.1 pgoyette * 20 1.1 pgoyette * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS 21 1.1 pgoyette * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 22 1.1 pgoyette * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 23 1.1 pgoyette * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 24 1.1 pgoyette * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 25 1.1 pgoyette * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 26 1.1 pgoyette * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 27 1.1 pgoyette * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 28 1.1 pgoyette * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 29 1.1 pgoyette * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 30 1.1 pgoyette * POSSIBILITY OF SUCH DAMAGE. 31 1.1 pgoyette */ 32 1.1 pgoyette 33 1.1 pgoyette /* 34 1.1 pgoyette * Serial Presence Detect (SPD) memory identification 35 1.1 pgoyette */ 36 1.1 pgoyette 37 1.1 pgoyette #include <sys/cdefs.h> 38 1.38 nakayama __KERNEL_RCSID(0, "$NetBSD: spdmem.c,v 1.38 2022/02/02 22:43:14 nakayama Exp $"); 39 1.1 pgoyette 40 1.1 pgoyette #include <sys/param.h> 41 1.1 pgoyette #include <sys/device.h> 42 1.1 pgoyette #include <sys/endian.h> 43 1.1 pgoyette #include <sys/sysctl.h> 44 1.1 pgoyette #include <machine/bswap.h> 45 1.1 pgoyette 46 1.1 pgoyette #include <dev/i2c/i2cvar.h> 47 1.1 pgoyette #include <dev/ic/spdmemreg.h> 48 1.1 pgoyette #include <dev/ic/spdmemvar.h> 49 1.1 pgoyette 50 1.1 pgoyette /* Routines for decoding spd data */ 51 1.1 pgoyette static void decode_edofpm(const struct sysctlnode *, device_t, struct spdmem *); 52 1.1 pgoyette static void decode_rom(const struct sysctlnode *, device_t, struct spdmem *); 53 1.1 pgoyette static void decode_sdram(const struct sysctlnode *, device_t, struct spdmem *, 54 1.1 pgoyette int); 55 1.1 pgoyette static void decode_ddr(const struct sysctlnode *, device_t, struct spdmem *); 56 1.1 pgoyette static void decode_ddr2(const struct sysctlnode *, device_t, struct spdmem *); 57 1.1 pgoyette static void decode_ddr3(const struct sysctlnode *, device_t, struct spdmem *); 58 1.13 pgoyette static void decode_ddr4(const struct sysctlnode *, device_t, struct spdmem *); 59 1.1 pgoyette static void decode_fbdimm(const struct sysctlnode *, device_t, struct spdmem *); 60 1.1 pgoyette 61 1.3 pgoyette static void decode_size_speed(device_t, const struct sysctlnode *, 62 1.3 pgoyette int, int, int, int, bool, const char *, int); 63 1.1 pgoyette static void decode_voltage_refresh(device_t, struct spdmem *); 64 1.1 pgoyette 65 1.1 pgoyette #define IS_RAMBUS_TYPE (s->sm_len < 4) 66 1.1 pgoyette 67 1.12 matt static const char* const spdmem_basic_types[] = { 68 1.1 pgoyette "unknown", 69 1.1 pgoyette "FPM", 70 1.1 pgoyette "EDO", 71 1.1 pgoyette "Pipelined Nibble", 72 1.1 pgoyette "SDRAM", 73 1.1 pgoyette "ROM", 74 1.1 pgoyette "DDR SGRAM", 75 1.1 pgoyette "DDR SDRAM", 76 1.1 pgoyette "DDR2 SDRAM", 77 1.1 pgoyette "DDR2 SDRAM FB", 78 1.1 pgoyette "DDR2 SDRAM FB Probe", 79 1.12 matt "DDR3 SDRAM", 80 1.20 msaitoh "DDR4 SDRAM", 81 1.20 msaitoh "unknown", 82 1.20 msaitoh "DDR4E SDRAM", 83 1.20 msaitoh "LPDDR3 SDRAM", 84 1.38 nakayama "LPDDR4 SDRAM", 85 1.36 msaitoh "LPDDR4X SDRAM", 86 1.38 nakayama "DDR5 SDRAM" 87 1.1 pgoyette }; 88 1.1 pgoyette 89 1.13 pgoyette static const char* const spdmem_ddr4_module_types[] = { 90 1.13 pgoyette "DDR4 Extended", 91 1.13 pgoyette "DDR4 RDIMM", 92 1.13 pgoyette "DDR4 UDIMM", 93 1.13 pgoyette "DDR4 SO-DIMM", 94 1.13 pgoyette "DDR4 Load-Reduced DIMM", 95 1.13 pgoyette "DDR4 Mini-RDIMM", 96 1.13 pgoyette "DDR4 Mini-UDIMM", 97 1.13 pgoyette "DDR4 Reserved", 98 1.13 pgoyette "DDR4 72Bit SO-RDIMM", 99 1.13 pgoyette "DDR4 72Bit SO-UDIMM", 100 1.13 pgoyette "DDR4 Undefined", 101 1.13 pgoyette "DDR4 Reserved", 102 1.13 pgoyette "DDR4 16Bit SO-DIMM", 103 1.13 pgoyette "DDR4 32Bit SO-DIMM", 104 1.13 pgoyette "DDR4 Reserved", 105 1.13 pgoyette "DDR4 Undefined" 106 1.13 pgoyette }; 107 1.13 pgoyette 108 1.12 matt static const char* const spdmem_superset_types[] = { 109 1.1 pgoyette "unknown", 110 1.1 pgoyette "ESDRAM", 111 1.1 pgoyette "DDR ESDRAM", 112 1.1 pgoyette "PEM EDO", 113 1.1 pgoyette "PEM SDRAM" 114 1.1 pgoyette }; 115 1.1 pgoyette 116 1.12 matt static const char* const spdmem_voltage_types[] = { 117 1.1 pgoyette "TTL (5V tolerant)", 118 1.1 pgoyette "LvTTL (not 5V tolerant)", 119 1.1 pgoyette "HSTL 1.5V", 120 1.1 pgoyette "SSTL 3.3V", 121 1.1 pgoyette "SSTL 2.5V", 122 1.1 pgoyette "SSTL 1.8V" 123 1.1 pgoyette }; 124 1.1 pgoyette 125 1.12 matt static const char* const spdmem_refresh_types[] = { 126 1.1 pgoyette "15.625us", 127 1.1 pgoyette "3.9us", 128 1.1 pgoyette "7.8us", 129 1.1 pgoyette "31.3us", 130 1.1 pgoyette "62.5us", 131 1.1 pgoyette "125us" 132 1.1 pgoyette }; 133 1.1 pgoyette 134 1.12 matt static const char* const spdmem_parity_types[] = { 135 1.1 pgoyette "no parity or ECC", 136 1.1 pgoyette "data parity", 137 1.1 pgoyette "data ECC", 138 1.1 pgoyette "data parity and ECC", 139 1.1 pgoyette "cmd/addr parity", 140 1.1 pgoyette "cmd/addr/data parity", 141 1.1 pgoyette "cmd/addr parity, data ECC", 142 1.1 pgoyette "cmd/addr/data parity, data ECC" 143 1.1 pgoyette }; 144 1.1 pgoyette 145 1.13 pgoyette int spd_rom_sizes[] = { 0, 128, 256, 384, 512 }; 146 1.13 pgoyette 147 1.13 pgoyette 148 1.1 pgoyette /* Cycle time fractional values (units of .001 ns) for DDR2 SDRAM */ 149 1.1 pgoyette static const uint16_t spdmem_cycle_frac[] = { 150 1.1 pgoyette 0, 100, 200, 300, 400, 500, 600, 700, 800, 900, 151 1.1 pgoyette 250, 333, 667, 750, 999, 999 152 1.1 pgoyette }; 153 1.1 pgoyette 154 1.1 pgoyette /* Format string for timing info */ 155 1.5 wiz #define LATENCY "tAA-tRCD-tRP-tRAS: %d-%d-%d-%d\n" 156 1.1 pgoyette 157 1.1 pgoyette /* CRC functions used for certain memory types */ 158 1.1 pgoyette 159 1.21 msaitoh static uint16_t 160 1.21 msaitoh spdcrc16(struct spdmem_softc *sc, int count) 161 1.1 pgoyette { 162 1.1 pgoyette uint16_t crc; 163 1.1 pgoyette int i, j; 164 1.1 pgoyette uint8_t val; 165 1.1 pgoyette crc = 0; 166 1.1 pgoyette for (j = 0; j <= count; j++) { 167 1.21 msaitoh (sc->sc_read)(sc, j, &val); 168 1.1 pgoyette crc = crc ^ val << 8; 169 1.1 pgoyette for (i = 0; i < 8; ++i) 170 1.1 pgoyette if (crc & 0x8000) 171 1.1 pgoyette crc = crc << 1 ^ 0x1021; 172 1.1 pgoyette else 173 1.1 pgoyette crc = crc << 1; 174 1.1 pgoyette } 175 1.1 pgoyette return (crc & 0xFFFF); 176 1.1 pgoyette } 177 1.1 pgoyette 178 1.1 pgoyette int 179 1.1 pgoyette spdmem_common_probe(struct spdmem_softc *sc) 180 1.1 pgoyette { 181 1.1 pgoyette int cksum = 0; 182 1.1 pgoyette uint8_t i, val, spd_type; 183 1.1 pgoyette int spd_len, spd_crc_cover; 184 1.1 pgoyette uint16_t crc_calc, crc_spd; 185 1.1 pgoyette 186 1.21 msaitoh /* Read failed means a device doesn't exist */ 187 1.21 msaitoh if ((sc->sc_read)(sc, 2, &spd_type) != 0) 188 1.21 msaitoh return 0; 189 1.1 pgoyette 190 1.22 msaitoh /* Memory type should not be 0 */ 191 1.22 msaitoh if (spd_type == 0x00) 192 1.22 msaitoh return 0; 193 1.22 msaitoh 194 1.1 pgoyette /* For older memory types, validate the checksum over 1st 63 bytes */ 195 1.1 pgoyette if (spd_type <= SPDMEM_MEMTYPE_DDR2SDRAM) { 196 1.21 msaitoh for (i = 0; i < 63; i++) { 197 1.21 msaitoh (sc->sc_read)(sc, i, &val); 198 1.21 msaitoh cksum += val; 199 1.21 msaitoh } 200 1.1 pgoyette 201 1.21 msaitoh (sc->sc_read)(sc, 63, &val); 202 1.1 pgoyette 203 1.21 msaitoh if ((cksum & 0xff) != val) { 204 1.1 pgoyette aprint_debug("spd checksum failed, calc = 0x%02x, " 205 1.1 pgoyette "spd = 0x%02x\n", cksum, val); 206 1.1 pgoyette return 0; 207 1.1 pgoyette } else 208 1.1 pgoyette return 1; 209 1.1 pgoyette } 210 1.1 pgoyette 211 1.1 pgoyette /* For DDR3 and FBDIMM, verify the CRC */ 212 1.1 pgoyette else if (spd_type <= SPDMEM_MEMTYPE_DDR3SDRAM) { 213 1.21 msaitoh (sc->sc_read)(sc, 0, &val); 214 1.21 msaitoh spd_len = val; 215 1.2 pgoyette if (spd_len & SPDMEM_SPDCRC_116) 216 1.1 pgoyette spd_crc_cover = 116; 217 1.1 pgoyette else 218 1.1 pgoyette spd_crc_cover = 125; 219 1.1 pgoyette switch (spd_len & SPDMEM_SPDLEN_MASK) { 220 1.1 pgoyette case SPDMEM_SPDLEN_128: 221 1.1 pgoyette spd_len = 128; 222 1.1 pgoyette break; 223 1.1 pgoyette case SPDMEM_SPDLEN_176: 224 1.1 pgoyette spd_len = 176; 225 1.1 pgoyette break; 226 1.1 pgoyette case SPDMEM_SPDLEN_256: 227 1.1 pgoyette spd_len = 256; 228 1.1 pgoyette break; 229 1.1 pgoyette default: 230 1.1 pgoyette return 0; 231 1.1 pgoyette } 232 1.1 pgoyette if (spd_crc_cover > spd_len) 233 1.1 pgoyette return 0; 234 1.1 pgoyette crc_calc = spdcrc16(sc, spd_crc_cover); 235 1.21 msaitoh (sc->sc_read)(sc, 127, &val); 236 1.21 msaitoh crc_spd = val << 8; 237 1.21 msaitoh (sc->sc_read)(sc, 126, &val); 238 1.21 msaitoh crc_spd |= val; 239 1.1 pgoyette if (crc_calc != crc_spd) { 240 1.1 pgoyette aprint_debug("crc16 failed, covers %d bytes, " 241 1.1 pgoyette "calc = 0x%04x, spd = 0x%04x\n", 242 1.1 pgoyette spd_crc_cover, crc_calc, crc_spd); 243 1.1 pgoyette return 0; 244 1.1 pgoyette } 245 1.1 pgoyette return 1; 246 1.13 pgoyette } else if (spd_type == SPDMEM_MEMTYPE_DDR4SDRAM) { 247 1.21 msaitoh (sc->sc_read)(sc, 0, &val); 248 1.21 msaitoh spd_len = val & 0x0f; 249 1.23 maya if ((unsigned int)spd_len >= __arraycount(spd_rom_sizes)) 250 1.13 pgoyette return 0; 251 1.13 pgoyette spd_len = spd_rom_sizes[spd_len]; 252 1.17 msaitoh spd_crc_cover = 125; /* For byte 0 to 125 */ 253 1.13 pgoyette if (spd_crc_cover > spd_len) 254 1.13 pgoyette return 0; 255 1.13 pgoyette crc_calc = spdcrc16(sc, spd_crc_cover); 256 1.21 msaitoh (sc->sc_read)(sc, 127, &val); 257 1.21 msaitoh crc_spd = val << 8; 258 1.21 msaitoh (sc->sc_read)(sc, 126, &val); 259 1.21 msaitoh crc_spd |= val; 260 1.13 pgoyette if (crc_calc != crc_spd) { 261 1.13 pgoyette aprint_debug("crc16 failed, covers %d bytes, " 262 1.13 pgoyette "calc = 0x%04x, spd = 0x%04x\n", 263 1.13 pgoyette spd_crc_cover, crc_calc, crc_spd); 264 1.13 pgoyette return 0; 265 1.13 pgoyette } 266 1.13 pgoyette /* 267 1.13 pgoyette * We probably could also verify the CRC for the other 268 1.13 pgoyette * "pages" of SPD data in blocks 1 and 2, but we'll do 269 1.13 pgoyette * it some other time. 270 1.13 pgoyette */ 271 1.13 pgoyette return 1; 272 1.37 msaitoh } else if (spd_type == SPDMEM_MEMTYPE_DDR5SDRAM) { 273 1.37 msaitoh /* XXX Need Datasheet. */ 274 1.37 msaitoh (sc->sc_read)(sc, 0, &val); 275 1.37 msaitoh spd_len = val & 0x0f; 276 1.37 msaitoh if ((unsigned int)spd_len >= __arraycount(spd_rom_sizes)) 277 1.37 msaitoh return 0; 278 1.37 msaitoh aprint_verbose("DDR5 SPD ROM?\n"); 279 1.37 msaitoh return 0; 280 1.22 msaitoh } 281 1.1 pgoyette 282 1.1 pgoyette /* For unrecognized memory types, don't match at all */ 283 1.1 pgoyette return 0; 284 1.1 pgoyette } 285 1.1 pgoyette 286 1.1 pgoyette void 287 1.1 pgoyette spdmem_common_attach(struct spdmem_softc *sc, device_t self) 288 1.1 pgoyette { 289 1.1 pgoyette struct spdmem *s = &(sc->sc_spd_data); 290 1.1 pgoyette const char *type; 291 1.1 pgoyette const char *rambus_rev = "Reserved"; 292 1.1 pgoyette int dimm_size; 293 1.3 pgoyette unsigned int i, spd_len, spd_size; 294 1.1 pgoyette const struct sysctlnode *node = NULL; 295 1.1 pgoyette 296 1.21 msaitoh (sc->sc_read)(sc, 0, &s->sm_len); 297 1.21 msaitoh (sc->sc_read)(sc, 1, &s->sm_size); 298 1.21 msaitoh (sc->sc_read)(sc, 2, &s->sm_type); 299 1.1 pgoyette 300 1.13 pgoyette if (s->sm_type == SPDMEM_MEMTYPE_DDR4SDRAM) { 301 1.13 pgoyette /* 302 1.13 pgoyette * An even newer encoding with one byte holding both 303 1.13 pgoyette * the used-size and capacity values 304 1.13 pgoyette */ 305 1.13 pgoyette spd_len = s->sm_len & 0x0f; 306 1.13 pgoyette spd_size = (s->sm_len >> 4) & 0x07; 307 1.13 pgoyette 308 1.13 pgoyette spd_len = spd_rom_sizes[spd_len]; 309 1.13 pgoyette spd_size *= 512; 310 1.13 pgoyette 311 1.13 pgoyette } else if (s->sm_type >= SPDMEM_MEMTYPE_FBDIMM) { 312 1.13 pgoyette /* 313 1.13 pgoyette * FBDIMM and DDR3 (and probably all newer) have a different 314 1.13 pgoyette * encoding of the SPD EEPROM used/total sizes 315 1.13 pgoyette */ 316 1.1 pgoyette spd_size = 64 << (s->sm_len & SPDMEM_SPDSIZE_MASK); 317 1.1 pgoyette switch (s->sm_len & SPDMEM_SPDLEN_MASK) { 318 1.1 pgoyette case SPDMEM_SPDLEN_128: 319 1.1 pgoyette spd_len = 128; 320 1.1 pgoyette break; 321 1.1 pgoyette case SPDMEM_SPDLEN_176: 322 1.1 pgoyette spd_len = 176; 323 1.1 pgoyette break; 324 1.1 pgoyette case SPDMEM_SPDLEN_256: 325 1.1 pgoyette spd_len = 256; 326 1.1 pgoyette break; 327 1.1 pgoyette default: 328 1.1 pgoyette spd_len = 64; 329 1.1 pgoyette break; 330 1.1 pgoyette } 331 1.1 pgoyette } else { 332 1.1 pgoyette spd_size = 1 << s->sm_size; 333 1.1 pgoyette spd_len = s->sm_len; 334 1.1 pgoyette if (spd_len < 64) 335 1.1 pgoyette spd_len = 64; 336 1.1 pgoyette } 337 1.1 pgoyette if (spd_len > spd_size) 338 1.1 pgoyette spd_len = spd_size; 339 1.1 pgoyette if (spd_len > sizeof(struct spdmem)) 340 1.1 pgoyette spd_len = sizeof(struct spdmem); 341 1.1 pgoyette for (i = 3; i < spd_len; i++) 342 1.21 msaitoh (sc->sc_read)(sc, i, &((uint8_t *)s)[i]); 343 1.1 pgoyette 344 1.1 pgoyette /* 345 1.1 pgoyette * Setup our sysctl subtree, hw.spdmemN 346 1.1 pgoyette */ 347 1.3 pgoyette sc->sc_sysctl_log = NULL; 348 1.9 pooka sysctl_createv(&sc->sc_sysctl_log, 0, NULL, &node, 349 1.9 pooka 0, CTLTYPE_NODE, 350 1.9 pooka device_xname(self), NULL, NULL, 0, NULL, 0, 351 1.9 pooka CTL_HW, CTL_CREATE, CTL_EOL); 352 1.1 pgoyette if (node != NULL && spd_len != 0) 353 1.33 msaitoh sysctl_createv(&sc->sc_sysctl_log, 0, NULL, NULL, 354 1.33 msaitoh 0, 355 1.33 msaitoh CTLTYPE_STRUCT, "spd_data", 356 1.1 pgoyette SYSCTL_DESCR("raw spd data"), NULL, 357 1.33 msaitoh 0, s, spd_len, 358 1.33 msaitoh CTL_HW, node->sysctl_num, CTL_CREATE, CTL_EOL); 359 1.1 pgoyette 360 1.1 pgoyette /* 361 1.1 pgoyette * Decode and print key SPD contents 362 1.1 pgoyette */ 363 1.1 pgoyette if (IS_RAMBUS_TYPE) { 364 1.1 pgoyette if (s->sm_type == SPDMEM_MEMTYPE_RAMBUS) 365 1.1 pgoyette type = "Rambus"; 366 1.1 pgoyette else if (s->sm_type == SPDMEM_MEMTYPE_DIRECTRAMBUS) 367 1.1 pgoyette type = "Direct Rambus"; 368 1.1 pgoyette else 369 1.1 pgoyette type = "Rambus (unknown)"; 370 1.1 pgoyette 371 1.1 pgoyette switch (s->sm_len) { 372 1.1 pgoyette case 0: 373 1.1 pgoyette rambus_rev = "Invalid"; 374 1.1 pgoyette break; 375 1.1 pgoyette case 1: 376 1.1 pgoyette rambus_rev = "0.7"; 377 1.1 pgoyette break; 378 1.1 pgoyette case 2: 379 1.1 pgoyette rambus_rev = "1.0"; 380 1.1 pgoyette break; 381 1.1 pgoyette default: 382 1.1 pgoyette rambus_rev = "Reserved"; 383 1.1 pgoyette break; 384 1.1 pgoyette } 385 1.1 pgoyette } else { 386 1.1 pgoyette if (s->sm_type < __arraycount(spdmem_basic_types)) 387 1.1 pgoyette type = spdmem_basic_types[s->sm_type]; 388 1.1 pgoyette else 389 1.1 pgoyette type = "unknown memory type"; 390 1.1 pgoyette 391 1.1 pgoyette if (s->sm_type == SPDMEM_MEMTYPE_EDO && 392 1.1 pgoyette s->sm_fpm.fpm_superset == SPDMEM_SUPERSET_EDO_PEM) 393 1.1 pgoyette type = spdmem_superset_types[SPDMEM_SUPERSET_EDO_PEM]; 394 1.1 pgoyette if (s->sm_type == SPDMEM_MEMTYPE_SDRAM && 395 1.1 pgoyette s->sm_sdr.sdr_superset == SPDMEM_SUPERSET_SDRAM_PEM) 396 1.1 pgoyette type = spdmem_superset_types[SPDMEM_SUPERSET_SDRAM_PEM]; 397 1.1 pgoyette if (s->sm_type == SPDMEM_MEMTYPE_DDRSDRAM && 398 1.1 pgoyette s->sm_ddr.ddr_superset == SPDMEM_SUPERSET_DDR_ESDRAM) 399 1.1 pgoyette type = 400 1.1 pgoyette spdmem_superset_types[SPDMEM_SUPERSET_DDR_ESDRAM]; 401 1.1 pgoyette if (s->sm_type == SPDMEM_MEMTYPE_SDRAM && 402 1.1 pgoyette s->sm_sdr.sdr_superset == SPDMEM_SUPERSET_ESDRAM) { 403 1.1 pgoyette type = spdmem_superset_types[SPDMEM_SUPERSET_ESDRAM]; 404 1.1 pgoyette } 405 1.13 pgoyette if (s->sm_type == SPDMEM_MEMTYPE_DDR4SDRAM && 406 1.13 pgoyette s->sm_ddr4.ddr4_mod_type < 407 1.13 pgoyette __arraycount(spdmem_ddr4_module_types)) { 408 1.13 pgoyette type = spdmem_ddr4_module_types[s->sm_ddr4.ddr4_mod_type]; 409 1.13 pgoyette } 410 1.1 pgoyette } 411 1.1 pgoyette 412 1.1 pgoyette strlcpy(sc->sc_type, type, SPDMEM_TYPE_MAXLEN); 413 1.20 msaitoh 414 1.20 msaitoh if (s->sm_type == SPDMEM_MEMTYPE_DDR4SDRAM) { 415 1.20 msaitoh /* 416 1.20 msaitoh * The latest spec (DDR4 SPD Document Release 3) defines 417 1.20 msaitoh * NVDIMM Hybrid only. 418 1.20 msaitoh */ 419 1.20 msaitoh if ((s->sm_ddr4.ddr4_hybrid) 420 1.20 msaitoh && (s->sm_ddr4.ddr4_hybrid_media == 1)) 421 1.20 msaitoh strlcat(sc->sc_type, " NVDIMM hybrid", 422 1.20 msaitoh SPDMEM_TYPE_MAXLEN); 423 1.20 msaitoh } 424 1.33 msaitoh 425 1.1 pgoyette if (node != NULL) 426 1.3 pgoyette sysctl_createv(&sc->sc_sysctl_log, 0, NULL, NULL, 427 1.1 pgoyette 0, 428 1.1 pgoyette CTLTYPE_STRING, "mem_type", 429 1.1 pgoyette SYSCTL_DESCR("memory module type"), NULL, 430 1.1 pgoyette 0, sc->sc_type, 0, 431 1.1 pgoyette CTL_HW, node->sysctl_num, CTL_CREATE, CTL_EOL); 432 1.1 pgoyette 433 1.1 pgoyette if (IS_RAMBUS_TYPE) { 434 1.8 soren aprint_naive("\n"); 435 1.8 soren aprint_normal("\n"); 436 1.8 soren aprint_normal_dev(self, "%s, SPD Revision %s", type, rambus_rev); 437 1.1 pgoyette dimm_size = 1 << (s->sm_rdr.rdr_rows + s->sm_rdr.rdr_cols - 13); 438 1.1 pgoyette if (dimm_size >= 1024) 439 1.1 pgoyette aprint_normal(", %dGB\n", dimm_size / 1024); 440 1.1 pgoyette else 441 1.1 pgoyette aprint_normal(", %dMB\n", dimm_size); 442 1.1 pgoyette 443 1.1 pgoyette /* No further decode for RAMBUS memory */ 444 1.1 pgoyette return; 445 1.1 pgoyette } 446 1.1 pgoyette switch (s->sm_type) { 447 1.1 pgoyette case SPDMEM_MEMTYPE_EDO: 448 1.1 pgoyette case SPDMEM_MEMTYPE_FPM: 449 1.1 pgoyette decode_edofpm(node, self, s); 450 1.1 pgoyette break; 451 1.1 pgoyette case SPDMEM_MEMTYPE_ROM: 452 1.1 pgoyette decode_rom(node, self, s); 453 1.1 pgoyette break; 454 1.1 pgoyette case SPDMEM_MEMTYPE_SDRAM: 455 1.1 pgoyette decode_sdram(node, self, s, spd_len); 456 1.1 pgoyette break; 457 1.1 pgoyette case SPDMEM_MEMTYPE_DDRSDRAM: 458 1.1 pgoyette decode_ddr(node, self, s); 459 1.1 pgoyette break; 460 1.1 pgoyette case SPDMEM_MEMTYPE_DDR2SDRAM: 461 1.1 pgoyette decode_ddr2(node, self, s); 462 1.1 pgoyette break; 463 1.1 pgoyette case SPDMEM_MEMTYPE_DDR3SDRAM: 464 1.1 pgoyette decode_ddr3(node, self, s); 465 1.1 pgoyette break; 466 1.1 pgoyette case SPDMEM_MEMTYPE_FBDIMM: 467 1.1 pgoyette case SPDMEM_MEMTYPE_FBDIMM_PROBE: 468 1.1 pgoyette decode_fbdimm(node, self, s); 469 1.1 pgoyette break; 470 1.13 pgoyette case SPDMEM_MEMTYPE_DDR4SDRAM: 471 1.13 pgoyette decode_ddr4(node, self, s); 472 1.13 pgoyette break; 473 1.1 pgoyette } 474 1.8 soren 475 1.8 soren /* Dump SPD */ 476 1.8 soren for (i = 0; i < spd_len; i += 16) { 477 1.8 soren unsigned int j, k; 478 1.8 soren aprint_debug_dev(self, "0x%02x:", i); 479 1.8 soren k = (spd_len > (i + 16)) ? i + 16 : spd_len; 480 1.8 soren for (j = i; j < k; j++) 481 1.8 soren aprint_debug(" %02x", ((uint8_t *)s)[j]); 482 1.8 soren aprint_debug("\n"); 483 1.8 soren } 484 1.1 pgoyette } 485 1.1 pgoyette 486 1.3 pgoyette int 487 1.3 pgoyette spdmem_common_detach(struct spdmem_softc *sc, device_t self) 488 1.3 pgoyette { 489 1.3 pgoyette sysctl_teardown(&sc->sc_sysctl_log); 490 1.3 pgoyette 491 1.3 pgoyette return 0; 492 1.3 pgoyette } 493 1.3 pgoyette 494 1.1 pgoyette static void 495 1.3 pgoyette decode_size_speed(device_t self, const struct sysctlnode *node, 496 1.3 pgoyette int dimm_size, int cycle_time, int d_clk, int bits, 497 1.3 pgoyette bool round, const char *ddr_type_string, int speed) 498 1.1 pgoyette { 499 1.1 pgoyette int p_clk; 500 1.7 chs struct spdmem_softc *sc = device_private(self); 501 1.1 pgoyette 502 1.1 pgoyette if (dimm_size < 1024) 503 1.1 pgoyette aprint_normal("%dMB", dimm_size); 504 1.1 pgoyette else 505 1.1 pgoyette aprint_normal("%dGB", dimm_size / 1024); 506 1.1 pgoyette if (node != NULL) 507 1.3 pgoyette sysctl_createv(&sc->sc_sysctl_log, 0, NULL, NULL, 508 1.1 pgoyette CTLFLAG_IMMEDIATE, 509 1.1 pgoyette CTLTYPE_INT, "size", 510 1.1 pgoyette SYSCTL_DESCR("module size in MB"), NULL, 511 1.1 pgoyette dimm_size, NULL, 0, 512 1.1 pgoyette CTL_HW, node->sysctl_num, CTL_CREATE, CTL_EOL); 513 1.1 pgoyette 514 1.1 pgoyette if (cycle_time == 0) { 515 1.1 pgoyette aprint_normal("\n"); 516 1.1 pgoyette return; 517 1.1 pgoyette } 518 1.1 pgoyette 519 1.1 pgoyette /* 520 1.1 pgoyette * Calculate p_clk first, since for DDR3 we need maximum significance. 521 1.1 pgoyette * DDR3 rating is not rounded to a multiple of 100. This results in 522 1.1 pgoyette * cycle_time of 1.5ns displayed as PC3-10666. 523 1.1 pgoyette * 524 1.1 pgoyette * For SDRAM, the speed is provided by the caller so we use it. 525 1.1 pgoyette */ 526 1.1 pgoyette d_clk *= 1000 * 1000; 527 1.1 pgoyette if (speed) 528 1.1 pgoyette p_clk = speed; 529 1.1 pgoyette else 530 1.1 pgoyette p_clk = (d_clk * bits) / 8 / cycle_time; 531 1.1 pgoyette d_clk = ((d_clk + cycle_time / 2) ) / cycle_time; 532 1.1 pgoyette if (round) { 533 1.1 pgoyette if ((p_clk % 100) >= 50) 534 1.1 pgoyette p_clk += 50; 535 1.1 pgoyette p_clk -= p_clk % 100; 536 1.1 pgoyette } 537 1.1 pgoyette aprint_normal(", %dMHz (%s-%d)\n", 538 1.1 pgoyette d_clk, ddr_type_string, p_clk); 539 1.1 pgoyette if (node != NULL) 540 1.3 pgoyette sysctl_createv(&sc->sc_sysctl_log, 0, NULL, NULL, 541 1.1 pgoyette CTLFLAG_IMMEDIATE, 542 1.1 pgoyette CTLTYPE_INT, "speed", 543 1.1 pgoyette SYSCTL_DESCR("memory speed in MHz"), 544 1.1 pgoyette NULL, d_clk, NULL, 0, 545 1.1 pgoyette CTL_HW, node->sysctl_num, CTL_CREATE, CTL_EOL); 546 1.1 pgoyette } 547 1.1 pgoyette 548 1.1 pgoyette static void 549 1.1 pgoyette decode_voltage_refresh(device_t self, struct spdmem *s) 550 1.1 pgoyette { 551 1.1 pgoyette const char *voltage, *refresh; 552 1.1 pgoyette 553 1.1 pgoyette if (s->sm_voltage < __arraycount(spdmem_voltage_types)) 554 1.1 pgoyette voltage = spdmem_voltage_types[s->sm_voltage]; 555 1.1 pgoyette else 556 1.1 pgoyette voltage = "unknown"; 557 1.1 pgoyette 558 1.1 pgoyette if (s->sm_refresh < __arraycount(spdmem_refresh_types)) 559 1.1 pgoyette refresh = spdmem_refresh_types[s->sm_refresh]; 560 1.1 pgoyette else 561 1.1 pgoyette refresh = "unknown"; 562 1.1 pgoyette 563 1.1 pgoyette aprint_verbose_dev(self, "voltage %s, refresh time %s%s\n", 564 1.1 pgoyette voltage, refresh, 565 1.1 pgoyette s->sm_selfrefresh?" (self-refreshing)":""); 566 1.1 pgoyette } 567 1.1 pgoyette 568 1.1 pgoyette static void 569 1.18 msaitoh decode_edofpm(const struct sysctlnode *node, device_t self, struct spdmem *s) 570 1.18 msaitoh { 571 1.18 msaitoh 572 1.8 soren aprint_naive("\n"); 573 1.8 soren aprint_normal("\n"); 574 1.8 soren aprint_normal_dev(self, "%s", spdmem_basic_types[s->sm_type]); 575 1.8 soren 576 1.1 pgoyette aprint_normal("\n"); 577 1.1 pgoyette aprint_verbose_dev(self, 578 1.1 pgoyette "%d rows, %d cols, %d banks, %dns tRAC, %dns tCAC\n", 579 1.1 pgoyette s->sm_fpm.fpm_rows, s->sm_fpm.fpm_cols, s->sm_fpm.fpm_banks, 580 1.1 pgoyette s->sm_fpm.fpm_tRAC, s->sm_fpm.fpm_tCAC); 581 1.1 pgoyette } 582 1.1 pgoyette 583 1.1 pgoyette static void 584 1.18 msaitoh decode_rom(const struct sysctlnode *node, device_t self, struct spdmem *s) 585 1.18 msaitoh { 586 1.18 msaitoh 587 1.8 soren aprint_naive("\n"); 588 1.8 soren aprint_normal("\n"); 589 1.8 soren aprint_normal_dev(self, "%s", spdmem_basic_types[s->sm_type]); 590 1.8 soren 591 1.1 pgoyette aprint_normal("\n"); 592 1.1 pgoyette aprint_verbose_dev(self, "%d rows, %d cols, %d banks\n", 593 1.1 pgoyette s->sm_rom.rom_rows, s->sm_rom.rom_cols, s->sm_rom.rom_banks); 594 1.1 pgoyette } 595 1.1 pgoyette 596 1.1 pgoyette static void 597 1.1 pgoyette decode_sdram(const struct sysctlnode *node, device_t self, struct spdmem *s, 598 1.18 msaitoh int spd_len) 599 1.18 msaitoh { 600 1.1 pgoyette int dimm_size, cycle_time, bits, tAA, i, speed, freq; 601 1.1 pgoyette 602 1.8 soren aprint_naive("\n"); 603 1.8 soren aprint_normal("\n"); 604 1.8 soren aprint_normal_dev(self, "%s", spdmem_basic_types[s->sm_type]); 605 1.8 soren 606 1.1 pgoyette aprint_normal("%s, %s, ", 607 1.1 pgoyette (s->sm_sdr.sdr_mod_attrs & SPDMEM_SDR_MASK_REG)? 608 1.1 pgoyette " (registered)":"", 609 1.1 pgoyette (s->sm_config < __arraycount(spdmem_parity_types))? 610 1.1 pgoyette spdmem_parity_types[s->sm_config]:"invalid parity"); 611 1.1 pgoyette 612 1.1 pgoyette dimm_size = 1 << (s->sm_sdr.sdr_rows + s->sm_sdr.sdr_cols - 17); 613 1.1 pgoyette dimm_size *= s->sm_sdr.sdr_banks * s->sm_sdr.sdr_banks_per_chip; 614 1.1 pgoyette 615 1.1 pgoyette cycle_time = s->sm_sdr.sdr_cycle_whole * 1000 + 616 1.1 pgoyette s->sm_sdr.sdr_cycle_tenths * 100; 617 1.1 pgoyette bits = le16toh(s->sm_sdr.sdr_datawidth); 618 1.1 pgoyette if (s->sm_config == 1 || s->sm_config == 2) 619 1.1 pgoyette bits -= 8; 620 1.1 pgoyette 621 1.1 pgoyette /* Calculate speed here - from OpenBSD */ 622 1.1 pgoyette if (spd_len >= 128) 623 1.1 pgoyette freq = ((uint8_t *)s)[126]; 624 1.1 pgoyette else 625 1.1 pgoyette freq = 0; 626 1.1 pgoyette switch (freq) { 627 1.1 pgoyette /* 628 1.33 msaitoh * Must check cycle time since some PC-133 DIMMs 629 1.1 pgoyette * actually report PC-100 630 1.1 pgoyette */ 631 1.1 pgoyette case 100: 632 1.1 pgoyette case 133: 633 1.1 pgoyette if (cycle_time < 8000) 634 1.1 pgoyette speed = 133; 635 1.1 pgoyette else 636 1.1 pgoyette speed = 100; 637 1.1 pgoyette break; 638 1.1 pgoyette case 0x66: /* Legacy DIMMs use _hex_ 66! */ 639 1.1 pgoyette default: 640 1.1 pgoyette speed = 66; 641 1.1 pgoyette } 642 1.3 pgoyette decode_size_speed(self, node, dimm_size, cycle_time, 1, bits, FALSE, 643 1.3 pgoyette "PC", speed); 644 1.1 pgoyette 645 1.1 pgoyette aprint_verbose_dev(self, 646 1.1 pgoyette "%d rows, %d cols, %d banks, %d banks/chip, %d.%dns cycle time\n", 647 1.1 pgoyette s->sm_sdr.sdr_rows, s->sm_sdr.sdr_cols, s->sm_sdr.sdr_banks, 648 1.1 pgoyette s->sm_sdr.sdr_banks_per_chip, cycle_time/1000, 649 1.1 pgoyette (cycle_time % 1000) / 100); 650 1.1 pgoyette 651 1.1 pgoyette tAA = 0; 652 1.1 pgoyette for (i = 0; i < 8; i++) 653 1.1 pgoyette if (s->sm_sdr.sdr_tCAS & (1 << i)) 654 1.1 pgoyette tAA = i; 655 1.1 pgoyette tAA++; 656 1.4 christos aprint_verbose_dev(self, LATENCY, tAA, s->sm_sdr.sdr_tRCD, 657 1.1 pgoyette s->sm_sdr.sdr_tRP, s->sm_sdr.sdr_tRAS); 658 1.1 pgoyette 659 1.1 pgoyette decode_voltage_refresh(self, s); 660 1.1 pgoyette } 661 1.1 pgoyette 662 1.1 pgoyette static void 663 1.18 msaitoh decode_ddr(const struct sysctlnode *node, device_t self, struct spdmem *s) 664 1.18 msaitoh { 665 1.1 pgoyette int dimm_size, cycle_time, bits, tAA, i; 666 1.1 pgoyette 667 1.8 soren aprint_naive("\n"); 668 1.8 soren aprint_normal("\n"); 669 1.8 soren aprint_normal_dev(self, "%s", spdmem_basic_types[s->sm_type]); 670 1.8 soren 671 1.1 pgoyette aprint_normal("%s, %s, ", 672 1.1 pgoyette (s->sm_ddr.ddr_mod_attrs & SPDMEM_DDR_MASK_REG)? 673 1.1 pgoyette " (registered)":"", 674 1.1 pgoyette (s->sm_config < __arraycount(spdmem_parity_types))? 675 1.1 pgoyette spdmem_parity_types[s->sm_config]:"invalid parity"); 676 1.1 pgoyette 677 1.1 pgoyette dimm_size = 1 << (s->sm_ddr.ddr_rows + s->sm_ddr.ddr_cols - 17); 678 1.1 pgoyette dimm_size *= s->sm_ddr.ddr_ranks * s->sm_ddr.ddr_banks_per_chip; 679 1.1 pgoyette 680 1.1 pgoyette cycle_time = s->sm_ddr.ddr_cycle_whole * 1000 + 681 1.1 pgoyette spdmem_cycle_frac[s->sm_ddr.ddr_cycle_tenths]; 682 1.1 pgoyette bits = le16toh(s->sm_ddr.ddr_datawidth); 683 1.1 pgoyette if (s->sm_config == 1 || s->sm_config == 2) 684 1.1 pgoyette bits -= 8; 685 1.3 pgoyette decode_size_speed(self, node, dimm_size, cycle_time, 2, bits, TRUE, 686 1.3 pgoyette "PC", 0); 687 1.1 pgoyette 688 1.1 pgoyette aprint_verbose_dev(self, 689 1.1 pgoyette "%d rows, %d cols, %d ranks, %d banks/chip, %d.%dns cycle time\n", 690 1.1 pgoyette s->sm_ddr.ddr_rows, s->sm_ddr.ddr_cols, s->sm_ddr.ddr_ranks, 691 1.1 pgoyette s->sm_ddr.ddr_banks_per_chip, cycle_time/1000, 692 1.1 pgoyette (cycle_time % 1000 + 50) / 100); 693 1.1 pgoyette 694 1.1 pgoyette tAA = 0; 695 1.1 pgoyette for (i = 2; i < 8; i++) 696 1.1 pgoyette if (s->sm_ddr.ddr_tCAS & (1 << i)) 697 1.1 pgoyette tAA = i; 698 1.1 pgoyette tAA /= 2; 699 1.1 pgoyette 700 1.1 pgoyette #define __DDR_ROUND(scale, field) \ 701 1.1 pgoyette ((scale * s->sm_ddr.field + cycle_time - 1) / cycle_time) 702 1.1 pgoyette 703 1.4 christos aprint_verbose_dev(self, LATENCY, tAA, __DDR_ROUND(250, ddr_tRCD), 704 1.1 pgoyette __DDR_ROUND(250, ddr_tRP), __DDR_ROUND(1000, ddr_tRAS)); 705 1.1 pgoyette 706 1.1 pgoyette #undef __DDR_ROUND 707 1.1 pgoyette 708 1.1 pgoyette decode_voltage_refresh(self, s); 709 1.1 pgoyette } 710 1.1 pgoyette 711 1.1 pgoyette static void 712 1.18 msaitoh decode_ddr2(const struct sysctlnode *node, device_t self, struct spdmem *s) 713 1.18 msaitoh { 714 1.1 pgoyette int dimm_size, cycle_time, bits, tAA, i; 715 1.1 pgoyette 716 1.8 soren aprint_naive("\n"); 717 1.8 soren aprint_normal("\n"); 718 1.8 soren aprint_normal_dev(self, "%s", spdmem_basic_types[s->sm_type]); 719 1.8 soren 720 1.1 pgoyette aprint_normal("%s, %s, ", 721 1.1 pgoyette (s->sm_ddr2.ddr2_mod_attrs & SPDMEM_DDR2_MASK_REG)? 722 1.1 pgoyette " (registered)":"", 723 1.1 pgoyette (s->sm_config < __arraycount(spdmem_parity_types))? 724 1.1 pgoyette spdmem_parity_types[s->sm_config]:"invalid parity"); 725 1.1 pgoyette 726 1.1 pgoyette dimm_size = 1 << (s->sm_ddr2.ddr2_rows + s->sm_ddr2.ddr2_cols - 17); 727 1.1 pgoyette dimm_size *= (s->sm_ddr2.ddr2_ranks + 1) * 728 1.1 pgoyette s->sm_ddr2.ddr2_banks_per_chip; 729 1.1 pgoyette 730 1.1 pgoyette cycle_time = s->sm_ddr2.ddr2_cycle_whole * 1000 + 731 1.1 pgoyette spdmem_cycle_frac[s->sm_ddr2.ddr2_cycle_frac]; 732 1.1 pgoyette bits = s->sm_ddr2.ddr2_datawidth; 733 1.1 pgoyette if ((s->sm_config & 0x03) != 0) 734 1.1 pgoyette bits -= 8; 735 1.3 pgoyette decode_size_speed(self, node, dimm_size, cycle_time, 2, bits, TRUE, 736 1.3 pgoyette "PC2", 0); 737 1.1 pgoyette 738 1.1 pgoyette aprint_verbose_dev(self, 739 1.1 pgoyette "%d rows, %d cols, %d ranks, %d banks/chip, %d.%02dns cycle time\n", 740 1.1 pgoyette s->sm_ddr2.ddr2_rows, s->sm_ddr2.ddr2_cols, 741 1.1 pgoyette s->sm_ddr2.ddr2_ranks + 1, s->sm_ddr2.ddr2_banks_per_chip, 742 1.1 pgoyette cycle_time / 1000, (cycle_time % 1000 + 5) /10 ); 743 1.1 pgoyette 744 1.1 pgoyette tAA = 0; 745 1.1 pgoyette for (i = 2; i < 8; i++) 746 1.1 pgoyette if (s->sm_ddr2.ddr2_tCAS & (1 << i)) 747 1.1 pgoyette tAA = i; 748 1.1 pgoyette 749 1.1 pgoyette #define __DDR2_ROUND(scale, field) \ 750 1.1 pgoyette ((scale * s->sm_ddr2.field + cycle_time - 1) / cycle_time) 751 1.1 pgoyette 752 1.4 christos aprint_verbose_dev(self, LATENCY, tAA, __DDR2_ROUND(250, ddr2_tRCD), 753 1.1 pgoyette __DDR2_ROUND(250, ddr2_tRP), __DDR2_ROUND(1000, ddr2_tRAS)); 754 1.1 pgoyette 755 1.1 pgoyette #undef __DDR_ROUND 756 1.1 pgoyette 757 1.1 pgoyette decode_voltage_refresh(self, s); 758 1.1 pgoyette } 759 1.1 pgoyette 760 1.1 pgoyette static void 761 1.26 christos print_part(const char *part, size_t pnsize) 762 1.18 msaitoh { 763 1.27 christos const char *p = memchr(part, ' ', pnsize); 764 1.27 christos if (p == NULL) 765 1.27 christos p = part + pnsize; 766 1.27 christos aprint_normal(": %.*s\n", (int)(p - part), part); 767 1.26 christos } 768 1.26 christos 769 1.34 msaitoh static u_int 770 1.34 msaitoh ddr3_value_pico(struct spdmem *s, uint8_t txx_mtb, uint8_t txx_ftb) 771 1.34 msaitoh { 772 1.34 msaitoh u_int mtb, ftb; /* in picoseconds */ 773 1.34 msaitoh intmax_t signed_txx_ftb; 774 1.34 msaitoh u_int val; 775 1.34 msaitoh 776 1.34 msaitoh mtb = (u_int)s->sm_ddr3.ddr3_mtb_dividend * 1000 / 777 1.34 msaitoh s->sm_ddr3.ddr3_mtb_divisor; 778 1.34 msaitoh ftb = (u_int)s->sm_ddr3.ddr3_ftb_dividend * 1000 / 779 1.34 msaitoh s->sm_ddr3.ddr3_ftb_divisor; 780 1.34 msaitoh 781 1.34 msaitoh /* tXX_ftb is signed value */ 782 1.34 msaitoh signed_txx_ftb = (int8_t)txx_ftb; 783 1.34 msaitoh val = txx_mtb * mtb + 784 1.34 msaitoh ((txx_ftb > 127) ? signed_txx_ftb : txx_ftb) * ftb / 1000; 785 1.34 msaitoh 786 1.34 msaitoh return val; 787 1.34 msaitoh } 788 1.34 msaitoh 789 1.34 msaitoh #define __DDR3_VALUE_PICO(s, field) \ 790 1.34 msaitoh ddr3_value_pico(s, s->sm_ddr3.ddr3_##field##_mtb, \ 791 1.34 msaitoh s->sm_ddr3.ddr3_##field##_ftb) 792 1.34 msaitoh 793 1.26 christos static void 794 1.26 christos decode_ddr3(const struct sysctlnode *node, device_t self, struct spdmem *s) 795 1.26 christos { 796 1.26 christos int dimm_size, cycle_time, bits; 797 1.26 christos 798 1.8 soren aprint_naive("\n"); 799 1.26 christos print_part(s->sm_ddr3.ddr3_part, sizeof(s->sm_ddr3.ddr3_part)); 800 1.8 soren aprint_normal_dev(self, "%s", spdmem_basic_types[s->sm_type]); 801 1.8 soren 802 1.1 pgoyette if (s->sm_ddr3.ddr3_mod_type == 803 1.1 pgoyette SPDMEM_DDR3_TYPE_MINI_RDIMM || 804 1.1 pgoyette s->sm_ddr3.ddr3_mod_type == SPDMEM_DDR3_TYPE_RDIMM) 805 1.1 pgoyette aprint_normal(" (registered)"); 806 1.1 pgoyette aprint_normal(", %sECC, %stemp-sensor, ", 807 1.1 pgoyette (s->sm_ddr3.ddr3_hasECC)?"":"no ", 808 1.1 pgoyette (s->sm_ddr3.ddr3_has_therm_sensor)?"":"no "); 809 1.1 pgoyette 810 1.1 pgoyette /* 811 1.1 pgoyette * DDR3 size specification is quite different from others 812 1.1 pgoyette * 813 1.1 pgoyette * Module capacity is defined as 814 1.1 pgoyette * Chip_Capacity_in_bits / 8bits-per-byte * 815 1.1 pgoyette * external_bus_width / internal_bus_width 816 1.1 pgoyette * We further divide by 2**20 to get our answer in MB 817 1.1 pgoyette */ 818 1.1 pgoyette dimm_size = (s->sm_ddr3.ddr3_chipsize + 28 - 20) - 3 + 819 1.1 pgoyette (s->sm_ddr3.ddr3_datawidth + 3) - 820 1.1 pgoyette (s->sm_ddr3.ddr3_chipwidth + 2); 821 1.1 pgoyette dimm_size = (1 << dimm_size) * (s->sm_ddr3.ddr3_physbanks + 1); 822 1.1 pgoyette 823 1.34 msaitoh cycle_time = __DDR3_VALUE_PICO(s, tCKmin); 824 1.1 pgoyette bits = 1 << (s->sm_ddr3.ddr3_datawidth + 3); 825 1.3 pgoyette decode_size_speed(self, node, dimm_size, cycle_time, 2, bits, FALSE, 826 1.3 pgoyette "PC3", 0); 827 1.1 pgoyette 828 1.1 pgoyette aprint_verbose_dev(self, 829 1.1 pgoyette "%d rows, %d cols, %d log. banks, %d phys. banks, " 830 1.1 pgoyette "%d.%03dns cycle time\n", 831 1.32 msaitoh s->sm_ddr3.ddr3_rows + 12, s->sm_ddr3.ddr3_cols + 9, 832 1.1 pgoyette 1 << (s->sm_ddr3.ddr3_logbanks + 3), 833 1.1 pgoyette s->sm_ddr3.ddr3_physbanks + 1, 834 1.1 pgoyette cycle_time/1000, cycle_time % 1000); 835 1.1 pgoyette 836 1.34 msaitoh #define __DDR3_CYCLES(val) \ 837 1.34 msaitoh ((val / cycle_time) + ((val % cycle_time) ? 1 : 0)) 838 1.1 pgoyette 839 1.34 msaitoh aprint_verbose_dev(self, LATENCY, 840 1.34 msaitoh __DDR3_CYCLES(__DDR3_VALUE_PICO(s, tAAmin)), 841 1.34 msaitoh __DDR3_CYCLES(__DDR3_VALUE_PICO(s, tRCDmin)), 842 1.34 msaitoh __DDR3_CYCLES(__DDR3_VALUE_PICO(s, tRPmin)), 843 1.35 msaitoh __DDR3_CYCLES((s->sm_ddr3.ddr3_tRAS_msb * 256 844 1.35 msaitoh + s->sm_ddr3.ddr3_tRAS_lsb) * s->sm_ddr3.ddr3_mtb_dividend 845 1.35 msaitoh / s->sm_ddr3.ddr3_mtb_divisor * 1000)); 846 1.1 pgoyette 847 1.1 pgoyette #undef __DDR3_CYCLES 848 1.14 msaitoh 849 1.14 msaitoh /* For DDR3, Voltage is written in another area */ 850 1.14 msaitoh if (!s->sm_ddr3.ddr3_NOT15V || s->sm_ddr3.ddr3_135V 851 1.14 msaitoh || s->sm_ddr3.ddr3_125V) { 852 1.14 msaitoh aprint_verbose("%s:", device_xname(self)); 853 1.14 msaitoh if (!s->sm_ddr3.ddr3_NOT15V) 854 1.14 msaitoh aprint_verbose(" 1.5V"); 855 1.14 msaitoh if (s->sm_ddr3.ddr3_135V) 856 1.14 msaitoh aprint_verbose(" 1.35V"); 857 1.14 msaitoh if (s->sm_ddr3.ddr3_125V) 858 1.14 msaitoh aprint_verbose(" 1.25V"); 859 1.14 msaitoh aprint_verbose(" operable\n"); 860 1.14 msaitoh } 861 1.1 pgoyette } 862 1.1 pgoyette 863 1.1 pgoyette static void 864 1.18 msaitoh decode_fbdimm(const struct sysctlnode *node, device_t self, struct spdmem *s) 865 1.18 msaitoh { 866 1.1 pgoyette int dimm_size, cycle_time, bits; 867 1.1 pgoyette 868 1.8 soren aprint_naive("\n"); 869 1.8 soren aprint_normal("\n"); 870 1.8 soren aprint_normal_dev(self, "%s", spdmem_basic_types[s->sm_type]); 871 1.8 soren 872 1.1 pgoyette /* 873 1.1 pgoyette * FB-DIMM module size calculation is very much like DDR3 874 1.1 pgoyette */ 875 1.1 pgoyette dimm_size = s->sm_fbd.fbdimm_rows + 12 + 876 1.1 pgoyette s->sm_fbd.fbdimm_cols + 9 - 20 - 3; 877 1.1 pgoyette dimm_size = (1 << dimm_size) * (1 << (s->sm_fbd.fbdimm_banks + 2)); 878 1.1 pgoyette 879 1.1 pgoyette cycle_time = (1000 * s->sm_fbd.fbdimm_mtb_dividend + 880 1.1 pgoyette (s->sm_fbd.fbdimm_mtb_divisor / 2)) / 881 1.1 pgoyette s->sm_fbd.fbdimm_mtb_divisor; 882 1.1 pgoyette bits = 1 << (s->sm_fbd.fbdimm_dev_width + 2); 883 1.3 pgoyette decode_size_speed(self, node, dimm_size, cycle_time, 2, bits, TRUE, 884 1.3 pgoyette "PC2", 0); 885 1.1 pgoyette 886 1.1 pgoyette aprint_verbose_dev(self, 887 1.1 pgoyette "%d rows, %d cols, %d banks, %d.%02dns cycle time\n", 888 1.1 pgoyette s->sm_fbd.fbdimm_rows, s->sm_fbd.fbdimm_cols, 889 1.1 pgoyette 1 << (s->sm_fbd.fbdimm_banks + 2), 890 1.1 pgoyette cycle_time / 1000, (cycle_time % 1000 + 5) /10 ); 891 1.1 pgoyette 892 1.1 pgoyette #define __FBDIMM_CYCLES(field) (s->sm_fbd.field / s->sm_fbd.fbdimm_tCKmin) 893 1.1 pgoyette 894 1.4 christos aprint_verbose_dev(self, LATENCY, __FBDIMM_CYCLES(fbdimm_tAAmin), 895 1.33 msaitoh __FBDIMM_CYCLES(fbdimm_tRCDmin), __FBDIMM_CYCLES(fbdimm_tRPmin), 896 1.33 msaitoh (s->sm_fbd.fbdimm_tRAS_msb * 256 + s->sm_fbd.fbdimm_tRAS_lsb) / 897 1.33 msaitoh s->sm_fbd.fbdimm_tCKmin); 898 1.1 pgoyette 899 1.1 pgoyette #undef __FBDIMM_CYCLES 900 1.1 pgoyette 901 1.1 pgoyette decode_voltage_refresh(self, s); 902 1.1 pgoyette } 903 1.13 pgoyette 904 1.13 pgoyette static void 905 1.18 msaitoh decode_ddr4(const struct sysctlnode *node, device_t self, struct spdmem *s) 906 1.18 msaitoh { 907 1.30 msaitoh int dimm_size, cycle_time, ranks; 908 1.33 msaitoh int tAA_clocks, tRCD_clocks, tRP_clocks, tRAS_clocks; 909 1.13 pgoyette 910 1.13 pgoyette aprint_naive("\n"); 911 1.26 christos print_part(s->sm_ddr4.ddr4_part_number, 912 1.26 christos sizeof(s->sm_ddr4.ddr4_part_number)); 913 1.13 pgoyette aprint_normal_dev(self, "%s", spdmem_basic_types[s->sm_type]); 914 1.13 pgoyette if (s->sm_ddr4.ddr4_mod_type < __arraycount(spdmem_ddr4_module_types)) 915 1.33 msaitoh aprint_normal(" (%s)", 916 1.13 pgoyette spdmem_ddr4_module_types[s->sm_ddr4.ddr4_mod_type]); 917 1.28 msaitoh aprint_normal(", %sECC, %stemp-sensor, ", 918 1.28 msaitoh (s->sm_ddr4.ddr4_bus_width_extension) ? "" : "no ", 919 1.28 msaitoh (s->sm_ddr4.ddr4_has_therm_sensor) ? "" : "no "); 920 1.13 pgoyette 921 1.13 pgoyette /* 922 1.13 pgoyette * DDR4 size calculation from JEDEC spec 923 1.13 pgoyette * 924 1.13 pgoyette * Module capacity in bytes is defined as 925 1.13 pgoyette * Chip_Capacity_in_bits / 8bits-per-byte * 926 1.13 pgoyette * primary_bus_width / DRAM_width * 927 1.13 pgoyette * logical_ranks_per_DIMM 928 1.13 pgoyette * 929 1.13 pgoyette * logical_ranks_per DIMM equals package_ranks, but multiply 930 1.13 pgoyette * by diecount for 3DS packages 931 1.13 pgoyette * 932 1.13 pgoyette * We further divide by 2**20 to get our answer in MB 933 1.13 pgoyette */ 934 1.13 pgoyette dimm_size = (s->sm_ddr4.ddr4_capacity + 28) /* chip_capacity */ 935 1.13 pgoyette - 20 /* convert to MB */ 936 1.13 pgoyette - 3 /* bits --> bytes */ 937 1.13 pgoyette + (s->sm_ddr4.ddr4_primary_bus_width + 3); /* bus width */ 938 1.13 pgoyette switch (s->sm_ddr4.ddr4_device_width) { /* DRAM width */ 939 1.13 pgoyette case 0: dimm_size -= 2; 940 1.13 pgoyette break; 941 1.13 pgoyette case 1: dimm_size -= 3; 942 1.13 pgoyette break; 943 1.13 pgoyette case 2: dimm_size -= 4; 944 1.13 pgoyette break; 945 1.13 pgoyette case 4: dimm_size -= 5; 946 1.13 pgoyette break; 947 1.13 pgoyette default: 948 1.13 pgoyette dimm_size = -1; /* flag invalid value */ 949 1.13 pgoyette } 950 1.33 msaitoh if (dimm_size >= 0) { 951 1.13 pgoyette dimm_size = (1 << dimm_size) * 952 1.13 pgoyette (s->sm_ddr4.ddr4_package_ranks + 1); /* log.ranks/DIMM */ 953 1.13 pgoyette if (s->sm_ddr4.ddr4_signal_loading == 2) { 954 1.19 pgoyette dimm_size *= (s->sm_ddr4.ddr4_diecount + 1); 955 1.13 pgoyette } 956 1.13 pgoyette } 957 1.13 pgoyette 958 1.24 msaitoh /* 959 1.24 msaitoh * Note that the ddr4_xxx_ftb fields are actually signed offsets from 960 1.24 msaitoh * the corresponding mtb value, so we might have to subtract 256! 961 1.24 msaitoh */ 962 1.18 msaitoh #define __DDR4_VALUE(field) ((s->sm_ddr4.ddr4_##field##_mtb * 125 + \ 963 1.18 msaitoh s->sm_ddr4.ddr4_##field##_ftb) - \ 964 1.18 msaitoh ((s->sm_ddr4.ddr4_##field##_ftb > 127)?256:0)) 965 1.13 pgoyette /* 966 1.33 msaitoh * For now, the only value for mtb is 0 = 125ps, and ftb = 1ps 967 1.13 pgoyette * so we don't need to figure out the time-base units - just 968 1.13 pgoyette * hard-code them for now. 969 1.13 pgoyette */ 970 1.18 msaitoh cycle_time = __DDR4_VALUE(tCKAVGmin); 971 1.13 pgoyette decode_size_speed(self, node, dimm_size, cycle_time, 2, 972 1.19 pgoyette 1 << (s->sm_ddr4.ddr4_primary_bus_width + 3), 973 1.13 pgoyette TRUE, "PC4", 0); 974 1.13 pgoyette 975 1.30 msaitoh ranks = s->sm_ddr4.ddr4_package_ranks + 1; 976 1.13 pgoyette aprint_verbose_dev(self, 977 1.30 msaitoh "%d rows, %d cols, %d ranks%s, %d banks/group, %d bank groups\n", 978 1.29 msaitoh s->sm_ddr4.ddr4_rows + 12, s->sm_ddr4.ddr4_cols + 9, 979 1.30 msaitoh ranks, (ranks > 1) ? ((s->sm_ddr4.ddr4_rank_mix == 1) 980 1.31 pgoyette ? " (asymmetric)" : " (symmetric)") : "", 981 1.13 pgoyette 1 << (2 + s->sm_ddr4.ddr4_logbanks), 982 1.30 msaitoh 1 << s->sm_ddr4.ddr4_bankgroups); 983 1.30 msaitoh 984 1.30 msaitoh aprint_verbose_dev(self, "%d.%03dns cycle time\n", 985 1.20 msaitoh cycle_time / 1000, cycle_time % 1000); 986 1.13 pgoyette 987 1.18 msaitoh tAA_clocks = __DDR4_VALUE(tAAmin) * 1000 / cycle_time; 988 1.18 msaitoh tRCD_clocks = __DDR4_VALUE(tRCDmin) * 1000 / cycle_time; 989 1.18 msaitoh tRP_clocks = __DDR4_VALUE(tRPmin) * 1000 / cycle_time; 990 1.13 pgoyette tRAS_clocks = (s->sm_ddr4.ddr4_tRASmin_msb * 256 + 991 1.13 pgoyette s->sm_ddr4.ddr4_tRASmin_lsb) * 125 * 1000 / cycle_time; 992 1.13 pgoyette 993 1.13 pgoyette /* 994 1.13 pgoyette * Per JEDEC spec, rounding is done by taking the time value, dividing 995 1.13 pgoyette * by the cycle time, subtracting .010 from the result, and then 996 1.13 pgoyette * rounded up to the nearest integer. Unfortunately, none of their 997 1.13 pgoyette * examples say what to do when the result of the subtraction is already 998 1.13 pgoyette * an integer. For now, assume that we still round up (so an interval 999 1.13 pgoyette * of exactly 12.010 clock cycles will be printed as 13). 1000 1.13 pgoyette */ 1001 1.13 pgoyette #define __DDR4_ROUND(value) ((value - 10) / 1000 + 1) 1002 1.13 pgoyette 1003 1.13 pgoyette aprint_verbose_dev(self, LATENCY, __DDR4_ROUND(tAA_clocks), 1004 1.18 msaitoh __DDR4_ROUND(tRCD_clocks), 1005 1.13 pgoyette __DDR4_ROUND(tRP_clocks), 1006 1.13 pgoyette __DDR4_ROUND(tRAS_clocks)); 1007 1.13 pgoyette 1008 1.13 pgoyette #undef __DDR4_VALUE 1009 1.13 pgoyette #undef __DDR4_ROUND 1010 1.13 pgoyette } 1011