xref: /illumos-gate/usr/src/lib/libjedec/common/libjedec_spd_ddr3.c (revision 8119dad84d6416f13557b0ba8e2aaf9064cbcfd3)
1  /*
2   * This file and its contents are supplied under the terms of the
3   * Common Development and Distribution License ("CDDL"), version 1.0.
4   * You may only use this file in accordance with the terms of version
5   * 1.0 of the CDDL.
6   *
7   * A full copy of the text of the CDDL should have accompanied this
8   * source.  A copy of the CDDL is also available via the Internet at
9   * http://www.illumos.org/license/CDDL.
10   */
11  
12  /*
13   * Copyright 2024 Oxide Computer Company
14   */
15  
16  /*
17   * DDR3-specific SPD processing logic. For an overview of the processing design
18   * please see libjedec_spd.c.
19   */
20  
21  #include <sys/sysmacros.h>
22  #include <sys/debug.h>
23  #include "libjedec_spd.h"
24  
25  static const spd_value_map_t spd_ddr3_nbytes_used_map[] = {
26  	{ SPD_DDR3_NBYTES_USED_UNDEF, 0, true },
27  	{ SPD_DDR3_NBYTES_USED_128, 128, false },
28  	{ SPD_DDR3_NBYTES_USED_176, 176, false },
29  	{ SPD_DDR3_NBYTES_USED_256, 256, false },
30  };
31  
32  static const spd_value_map_t spd_ddr3_nbytes_total_map[] = {
33  	{ SPD_DDR3_NBYTES_TOTAL_UNDEF, 0, true },
34  	{ SPD_DDR3_NBYTES_TOTAL_256, 256, false }
35  };
36  
37  /*
38   * The macro values represent the last byte covered therefore the number of
39   * bytes is that plus one.
40   */
41  static const spd_value_map_t spd_ddr3_crc_map[] = {
42  	{ SPD_DDR3_NBYTES_CRC_125, 126, false },
43  	{ SPD_DDR3_NBYTES_CRC_116, 117, false }
44  };
45  
46  static void
spd_parse_ddr3_nbytes(spd_info_t * si,uint32_t off,uint32_t len,const char * key)47  spd_parse_ddr3_nbytes(spd_info_t *si, uint32_t off, uint32_t len,
48      const char *key)
49  {
50  	const uint8_t data = si->si_data[off];
51  	const uint8_t used = SPD_DDR3_NBYTES_USED(data);
52  	const uint8_t total = SPD_DDR3_NBYTES_TOTAL(data);
53  	const uint8_t crc = SPD_DDR3_NBYTES_CRC(data);
54  
55  	spd_insert_map(si, SPD_KEY_NBYTES_USED, used, spd_ddr3_nbytes_used_map,
56  	    ARRAY_SIZE(spd_ddr3_nbytes_used_map));
57  	spd_insert_map(si, SPD_KEY_NBYTES_TOTAL, total,
58  	    spd_ddr3_nbytes_total_map, ARRAY_SIZE(spd_ddr3_nbytes_total_map));
59  
60  	/*
61  	 * Unlike DDR5, there is no specific definition to indicate that the SPD
62  	 * is present or what type of device it is. There is only one standard
63  	 * DDR3 EEPROM, EE1002, so we note that it's here when we process this.
64  	 */
65  	spd_upsert_flag(si, SPD_KEY_DEVS, SPD_DEVICE_SPD);
66  	spd_nvl_insert_u32(si, SPD_KEY_DEV_SPD_TYPE, SPD_SPD_T_EE1002);
67  
68  	spd_insert_map(si, SPD_KEY_CRC_DDR3_LEN, crc, spd_ddr3_crc_map,
69  	    ARRAY_SIZE(spd_ddr3_crc_map));
70  }
71  
72  static const spd_value_map_t spd_ddr3_mod_type_map[] = {
73  	{ SPD_DDR3_MOD_TYPE_TYPE_UNDEF, UINT32_MAX, true },
74  	{ SPD_DDR3_MOD_TYPE_TYPE_RDIMM, SPD_MOD_TYPE_RDIMM, false },
75  	{ SPD_DDR3_MOD_TYPE_TYPE_UDIMM, SPD_MOD_TYPE_UDIMM, false },
76  	{ SPD_DDR3_MOD_TYPE_TYPE_SODIMM, SPD_MOD_TYPE_SODIMM, false },
77  	{ SPD_DDR3_MOD_TYPE_TYPE_MICRO_DIMM, SPD_MOD_TYPE_MICRO_DIMM, false },
78  	{ SPD_DDR3_MOD_TYPE_TYPE_MINI_RDIMM, SPD_MOD_TYPE_MINI_RDIMM, false },
79  	{ SPD_DDR3_MOD_TYPE_TYPE_MINI_UDIMM, SPD_MOD_TYPE_MINI_UDIMM, false },
80  	{ SPD_DDR3_MOD_TYPE_TYPE_MINI_CDIMM, SPD_MOD_TYPE_MINI_CDIMM, false },
81  	{ SPD_DDR3_MOD_TYPE_TYPE_72b_SORDIMM, SPD_MOD_TYPE_72b_SO_RDIMM,
82  	    false },
83  	{ SPD_DDR3_MOD_TYPE_TYPE_72b_SOUDIMM, SPD_MOD_TYPE_72b_SO_UDIMM,
84  	    false },
85  	{ SPD_DDR3_MOD_TYPE_TYPE_72b_SOCDIMM, SPD_MOD_TYPE_72b_SO_CDIMM,
86  	    false },
87  	{ SPD_DDR3_MOD_TYPE_TYPE_LRDIMM, SPD_MOD_TYPE_LRDIMM, false },
88  	{ SPD_DDR3_MOD_TYPE_TYPE_16b_SODIMM, SPD_MOD_TYPE_16b_SO_DIMM, false },
89  	{ SPD_DDR3_MOD_TYPE_TYPE_32b_SODIMM, SPD_MOD_TYPE_32b_SO_DIMM, false },
90  };
91  
92  static void
spd_parse_ddr3_mod_type(spd_info_t * si,uint32_t off,uint32_t len,const char * key)93  spd_parse_ddr3_mod_type(spd_info_t *si, uint32_t off, uint32_t len,
94      const char *key)
95  {
96  	const uint8_t data = si->si_data[off];
97  	const uint8_t type = SPD_DDR3_MOD_TYPE_TYPE(data);
98  
99  	spd_insert_map(si, SPD_KEY_MOD_TYPE, type, spd_ddr3_mod_type_map,
100  	    ARRAY_SIZE(spd_ddr3_mod_type_map));
101  }
102  
103  static const spd_value_range_t spd_ddr3_nba_range = {
104  	.svr_max = SPD_DDR3_DENSITY_NBA_BITS_MAX,
105  	.svr_base = SPD_DDR3_DENSITY_NBA_BITS_BASE
106  };
107  
108  static const spd_value_map64_t spd_ddr3_density_map[] = {
109  	{SPD_DDR3_DENSITY_DENSITY_256Mb, 256ULL * 1024ULL * 1024ULL, false },
110  	{SPD_DDR3_DENSITY_DENSITY_512Mb, 512ULL * 1024ULL * 1024ULL, false },
111  	{SPD_DDR3_DENSITY_DENSITY_1Gb, 1ULL * 1024ULL * 1024ULL * 1024ULL,
112  	    false },
113  	{SPD_DDR3_DENSITY_DENSITY_2Gb, 2ULL * 1024ULL * 1024ULL * 1024ULL,
114  	    false },
115  	{SPD_DDR3_DENSITY_DENSITY_4Gb, 4ULL * 1024ULL * 1024ULL * 1024ULL,
116  	    false },
117  	{SPD_DDR3_DENSITY_DENSITY_8Gb, 8ULL * 1024ULL * 1024ULL * 1024ULL,
118  	    false },
119  	{SPD_DDR3_DENSITY_DENSITY_16Gb, 16ULL * 1024ULL * 1024ULL * 1024ULL,
120  	    false },
121  	{SPD_DDR3_DENSITY_DENSITY_32Gb, 32ULL * 1024ULL * 1024ULL * 1024ULL,
122  	    false },
123  	{SPD_DDR3_DENSITY_DENSITY_12Gb, 12ULL * 1024ULL * 1024ULL * 1024ULL,
124  	    false },
125  	{SPD_DDR3_DENSITY_DENSITY_24Gb, 24ULL * 1024ULL * 1024ULL * 1024ULL,
126  	    false },
127  };
128  
129  /*
130   * DDR3 does not define bank groups, hence when we insert the bank address bits
131   * we come back and set bank group bits to 0.
132   */
133  static void
spd_parse_ddr3_density(spd_info_t * si,uint32_t off,uint32_t len,const char * key)134  spd_parse_ddr3_density(spd_info_t *si, uint32_t off, uint32_t len,
135      const char *key)
136  {
137  	const uint8_t data = si->si_data[off];
138  	const uint8_t dens = SPD_DDR3_DENSITY_DENSITY(data);
139  	const uint8_t nba = SPD_DDR3_DENSITY_NBA_BITS(data);
140  
141  	spd_insert_range(si, SPD_KEY_NBANK_BITS, nba, &spd_ddr3_nba_range);
142  	spd_nvl_insert_u32(si, SPD_KEY_NBGRP_BITS, 0);
143  	spd_insert_map64(si, SPD_KEY_DIE_SIZE, dens, spd_ddr3_density_map,
144  	    ARRAY_SIZE(spd_ddr3_density_map));
145  }
146  
147  static const spd_value_range_t spd_ddr3_nrow_range = {
148  	.svr_max = SPD_DDR3_ADDR_NROWS_MAX,
149  	.svr_base = SPD_DDR3_ADDR_NROWS_BASE
150  };
151  
152  static const spd_value_range_t spd_ddr3_ncol_range = {
153  	.svr_max = SPD_DDR3_ADDR_NCOLS_MAX,
154  	.svr_base = SPD_DDR3_ADDR_NCOLS_BASE
155  };
156  
157  static void
spd_parse_ddr3_addr(spd_info_t * si,uint32_t off,uint32_t len,const char * key)158  spd_parse_ddr3_addr(spd_info_t *si, uint32_t off, uint32_t len,
159      const char *key)
160  {
161  	const uint8_t data = si->si_data[off];
162  	const uint8_t nrows = SPD_DDR3_ADDR_NROWS(data);
163  	const uint8_t ncols = SPD_DDR3_ADDR_NCOLS(data);
164  
165  	spd_insert_range(si, SPD_KEY_NROW_BITS, nrows, &spd_ddr3_nrow_range);
166  	spd_insert_range(si, SPD_KEY_NCOL_BITS, ncols, &spd_ddr3_ncol_range);
167  }
168  
169  static void
spd_parse_ddr3_volt(spd_info_t * si,uint32_t off,uint32_t len,const char * key)170  spd_parse_ddr3_volt(spd_info_t *si, uint32_t off, uint32_t len,
171      const char *key)
172  {
173  	const uint8_t data = si->si_data[off];
174  	uint32_t volts[3];
175  	uint_t nvolt = 0;
176  
177  	/*
178  	 * DDR3 came out with 1.5V support initially meaning a value of zero
179  	 * indicates that 1.5V is supported. Affirmative values came later.
180  	 */
181  	if (SPD_DDR3_VOLT_V1P5_OPER(data) == 0) {
182  		volts[nvolt] = 1500;
183  		nvolt++;
184  	}
185  
186  	if (SPD_DDR3_VOLT_V1P35_OPER(data) != 0) {
187  		volts[nvolt] = 1350;
188  		nvolt++;
189  	}
190  
191  	if (SPD_DDR3_VOLT_V1P25_OPER(data) != 0) {
192  		volts[nvolt] = 1250;
193  		nvolt++;
194  	}
195  
196  	if (nvolt > 0) {
197  		spd_nvl_insert_u32_array(si, key, volts, nvolt);
198  	}
199  }
200  
201  static const spd_value_range_t spd_ddr3_width_range = {
202  	.svr_base = SPD_DDR3_MOD_ORG_WIDTH_BASE,
203  	.svr_max = SPD_DDR3_MOD_ORG_WIDTH_MAX,
204  	.svr_exp = true
205  };
206  
207  static const spd_value_map_t spd_ddr3_nranks[] = {
208  	{ SPD_DDR3_MOD_ORG_NRANKS_1, 1, false },
209  	{ SPD_DDR3_MOD_ORG_NRANKS_2, 2, false },
210  	{ SPD_DDR3_MOD_ORG_NRANKS_3, 3, false },
211  	{ SPD_DDR3_MOD_ORG_NRANKS_4, 4, false },
212  	{ SPD_DDR3_MOD_ORG_NRANKS_8, 8, false }
213  };
214  
215  static void
spd_parse_ddr3_mod_org(spd_info_t * si,uint32_t off,uint32_t len,const char * key)216  spd_parse_ddr3_mod_org(spd_info_t *si, uint32_t off, uint32_t len,
217      const char *key)
218  {
219  	const uint8_t data = si->si_data[off];
220  	const uint8_t nranks = SPD_DDR4_MOD_ORG_NPKG_RANK(data);
221  	const uint8_t width = SPD_DDR4_MOD_ORG_WIDTH(data);
222  
223  	spd_insert_range(si, SPD_KEY_DRAM_WIDTH, width, &spd_ddr3_width_range);
224  	spd_insert_map(si, SPD_KEY_NRANKS, nranks, spd_ddr3_nranks,
225  	    ARRAY_SIZE(spd_ddr3_nranks));
226  }
227  
228  static const spd_value_map_t spd_ddr3_ext_width[] = {
229  	{ SPD_DDR4_MOD_BUS_WIDTH_EXT_NONE, 0, false },
230  	{ SPD_DDR4_MOD_BUS_WIDTH_EXT_8b, 8, false }
231  };
232  
233  static const spd_value_range_t spd_ddr3_pri_range = {
234  	.svr_base = SPD_DDR3_BUS_WIDTH_PRI_BASE,
235  	.svr_max = SPD_DDR3_BUS_WIDTH_PRI_MAX,
236  	.svr_exp = true
237  };
238  
239  static void
spd_parse_ddr3_bus_width(spd_info_t * si,uint32_t off,uint32_t len,const char * key)240  spd_parse_ddr3_bus_width(spd_info_t *si, uint32_t off, uint32_t len,
241      const char *key)
242  {
243  	const uint8_t data = si->si_data[off];
244  	const uint8_t ext = SPD_DDR3_BUS_WIDTH_EXT(data);
245  	const uint8_t pri = SPD_DDR3_BUS_WIDTH_PRI(data);
246  
247  	/*
248  	 * DDR3 only has a single channel and subchanne. Record that reality
249  	 * here.
250  	 */
251  	spd_nvl_insert_u32(si, SPD_KEY_NSUBCHAN, 1);
252  	spd_nvl_insert_u32(si, SPD_KEY_DRAM_NCHAN, 1);
253  	spd_insert_range(si, SPD_KEY_DATA_WIDTH, pri, &spd_ddr3_pri_range);
254  	spd_insert_map(si, SPD_KEY_ECC_WIDTH, ext, spd_ddr3_ext_width,
255  	    ARRAY_SIZE(spd_ddr3_ext_width));
256  }
257  
258  /*
259   * We only currently support a 1 ps FTB. The DDR3 spec has examples of 2.5ps and
260   * 5ps versions. 1p was the magic number required for DDR4 and LPDDR3-5. For now
261   * we admit we don't support processing it and will cross the bridge when it
262   * becomes important for consumers.
263   */
264  static void
spd_parse_ddr3_ftb(spd_info_t * si,uint32_t off,uint32_t len,const char * key)265  spd_parse_ddr3_ftb(spd_info_t *si, uint32_t off, uint32_t len,
266      const char *key)
267  {
268  	const uint8_t data = si->si_data[off];
269  
270  	if (SPD_DDR3_FTB_DIVIDEND(data) != 1 ||
271  	    SPD_DDR3_FTB_DIVISOR(data) != 1) {
272  		spd_nvl_err(si, key, SPD_ERROR_NO_XLATE, "library cannot "
273  		    "handle FTB value that's not 1ps, found divisor and "
274  		    "dividend %u/%u", SPD_DDR3_FTB_DIVISOR(data),
275  		    SPD_DDR3_FTB_DIVIDEND(data));
276  		return;
277  	}
278  
279  	spd_nvl_insert_u32(si, key, SPD_DDR3_FTB_PS);
280  }
281  
282  /*
283   * There are two bytes that represent the divisor and dividend; however, only a
284   * value that results in 125ps is supported by the spec.
285   */
286  static void
spd_parse_ddr3_mtb(spd_info_t * si,uint32_t off,uint32_t len,const char * key)287  spd_parse_ddr3_mtb(spd_info_t *si, uint32_t off, uint32_t len,
288      const char *key)
289  {
290  	const uint8_t dividend = si->si_data[off];
291  	const uint8_t divisor = si->si_data[off + 1];
292  
293  	if (dividend != SPD_DDR3_MTB_125PS_DIVIDEND ||
294  	    divisor != SPD_DDR3_MTB_125PS_DIVISOR) {
295  		spd_nvl_err(si, key, SPD_ERROR_NO_XLATE, "library encountered "
296  		    "undefined MTB value (not 125ps): found divisor and "
297  		    "dividend %u/%u", divisor, dividend);
298  		return;
299  	}
300  
301  	spd_nvl_insert_u32(si, key, SPD_DDR3_MTB_PS);
302  }
303  
304  static void
spd_parse_ddr3_cas(spd_info_t * si,uint32_t off,uint32_t len,const char * key)305  spd_parse_ddr3_cas(spd_info_t *si, uint32_t off, uint32_t len,
306      const char *key)
307  {
308  	uint32_t cas[16] = { 0 };
309  	uint_t ncas = 0;
310  
311  	ASSERT3U(len, ==, 2);
312  	for (uint32_t byte = 0; byte < len; byte++) {
313  		const uint32_t data = si->si_data[off + byte];
314  		uint32_t nbits = NBBY;
315  
316  		/*
317  		 * The last byte reserves the last bit.
318  		 */
319  		if (byte == len - 1)
320  			nbits--;
321  
322  		for (uint32_t i = 0; i < nbits; i++) {
323  			if (bitx8(data, i, i) == 1) {
324  				cas[ncas] = SPD_DDR3_CAS_BASE + i + NBBY * byte;
325  				ncas++;
326  			}
327  		}
328  	}
329  
330  	spd_nvl_insert_u32_array(si, key, cas, ncas);
331  }
332  
333  /*
334   * Parse a time value that is a single number of MTB units.
335   */
336  static void
spd_parse_ddr3_mtb_time(spd_info_t * si,uint32_t off,uint32_t len,const char * key)337  spd_parse_ddr3_mtb_time(spd_info_t *si, uint32_t off, uint32_t len,
338      const char *key)
339  {
340  	const uint64_t ps = (uint64_t)si->si_data[off] * SPD_DDR3_MTB_PS;
341  
342  	if (ps == 0) {
343  		spd_nvl_err(si, key, SPD_ERROR_NO_XLATE,
344  		    "encountered unexpected zero time value");
345  		return;
346  	}
347  	spd_nvl_insert_u64(si, key, ps);
348  }
349  
350  /*
351   *
352   * t~RAS~ consists of the upper nibble at off and the MTB at off + 1.
353   */
354  static void
spd_parse_ddr3_tras(spd_info_t * si,uint32_t off,uint32_t len,const char * key)355  spd_parse_ddr3_tras(spd_info_t *si, uint32_t off, uint32_t len,
356      const char *key)
357  {
358  	const uint8_t ras_nib = SPD_DDR3_RAS_RC_UPPER_RAS(si->si_data[off]);
359  	ASSERT3U(len, ==, 2);
360  
361  	return (spd_parse_ddr_time(si, key, ras_nib, si->si_data[off + 1], 0));
362  }
363  
364  /*
365   * t~RC~ consists of an upper 4-bit nibble at off. Its MTB is at off + 2. The
366   * FTB is at off + len - 1.
367   */
368  static void
spd_parse_ddr3_trc(spd_info_t * si,uint32_t off,uint32_t len,const char * key)369  spd_parse_ddr3_trc(spd_info_t *si, uint32_t off, uint32_t len,
370      const char *key)
371  {
372  	const uint8_t rc_nib = SPD_DDR3_RAS_RC_UPPER_RC(si->si_data[off]);
373  
374  	return (spd_parse_ddr_time(si, key, rc_nib, si->si_data[off + 2],
375  	    si->si_data[off + len - 1]));
376  }
377  
378  static void
spd_parse_ddr3_tfaw(spd_info_t * si,uint32_t off,uint32_t len,const char * key)379  spd_parse_ddr3_tfaw(spd_info_t *si, uint32_t off, uint32_t len,
380      const char *key)
381  {
382  	const uint8_t nib = SPD_DDR3_TFAB_NIB_UPPER_TFAW(si->si_data[off]);
383  	ASSERT3U(len, ==, 2);
384  
385  	return (spd_parse_ddr_time(si, key, nib, si->si_data[off + 1], 0));
386  }
387  
388  static void
spd_parse_ddr3_opt_feat(spd_info_t * si,uint32_t off,uint32_t len,const char * key)389  spd_parse_ddr3_opt_feat(spd_info_t *si, uint32_t off, uint32_t len,
390      const char *key)
391  {
392  	const uint8_t data = si->si_data[off];
393  	spd_ddr3_feat_t flags = 0;
394  
395  	if (SPD_DDR3_OPT_FEAT_RZQ6(data) != 0)
396  		flags |= SPD_DDR3_FEAT_RZQ_6;
397  	if (SPD_DDR3_OPT_FEAT_RZQ7(data) != 0)
398  		flags |= SPD_DDR3_FEAT_RZQ_7;
399  	if (SPD_DDR3_OPT_FEAT_DLLO(data) != 0)
400  		flags |= SPD_DDR3_FEAT_DLL_OFF;
401  
402  	if (flags != 0) {
403  		spd_upsert_flag(si, SPD_KEY_DDR3_FEAT, flags);
404  	}
405  }
406  
407  static const spd_value_map_t spd_ddr3_temp[] = {
408  	{ SPD_DDR3_REFRESH_ETR_TEMP_85C, JEDEC_TEMP_CASE_NT, false },
409  	{ SPD_DDR3_REFRESH_ETR_TEMP_95C, JEDEC_TEMP_CASE_XT, false },
410  };
411  
412  static const spd_value_map_t spd_ddr3_xtrr[] = {
413  	{ SPD_DDR3_REFRESH_ETR_REF_2X, 2, false },
414  	{ SPD_DDR3_REFRESH_ETR_REF_1X, 1, false },
415  };
416  
417  /*
418   * While this defines an ODTS bit it was pending a ballot and it's not clear to
419   * us that this ballot has ever passed. If it has, then we will denote
420   * something there.
421   */
422  static void
spd_parse_ddr3_refresh(spd_info_t * si,uint32_t off,uint32_t len,const char * key)423  spd_parse_ddr3_refresh(spd_info_t *si, uint32_t off, uint32_t len,
424      const char *key)
425  {
426  	const uint8_t data = si->si_data[off];
427  	const uint8_t etr = SPD_DDR3_REFRESH_ETR_TEMP(data);
428  	const uint8_t rr = SPD_DDR3_REFRESH_ETR_REF(data);
429  
430  	spd_insert_map(si, SPD_KEY_MOD_OPER_TEMP, etr,
431  	    spd_ddr3_temp, ARRAY_SIZE(spd_ddr3_temp));
432  	spd_insert_map(si, SPD_KEY_DDR3_XTRR, rr,
433  	    spd_ddr3_xtrr, ARRAY_SIZE(spd_ddr3_xtrr));
434  	if (SPD_DDR3_REFRESH_ASR_SUP(data) != 0) {
435  		spd_upsert_flag(si, SPD_KEY_DDR3_FEAT, SPD_DDR3_FEAT_ASR);
436  	}
437  
438  	if (SPD_DDR3_REFRESH_PASR_SUP(data) != 0) {
439  		spd_nvl_insert_key(si, SPD_KEY_DDR_PASR);
440  	}
441  }
442  
443  static void
spd_parse_ddr3_ts(spd_info_t * si,uint32_t off,uint32_t len,const char * key)444  spd_parse_ddr3_ts(spd_info_t *si, uint32_t off, uint32_t len,
445      const char *key)
446  {
447  	const uint8_t data = si->si_data[off];
448  
449  	if (SPD_DDR3_MOD_THERM_PRES(data)) {
450  		spd_upsert_flag(si, SPD_KEY_DEVS, SPD_DEVICE_TEMP_1);
451  		spd_nvl_insert_u32(si, SPD_KEY_DEV_TEMP_TYPE,
452  		    SPD_TEMP_T_TSE2002);
453  	}
454  }
455  
456  static const spd_value_map_t spd_ddr3_sl_map[] = {
457  	{ SPD_DDR3_PKG_SIG_LOAD_UNSPEC, SPD_SL_UNSPECIFIED, false },
458  	{ SPD_DDR3_PKG_SIG_LOAD_MULTI, SPD_SL_MUTLI_STACK, false },
459  	{ SPD_DDR3_PKG_SIG_LOAD_SINGLE, SPD_SL_3DS, false }
460  };
461  
462  static const spd_value_range_t spd_ddr3_ndie_range = {
463  	.svr_min = SPD_DDR3_PKG_DIE_CNT_MIN,
464  	.svr_max = SPD_DDR3_PKG_DIE_CNT_MAX,
465  	.svr_exp = true
466  };
467  
468  static void
spd_parse_ddr3_type(spd_info_t * si,uint32_t off,uint32_t len,const char * key)469  spd_parse_ddr3_type(spd_info_t *si, uint32_t off, uint32_t len,
470      const char *key)
471  {
472  	const uint8_t data = si->si_data[off];
473  	const uint8_t ndie = SPD_DDR3_PKG_DIE_CNT(data);
474  	const uint8_t sl = SPD_DDR3_PKG_SIG_LOAD(data);
475  
476  	if (SPD_DDR3_PKG_TYPE(data) == SPD_DDR3_PKG_TYPE_NOT) {
477  		spd_nvl_insert_key(si, SPD_KEY_PKG_NOT_MONO);
478  	}
479  
480  	/*
481  	 * A value of zero here is considered unspecified.
482  	 */
483  	if (SPD_DDR3_PKG_DIE_CNT(data) != 0) {
484  		spd_insert_range(si, SPD_KEY_PKG_NDIE, ndie,
485  		    &spd_ddr3_ndie_range);
486  	}
487  
488  	spd_insert_map(si, SPD_KEY_PKG_SL, sl, spd_ddr3_sl_map,
489  	    ARRAY_SIZE(spd_ddr3_sl_map));
490  }
491  
492  static const spd_value_map_t spd_ddr3_maw_map[] = {
493  	{ SPD_DDR3_MAC_MAW_8192X, 8192, false },
494  	{ SPD_DDR3_MAC_MAW_4096X, 4096, false },
495  	{ SPD_DDR3_MAC_MAW_2048X, 2048, false }
496  };
497  
498  static const spd_value_map_t spd_ddr3_mac_map[] = {
499  	{ SPD_DDR3_MAC_MAC_UNTESTED, 0, true},
500  	{ SPD_DDR3_MAC_MAC_700K, 700000, false },
501  	{ SPD_DDR3_MAC_MAC_600K, 600000, false },
502  	{ SPD_DDR3_MAC_MAC_500K, 500000, false },
503  	{ SPD_DDR3_MAC_MAC_400K, 400000, false },
504  	{ SPD_DDR3_MAC_MAC_300K, 300000, false },
505  	{ SPD_DDR3_MAC_MAC_200K, 200000, false },
506  	{ SPD_DDR3_MAC_MAC_UNLIMITED, SPD_KEY_MAC_UNLIMITED, false }
507  };
508  
509  static void
spd_parse_ddr3_mac(spd_info_t * si,uint32_t off,uint32_t len,const char * key)510  spd_parse_ddr3_mac(spd_info_t *si, uint32_t off, uint32_t len, const char *key)
511  {
512  	const uint8_t data = si->si_data[off];
513  	const uint8_t maw = SPD_DDR3_MAC_MAW(data);
514  	const uint8_t mac = SPD_DDR3_MAC_MAC(data);
515  
516  	spd_insert_map(si, SPD_KEY_MAW, maw, spd_ddr3_maw_map,
517  	    ARRAY_SIZE(spd_ddr3_maw_map));
518  	spd_insert_map(si, SPD_KEY_MAC, mac, spd_ddr3_mac_map,
519  	    ARRAY_SIZE(spd_ddr3_mac_map));
520  }
521  
522  /*
523   * The DDR3 CRC comes in two different lengths as the DDR3 CRC may optionally
524   * cover the manufacturing information or stop short at byte 116. Which length
525   * this is is defined in byte 0.
526   */
527  static void
spd_parse_ddr3_crc(spd_info_t * si,uint32_t off,uint32_t len,const char * key)528  spd_parse_ddr3_crc(spd_info_t *si, uint32_t off, uint32_t len, const char *key)
529  {
530  	const uint16_t expect = si->si_data[off + len - 2] |
531  	    (si->si_data[off + len - 1] << 8);
532  	const uint8_t crc = SPD_DDR3_NBYTES_CRC(si->si_data[SPD_DDR3_NBYTES]);
533  	const uint32_t crc_len = crc == SPD_DDR3_NBYTES_CRC_125 ? 127 : 117;
534  
535  	spd_parse_crc_expect(si, off, crc_len, expect, key);
536  }
537  
538  static const spd_parse_t spd_ddr3_common[] = {
539  	{ .sp_off = SPD_DDR3_NBYTES, .sp_parse = spd_parse_ddr3_nbytes },
540  	{ .sp_off = SPD_DDR3_SPD_REV, .sp_parse = spd_parse_rev },
541  	/*
542  	 * We have previously validated that the DRAM type is something that we
543  	 * understand. We pass through the raw enum to users here.
544  	 */
545  	{ .sp_off = SPD_DDR3_DRAM_TYPE, .sp_key = SPD_KEY_DRAM_TYPE,
546  	    .sp_parse = spd_parse_raw_u8 },
547  	{ .sp_off = SPD_DDR3_MOD_TYPE, .sp_parse = spd_parse_ddr3_mod_type },
548  	{ .sp_off = SPD_DDR3_DENSITY, .sp_parse = spd_parse_ddr3_density },
549  	{ .sp_off = SPD_DDR3_ADDR, .sp_parse = spd_parse_ddr3_addr },
550  	{ .sp_off = SPD_DDR3_VOLT, .sp_key = SPD_KEY_NOM_VDD,
551  	    .sp_parse = spd_parse_ddr3_volt },
552  	{ .sp_off = SPD_DDR3_MOD_ORG, .sp_parse = spd_parse_ddr3_mod_org },
553  	{ .sp_off = SPD_DDR3_BUS_WIDTH, .sp_parse = spd_parse_ddr3_bus_width },
554  	{ .sp_off = SPD_DDR3_FTB, .sp_key = SPD_KEY_FTB,
555  	    .sp_parse = spd_parse_ddr3_ftb },
556  	{ .sp_off = SPD_DDR3_MTB_DIVIDEND, .sp_key = SPD_KEY_MTB, .sp_len = 2,
557  	    .sp_parse = spd_parse_ddr3_mtb },
558  	{ .sp_off = SPD_DDR3_TCK_MIN, .sp_key = SPD_KEY_TCKAVG_MIN,
559  	    .sp_len = SPD_DDR3_TCK_MIN_FINE - SPD_DDR3_TCK_MIN + 1,
560  	    .sp_parse = spd_parse_mtb_ftb_time_pair },
561  	{ .sp_off = SPD_DDR3_CAS_SUP0, .sp_key = SPD_KEY_CAS, .sp_len = 2,
562  	    .sp_parse = spd_parse_ddr3_cas },
563  	{ .sp_off = SPD_DDR3_TAA_MIN, .sp_key = SPD_KEY_TAA_MIN,
564  	    .sp_len = SPD_DDR3_TAA_MIN_FINE - SPD_DDR3_TAA_MIN + 1,
565  	    .sp_parse = spd_parse_mtb_ftb_time_pair },
566  	{ .sp_off = SPD_DDR3_TWR_MIN, .sp_key = SPD_KEY_TWR_MIN,
567  	    .sp_parse = spd_parse_ddr3_mtb_time },
568  	{ .sp_off = SPD_DDR3_TRCD_MIN, .sp_key = SPD_KEY_TRCD_MIN,
569  	    .sp_len = SPD_DDR3_TRCD_MIN_FINE - SPD_DDR3_TRCD_MIN + 1,
570  	    .sp_parse = spd_parse_mtb_ftb_time_pair },
571  	/*
572  	 * DDR3 defines only a single tRRD value. There are no bank groups in
573  	 * DDR3 therefore we translate that to tRRD_L, as we consider everything
574  	 * to be in a single bank group.
575  	 */
576  	{ .sp_off = SPD_DDR3_TRRD_MIN, .sp_key = SPD_KEY_TRRD_L_MIN,
577  	    .sp_parse = spd_parse_ddr3_mtb_time },
578  	{ .sp_off = SPD_DDR3_TRP_MIN, .sp_key = SPD_KEY_TRP_MIN,
579  	    .sp_len = SPD_DDR3_TRP_MIN_FINE - SPD_DDR3_TRP_MIN + 1,
580  	    .sp_parse = spd_parse_mtb_ftb_time_pair },
581  	{ .sp_off = SPD_DDR3_RAS_RC_UPPER, .sp_len = 2,
582  	    .sp_key = SPD_KEY_TRAS_MIN, .sp_parse = spd_parse_ddr3_tras },
583  	{ .sp_off = SPD_DDR3_RAS_RC_UPPER, .sp_key = SPD_KEY_TRC_MIN,
584  	    .sp_len = SPD_DDR3_TRC_MIN_FINE - SPD_DDR3_RAS_RC_UPPER + 1,
585  	    .sp_parse = spd_parse_ddr3_trc },
586  	/*
587  	 * Our rough understanding is that the DDR3 tRFC is a 1x rate.
588  	 */
589  	{ .sp_off = SPD_DDR3_TRFC_MIN_LSB, .sp_len = 2,
590  	    .sp_key = SPD_KEY_TRFC1_MIN, .sp_parse = spd_parse_mtb_pair },
591  	/*
592  	 * tWTR is like tRRD and it gets mapped to the same bank group case.
593  	 */
594  	{ .sp_off = SPD_DDR3_TWTR_MIN, .sp_key = SPD_KEY_TWTRS_MIN,
595  	    .sp_parse = spd_parse_ddr3_mtb_time },
596  	{ .sp_off = SPD_DDR3_TRTP_MIN, .sp_key = SPD_KEY_TRTP,
597  	    .sp_parse = spd_parse_ddr3_mtb_time },
598  	{ .sp_off = SPD_DDR3_TFAW_NIB, .sp_len = 2,
599  	    .sp_key = SPD_KEY_TFAW, .sp_parse = spd_parse_ddr3_tfaw },
600  	{ .sp_off = SPD_DDR3_OPT_FEAT, .sp_parse = spd_parse_ddr3_opt_feat },
601  	{ .sp_off = SPD_DDR3_REFRESH, .sp_parse = spd_parse_ddr3_refresh },
602  	{ .sp_off = SPD_DDR3_MOD_THERM, .sp_parse = spd_parse_ddr3_ts },
603  	{ .sp_off = SPD_DDR3_TYPE, .sp_parse = spd_parse_ddr3_type },
604  	{ .sp_off = SPD_DDR3_MAC, .sp_parse = spd_parse_ddr3_mac},
605  	/*
606  	 * As the CRC is part of all module types we just stick in with the
607  	 * general processing.
608  	 */
609  	{ .sp_len = SPD_DDR3_CRC_MSB + 1, .sp_key = SPD_KEY_CRC_DDR3,
610  	    .sp_parse = spd_parse_ddr3_crc },
611  };
612  
613  static const spd_parse_t spd_ddr3_mfg[] = {
614  	{ .sp_off = SPD_DDR3_MFG_MOD_ID0, .sp_len = 2,
615  	    .sp_key = SPD_KEY_MFG_MOD_MFG_ID,
616  	    .sp_parse = spd_parse_jedec_id },
617  	{ .sp_off = SPD_DDR3_MFG_MOD_ID0, .sp_len = 2,
618  	    .sp_key = SPD_KEY_MFG_MOD_MFG_NAME,
619  	    .sp_parse = spd_parse_jedec_id_str },
620  	{ .sp_off = SPD_DDR3_MFG_LOC, .sp_key = SPD_KEY_MFG_MOD_LOC_ID,
621  	    .sp_parse = spd_parse_raw_u8 },
622  	{ .sp_off = SPD_DDR3_MFG_YEAR, .sp_key = SPD_KEY_MFG_MOD_YEAR,
623  	    .sp_parse = spd_parse_hex_string },
624  	{ .sp_off = SPD_DDR3_MFG_WEEK, .sp_key = SPD_KEY_MFG_MOD_WEEK,
625  	    .sp_parse = spd_parse_hex_string },
626  	{ .sp_off = SPD_DDR3_MOD_SN, .sp_len = SPD_DDR3_MOD_SN_LEN,
627  	    .sp_key = SPD_KEY_MFG_MOD_SN, .sp_parse = spd_parse_hex_string },
628  	{ .sp_off = SPD_DDR3_MOD_PN, .sp_len = SPD_DDR3_MOD_PN_LEN,
629  	    .sp_key = SPD_KEY_MFG_MOD_PN, .sp_parse = spd_parse_string },
630  	/*
631  	 * In DDR3 the module revision is a two byte value that is up to the
632  	 * vendor to define. While we've seen one instance where this was split
633  	 * into a DDR4 style module and DRAM revision, we just blindly turn it
634  	 * into a hex string just because that is not a guarantee.
635  	 */
636  	{ .sp_off = SPD_DDR3_MOD_REV, .sp_len = SPD_DDR3_MOD_REV_LEN,
637  	    .sp_key = SPD_KEY_MFG_MOD_REV, .sp_parse = spd_parse_hex_string },
638  	{ .sp_off = SPD_DDR3_MFG_DRAM_ID0, .sp_len = 2,
639  	    .sp_key = SPD_KEY_MFG_DRAM_MFG_ID,
640  	    .sp_parse = spd_parse_jedec_id },
641  	{ .sp_off = SPD_DDR3_MFG_DRAM_ID0, .sp_len = 2,
642  	    .sp_key = SPD_KEY_MFG_DRAM_MFG_NAME,
643  	    .sp_parse = spd_parse_jedec_id_str },
644  };
645  
646  static void
spd_parse_ddr3_design(spd_info_t * si,uint32_t off,uint32_t len,const char * key)647  spd_parse_ddr3_design(spd_info_t *si, uint32_t off, uint32_t len,
648      const char *key)
649  {
650  	ASSERT3U(off, >=, SPD_DDR3_RDIMM_HEIGHT);
651  	return (spd_parse_design(si, off, SPD_DDR3_UDIMM_HEIGHT));
652  }
653  
654  static void
spd_parse_ddr3_edge(spd_info_t * si,uint32_t off,uint32_t len,const char * key)655  spd_parse_ddr3_edge(spd_info_t *si, uint32_t off, uint32_t len,
656      const char *key)
657  {
658  	const uint8_t data = si->si_data[off];
659  
660  	if (SPD_DDR3_UDIMM_MAP_R1(data) == SPD_DDR3_UDIMM_MAP_R1_MIRROR)
661  		spd_nvl_insert_key(si, SPD_KEY_MOD_EDGE_MIRROR);
662  }
663  
664  static const spd_parse_t spd_ddr3_udimm[] = {
665  	{ .sp_off = SPD_DDR3_UDIMM_HEIGHT, .sp_key = SPD_KEY_MOD_HEIGHT,
666  	    .sp_parse = spd_parse_height },
667  	{ .sp_off = SPD_DDR3_UDIMM_THICK, .sp_parse = spd_parse_thickness },
668  	{ .sp_off = SPD_DDR3_UDIMM_REF, .sp_parse = spd_parse_ddr3_design },
669  	{ .sp_off = SPD_DDR3_UDIMM_MAP, .sp_parse = spd_parse_ddr3_edge }
670  };
671  
672  /*
673   * This mapping is true for both the number of rows and registers.
674   */
675  static const spd_value_map_t spd_ddr3_rdimm_nrows_map[] = {
676  	{ 0, 0, true },
677  	{ 1, 1, false },
678  	{ 2, 2, false },
679  	{ 3, 4, false }
680  };
681  
682  static void
spd_parse_ddr3_rdimm_attr(spd_info_t * si,uint32_t off,uint32_t len,const char * key)683  spd_parse_ddr3_rdimm_attr(spd_info_t *si, uint32_t off, uint32_t len,
684      const char *key)
685  {
686  	const uint8_t data = si->si_data[off];
687  	const uint8_t nregs = SPD_DDR3_RDIMM_ATTR_NREGS(data);
688  	const uint8_t nrows = SPD_DDR3_RDIMM_ATTR_NROWS(data);
689  
690  	spd_insert_map(si, SPD_KEY_MOD_NROWS, nrows, spd_ddr3_rdimm_nrows_map,
691  	    ARRAY_SIZE(spd_ddr3_rdimm_nrows_map));
692  	spd_insert_map(si, SPD_KEY_MOD_NREGS, nregs, spd_ddr3_rdimm_nrows_map,
693  	    ARRAY_SIZE(spd_ddr3_rdimm_nrows_map));
694  }
695  
696  static void
spd_parse_ddr3_rdimm_hs(spd_info_t * si,uint32_t off,uint32_t len,const char * key)697  spd_parse_ddr3_rdimm_hs(spd_info_t *si, uint32_t off, uint32_t len,
698      const char *key)
699  {
700  	const uint8_t data = si->si_data[off];
701  
702  	if (SPD_DDR3_RDIMM_THERM_IMPL(data) != 0)
703  		spd_upsert_flag(si, SPD_KEY_DEVS, SPD_DEVICE_HS);
704  }
705  
706  static void
spd_parse_ddr3_rdimm_type(spd_info_t * si,uint32_t off,uint32_t len,const char * key)707  spd_parse_ddr3_rdimm_type(spd_info_t *si, uint32_t off, uint32_t len,
708      const char *key)
709  {
710  	const uint8_t data = si->si_data[off];
711  	const uint8_t type = SPD_DDR3_RDIMM_RTYPE_TYPE(data);
712  
713  	if (type != SPD_DDR3_RDIMM_RTYPE_TYPE_SSTE32882) {
714  		spd_nvl_err(si, SPD_KEY_DEV_RCD_TYPE, SPD_ERROR_NO_XLATE,
715  		    "encountered unknown register type value: 0x%x", type);
716  		return;
717  	}
718  
719  	spd_upsert_flag(si, SPD_KEY_DEVS, SPD_DEVICE_RCD);
720  	spd_nvl_insert_u32(si, SPD_KEY_DEV_RCD_TYPE, SPD_RCD_T_SSTE32882);
721  }
722  
723  /*
724   * There are different variants of these maps that RDIMMs and LRDIMMs share
725   * which are used depending on the specific register value and what it actually
726   * supports.
727   */
728  static const spd_value_map_t spd_ddr3_rdimm_lmsv_ds_map[] = {
729  	{ SPD_DDR3_RDIMM_DS_LIGHT, SPD_DRIVE_LIGHT, false },
730  	{ SPD_DDR3_RDIMM_DS_MODERATE, SPD_DRIVE_MODERATE, false },
731  	{ SPD_DDR3_RDIMM_DS_STRONG, SPD_DRIVE_STRONG, false },
732  	{ SPD_DDR3_RDIMM_DS_VERY_STRONG, SPD_DRIVE_VERY_STRONG, false },
733  };
734  
735  static const spd_value_map_t spd_ddr3_rdimm_lms_ds_map[] = {
736  	{ SPD_DDR3_RDIMM_DS_LIGHT, SPD_DRIVE_LIGHT, false },
737  	{ SPD_DDR3_RDIMM_DS_MODERATE, SPD_DRIVE_MODERATE, false },
738  	{ SPD_DDR3_RDIMM_DS_STRONG, SPD_DRIVE_STRONG, false },
739  };
740  
741  static const spd_value_map_t spd_ddr3_rdimm_lm_ds_map[] = {
742  	{ SPD_DDR3_RDIMM_DS_LIGHT, SPD_DRIVE_LIGHT, false },
743  	{ SPD_DDR3_RDIMM_DS_MODERATE, SPD_DRIVE_MODERATE, false },
744  };
745  
746  static void
spd_parse_ddr3_rdimm_cads(spd_info_t * si,uint32_t off,uint32_t len,const char * key)747  spd_parse_ddr3_rdimm_cads(spd_info_t *si, uint32_t off, uint32_t len,
748      const char *key)
749  {
750  	const uint8_t data = si->si_data[off];
751  	const uint8_t caa = SPD_DDR3_RDIMM_CADS_CAA(data);
752  	const uint8_t cab = SPD_DDR3_RDIMM_CADS_CAB(data);
753  
754  	spd_insert_map(si, SPD_KEY_DDR3_RCD_DS_CAA, caa,
755  	    spd_ddr3_rdimm_lms_ds_map, ARRAY_SIZE(spd_ddr3_rdimm_lms_ds_map));
756  	spd_insert_map(si, SPD_KEY_DDR3_RCD_DS_CAB, cab,
757  	    spd_ddr3_rdimm_lms_ds_map, ARRAY_SIZE(spd_ddr3_rdimm_lms_ds_map));
758  }
759  
760  static void
spd_parse_ddr3_rdimm_ccds(spd_info_t * si,uint32_t off,uint32_t len,const char * key)761  spd_parse_ddr3_rdimm_ccds(spd_info_t *si, uint32_t off, uint32_t len,
762      const char *key)
763  {
764  	const uint8_t data = si->si_data[off];
765  	const uint8_t ctla = SPD_DDR3_RDIMM_CCDS_CTLA(data);
766  	const uint8_t ctlb = SPD_DDR3_RDIMM_CCDS_CTLB(data);
767  	const uint8_t y1 = SPD_DDR3_RDIMM_CCDS_CLK1(data);
768  	const uint8_t y0 = SPD_DDR3_RDIMM_CCDS_CLK0(data);
769  
770  
771  	spd_insert_map(si, SPD_KEY_DDR3_RCD_DS_CTLA, ctla,
772  	    spd_ddr3_rdimm_lm_ds_map, ARRAY_SIZE(spd_ddr3_rdimm_lm_ds_map));
773  	spd_insert_map(si, SPD_KEY_DDR3_RCD_DS_CTLB, ctlb,
774  	    spd_ddr3_rdimm_lm_ds_map, ARRAY_SIZE(spd_ddr3_rdimm_lm_ds_map));
775  	spd_insert_map(si, SPD_KEY_DDR3_RCD_DS_Y0, y0,
776  	    spd_ddr3_rdimm_lms_ds_map, ARRAY_SIZE(spd_ddr3_rdimm_lms_ds_map));
777  	spd_insert_map(si, SPD_KEY_DDR3_RCD_DS_Y1, y1,
778  	    spd_ddr3_rdimm_lms_ds_map, ARRAY_SIZE(spd_ddr3_rdimm_lms_ds_map));
779  }
780  
781  static const spd_parse_t spd_ddr3_rdimm[] = {
782  	{ .sp_off = SPD_DDR3_RDIMM_HEIGHT, .sp_key = SPD_KEY_MOD_HEIGHT,
783  	    .sp_parse = spd_parse_height },
784  	{ .sp_off = SPD_DDR3_RDIMM_THICK, .sp_parse = spd_parse_thickness },
785  	{ .sp_off = SPD_DDR3_RDIMM_REF, .sp_parse = spd_parse_ddr3_design },
786  	{ .sp_off = SPD_DDR3_RDIMM_ATTR,
787  	    .sp_parse = spd_parse_ddr3_rdimm_attr },
788  	{ .sp_off = SPD_DDR3_RDIMM_THERM, .sp_parse = spd_parse_ddr3_rdimm_hs },
789  	{ .sp_off = SPD_DDR3_RDIMM_REG_MFG_ID0, .sp_len = 2,
790  	    .sp_key = SPD_KEY_DEV_RCD_MFG,
791  	    .sp_parse = spd_parse_jedec_id },
792  	{ .sp_off = SPD_DDR3_RDIMM_REG_MFG_ID0, .sp_len = 2,
793  	    .sp_key = SPD_KEY_DEV_RCD_MFG_NAME,
794  	    .sp_parse = spd_parse_jedec_id_str },
795  	{ .sp_off = SPD_DDR3_RDIMM_REV, .sp_key = SPD_KEY_DEV_RCD_REV,
796  	    .sp_parse = spd_parse_dram_step },
797  	{ .sp_off = SPD_DDR3_RDIMM_RTYPE,
798  	    .sp_parse = spd_parse_ddr3_rdimm_type },
799  	{ .sp_off = SPD_DDR3_RDIMM_CADS,
800  	    .sp_parse = spd_parse_ddr3_rdimm_cads },
801  	{ .sp_off = SPD_DDR3_RDIMM_CCDS,
802  	    .sp_parse = spd_parse_ddr3_rdimm_ccds },
803  };
804  
805  static const spd_parse_t spd_ddr3_cdimm[] = {
806  	{ .sp_off = SPD_DDR3_CDIMM_HEIGHT, .sp_key = SPD_KEY_MOD_HEIGHT,
807  	    .sp_parse = spd_parse_height },
808  	{ .sp_off = SPD_DDR3_CDIMM_THICK, .sp_parse = spd_parse_thickness },
809  	{ .sp_off = SPD_DDR3_CDIMM_REF, .sp_parse = spd_parse_ddr3_design },
810  };
811  
812  static const spd_value_map_t spd_ddr3_lrdimm_nrows_map[] = {
813  	{ 0, 0, true },
814  	{ 1, 1, false },
815  	{ 2, 2, false },
816  };
817  
818  static const spd_value_map_t spd_ddr3_lrdimm_orient_map[] = {
819  	{ SPD_DDR3_LRDIMM_ATTR_ORIENT_VERT, SPD_ORNT_VERTICAL, false },
820  	{ SPD_DDR3_LRDIMM_ATTR_ORIENT_HORIZ, SPD_ORNT_HORIZONTAL, false }
821  };
822  
823  static void
spd_parse_ddr3_lrdimm_attr(spd_info_t * si,uint32_t off,uint32_t len,const char * key)824  spd_parse_ddr3_lrdimm_attr(spd_info_t *si, uint32_t off, uint32_t len,
825      const char *key)
826  {
827  	const uint8_t data = si->si_data[off];
828  	const uint8_t mirror = SPD_DDR3_LRDIMM_ATTR_MIR(data);
829  	const uint8_t nrows = SPD_DDR3_LRDIMM_ATTR_NROWS(data);
830  	const uint8_t orient = SPD_DDR3_LRDIMM_ATTR_ORIENT(data);
831  
832  	if (mirror == SPD_DDR3_LRDIMM_ATTR_MIR_ODD_ARE)
833  		spd_nvl_insert_key(si, SPD_KEY_MOD_EDGE_MIRROR);
834  
835  	spd_insert_map(si, SPD_KEY_MOD_NROWS, nrows, spd_ddr3_lrdimm_nrows_map,
836  	    ARRAY_SIZE(spd_ddr3_lrdimm_nrows_map));
837  	spd_insert_map(si, SPD_KEY_DDR3_MB_ORIENT, orient,
838  	    spd_ddr3_lrdimm_orient_map, ARRAY_SIZE(spd_ddr3_lrdimm_orient_map));
839  
840  	if (SPD_DDR3_LRDIMM_ATTR_HS(data) != 0)
841  		spd_upsert_flag(si, SPD_KEY_DEVS, SPD_DEVICE_HS);
842  }
843  
844  static void
spd_parse_ddr3_lrdimm_mb(spd_info_t * si,uint32_t off,uint32_t len,const char * key)845  spd_parse_ddr3_lrdimm_mb(spd_info_t *si, uint32_t off, uint32_t len,
846      const char *key)
847  {
848  	ASSERT3U(len, ==, 2);
849  
850  	/*
851  	 * Use this chance to set the DDR3 MB device as present and its type.
852  	 */
853  	spd_upsert_flag(si, SPD_KEY_DEVS, SPD_DEVICE_DB);
854  	spd_nvl_insert_u32(si, SPD_KEY_DEV_DB_TYPE, SPD_DB_T_DDR3MB);
855  	spd_parse_jedec_id(si, off, 2, SPD_KEY_DEV_DB_MFG);
856  	spd_parse_jedec_id_str(si, off, 2, SPD_KEY_DEV_DB_MFG_NAME);
857  }
858  
859  static void
spd_parse_ddr3_lrdimm_tcds(spd_info_t * si,uint32_t off,uint32_t len,const char * key)860  spd_parse_ddr3_lrdimm_tcds(spd_info_t *si, uint32_t off, uint32_t len,
861      const char *key)
862  {
863  	const uint8_t data = si->si_data[off];
864  	const uint8_t ca = SPD_DDR3_LRDIMM_TCDS_AC(data);
865  	const uint8_t cs = SPD_DDR3_LRDIMM_TCDS_QxCS(data);
866  
867  	spd_insert_map(si, SPD_KEY_DDR3_MB_DS_CA, ca,
868  	    spd_ddr3_rdimm_lmsv_ds_map, ARRAY_SIZE(spd_ddr3_rdimm_lmsv_ds_map));
869  	spd_insert_map(si, SPD_KEY_DDR3_MB_DS_CS, cs,
870  	    spd_ddr3_rdimm_lms_ds_map, ARRAY_SIZE(spd_ddr3_rdimm_lms_ds_map));
871  }
872  
873  static void
spd_parse_ddr3_lrdimm_ckds(spd_info_t * si,uint32_t off,uint32_t len,const char * key)874  spd_parse_ddr3_lrdimm_ckds(spd_info_t *si, uint32_t off, uint32_t len,
875      const char *key)
876  {
877  	const uint8_t data = si->si_data[off];
878  	const uint8_t odt = SPD_DDR3_LRDIMM_CKDS_ODT(data);
879  	const uint8_t cke = SPD_DDR3_LRDIMM_CKDS_CKE(data);
880  	const uint8_t y1 = SPD_DDR3_LRDIMM_CKDS_Y1Y3(data);
881  	const uint8_t y0 = SPD_DDR3_LRDIMM_CKDS_Y0Y2(data);
882  
883  	spd_insert_map(si, SPD_KEY_DDR3_MB_DS_ODT, odt,
884  	    spd_ddr3_rdimm_lms_ds_map, ARRAY_SIZE(spd_ddr3_rdimm_lms_ds_map));
885  	spd_insert_map(si, SPD_KEY_DDR3_MB_DS_CKE, cke,
886  	    spd_ddr3_rdimm_lms_ds_map, ARRAY_SIZE(spd_ddr3_rdimm_lms_ds_map));
887  	spd_insert_map(si, SPD_KEY_DDR3_MB_DS_Y1, y1,
888  	    spd_ddr3_rdimm_lms_ds_map, ARRAY_SIZE(spd_ddr3_rdimm_lms_ds_map));
889  	spd_insert_map(si, SPD_KEY_DDR3_MB_DS_Y0, y0,
890  	    spd_ddr3_rdimm_lms_ds_map, ARRAY_SIZE(spd_ddr3_rdimm_lms_ds_map));
891  }
892  
893  static void
spd_parse_ddr3_lrdimm_ext_delay(spd_info_t * si,uint32_t off,uint32_t len,const char * key)894  spd_parse_ddr3_lrdimm_ext_delay(spd_info_t *si, uint32_t off, uint32_t len,
895      const char *key)
896  {
897  	const uint8_t data = si->si_data[off];
898  	const uint8_t y = SPD_DDR3_LRDIMM_EXTD_Y(data);
899  	const uint8_t cs = SPD_DDR3_LRDIMM_EXTD_CS(data);
900  	const uint8_t odt = SPD_DDR3_LRDIMM_EXTD_ODT(data);
901  	const uint8_t cke = SPD_DDR3_LRDIMM_EXTD_CKE(data);
902  
903  	/*
904  	 * A value of 0 is equal to no delay, otherwise these are a measure of
905  	 * x/128 * tCK values and we store x in the nvlist.
906  	 */
907  	if (y != 0)
908  		spd_nvl_insert_u32(si, SPD_KEY_DDR3_MB_EXTD_Y, y);
909  	if (cs != 0)
910  		spd_nvl_insert_u32(si, SPD_KEY_DDR3_MB_EXTD_CS, cs);
911  	if (odt != 0)
912  		spd_nvl_insert_u32(si, SPD_KEY_DDR3_MB_EXTD_ODT, odt);
913  	if (cke != 0)
914  		spd_nvl_insert_u32(si, SPD_KEY_DDR3_MB_EXTD_CKE, cke);
915  }
916  
917  /*
918   * Each additive delay nibble contains an enable bit. However, the enable bit
919   * for Y clocks is actually bit 0 in SPD_DDR3_LRDIMM_TCDS.
920   */
921  static void
spd_parse_ddr3_lrdimm_add_delay_csy(spd_info_t * si,uint32_t off,uint32_t len,const char * key)922  spd_parse_ddr3_lrdimm_add_delay_csy(spd_info_t *si, uint32_t off, uint32_t len,
923      const char *key)
924  {
925  	const uint8_t data = si->si_data[off];
926  	const uint8_t y = SPD_DDR3_LRDIMM_ADDD_CSY_Y(data);
927  	const uint8_t cs = SPD_DDR3_LRDIMM_ADDD_CSY_CS(data);
928  	ASSERT3U(off, >, SPD_DDR3_LRDIMM_TCDS);
929  	const uint8_t yen = si->si_data[SPD_DDR3_LRDIMM_TCDS];
930  
931  	if (SPD_DDR3_LRDIMM_TCDS_ACPL(yen) != SPD_DDR3_LRDIMM_TCDS_ACPL_STD) {
932  		const uint8_t val = SPD_DDR3_LRDIMM_ADD_BASE - y;
933  		spd_nvl_insert_u32(si, SPD_KEY_DDR3_MB_ADDD_Y, val);
934  	}
935  
936  	if (SPD_DDR3_LRDIMM_ADDD_CSY_CS_EN(data) != 0) {
937  		const uint8_t val = SPD_DDR3_LRDIMM_ADD_BASE - cs;
938  		spd_nvl_insert_u32(si, SPD_KEY_DDR3_MB_ADDD_CS, val);
939  	}
940  }
941  
942  static void
spd_parse_ddr3_lrdimm_add_delay_odt(spd_info_t * si,uint32_t off,uint32_t len,const char * key)943  spd_parse_ddr3_lrdimm_add_delay_odt(spd_info_t *si, uint32_t off, uint32_t len,
944      const char *key)
945  {
946  	const uint8_t data = si->si_data[off];
947  	const uint8_t cke = SPD_DDR3_LRDIMM_ADDD_ODT_CKE(data);
948  	const uint8_t odt = SPD_DDR3_LRDIMM_ADDD_ODT_ODT(data);
949  
950  	if (SPD_DDR3_LRDIMM_ADDD_ODT_CKE_EN(data) != 0) {
951  		const uint8_t val = SPD_DDR3_LRDIMM_ADD_BASE - cke;
952  		spd_nvl_insert_u32(si, SPD_KEY_DDR3_MB_ADDD_CKE, val);
953  	}
954  
955  	if (SPD_DDR3_LRDIMM_ADDD_ODT_ODT_EN(data) != 0) {
956  		const uint8_t val = SPD_DDR3_LRDIMM_ADD_BASE - odt;
957  		spd_nvl_insert_u32(si, SPD_KEY_DDR3_MB_ADDD_ODT, val);
958  	}
959  }
960  
961  static const spd_value_map_t spd_ddr3_mdq_ds_map[] = {
962  	{ SPD_DDR3_LRDIMM_MDQ_DS_40R, 40, false },
963  	{ SPD_DDR3_LRDIMM_MDQ_DS_34R, 34, false },
964  	{ SPD_DDR3_LRDIMM_MDQ_DS_48R, 48, false },
965  	{ SPD_DDR3_LRDIMM_MDQ_DS_27R, 27, false },
966  	{ SPD_DDR3_LRDIMM_MDQ_DS_20R, 20, false }
967  };
968  
969  static const spd_value_map_t spd_ddr3_odt_map[] = {
970  	{ SPD_DDR3_LRDIMM_MDQ_ODT_DIS, SPD_TERM_DISABLED, false },
971  	{ SPD_DDR3_LRDIMM_MDQ_ODT_60R, 60, false },
972  	{ SPD_DDR3_LRDIMM_MDQ_ODT_120R, 120, false },
973  	{ SPD_DDR3_LRDIMM_MDQ_ODT_40R, 40, false },
974  	{ SPD_DDR3_LRDIMM_MDQ_ODT_30R, 30, false },
975  	{ SPD_DDR3_LRDIMM_MDQ_ODT_240R, 240, false },
976  	{ SPD_DDR3_LRDIMM_MDQ_ODT_80R, 80, false },
977  };
978  
979  static void
spd_parse_ddr3_lrdimm_mdq(spd_info_t * si,uint32_t off,uint32_t len,const char * key)980  spd_parse_ddr3_lrdimm_mdq(spd_info_t *si, uint32_t off, uint32_t len,
981      const char *key)
982  {
983  	const uint8_t d800 = si->si_data[off];
984  	const uint8_t d1333 = si->si_data[off + SPD_DDR3_LRDIMM_STRIDE];
985  	const uint8_t d1866 = si->si_data[off + SPD_DDR3_LRDIMM_STRIDE * 2];
986  	const uint8_t odt[3] = { SPD_DDR3_LRDIMM_MDQ_ODT(d800),
987  	    SPD_DDR3_LRDIMM_MDQ_ODT(d1333), SPD_DDR3_LRDIMM_MDQ_ODT(d1866) };
988  	const uint8_t ds[3] = { SPD_DDR3_LRDIMM_MDQ_DS(d800),
989  	    SPD_DDR3_LRDIMM_MDQ_DS(d1333), SPD_DDR3_LRDIMM_MDQ_DS(d1866) };
990  
991  	spd_insert_map_array(si, SPD_KEY_DDR3_MDQ_ODT, odt, ARRAY_SIZE(odt),
992  	    spd_ddr3_odt_map, ARRAY_SIZE(spd_ddr3_odt_map));
993  	spd_insert_map_array(si, SPD_KEY_DDR3_MDQ_DS, ds, ARRAY_SIZE(ds),
994  	    spd_ddr3_mdq_ds_map, ARRAY_SIZE(spd_ddr3_mdq_ds_map));
995  }
996  
997  static void
spd_parse_ddr3_lrdimm_odt_common(spd_info_t * si,uint32_t off,const char * r0_odt0_rd_key,const char * r0_odt1_rd_key,const char * r1_odt0_rd_key,const char * r1_odt1_rd_key,const char * r0_odt0_wr_key,const char * r0_odt1_wr_key,const char * r1_odt0_wr_key,const char * r1_odt1_wr_key)998  spd_parse_ddr3_lrdimm_odt_common(spd_info_t *si, uint32_t off,
999      const char *r0_odt0_rd_key, const char *r0_odt1_rd_key,
1000      const char *r1_odt0_rd_key, const char *r1_odt1_rd_key,
1001      const char *r0_odt0_wr_key, const char *r0_odt1_wr_key,
1002      const char *r1_odt0_wr_key, const char *r1_odt1_wr_key)
1003  {
1004  	const uint8_t d800 = si->si_data[off];
1005  	const uint8_t d1333 = si->si_data[off + SPD_DDR3_LRDIMM_STRIDE];
1006  	const uint8_t d1866 = si->si_data[off + SPD_DDR3_LRDIMM_STRIDE * 2];
1007  	boolean_t r0_odt0_rd[3] = { SPD_DDR3_LRDIMM_ODT_R0_ODT0_RD(d800),
1008  	    SPD_DDR3_LRDIMM_ODT_R0_ODT0_RD(d1333),
1009  	    SPD_DDR3_LRDIMM_ODT_R0_ODT0_RD(d1866) };
1010  	boolean_t r0_odt1_rd[3] = { SPD_DDR3_LRDIMM_ODT_R0_ODT1_RD(d800),
1011  	    SPD_DDR3_LRDIMM_ODT_R0_ODT1_RD(d1333),
1012  	    SPD_DDR3_LRDIMM_ODT_R0_ODT1_RD(d1866) };
1013  	boolean_t r1_odt0_rd[3] = { SPD_DDR3_LRDIMM_ODT_R1_ODT0_RD(d800),
1014  	    SPD_DDR3_LRDIMM_ODT_R1_ODT0_RD(d1333),
1015  	    SPD_DDR3_LRDIMM_ODT_R1_ODT0_RD(d1866) };
1016  	boolean_t r1_odt1_rd[3] = { SPD_DDR3_LRDIMM_ODT_R1_ODT1_RD(d800),
1017  	    SPD_DDR3_LRDIMM_ODT_R1_ODT1_RD(d1333),
1018  	    SPD_DDR3_LRDIMM_ODT_R1_ODT1_RD(d1866) };
1019  	boolean_t r0_odt0_wr[3] = { SPD_DDR3_LRDIMM_ODT_R0_ODT0_WR(d800),
1020  	    SPD_DDR3_LRDIMM_ODT_R0_ODT0_WR(d1333),
1021  	    SPD_DDR3_LRDIMM_ODT_R0_ODT0_WR(d1866) };
1022  	boolean_t r0_odt1_wr[3] = { SPD_DDR3_LRDIMM_ODT_R0_ODT1_WR(d800),
1023  	    SPD_DDR3_LRDIMM_ODT_R0_ODT1_WR(d1333),
1024  	    SPD_DDR3_LRDIMM_ODT_R0_ODT1_WR(d1866) };
1025  	boolean_t r1_odt0_wr[3] = { SPD_DDR3_LRDIMM_ODT_R1_ODT0_WR(d800),
1026  	    SPD_DDR3_LRDIMM_ODT_R1_ODT0_WR(d1333),
1027  	    SPD_DDR3_LRDIMM_ODT_R1_ODT0_WR(d1866) };
1028  	boolean_t r1_odt1_wr[3] = { SPD_DDR3_LRDIMM_ODT_R1_ODT1_WR(d800),
1029  	    SPD_DDR3_LRDIMM_ODT_R1_ODT1_WR(d1333),
1030  	    SPD_DDR3_LRDIMM_ODT_R1_ODT1_WR(d1866) };
1031  
1032  	spd_nvl_insert_boolean_array(si, r0_odt0_rd_key, r0_odt0_rd,
1033  	    ARRAY_SIZE(r0_odt0_rd));
1034  	spd_nvl_insert_boolean_array(si, r0_odt1_rd_key, r0_odt1_rd,
1035  	    ARRAY_SIZE(r0_odt1_rd));
1036  	spd_nvl_insert_boolean_array(si, r1_odt0_rd_key, r1_odt0_rd,
1037  	    ARRAY_SIZE(r1_odt0_rd));
1038  	spd_nvl_insert_boolean_array(si, r1_odt1_rd_key, r1_odt1_rd,
1039  	    ARRAY_SIZE(r1_odt1_rd));
1040  	spd_nvl_insert_boolean_array(si, r0_odt0_wr_key, r0_odt0_wr,
1041  	    ARRAY_SIZE(r0_odt0_wr));
1042  	spd_nvl_insert_boolean_array(si, r0_odt1_wr_key, r0_odt1_wr,
1043  	    ARRAY_SIZE(r0_odt1_wr));
1044  	spd_nvl_insert_boolean_array(si, r1_odt0_wr_key, r1_odt0_wr,
1045  	    ARRAY_SIZE(r1_odt0_wr));
1046  	spd_nvl_insert_boolean_array(si, r1_odt1_wr_key, r1_odt1_wr,
1047  	    ARRAY_SIZE(r1_odt1_wr));
1048  }
1049  
1050  static void
spd_parse_ddr3_lrdimm_odt_r0(spd_info_t * si,uint32_t off,uint32_t len,const char * key)1051  spd_parse_ddr3_lrdimm_odt_r0(spd_info_t *si, uint32_t off, uint32_t len,
1052      const char *key)
1053  {
1054  	spd_parse_ddr3_lrdimm_odt_common(si, off,
1055  	    SPD_KEY_DDR3_MB_R0_ODT0_RD, SPD_KEY_DDR3_MB_R0_ODT1_RD,
1056  	    SPD_KEY_DDR3_MB_R1_ODT0_RD, SPD_KEY_DDR3_MB_R1_ODT1_RD,
1057  	    SPD_KEY_DDR3_MB_R0_ODT0_WR, SPD_KEY_DDR3_MB_R0_ODT1_WR,
1058  	    SPD_KEY_DDR3_MB_R1_ODT0_WR, SPD_KEY_DDR3_MB_R1_ODT1_WR);
1059  }
1060  
1061  static void
spd_parse_ddr3_lrdimm_odt_r2(spd_info_t * si,uint32_t off,uint32_t len,const char * key)1062  spd_parse_ddr3_lrdimm_odt_r2(spd_info_t *si, uint32_t off, uint32_t len,
1063      const char *key)
1064  {
1065  	spd_parse_ddr3_lrdimm_odt_common(si, off,
1066  	    SPD_KEY_DDR3_MB_R2_ODT0_RD, SPD_KEY_DDR3_MB_R2_ODT1_RD,
1067  	    SPD_KEY_DDR3_MB_R3_ODT0_RD, SPD_KEY_DDR3_MB_R3_ODT1_RD,
1068  	    SPD_KEY_DDR3_MB_R2_ODT0_WR, SPD_KEY_DDR3_MB_R2_ODT1_WR,
1069  	    SPD_KEY_DDR3_MB_R3_ODT0_WR, SPD_KEY_DDR3_MB_R3_ODT1_WR);
1070  
1071  }
1072  
1073  static void
spd_parse_ddr3_lrdimm_odt_r4(spd_info_t * si,uint32_t off,uint32_t len,const char * key)1074  spd_parse_ddr3_lrdimm_odt_r4(spd_info_t *si, uint32_t off, uint32_t len,
1075      const char *key)
1076  {
1077  	spd_parse_ddr3_lrdimm_odt_common(si, off,
1078  	    SPD_KEY_DDR3_MB_R4_ODT0_RD, SPD_KEY_DDR3_MB_R4_ODT1_RD,
1079  	    SPD_KEY_DDR3_MB_R5_ODT0_RD, SPD_KEY_DDR3_MB_R5_ODT1_RD,
1080  	    SPD_KEY_DDR3_MB_R4_ODT0_WR, SPD_KEY_DDR3_MB_R4_ODT1_WR,
1081  	    SPD_KEY_DDR3_MB_R5_ODT0_WR, SPD_KEY_DDR3_MB_R5_ODT1_WR);
1082  
1083  }
1084  
1085  static void
spd_parse_ddr3_lrdimm_odt_r6(spd_info_t * si,uint32_t off,uint32_t len,const char * key)1086  spd_parse_ddr3_lrdimm_odt_r6(spd_info_t *si, uint32_t off, uint32_t len,
1087      const char *key)
1088  {
1089  	spd_parse_ddr3_lrdimm_odt_common(si, off,
1090  	    SPD_KEY_DDR3_MB_R6_ODT0_RD, SPD_KEY_DDR3_MB_R6_ODT1_RD,
1091  	    SPD_KEY_DDR3_MB_R7_ODT0_RD, SPD_KEY_DDR3_MB_R7_ODT1_RD,
1092  	    SPD_KEY_DDR3_MB_R6_ODT0_WR, SPD_KEY_DDR3_MB_R6_ODT1_WR,
1093  	    SPD_KEY_DDR3_MB_R7_ODT0_WR, SPD_KEY_DDR3_MB_R7_ODT1_WR);
1094  }
1095  
1096  static const spd_value_map_t spd_ddr3_rtt_wr_map[] = {
1097  	{ SPD_DDR3_LRDIMM_RTT_WR_DIS, SPD_TERM_DISABLED, false },
1098  	{ SPD_DDR3_LRDIMM_RTT_WR_60R, 60, false },
1099  	{ SPD_DDR3_LRDIMM_RTT_WR_120R, 120, false },
1100  };
1101  
1102  static const spd_value_map_t spd_ddr3_rtt_nom_map[] = {
1103  	{ SPD_DDR3_LRDIMM_RTT_NOM_DIS, SPD_TERM_DISABLED, false },
1104  	{ SPD_DDR3_LRDIMM_RTT_NOM_60R, 60, false },
1105  	{ SPD_DDR3_LRDIMM_RTT_NOM_120R, 120, false },
1106  	{ SPD_DDR3_LRDIMM_RTT_NOM_40R, 40, false },
1107  	{ SPD_DDR3_LRDIMM_RTT_NOM_20R, 20, false },
1108  	{ SPD_DDR3_LRDIMM_RTT_NOM_30R, 30, false },
1109  };
1110  
1111  static const spd_value_map_t spd_ddr3_dram_imp_map[] = {
1112  	{ SPD_DDR3_LRDIMM_RTT_IMP_40R, 40, false },
1113  	{ SPD_DDR3_LRDIMM_RTT_IMP_34R, 34, false }
1114  };
1115  
1116  static void
spd_parse_ddr3_lrdimm_rtt(spd_info_t * si,uint32_t off,uint32_t len,const char * key)1117  spd_parse_ddr3_lrdimm_rtt(spd_info_t *si, uint32_t off, uint32_t len,
1118      const char *key)
1119  {
1120  	const uint8_t d800 = si->si_data[off];
1121  	const uint8_t d1333 = si->si_data[off + SPD_DDR3_LRDIMM_STRIDE];
1122  	const uint8_t d1866 = si->si_data[off + SPD_DDR3_LRDIMM_STRIDE * 2];
1123  	const uint8_t imp[3] = { SPD_DDR3_LRDIMM_RTT_IMP(d800),
1124  	    SPD_DDR3_LRDIMM_RTT_IMP(d1333), SPD_DDR3_LRDIMM_RTT_IMP(d1866) };
1125  	const uint8_t nom[3] = { SPD_DDR3_LRDIMM_RTT_NOM(d800),
1126  	    SPD_DDR3_LRDIMM_RTT_NOM(d1333), SPD_DDR3_LRDIMM_RTT_NOM(d1866) };
1127  	const uint8_t wr[3] = { SPD_DDR3_LRDIMM_RTT_WR(d800),
1128  	    SPD_DDR3_LRDIMM_RTT_WR(d1333), SPD_DDR3_LRDIMM_RTT_WR(d1866) };
1129  
1130  	spd_insert_map_array(si, SPD_KEY_DDR3_DRAM_DS, imp, ARRAY_SIZE(imp),
1131  	    spd_ddr3_dram_imp_map, ARRAY_SIZE(spd_ddr3_dram_imp_map));
1132  	spd_insert_map_array(si, SPD_KEY_DDR3_RTT_NOM, nom, ARRAY_SIZE(nom),
1133  	    spd_ddr3_rtt_nom_map, ARRAY_SIZE(spd_ddr3_rtt_nom_map));
1134  	spd_insert_map_array(si, SPD_KEY_DDR3_RTT_WRT, wr, ARRAY_SIZE(wr),
1135  	    spd_ddr3_rtt_wr_map, ARRAY_SIZE(spd_ddr3_rtt_wr_map));
1136  }
1137  
1138  /*
1139   * Parse the delay that is spread out amongst three registers, each of which are
1140   * two apart. These are for 1.5V, 1.35, and 1.25V each.
1141   */
1142  static void
spd_parse_ddr3_lrdimm_mod_delay(spd_info_t * si,uint32_t off,uint32_t len,const char * key)1143  spd_parse_ddr3_lrdimm_mod_delay(spd_info_t *si, uint32_t off, uint32_t len,
1144      const char *key)
1145  {
1146  	const uint8_t d1v5 = si->si_data[off];
1147  	const uint8_t d1v35 = si->si_data[off + 2];
1148  	const uint8_t d1v25 = si->si_data[off + 4];
1149  	uint64_t delay[3] = { d1v25 * SPD_DDR3_MTB_PS, d1v35 * SPD_DDR3_MTB_PS,
1150  	    d1v5 * SPD_DDR3_MTB_PS };
1151  
1152  	spd_nvl_insert_u64_array(si, key, delay, ARRAY_SIZE(delay));
1153  }
1154  
1155  static const spd_parse_t spd_ddr3_lrdimm[] = {
1156  	{ .sp_off = SPD_DDR3_LRDIMM_HEIGHT, .sp_key = SPD_KEY_MOD_HEIGHT,
1157  	    .sp_parse = spd_parse_height },
1158  	{ .sp_off = SPD_DDR3_LRDIMM_THICK, .sp_parse = spd_parse_thickness },
1159  	{ .sp_off = SPD_DDR3_LRDIMM_REF, .sp_parse = spd_parse_ddr3_design },
1160  	{ .sp_off = SPD_DDR3_LRDIMM_ATTR,
1161  	    .sp_parse = spd_parse_ddr3_lrdimm_attr },
1162  	{ .sp_off = SPD_DDR3_LRDIMM_MB_REV, .sp_key = SPD_KEY_DEV_DB_REV,
1163  	    .sp_parse = spd_parse_dram_step },
1164  	{ .sp_off = SPD_DDR3_LRDIMM_MB_MFG_ID0, .sp_len = 2,
1165  	    .sp_parse = spd_parse_ddr3_lrdimm_mb },
1166  	{ .sp_off = SPD_DDR3_LRDIMM_TCDS,
1167  	    .sp_parse = spd_parse_ddr3_lrdimm_tcds },
1168  	{ .sp_off = SPD_DDR3_LRDIMM_CKDS,
1169  	    .sp_parse = spd_parse_ddr3_lrdimm_ckds },
1170  	{ .sp_off = SPD_DDR3_LRDIMM_EXTD,
1171  	    .sp_parse = spd_parse_ddr3_lrdimm_ext_delay },
1172  	{ .sp_off = SPD_DDR3_LRDIMM_ADDD_CSY,
1173  	    .sp_parse = spd_parse_ddr3_lrdimm_add_delay_csy },
1174  	{ .sp_off = SPD_DDR3_LRDIMM_ADDD_ODT,
1175  	    .sp_parse = spd_parse_ddr3_lrdimm_add_delay_odt },
1176  	{ .sp_off = SPD_DDR3_LRDIMM_MDQ_800,
1177  	    .sp_len = SPD_DDR3_LRDIMM_MDQ_1866 - SPD_DDR3_LRDIMM_MDQ_800 + 1,
1178  	    .sp_parse = spd_parse_ddr3_lrdimm_mdq },
1179  	{ .sp_off = SPD_DDR3_LRDIMM_ODT_R0_800,
1180  	    .sp_len = SPD_DDR3_LRDIMM_ODT_R0_1866 -
1181  	    SPD_DDR3_LRDIMM_ODT_R0_800 + 1,
1182  	    .sp_parse = spd_parse_ddr3_lrdimm_odt_r0 },
1183  	{ .sp_off = SPD_DDR3_LRDIMM_ODT_R2_800,
1184  	    .sp_len = SPD_DDR3_LRDIMM_ODT_R2_1866 -
1185  	    SPD_DDR3_LRDIMM_ODT_R2_800 + 1,
1186  	    .sp_parse = spd_parse_ddr3_lrdimm_odt_r2 },
1187  	{ .sp_off = SPD_DDR3_LRDIMM_ODT_R4_800,
1188  	    .sp_len = SPD_DDR3_LRDIMM_ODT_R4_1866 -
1189  	    SPD_DDR3_LRDIMM_ODT_R4_800 + 1,
1190  	    .sp_parse = spd_parse_ddr3_lrdimm_odt_r4 },
1191  	{ .sp_off = SPD_DDR3_LRDIMM_ODT_R6_800,
1192  	    .sp_len = SPD_DDR3_LRDIMM_ODT_R6_1866 -
1193  	    SPD_DDR3_LRDIMM_ODT_R6_800 + 1,
1194  	    .sp_parse = spd_parse_ddr3_lrdimm_odt_r6 },
1195  	{ .sp_off = SPD_DDR3_LRDIMM_RTT_800,
1196  	    .sp_len = SPD_DDR3_LRDIMM_RTT_1866 - SPD_DDR3_LRDIMM_RTT_800 + 1,
1197  	    .sp_parse = spd_parse_ddr3_lrdimm_rtt },
1198  	{ .sp_off = SPD_DDR3_LRDIMM_MIN_DELAY_1V5,
1199  	    .sp_key = SPD_KEY_DDR3_MOD_MIN_DELAY,
1200  	    .sp_len = SPD_DDR3_LRDIMM_MIN_DELAY_1V25 -
1201  	    SPD_DDR3_LRDIMM_MIN_DELAY_1V5 + 1,
1202  	    .sp_parse = spd_parse_ddr3_lrdimm_mod_delay },
1203  	{ .sp_off = SPD_DDR3_LRDIMM_MAX_DELAY_1V5,
1204  	    .sp_key = SPD_KEY_DDR3_MOD_MAX_DELAY,
1205  	    .sp_len = SPD_DDR3_LRDIMM_MAX_DELAY_1V25 -
1206  	    SPD_DDR3_LRDIMM_MAX_DELAY_1V5 + 1,
1207  	    .sp_parse = spd_parse_ddr3_lrdimm_mod_delay },
1208  	{ .sp_off = SPD_DDR3_LRDIMM_PERS, .sp_key = SPD_KEY_DDR3_MB_PERS,
1209  	    .sp_len = SPD_DDR3_LRDIMM_PERS_NBYTES,
1210  	    .sp_parse = spd_parse_u8_array }
1211  };
1212  
1213  static void
spd_parse_ddr3_mod_specific(spd_info_t * si)1214  spd_parse_ddr3_mod_specific(spd_info_t *si)
1215  {
1216  	uint32_t type;
1217  
1218  	if (nvlist_lookup_uint32(si->si_nvl, SPD_KEY_MOD_TYPE, &type) != 0)
1219  		return;
1220  
1221  	switch (type) {
1222  	case SPD_MOD_TYPE_UDIMM:
1223  	case SPD_MOD_TYPE_SODIMM:
1224  	case SPD_MOD_TYPE_MICRO_DIMM:
1225  	case SPD_MOD_TYPE_MINI_UDIMM:
1226  	case SPD_MOD_TYPE_16b_SO_DIMM:
1227  	case SPD_MOD_TYPE_32b_SO_DIMM:
1228  	case SPD_MOD_TYPE_72b_SO_UDIMM:
1229  		spd_parse(si, spd_ddr3_udimm, ARRAY_SIZE(spd_ddr3_udimm));
1230  		break;
1231  	case SPD_MOD_TYPE_RDIMM:
1232  	case SPD_MOD_TYPE_MINI_RDIMM:
1233  	case SPD_MOD_TYPE_72b_SO_RDIMM:
1234  		spd_parse(si, spd_ddr3_rdimm, ARRAY_SIZE(spd_ddr3_rdimm));
1235  		break;
1236  	case SPD_MOD_TYPE_72b_SO_CDIMM:
1237  	case SPD_MOD_TYPE_MINI_CDIMM:
1238  		spd_parse(si, spd_ddr3_cdimm, ARRAY_SIZE(spd_ddr3_cdimm));
1239  		break;
1240  	case SPD_MOD_TYPE_LRDIMM:
1241  		spd_parse(si, spd_ddr3_lrdimm, ARRAY_SIZE(spd_ddr3_lrdimm));
1242  		break;
1243  	default:
1244  		break;
1245  	}
1246  }
1247  
1248  void
spd_parse_ddr3(spd_info_t * si)1249  spd_parse_ddr3(spd_info_t *si)
1250  {
1251  	if (SPD_DDR3_SPD_REV_ENC(si->si_data[SPD_DDR3_SPD_REV]) !=
1252  	    SPD_DDR3_SPD_REV_V1) {
1253  		si->si_error = LIBJEDEC_SPD_UNSUP_REV;
1254  		return;
1255  	}
1256  
1257  	spd_parse(si, spd_ddr3_common, ARRAY_SIZE(spd_ddr3_common));
1258  	spd_parse_ddr3_mod_specific(si);
1259  	spd_parse(si, spd_ddr3_mfg, ARRAY_SIZE(spd_ddr3_mfg));
1260  }
1261