diff options
author | Rob Barnes <robbarnes@google.com> | 2020-08-26 12:47:27 -0600 |
---|---|---|
committer | Furquan Shaikh <furquan@google.com> | 2020-08-27 20:14:34 +0000 |
commit | 196e9c002122d3469ab486d2f40af1e66dcdf067 (patch) | |
tree | 0dff97ec9060bd6c056a7c49f96e64e7ce15812d /util/spd_tools/intel/lp4x | |
parent | 1860cd460aaf3dabb58d996b81d51916949e59b3 (diff) |
util/spd_tools: Remove intel subfolder
Move ddr4 and lp4x to spd_tools root folder. The tool now applies to non
intel platforms.
BUG=b:162939176
TEST=Run tool
Signed-off-by: Rob Barnes <robbarnes@google.com>
Change-Id: I0941ea036d760ee27eb34f259f4506a4b7584bee
Reviewed-on: https://review.coreboot.org/c/coreboot/+/44844
Reviewed-by: Furquan Shaikh <furquan@google.com>
Reviewed-by: Nick Vaccaro <nvaccaro@google.com>
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Diffstat (limited to 'util/spd_tools/intel/lp4x')
-rw-r--r-- | util/spd_tools/intel/lp4x/README.md | 265 | ||||
-rw-r--r-- | util/spd_tools/intel/lp4x/gen_part_id.go | 215 | ||||
-rw-r--r-- | util/spd_tools/intel/lp4x/gen_spd.go | 986 | ||||
-rw-r--r-- | util/spd_tools/intel/lp4x/global_lp4x_mem_parts.json.txt | 186 |
4 files changed, 0 insertions, 1652 deletions
diff --git a/util/spd_tools/intel/lp4x/README.md b/util/spd_tools/intel/lp4x/README.md deleted file mode 100644 index e614f259cf..0000000000 --- a/util/spd_tools/intel/lp4x/README.md +++ /dev/null @@ -1,265 +0,0 @@ -# LPDDR4x SPD tools README - -Tools for generating SPD files for LPDDR4x memory used in memory down -configurations on Intel Tiger Lake (TGL) and Jasper Lake (JSL) based -platforms. These tools generate SPDs following JESD209-4C -specification and Intel recommendations (doc #616599, #610202) for -LPDDR4x SPD. - -There are two tools provided that assist TGL and JSL based mainboards -to generate SPDs and Makefile to integrate these SPDs in coreboot -build. These tools can also be used to allocate DRAM IDs (configure -DRAM hardware straps) for any LPDDR4x memory part used by the board. - -* gen_spd.go: Generates de-duplicated SPD files using a global memory - part list provided by the mainboard in JSON format. Additionally, - generates a SPD manifest file(in CSV format) with information about - what memory part from the global list uses which of the generated - SPD files. - -* gen_part_id.go: Allocates DRAM strap IDs for different LPDDR4x - memory parts used by the board. Takes as input list of memory parts - used by the board (with one memory part on each line) and the SPD - manifest file generated by gen_spd.go. Generates Makefile.inc for - integrating the generated SPD files in the coreboot build. - -## Tool 1 - gen_spd.go - -This program takes as input: -* Pointer to directory where the generated SPD files and manifest will - be placed. -* JSON file containing a global list of memory parts with their - attributes as per the datasheet. This is the list of all known - LPDDR4x memory parts irrespective of their usage on the board. -* SoC platform name for which the SPDs are being generated. Currently - supported platform names are `TGL` and `JSL`. - -Input JSON file requires the following two fields for every memory part: -* `name`: Name of the memory part -* `attribs`: List of attributes of the memory part as per its - datasheet. These attributes match the part specifications and are - independent of any SoC expectations. Tool takes care of translating - the physical attributes of the memory part to match JEDEC and Intel - MRC expectations. - -`attribs` field further contains two types of sub-fields: -* Mandatory: These attributes have to be provided for a memory part. -* Optional: These attributes can be provided by memory part if it wants - to override the defaults. - -### Mandatory `attribs` - -* `densityPerChannelGb`: Density in Gb of the physical channel. - -* `banks`: Number of banks per physical channel. This is typically 8 - for LPDDR4x memory parts. - -* `channelsPerDie`: Number of physical channels per die. Valid values: - `1, 2, 4`. For a part with x16 bit width, number of channels per die - is 1 or 2. For a part with x8 bit width, number of channels can be - 2 or 4 (4 is basically when two dual-channel byte mode devices are - combined as shown in Figure 3 in JESD209-4C). - -* `diesPerPackage`: Number of physical dies in each SDRAM - package. As per JESD209-4C, "Standard LPDDR4 package ballmaps - allocate one ZQ ball per die." Thus, number of diesPerPackage is the - number of ZQ balls on the package. - -* `bitWidthPerChannel`: Width of each physical channel. Valid values: - `8, 16` bits. - -* `ranksPerChannel`: Number of ranks per physical channel. Valid - values: `1, 2`. If the channels across multiple dies share the same - DQ/DQS pins but use a separate CS, then ranks is 2 else it is 1. - -* `speedMbps`: Maximum data rate supported by the part in Mbps. Valid - values: `3200, 3733, 4267` Mbps. - -### Optional `attribs` - -* `trfcabNs`: Minimum Refresh Recovery Delay Time (tRFCab) for all - banks in nanoseconds. As per JESD209-4C, this is dependent on the - density per channel. Default values used: - * 6Gb : 280ns - * 8Gb : 280ns - * 12Gb: 380ns - * 16Gb: 380ns - -* `trfcpbNs`: Minimum Refresh Recovery Delay Time (tRFCab) per - bank in nanoseconds. As per JESD209-4C, this is dependent on the - density per channel. Default values used: - * 6Gb : 140ns - * 8Gb : 140ns - * 12Gb: 190ns - * 16Gb: 190ns - -* `trpabMinNs`: Minimum Row Precharge Delay Time (tRPab) for all banks - in nanoseconds. As per JESD209-4C, this is max(21ns, 4nck) which - defaults to `21ns`. - -* `trppbMinNs`: Minimum Row Precharge Delay Time (tRPpb) per bank in - nanoseconds. As per JESD209-4C, this is max(18ns, 4nck) which - defaults to `18ns`. - -* `tckMinPs`: SDRAM minimum cycle time (tckMin) value in - picoseconds. This is typically calculated based on the `speedMbps` - attribute. `(1 / speedMbps) * 2`. Default values used(taken from - JESD209-4C): - * 4267 Mbps: 468ps - * 3733 Mbps: 535ps - * 3200 Mbps: 625ps - -* `tckMaxPs`: SDRAM maximum cycle time (tckMax) value in - picoseconds. Default value used: `31875ps`. As per JESD209-4C, - TCKmax should be 100ns (100000ps) for all speed grades. But the SPD - byte to encode this field is only 1 byte. Hence, the maximum value - that can be encoded is 31875ps. - -* `taaMinPs`: Minimum CAS Latency Time(taaMin) in picoseconds. This - value defaults to nck * tckMin, where nck is minimum CAS latency. - -* `trcdMinNs`: Minimum RAS# to CAS# Delay Time (tRCDmin) in - nanoseconds. As per JESD209-4C, this is max(18ns, 4nck) which - defaults to `18ns`. - -* `casLatencies`: List of CAS latencies supported by the - part. This is dependent on the attrib `speedMbps`. Default values - used: - * 4267: `"6 10 14 20 24 28 32 36"`. - * 3733: `"6 10 14 20 24 28 32"`. - * 3200: `"6 10 14 20 24 28"`. - -### Example JSON file -``` -{ - "parts": [ - { - "name": "MEMORY_PART_A", - "attribs": { - "densityPerChannelGb": 8, - "banks": 8, - "channelsPerDie": 2, - "diesPerPackage": 2, - "bitWidthPerChannel": 16, - "ranksPerChannel": 1, - "speedMbps": 4267 - } - }, - { - "name": "MEMORY_PART_B", - "attribs": { - "densityPerChannelGb": 8, - "banks": 8, - "channelsPerDie": 1, - "diesPerPackage": 2, - "bitWidthPerChannel": 16, - "ranksPerChannel": 1, - "speedMbps": 3733, - "casLatencies": "14 20 24 28 32", - "tckMaxPs": "1250" - } - } - ] -} -``` - -### Output - -This tool generates the following files using the global list of -memory parts in JSON format as described above: - * De-duplicated SPDs required for the different memory parts. These - SPD files are named (spd_1.hex, spd_2.hex, spd_3.hex and so on) - and placed in the directory provided as an input to the tool. - * CSV file representing which of the deduplicated SPD files is used - by which memory part. This file is named as - `spd_manifest.generated.txt` and placed in the directory provided - as an input to the tool along with the generated SPD - files. Example CSV file: - ``` - MEMORY_PART_A, spd_1.hex - MEMORY_PART_B, spd_2.hex - MEMORY_PART_C, spd_3.hex - MEMORY_PART_D, spd_2.hex - MEMORY_PART_E, spd_2.hex - ``` - -## Tool 2 - gen_part_id.go - -This program takes as input: -* Pointer to directory where the SPD files and the manifest file - `spd_manifest.generated.txt` (in CSV format) are placed by - gen_spd.go -* File containing list of memory parts used by the board. Each line of - the file is supposed to contain one memory part `name` as present in - the global list of memory parts provided to gen_spd.go -* Pointer to directory where the generated Makefile.inc should be - placed by the tool. - -### Output - -This program provides the following: - -* Prints out the list of DRAM hardware strap IDs that should be - allocated to each memory part listed in the input file. -* Makefile.inc is generated in the provided directory to integrate - SPDs generated by gen_spd.go with the coreboot build for the board. -* dram_id.generated.txt is generated in the same directory as - Makefile. This contains the part IDs assigned to the different - memory parts. (Useful to integrate in board schematics). - -Sample output (dram_id.generated.txt): -``` -DRAM Part Name ID to assign -MEMORY_PART_A 0 (0000) -MEMORY_PART_B 1 (0001) -MEMORY_PART_C 2 (0010) -MEMORY_PART_D 1 (0001) -``` - -Sample Makefile.inc: -``` -## SPDX-License-Identifier: GPL-2.0-or-later -## This is an auto-generated file. Do not edit!! - -SPD_SOURCES = -SPD_SOURCES += spd_1.hex # ID = 0(0b0000) Parts = MEMORY_PART_A -SPD_SOURCES += spd_2.hex # ID = 1(0b0001) Parts = MEMORY_PART_B, MEMORY_PART_D -SPD_SOURCES += spd_3.hex # ID = 2(0b0010) Parts = MEMORY_PART_C -``` - -### Note of caution - -This program assigns DRAM IDs using the order of DRAM part names -provided in the input file. Thus, when adding a new memory part to the -list, it should always go to the end of the input text file. This -guarantees that the memory parts that were already assigned IDs do not -change. - -## How to build the tools? -``` -# go build gen_spd.go -# go build gen_part_id.go -``` - -## How to use the tools? -``` -# ./gen_spd <spd_dir> <mem_parts_list_json> <platform> -# ./gen_part_id <spd_dir> <makefile_dir> <mem_parts_used_file> -``` - -### Need to add a new memory part for a board? - -* If the memory part is not present in the global list of memory - parts, then add the memory part name and attributes as per the - datasheet to the file containing the global list. - * Use `gen_spd.go` with input as the file containing the global list - of memory parts to generate de-duplicated SPDs. - * If a new SPD file is generated, use `git add` to add it to the - tree and push a CL for review. -* Update the file containing memory parts used by board (variant) to - add the new memory part name at the end of the file. - * Use gen_part_id.go providing it pointer to the location where SPD - files are stored and file containing the list of memory parts used - by the board(variant). - * Use `git add` to add `Makefile.inc` and `dram_id.generated.txt` - with updated changes and push a CL for review. diff --git a/util/spd_tools/intel/lp4x/gen_part_id.go b/util/spd_tools/intel/lp4x/gen_part_id.go deleted file mode 100644 index 7ed255c83b..0000000000 --- a/util/spd_tools/intel/lp4x/gen_part_id.go +++ /dev/null @@ -1,215 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later */ - -package main - -import ( - "encoding/csv" - "fmt" - "io" - "io/ioutil" - "log" - "os" - "path/filepath" - "strings" -) - -/* - * This program allocates DRAM strap IDs for different parts that are being used by the variant. - * - * It expects the following inputs: - * Pointer to SPD directory. This is the location where SPD files and SPD Manifest generated by - * gen_spd.go are placed. - * Pointer to Makefile directory. Makefile.inc generated by this program is placed in this - * location. - * Text file containing a list of memory parts names used by the board. Each line in the file - * is expected to have one memory part name. - */ -const ( - SPDManifestFileName = "spd_manifest.generated.txt" - MakefileName = "Makefile.inc" - DRAMIdFileName = "dram_id.generated.txt" -) - -func usage() { - fmt.Printf("\nUsage: %s <spd_dir> <makefile_dir> <mem_parts_used_file>\n\n", os.Args[0]) - fmt.Printf(" where,\n") - fmt.Printf(" spd_dir = Directory path containing SPD files and manifest generated by gen_spd.go\n") - fmt.Printf(" makefile_dir = Directory path where generated Makefile.inc should be placed\n") - fmt.Printf(" mem_parts_used_file = File containing list of memory parts used by the board\n\n\n") -} - -func checkArgs() error { - - for _, arg := range os.Args[1:] { - if _, err := os.Stat(arg); err != nil { - return err - } - } - - return nil -} - -/* - * Read input file that contains list of memory part names used by the variant (one on a line) - * and split into separate strings for each part name. - */ -func readParts(memPartsUsedFileName string) ([]string, error) { - lines, err := ioutil.ReadFile(memPartsUsedFileName) - if err != nil { - return nil, err - } - str := string(lines) - parts := strings.Split(str, "\n") - - return parts, nil -} - -/* - * Read SPD manifest file(CSV) generated by gen_spd program and generate two maps: - * 1. Part to SPD Map : This maps global memory part name to generated SPD file name - * 2. SPD to Index Map: This generates a map of deduplicated SPD file names to index assigned to - * that SPD. This function sets index for all SPDs to -1. This index gets - * updated as part of genPartIdInfo() depending upon the SPDs actually used - * by the variant. - */ -func readSPDManifest(SPDDirName string) (map[string]string, map[string]int, error) { - f, err := os.Open(filepath.Join(SPDDirName, SPDManifestFileName)) - if err != nil { - return nil, nil, err - } - defer f.Close() - r := csv.NewReader(f) - - partToSPDMap := make(map[string]string) - SPDToIndexMap := make(map[string]int) - - for { - fields, err := r.Read() - - if err == io.EOF { - break - } - - if err != nil { - return nil, nil, err - } - - if len(fields) != 2 { - return nil, nil, fmt.Errorf("CSV file is incorrectly formatted") - } - - partToSPDMap[fields[0]] = fields[1] - SPDToIndexMap[fields[1]] = -1 - } - - return partToSPDMap, SPDToIndexMap, nil -} - -/* Print information about memory part used by variant and ID assigned to it. */ -func appendPartIdInfo(s *string, partName string, index int) { - *s += fmt.Sprintf("%-30s %d (%04b)\n", partName, index, int64(index)) -} - -type partIds struct { - SPDFileName string - memParts string -} - -/* - * For each part used by variant, check if the SPD (as per the manifest) already has an ID - * assigned to it. If yes, then add the part name to the list of memory parts supported by the - * SPD entry. If not, then assign the next ID to the SPD file and add the part name to the - * list of memory parts supported by the SPD entry. - * - * Returns list of partIds that contains spdFileName and supported memory parts for each - * assigned ID. - */ -func genPartIdInfo(parts []string, partToSPDMap map[string]string, SPDToIndexMap map[string]int, makefileDirName string) ([]partIds, error) { - partIdList := []partIds{} - curId := 0 - var s string - - s += fmt.Sprintf("%-30s %s\n", "DRAM Part Name", "ID to assign") - - for _, p := range parts { - if p == "" { - continue - } - - SPDFileName,ok := partToSPDMap[p] - if !ok { - return nil, fmt.Errorf("Failed to find part ", p, " in SPD Manifest. Please add the part to global part list and regenerate SPD Manifest") - } - - index := SPDToIndexMap[SPDFileName] - if index != -1 { - partIdList[index].memParts += ", " + p - appendPartIdInfo(&s, p, index) - continue - } - - SPDToIndexMap[SPDFileName] = curId - - appendPartIdInfo(&s, p, curId) - entry := partIds{SPDFileName: SPDFileName, memParts: p} - partIdList = append(partIdList, entry) - - curId++ - } - - fmt.Printf("%s", s) - err := ioutil.WriteFile(filepath.Join(makefileDirName, DRAMIdFileName), []byte(s), 0644) - - return partIdList, err -} - -var generatedCodeLicense string = "## SPDX-License-Identifier: GPL-2.0-or-later" -var autoGeneratedInfo string = "## This is an auto-generated file. Do not edit!!" - -/* - * This function generates Makefile.inc under the variant directory path and adds assigned SPDs - * to SPD_SOURCES. - */ -func genMakefile(partIdList []partIds, makefileDirName string) error { - var s string - - s += fmt.Sprintf("%s\n%s\n\n", generatedCodeLicense, autoGeneratedInfo) - s += fmt.Sprintf("MEMORY_TYPE = lp4x\n\n") - s += fmt.Sprintf("SPD_SOURCES =\n") - - for i := 0; i < len(partIdList); i++ { - s += fmt.Sprintf("SPD_SOURCES += %s ", partIdList[i].SPDFileName) - s += fmt.Sprintf(" # ID = %d(0b%04b) ", i, int64(i)) - s += fmt.Sprintf(" Parts = %04s\n", partIdList[i].memParts) - } - - return ioutil.WriteFile(filepath.Join(makefileDirName, MakefileName), []byte(s), 0644) -} - -func main() { - if len(os.Args) != 4 { - usage() - log.Fatal("Incorrect number of arguments") - } - - SPDDir, MakefileDir, MemPartsUsedFile := os.Args[1], os.Args[2], os.Args[3] - - partToSPDMap, SPDToIndexMap, err := readSPDManifest(SPDDir) - if err != nil { - log.Fatal(err) - } - - parts, err := readParts(MemPartsUsedFile) - if err != nil { - log.Fatal(err) - } - - partIdList, err := genPartIdInfo(parts, partToSPDMap, SPDToIndexMap, MakefileDir) - if err != nil { - log.Fatal(err) - } - - if err := genMakefile(partIdList, MakefileDir); err != nil { - log.Fatal(err) - } -} diff --git a/util/spd_tools/intel/lp4x/gen_spd.go b/util/spd_tools/intel/lp4x/gen_spd.go deleted file mode 100644 index 2465815e49..0000000000 --- a/util/spd_tools/intel/lp4x/gen_spd.go +++ /dev/null @@ -1,986 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later */ - -package main - -import ( - "encoding/json" - "fmt" - "io/ioutil" - "log" - "os" - "path/filepath" - "reflect" - "strconv" - "strings" -) - -/* - * This program generates de-duplicated SPD files for LPDDR4x memory using the global memory - * part list provided in CSV format. In addition to that, it also generates SPD manifest in CSV - * format that contains entries of type (DRAM part name, SPD file name) which provides the SPD - * file name used by a given DRAM part. - * - * It takes as input: - * Pointer to directory where the generated SPD files will be placed. - * JSON file containing a list of memory parts with their attributes as per datasheet. - */ -const ( - SPDManifestFileName = "spd_manifest.generated.txt" - - PlatformTGL = 0 - PlatformJSL = 1 -) - -var platformMap = map[string]int { - "TGL": PlatformTGL, - "JSL": PlatformJSL, -} - -var currPlatform int - -type memAttributes struct { - /* Primary attributes - must be provided by JSON file for each part */ - DensityPerChannelGb int - Banks int - ChannelsPerDie int - DiesPerPackage int - BitWidthPerChannel int - RanksPerChannel int - SpeedMbps int - - /* - * All the following parameters are optional and required only if the part requires - * special parameters as per the datasheet. - */ - /* Timing parameters */ - TRFCABNs int - TRFCPBNs int - TRPABMinNs int - TRPPBMinNs int - TCKMinPs int - TCKMaxPs int - TAAMinPs int - TRCDMinNs int - - /* CAS */ - CASLatencies string - CASFirstByte byte - CASSecondByte byte - CASThirdByte byte -} - -/* This encodes the density in Gb to SPD values as per JESD 21-C */ -var densityGbToSPDEncoding = map[int]byte { - 4: 0x4, - 6: 0xb, - 8: 0x5, - 12: 0x8, - 16: 0x6, - 24: 0x9, - 32: 0x7, -} - -/* - * Table 3 from JESD209-4C. - * Maps density per physical channel to row-column encoding as per JESD 21-C for a device with - * x16 physical channel. - */ -var densityGbx16ChannelToRowColumnEncoding = map[int]byte { - 4: 0x19, /* 15 rows, 10 columns */ - 6: 0x21, /* 16 rows, 10 columns */ - 8: 0x21, /* 16 rows, 10 columns */ - 12: 0x29, /* 17 rows, 10 columns */ - 16: 0x29, /* 17 rows, 10 columns */ -} - -/* - * Table 5 from JESD209-4C. - * Maps density per physical channel to row-column encoding as per JESD 21-C for a device with - * x8 physical channel. - */ -var densityGbx8ChannelToRowColumnEncoding = map[int]byte { - 3: 0x21, /* 16 rows, 10 columns */ - 4: 0x21, /* 16 rows, 10 columns */ - 6: 0x29, /* 17 rows, 10 columns */ - 8: 0x29, /* 17 rows, 10 columns */ - 12: 0x31, /* 18 rows, 10 columns */ - 16: 0x31, /* 18 rows, 10 columns */ -} - -type refreshTimings struct { - TRFCABNs int - TRFCPBNs int -} - -/* - * Table 112 from JESD209-4C - * Maps density per physical channel to refresh timings. This is the same for x8 and x16 - * devices. - */ -var densityGbPhysicalChannelToRefreshEncoding = map[int]refreshTimings { - 3: { - TRFCABNs: 180, - TRFCPBNs: 90, - }, - 4: { - TRFCABNs: 180, - TRFCPBNs: 90, - }, - 6: { - TRFCABNs: 280, - TRFCPBNs: 140, - }, - 8: { - TRFCABNs: 280, - TRFCPBNs: 140, - }, - 12: { - TRFCABNs: 380, - TRFCPBNs: 190, - }, - 16: { - TRFCABNs: 380, - TRFCPBNs: 190, - }, -} - -type speedParams struct { - TCKMinPs int - TCKMaxPs int - CASLatenciesx16Channel string - CASLatenciesx8Channel string -} - -const ( - /* First Byte */ - CAS6 = 1 << 1 - CAS10 = 1 << 4 - CAS14 = 1 << 7 - /* Second Byte */ - CAS16 = 1 << 0 - CAS20 = 1 << 2 - CAS22 = 1 << 3 - CAS24 = 1 << 4 - CAS26 = 1 << 5 - CAS28 = 1 << 6 - /* Third Byte */ - CAS32 = 1 << 0 - CAS36 = 1 << 2 - CAS40 = 1 << 4 -) - -const ( - /* - * JEDEC spec says that TCKmax should be 100ns for all speed grades. - * 100ns in MTB units comes out to be 0x320. But since this is a byte field, set it to - * 0xFF i.e. 31.875ns. - */ - TCKMaxPsDefault = 31875 -) - -var speedMbpsToSPDEncoding = map[int]speedParams { - 4267: { - TCKMinPs: 468, /* 1/4267 * 2 */ - TCKMaxPs: TCKMaxPsDefault, - CASLatenciesx16Channel: "6 10 14 20 24 28 32 36", - CASLatenciesx8Channel: "6 10 16 22 26 32 36 40", - }, - 3733: { - TCKMinPs: 535, /* 1/3733 * 2 */ - TCKMaxPs: TCKMaxPsDefault, - CASLatenciesx16Channel: "6 10 14 20 24 28 32", - CASLatenciesx8Channel: "6 10 16 22 26 32 36", - }, - 3200: { - TCKMinPs: 625, /* 1/3200 * 2 */ - TCKMaxPs: TCKMaxPsDefault, - CASLatenciesx16Channel: "6 10 14 20 24 28", - CASLatenciesx8Channel: "6 10 16 22 26 32", - }, -} - -var bankEncoding = map[int]byte { - 4: 0 << 4, - 8: 1 << 4, -} - -const ( - TGLLogicalChannelWidth = 16 -) - -/* Returns density to encode as per Intel MRC expectations. */ -func getMRCDensity(memAttribs *memAttributes) int { - if currPlatform == PlatformTGL { - /* - * Intel MRC on TGL expects density per logical channel to be encoded in - * SPDIndexDensityBanks. Logical channel on TGL is an x16 channel. - */ - return memAttribs.DensityPerChannelGb * TGLLogicalChannelWidth / memAttribs.BitWidthPerChannel - } else if currPlatform == PlatformJSL { - /* - * Intel MRC on JSL expects density per die to be encoded in - * SPDIndexDensityBanks. - */ - return memAttribs.DensityPerChannelGb * memAttribs.ChannelsPerDie - } - - return 0 -} - -func encodeDensityBanks(memAttribs *memAttributes) byte { - var b byte - - b = densityGbToSPDEncoding[getMRCDensity(memAttribs)] - b |= bankEncoding[memAttribs.Banks] - - return b -} - -func encodeSdramAddressing(memAttribs *memAttributes) byte { - densityPerChannelGb := memAttribs.DensityPerChannelGb - if memAttribs.BitWidthPerChannel == 8 { - return densityGbx8ChannelToRowColumnEncoding[densityPerChannelGb] - } else { - return densityGbx16ChannelToRowColumnEncoding[densityPerChannelGb] - } - return 0 -} - -func encodeChannelsPerDie(channels int) byte { - var temp byte - - temp = byte(channels >> 1) - - return temp << 2 -} - -func encodePackage(dies int) byte { - var temp byte - - if dies > 1 { - /* If more than one die, then this is a non-monolithic device. */ - temp = 1 - } else { - /* If only single die, then this is a monolithic device. */ - temp = 0 - } - - return temp << 7 -} - -func encodeDiesPerPackage(memAttribs *memAttributes) byte { - var dies int = 0 - if currPlatform == PlatformTGL { - /* Intel MRC expects logical dies to be encoded for TGL. */ - dies = memAttribs.ChannelsPerDie * memAttribs.RanksPerChannel * memAttribs.BitWidthPerChannel / 16 - } else if currPlatform == PlatformJSL { - /* Intel MRC expects physical dies to be encoded for JSL. */ - dies = memAttribs.DiesPerPackage - } - - b := encodePackage(dies) /* Monolithic / Non-monolithic device */ - b |= (byte(dies) - 1) << 4 - - return b -} - -func encodePackageType(memAttribs *memAttributes) byte { - var b byte - - b |= encodeChannelsPerDie(memAttribs.ChannelsPerDie) - b |= encodeDiesPerPackage(memAttribs) - - return b -} - -func encodeDataWidth(bitWidthPerChannel int) byte { - return byte(bitWidthPerChannel / 8) -} - -func encodeRanks(ranks int) byte { - var b byte - b = byte(ranks - 1) - return b << 3 -} - -func encodeModuleOrganization(memAttribs *memAttributes) byte { - var b byte - - b = encodeDataWidth(memAttribs.BitWidthPerChannel) - b |= encodeRanks(memAttribs.RanksPerChannel) - - return b -} - -const ( - /* - * As per advisory 616599: - * 7:5 (Number of system channels) = 000 (1 channel always) - * 2:0 (Bus width) = 001 (x16 always) - * Set to 0x01. - */ - SPDValueBusWidthTGL = 0x01 - /* - * As per advisory 610202: - * 7:5 (Number of system channels) = 001 (2 channel always) - * 2:0 (Bus width) = 010 (x32 always) - * Set to 0x01. - */ - SPDValueBusWidthJSL = 0x22 -) - -func encodeBusWidth(memAttribs *memAttributes) byte { - if currPlatform == PlatformTGL { - return SPDValueBusWidthTGL - } else if currPlatform == PlatformJSL { - return SPDValueBusWidthJSL - } - return 0 -} - -func encodeTCKMin(memAttribs *memAttributes) byte { - return convPsToMtbByte(memAttribs.TCKMinPs) -} - -func encodeTCKMinFineOffset(memAttribs *memAttributes) byte { - return convPsToFtbByte(memAttribs.TCKMinPs) -} - -func encodeTCKMax(memAttribs *memAttributes) byte { - return convPsToMtbByte(memAttribs.TCKMaxPs) -} - -func encodeTCKMaxFineOffset(memAttribs *memAttributes) byte { - return convPsToFtbByte(memAttribs.TCKMaxPs) -} - -func encodeCASFirstByte(memAttribs *memAttributes) byte { - return memAttribs.CASFirstByte -} - -func encodeCASSecondByte(memAttribs *memAttributes) byte { - return memAttribs.CASSecondByte -} - -func encodeCASThirdByte(memAttribs *memAttributes) byte { - return memAttribs.CASThirdByte -} - -func divRoundUp(dividend int, divisor int) int { - return (dividend + divisor - 1) / divisor -} - -func convNsToPs(timeNs int) int { - return timeNs * 1000 -} - -func convMtbToPs(mtb int) int { - return mtb * 125 -} - -func convPsToMtb(timePs int) int { - return divRoundUp(timePs, 125) -} - -func convPsToMtbByte(timePs int) byte { - return byte(convPsToMtb(timePs) & 0xff) -} - -func convPsToFtbByte(timePs int) byte { - mtb := convPsToMtb(timePs) - ftb := timePs - convMtbToPs(mtb) - - return byte(ftb) -} - -func convNsToMtb(timeNs int) int { - return convPsToMtb(convNsToPs(timeNs)) -} - -func convNsToMtbByte(timeNs int) byte { - return convPsToMtbByte(convNsToPs(timeNs)) -} - -func convNsToFtbByte(timeNs int) byte { - return convPsToFtbByte(convNsToPs(timeNs)) -} - -func encodeTAAMin(memAttribs *memAttributes) byte { - return convPsToMtbByte(memAttribs.TAAMinPs) -} - -func encodeTAAMinFineOffset(memAttribs *memAttributes) byte { - return convPsToFtbByte(memAttribs.TAAMinPs) -} - -func encodeTRCDMin(memAttribs *memAttributes) byte { - return convNsToMtbByte(memAttribs.TRCDMinNs) -} - -func encodeTRCDMinFineOffset(memAttribs *memAttributes) byte { - return convNsToFtbByte(memAttribs.TRCDMinNs) -} - -func encodeTRPABMin(memAttribs *memAttributes) byte { - return convNsToMtbByte(memAttribs.TRPABMinNs) -} - -func encodeTRPABMinFineOffset(memAttribs *memAttributes) byte { - return convNsToFtbByte(memAttribs.TRPABMinNs) -} - -func encodeTRPPBMin(memAttribs *memAttributes) byte { - return convNsToMtbByte(memAttribs.TRPPBMinNs) -} - -func encodeTRPPBMinFineOffset(memAttribs *memAttributes) byte { - return convNsToFtbByte(memAttribs.TRPPBMinNs) -} - -func encodeTRFCABMinMsb(memAttribs *memAttributes) byte { - return byte((convNsToMtb(memAttribs.TRFCABNs) >> 8) & 0xff) -} - -func encodeTRFCABMinLsb(memAttribs *memAttributes) byte { - return byte(convNsToMtb(memAttribs.TRFCABNs) & 0xff) -} - -func encodeTRFCPBMinMsb(memAttribs *memAttributes) byte { - return byte((convNsToMtb(memAttribs.TRFCPBNs) >> 8) & 0xff) -} - -func encodeTRFCPBMinLsb(memAttribs *memAttributes) byte { - return byte(convNsToMtb(memAttribs.TRFCPBNs) & 0xff) -} - -type SPDAttribFunc func (*memAttributes) byte - -type SPDAttribTableEntry struct { - constVal byte - getVal SPDAttribFunc -} - -const ( - /* SPD Byte Index */ - SPDIndexSize = 0 - SPDIndexRevision = 1 - SPDIndexMemoryType = 2 - SPDIndexModuleType = 3 - SPDIndexDensityBanks = 4 - SPDIndexAddressing = 5 - SPDIndexPackageType = 6 - SPDIndexOptionalFeatures = 7 - SPDIndexModuleOrganization = 12 - SPDIndexBusWidth = 13 - SPDIndexTimebases = 17 - SPDIndexTCKMin = 18 - SPDIndexTCKMax = 19 - SPDIndexCASFirstByte = 20 - SPDIndexCASSecondByte = 21 - SPDIndexCASThirdByte = 22 - SPDIndexCASFourthByte = 23 - SPDIndexTAAMin = 24 - SPDIndexReadWriteLatency = 25 - SPDIndexTRCDMin = 26 - SPDIndexTRPABMin = 27 - SPDIndexTRPPBMin = 28 - SPDIndexTRFCABMinLSB = 29 - SPDIndexTRFCABMinMSB = 30 - SPDIndexTRFCPBMinLSB = 31 - SPDIndexTRFCPBMinMSB = 32 - SPDIndexTRPPBMinFineOffset = 120 - SPDIndexTRPABMinFineOffset = 121 - SPDIndexTRCDMinFineOffset = 122 - SPDIndexTAAMinFineOffset = 123 - SPDIndexTCKMaxFineOffset = 124 - SPDIndexTCKMinFineOffset = 125 - SPDIndexManufacturerPartNumberStartByte = 329 - SPDIndexManufacturerPartNumberEndByte = 348 - - /* SPD Byte Value */ - - /* - * From JEDEC spec: - * 6:4 (Bytes total) = 2 (512 bytes) - * 3:0 (Bytes used) = 3 (384 bytes) - * Set to 0x23 for LPDDR4x. - */ - SPDValueSize = 0x23 - - /* - * From JEDEC spec: Revision 1.1 - * Set to 0x11. - */ - SPDValueRevision = 0x11 - - /* LPDDR4x memory type = 0x11 */ - SPDValueMemoryType = 0x11 - - /* - * From JEDEC spec: - * 7:7 (Hybrid) = 0 (Not hybrid) - * 6:4 (Hybrid media) = 000 (Not hybrid) - * 3:0 (Base Module Type) = 1110 (Non-DIMM solution) - * - * This is dependent on hardware design. LPDDR4x only has memory down solution. - * Hence this is not hybrid non-DIMM solution. - * Set to 0x0E. - */ - SPDValueModuleType = 0x0e - - /* - * From JEDEC spec: - * 5:4 (Maximum Activate Window) = 00 (8192 * tREFI) - * 3:0 (Maximum Activate Count) = 1000 (Unlimited MAC) - * - * Needs to come from datasheet, but most parts seem to support unlimited MAC. - * MR#24 OP3 - */ - SPDValueOptionalFeatures = 0x08 - - /* - * From JEDEC spec: - * 3:2 (MTB) = 00 (0.125ns) - * 1:0 (FTB) = 00 (1ps) - * Set to 0x00. - */ - SPDValueTimebases = 0x00 - - /* CAS fourth byte: All bits are reserved */ - SPDValueCASFourthByte = 0x00 - - /* Write Latency Set A and Read Latency DBI-RD disabled. */ - SPDValueReadWriteLatency = 0x00 - - /* As per JEDEC spec, unused digits of manufacturer part number are left as blank. */ - SPDValueManufacturerPartNumberBlank = 0x20 -) - -var SPDAttribTable = map[int]SPDAttribTableEntry { - SPDIndexSize: { constVal: SPDValueSize }, - SPDIndexRevision: { constVal: SPDValueRevision }, - SPDIndexMemoryType: { constVal: SPDValueMemoryType }, - SPDIndexModuleType: { constVal: SPDValueModuleType }, - SPDIndexDensityBanks: { getVal: encodeDensityBanks }, - SPDIndexAddressing: { getVal: encodeSdramAddressing }, - SPDIndexPackageType: { getVal: encodePackageType }, - SPDIndexOptionalFeatures: { constVal: SPDValueOptionalFeatures }, - SPDIndexModuleOrganization: { getVal: encodeModuleOrganization }, - SPDIndexBusWidth: { getVal: encodeBusWidth }, - SPDIndexTimebases: { constVal: SPDValueTimebases }, - SPDIndexTCKMin: { getVal: encodeTCKMin }, - SPDIndexTCKMax: { getVal: encodeTCKMax }, - SPDIndexTCKMaxFineOffset: { getVal: encodeTCKMaxFineOffset }, - SPDIndexTCKMinFineOffset: { getVal: encodeTCKMinFineOffset }, - SPDIndexCASFirstByte: { getVal: encodeCASFirstByte }, - SPDIndexCASSecondByte: { getVal: encodeCASSecondByte }, - SPDIndexCASThirdByte: { getVal: encodeCASThirdByte }, - SPDIndexCASFourthByte: { constVal: SPDValueCASFourthByte }, - SPDIndexTAAMin: { getVal: encodeTAAMin }, - SPDIndexTAAMinFineOffset: { getVal: encodeTAAMinFineOffset }, - SPDIndexReadWriteLatency: { constVal: SPDValueReadWriteLatency }, - SPDIndexTRCDMin: { getVal: encodeTRCDMin }, - SPDIndexTRCDMinFineOffset: { getVal: encodeTRCDMinFineOffset }, - SPDIndexTRPABMin: { getVal: encodeTRPABMin }, - SPDIndexTRPABMinFineOffset: { getVal: encodeTRPABMinFineOffset }, - SPDIndexTRPPBMin: { getVal: encodeTRPPBMin }, - SPDIndexTRPPBMinFineOffset: { getVal: encodeTRPPBMinFineOffset }, - SPDIndexTRFCABMinLSB: { getVal: encodeTRFCABMinLsb }, - SPDIndexTRFCABMinMSB: { getVal: encodeTRFCABMinMsb }, - SPDIndexTRFCPBMinLSB: { getVal: encodeTRFCPBMinLsb }, - SPDIndexTRFCPBMinMSB: { getVal: encodeTRFCPBMinMsb }, -} - -type memParts struct { - MemParts []memPart `json:"parts"` -} - -type memPart struct { - Name string - Attribs memAttributes - SPDFileName string -} - -func writeSPDManifest(memParts *memParts, SPDDirName string) error { - var s string - - fmt.Printf("Generating SPD Manifest with following entries:\n") - - for i := 0; i < len(memParts.MemParts); i++ { - fmt.Printf("%-40s %s\n", memParts.MemParts[i].Name, memParts.MemParts[i].SPDFileName) - s += fmt.Sprintf("%s,%s\n", memParts.MemParts[i].Name, memParts.MemParts[i].SPDFileName) - } - - return ioutil.WriteFile(filepath.Join(SPDDirName, SPDManifestFileName), []byte(s), 0644) -} - -func isManufacturerPartNumberByte(index int) bool { - if index >= SPDIndexManufacturerPartNumberStartByte && index <= SPDIndexManufacturerPartNumberEndByte { - return true - } - return false -} - -func getSPDByte(index int, memAttribs *memAttributes) byte { - e, ok := SPDAttribTable[index] - if ok == false { - if isManufacturerPartNumberByte(index) { - return SPDValueManufacturerPartNumberBlank - } - return 0x00 - } - - if e.getVal != nil { - return e.getVal(memAttribs) - } - - return e.constVal -} - -func createSPD(memAttribs *memAttributes) string { - var s string - - for i := 0; i < 512; i++ { - b := getSPDByte(i, memAttribs) - - if (i + 1) % 16 == 0 { - s += fmt.Sprintf("%02X\n", b) - } else { - s += fmt.Sprintf("%02X ", b) - } - } - - return s -} - -func dedupeMemoryPart(dedupedParts []*memPart, memPart *memPart) bool { - for i := 0; i < len(dedupedParts); i++ { - if reflect.DeepEqual(dedupedParts[i].Attribs, memPart.Attribs) { - memPart.SPDFileName = dedupedParts[i].SPDFileName - return true - } - } - - return false -} - -func generateSPD(memPart *memPart, SPDId int, SPDDirName string) { - s := createSPD(&memPart.Attribs) - memPart.SPDFileName = fmt.Sprintf("spd-%d.hex", SPDId) - ioutil.WriteFile(filepath.Join(SPDDirName, memPart.SPDFileName), []byte(s), 0644) -} - -func readMemoryParts(memParts *memParts, memPartsFileName string) error { - databytes, err := ioutil.ReadFile(memPartsFileName) - if err != nil { - return err - } - - return json.Unmarshal(databytes, memParts) -} - -func validateDensityx8Channel(densityPerChannelGb int) error { - if _, ok := densityGbx8ChannelToRowColumnEncoding[densityPerChannelGb]; ok == false { - return fmt.Errorf("Incorrect x8 density: ", densityPerChannelGb, "Gb") - } - return nil -} - -func validateDensityx16Channel(densityPerChannelGb int) error { - if _, ok := densityGbx16ChannelToRowColumnEncoding[densityPerChannelGb]; ok == false { - return fmt.Errorf("Incorrect x16 density: ", densityPerChannelGb, "Gb") - } - return nil -} - -func validateDensity(memAttribs *memAttributes) error { - if memAttribs.BitWidthPerChannel == 8 { - return validateDensityx8Channel(memAttribs.DensityPerChannelGb) - } else if memAttribs.BitWidthPerChannel == 16 { - return validateDensityx16Channel(memAttribs.DensityPerChannelGb) - } - - return fmt.Errorf("No density table for this bit width: ", memAttribs.BitWidthPerChannel) -} - -func validateBanks(banks int) error { - if banks != 4 && banks != 8 { - return fmt.Errorf("Incorrect banks: ", banks) - } - return nil -} - -func validateChannels(channels int) error { - if channels != 1 && channels != 2 && channels != 4 { - return fmt.Errorf("Incorrect channels per die: ", channels) - } - return nil -} - -func validateDataWidth(width int) error { - if width != 8 && width != 16 { - return fmt.Errorf("Incorrect bit width: ", width) - } - return nil -} - -func validateRanks(ranks int) error { - if ranks != 1 && ranks != 2 { - return fmt.Errorf("Incorrect ranks: ", ranks) - } - return nil -} - -func validateSpeed(speed int) error { - if _, ok := speedMbpsToSPDEncoding[speed]; ok == false { - return fmt.Errorf("Incorrect speed: ", speed, " Mbps") - } - return nil -} - -func validateMemoryParts(memParts *memParts) error { - for i := 0; i < len(memParts.MemParts); i++ { - if err := validateBanks(memParts.MemParts[i].Attribs.Banks); err != nil { - return err - } - if err := validateChannels(memParts.MemParts[i].Attribs.ChannelsPerDie); err != nil { - return err - } - if err := validateDataWidth(memParts.MemParts[i].Attribs.BitWidthPerChannel); err != nil { - return err - } - if err := validateDensity(&memParts.MemParts[i].Attribs); err != nil { - return err - } - if err := validateRanks(memParts.MemParts[i].Attribs.RanksPerChannel); err != nil { - return err - } - if err := validateSpeed(memParts.MemParts[i].Attribs.SpeedMbps); err != nil { - return err - } - } - return nil -} - -func encodeLatencies(latency int, memAttribs *memAttributes) error { - switch latency { - case 6: - memAttribs.CASFirstByte |= CAS6 - case 10: - memAttribs.CASFirstByte |= CAS10 - case 14: - memAttribs.CASFirstByte |= CAS14 - case 16: - memAttribs.CASSecondByte |= CAS16 - case 20: - memAttribs.CASSecondByte |= CAS20 - case 22: - memAttribs.CASSecondByte |= CAS22 - case 24: - memAttribs.CASSecondByte |= CAS24 - case 26: - memAttribs.CASSecondByte |= CAS26 - case 28: - memAttribs.CASSecondByte |= CAS28 - case 32: - memAttribs.CASThirdByte |= CAS32 - case 36: - memAttribs.CASThirdByte |= CAS36 - case 40: - memAttribs.CASThirdByte |= CAS40 - default: - fmt.Errorf("Incorrect CAS Latency: ", latency) - } - - return nil -} - -func updateTCK(memAttribs *memAttributes) { - if memAttribs.TCKMinPs == 0 { - memAttribs.TCKMinPs = speedMbpsToSPDEncoding[memAttribs.SpeedMbps].TCKMinPs - } - if memAttribs.TCKMaxPs == 0 { - memAttribs.TCKMaxPs = speedMbpsToSPDEncoding[memAttribs.SpeedMbps].TCKMaxPs - } -} - -func getCASLatencies(memAttribs *memAttributes) string { - if memAttribs.BitWidthPerChannel == 16 { - return speedMbpsToSPDEncoding[memAttribs.SpeedMbps].CASLatenciesx16Channel - } else if memAttribs.BitWidthPerChannel == 8 { - return speedMbpsToSPDEncoding[memAttribs.SpeedMbps].CASLatenciesx8Channel - } - - return "" -} - -func updateCAS(memAttribs *memAttributes) error { - if len(memAttribs.CASLatencies) == 0 { - memAttribs.CASLatencies = getCASLatencies(memAttribs) - } - - latencies := strings.Fields(memAttribs.CASLatencies) - for i := 0; i < len(latencies); i++ { - latency,err := strconv.Atoi(latencies[i]) - if err != nil { - return fmt.Errorf("Unable to convert latency ", latencies[i]) - } - if err := encodeLatencies(latency, memAttribs); err != nil { - return err - } - } - return nil -} - -func getMinCAS(memAttribs *memAttributes) (int, error) { - if (memAttribs.CASThirdByte & CAS40) != 0 { - return 40, nil - } - if (memAttribs.CASThirdByte & CAS36) != 0 { - return 36, nil - } - if (memAttribs.CASThirdByte & CAS32) != 0 { - return 32, nil - } - if (memAttribs.CASSecondByte & CAS28) != 0 { - return 28, nil - } - - return 0, fmt.Errorf("Unexpected min CAS") -} - -func updateTAAMin(memAttribs *memAttributes) error { - if memAttribs.TAAMinPs == 0 { - minCAS, err := getMinCAS(memAttribs) - if err != nil { - return err - } - memAttribs.TAAMinPs = memAttribs.TCKMinPs * minCAS - } - - return nil -} - -func updateTRFCAB(memAttribs *memAttributes) { - if memAttribs.TRFCABNs == 0 { - memAttribs.TRFCABNs = densityGbPhysicalChannelToRefreshEncoding[memAttribs.DensityPerChannelGb].TRFCABNs - } -} - -func updateTRFCPB(memAttribs *memAttributes) { - if memAttribs.TRFCPBNs == 0 { - memAttribs.TRFCPBNs = densityGbPhysicalChannelToRefreshEncoding[memAttribs.DensityPerChannelGb].TRFCPBNs - } -} - -func updateTRCD(memAttribs *memAttributes) { - if memAttribs.TRCDMinNs == 0 { - /* JEDEC spec says max of 18ns */ - memAttribs.TRCDMinNs = 18 - } -} - -func updateTRPAB(memAttribs *memAttributes) { - if memAttribs.TRPABMinNs == 0 { - /* JEDEC spec says max of 21ns */ - memAttribs.TRPABMinNs = 21 - } -} - -func updateTRPPB(memAttribs *memAttributes) { - if memAttribs.TRPPBMinNs == 0 { - /* JEDEC spec says max of 18ns */ - memAttribs.TRPPBMinNs = 18 - } -} - -func normalizeMemoryAttributes(memAttribs *memAttributes) { - if currPlatform == PlatformTGL { - /* - * TGL does not really use physical organization of dies per package when - * generating the SPD. So, set it to 0 here so that deduplication ignores - * that field. - */ - memAttribs.DiesPerPackage = 0 - } -} - -func updateMemoryAttributes(memAttribs *memAttributes) error { - updateTCK(memAttribs) - if err := updateCAS(memAttribs); err != nil { - return err - } - if err := updateTAAMin(memAttribs); err != nil { - return err - } - updateTRFCAB(memAttribs) - updateTRFCPB(memAttribs) - updateTRCD(memAttribs) - updateTRPAB(memAttribs) - updateTRPPB(memAttribs) - - normalizeMemoryAttributes(memAttribs) - - return nil -} - -func isPlatformSupported(platform string) error { - var ok bool - - currPlatform, ok = platformMap[platform] - if ok == false { - return fmt.Errorf("Unsupported platform: ", platform) - } - - return nil -} - -func usage() { - fmt.Printf("\nUsage: %s <spd_dir> <mem_parts_list_json> <platform>\n\n", os.Args[0]) - fmt.Printf(" where,\n") - fmt.Printf(" spd_dir = Directory path containing SPD files and manifest generated by gen_spd.go\n") - fmt.Printf(" mem_parts_list_json = JSON File containing list of memory parts and attributes\n") - fmt.Printf(" platform = SoC Platform for which the SPDs are being generated\n\n\n") -} - -func main() { - if len(os.Args) != 4 { - usage() - log.Fatal("Incorrect number of arguments") - } - - var memParts memParts - var dedupedParts []*memPart - - SPDDir, GlobalMemPartsFile, Platform := os.Args[1], os.Args[2], strings.ToUpper(os.Args[3]) - - if err := isPlatformSupported(Platform); err != nil { - log.Fatal(err) - } - - if err := readMemoryParts(&memParts, GlobalMemPartsFile); err != nil { - log.Fatal(err) - } - - if err := validateMemoryParts(&memParts); err != nil { - log.Fatal(err) - } - - SPDId := 1 - - for i := 0; i < len(memParts.MemParts); i++ { - if err := updateMemoryAttributes(&memParts.MemParts[i].Attribs); err != nil { - log.Fatal(err) - } - - if dedupeMemoryPart(dedupedParts, &memParts.MemParts[i]) == false { - generateSPD(&memParts.MemParts[i], SPDId, SPDDir) - SPDId++ - dedupedParts = append(dedupedParts, &memParts.MemParts[i]) - } - } - - if err := writeSPDManifest(&memParts, SPDDir); err != nil { - log.Fatal(err) - } -} diff --git a/util/spd_tools/intel/lp4x/global_lp4x_mem_parts.json.txt b/util/spd_tools/intel/lp4x/global_lp4x_mem_parts.json.txt deleted file mode 100644 index 109fadb916..0000000000 --- a/util/spd_tools/intel/lp4x/global_lp4x_mem_parts.json.txt +++ /dev/null @@ -1,186 +0,0 @@ -{ - "parts": [ - { - "name": "H9HCNNNBKMMLXR-NEE", - "attribs": { - "densityPerChannelGb": 8, - "banks": 8, - "channelsPerDie": 2, - "diesPerPackage": 1, - "bitWidthPerChannel": 16, - "ranksPerChannel": 1, - "speedMbps": 4267 - } - }, - { - "name": "H9HCNNNFAMMLXR-NEE", - "attribs": { - "densityPerChannelGb": 8, - "banks": 8, - "channelsPerDie": 4, - "diesPerPackage": 2, - "bitWidthPerChannel": 8, - "ranksPerChannel": 2, - "speedMbps": 4267 - } - }, - { - "name": "K4U6E3S4AA-MGCL", - "attribs": { - "densityPerChannelGb": 8, - "banks": 8, - "channelsPerDie": 2, - "diesPerPackage": 1, - "bitWidthPerChannel": 16, - "ranksPerChannel": 1, - "speedMbps": 4267 - } - }, - { - "name": "K4UBE3D4AA-MGCL", - "attribs": { - "densityPerChannelGb": 8, - "banks": 8, - "channelsPerDie": 2, - "diesPerPackage": 2, - "bitWidthPerChannel": 16, - "ranksPerChannel": 2, - "speedMbps": 4267 - } - }, - { - "name": "MT53E1G32D2NP-046 WT:A", - "attribs": { - "densityPerChannelGb": 16, - "banks": 8, - "channelsPerDie": 2, - "diesPerPackage": 1, - "bitWidthPerChannel": 16, - "ranksPerChannel": 1, - "speedMbps": 4267 - } - }, - { - "name": "H9HKNNNCRMBVAR-NEH", - "attribs": { - "densityPerChannelGb": 8, - "banks": 8, - "channelsPerDie": 2, - "diesPerPackage": 2, - "bitWidthPerChannel": 16, - "ranksPerChannel": 1, - "speedMbps": 4267 - } - }, - { - "name": "MT53E1G64D4SQ-046 WT:A", - "attribs": { - "densityPerChannelGb": 16, - "banks": 8, - "channelsPerDie": 2, - "diesPerPackage": 2, - "bitWidthPerChannel": 16, - "ranksPerChannel": 1, - "speedMbps": 4267 - } - }, - { - "name": "MT53E512M32D2NP-046 WT:F", - "attribs": { - "densityPerChannelGb": 8, - "banks": 8, - "channelsPerDie": 2, - "diesPerPackage": 1, - "bitWidthPerChannel": 16, - "ranksPerChannel": 1, - "speedMbps": 4267 - } - }, - { - "name": "NT6AP256T32AV-J2", - "attribs": { - "densityPerChannelGb": 4, - "banks": 8, - "channelsPerDie": 2, - "diesPerPackage": 1, - "bitWidthPerChannel": 16, - "ranksPerChannel": 1, - "speedMbps": 3733, - "tckMaxPs": 1250, - "casLatencies": "14 20 24 28 32" - } - }, - { - "name": "K4U6E3S4AA-MGCR", - "attribs": { - "densityPerChannelGb": 8, - "banks": 8, - "channelsPerDie": 2, - "diesPerPackage": 1, - "bitWidthPerChannel": 16, - "ranksPerChannel": 1, - "speedMbps": 4267 - } - }, - { - "name": "MT53E512M32D2NP-046 WT:E", - "attribs": { - "densityPerChannelGb": 8, - "banks": 8, - "channelsPerDie": 2, - "diesPerPackage": 1, - "bitWidthPerChannel": 16, - "ranksPerChannel": 1, - "speedMbps": 4267 - } - }, - { - "name": "H9HCNNNCPMMLXR-NEE", - "attribs": { - "densityPerChannelGb": 8, - "banks": 8, - "channelsPerDie": 2, - "diesPerPackage": 2, - "bitWidthPerChannel": 16, - "ranksPerChannel": 2, - "speedMbps": 4267 - } - }, - { - "name": "K4UBE3D4AA-MGCR", - "attribs": { - "densityPerChannelGb": 8, - "banks": 8, - "channelsPerDie": 2, - "diesPerPackage": 2, - "bitWidthPerChannel": 16, - "ranksPerChannel": 2, - "speedMbps": 4267 - } - }, - { - "name": "MT53E512M64D4NW-046 WT:E", - "attribs": { - "densityPerChannelGb": 8, - "banks": 8, - "channelsPerDie": 2, - "diesPerPackage": 2, - "bitWidthPerChannel": 16, - "ranksPerChannel": 1, - "speedMbps": 4267 - } - }, - { - "name": "MT53E1G64D8NW-046 WT:E", - "attribs": { - "densityPerChannelGb": 8, - "banks": 8, - "channelsPerDie": 2, - "diesPerPackage": 4, - "bitWidthPerChannel": 16, - "ranksPerChannel": 2, - "speedMbps": 4267 - } - } - ] -} |