xref: /illumos-gate/usr/src/man/man3jedec/libjedec_spd.3jedec (revision 8119dad84d6416f13557b0ba8e2aaf9064cbcfd3)
1b3783300SRobert Mustacchi.\"
2b3783300SRobert Mustacchi.\" This file and its contents are supplied under the terms of the
3b3783300SRobert Mustacchi.\" Common Development and Distribution License ("CDDL"), version 1.0.
4b3783300SRobert Mustacchi.\" You may only use this file in accordance with the terms of version
5b3783300SRobert Mustacchi.\" 1.0 of the CDDL.
6b3783300SRobert Mustacchi.\"
7b3783300SRobert Mustacchi.\" A full copy of the text of the CDDL should have accompanied this
8b3783300SRobert Mustacchi.\" source.  A copy of the CDDL is also available via the Internet at
9b3783300SRobert Mustacchi.\" http://www.illumos.org/license/CDDL.
10b3783300SRobert Mustacchi.\"
11b3783300SRobert Mustacchi.\"
12*8119dad8SRobert Mustacchi.\" Copyright 2024 Oxide Computer Company
13b3783300SRobert Mustacchi.\"
14*8119dad8SRobert Mustacchi.Dd September 2, 2024
15b3783300SRobert Mustacchi.Dt LIBJEDEC_SPD 3JEDEC
16b3783300SRobert Mustacchi.Os
17b3783300SRobert Mustacchi.Sh NAME
18b3783300SRobert Mustacchi.Nm libjedec_spd
19b3783300SRobert Mustacchi.Nd parse DIMM SPD data
20b3783300SRobert Mustacchi.Sh LIBRARY
21b3783300SRobert Mustacchi.Lb libjedec
22b3783300SRobert Mustacchi.Sh SYNOPSIS
23b3783300SRobert Mustacchi.In libjedec.h
24b3783300SRobert Mustacchi.Ft "nvlist_t *"
25b3783300SRobert Mustacchi.Fo libjedec_spd
26b3783300SRobert Mustacchi.Fa "const uint8_t *buf"
27b3783300SRobert Mustacchi.Fa "size_t buflen"
28b3783300SRobert Mustacchi.Fa "spd_error_t *errp
29b3783300SRobert Mustacchi.Fc
30b3783300SRobert Mustacchi.Sh DESCRIPTION
31b3783300SRobert MustacchiThe
32b3783300SRobert Mustacchi.Fn libjedec_spd
33b3783300SRobert Mustacchifunction parses a binary payload of SPD
34b3783300SRobert Mustacchi.Pq serial presence detect
35b3783300SRobert Mustacchidata and transforms it into a
36b3783300SRobert Mustacchi.Vt nvlist_t
37b3783300SRobert Mustacchithat can be used by callers to inspect the data.
38b3783300SRobert Mustacchi.Pp
39b3783300SRobert MustacchiSPD data is defined by JEDEC and used in various DDR DRAM standards.
40b3783300SRobert MustacchiThis information describes everything from the size and organization of
41b3783300SRobert Mustacchithe DIMM and its dies,
42b3783300SRobert Mustacchitiming information, electrical properties, manufacturing data, and more.
43b3783300SRobert MustacchiA DRAM module
44b3783300SRobert Mustacchi.Pq the thing we plug into a computer
45b3783300SRobert Mustacchiis made up of a number of different components.
46b3783300SRobert MustacchiFor example, a DDR5 module
47b3783300SRobert Mustacchi.Pq which is plugged into a slot
48b3783300SRobert Mustacchicontains not only a number of different DRAM dies, but also power
49b3783300SRobert Mustacchicontrollers, registers, clock drivers, and more.
50b3783300SRobert MustacchiThe SPD data describes all of this information.
51b3783300SRobert Mustacchi.Pp
52b3783300SRobert MustacchiThere are two major properties of SPD information that determine which
53b3783300SRobert Mustacchikeys are present in it:
54b3783300SRobert Mustacchi.Bl -enum -width Ds
55b3783300SRobert Mustacchi.It
56b3783300SRobert MustacchiThe DDR version that the device implements.
57b3783300SRobert MustacchiExamples of the version information include DDR4, LPDDR5, DDR3, and many
58b3783300SRobert Mustacchiothers.
59b3783300SRobert Mustacchi.It
60b3783300SRobert MustacchiThe module's type.
61b3783300SRobert MustacchiExamples of this include whether it is an RDIMM
62b3783300SRobert Mustacchi.Pq registered DIMM ,
63b3783300SRobert MustacchiUDIMM
64b3783300SRobert Mustacchi.Pq unregistered DIMM ,
65b3783300SRobert Mustacchisoldered down, etc.
66b3783300SRobert Mustacchi.El
67b3783300SRobert Mustacchi.Pp
68b3783300SRobert MustacchiWhile each DDR version has different SPD information and the module's
69b3783300SRobert Mustacchitype may further modify parts of it, the
70b3783300SRobert Mustacchi.Vt nvlist_t
71b3783300SRobert Mustacchithat is returned attempts to normalize this information as much as
72b3783300SRobert Mustacchipossible.
73b3783300SRobert MustacchiEach key that is returned is defined in
74b3783300SRobert Mustacchi.In libjedec.h
75b3783300SRobert Mustacchias a macro.
76b3783300SRobert MustacchiThe key space is dot
77b3783300SRobert Mustacchi.Pq Sq \&.
78b3783300SRobert Mustacchidelineated.
79b3783300SRobert MustacchiThe following key spaces are currently used:
80b3783300SRobert Mustacchi.Bl -tag -width Ds
81b3783300SRobert Mustacchi.It Dq meta
82b3783300SRobert MustacchiThis contains information about the SPD ROM itself, the encoding
83b3783300SRobert Mustacchirevision, the DRAM standard in use, the type of module, etc.
84b3783300SRobert MustacchiThis section also contains all of the CRC values and information that
85b3783300SRobert Mustacchiaffects how the rest of data is parsed
86b3783300SRobert Mustacchi.Pq such as whether or not the package is monolithic .
87b3783300SRobert Mustacchi.It Dq dram
88b3783300SRobert MustacchiThis section contains information that is specific to the SDRAM dies
89b3783300SRobert Mustacchithat are present.
90b3783300SRobert MustacchiThis includes addressing information such as the number of rows,
91b3783300SRobert Mustacchicolumns, banks, and bank groups that are on each die.
92b3783300SRobert MustacchiIt also includes information such as the supported voltages of the dies
93b3783300SRobert Mustacchithemselves and then describes a lot of the different timing properties
94b3783300SRobert Mustacchisuch as the minimum times that a controller must wait between certain
95b3783300SRobert Mustacchiactions.
96b3783300SRobert Mustacchi.It Dq ddr4 , Dq ddr5
97b3783300SRobert MustacchiThis section contains information that is specific to a given DDR
98b3783300SRobert Mustacchistandard and cannot otherwise share a common definition.
99b3783300SRobert MustacchiThis section has a few additional subdivisions of information to cover
100b3783300SRobert Mustacchiitems related to the module's type or are otherwise logically grouped
101b3783300SRobert Mustacchitogether such as refresh management.
102b3783300SRobert MustacchiFor example, the library uses namespaces such as
103b3783300SRobert Mustacchi.Dq ddr4.rdimm
104b3783300SRobert Mustacchiand
105b3783300SRobert Mustacchi.Dq ddr5.lrdimm
106b3783300SRobert Mustacchifor properties that would be specific to DDR4 RDIMMs and DDR5 LRDIMMs
107b3783300SRobert Mustacchirespectively.
108*8119dad8SRobert Mustacchi.Pp
109*8119dad8SRobert MustacchiSimilarly, there are subdivisions based on the device in question.
110*8119dad8SRobert MustacchiFor example,
111*8119dad8SRobert Mustacchi.Dq ddr3.mb
112*8119dad8SRobert Mustacchiand
113*8119dad8SRobert Mustacchi.Dq ddr4.rcd
114*8119dad8SRobert Mustacchirefer to properties of the DDR3 memory buffer and the DDR4 registering
115*8119dad8SRobert Mustacchiclock driver respectively.
116*8119dad8SRobert Mustacchi.It Dq lp
117*8119dad8SRobert MustacchiThis section describes information that is specific to low power
118*8119dad8SRobert Mustacchidevices that come from the LPDDR standards.
119*8119dad8SRobert Mustacchi.It Dq channel
120*8119dad8SRobert MustacchiThis section describes properties that are specific to the
121*8119dad8SRobert Mustacchiimplementation of a channel.
122*8119dad8SRobert MustacchiDDR3 and DDR4 DIMMs have a single channel.
123*8119dad8SRobert MustacchiDDR5 DIMMs have a single channel that is broken into two sub-channels.
124*8119dad8SRobert MustacchiA channel represents a specific data stream to the host.
125*8119dad8SRobert MustacchiMost DDR channels are 64-bit channels with optional ECC.
126*8119dad8SRobert MustacchiLPDDR devices have rather different channel widths and their soldered
127*8119dad8SRobert Mustacchidown form factor may have more than one channel present
128*8119dad8SRobert Mustacchi.Pq regardless of sub-channels .
129b3783300SRobert Mustacchi.It Dq module
130b3783300SRobert MustacchiThis section relates to information about the physical module which
131b3783300SRobert Mustacchiincludes information such as its physical dimensions, the types of
132b3783300SRobert Mustacchicomponents that are present on it, signal mapping, and related.
133b3783300SRobert Mustacchi.It Dq mfg
134b3783300SRobert MustacchiThis section contains information about the module manufacturing.
135b3783300SRobert MustacchiThis is where things like the module's serial number, the manufacturer,
136b3783300SRobert Mustacchithe part number, and related can be found.
137b3783300SRobert MustacchiGenerally this information is found in a different part of the SPD ROM
138b3783300SRobert Mustacchiand therefore may not always be present.
139b3783300SRobert Mustacchi.It Dq errors
140b3783300SRobert MustacchiThis section is an embedded
141b3783300SRobert Mustacchi.Vt nvlist_t
142b3783300SRobert Mustacchithat contains keys for each value that couldn't be parsed.
143b3783300SRobert MustacchiFor more information, see the
144b3783300SRobert Mustacchi.Sx Parsing Errors
145b3783300SRobert Mustacchisection for more information.
146b3783300SRobert Mustacchi.El
147b3783300SRobert Mustacchi.Ss Data Types
148b3783300SRobert MustacchiThe library attempts to use a fixed number of data types when performing
149b3783300SRobert Mustacchiconversions and follows the following guidelines:
150b3783300SRobert Mustacchi.Bl -bullet
151b3783300SRobert Mustacchi.It
152b3783300SRobert MustacchiBy default, integer values use a
153b3783300SRobert Mustacchi.Vt uint32_t
154b3783300SRobert Mustacchito try and make things more uniform where possible and to allow for
155b3783300SRobert Mustacchifuture changes.
156b3783300SRobert MustacchiA
157b3783300SRobert Mustacchi.Vt uint64_t
158b3783300SRobert Mustacchiis used when the types contain data that could naturally overflow a
159b3783300SRobert Mustacchi.Vt uint32_t
160b3783300SRobert Mustacchisuch as when counting the number of bits, bytes, or measuring time
161b3783300SRobert Mustacchi.Pq which is normalized to picoseconds .
162b3783300SRobert Mustacchi.Pp
163b3783300SRobert MustacchiAll integers are denoted as such explicitly with their size: either
164b3783300SRobert Mustacchi.Sq uint32_t
165b3783300SRobert Mustacchior
166b3783300SRobert Mustacchi.Sq uint64_t .
167b3783300SRobert MustacchiSome banks of keys all have the same type and are denoted as such in the
168b3783300SRobert Mustacchiintroductory block comment.
169b3783300SRobert MustacchiUse
170b3783300SRobert Mustacchi.Xr nvlist_lookup_uint32 3NVPAIR
171b3783300SRobert Mustacchior
172b3783300SRobert Mustacchi.Xr nvlist_lookup_uint64 3NVPAIR
173b3783300SRobert Mustacchito retrieve these keys.
174b3783300SRobert Mustacchi.It
175b3783300SRobert MustacchiStrings, which are stored as traditional
176b3783300SRobert Mustacchi.Vt char *
177b3783300SRobert Mustacchivalues should only contain printable characters.
178b3783300SRobert Mustacchi.Pp
179b3783300SRobert MustacchiAll strings are denoted as such by using the comment
180b3783300SRobert Mustacchi.Sq string .
181b3783300SRobert MustacchiUse
182b3783300SRobert Mustacchi.Xr nvlist_lookup_string 3NVPAIR
183b3783300SRobert Mustacchito retrieve these keys.
184b3783300SRobert Mustacchi.It
185b3783300SRobert MustacchiThere are many values which represent enumerations.
186b3783300SRobert MustacchiThe raw type is stored as a
187b3783300SRobert Mustacchi.Vt uint32_t .
188b3783300SRobert MustacchiIn general, these enumerations, unless otherwise indicated should not be
189b3783300SRobert Mustacchiassumed to have the identical values of a given specification.
190b3783300SRobert MustacchiThis is done because the values are not always uniform from
191b3783300SRobert Mustacchispecification to specification, except in rare cases.
192b3783300SRobert MustacchiNot all DDR specifications can result in the same set of enumeration
193b3783300SRobert Mustacchivalues.
194b3783300SRobert Mustacchi.Pp
195b3783300SRobert MustacchiFor example, consider the
196b3783300SRobert Mustacchi.Vt spd_temp_type_t
197b3783300SRobert Mustacchiwhich is an enumeration that describes the kind of temperature
198b3783300SRobert Mustacchimonitoring device present.
199b3783300SRobert MustacchiThe enumeration contains values from DDR3, DDR4, and DDR5; however, each
200b3783300SRobert Mustacchistandard has its own defined type of SPD temperature sensor.
201b3783300SRobert Mustacchi.Pp
202b3783300SRobert MustacchiAll enumerations are denoted as such by using the comment
203b3783300SRobert Mustacchi.Sq uint32_t Pq enum .
204b3783300SRobert MustacchiUse
205b3783300SRobert Mustacchi.Xr nvlist_lookup_uint32 3NVPAIR
206b3783300SRobert Mustacchito retrieve these keys.
207b3783300SRobert Mustacchi.It
208b3783300SRobert MustacchiSeveral items are used to indicate a fact, but do not have any actual
209b3783300SRobert Mustacchidata associated with them.
210b3783300SRobert MustacchiTheir mere presence is sufficient to indicate a unique property of the
211b3783300SRobert MustacchiDIMM.
212b3783300SRobert MustacchiExamples of this include if the package is non-monolithic, the DIMM has
213b3783300SRobert Mustacchiasymmetrical ranks, etc.
214b3783300SRobert Mustacchi.Pp
215b3783300SRobert MustacchiAll such items are denoted as such by using the comment
216b3783300SRobert Mustacchi.Sq key .
217b3783300SRobert MustacchiUse
218b3783300SRobert Mustacchi.Xr nvlist_lookup_boolean 3NVPAIR
219b3783300SRobert Mustacchito retrieve these keys.
220b3783300SRobert Mustacchi.It
221b3783300SRobert MustacchiA few types use arrays of
222b3783300SRobert Mustacchi.Vt uint32_t
223b3783300SRobert Mustacchivalues to denote information.
224b3783300SRobert MustacchiSome of the keys have a fixed number of entries that are expected, while
225b3783300SRobert Mustacchiothers are variable and will depend on the parsed data.
226b3783300SRobert MustacchiFor example, a JEDEC ID is always encoded as two
227b3783300SRobert Mustacchi.Vt uint32_t
228b3783300SRobert Mustacchivalues, the continuation and the underlying ID itself.
229b3783300SRobert MustacchiOther values, such as the number of supported voltages or CAS latencies
230b3783300SRobert Mustacchiwill vary.
231b3783300SRobert Mustacchi.Pp
232b3783300SRobert MustacchiAll fixed size arrays denote their size by using the comment
233b3783300SRobert Mustacchi.Sq uint32_t [4] ,
234b3783300SRobert Mustacchiwhere the number four is replaced with the actual size.
235b3783300SRobert MustacchiAll variable sized arrays elide the number and are denoted by the
236b3783300SRobert Mustacchicomment
237b3783300SRobert Mustacchi.Sq uint32_t [] .
238b3783300SRobert MustacchiUse
239b3783300SRobert Mustacchi.Xr nvlist_lookup_uint32_array 3NVPAIR
240b3783300SRobert Mustacchito retrieve these keys.
241*8119dad8SRobert Mustacchi.Pp
242*8119dad8SRobert MustacchiA few keys will use different sized integer arrays.
243*8119dad8SRobert MustacchiFor example, arrays that relate to timing parameters use arrays of
244*8119dad8SRobert Mustacchi.Vt uint64_t
245*8119dad8SRobert Mustacchito match the broader pattern of using the
246*8119dad8SRobert Mustacchi.Vt uint64_t
247*8119dad8SRobert Mustacchifor timing.
248b3783300SRobert Mustacchi.El
249b3783300SRobert Mustacchi.Ss Parsing Errors
250b3783300SRobert MustacchiThere are a number of different issues that can arise when trying to
251b3783300SRobert Mustacchiparse the SPD data that a device returns.
252b3783300SRobert MustacchiThe library attempts to parse as much as it can and breaks errors into
253b3783300SRobert Mustacchitwo large categories:
254b3783300SRobert Mustacchi.Bl -enum -width Ds
255b3783300SRobert Mustacchi.It
256b3783300SRobert MustacchiErrors which prevent us from doing anything at all, which are noted in
257b3783300SRobert Mustacchithe
258b3783300SRobert Mustacchi.Sx ERRORS
259b3783300SRobert Mustacchisection.
260b3783300SRobert MustacchiThe main items that relate to data
261b3783300SRobert Mustacchi.Pq as opposed to issues like running out of memory
262b3783300SRobert Mustacchiinclude when we encounter a DDR specification that we don't support or
263b3783300SRobert Mustacchithat the data has an encoding version we don't understand.
264b3783300SRobert MustacchiThis can also occur if there's not enough data for us to figure out what
265b3783300SRobert Mustacchikind of SPD information is encoded.
266b3783300SRobert Mustacchi.It
267b3783300SRobert MustacchiErrors that mean we cannot parse a specific piece of SPD data.
268b3783300SRobert MustacchiThis is by far the most common form of error that we encounter and these
269b3783300SRobert Mustacchiare the entries that make up the
270b3783300SRobert Mustacchi.Dq errors
271b3783300SRobert Mustacchisection of the returned
272b3783300SRobert Mustacchi.Vt nvlist_t
273b3783300SRobert Mustacchithat was mentioned earlier.
274b3783300SRobert Mustacchi.El
275b3783300SRobert Mustacchi.Pp
276b3783300SRobert MustacchiThe
277b3783300SRobert Mustacchi.Dq errors
278b3783300SRobert Mustacchisection is a nested
279b3783300SRobert Mustacchi.Vt nvlist_t
280b3783300SRobert Mustacchithat can be retrieved by using the
281b3783300SRobert Mustacchi.Dv SPD_KEY_ERRS
282b3783300SRobert Mustacchikey.
283b3783300SRobert MustacchiThis keys in this nvlist use the same name as the normal data keys.
284b3783300SRobert MustacchiFor example, if we were unable to properly parse the manufacturer's
285b3783300SRobert MustacchiJEDEC ID, then the key
286b3783300SRobert Mustacchi.Dv SPD_KEY_MFG_MOD_MFG_ID
287b3783300SRobert Mustacchi.Pq Dq mfg.module-mfg-id
288b3783300SRobert Mustacchiwould not be present in the top-level
289b3783300SRobert Mustacchi.Vt nvlist_t
290b3783300SRobert Mustacchiand would instead be in the error
291b3783300SRobert Mustacchi.Vt nvlist_t .
292b3783300SRobert Mustacchi.Pp
293b3783300SRobert MustacchiEach item present in the error
294b3783300SRobert Mustacchi.Vt nvlist_t
295b3783300SRobert Mustacchiis itself a
296b3783300SRobert Mustacchi.Vt nvlist_t
297b3783300SRobert Mustacchiwhich contains the following keys:
298b3783300SRobert Mustacchi.Bl -tag -width Ds
299b3783300SRobert Mustacchi.It Dv SPD_KEY_ERRS_CODE
300b3783300SRobert MustacchiThe error code, a
301b3783300SRobert Mustacchi.Vt uint32_t,
302b3783300SRobert Mustacchiindicates a class of issue that occurred and its values are defined by
303b3783300SRobert Mustacchithe
304b3783300SRobert Mustacchi.Vt spd_error_kind_t
305b3783300SRobert Mustacchienumeration.
306b3783300SRobert MustacchiThe following errors are defined:
307b3783300SRobert Mustacchi.Bl -tag -width Ds
308b3783300SRobert Mustacchi.It SPD_ERROR_NO_XLATE
309b3783300SRobert MustacchiThis indicates that the library did not know how to interpret a specific
310b3783300SRobert Mustacchibinary value.
311b3783300SRobert MustacchiFor example, if a given particular field was using what we believed to
312b3783300SRobert Mustacchibe a reserved value then we would set this error.
313b3783300SRobert Mustacchi.It SPD_ERROR_UNPRINT
314b3783300SRobert MustacchiThis indicates that we encountered a non-ASCII or otherwise unprintable
315b3783300SRobert Mustacchicharacter that was not allowed in the SPD string character set.
316b3783300SRobert Mustacchi.It SPD_ERROR_NO_DATA
317b3783300SRobert MustacchiThis indicates that there was no data for a given key.
318b3783300SRobert MustacchiFor example, this would be a string that consisted solely of space
319b3783300SRobert Mustacchicharacters which are used to represent padding.
320b3783300SRobert Mustacchi.It SPD_ERROR_INTERNAL
321b3783300SRobert MustacchiThis indicates that something went wrong inside the library that was
322b3783300SRobert Mustacchiunexpected.
323b3783300SRobert Mustacchi.It SPD_ERROR_BAD_DATA
324b3783300SRobert MustacchiThis indicates that we've encountered something strange about the data
325b3783300SRobert Mustacchiin question.
326b3783300SRobert MustacchiFor example, this would be used for an invalid CRC or if the combination
327b3783300SRobert Mustacchiof values would cause an underflow in a calculation.
328b3783300SRobert Mustacchi.El
329b3783300SRobert Mustacchi.It Dv SPD_KEY_ERRS_MSG
330b3783300SRobert MustacchiThis is an error message that is intended for a person to understand and
331b3783300SRobert Mustacchicontains more specific information than the code above.
332b3783300SRobert Mustacchi.El
333b3783300SRobert Mustacchi.Pp
334b3783300SRobert MustacchiFinally, there is one last top-level key that we will set if we find
335b3783300SRobert Mustacchithat the set of data that we had was incomplete.
336b3783300SRobert MustacchiRather than tag every single item in the
337b3783300SRobert Mustacchi.Dq errors
338b3783300SRobert Mustacchi.Vt nvlist_t ,
339b3783300SRobert Mustacchiwe instead insert the key
340b3783300SRobert Mustacchi.Dv SPD_KEY_INCOMPLETE
341b3783300SRobert Mustacchion the top-level nvlist.
342b3783300SRobert MustacchiThe key is a
343b3783300SRobert Mustacchi.Vt uint32_t
344b3783300SRobert Mustacchithat contains the starting offset of the
345b3783300SRobert Mustacchi.Sy key
346b3783300SRobert Mustacchithat we were unable to parse, which may be less than the total amount of
347b3783300SRobert Mustacchidata that was provided.
348b3783300SRobert MustacchiFor example, if we had 100 bytes of data, but there was a 20 byte key
349b3783300SRobert Mustacchistarting at byte 90, the this key would have a value of 90 as that's
350b3783300SRobert Mustacchiwhat we were unable to parse.
351b3783300SRobert Mustacchi.Sh RETURN VALUES
352b3783300SRobert MustacchiUpon successful completion, the
353b3783300SRobert Mustacchi.Fn libjedec_spd
354b3783300SRobert Mustacchifunction returns an allocated
355b3783300SRobert Mustacchi.Vt nvlist_t
356b3783300SRobert Mustacchithat contains the parsed SPD data.
357b3783300SRobert MustacchiThere may be individual SPD fields that were unparsable which will be
358b3783300SRobert Mustacchifound in the
359b3783300SRobert Mustacchi.Dv SPD_KEY_ERRS
360b3783300SRobert Mustacchifield of the nvlist still.
361b3783300SRobert MustacchiOtherwise
362b3783300SRobert Mustacchi.Dv NULL
363b3783300SRobert Mustacchiis returned
364b3783300SRobert Mustacchiand
365b3783300SRobert Mustacchi.Fa errp
366b3783300SRobert Mustacchiis set with a value that indicates why the function was unable to parse
367b3783300SRobert Mustacchiany data.
368b3783300SRobert Mustacchi.Sh EXAMPLES
369b3783300SRobert Mustacchi.Sy Example 1
370b3783300SRobert MustacchiPrinting SPD DRAM and Module Type
371b3783300SRobert Mustacchi.Pp
372b3783300SRobert MustacchiThe following example shows how to parse the SPD information and print
373b3783300SRobert Mustacchiout the type of DRAM and module's type.
374b3783300SRobert MustacchiThis example assumes that one has already obtained the raw SPD file from
375b3783300SRobert Mustacchisomewhere and just prints the raw values.
376b3783300SRobert Mustacchi.Bd -literal -offset 2
377b3783300SRobert Mustacchi#include <stdio.h>
378b3783300SRobert Mustacchi#include <stdint.h>
379b3783300SRobert Mustacchi#include <libjedec.h>
380b3783300SRobert Mustacchi
381b3783300SRobert Mustacchivoid
382b3783300SRobert Mustacchidump_dram_module_type(const uint8_t *buf, size_t len)
383b3783300SRobert Mustacchi{
384b3783300SRobert Mustacchi	nvlist_t *nvl;
385b3783300SRobert Mustacchi	spd_error_t err;
386b3783300SRobert Mustacchi	uint32_t ddr, mod;
387b3783300SRobert Mustacchi
388b3783300SRobert Mustacchi	nvl = libjedec_spd(buf, len, &err);
389b3783300SRobert Mustacchi	if (nvl == NULL) {
390b3783300SRobert Mustacchi		(void) fprintf(stderr, "failed to parse SPD data: 0x%x\en",
391b3783300SRobert Mustacchi		    err);
392b3783300SRobert Mustacchi		return;
393b3783300SRobert Mustacchi	}
394b3783300SRobert Mustacchi
395b3783300SRobert Mustacchi	if (nvlist_lookup_pairs(nvl, 0,
396b3783300SRobert Mustacchi	    SPD_KEY_DRAM_TYPE, DATA_TYPE_UINT32, &ddr,
397b3783300SRobert Mustacchi	    SPD_KEY_MOD_TYPE, DATA_TYPE_UINT32, &mod,
398b3783300SRobert Mustacchi	    NULL) != 0) {
399b3783300SRobert Mustacchi		nvlist_free(nvl);
400b3783300SRobert Mustacchi		(void) fprintf(stderr, "failed to look up keys\en");
401b3783300SRobert Mustacchi		return;
402b3783300SRobert Mustacchi	}
403b3783300SRobert Mustacchi
404b3783300SRobert Mustacchi	nvlist_free(nvl);
405b3783300SRobert Mustacchi	(void) printf("Found DDR type 0x%x, module type 0x%x\en", ddr,
406b3783300SRobert Mustacchi	    mod);
407b3783300SRobert Mustacchi}
408b3783300SRobert Mustacchi.Ed
409b3783300SRobert Mustacchi.Sh ERRORS
410b3783300SRobert MustacchiUpon returning from the
411b3783300SRobert Mustacchi.Fn libjedec_spd
412b3783300SRobert Mustacchifunction, the
413b3783300SRobert Mustacchi.Fa errp
414b3783300SRobert Mustacchipointer will be set to one of the following values:
415b3783300SRobert Mustacchi.Bl  -tag -width Dv
416b3783300SRobert Mustacchi.It Er LIBJEDEC_SPD_OK
417b3783300SRobert MustacchiThis indicates that the system was able to parse SPD data into a valid
418b3783300SRobert Mustacchi.Vt nvlist_t
419b3783300SRobert Mustacchiand return it to the caller.
420b3783300SRobert MustacchiThis code should never appear when the function fails and returns
421b3783300SRobert Mustacchi.Dv NULL .
422b3783300SRobert MustacchiCallers must still cehck the contents of the
423b3783300SRobert Mustacchi.Dv SPD_KEY_ERRS
424b3783300SRobert Mustacchinvlist.
425b3783300SRobert Mustacchi.It Dv LIBJEDEC_SPD_NOMEM
426b3783300SRobert MustacchiThis indicates that the system ran out of memory while trying to
427b3783300SRobert Mustacchiconstruct the
428b3783300SRobert Mustacchi.Vt nvlist_t
429b3783300SRobert Mustacchito return.
430b3783300SRobert Mustacchi.It Dv LIBJEDEC_SPD_TOOSHORT
431b3783300SRobert MustacchiThis indicates that not enough SPD data was present as indicated by
432b3783300SRobert Mustacchi.Fa buf
433b3783300SRobert Mustacchiand
434b3783300SRobert Mustacchi.Fa buflen
435b3783300SRobert Mustacchifor the given type of SPD information and therefore we were unable to
436b3783300SRobert Mustacchisuccessfully parse basic information.
437b3783300SRobert Mustacchi.It Dv LIBJEDEC_SPD_UNSUP_TYPE
438b3783300SRobert MustacchiThis indicates that the type of SPD data present, e.g. DDR4 SDRAM,
439b3783300SRobert MustacchiLPDDR3, etc., that was found is not currently supported by the library.
440b3783300SRobert Mustacchi.It Dv LIBJEDEC_SPD_UNSUP_REV
441b3783300SRobert MustacchiThis indicates that while the library is familiar with the specific type
442b3783300SRobert Mustacchiof SPD data present, the encoding level of the data
443b3783300SRobert Mustacchi.Pq similar to a major version
444b3783300SRobert Mustacchiis unsupported by the library.
445b3783300SRobert Mustacchi.El
446b3783300SRobert Mustacchi.Sh INTERFACE STABILITY
447b3783300SRobert Mustacchi.Sy Uncommitted
448b3783300SRobert Mustacchi.Sh MT-LEVEL
449b3783300SRobert Mustacchi.Sy MT-Safe
450b3783300SRobert Mustacchi.Sh SEE ALSO
451b3783300SRobert Mustacchi.Xr libjedec 3LIB ,
452b3783300SRobert Mustacchi.Xr nvlist_lookup_boolean 3NVPAIR ,
453b3783300SRobert Mustacchi.Xr nvlist_lookup_string 3NVPAIR ,
454b3783300SRobert Mustacchi.Xr nvlist_lookup_uint32 3NVPAIR ,
455b3783300SRobert Mustacchi.Xr nvlist_lookup_uint32_array 3NVPAIR ,
456b3783300SRobert Mustacchi.Xr nvlist_lookup_uint64 3NVPAIR
457b3783300SRobert Mustacchi.Pp
458b3783300SRobert Mustacchi.Rs
459b3783300SRobert Mustacchi.%Q JEDEC Solid State Technology Association
460b3783300SRobert Mustacchi.%T Serial Presence Detect (SPD), General Standard
461b3783300SRobert Mustacchi.%N 21-C
462b3783300SRobert Mustacchi.Re
463b3783300SRobert Mustacchi.Rs
464b3783300SRobert Mustacchi.%Q JEDEC Solid State Technology Association
465b3783300SRobert Mustacchi.%T DDR5 Serial Presence Detect (SPD) Contents
466*8119dad8SRobert Mustacchi.%N JESD400-5B Document Release 1.2
467*8119dad8SRobert Mustacchi.%D October 2023
468*8119dad8SRobert Mustacchi.Re
469*8119dad8SRobert Mustacchi.Rs
470*8119dad8SRobert Mustacchi.%Q JEDEC Solid State Technology Association
471*8119dad8SRobert Mustacchi.%T LPDDR5/5X Serial Presence Detect (SPD) Contents
472*8119dad8SRobert Mustacchi.%N JESD406-5 Document Release 1.0
473*8119dad8SRobert Mustacchi.%D June 2024
474b3783300SRobert Mustacchi.Re
475