11566bc34SRobert Mustacchi /*
21566bc34SRobert Mustacchi  * This file and its contents are supplied under the terms of the
31566bc34SRobert Mustacchi  * Common Development and Distribution License ("CDDL"), version 1.0.
41566bc34SRobert Mustacchi  * You may only use this file in accordance with the terms of version
51566bc34SRobert Mustacchi  * 1.0 of the CDDL.
61566bc34SRobert Mustacchi  *
71566bc34SRobert Mustacchi  * A full copy of the text of the CDDL should have accompanied this
81566bc34SRobert Mustacchi  * source.  A copy of the CDDL is also available via the Internet at
91566bc34SRobert Mustacchi  * http://www.illumos.org/license/CDDL.
101566bc34SRobert Mustacchi  */
111566bc34SRobert Mustacchi 
121566bc34SRobert Mustacchi /*
131566bc34SRobert Mustacchi  * Copyright (c) 2018, Joyent, Inc.
14*fe82ebb0SRobert Mustacchi  * Copyright 2023 Oxide Computer Company
151566bc34SRobert Mustacchi  */
161566bc34SRobert Mustacchi 
171566bc34SRobert Mustacchi #ifndef _LIBJEDEC_H
181566bc34SRobert Mustacchi #define	_LIBJEDEC_H
191566bc34SRobert Mustacchi 
201566bc34SRobert Mustacchi /*
21*fe82ebb0SRobert Mustacchi  * Library routines that support various JEDEC standards:
22*fe82ebb0SRobert Mustacchi  *
23*fe82ebb0SRobert Mustacchi  *  o JEDEC JEP-106 vendor data
24*fe82ebb0SRobert Mustacchi  *  o Temperature range and Measurement Standards for Components and Modules
25*fe82ebb0SRobert Mustacchi  *    (JESD402-1)
26*fe82ebb0SRobert Mustacchi  *  o DDR4 Serial Presence Detect (SPD) decoding
27*fe82ebb0SRobert Mustacchi  *  o DDR5 Serial Presence Detect (SPD) decoding
281566bc34SRobert Mustacchi  */
291566bc34SRobert Mustacchi 
30*fe82ebb0SRobert Mustacchi #include <sys/types.h>
31*fe82ebb0SRobert Mustacchi #include <stdint.h>
32*fe82ebb0SRobert Mustacchi #include <libnvpair.h>
33*fe82ebb0SRobert Mustacchi 
341566bc34SRobert Mustacchi #ifdef __cplusplus
351566bc34SRobert Mustacchi extern "C" {
361566bc34SRobert Mustacchi #endif
371566bc34SRobert Mustacchi 
38*fe82ebb0SRobert Mustacchi /*
39*fe82ebb0SRobert Mustacchi  * Decode a JEDEC continuation ID (without parity) and a group ID.
40*fe82ebb0SRobert Mustacchi  */
411566bc34SRobert Mustacchi extern const char *libjedec_vendor_string(uint_t, uint_t);
421566bc34SRobert Mustacchi 
43*fe82ebb0SRobert Mustacchi /*
44*fe82ebb0SRobert Mustacchi  * JEDEC operating temperature ranges. These are defined in JESD402-1A (March
45*fe82ebb0SRobert Mustacchi  * 2022).
46*fe82ebb0SRobert Mustacchi  */
47*fe82ebb0SRobert Mustacchi typedef enum {
48*fe82ebb0SRobert Mustacchi 	/*
49*fe82ebb0SRobert Mustacchi 	 * Case Operating Temperature Ranges
50*fe82ebb0SRobert Mustacchi 	 */
51*fe82ebb0SRobert Mustacchi 	JEDEC_TEMP_CASE_A1T,
52*fe82ebb0SRobert Mustacchi 	JEDEC_TEMP_CASE_A2T,
53*fe82ebb0SRobert Mustacchi 	JEDEC_TEMP_CASE_A3T,
54*fe82ebb0SRobert Mustacchi 	JEDEC_TEMP_CASE_IT,
55*fe82ebb0SRobert Mustacchi 	JEDEC_TEMP_CASE_ET,
56*fe82ebb0SRobert Mustacchi 	JEDEC_TEMP_CASE_ST,
57*fe82ebb0SRobert Mustacchi 	JEDEC_TEMP_CASE_XT,
58*fe82ebb0SRobert Mustacchi 	JEDEC_TEMP_CASE_NT,
59*fe82ebb0SRobert Mustacchi 	JEDEC_TEMP_CASE_RT,
60*fe82ebb0SRobert Mustacchi 	/*
61*fe82ebb0SRobert Mustacchi 	 * Operating Ambient Temperature Ranges
62*fe82ebb0SRobert Mustacchi 	 */
63*fe82ebb0SRobert Mustacchi 	JEDEC_TEMP_AMB_CT,
64*fe82ebb0SRobert Mustacchi 	JEDEC_TEMP_AMB_IOT,
65*fe82ebb0SRobert Mustacchi 	JEDEC_TEMP_AMB_IPT,
66*fe82ebb0SRobert Mustacchi 	JEDEC_TEMP_AMB_IXT,
67*fe82ebb0SRobert Mustacchi 	JEDEC_TEMP_AMB_AO3T,
68*fe82ebb0SRobert Mustacchi 	JEDEC_TEMP_AMB_AO2T,
69*fe82ebb0SRobert Mustacchi 	JEDEC_TEMP_AMB_AO1T,
70*fe82ebb0SRobert Mustacchi 	/*
71*fe82ebb0SRobert Mustacchi 	 * Storage temperature ranges
72*fe82ebb0SRobert Mustacchi 	 */
73*fe82ebb0SRobert Mustacchi 	JEDEC_TEMP_STOR_2,
74*fe82ebb0SRobert Mustacchi 	JEDEC_TEMP_STOR_1B,
75*fe82ebb0SRobert Mustacchi 	JEDEC_TEMP_STOR_1A,
76*fe82ebb0SRobert Mustacchi 	JEDEC_TEMP_STOR_ST
77*fe82ebb0SRobert Mustacchi } libjedec_temp_range_t;
78*fe82ebb0SRobert Mustacchi extern boolean_t libjedec_temp_range(libjedec_temp_range_t, int32_t *,
79*fe82ebb0SRobert Mustacchi     int32_t *);
80*fe82ebb0SRobert Mustacchi 
81*fe82ebb0SRobert Mustacchi /*
82*fe82ebb0SRobert Mustacchi  * This is a series of error codes that libjedec may produce while trying to
83*fe82ebb0SRobert Mustacchi  * parse the overall SPD data structure. These represent a top-level failure and
84*fe82ebb0SRobert Mustacchi  * have meaning when no nvlist_t is returned.
85*fe82ebb0SRobert Mustacchi  */
86*fe82ebb0SRobert Mustacchi typedef enum {
87*fe82ebb0SRobert Mustacchi 	/*
88*fe82ebb0SRobert Mustacchi 	 * Indicates that we didn't encounter a fatal error; however, we may
89*fe82ebb0SRobert Mustacchi 	 * have a specific parsing error that relates to a key in the nvlist.
90*fe82ebb0SRobert Mustacchi 	 */
91*fe82ebb0SRobert Mustacchi 	LIBJEDEC_SPD_OK	= 0,
92*fe82ebb0SRobert Mustacchi 	/*
93*fe82ebb0SRobert Mustacchi 	 * Indicates that we did not have enough memory while trying to
94*fe82ebb0SRobert Mustacchi 	 * construct the generated nvlist_t.
95*fe82ebb0SRobert Mustacchi 	 */
96*fe82ebb0SRobert Mustacchi 	LIBJEDEC_SPD_NOMEM,
97*fe82ebb0SRobert Mustacchi 	/*
98*fe82ebb0SRobert Mustacchi 	 * Indicates that the data that we found was insufficient to
99*fe82ebb0SRobert Mustacchi 	 * successfully parse basic information. The required size varies per
100*fe82ebb0SRobert Mustacchi 	 * SPD key byte type.
101*fe82ebb0SRobert Mustacchi 	 */
102*fe82ebb0SRobert Mustacchi 	LIBJEDEC_SPD_TOOSHORT,
103*fe82ebb0SRobert Mustacchi 	/*
104*fe82ebb0SRobert Mustacchi 	 * Indicates that we found an unsupported type of SPD data and therefore
105*fe82ebb0SRobert Mustacchi 	 * cannot parse this.
106*fe82ebb0SRobert Mustacchi 	 */
107*fe82ebb0SRobert Mustacchi 	LIBJEDEC_SPD_UNSUP_TYPE,
108*fe82ebb0SRobert Mustacchi 	/*
109*fe82ebb0SRobert Mustacchi 	 * Indicates that while we found a supported type of SPD data, we do not
110*fe82ebb0SRobert Mustacchi 	 * understand its revision.
111*fe82ebb0SRobert Mustacchi 	 */
112*fe82ebb0SRobert Mustacchi 	LIBJEDEC_SPD_UNSUP_REV
113*fe82ebb0SRobert Mustacchi } spd_error_t;
114*fe82ebb0SRobert Mustacchi 
115*fe82ebb0SRobert Mustacchi /*
116*fe82ebb0SRobert Mustacchi  * Decode a binary payload of SPD data, if possible. The returned nvlist is made
117*fe82ebb0SRobert Mustacchi  * up of a series of keys described below. Parsing errors are broken into two
118*fe82ebb0SRobert Mustacchi  * categories. Fatal errors set a value in the spd_error_t below. Non-fatal
119*fe82ebb0SRobert Mustacchi  * errors, such as encountering a value which we don't have a translation for,
120*fe82ebb0SRobert Mustacchi  * are in a nested errors nvlist_t indexed by key.
121*fe82ebb0SRobert Mustacchi  *
122*fe82ebb0SRobert Mustacchi  * The keys are all dot delineated to create a few different top-level
123*fe82ebb0SRobert Mustacchi  * namespaces. These include:
124*fe82ebb0SRobert Mustacchi  *
125*fe82ebb0SRobert Mustacchi  * "meta" -- Which includes information about the SPD, encoding, and things like
126*fe82ebb0SRobert Mustacchi  * the type of module.
127*fe82ebb0SRobert Mustacchi  *
128*fe82ebb0SRobert Mustacchi  * "dram" -- Parameters that are specific to the SDRAM dies present. What one
129*fe82ebb0SRobert Mustacchi  * thinks of as a stick of DRAM consists of several different SDRAM dies on the
130*fe82ebb0SRobert Mustacchi  * PCB. This includes things like the row and columns bits and timing
131*fe82ebb0SRobert Mustacchi  * information.
132*fe82ebb0SRobert Mustacchi  *
133*fe82ebb0SRobert Mustacchi  * "ddr4", "ddr5" -- These include information which is specific to the general
134*fe82ebb0SRobert Mustacchi  * DDR standard. While we have tried to consolidate information between them
135*fe82ebb0SRobert Mustacchi  * where applicable, some things are specific to the standard.
136*fe82ebb0SRobert Mustacchi  *
137*fe82ebb0SRobert Mustacchi  * "module" -- Parameters that are specific to the broader module and PCB
138*fe82ebb0SRobert Mustacchi  * itself. This includes information like the height or devices present.
139*fe82ebb0SRobert Mustacchi  *
140*fe82ebb0SRobert Mustacchi  * "ddr4.rdimm", "ddr4.lrdimm", "ddr5.rdimm", etc. -- These are parameter that
141*fe82ebb0SRobert Mustacchi  * are specific to a module being both the combination of a specific DDR
142*fe82ebb0SRobert Mustacchi  * standard and a specific type of module. Common parameters are often in the
143*fe82ebb0SRobert Mustacchi  * "module" section.
144*fe82ebb0SRobert Mustacchi  *
145*fe82ebb0SRobert Mustacchi  * "mfg" -- Manufacturing related information.
146*fe82ebb0SRobert Mustacchi  *
147*fe82ebb0SRobert Mustacchi  * "errors" -- The key for the errors nvlist_t. See the spd_error_kind_t
148*fe82ebb0SRobert Mustacchi  * definition later on. Each error has both a numeric code and a string message.
149*fe82ebb0SRobert Mustacchi  */
150*fe82ebb0SRobert Mustacchi extern nvlist_t *libjedec_spd(const uint8_t *, size_t, spd_error_t *);
151*fe82ebb0SRobert Mustacchi 
152*fe82ebb0SRobert Mustacchi /*
153*fe82ebb0SRobert Mustacchi  * The following are keys in the metadata nvlist_t. The SPD_KEY_NBYTES_TOTAL is
154*fe82ebb0SRobert Mustacchi  * present in DDR4 and DDR5. The SPD_KEY_NBYTES_USED is only present on DDR4
155*fe82ebb0SRobert Mustacchi  * right now. All supported SPD encodings have the raw revision information. If
156*fe82ebb0SRobert Mustacchi  * the values for the total bytes or used bytes are set to undefined, then they
157*fe82ebb0SRobert Mustacchi  * will not be present.
158*fe82ebb0SRobert Mustacchi  *
159*fe82ebb0SRobert Mustacchi  * DDR5 introduces an idea of a public beta level that gets reset between
160*fe82ebb0SRobert Mustacchi  * external releases. It theoretically modifies every scion. DDR5 also
161*fe82ebb0SRobert Mustacchi  * introduces a second revision that is for the module information. This will
162*fe82ebb0SRobert Mustacchi  * not be present on systems prior to DDR5.
163*fe82ebb0SRobert Mustacchi  */
164*fe82ebb0SRobert Mustacchi #define	SPD_KEY_NBYTES_TOTAL	"meta.total-bytes"	/* uint32_t */
165*fe82ebb0SRobert Mustacchi #define	SPD_KEY_NBYTES_USED	"meta.used-bytes"	/* uint32_t */
166*fe82ebb0SRobert Mustacchi #define	SPD_KEY_REV_ENC	"meta.revision-encoding"	/* uint32_t */
167*fe82ebb0SRobert Mustacchi #define	SPD_KEY_REV_ADD	"meta.revision-additions"	/* uint32_t */
168*fe82ebb0SRobert Mustacchi #define	SPD_KEY_BETA	"meta.beta-version"		/* uint32_t */
169*fe82ebb0SRobert Mustacchi #define	SPD_KEY_MOD_REV_ENC	"meta.module-revision-encoding"	/* uint32_t */
170*fe82ebb0SRobert Mustacchi #define	SPD_KEY_MOD_REV_ADD	"meta.module-revision-additions" /* uint32_t */
171*fe82ebb0SRobert Mustacchi 
172*fe82ebb0SRobert Mustacchi /*
173*fe82ebb0SRobert Mustacchi  * DRAM Type information. This indicates the standard that the device conforms
174*fe82ebb0SRobert Mustacchi  * to. This enumeration's values match the JEDEC specification's values. This is
175*fe82ebb0SRobert Mustacchi  * present for everything.
176*fe82ebb0SRobert Mustacchi  */
177*fe82ebb0SRobert Mustacchi typedef enum {
178*fe82ebb0SRobert Mustacchi 	SPD_DT_FAST_PAGE_MODE		= 0x01,
179*fe82ebb0SRobert Mustacchi 	SPD_DT_EDO			= 0x02,
180*fe82ebb0SRobert Mustacchi 	SPD_DT_PIPE_NIBBLE		= 0x03,
181*fe82ebb0SRobert Mustacchi 	SPD_DT_SDRAM			= 0x04,
182*fe82ebb0SRobert Mustacchi 	SPD_DT_ROM			= 0x05,
183*fe82ebb0SRobert Mustacchi 	SPD_DT_DDR_SGRAM		= 0x06,
184*fe82ebb0SRobert Mustacchi 	SPD_DT_DDR_SDRAM		= 0x07,
185*fe82ebb0SRobert Mustacchi 	SPD_DT_DDR2_SDRAM		= 0x08,
186*fe82ebb0SRobert Mustacchi 	SPD_DT_DDR2_SDRAM_FBDIMM	= 0x09,
187*fe82ebb0SRobert Mustacchi 	SPD_DT_DDR2_SDRAM_FDIMM_P	= 0x0a,
188*fe82ebb0SRobert Mustacchi 	SPD_DT_DDR3_SDRAM		= 0x0b,
189*fe82ebb0SRobert Mustacchi 	SPD_DT_DDR4_SDRAM		= 0x0c,
190*fe82ebb0SRobert Mustacchi 	SPD_DT_DDR4E_SDRAM		= 0x0e,
191*fe82ebb0SRobert Mustacchi 	SPD_DT_LPDDR3_SDRAM		= 0x0f,
192*fe82ebb0SRobert Mustacchi 	SPD_DT_LPDDR4_SDRAM		= 0x10,
193*fe82ebb0SRobert Mustacchi 	SPD_DT_LPDDR4X_SDRAM		= 0x11,
194*fe82ebb0SRobert Mustacchi 	SPD_DT_DDR5_SDRAM		= 0x12,
195*fe82ebb0SRobert Mustacchi 	SPD_DT_LPDDR5_SDRAM		= 0x13,
196*fe82ebb0SRobert Mustacchi 	SPD_DT_DDR5_NVDIMM_P		= 0x14,
197*fe82ebb0SRobert Mustacchi 	SPD_DT_LPDDR5X_SDRAM		= 0x15
198*fe82ebb0SRobert Mustacchi } spd_dram_type_t;
199*fe82ebb0SRobert Mustacchi #define	SPD_KEY_DRAM_TYPE	"meta.dram-type"	/* uint32_t (enum) */
200*fe82ebb0SRobert Mustacchi 
201*fe82ebb0SRobert Mustacchi typedef enum {
202*fe82ebb0SRobert Mustacchi 	SPD_MOD_TYPE_RDIMM,
203*fe82ebb0SRobert Mustacchi 	SPD_MOD_TYPE_UDIMM,
204*fe82ebb0SRobert Mustacchi 	SPD_MOD_TYPE_SODIMM,
205*fe82ebb0SRobert Mustacchi 	SPD_MOD_TYPE_LRDIMM,
206*fe82ebb0SRobert Mustacchi 	SPD_MOD_TYPE_MRDIMM,
207*fe82ebb0SRobert Mustacchi 	SPD_MOD_TYPE_DDIMM,
208*fe82ebb0SRobert Mustacchi 	SPD_MOD_TYPE_SOLDER,
209*fe82ebb0SRobert Mustacchi 	SPD_MOD_TYPE_MINI_RDIMM,
210*fe82ebb0SRobert Mustacchi 	SPD_MOD_TYPE_MINI_UDIMM,
211*fe82ebb0SRobert Mustacchi 	SPD_MOD_TYPE_72b_SO_RDIMM,
212*fe82ebb0SRobert Mustacchi 	SPD_MOD_TYPE_72b_SO_UDIMM,
213*fe82ebb0SRobert Mustacchi 	SPD_MOD_TYPE_16b_SO_DIMM,
214*fe82ebb0SRobert Mustacchi 	SPD_MOD_TYPE_32b_SO_DIMM
215*fe82ebb0SRobert Mustacchi } spd_module_type_t;
216*fe82ebb0SRobert Mustacchi #define	SPD_KEY_MOD_TYPE	"meta.module-type"	/* uint32_t (enum) */
217*fe82ebb0SRobert Mustacchi typedef enum {
218*fe82ebb0SRobert Mustacchi 	SPD_MOD_NOT_HYBRID,
219*fe82ebb0SRobert Mustacchi 	SPD_MOD_HYBRID_NVDIMMM
220*fe82ebb0SRobert Mustacchi } spd_module_hybrid_t;
221*fe82ebb0SRobert Mustacchi #define	SPD_KEY_MOD_HYBRID_TYPE	"meta.hybrid-type"	/* uint32_t */
222*fe82ebb0SRobert Mustacchi 
223*fe82ebb0SRobert Mustacchi typedef enum {
224*fe82ebb0SRobert Mustacchi 	SPD_MOD_TYPE_NVDIMM_N,
225*fe82ebb0SRobert Mustacchi 	SPD_MOD_TYPE_NVDIMM_P,
226*fe82ebb0SRobert Mustacchi 	SPD_MOD_TYPE_NVDIMM_H
227*fe82ebb0SRobert Mustacchi } spd_module_nvdimm_type_t;
228*fe82ebb0SRobert Mustacchi #define	SPD_KEY_MOD_NVDIMM_TYPE	"meta.nvdimm-type"	/* uint32_t */
229*fe82ebb0SRobert Mustacchi 
230*fe82ebb0SRobert Mustacchi /*
231*fe82ebb0SRobert Mustacchi  * Different SPD standards have different integrity rules. The regions covered
232*fe82ebb0SRobert Mustacchi  * by the CRCs also vary. We end up with per-spec keys. All data types for these
233*fe82ebb0SRobert Mustacchi  * are uint32_t's so that way we can record the expected CRC. We use a uint32_t
234*fe82ebb0SRobert Mustacchi  * for consistency even though the data only fits in a uint16_t. Note, callers
235*fe82ebb0SRobert Mustacchi  * must check to see if these exist. If there are keys with these names in the
236*fe82ebb0SRobert Mustacchi  * errors object, then the rest of the data should be considered suspect, but we
237*fe82ebb0SRobert Mustacchi  * will have attempted to parse everything we can.
238*fe82ebb0SRobert Mustacchi  */
239*fe82ebb0SRobert Mustacchi #define	SPD_KEY_CRC_DDR4_BASE	"meta.crc-ddr4-base"	/* uint32_t */
240*fe82ebb0SRobert Mustacchi #define	SPD_KEY_CRC_DDR4_BLK1	"meta.crc-ddr4-block1"	/* uint32_t */
241*fe82ebb0SRobert Mustacchi #define	SPD_KEY_CRC_DDR5	"meta.crc-ddr5"		/* uint32_t */
242*fe82ebb0SRobert Mustacchi 
243*fe82ebb0SRobert Mustacchi /*
244*fe82ebb0SRobert Mustacchi  * DDR5 adds a field in the SPD to describe how data should be hashed to compute
245*fe82ebb0SRobert Mustacchi  * and compare to an attribute certification to authenticate modules. This is
246*fe82ebb0SRobert Mustacchi  * only present in DDR5. We only add a value here if this is actually supported.
247*fe82ebb0SRobert Mustacchi  */
248*fe82ebb0SRobert Mustacchi typedef enum {
249*fe82ebb0SRobert Mustacchi 	SPD_HASH_SEQ_ALG_1
250*fe82ebb0SRobert Mustacchi } spd_hash_seq_alg_t;
251*fe82ebb0SRobert Mustacchi #define	SPD_KEY_HASH_SEQ	"meta.hash-sequence-algorithm"	/* uint32_t */
252*fe82ebb0SRobert Mustacchi 
253*fe82ebb0SRobert Mustacchi /*
254*fe82ebb0SRobert Mustacchi  * This section contains information related to DRAM technology.
255*fe82ebb0SRobert Mustacchi  */
256*fe82ebb0SRobert Mustacchi 
257*fe82ebb0SRobert Mustacchi /*
258*fe82ebb0SRobert Mustacchi  * Bank, bank group, row, and column bits. These are all present in both DDR4
259*fe82ebb0SRobert Mustacchi  * and DDR5. DDR4 allows cases where there are no bank groups. If no bits are
260*fe82ebb0SRobert Mustacchi  * used, then this item is empty.
261*fe82ebb0SRobert Mustacchi  */
262*fe82ebb0SRobert Mustacchi #define	SPD_KEY_NROW_BITS	"dram.num-row-bits"	/* uint32_t */
263*fe82ebb0SRobert Mustacchi #define	SPD_KEY_NCOL_BITS	"dram.num-column-bits"	/* uint32_t */
264*fe82ebb0SRobert Mustacchi #define	SPD_KEY_NBANK_BITS	"dram.num-bank-bits"	/* uint32_t */
265*fe82ebb0SRobert Mustacchi #define	SPD_KEY_NBGRP_BITS	"dram.num-bank-group-bits"	/* uint32_t */
266*fe82ebb0SRobert Mustacchi #define	SPD_KEY_SEC_NROW_BITS	"dram.sec-num-row-bits"		/* uint32_t */
267*fe82ebb0SRobert Mustacchi #define	SPD_KEY_SEC_NCOL_BITS	"dram.sec-num-column-bits"	/* uint32_t */
268*fe82ebb0SRobert Mustacchi #define	SPD_KEY_SEC_NBANK_BITS	"dram.sec-num-bank-bits"	/* uint32_t */
269*fe82ebb0SRobert Mustacchi #define	SPD_KEY_SEC_NBGRP_BITS	"dram.sec-num-bank-group-bits"	/* uint32_t */
270*fe82ebb0SRobert Mustacchi 
271*fe82ebb0SRobert Mustacchi /*
272*fe82ebb0SRobert Mustacchi  * Die Density. This is the capacity that each die contains in bits.
273*fe82ebb0SRobert Mustacchi  */
274*fe82ebb0SRobert Mustacchi #define	SPD_KEY_DIE_SIZE	"dram.die-bit-size"	/* uint64_t */
275*fe82ebb0SRobert Mustacchi #define	SPD_KEY_SEC_DIE_SIZE	"dram.sec-die-bit-size"	/* uint64_t */
276*fe82ebb0SRobert Mustacchi 
277*fe82ebb0SRobert Mustacchi /*
278*fe82ebb0SRobert Mustacchi  * Package information. DRAM may be made up of a monolithic package type or
279*fe82ebb0SRobert Mustacchi  * several different types. There is a boolean property present to indicate that
280*fe82ebb0SRobert Mustacchi  * it is not monolithic. For these there is a die count and then a separate
281*fe82ebb0SRobert Mustacchi  * notion of what the signal loading type is. If the property is present then we
282*fe82ebb0SRobert Mustacchi  * will also have the die count and loading type for the secondary. Note, these
283*fe82ebb0SRobert Mustacchi  * loading parameters are considered at the device balls as opposed to specific
284*fe82ebb0SRobert Mustacchi  * signals.
285*fe82ebb0SRobert Mustacchi  */
286*fe82ebb0SRobert Mustacchi #define	SPD_KEY_PKG_NOT_MONO	"meta.non-monolithic-package"	/* key only */
287*fe82ebb0SRobert Mustacchi #define	SPD_KEY_PKG_NDIE	"dram.package-die-count"	/* uint32_t */
288*fe82ebb0SRobert Mustacchi #define	SPD_KEY_SEC_PKG_NDIE	"dram.sec-package-die-count"	/* uint32_t */
289*fe82ebb0SRobert Mustacchi typedef enum {
290*fe82ebb0SRobert Mustacchi 	SPD_SL_UNSPECIFIED,
291*fe82ebb0SRobert Mustacchi 	SPD_SL_MUTLI_STACK,
292*fe82ebb0SRobert Mustacchi 	SPD_SL_3DS
293*fe82ebb0SRobert Mustacchi } spd_signal_loading_t;
294*fe82ebb0SRobert Mustacchi #define	SPD_KEY_PKG_SL		"dram.package-sig-loading"	/* uint32_t */
295*fe82ebb0SRobert Mustacchi #define	SPD_KEY_SEC_PKG_SL	"dram.sec-package-sig-loading"	/* uint32_t */
296*fe82ebb0SRobert Mustacchi 
297*fe82ebb0SRobert Mustacchi /*
298*fe82ebb0SRobert Mustacchi  * Post-package Repair. PPR is supported in DDR4 and DDR5. A key is used to
299*fe82ebb0SRobert Mustacchi  * indicate  If PPR is not supported, then this will not be present.
300*fe82ebb0SRobert Mustacchi  */
301*fe82ebb0SRobert Mustacchi typedef enum {
302*fe82ebb0SRobert Mustacchi 	SPD_PPR_F_HARD_PPR		= 1 << 0,
303*fe82ebb0SRobert Mustacchi 	SPD_PPR_F_SOFT_PPR		= 1 << 2,
304*fe82ebb0SRobert Mustacchi 	SPD_PPR_F_MBIST_PPR		= 1 << 3,
305*fe82ebb0SRobert Mustacchi 	SPD_PPR_F_PPR_UNDO		= 1 << 4
306*fe82ebb0SRobert Mustacchi } spd_ppr_flags_t;
307*fe82ebb0SRobert Mustacchi 
308*fe82ebb0SRobert Mustacchi typedef enum {
309*fe82ebb0SRobert Mustacchi 	SPD_PPR_GRAN_BANK_GROUP,
310*fe82ebb0SRobert Mustacchi 	SPD_PPR_GRAN_BANK
311*fe82ebb0SRobert Mustacchi } spd_ppr_gran_t;
312*fe82ebb0SRobert Mustacchi #define	SPD_KEY_PPR		"dram.ppr-flags"	/* uint32_t (enum) */
313*fe82ebb0SRobert Mustacchi #define	SPD_KEY_PPR_GRAN	"dram.ppr-gran"		/* uint32_t (enum) */
314*fe82ebb0SRobert Mustacchi 
315*fe82ebb0SRobert Mustacchi /*
316*fe82ebb0SRobert Mustacchi  * Voltages in mV. This is an array of nominal voltages that are supported. DDR3
317*fe82ebb0SRobert Mustacchi  * defines multiple voltages, but DDR4 and DDR5 only have a single voltage
318*fe82ebb0SRobert Mustacchi  * (specific to the supply). DDR3 and DDR4 only defined V~DD~ in SPD. While
319*fe82ebb0SRobert Mustacchi  * V~DQ~ and V~PP~ are defined in DDR5.
320*fe82ebb0SRobert Mustacchi  */
321*fe82ebb0SRobert Mustacchi #define	SPD_KEY_NOM_VDD		"dram.nominal-vdd"	/* uint32_t[] */
322*fe82ebb0SRobert Mustacchi #define	SPD_KEY_NOM_VDDQ	"dram.nominal-vddq"	/* uint32_t[] */
323*fe82ebb0SRobert Mustacchi #define	SPD_KEY_NOM_VPP		"dram.nominal-vpp"	/* uint32_t[] */
324*fe82ebb0SRobert Mustacchi 
325*fe82ebb0SRobert Mustacchi /*
326*fe82ebb0SRobert Mustacchi  * DRAM module organization. This describes the number of ranks that exist on
327*fe82ebb0SRobert Mustacchi  * the device. In DDR5 this refers to the sub-channel. In DDR4, it refers to the
328*fe82ebb0SRobert Mustacchi  * entire channel. The rank mix may be symmetrical or asymmetrical. A key will
329*fe82ebb0SRobert Mustacchi  * be set if that's the case.
330*fe82ebb0SRobert Mustacchi  */
331*fe82ebb0SRobert Mustacchi #define	SPD_KEY_RANK_ASYM	"dram.asymmetrical-ranks"	/* key */
332*fe82ebb0SRobert Mustacchi #define	SPD_KEY_NRANKS		"dram.num-ranks"	/* uint32_t */
333*fe82ebb0SRobert Mustacchi 
334*fe82ebb0SRobert Mustacchi /*
335*fe82ebb0SRobert Mustacchi  * DRAM and Module widths. The module width is what we think of of when we think
336*fe82ebb0SRobert Mustacchi  * of an entire stick, e.g. the DDR4 72-bit (64-bit data, 8-bit ECC) bus.
337*fe82ebb0SRobert Mustacchi  * Separately the individual DRAM dies themselves have a width which is
338*fe82ebb0SRobert Mustacchi  * SPD_KEY_DRAM_WIDTH. The main bus width is split between the primary data size
339*fe82ebb0SRobert Mustacchi  * and the ecc data size. In DDR4 and earlier this is the entire channel. In
340*fe82ebb0SRobert Mustacchi  * DDR5 this is duplicated for each sub-channel.
341*fe82ebb0SRobert Mustacchi  */
342*fe82ebb0SRobert Mustacchi #define	SPD_KEY_DRAM_WIDTH	"dram.width"		/* uint32_t */
343*fe82ebb0SRobert Mustacchi #define	SPD_KEY_SEC_DRAM_WIDTH	"dram.sec-width"	/* uint32_t */
344*fe82ebb0SRobert Mustacchi #define	SPD_KEY_NSUBCHAN	"module.num-subchan"	/* uint32_t */
345*fe82ebb0SRobert Mustacchi #define	SPD_KEY_DATA_WIDTH	"module.data-width"	/* uint32_t */
346*fe82ebb0SRobert Mustacchi #define	SPD_KEY_ECC_WIDTH	"module.ecc-width"	/* uint32_t */
347*fe82ebb0SRobert Mustacchi 
348*fe82ebb0SRobert Mustacchi /*
349*fe82ebb0SRobert Mustacchi  * DDR3 and DDR4 specify specific timebases in the SPD data. DDR5 just requires
350*fe82ebb0SRobert Mustacchi  * a specific timebase. In the case of DDR5 we just set both values to be the
351*fe82ebb0SRobert Mustacchi  * same. This like all other time values is explicitly in ps.
352*fe82ebb0SRobert Mustacchi  */
353*fe82ebb0SRobert Mustacchi #define	SPD_KEY_MTB	"dram.median-time-base"		/* uint32_t */
354*fe82ebb0SRobert Mustacchi #define	SPD_KEY_FTB	"dram.fine-time-base"		/* uint32_t */
355*fe82ebb0SRobert Mustacchi 
356*fe82ebb0SRobert Mustacchi /*
357*fe82ebb0SRobert Mustacchi  * Supported CAS Latencies. This is an array of integers to indicate which index
358*fe82ebb0SRobert Mustacchi  * CAS latencies are possible.
359*fe82ebb0SRobert Mustacchi  */
360*fe82ebb0SRobert Mustacchi #define	SPD_KEY_CAS	"dram.cas-latencies"		/* uint32_t [] */
361*fe82ebb0SRobert Mustacchi 
362*fe82ebb0SRobert Mustacchi /*
363*fe82ebb0SRobert Mustacchi  * Time parameters. These are all in picoseconds. All values are uint64_t.
364*fe82ebb0SRobert Mustacchi  */
365*fe82ebb0SRobert Mustacchi #define	SPD_KEY_TCKAVG_MIN	"dram.t~CKAVG~min"
366*fe82ebb0SRobert Mustacchi #define	SPD_KEY_TCKAVG_MAX	"dram.t~CKAVG~max"
367*fe82ebb0SRobert Mustacchi #define	SPD_KEY_TAA_MIN		"dram.t~AA~min"
368*fe82ebb0SRobert Mustacchi #define	SPD_KEY_TRCD_MIN	"dram.t~RCD~min"
369*fe82ebb0SRobert Mustacchi #define	SPD_KEY_TRP_MIN		"dram.t~RP~min"
370*fe82ebb0SRobert Mustacchi #define	SPD_KEY_TRAS_MIN	"dram.t~RAS~min"
371*fe82ebb0SRobert Mustacchi #define	SPD_KEY_TRC_MIN		"dram.t~RC~min"
372*fe82ebb0SRobert Mustacchi #define	SPD_KEY_TRFC1_MIN	"dram.t~RFC1~min"
373*fe82ebb0SRobert Mustacchi #define	SPD_KEY_TRFC2_MIN	"dram.t~RFC2~min"
374*fe82ebb0SRobert Mustacchi #define	SPD_KEY_TFAW		"dram.t~FAW~"
375*fe82ebb0SRobert Mustacchi #define	SPD_KEY_TRRD_L_MIN	"dram.t~RRD_S~min"
376*fe82ebb0SRobert Mustacchi #define	SPD_KEY_TCCD_L_MIN	"dram.t~CCD_S~min"
377*fe82ebb0SRobert Mustacchi #define	SPD_KEY_TWR_MIN		"dram.t~WR~min"
378*fe82ebb0SRobert Mustacchi 
379*fe82ebb0SRobert Mustacchi /*
380*fe82ebb0SRobert Mustacchi  * The following time are only used in DDR4. While some of the DDR4 and DDR5
381*fe82ebb0SRobert Mustacchi  * write to read or write to write parameters are similar, because they use
382*fe82ebb0SRobert Mustacchi  * different names for times, we distinguish them as different values.
383*fe82ebb0SRobert Mustacchi  */
384*fe82ebb0SRobert Mustacchi #define	SPD_KEY_TRFC4_MIN	"dram.t~RFC4~min"
385*fe82ebb0SRobert Mustacchi #define	SPD_KEY_TRRD_S_MIN	"dram.t~RRD_S~min"
386*fe82ebb0SRobert Mustacchi #define	SPD_KEY_TWTRS_MIN	"dram.t~WTR_S~min"
387*fe82ebb0SRobert Mustacchi #define	SPD_KEY_TWTRL_MIN	"dram.t~WTR_L~min"
388*fe82ebb0SRobert Mustacchi 
389*fe82ebb0SRobert Mustacchi /*
390*fe82ebb0SRobert Mustacchi  * The following times are specific to DDR5. t~CCD_L_WTR~ in DDR5 is the
391*fe82ebb0SRobert Mustacchi  * equivalent to t~WTRS_L~min, same with t~CCD_S_WTR~.
392*fe82ebb0SRobert Mustacchi  */
393*fe82ebb0SRobert Mustacchi #define	SPD_KEY_TCCDLWR		"dram.t~CCD_L_WR"
394*fe82ebb0SRobert Mustacchi #define	SPD_KEY_TCCDLWR2	"dram.t~CCD_L_WR2"
395*fe82ebb0SRobert Mustacchi #define	SPD_KEY_TCCDLWTR	"dram.t~CCD_L_WTR"
396*fe82ebb0SRobert Mustacchi #define	SPD_KEY_TCCDSWTR	"dram.t~CCD_S_WTR"
397*fe82ebb0SRobert Mustacchi #define	SPD_KEY_TRTP		"dram.t~RTP~"
398*fe82ebb0SRobert Mustacchi 
399*fe82ebb0SRobert Mustacchi /*
400*fe82ebb0SRobert Mustacchi  * While prior DDR standards did have minimum clock times for certain
401*fe82ebb0SRobert Mustacchi  * activities, these were first added to the SPD data in DDR5. All values for
402*fe82ebb0SRobert Mustacchi  * these are uint32_t's and are in clock cycles.
403*fe82ebb0SRobert Mustacchi  */
404*fe82ebb0SRobert Mustacchi #define	SPD_KEY_TRRDL_NCK	"dram.t~RRD_L~nCK"
405*fe82ebb0SRobert Mustacchi #define	SPD_KEY_TCCDL_NCK	"dram.t~CCD_L~nCK"
406*fe82ebb0SRobert Mustacchi #define	SPD_KEY_TCCDLWR_NCK	"dram.t~CCD_L_WR~nCK"
407*fe82ebb0SRobert Mustacchi #define	SPD_KEY_TCCDLWR2_NCK	"dram.t~CCD_L_WR2~nCK"
408*fe82ebb0SRobert Mustacchi #define	SPD_KEY_TFAW_NCK	"dram.t~FAW~nCK"
409*fe82ebb0SRobert Mustacchi #define	SPD_KEY_TCCDLWTR_NCK	"dram.t~CCD_L_WTR~nCK"
410*fe82ebb0SRobert Mustacchi #define	SPD_KEY_TCCDSWTR_NCK	"dram.t~CCD_S_WTR~nCK"
411*fe82ebb0SRobert Mustacchi #define	SPD_KEY_TRTP_NCK	"dram.t~RTP~nCK"
412*fe82ebb0SRobert Mustacchi 
413*fe82ebb0SRobert Mustacchi /*
414*fe82ebb0SRobert Mustacchi  * The following times are only used in DDR5. The RFCx_dlr values are for 3DS
415*fe82ebb0SRobert Mustacchi  * RDIMMs.
416*fe82ebb0SRobert Mustacchi  */
417*fe82ebb0SRobert Mustacchi #define	SPD_KEY_TRFCSB		"dram.t~RFCsb~"
418*fe82ebb0SRobert Mustacchi #define	SPD_KEY_TRFC1_DLR	"dram.3ds-t~RFC1_dlr~"
419*fe82ebb0SRobert Mustacchi #define	SPD_KEY_TRFC2_DLR	"dram.3ds-t~RFC2_dlr~"
420*fe82ebb0SRobert Mustacchi #define	SPD_KEY_TRFCSB_DLR	"dram.3ds-t~RFCsb_dlr~"
421*fe82ebb0SRobert Mustacchi 
422*fe82ebb0SRobert Mustacchi /*
423*fe82ebb0SRobert Mustacchi  * The following are DDR4 specific properties, so they are prefixed with "ddr4".
424*fe82ebb0SRobert Mustacchi  * These refer to the maximum activate window and the maximum activate count. In
425*fe82ebb0SRobert Mustacchi  * cases where the MAC is unknown no key will be present.
426*fe82ebb0SRobert Mustacchi  */
427*fe82ebb0SRobert Mustacchi #define	SPD_KEY_DDR4_MAW	"ddr4.maw"		/* uint32_t */
428*fe82ebb0SRobert Mustacchi #define	SPD_KEY_DDR4_MAC	"ddr4.mac"		/* uint32_t */
429*fe82ebb0SRobert Mustacchi #define	SPD_KEY_DDR4_MAC_UNLIMITED	UINT32_MAX
430*fe82ebb0SRobert Mustacchi 
431*fe82ebb0SRobert Mustacchi /*
432*fe82ebb0SRobert Mustacchi  * The following are DDR5 specific properties. BL32 indicates whether burst
433*fe82ebb0SRobert Mustacchi  * length 32 mode is supported, which is a key. Along with the partial array
434*fe82ebb0SRobert Mustacchi  * self refresh. The Duty Cycle Adjustor is an enumeration because there are
435*fe82ebb0SRobert Mustacchi  * multiple modes. The wide temperature sensing is another DDR5 bit represented
436*fe82ebb0SRobert Mustacchi  * as a key as well as an enum of fault handling.
437*fe82ebb0SRobert Mustacchi  */
438*fe82ebb0SRobert Mustacchi #define	SPD_KEY_DDR5_BL32	"ddr5.bl32"		/* key */
439*fe82ebb0SRobert Mustacchi #define	SPD_KEY_DDR5_PASR	"ddr5.pasr"		/* key */
440*fe82ebb0SRobert Mustacchi typedef enum {
441*fe82ebb0SRobert Mustacchi 	SPD_DCA_UNSPPORTED,
442*fe82ebb0SRobert Mustacchi 	SPD_DCA_1_OR_2_PHASE,
443*fe82ebb0SRobert Mustacchi 	SPD_DCA_4_PHASE
444*fe82ebb0SRobert Mustacchi } spd_dca_t;
445*fe82ebb0SRobert Mustacchi #define	SPD_KEY_DDR5_DCA	"ddr5.dca"		/* uint32_t */
446*fe82ebb0SRobert Mustacchi #define	SPD_KEY_DDR5_WIDE_TS	"ddr5.wide-temp-sense"	/* key */
447*fe82ebb0SRobert Mustacchi typedef enum {
448*fe82ebb0SRobert Mustacchi 	SPD_FLT_BOUNDED		= 1 << 0,
449*fe82ebb0SRobert Mustacchi 	SPD_FLT_WRSUP_MR9	= 1 << 1,
450*fe82ebb0SRobert Mustacchi 	SPD_FLT_WRSUP_MR15	= 1 << 2
451*fe82ebb0SRobert Mustacchi } spd_fault_t;
452*fe82ebb0SRobert Mustacchi #define	SPD_KEY_DDR5_FLT	"ddr5.fault-handling"	/* uint32_t */
453*fe82ebb0SRobert Mustacchi 
454*fe82ebb0SRobert Mustacchi /*
455*fe82ebb0SRobert Mustacchi  * DDR5 allows for non-standard core timing options. This is indicated by a
456*fe82ebb0SRobert Mustacchi  * single key that acts as a flag.
457*fe82ebb0SRobert Mustacchi  */
458*fe82ebb0SRobert Mustacchi #define	SPD_KEY_DDR5_NONSTD_TIME	"ddr5.non-standard-timing" /* key */
459*fe82ebb0SRobert Mustacchi 
460*fe82ebb0SRobert Mustacchi /*
461*fe82ebb0SRobert Mustacchi  * DDR5 adds information about refresh management. This is split into
462*fe82ebb0SRobert Mustacchi  * information about general refresh management and then optional adaptive
463*fe82ebb0SRobert Mustacchi  * refresh management. There are three levels of adaptive refresh management
464*fe82ebb0SRobert Mustacchi  * titled A, B, and C. Both the general refresh management and the adaptive
465*fe82ebb0SRobert Mustacchi  * refresh management exist for both the primary and secondary types in
466*fe82ebb0SRobert Mustacchi  * asymmetrical modules. All values here are uint32_t's.
467*fe82ebb0SRobert Mustacchi  */
468*fe82ebb0SRobert Mustacchi typedef enum {
469*fe82ebb0SRobert Mustacchi 	SPD_RFM_F_REQUIRED	= 1 << 0,
470*fe82ebb0SRobert Mustacchi 	SPD_RFM_F_DRFM_SUP	= 1 << 1,
471*fe82ebb0SRobert Mustacchi } spd_rfm_flags_t;
472*fe82ebb0SRobert Mustacchi #define	SPD_KEY_DDR5_RFM_FLAGS_PRI	"ddr5.rfm.flags"
473*fe82ebb0SRobert Mustacchi #define	SPD_KEY_DDR5_RFM_RAAIMT_PRI	"ddr5.rfm.raaimt"
474*fe82ebb0SRobert Mustacchi #define	SPD_KEY_DDR5_RFM_RAAIMT_FGR_PRI	"ddr5.rfm.raaimt-fgr"
475*fe82ebb0SRobert Mustacchi #define	SPD_KEY_DDR5_RFM_RAAMMT_PRI	"ddr5.rfm.raammt"
476*fe82ebb0SRobert Mustacchi #define	SPD_KEY_DDR5_RFM_RAAMMT_FGR_PRI	"ddr5.rfm.raammt-fgr"
477*fe82ebb0SRobert Mustacchi #define	SPD_KEY_DDR5_RFM_BRC_CFG_PRI	"ddr5.rfm.brc-config"
478*fe82ebb0SRobert Mustacchi 
479*fe82ebb0SRobert Mustacchi typedef enum {
480*fe82ebb0SRobert Mustacchi 	SPD_BRC_F_LVL_2		= 1 << 0,
481*fe82ebb0SRobert Mustacchi 	SPD_BRC_F_LVL_3		= 1 << 1,
482*fe82ebb0SRobert Mustacchi 	SPD_BRC_F_LVL_4		= 1 << 2
483*fe82ebb0SRobert Mustacchi } spd_brc_flags_t;
484*fe82ebb0SRobert Mustacchi #define	SPD_KEY_DDR5_RFM_BRC_SUP_PRI	"ddr5.rfm.brc-level"
485*fe82ebb0SRobert Mustacchi #define	SPD_KEY_DDR5_RFM_RAA_DEC_PRI	"ddr5.rfm.raa-dec"
486*fe82ebb0SRobert Mustacchi #define	SPD_KEY_DDR5_RFM_FLAGS_SEC	"ddr5.rfm.sec-flags"
487*fe82ebb0SRobert Mustacchi #define	SPD_KEY_DDR5_RFM_RAAIMT_SEC	"ddr5.rfm.sec-raaimt"
488*fe82ebb0SRobert Mustacchi #define	SPD_KEY_DDR5_RFM_RAAIMT_FGR_SEC	"ddr5.rfm.sec-raaimt-fgr"
489*fe82ebb0SRobert Mustacchi #define	SPD_KEY_DDR5_RFM_RAAMMT_SEC	"ddr5.rfm.sec-raammt"
490*fe82ebb0SRobert Mustacchi #define	SPD_KEY_DDR5_RFM_RAAMMT_FGR_SEC	"ddr5.rfm.sec-raammt-fgr"
491*fe82ebb0SRobert Mustacchi #define	SPD_KEY_DDR5_RFM_BRC_CFG_SEC	"ddr5.rfm.sec-brc-config"
492*fe82ebb0SRobert Mustacchi #define	SPD_KEY_DDR5_RFM_BRC_SUP_SEC	"ddr5.rfm.sec-brc-level"
493*fe82ebb0SRobert Mustacchi #define	SPD_KEY_DDR5_RFM_RAA_DEC_SEC	"ddr5.rfm.sec-raa-dec"
494*fe82ebb0SRobert Mustacchi 
495*fe82ebb0SRobert Mustacchi #define	SPD_KEY_DDR5_ARFMA_FLAGS_PRI		"ddr5.arfm-a.flags"
496*fe82ebb0SRobert Mustacchi #define	SPD_KEY_DDR5_ARFMA_RAAIMT_PRI		"ddr5.arfm-a.raaimt"
497*fe82ebb0SRobert Mustacchi #define	SPD_KEY_DDR5_ARFMA_RAAIMT_FGR_PRI	"ddr5.arfm-a.raaimt-fgr"
498*fe82ebb0SRobert Mustacchi #define	SPD_KEY_DDR5_ARFMA_RAAMMT_PRI		"ddr5.arfm-a.raammt"
499*fe82ebb0SRobert Mustacchi #define	SPD_KEY_DDR5_ARFMA_RAAMMT_FGR_PRI	"ddr5.arfm-a.raammt-fgr"
500*fe82ebb0SRobert Mustacchi #define	SPD_KEY_DDR5_ARFMA_BRC_CFG_PRI		"ddr5.arfm-a.brc-config"
501*fe82ebb0SRobert Mustacchi #define	SPD_KEY_DDR5_ARFMA_BRC_SUP_PRI		"ddr5.arfm-a.brc-level"
502*fe82ebb0SRobert Mustacchi #define	SPD_KEY_DDR5_ARFMA_RAA_DEC_PRI		"ddr5.arfm-a.raa-dec"
503*fe82ebb0SRobert Mustacchi #define	SPD_KEY_DDR5_ARFMA_FLAGS_SEC		"ddr5.arfm-a.sec-flags"
504*fe82ebb0SRobert Mustacchi #define	SPD_KEY_DDR5_ARFMA_RAAIMT_SEC		"ddr5.arfm-a.sec-raaimt"
505*fe82ebb0SRobert Mustacchi #define	SPD_KEY_DDR5_ARFMA_RAAIMT_FGR_SEC	"ddr5.arfm-a.sec-raaimt-fgr"
506*fe82ebb0SRobert Mustacchi #define	SPD_KEY_DDR5_ARFMA_RAAMMT_SEC		"ddr5.arfm-a.sec-raammt"
507*fe82ebb0SRobert Mustacchi #define	SPD_KEY_DDR5_ARFMA_RAAMMT_FGR_SEC	"ddr5.arfm-a.sec-raammt-fgr"
508*fe82ebb0SRobert Mustacchi #define	SPD_KEY_DDR5_ARFMA_BRC_CFG_SEC		"ddr5.arfm-a.sec-brc-config"
509*fe82ebb0SRobert Mustacchi #define	SPD_KEY_DDR5_ARFMA_BRC_SUP_SEC		"ddr5.arfm-a.sec-brc-level"
510*fe82ebb0SRobert Mustacchi #define	SPD_KEY_DDR5_ARFMA_RAA_DEC_SEC		"ddr5.arfm-a.sec-raa-dec"
511*fe82ebb0SRobert Mustacchi 
512*fe82ebb0SRobert Mustacchi #define	SPD_KEY_DDR5_ARFMB_FLAGS_PRI		"ddr5.arfm-b.flags"
513*fe82ebb0SRobert Mustacchi #define	SPD_KEY_DDR5_ARFMB_RAAIMT_PRI		"ddr5.arfm-b.raaimt"
514*fe82ebb0SRobert Mustacchi #define	SPD_KEY_DDR5_ARFMB_RAAIMT_FGR_PRI	"ddr5.arfm-b.raaimt-fgr"
515*fe82ebb0SRobert Mustacchi #define	SPD_KEY_DDR5_ARFMB_RAAMMT_PRI		"ddr5.arfm-b.raammt"
516*fe82ebb0SRobert Mustacchi #define	SPD_KEY_DDR5_ARFMB_RAAMMT_FGR_PRI	"ddr5.arfm-b.raammt-fgr"
517*fe82ebb0SRobert Mustacchi #define	SPD_KEY_DDR5_ARFMB_BRC_CFG_PRI		"ddr5.arfm-b.brc-config"
518*fe82ebb0SRobert Mustacchi #define	SPD_KEY_DDR5_ARFMB_BRC_SUP_PRI		"ddr5.arfm-b.brc-level"
519*fe82ebb0SRobert Mustacchi #define	SPD_KEY_DDR5_ARFMB_RAA_DEC_PRI		"ddr5.arfm-b.raa-dec"
520*fe82ebb0SRobert Mustacchi #define	SPD_KEY_DDR5_ARFMB_FLAGS_SEC		"ddr5.arfm-b.sec-flags"
521*fe82ebb0SRobert Mustacchi #define	SPD_KEY_DDR5_ARFMB_RAAIMT_SEC		"ddr5.arfm-b.sec-raaimt"
522*fe82ebb0SRobert Mustacchi #define	SPD_KEY_DDR5_ARFMB_RAAIMT_FGR_SEC	"ddr5.arfm-b.sec-raaimt-fgr"
523*fe82ebb0SRobert Mustacchi #define	SPD_KEY_DDR5_ARFMB_RAAMMT_SEC		"ddr5.arfm-b.sec-raammt"
524*fe82ebb0SRobert Mustacchi #define	SPD_KEY_DDR5_ARFMB_RAAMMT_FGR_SEC	"ddr5.arfm-b.sec-raammt-fgr"
525*fe82ebb0SRobert Mustacchi #define	SPD_KEY_DDR5_ARFMB_BRC_CFG_SEC		"ddr5.arfm-b.sec-brc-config"
526*fe82ebb0SRobert Mustacchi #define	SPD_KEY_DDR5_ARFMB_BRC_SUP_SEC		"ddr5.arfm-b.sec-brc-level"
527*fe82ebb0SRobert Mustacchi #define	SPD_KEY_DDR5_ARFMB_RAA_DEC_SEC		"ddr5.arfm-b.sec-raa-dec"
528*fe82ebb0SRobert Mustacchi 
529*fe82ebb0SRobert Mustacchi #define	SPD_KEY_DDR5_ARFMC_FLAGS_PRI		"ddr5.arfm-c.flags"
530*fe82ebb0SRobert Mustacchi #define	SPD_KEY_DDR5_ARFMC_RAAIMT_PRI		"ddr5.arfm-c.raaimt"
531*fe82ebb0SRobert Mustacchi #define	SPD_KEY_DDR5_ARFMC_RAAIMT_FGR_PRI	"ddr5.arfm-c.raaimt-fgr"
532*fe82ebb0SRobert Mustacchi #define	SPD_KEY_DDR5_ARFMC_RAAMMT_PRI		"ddr5.arfm-c.raammt"
533*fe82ebb0SRobert Mustacchi #define	SPD_KEY_DDR5_ARFMC_RAAMMT_FGR_PRI	"ddr5.arfm-c.raammt-fgr"
534*fe82ebb0SRobert Mustacchi #define	SPD_KEY_DDR5_ARFMC_BRC_CFG_PRI		"ddr5.arfm-c.brc-config"
535*fe82ebb0SRobert Mustacchi #define	SPD_KEY_DDR5_ARFMC_BRC_SUP_PRI		"ddr5.arfm-c.brc-level"
536*fe82ebb0SRobert Mustacchi #define	SPD_KEY_DDR5_ARFMC_RAA_DEC_PRI		"ddr5.arfm-c.raa-dec"
537*fe82ebb0SRobert Mustacchi #define	SPD_KEY_DDR5_ARFMC_FLAGS_SEC		"ddr5.arfm-c.sec-flags"
538*fe82ebb0SRobert Mustacchi #define	SPD_KEY_DDR5_ARFMC_RAAIMT_SEC		"ddr5.arfm-c.sec-raaimt"
539*fe82ebb0SRobert Mustacchi #define	SPD_KEY_DDR5_ARFMC_RAAIMT_FGR_SEC	"ddr5.arfm-c.sec-raaimt-fgr"
540*fe82ebb0SRobert Mustacchi #define	SPD_KEY_DDR5_ARFMC_RAAMMT_SEC		"ddr5.arfm-c.sec-raammt"
541*fe82ebb0SRobert Mustacchi #define	SPD_KEY_DDR5_ARFMC_RAAMMT_FGR_SEC	"ddr5.arfm-c.sec-raammt-fgr"
542*fe82ebb0SRobert Mustacchi #define	SPD_KEY_DDR5_ARFMC_BRC_CFG_SEC		"ddr5.arfm-c.sec-brc-config"
543*fe82ebb0SRobert Mustacchi #define	SPD_KEY_DDR5_ARFMC_BRC_SUP_SEC		"ddr5.arfm-c.sec-brc-level"
544*fe82ebb0SRobert Mustacchi #define	SPD_KEY_DDR5_ARFMC_RAA_DEC_SEC		"ddr5.arfm-c.sec-raa-dec"
545*fe82ebb0SRobert Mustacchi /*
546*fe82ebb0SRobert Mustacchi  * Module-type specific keys and values. These are often the intersection of
547*fe82ebb0SRobert Mustacchi  * both the DDR standard and the module type. That is, a DDR4 and DDR5 RDIMM
548*fe82ebb0SRobert Mustacchi  * expose some information that isn't quite the same. These often contain things
549*fe82ebb0SRobert Mustacchi  * that are drive strengths and slew rates. These kinds of items fall into two
550*fe82ebb0SRobert Mustacchi  * categories. Ones where there is a fixed resistance and one where there is a
551*fe82ebb0SRobert Mustacchi  * qualitative range that depends on things like the specific parts present.
552*fe82ebb0SRobert Mustacchi  */
553*fe82ebb0SRobert Mustacchi typedef enum {
554*fe82ebb0SRobert Mustacchi 	SPD_DRIVE_LIGHT,
555*fe82ebb0SRobert Mustacchi 	SPD_DRIVE_MODERATE,
556*fe82ebb0SRobert Mustacchi 	SPD_DRIVE_STRONG,
557*fe82ebb0SRobert Mustacchi 	SPD_DRIVE_VERY_STRONG
558*fe82ebb0SRobert Mustacchi } spd_drive_t;
559*fe82ebb0SRobert Mustacchi 
560*fe82ebb0SRobert Mustacchi typedef enum {
561*fe82ebb0SRobert Mustacchi 	SPD_SLEW_SLOW,
562*fe82ebb0SRobert Mustacchi 	SPD_SLEW_MODERATE,
563*fe82ebb0SRobert Mustacchi 	SPD_SLEW_FAST
564*fe82ebb0SRobert Mustacchi } spd_slew_t;
565*fe82ebb0SRobert Mustacchi 
566*fe82ebb0SRobert Mustacchi /*
567*fe82ebb0SRobert Mustacchi  * DDR4 RDIMM drive strengths. These all use the spd_drive_t. These are all on
568*fe82ebb0SRobert Mustacchi  * the RCD. There is also a key for whether or not slew-control is supported.
569*fe82ebb0SRobert Mustacchi  */
570*fe82ebb0SRobert Mustacchi #define	SPD_KEY_DDR4_RCD_SLEW	"ddr4.rdimm.rcd-slew-control"	/* key */
571*fe82ebb0SRobert Mustacchi #define	SPD_KEY_DDR4_RCD_DS_CKE	"ddr4.rdimm.cke-drive-strength"
572*fe82ebb0SRobert Mustacchi #define	SPD_KEY_DDR4_RCD_DS_ODT	"ddr4.rdimm.odt-drive-strength"
573*fe82ebb0SRobert Mustacchi #define	SPD_KEY_DDR4_RCD_DS_CA	"ddr4.rdimm.ca-drive-strength"
574*fe82ebb0SRobert Mustacchi #define	SPD_KEY_DDR4_RCD_DS_CS	"ddr4.rdimm.cs-drive-strength"
575*fe82ebb0SRobert Mustacchi #define	SPD_KEY_DDR4_RCD_DS_Y0	"ddr4.rdimm.y0-drive-strength"
576*fe82ebb0SRobert Mustacchi #define	SPD_KEY_DDR4_RCD_DS_Y1	"ddr4.rdimm.y1-drive-strength"
577*fe82ebb0SRobert Mustacchi #define	SPD_KEY_DDR4_RCD_DS_BCOM	"ddr4.lrdimm.bcom-drive-strength"
578*fe82ebb0SRobert Mustacchi #define	SPD_KEY_DDR4_RCD_DS_BCK	"ddr4.lrdimm.bck-drive-strength"
579*fe82ebb0SRobert Mustacchi 
580*fe82ebb0SRobert Mustacchi /*
581*fe82ebb0SRobert Mustacchi  * DDR4 LRDIMMs specify the VrefDQ for each package rank. These are communicated
582*fe82ebb0SRobert Mustacchi  * in terms of the DDR4 spec which specifies them as a percentage of the actual
583*fe82ebb0SRobert Mustacchi  * voltage. This is always phrased in the spec as AB.CD%, so for example 60.25%.
584*fe82ebb0SRobert Mustacchi  * We treat this percentage as a four digit unsigned value rather than trying to
585*fe82ebb0SRobert Mustacchi  * play games with whether or not the value can be represented in floating
586*fe82ebb0SRobert Mustacchi  * point. Divide the value by 100 to get the percentage. That is, 47.60% will be
587*fe82ebb0SRobert Mustacchi  * encoded as 4760. All of these values are a uint32_t.
588*fe82ebb0SRobert Mustacchi  */
589*fe82ebb0SRobert Mustacchi #define	SPD_KEY_DDR4_VREFDQ_R0	"ddr4.lrdimm.VrefDQ-rank0"
590*fe82ebb0SRobert Mustacchi #define	SPD_KEY_DDR4_VREFDQ_R1	"ddr4.lrdimm.VrefDQ-rank1"
591*fe82ebb0SRobert Mustacchi #define	SPD_KEY_DDR4_VREFDQ_R2	"ddr4.lrdimm.VrefDQ-rank2"
592*fe82ebb0SRobert Mustacchi #define	SPD_KEY_DDR4_VREFDQ_R3	"ddr4.lrdimm.VrefDQ-rank3"
593*fe82ebb0SRobert Mustacchi #define	SPD_KEY_DDR4_VREFDQ_DB	"ddr4.lrdimm.VrefDQ-db"
594*fe82ebb0SRobert Mustacchi 
595*fe82ebb0SRobert Mustacchi /*
596*fe82ebb0SRobert Mustacchi  * DDR4 LRDIMMs define the data buffer drive strength and termination in terms
597*fe82ebb0SRobert Mustacchi  * of various data rate ranges. Specifically (0, 1866], (1866, 2400], and (2400,
598*fe82ebb0SRobert Mustacchi  * 3200]. All of these values are measured in terms of Ohms. As such, all of
599*fe82ebb0SRobert Mustacchi  * these values are an array of three uint32_t's whose values correspond to each
600*fe82ebb0SRobert Mustacchi  * of those ranges. We define a few additional values for these to represent
601*fe82ebb0SRobert Mustacchi  * cases where they are disabled or high-impedance.
602*fe82ebb0SRobert Mustacchi  */
603*fe82ebb0SRobert Mustacchi #define	SPD_KEY_DDR4_TERM_DISABLED	0
604*fe82ebb0SRobert Mustacchi #define	SPD_KEY_DDR4_TERM_HIZ		UINT32_MAX
605*fe82ebb0SRobert Mustacchi #define	SPD_KEY_DDR4_MDQ_RTT	"ddr4.lrdimm.mdq-read-termination"
606*fe82ebb0SRobert Mustacchi #define	SPD_KEY_DDR4_MDQ_DS	"ddr4.lrdimm.mdq-drive-strength"
607*fe82ebb0SRobert Mustacchi #define	SPD_KEY_DDR4_DRAM_DS	"ddr4.lrdimm.dram-drive-strength"
608*fe82ebb0SRobert Mustacchi #define	SPD_KEY_DDR4_RTT_WR	"ddr4.lrdimm.odt-read-termination-wr"
609*fe82ebb0SRobert Mustacchi #define	SPD_KEY_DDR4_RTT_NOM	"ddr4.lrdimm.odt-read-termination-nom"
610*fe82ebb0SRobert Mustacchi #define	SPD_KEY_DDR4_RTT_PARK_R0	"ddr4.lrdimm.odt-r0_1-rtt-park"
611*fe82ebb0SRobert Mustacchi #define	SPD_KEY_DDR4_RTT_PARK_R2	"ddr4.lrdimm.odt-r2_3-rtt-park"
612*fe82ebb0SRobert Mustacchi 
613*fe82ebb0SRobert Mustacchi /*
614*fe82ebb0SRobert Mustacchi  * The last DDR4 LRDIMM specific component is whether or not the data buffer's
615*fe82ebb0SRobert Mustacchi  * gain and decision feedback equalization are supported. These both are keys.
616*fe82ebb0SRobert Mustacchi  */
617*fe82ebb0SRobert Mustacchi #define	SPD_KEY_DDR4_DB_GAIN	"ddr4.lrdimm.db-gain-adjustment"
618*fe82ebb0SRobert Mustacchi #define	SPD_KEY_DDR4_DB_DFE	"ddr4.lrdimm.decision-feedback-eq"
619*fe82ebb0SRobert Mustacchi 
620*fe82ebb0SRobert Mustacchi /*
621*fe82ebb0SRobert Mustacchi  * DDR5 RDIMMs and LRDIMMs have specific enables for groups of pins. There are
622*fe82ebb0SRobert Mustacchi  * then
623*fe82ebb0SRobert Mustacchi  * differential impedence measurements. These are all in Ohms. Separately there
624*fe82ebb0SRobert Mustacchi  * are slew rates, those use the spd_slew_t. Because these use different units
625*fe82ebb0SRobert Mustacchi  * between DDR4 and DDR5, we treat them as different keys.
626*fe82ebb0SRobert Mustacchi  */
627*fe82ebb0SRobert Mustacchi #define	SPD_KEY_DDR5_RCD_QACK_EN	"ddr5.rdimm.rcd-qack-enabled"
628*fe82ebb0SRobert Mustacchi #define	SPD_KEY_DDR5_RCD_QBCK_EN	"ddr5.rdimm.rcd-qbck-enabled"
629*fe82ebb0SRobert Mustacchi #define	SPD_KEY_DDR5_RCD_QCCK_EN	"ddr5.rdimm.rcd-qcck-enabled"
630*fe82ebb0SRobert Mustacchi #define	SPD_KEY_DDR5_RCD_QDCK_EN	"ddr5.rdimm.rcd-qdck-enabled"
631*fe82ebb0SRobert Mustacchi #define	SPD_KEY_DDR5_RCD_BCK_EN		"ddr5.rdimm.rcd-bck-enabled"
632*fe82ebb0SRobert Mustacchi #define	SPD_KEY_DDR5_RCD_QACA_EN	"ddr5.rdimm.rcd-qaca-enabled"
633*fe82ebb0SRobert Mustacchi #define	SPD_KEY_DDR5_RCD_QBCA_EN	"ddr5.rdimm.rcd-qbca-enabled"
634*fe82ebb0SRobert Mustacchi #define	SPD_KEY_DDR5_RCD_DCS1_EN	"ddr5.rdimm.rcd-dcs1-enabled"
635*fe82ebb0SRobert Mustacchi #define	SPD_KEY_DDR5_RCD_QxCA13_EN	"ddr5.rdimm.rcd-qxca13-enabled"
636*fe82ebb0SRobert Mustacchi #define	SPD_KEY_DDR5_RCD_QACS_EN	"ddr5.rdimm.rcd-qacs-enabled"
637*fe82ebb0SRobert Mustacchi #define	SPD_KEY_DDR5_RCD_QBCS_EN	"ddr5.rdimm.rcd-qbcs-enabled"
638*fe82ebb0SRobert Mustacchi 
639*fe82ebb0SRobert Mustacchi /* Impedence measurements are uint32_t's in Ohms */
640*fe82ebb0SRobert Mustacchi #define	SPD_KEY_DDR5_RCD_QACK_IMP	"ddr5.rdimm.rcd-qack-impedance"
641*fe82ebb0SRobert Mustacchi #define	SPD_KEY_DDR5_RCD_QBCK_IMP	"ddr5.rdimm.rcd-qbck-impedance"
642*fe82ebb0SRobert Mustacchi #define	SPD_KEY_DDR5_RCD_QCCK_IMP	"ddr5.rdimm.rcd-qcck-impedance"
643*fe82ebb0SRobert Mustacchi #define	SPD_KEY_DDR5_RCD_QDCK_IMP	"ddr5.rdimm.rcd-qdck-impedance"
644*fe82ebb0SRobert Mustacchi #define	SPD_KEY_DDR5_RCD_CS_IMP		"ddr5.rdimm.rcd-cs-impedance"
645*fe82ebb0SRobert Mustacchi #define	SPD_KEY_DDR5_RCD_CA_IMP		"ddr5.rdimm.rcd-ca-impedance"
646*fe82ebb0SRobert Mustacchi 
647*fe82ebb0SRobert Mustacchi /* Slew rates use the spd_rate_t encoded as a uint32_t */
648*fe82ebb0SRobert Mustacchi #define	SPD_KEY_DDR5_RCD_QCK_SLEW	"ddr5.rdimm.rcd-qck-slew"
649*fe82ebb0SRobert Mustacchi #define	SPD_KEY_DDR5_RCD_QCA_SLEW	"ddr5.rdimm.rcd-qck-slew"
650*fe82ebb0SRobert Mustacchi #define	SPD_KEY_DDR5_RCD_QCS_SLEW	"ddr5.rdimm.rcd-qcs-slew"
651*fe82ebb0SRobert Mustacchi 
652*fe82ebb0SRobert Mustacchi /*
653*fe82ebb0SRobert Mustacchi  * These are all speific to DDR5 LRDIMMs. The values are the same as above. In
654*fe82ebb0SRobert Mustacchi  * particular, the DWS RTT values are also in Ohms. If RTT termination is
655*fe82ebb0SRobert Mustacchi  * disabled then the key will not be present.
656*fe82ebb0SRobert Mustacchi  */
657*fe82ebb0SRobert Mustacchi #define	SPD_KEY_DDR5_RCD_BCS_EN		"ddr5.lrdimm.rcd-bcs-enabled" /* key */
658*fe82ebb0SRobert Mustacchi #define	SPD_KEY_DDR5_RCD_BCOM_IMP	"ddr5.lrdimm.rcd-bcom-impedance"
659*fe82ebb0SRobert Mustacchi #define	SPD_KEY_DDR5_RCD_BCK_IMP	"ddr5.lrdimm.rcd-bck-impedance"
660*fe82ebb0SRobert Mustacchi #define	SPD_KEY_DDR5_RCD_RTT_TERM	"ddr5.lrdimm.rcd-dqs-rtt"
661*fe82ebb0SRobert Mustacchi #define	SPD_KEY_DDR5_RCD_BCOM_SLEW	"ddr5.lrdimm.rcd-bcom-slew"
662*fe82ebb0SRobert Mustacchi #define	SPD_KEY_DDR5_RCD_BCK_SLEW	"ddr5.lrdimm.rcd-bck-slew"
663*fe82ebb0SRobert Mustacchi 
664*fe82ebb0SRobert Mustacchi 
665*fe82ebb0SRobert Mustacchi /*
666*fe82ebb0SRobert Mustacchi  * Module Properties. These are items that generally relate to the module as a
667*fe82ebb0SRobert Mustacchi  * whole.
668*fe82ebb0SRobert Mustacchi  */
669*fe82ebb0SRobert Mustacchi 
670*fe82ebb0SRobert Mustacchi /*
671*fe82ebb0SRobert Mustacchi  * Connection Mapping. In DDR4 there is the ability to remap groups of pins from
672*fe82ebb0SRobert Mustacchi  * the connector to the various package SDRAMs. Every 4 bits can be remapped to
673*fe82ebb0SRobert Mustacchi  * either another upper or lower nibble in a package. Separately bits can also
674*fe82ebb0SRobert Mustacchi  * be flipped between packages. These exist for all 64-bits of DQ and 8 bits of
675*fe82ebb0SRobert Mustacchi  * CBs. If mirroring is set, then a key will be added for that pin group. For
676*fe82ebb0SRobert Mustacchi  * each pin group, the mapping to a specific type of rewriting will be done. We
677*fe82ebb0SRobert Mustacchi  * conventionally use 0, 1, 2, and 3 as the lower nibble and 4, 5, 6, 7 as the
678*fe82ebb0SRobert Mustacchi  * upper nibble, though the actual pins will vary based on where they are.
679*fe82ebb0SRobert Mustacchi  */
680*fe82ebb0SRobert Mustacchi #define	SPD_KEY_DDR4_MAP_DQ0	"module.dq0-map"	/* uint32_t [4] */
681*fe82ebb0SRobert Mustacchi #define	SPD_KEY_DDR4_MAP_DQ4	"module.dq4-map"	/* uint32_t [4] */
682*fe82ebb0SRobert Mustacchi #define	SPD_KEY_DDR4_MAP_DQ8	"module.dq8-map"	/* uint32_t [4] */
683*fe82ebb0SRobert Mustacchi #define	SPD_KEY_DDR4_MAP_DQ12	"module.dq12-map"	/* uint32_t [4] */
684*fe82ebb0SRobert Mustacchi #define	SPD_KEY_DDR4_MAP_DQ16	"module.dq16-map"	/* uint32_t [4] */
685*fe82ebb0SRobert Mustacchi #define	SPD_KEY_DDR4_MAP_DQ20	"module.dq20-map"	/* uint32_t [4] */
686*fe82ebb0SRobert Mustacchi #define	SPD_KEY_DDR4_MAP_DQ24	"module.dq24-map"	/* uint32_t [4] */
687*fe82ebb0SRobert Mustacchi #define	SPD_KEY_DDR4_MAP_DQ28	"module.dq28-map"	/* uint32_t [4] */
688*fe82ebb0SRobert Mustacchi #define	SPD_KEY_DDR4_MAP_DQ32	"module.dq32-map"	/* uint32_t [4] */
689*fe82ebb0SRobert Mustacchi #define	SPD_KEY_DDR4_MAP_DQ36	"module.dq36-map"	/* uint36_t [4] */
690*fe82ebb0SRobert Mustacchi #define	SPD_KEY_DDR4_MAP_DQ40	"module.dq40-map"	/* uint32_t [4] */
691*fe82ebb0SRobert Mustacchi #define	SPD_KEY_DDR4_MAP_DQ44	"module.dq44-map"	/* uint32_t [4] */
692*fe82ebb0SRobert Mustacchi #define	SPD_KEY_DDR4_MAP_DQ48	"module.dq48-map"	/* uint32_t [4] */
693*fe82ebb0SRobert Mustacchi #define	SPD_KEY_DDR4_MAP_DQ52	"module.dq52-map"	/* uint32_t [4] */
694*fe82ebb0SRobert Mustacchi #define	SPD_KEY_DDR4_MAP_DQ56	"module.dq56-map"	/* uint32_t [4] */
695*fe82ebb0SRobert Mustacchi #define	SPD_KEY_DDR4_MAP_DQ60	"module.dq60-map"	/* uint32_t [4] */
696*fe82ebb0SRobert Mustacchi #define	SPD_KEY_DDR4_MAP_CB0	"module.dq0-map"	/* uint32_t [4] */
697*fe82ebb0SRobert Mustacchi #define	SPD_KEY_DDR4_MAP_CB4	"module.dq4-map"	/* uint32_t [4] */
698*fe82ebb0SRobert Mustacchi 
699*fe82ebb0SRobert Mustacchi /*
700*fe82ebb0SRobert Mustacchi  * In addition, there is module level mapping in DDR4 that is used to indicate
701*fe82ebb0SRobert Mustacchi  * that odd ranks are mirrored. This is between the edge connector and the DRAM
702*fe82ebb0SRobert Mustacchi  * itself. We only add a key when it is mirrored.
703*fe82ebb0SRobert Mustacchi  */
704*fe82ebb0SRobert Mustacchi #define	SPD_KEY_DDR4_MIRROR	"module.edge-odd-mirror"	/* key */
705*fe82ebb0SRobert Mustacchi 
706*fe82ebb0SRobert Mustacchi /*
707*fe82ebb0SRobert Mustacchi  * Present devices. Modules often have multiple additional types of devices
708*fe82ebb0SRobert Mustacchi  * present like temperature sensors, voltage regulators, registers, etc. The
709*fe82ebb0SRobert Mustacchi  * following key indicates what all is present on this DIMM. Depending on the
710*fe82ebb0SRobert Mustacchi  * DDR revision, we will then have additional keys with its ID, revision, name,
711*fe82ebb0SRobert Mustacchi  * and compliant type. In a few cases we will define the type and presence based
712*fe82ebb0SRobert Mustacchi  * on information. For example, DDR4 only allows a single type of temperature
713*fe82ebb0SRobert Mustacchi  * sensor or SPD device. Even though we don't know the manufacturer, we will
714*fe82ebb0SRobert Mustacchi  * still note this.
715*fe82ebb0SRobert Mustacchi  *
716*fe82ebb0SRobert Mustacchi  * Each of these items will have four keys. One for the manufacturer ID, one for
717*fe82ebb0SRobert Mustacchi  * their string name, one for the device type, and one for the revision. Note,
718*fe82ebb0SRobert Mustacchi  * while TS1 and TS2 are both flags in DDR5, they share common manufacturer
719*fe82ebb0SRobert Mustacchi  * information, which is why there is only one entry here.
720*fe82ebb0SRobert Mustacchi  *
721*fe82ebb0SRobert Mustacchi  * For each device type there is a separate enum with supported types of devices
722*fe82ebb0SRobert Mustacchi  * that can be present for these.
723*fe82ebb0SRobert Mustacchi  */
724*fe82ebb0SRobert Mustacchi typedef enum {
725*fe82ebb0SRobert Mustacchi 	SPD_DEVICE_TEMP_1	= 1 << 0,
726*fe82ebb0SRobert Mustacchi 	SPD_DEVICE_TEMP_2	= 1 << 1,
727*fe82ebb0SRobert Mustacchi 	SPD_DEVICE_HS		= 1 << 2,
728*fe82ebb0SRobert Mustacchi 	SPD_DEVICE_PMIC_0	= 1 << 3,
729*fe82ebb0SRobert Mustacchi 	SPD_DEVICE_PMIC_1	= 1 << 4,
730*fe82ebb0SRobert Mustacchi 	SPD_DEVICE_PMIC_2	= 1 << 5,
731*fe82ebb0SRobert Mustacchi 	SPD_DEVICE_CD		= 1 << 6,
732*fe82ebb0SRobert Mustacchi 	SPD_DEVICE_RCD		= 1 << 7,
733*fe82ebb0SRobert Mustacchi 	SPD_DEVICE_DB		= 1 << 8,
734*fe82ebb0SRobert Mustacchi 	SPD_DEVICE_MRCD		= 1 << 9,
735*fe82ebb0SRobert Mustacchi 	SPD_DEVICE_MDB		= 1 << 10,
736*fe82ebb0SRobert Mustacchi 	SPD_DEVICE_DMB		= 1 << 11,
737*fe82ebb0SRobert Mustacchi 	SPD_DEVICE_SPD		= 1 << 12
738*fe82ebb0SRobert Mustacchi } spd_device_t;
739*fe82ebb0SRobert Mustacchi #define	SPD_KEY_DEVS		"module.devices"	/* uint32_t */
740*fe82ebb0SRobert Mustacchi 
741*fe82ebb0SRobert Mustacchi typedef enum {
742*fe82ebb0SRobert Mustacchi 	/* DDR3 */
743*fe82ebb0SRobert Mustacchi 	SPD_TEMP_T_TSE2002,
744*fe82ebb0SRobert Mustacchi 	/* DDR4 and LPDDR4 */
745*fe82ebb0SRobert Mustacchi 	SPD_TEMP_T_TSE2004av,
746*fe82ebb0SRobert Mustacchi 	/* DDR5 */
747*fe82ebb0SRobert Mustacchi 	SPD_TEMP_T_TS5111,
748*fe82ebb0SRobert Mustacchi 	SPD_TEMP_T_TS5110
749*fe82ebb0SRobert Mustacchi } spd_temp_type_t;
750*fe82ebb0SRobert Mustacchi 
751*fe82ebb0SRobert Mustacchi typedef enum {
752*fe82ebb0SRobert Mustacchi 	/* DDR5 */
753*fe82ebb0SRobert Mustacchi 	SPD_PMIC_T_PMIC5000,
754*fe82ebb0SRobert Mustacchi 	SPD_PMIC_T_PMIC5010,
755*fe82ebb0SRobert Mustacchi 	SPD_PMIC_T_PMIC5100
756*fe82ebb0SRobert Mustacchi } spd_pmic_type_t;
757*fe82ebb0SRobert Mustacchi 
758*fe82ebb0SRobert Mustacchi typedef enum {
759*fe82ebb0SRobert Mustacchi 	/* DDR5 */
760*fe82ebb0SRobert Mustacchi 	SPD_CD_T_DDR5CK01
761*fe82ebb0SRobert Mustacchi } spd_cd_type_t;
762*fe82ebb0SRobert Mustacchi 
763*fe82ebb0SRobert Mustacchi typedef enum {
764*fe82ebb0SRobert Mustacchi 	/* DDR3 */
765*fe82ebb0SRobert Mustacchi 	SPD_RCD_T_SSTE32882,
766*fe82ebb0SRobert Mustacchi 	/* DDR4 */
767*fe82ebb0SRobert Mustacchi 	SPD_RCD_T_DDR4RCD01,
768*fe82ebb0SRobert Mustacchi 	SPD_RCD_T_DDR4RCD02,
769*fe82ebb0SRobert Mustacchi 	/* DDR5 */
770*fe82ebb0SRobert Mustacchi 	SPD_RCD_T_DDR5RCD01,
771*fe82ebb0SRobert Mustacchi 	SPD_RCD_T_DDR5RCD02,
772*fe82ebb0SRobert Mustacchi 	SPD_RCD_T_DDR5RCD03
773*fe82ebb0SRobert Mustacchi } spd_rcd_type_t;
774*fe82ebb0SRobert Mustacchi 
775*fe82ebb0SRobert Mustacchi typedef enum {
776*fe82ebb0SRobert Mustacchi 	/* DDR4 */
777*fe82ebb0SRobert Mustacchi 	SPD_DB_T_DDR4DB01,
778*fe82ebb0SRobert Mustacchi 	SPD_DB_T_DDR4DB02,
779*fe82ebb0SRobert Mustacchi 	/* DDR5 */
780*fe82ebb0SRobert Mustacchi 	SPD_DB_T_DDR5DB01,
781*fe82ebb0SRobert Mustacchi 	SPD_DB_T_DDR5DB02
782*fe82ebb0SRobert Mustacchi } spd_db_type_t;
783*fe82ebb0SRobert Mustacchi 
784*fe82ebb0SRobert Mustacchi typedef enum {
785*fe82ebb0SRobert Mustacchi 	/* DDR5 */
786*fe82ebb0SRobert Mustacchi 	SPD_MRCD_T_DDR5MRCD01
787*fe82ebb0SRobert Mustacchi } spd_mrcd_type_t;
788*fe82ebb0SRobert Mustacchi 
789*fe82ebb0SRobert Mustacchi typedef enum {
790*fe82ebb0SRobert Mustacchi 	/* DDR5 */
791*fe82ebb0SRobert Mustacchi 	SPD_MDB_T_DDR5MDB01
792*fe82ebb0SRobert Mustacchi } spd_mdb_type_t;
793*fe82ebb0SRobert Mustacchi 
794*fe82ebb0SRobert Mustacchi typedef enum {
795*fe82ebb0SRobert Mustacchi 	/* DDR5 */
796*fe82ebb0SRobert Mustacchi 	SPD_DMB_T_DMB5011
797*fe82ebb0SRobert Mustacchi } spd_dmb_type_t;
798*fe82ebb0SRobert Mustacchi 
799*fe82ebb0SRobert Mustacchi typedef enum {
800*fe82ebb0SRobert Mustacchi 	/* DDR4 */
801*fe82ebb0SRobert Mustacchi 	SPD_SPD_T_EE1004,
802*fe82ebb0SRobert Mustacchi 	/* DDR5 */
803*fe82ebb0SRobert Mustacchi 	SPD_SPD_T_SPD5118,
804*fe82ebb0SRobert Mustacchi 	SPD_SPD_T_ESPD5216
805*fe82ebb0SRobert Mustacchi } spd_spd_type_t;
806*fe82ebb0SRobert Mustacchi 
807*fe82ebb0SRobert Mustacchi #define	SPD_KEY_DEV_TEMP_MFG	"module.temp.mfg-id"	/* uint32_t [2] */
808*fe82ebb0SRobert Mustacchi #define	SPD_KEY_DEV_TEMP_MFG_NAME	"module.temp.mfg-name"	/* string */
809*fe82ebb0SRobert Mustacchi #define	SPD_KEY_DEV_TEMP_TYPE	"module.temp.type"	/* uint32_t */
810*fe82ebb0SRobert Mustacchi #define	SPD_KEY_DEV_TEMP_REV	"module.temp.revision"	/* string */
811*fe82ebb0SRobert Mustacchi 
812*fe82ebb0SRobert Mustacchi #define	SPD_KEY_DEV_PMIC0_MFG	"module.pmic0.mfg-id"	/* uint32_t [2] */
813*fe82ebb0SRobert Mustacchi #define	SPD_KEY_DEV_PMIC0_MFG_NAME	"module.pmic0.mfg-name"	/* string */
814*fe82ebb0SRobert Mustacchi #define	SPD_KEY_DEV_PMIC0_TYPE	"module.pmic0.type"	/* uint32_t */
815*fe82ebb0SRobert Mustacchi #define	SPD_KEY_DEV_PMIC0_REV	"module.pmic0.revision"	/* string */
816*fe82ebb0SRobert Mustacchi #define	SPD_KEY_DEV_PMIC1_MFG	"module.pmic1.mfg-id"	/* uint32_t [2] */
817*fe82ebb0SRobert Mustacchi #define	SPD_KEY_DEV_PMIC1_MFG_NAME	"module.pmic1.mfg-name"	/* string */
818*fe82ebb0SRobert Mustacchi #define	SPD_KEY_DEV_PMIC1_TYPE	"module.pmic1.type"	/* uint32_t */
819*fe82ebb0SRobert Mustacchi #define	SPD_KEY_DEV_PMIC1_REV	"module.pmic1.revision"	/* string */
820*fe82ebb0SRobert Mustacchi #define	SPD_KEY_DEV_PMIC2_MFG	"module.pmic2.mfg-id"	/* uint32_t [2] */
821*fe82ebb0SRobert Mustacchi #define	SPD_KEY_DEV_PMIC2_MFG_NAME	"module.pmic2.mfg-name"	/* string */
822*fe82ebb0SRobert Mustacchi #define	SPD_KEY_DEV_PMIC2_TYPE	"module.pmic2.type"	/* uint32_t */
823*fe82ebb0SRobert Mustacchi #define	SPD_KEY_DEV_PMIC2_REV	"module.pmic2.revision"	/* string */
824*fe82ebb0SRobert Mustacchi 
825*fe82ebb0SRobert Mustacchi #define	SPD_KEY_DEV_CD_MFG	"module.cd.mfg-id"	/* uint32_t [2] */
826*fe82ebb0SRobert Mustacchi #define	SPD_KEY_DEV_CD_MFG_NAME	"module.cd.mfg-name"	/* string */
827*fe82ebb0SRobert Mustacchi #define	SPD_KEY_DEV_CD_TYPE	"module.cd.type"	/* uint32_t */
828*fe82ebb0SRobert Mustacchi #define	SPD_KEY_DEV_CD_REV	"module.cd.revision"	/* string */
829*fe82ebb0SRobert Mustacchi 
830*fe82ebb0SRobert Mustacchi #define	SPD_KEY_DEV_RCD_MFG	"module.rcd.mfg-id"	/* uint32_t [2] */
831*fe82ebb0SRobert Mustacchi #define	SPD_KEY_DEV_RCD_MFG_NAME	"module.rcd.mfg-name"	/* string */
832*fe82ebb0SRobert Mustacchi #define	SPD_KEY_DEV_RCD_TYPE	"module.rcd.type"	/* uint32_t */
833*fe82ebb0SRobert Mustacchi #define	SPD_KEY_DEV_RCD_REV	"module.rcd.revision"	/* string */
834*fe82ebb0SRobert Mustacchi 
835*fe82ebb0SRobert Mustacchi #define	SPD_KEY_DEV_DB_MFG	"module.db.mfg-id"	/* uint32_t [2] */
836*fe82ebb0SRobert Mustacchi #define	SPD_KEY_DEV_DB_MFG_NAME	"module.db.mfg-name"	/* string */
837*fe82ebb0SRobert Mustacchi #define	SPD_KEY_DEV_DB_TYPE	"module.db.type"	/* uint32_t */
838*fe82ebb0SRobert Mustacchi #define	SPD_KEY_DEV_DB_REV	"module.db.revision"	/* string */
839*fe82ebb0SRobert Mustacchi 
840*fe82ebb0SRobert Mustacchi #define	SPD_KEY_DEV_MRCD_MFG	"module.mrcd.mfg-id"	/* uint32_t [2] */
841*fe82ebb0SRobert Mustacchi #define	SPD_KEY_DEV_MRCD_MFG_NAME	"module.mrcd.mfg-name"	/* string */
842*fe82ebb0SRobert Mustacchi #define	SPD_KEY_DEV_MRCD_TYPE	"module.mrcd.type"	/* uint32_t */
843*fe82ebb0SRobert Mustacchi #define	SPD_KEY_DEV_MRCD_REV	"module.mrcd.revision"	/* string */
844*fe82ebb0SRobert Mustacchi 
845*fe82ebb0SRobert Mustacchi #define	SPD_KEY_DEV_MDB_MFG	"module.mdb.mfg-id"	/* uint32_t [2] */
846*fe82ebb0SRobert Mustacchi #define	SPD_KEY_DEV_MDB_MFG_NAME	"module.mdb.mfg-name"	/* string */
847*fe82ebb0SRobert Mustacchi #define	SPD_KEY_DEV_MDB_TYPE	"module.mdb.type"	/* uint32_t */
848*fe82ebb0SRobert Mustacchi #define	SPD_KEY_DEV_MDB_REV	"module.mdb.revision"	/* string */
849*fe82ebb0SRobert Mustacchi 
850*fe82ebb0SRobert Mustacchi #define	SPD_KEY_DEV_DMB_MFG	"module.dmb.mfg-id"	/* uint32_t [2] */
851*fe82ebb0SRobert Mustacchi #define	SPD_KEY_DEV_DMB_MFG_NAME	"module.dmb.mfg-name"	/* string */
852*fe82ebb0SRobert Mustacchi #define	SPD_KEY_DEV_DMB_TYPE	"module.dmb.type"	/* uint32_t */
853*fe82ebb0SRobert Mustacchi #define	SPD_KEY_DEV_DMB_REV	"module.dmb.revision"	/* string */
854*fe82ebb0SRobert Mustacchi 
855*fe82ebb0SRobert Mustacchi #define	SPD_KEY_DEV_SPD_MFG	"module.spd.mfg-id"	/* uint32_t [2] */
856*fe82ebb0SRobert Mustacchi #define	SPD_KEY_DEV_SPD_MFG_NAME	"module.spd.mfg-name"	/* string */
857*fe82ebb0SRobert Mustacchi #define	SPD_KEY_DEV_SPD_TYPE	"module.spd.type"	/* uint32_t */
858*fe82ebb0SRobert Mustacchi #define	SPD_KEY_DEV_SPD_REV	"module.spd.revision"	/* string */
859*fe82ebb0SRobert Mustacchi 
860*fe82ebb0SRobert Mustacchi /*
861*fe82ebb0SRobert Mustacchi  * Module physical dimensions. DRAM modules provide information about their
862*fe82ebb0SRobert Mustacchi  * height and their front and back thicknesses. All values are in millimeters.
863*fe82ebb0SRobert Mustacchi  * In general, values are defined as 1 mm ranges in the form such as 18mm <
864*fe82ebb0SRobert Mustacchi  * height <= 19mm or 2mm < thickness <= 3mm. As such in all these ranges we
865*fe82ebb0SRobert Mustacchi  * encode it as the less than or equal to side of the thickness or height.
866*fe82ebb0SRobert Mustacchi  *
867*fe82ebb0SRobert Mustacchi  * However, at the extremes of thickness and height, it can be arbitrary. The
868*fe82ebb0SRobert Mustacchi  * minimum height can be any value <= 15mm and the maximum is just > 45mm.
869*fe82ebb0SRobert Mustacchi  * Similarly the maximum thickness is just any value greater than 15mm. For
870*fe82ebb0SRobert Mustacchi  * these values, we define aliases that can be used to indicate we're in these
871*fe82ebb0SRobert Mustacchi  * conditions for the height and thickness, allowing this to otherwise be the
872*fe82ebb0SRobert Mustacchi  * common well understood value.
873*fe82ebb0SRobert Mustacchi  */
874*fe82ebb0SRobert Mustacchi #define	SPD_MOD_HEIGHT_LT15MM	15
875*fe82ebb0SRobert Mustacchi #define	SPD_MOD_HEIGHT_GT45MM	46
876*fe82ebb0SRobert Mustacchi #define	SPD_KEY_MOD_HEIGHT	"module.height"		/* uint32_t */
877*fe82ebb0SRobert Mustacchi #define	SPD_MOD_THICK_GT15MM	16
878*fe82ebb0SRobert Mustacchi #define	SPD_KEY_MOD_FRONT_THICK	"module.front-thickness"	/* uint32_t */
879*fe82ebb0SRobert Mustacchi #define	SPD_KEY_MOD_BACK_THICK	"module.back-thickness"	/* uint32_t */
880*fe82ebb0SRobert Mustacchi 
881*fe82ebb0SRobert Mustacchi /*
882*fe82ebb0SRobert Mustacchi  * This is the number of rows of DRAM dies on the module. In addition, DDR4
883*fe82ebb0SRobert Mustacchi  * provides the number of registers present on the device. This is not present
884*fe82ebb0SRobert Mustacchi  * in DDR5.
885*fe82ebb0SRobert Mustacchi  */
886*fe82ebb0SRobert Mustacchi #define	SPD_KEY_MOD_NROWS	"module.dram-die-rows"		/* uint32_t */
887*fe82ebb0SRobert Mustacchi #define	SPD_KEY_MOD_NREGS	"module.total-registers"	/* uint32_t */
888*fe82ebb0SRobert Mustacchi 
889*fe82ebb0SRobert Mustacchi /*
890*fe82ebb0SRobert Mustacchi  * Operating temperature ranges. These ranges are defined by JEDEC. The code can
891*fe82ebb0SRobert Mustacchi  * be translated with libjedec_temp_range() to transform it into a pair of
892*fe82ebb0SRobert Mustacchi  * values.
893*fe82ebb0SRobert Mustacchi  */
894*fe82ebb0SRobert Mustacchi 
895*fe82ebb0SRobert Mustacchi #define	SPD_KEY_MOD_OPER_TEMP	"module.operating-temperature"	/* uint32_t */
896*fe82ebb0SRobert Mustacchi 
897*fe82ebb0SRobert Mustacchi /*
898*fe82ebb0SRobert Mustacchi  * Module reference card and design revision. JEDEC provides various reference
899*fe82ebb0SRobert Mustacchi  * designs for modules and revisions of those.
900*fe82ebb0SRobert Mustacchi  */
901*fe82ebb0SRobert Mustacchi #define	SPD_KEY_MOD_REF_DESIGN	"module.reference-design"	/* string */
902*fe82ebb0SRobert Mustacchi #define	SPD_KEY_MOD_DESIGN_REV	"module.design-revision"	/* uint32_t */
903*fe82ebb0SRobert Mustacchi 
904*fe82ebb0SRobert Mustacchi /*
905*fe82ebb0SRobert Mustacchi  * Manufacturing Section. These keys are present if manufacturing related
906*fe82ebb0SRobert Mustacchi  * information is made available. This space is not DIMM-revision specific. All
907*fe82ebb0SRobert Mustacchi  * fields are defined in DDR4 and DDR5. Note, the SPD_KEY_MFG_DRAM_STEP is
908*fe82ebb0SRobert Mustacchi  * optional and therefore an invalid value will result in this not being
909*fe82ebb0SRobert Mustacchi  * present.
910*fe82ebb0SRobert Mustacchi  */
911*fe82ebb0SRobert Mustacchi #define	SPD_KEY_MFG_MOD_MFG_ID	"mfg.module-mfg-id"	/* uint32[2] */
912*fe82ebb0SRobert Mustacchi #define	SPD_KEY_MFG_MOD_MFG_NAME	"mfg.module-mfg-name"	/* string */
913*fe82ebb0SRobert Mustacchi #define	SPD_KEY_MFG_DRAM_MFG_ID	"mfg.dram-mfg-id"	/* uint32[2] */
914*fe82ebb0SRobert Mustacchi #define	SPD_KEY_MFG_DRAM_MFG_NAME	"mfg.dram-mfg-name"	/* string */
915*fe82ebb0SRobert Mustacchi #define	SPD_KEY_MFG_MOD_LOC_ID	"mfg.module-loc-id"	/* uint32 */
916*fe82ebb0SRobert Mustacchi #define	SPD_KEY_MFG_MOD_YEAR	"mfg.module-year"	/* string */
917*fe82ebb0SRobert Mustacchi #define	SPD_KEY_MFG_MOD_WEEK	"mfg.module-week"	/* string */
918*fe82ebb0SRobert Mustacchi #define	SPD_KEY_MFG_MOD_PN	"mfg.module-pn"		/* string */
919*fe82ebb0SRobert Mustacchi #define	SPD_KEY_MFG_MOD_SN	"mfg.module-sn"		/* string */
920*fe82ebb0SRobert Mustacchi #define	SPD_KEY_MFG_MOD_REV	"mfg.module-rev"	/* string */
921*fe82ebb0SRobert Mustacchi #define	SPD_KEY_MFG_DRAM_STEP	"mfg.dram-step"		/* string */
922*fe82ebb0SRobert Mustacchi 
923*fe82ebb0SRobert Mustacchi /*
924*fe82ebb0SRobert Mustacchi  * The errors nvlist_t is designed such that it is a nested nvlist_t in the
925*fe82ebb0SRobert Mustacchi  * returned data. Each key in that nvlist_t corresponds to a key that we would
926*fe82ebb0SRobert Mustacchi  * otherwise produce. Each key is an nvlist_t that has two keys, a 'code' and a
927*fe82ebb0SRobert Mustacchi  * 'message'.
928*fe82ebb0SRobert Mustacchi  *
929*fe82ebb0SRobert Mustacchi  * There is currently an additional top-level special key. This is the
930*fe82ebb0SRobert Mustacchi  * 'incomplete' key. When data is too short to process an entry, rather than
931*fe82ebb0SRobert Mustacchi  * flag every possible missing key (as most times the consumer will know the
932*fe82ebb0SRobert Mustacchi  * amount of data they have), for the time being we will insert a single
933*fe82ebb0SRobert Mustacchi  * incomplete key with a uint32_t whose value indicates the starting offset of
934*fe82ebb0SRobert Mustacchi  * the key that we could not process. Note, this may not be the first byte that
935*fe82ebb0SRobert Mustacchi  * was missing (if we had 100 bytes and a 20 byte key at offset 90, we would
936*fe82ebb0SRobert Mustacchi  * insert 90).
937*fe82ebb0SRobert Mustacchi  */
938*fe82ebb0SRobert Mustacchi typedef enum {
939*fe82ebb0SRobert Mustacchi 	/*
940*fe82ebb0SRobert Mustacchi 	 * Indicates that the error occurred because we could not translate a
941*fe82ebb0SRobert Mustacchi 	 * given piece of information. For example, a value that we didn't know
942*fe82ebb0SRobert Mustacchi 	 * or a failure to look up something in a string table.
943*fe82ebb0SRobert Mustacchi 	 */
944*fe82ebb0SRobert Mustacchi 	SPD_ERROR_NO_XLATE,
945*fe82ebb0SRobert Mustacchi 	/*
946*fe82ebb0SRobert Mustacchi 	 * This indicates that we encountered an non-ASCII or unprintable
947*fe82ebb0SRobert Mustacchi 	 * character in an SPD string which should not be allowed per se.
948*fe82ebb0SRobert Mustacchi 	 */
949*fe82ebb0SRobert Mustacchi 	SPD_ERROR_UNPRINT,
950*fe82ebb0SRobert Mustacchi 	/*
951*fe82ebb0SRobert Mustacchi 	 * This indicates that there was no data for a given key. For example, a
952*fe82ebb0SRobert Mustacchi 	 * string that was all padded spaces.
953*fe82ebb0SRobert Mustacchi 	 */
954*fe82ebb0SRobert Mustacchi 	SPD_ERROR_NO_DATA,
955*fe82ebb0SRobert Mustacchi 	/*
956*fe82ebb0SRobert Mustacchi 	 * Indicates that some kind of internal error occurred.
957*fe82ebb0SRobert Mustacchi 	 */
958*fe82ebb0SRobert Mustacchi 	SPD_ERROR_INTERNAL,
959*fe82ebb0SRobert Mustacchi 	/*
960*fe82ebb0SRobert Mustacchi 	 * This indicates that there's something suspicious or weird to us about
961*fe82ebb0SRobert Mustacchi 	 * the data in question. The most common case is a bad CRC.
962*fe82ebb0SRobert Mustacchi 	 */
963*fe82ebb0SRobert Mustacchi 	SPD_ERROR_BAD_DATA
964*fe82ebb0SRobert Mustacchi } spd_error_kind_t;
965*fe82ebb0SRobert Mustacchi #define	SPD_KEY_INCOMPLETE	"incomplete"	/* uint32_t */
966*fe82ebb0SRobert Mustacchi #define	SPD_KEY_ERRS		"errors"	/* nvlist_t */
967*fe82ebb0SRobert Mustacchi #define	SPD_KEY_ERRS_CODE	"code"		/* uint32_t */
968*fe82ebb0SRobert Mustacchi #define	SPD_KEY_ERRS_MSG	"message"	/* string */
969*fe82ebb0SRobert Mustacchi 
9701566bc34SRobert Mustacchi #ifdef __cplusplus
9711566bc34SRobert Mustacchi }
9721566bc34SRobert Mustacchi #endif
9731566bc34SRobert Mustacchi 
9741566bc34SRobert Mustacchi #endif /* _LIBJEDEC_H */
975