util/spd_tools: Add support for exclusive IDs
[coreboot.git] / util / spd_tools / README.md
blob01bc417c8b14099c3107e8d7f8f78c4ef97139fb
1 # SPD tools
3 A set of tools to generate SPD files for platforms with memory down
4 configurations.
6 The memory technologies currently supported are:
8 *   LPDDR4x - based on the JESD209-4C spec and Intel recommendations
9     (docs #616599, #610202, #634730).
10 *   DDR4 - based on the JESD79-4C and Jedec 4.1.2.L-5 R29 v103 specs.
11 *   LPDDR5 - based on the LPDDR5 spec JESD209-5B, the SPD spec SPD4.1.2.M-2 (the
12     LPDDR3/4 spec is used since JEDEC has not released an SPD spec for LPDDR5),
13     and Intel recommendations in advisory #616599.
15 There are two tools provided to assist with generating SPDs and Makefiles to
16 integrate into the coreboot build. These tools can also be used to allocate DRAM
17 IDs (configure DRAM hardware straps) for any memory part used by a board.
19 *   `spd_gen`: This tool generates de-duplicated SPD files using a global memory
20     part list. It also generates a CSV manifest file which maps each memory part
21     in the global list to one of the generated SPD files. For each supported
22     memory technology, multiple sets of SPDs are generated. Each set corresponds
23     to a set of SoC platforms with different SPD requirements, e.g. due to
24     different expectations in the memory training code. Another CSV manifest
25     maps each supported platform to one of these sets.
26 *   `part_id_gen`: This tool allocates DRAM strap IDs for the different memory
27     parts used by a board. It takes as input a CSV file of the memory parts used
28     with optional fixed IDs. It generates a Makefile.inc which is used to
29     integrate the SPD files generated by `spd_gen` into the coreboot build.
31 ## Tool 1 - `spd_gen`
33 This program takes the following inputs:
35 *   A JSON file containing a global list of memory parts with their attributes
36     as per the datasheet. This is the list of all known memory parts for the
37     given memory technology.
38 *   The memory technology for which to generate the SPDs, e.g. "lp4x".
40 The input JSON file requires the following two fields for every memory part:
42 *   `name`: The name of the memory part.
43 *   `attribs`: A list of the memory part's attributes, as per its datasheet.
44     These attributes match the part specifications and are independent of any
45     SoC expectations. The tool takes care of translating the physical attributes
46     of the memory part to match JEDEC spec and memory traning code expectations.
48 The `attribs` field further contains two types of sub-field:
50 *   Mandatory: These attributes must be provided for each memory part.
51 *   Optional: These attributes may be provided for a memory part in order to
52     override the defaults.
54 The attributes are different for each memory technology.
56 ### LP4x attributes
58 #### Mandatory
60 *   `densityPerChannelGb`: Density in Gb of the physical channel.
62 *   `banks`: Number of banks per physical channel. This is typically 8 for
63     LPDDR4x memory parts.
65 *   `channelsPerDie`: Number of physical channels per die. Valid values: `1, 2,
66     4`. For a part with x16 bit width, number of channels per die is 1 or 2. For
67     a part with x8 bit width, number of channels can be 2 or 4 (4 is basically
68     when two dual-channel byte mode devices are combined as shown in Figure 3 in
69     JESD209-4C).
71 *   `diesPerPackage`: Number of physical dies in each SDRAM package. As per
72     JESD209-4C, "Standard LPDDR4 package ballmaps allocate one ZQ ball per die."
73     Thus, number of diesPerPackage is the number of ZQ balls on the package.
75 *   `bitWidthPerChannel`: Width of each physical channel. Valid values: `8, 16`
76     bits.
78 *   `ranksPerChannel`: Number of ranks per physical channel. Valid values: `1,
79     2`. If the channels across multiple dies share the same DQ/DQS pins but use
80     a separate CS, then ranks is 2 else it is 1.
82 *   `speedMbps`: Maximum data rate supported by the part in Mbps. Valid values:
83     `3200, 3733, 4267` Mbps.
85 #### Optional
87 *   `trfcabNs`: Minimum Refresh Recovery Delay Time (tRFCab) for all banks in
88     nanoseconds. As per JESD209-4C, this is dependent on the density per
89     channel. Default values used:
91     *   6Gb : 280ns
92     *   8Gb : 280ns
93     *   12Gb: 380ns
94     *   16Gb: 380ns
96 *   `trfcpbNs`: Minimum Refresh Recovery Delay Time (tRFCab) per bank in
97     nanoseconds. As per JESD209-4C, this is dependent on the density per
98     channel. Default values used:
100     *   6Gb : 140ns
101     *   8Gb : 140ns
102     *   12Gb: 190ns
103     *   16Gb: 190ns
105 *   `trpabMinNs`: Minimum Row Precharge Delay Time (tRPab) for all banks in
106     nanoseconds. As per JESD209-4C, this is max(21ns, 4nck) which defaults to
107     `21ns`.
109 *   `trppbMinNs`: Minimum Row Precharge Delay Time (tRPpb) per bank in
110     nanoseconds. As per JESD209-4C, this is max(18ns, 4nck) which defaults to
111     `18ns`.
113 *   `tckMinPs`: SDRAM minimum cycle time (tckMin) value in picoseconds. This is
114     typically calculated based on the `speedMbps` attribute. `(1 / speedMbps) *
115     2`. Default values used(taken from JESD209-4C):
117     *   4267 Mbps: 468ps
118     *   3733 Mbps: 535ps
119     *   3200 Mbps: 625ps
121 *   `tckMaxPs`: SDRAM maximum cycle time (tckMax) value in picoseconds. Default
122     value used: `31875ps`. As per JESD209-4C, TCKmax should be 100ns (100000ps)
123     for all speed grades. But the SPD byte to encode this field is only 1 byte.
124     Hence, the maximum value that can be encoded is 31875ps.
126 *   `taaMinPs`: Minimum CAS Latency Time(taaMin) in picoseconds. This value
127     defaults to nck * tckMin, where nck is minimum CAS latency.
129 *   `trcdMinNs`: Minimum RAS# to CAS# Delay Time (tRCDmin) in nanoseconds. As
130     per JESD209-4C, this is max(18ns, 4nck) which defaults to `18ns`.
132 *   `casLatencies`: List of CAS latencies supported by the part. This is
133     dependent on the attrib `speedMbps`. Default values used:
135     *   4267: `"6 10 14 20 24 28 32 36"`.
136     *   3733: `"6 10 14 20 24 28 32"`.
137     *   3200: `"6 10 14 20 24 28"`.
139 #### Example `memory_parts.json`
143     "parts": [
144         {
145             "name": "MT53D512M64D4NW-046 WT:F",
146             "attribs": {
147                 "densityPerChannelGb": 8,
148                 "banks": 8,
149                 "channelsPerDie": 2,
150                 "diesPerPackage": 2,
151                 "bitWidthPerChannel": 16,
152                 "ranksPerChannel": 1,
153                 "speedMbps": 4267
154             }
155         },
156         {
157             "name": "NT6AP256T32AV-J1",
158             "attribs": {
159                 "densityPerChannelGb": 4,
160                 "banks": 8,
161                 "channelsPerDie": 2,
162                 "diesPerPackage": 1,
163                 "bitWidthPerChannel": 16,
164                 "ranksPerChannel": 1,
165                 "speedMbps": 4267,
166                 "tckMaxPs": 1250,
167                 "casLatencies": "14 20 24 28 32 36"
168             }
169         },
170     ]
174 ### DDR4 attributes
176 #### Mandatory
178 *   `speedMTps`: Maximum rate supported by the part in MT/s. Valid values:
179     `1600, 1866, 2133, 2400, 2666, 2933, 3200` MT/s.
181 *   `CL_nRCD_nRP`: Refers to CAS Latency specified for the part (find
182     "CL-nRCD-nRP" in the vendor spec for the DDR4 part).
184 *   `capacityPerDieGb`: Capacity per die in gigabits. Valid values: `2, 4, 8,
185     16` Gb part.
187 *   `diesPerPackage`: Number of dies on the part. Valid values: `1, 2` dies per
188     package.
190 *   `packageBusWidth`: Number of bits of the device's address bus. Valid values:
191     `8, 16` bit-wide bus. NOTE: Width of x4 is not supported by this tool.
193 *   `ranksPerPackage`: From Jedec doc 4_01_02_AnnexL-1R23: “Package ranks per
194     DIMM” refers to the collections of devices on the module sharing common chip
195     select signals (across the data width of the DIMM), either from the edge
196     connector for unbuffered modules or from the outputs of a registering clock
197     driver for RDIMMs and LRDIMMs.Number of bits of the device's address bus.
198     Valid values: `1, 2` package ranks.
200 #### Optional
202 The following options are calculated by the tool based on the mandatory
203 attributes described for the part, but there may be cases where a default value
204 must be overridden, such as when a device appears to be 3200AA, but does not
205 support all of the CAS latencies typically supported by a speed bin 3200AA part.
206 To deal with such a case, the variable can be overridden here and the tool will
207 use this value instead of calculating one. All values must be defined in
208 picosecond units, except for "CASLatencies", which would be represented as a
209 string like "9 10 11 12 14".
211 *   `TAAMinPs`: Defines the minimum CAS Latency. Table 48 of Jedec doc
212     4_01_02_AnnexL-5R29 lists tAAmin for each speed grade.
214 *   `TRASMinPs`: Refers to the minimum active to precharge delay time. Table 55
215     of Jedec doc 4_01_02_AnnexL-5R29 lists tRPmin for each speed grade.
217 *   `TCKMinPs`: Refers to the minimum clock cycle time. Table 42 of Jedec doc
218     4_01_02_AnnexL-5R29 lists tCKmin for each speed grade.
220 *   `TCKMaxPs`:Refers to the minimum clock cycle time. Table 44 of Jedec doc
221     4_01_02_AnnexL-5R29 lists tCKmin for each speed grade.
223 *   `TRFC1MinPs`: Refers to the minimum refresh recovery delay time. Table 59 of
224     Jedec doc 4_01_02_AnnexL-5R29 lists tRFC1min for each page size.
226 *   `TRFC2MinPs`: Refers to the minimum refresh recovery delay time. Table 61 of
227     Jedec doc 4_01_02_AnnexL-5R29 lists tRFC2min for each page size.
229 *   `TRFC4MinPs`: Refers to the minimum refresh recovery delay time. Table 63 of
230     Jedec doc 4_01_02_AnnexL-5R29 lists tRFC4min for each page size.
232 *   `TFAWMinPs`:: Refers to the minimum four activate window delay time. Table
233     66 of Jedec doc 4_01_02_AnnexL-5R29 lists tFAWmin for each speed grade and
234     page size combination.
236 *   `TRRDSMinPs`: Refers to the minimum activate to activate delay time to
237     different bank groups. Table 68 of Jedec doc 4_01_02_AnnexL-5R29 lists
238     tRRD_Smin for each speed grade and page size combination.
240 *   `TRRDLMinPs`: Refers to the minimum activate to activate delay time to the
241     same bank group. Table 70 of Jedec doc 4_01_02_AnnexL-5R29 lists tRRD_Lmin
242     for each speed grade and page size combination.
244 *   `TCCDLMinPs`: Refers to the minimum CAS to CAS delay time to same bank
245     group. Table 72 of Jedec doc 4_01_02_AnnexL-5R29 lists tCCD_Lmin for each
246     speed grade.
248 *   `TWRMinPs`: Refers to the minimum write recovery time. Table 75 of Jedec doc
249     4_01_02_AnnexL-5R29 lists tWRmin for each ddr4 type.
251 *   `TWTRSMinPs`: Refers to minimum write to read time to different bank group.
252     Table 78 of Jedec doc 4_01_02_AnnexL-5R29 lists tWTR_Smin for each ddr4
253     type.
255 *   `TWTRLMinPs`: Refers to minimum write to read time to same bank group. Table
256     80 of Jedec doc 4_01_02_AnnexL-5R29 lists tWTR_Lmin for each ddr4 type.
258 *   `CASLatencies`: Refers to the CAS latencies supported by the part. The speed
259     bin tables in the back of Jedec doc 4_01_02_AnnexL-5R29 define the standard
260     CAS latencies that a speed bin part is supposed to support. In cases where a
261     part does not support all of the CAS latencies listed in the speed bin
262     tables, this entry should be used to override the default settings.
264 #### Example `memory_parts.json`
268     "parts": [
269         {
270             "name": "K4A8G165WC-BCWE",
271             "attribs": {
272                 "speedMTps": 3200,
273                 "CL_nRCD_nRP": 22,
274                 "capacityPerDieGb": 8,
275                 "diesPerPackage": 1,
276                 "packageBusWidth": 16,
277                 "ranksPerPackage": 1
278             }
279         },
280         {
281             "name": "MT40A1G16KD-062E:E",
282             "attribs": {
283                 "speedMTps": 3200,
284                 "CL_nRCD_nRP": 22,
285                 "capacityPerDieGb": 16,
286                 "diesPerPackage": 1,
287                 "packageBusWidth": 16,
288                 "ranksPerPackage": 1,
289                 "TRFC1MinPs": 350000,
290                 "TRFC2MinPs": 260000,
291                 "TRFC4MinPs": 160000
292             }
293         },
294     ]
298 ### LP5 attributes
300 #### Mandatory
302 *   `densityPerDieGb`: Density per die in Gb. Valid values: `4, 6, 8, 12, 16,
303     24, 32` Gb per die.
305 *   `diesPerPackage`: Number of physical dies in each SDRAM package. Valid
306     values: `2, 4, 8` dies per package.
308 *   `bitWidthPerChannel`: Width of each physical channel. Valid values: `8, 16`
309     bits.
311 *   `ranksPerChannel`: Number of ranks per physical channel. Valid values: `1,
312     2`. If the channels across multiple dies share the same DQ/DQS pins but use
313     a separate CS, then ranks is 2 else it is 1.
315 *   `speedMbps`: Maximum data rate supported by the part in Mbps. Valid values:
316     `5500, 6400` Mbps.
318 #### Optional
320 *   `trfcabNs`: Minimum Refresh Recovery Delay Time (tRFCab) for all banks in
321     nanoseconds. As per JESD209-5B, this is dependent on the density per die.
322     Default values used:
324     *   4 Gb : 180 ns
325     *   6 Gb : 210 ns
326     *   8 Gb : 210 ns
327     *   12 Gb: 280 ns
328     *   16 Gb: 280 ns
329     *   24 Gb: 380 ns
330     *   32 Gb: 380 ns
332 *   `trfcpbNs`: Minimum Refresh Recovery Delay Time (tRFCpb) per bank in
333     nanoseconds. As per JESD209-5B, this is dependent on the density per die.
334     Default values used:
336     *   4 Gb : 90 ns
337     *   6 Gb : 120 ns
338     *   8 Gb : 120 ns
339     *   12 Gb: 140 ns
340     *   16 Gb: 140 ns
341     *   24 Gb: 190 ns
342     *   32 Gb: 190 ns
344 *   `trpabMinNs`: Minimum Row Precharge Delay Time (tRPab) for all banks in
345     nanoseconds. As per JESD209-5B, this is max(21ns, 2nCK), which defaults to
346     `21 ns`.
348 *   `trppbMinNs`: Minimum Row Precharge Delay Time (tRPpb) per bank in
349     nanoseconds. As per JESD209-5B, this is max(18ns, 2nCK) which defaults to
350     `18 ns`.
352 *   `tckMinPs`: SDRAM minimum cycle time (tCKmin) value in picoseconds. LPDDR5
353     has two clocks: the command/addrees clock (CK) and the data clock (WCK).
354     They are related by the WCK:CK ratio, which can be either 4:1 or 2:1. For
355     LPDDR5, tCKmin is the CK period, which can be calculated from the
356     `speedMbps` attribute and the WCK:CK ratio as follows: `tCKmin = 1 /
357     (speedMbps / 2 / WCK:CK)`. The default values used are for a 4:1 WCK:CK
358     ratio:
360     *   6400 Mbps: 1250 ps
361     *   5500 Mbps: 1455 ps
363 *   `taaMinPs`: Minimum CAS Latency Time(tAAmin) in picoseconds. This value
364     defaults to nck * tCKmin, where nck is maximum CAS latency, and is
365     determined from the `speedMbps` attribute as per JESD209-5B:
367     *   6400 Mbps: 17
368     *   5500 Mbps: 15
370 *   `trcdMinNs`: Minimum RAS# to CAS# Delay Time (tRCDmin) in nanoseconds. As
371     per JESD209-5B, this is max(18ns, 2nCK) which defaults to `18 ns`.
373 #### Example `memory_parts.json`
377     "parts": [
378         {
379             "name": "MT62F1G32D4DR-031 WT:B",
380             "attribs": {
381                 "densityPerDieGb": 8,
382                 "diesPerPackage": 4,
383                 "bitWidthPerChannel": 16,
384                 "ranksPerChannel": 2,
385                 "speedMbps": 6400
386             }
387         },
388     ]
392 ### Output
394 The `spd_gen` tool generates the directory structure shown below. The inputs to
395 the tool are the `memory_parts.json` files, and all other files are generated.
398     spd
399       |
400       |_ lp4x
401            |
402            |_ memory_parts.json
403            |_ platforms_manifest.generated.txt
404            |_ set-0
405                 |_parts_spd_manifest.generated.txt
406                 |_spd-1.hex
407                 |_spd-2.hex
408                 |_...
409            |_ set-1
410                 |_...
411            |_...
412       |
413       |_ ddr4
414            |
415            |_ memory_parts.json
416            |_ platforms_manifest.generated.txt
417            |_ set-0
418                 |_parts_spd_manifest.generated.txt
419                 |_spd-1.hex
420                 |_spd-2.hex
421                 |_...
422            |_ set-1
423                 |_...
424            |_...
425       |_...
428 The files generated are:
430 *   `spd-X.hex`: Deduplicated SPDs for all the memory parts in the input JSON
431     file.
433 *   `parts_spd_manifest.generated.txt`: A CSV file mapping each memory part to
434     one of the deduplicated SPD files. E.g.
436     ```
437     H9HCNNNBKMMLXR-NEE,spd-1.hex
438     H9HCNNNFAMMLXR-NEE,spd-2.hex
439     K4U6E3S4AA-MGCL,spd-1.hex
440     K4UBE3D4AA-MGCL,spd-3.hex
441     MT53E1G32D2NP-046 WT:A,spd-4.hex
442     ```
444 *   `platforms_manifest.generated.txt`: A CSV file mapping each platform to the
445     SPD set used by that platform. E.g.
447     ```
448     TGL,set-0
449     ADL,set-0
450     JSL,set-1
451     CZN,set-1
452     ```
454 ## Tool 2 - `part_id_gen`
456 This program takes the following inputs:
458 *   The SoC platform which the board is based on, e.g. ADL.
459 *   The memory technology used by the board, e.g. lp4x.
460 *   The path to the directory where the generated Makefile.inc should be placed.
461 *   A CSV file containing a list of the memory parts used by the board, with an
462 *   optional fixed or exclusive ID for each part. A fixed ID is simply an integer
463 *   and it ensure that part (and any that share the same SPD) will be assigned
464 *   that ID. An exclusive ID is prefixed with `*` and ensures that only parts with
465 *   the same exclusive ID will be assigned that ID, even if they would otherwise
466 *   share the same ID.
467 *   NOTE: Only assign a fixed/exclusive ID if required for legacy reasons.
469 Example of a CSV file using fixed and exclusive IDs:
472 K4AAG165WA-BCWE,1
473 MT40A512M16TB-062E:J
474 MT40A1G16KD-062E:E
475 K4A8G165WC-BCWE
476 H5AN8G6NDJR-XNC,8
477 H5ANAG6NCMR-XNC,*9
480 Explanation: This will ensure that the SPDs for K4AAG165WA-BCWE and
481 H5AN8G6NDJR-XNC are assigned to IDs 1 and 8 respectively. H5ANAG6NCMR-XNC
482 will be assigned ID 9 and no other part will be assigned ID 9 even if it
483 shares the same SPD. The SPDs for all other memory parts will be assigned to
484 the first compatible ID. Assigning fixed/exclusive IDs may result in duplicate
485 SPD entries or gaps in the ID mapping.
487 ### Output
489 The `part_id_gen` tool outputs the following:
491 *   It prints the DRAM hardware strap ID which should be allocated to each
492     memory part in the input file.
493 *   It generates a `Makefile.inc` in the given directory. This is used to
494     integrate the SPD files generated by `spd_gen` with the coreboot build for
495     the board.
496 *   It generates a `dram_id.generated.txt` in the same directory as the
497     `Makefile.inc`. This lists the part IDs assigned to each memory part, and is
498     useful for itegration with the board schematics.
500 Sample `Makefile.inc`:
503 # SPDX-License-Identifier: GPL-2.0-or-later
504 # This is an auto-generated file. Do not edit!!
505 # Generated by:
506 # util/spd_tools/bin/part_id_gen ADL lp4x src/mainboard/google/brya/variants/felwinter/memory src/mainboard/google/brya/variants/felwinter/memory/mem_parts_used.txt
508 SPD_SOURCES =
509 SPD_SOURCES += spd/lp4x/set-0/spd-1.hex      # ID = 0(0b0000)  Parts = K4U6E3S4AA-MGCR, H9HCNNNBKMMLXR-NEE
510 SPD_SOURCES += spd/lp4x/set-0/spd-3.hex      # ID = 1(0b0001)  Parts = K4UBE3D4AA-MGCR
511 SPD_SOURCES += spd/lp4x/set-0/spd-4.hex      # ID = 2(0b0010)  Parts = MT53E1G32D2NP-046 WT:A
514 NOTE: Empty entries may be required if there is a gap created by a memory part
515 with a fixed ID.
517 Sample `dram_id.generated.txt`:
520 # SPDX-License-Identifier: GPL-2.0-or-later
521 # This is an auto-generated file. Do not edit!!
522 # Generated by:
523 # util/spd_tools/bin/part_id_gen ADL lp4x src/mainboard/google/brya/variants/felwinter/memory src/mainboard/google/brya/variants/felwinter/memory/mem_parts_used.txt
525 DRAM Part Name                 ID to assign
526 K4U6E3S4AA-MGCR                0 (0000)
527 K4UBE3D4AA-MGCR                1 (0001)
528 H9HCNNNBKMMLXR-NEE             0 (0000)
529 MT53E1G32D2NP-046 WT:A         2 (0010)
532 ### Note of caution
534 The `part_id_gen` tool assigns DRAM IDs based on the order of the part names in
535 the input file. Thus, when adding a new memory part to the list, it should
536 always go at the end of the file. This guarantees that the memory parts that
537 were already assigned IDs do not change.
539 ## How to build the tools?
542 make clean -C util/spd_tools
543 make -C util/spd_tools
546 ## How to use the tools?
548 ### `spd_gen`
550 Usage:
553 util/spd_tools/bin/spd_gen <mem_parts_list_json> <mem_technology>
556 Example:
559 util/spd_tools/bin/spd_gen spd/lp4x/memory_parts.json lp4x
562 ### `part_id_gen`
564 Usage:
567 util/spd_tools/bin/part_id_gen <platform> <mem_technology> <makefile_dir> <mem_parts_used_file>
570 Example:
573 util/spd_tools/bin/part_id_gen \
574   ADL \
575   lp4x \
576   src/mainboard/google/brya/variants/felwinter/memory \
577   src/mainboard/google/brya/variants/felwinter/memory/mem_parts_used.txt
580 ### Need to add a new memory part for a board?
582 *   If the memory part is not present in the global list of memory parts for
583     that memory technology (e.g. `spd/lp4x/memory_parts.json`), then add the
584     memory part name and attributes as per the datasheet.
586     *   Use `spd_gen` to regenerate all the SPD files and manifests for that
587         memory technology. Either a new SPD file will be generated for the new
588         part, or an existing one will be reused.
589     *   Upload the new SPD (if one is created) and the manifest changes for
590         review.
592 *   Update the file containing the memory parts used by board (variant), by
593     adding the new memory part name at the end of the file.
595     *   Use `part_id_gen` to update the variant's `Makefile.inc` and
596         `dram_id.generated.txt` with the new part.
597     *   Upload the changes to `Makefile.inc` and `dram_id.generated.txt` for
598         review.
600 ## How to add support for a new memory technology
602 ### 1. Gather the SPD requirements
604 To generate SPDs for the new memory technology, information is needed about the
605 list of bytes in the SPD and how the value of each byte should be determined.
606 This information usually comes from a combination of:
608 *   The JEDEC spec for the memory technology, e.g. JESD209-5B for LPDDR5.
609 *   The JEDEC SPD spec for the memory technology, e.g. SPD4.1.2.M-2 for LPDDR3/4
610     (also used for LP4x and LP5).
611 *   Platform-specific requirements. SoC vendors often don't follow the JEDEC
612     specs exactly. E.g. the memory training code may expect certain SPD bytes to
613     encode a different value to what is stated in the spec. So for each SoC
614     platform using the new memory technology, any platform-specific requirements
615     need to be gathered.
617 ### 2. Implement support in spd_tools
619 Support for the new memory technology needs to be added to both the `spd_gen`
620 and `part_id_gen` tools.
622 #### `spd_gen`
624 Adding support to `spd_gen` requires implementing the logic to generate SPDs for
625 the new memory technology. The changes required are:
627 *   Add the new memory technology to the `memTechMap` in `spd_gen/spd_gen.go`.
628 *   Add a new file `spd_gen/<mem_tech>.go`. This file will contain all the logic
629     for generating SPDs for the new memory technology. It needs to implement the
630     `memTech` interface defined in `spd_gen/spd_gen.go`. The interface functions
631     are documented inline. Examples of how the interface is implemented for
632     existing memory technologies can be found in the `spd_gen/` directory, e.g.
633     `lp4x.go`, `ddr4.go`, `lp5.go`. While not strictly necessary, it is
634     recommended to follow the overall structure of these existing files when
635     adding a new memory technology.
637 #### `part_id_gen`
639 The `part_id_gen` tool is memory technology-agnostic, so the only change
640 required is:
642 *   Add the new memory technology to the `supportedMemTechs` list in
643     `part_id_gen/part_id_gen.go`.