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