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