diff options
Diffstat (limited to 'util/spd_tools/ddr4/gen_part_id.go')
-rw-r--r-- | util/spd_tools/ddr4/gen_part_id.go | 138 |
1 files changed, 115 insertions, 23 deletions
diff --git a/util/spd_tools/ddr4/gen_part_id.go b/util/spd_tools/ddr4/gen_part_id.go index e0adaaf994..c0098aba1d 100644 --- a/util/spd_tools/ddr4/gen_part_id.go +++ b/util/spd_tools/ddr4/gen_part_id.go @@ -10,7 +10,7 @@ import ( "log" "os" "path/filepath" - "strings" + "strconv" ) /* @@ -28,6 +28,7 @@ const ( SPDManifestFileName = "ddr4_spd_manifest.generated.txt" MakefileName = "Makefile.inc" DRAMIdFileName = "dram_id.generated.txt" + MaxMemoryId = 15 ) func usage() { @@ -35,7 +36,7 @@ func usage() { 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") + fmt.Printf(" mem_parts_used_file = CSV file containing list of memory parts used by the board and optional fixed ids\n\n\n") } func checkArgs() error { @@ -49,17 +50,53 @@ func checkArgs() error { return nil } +type usedPart struct { + partName string + index int +} /* - * 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. + * Read input file CSV that contains list of memory part names used by the variant + * and an optional assigned id. */ -func readParts(memPartsUsedFileName string) ([]string, error) { - lines, err := ioutil.ReadFile(memPartsUsedFileName) +func readParts(memPartsUsedFileName string) ([]usedPart, error) { + + f, err := os.Open(memPartsUsedFileName) if err != nil { return nil, err } - str := string(lines) - parts := strings.Split(str, "\n") + defer f.Close() + r := csv.NewReader(f) + r.FieldsPerRecord = -1 // Allow variable length records + r.TrimLeadingSpace = true + + parts := []usedPart{} + + for { + fields, err := r.Read() + + if err == io.EOF { + break + } + + if err != nil { + return nil, err + } + + if len(fields) == 1 { + parts = append(parts, usedPart{fields[0], -1}) + } else if len(fields) == 2 { + assignedId, err := strconv.Atoi(fields[1]) + if err != nil { + return nil, err + } + if assignedId > MaxMemoryId || assignedId < 0 { + return nil, fmt.Errorf("Out of bounds assigned id %d for part %s", assignedId, fields[0]) + } + parts = append(parts, usedPart{fields[0], assignedId}) + } else { + return nil, fmt.Errorf("mem_parts_used_file file is incorrectly formatted") + } + } return parts, nil } @@ -124,37 +161,87 @@ type partIds struct { * 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) { +func genPartIdInfo(parts []usedPart, partToSPDMap map[string]string, SPDToIndexMap map[string]int, makefileDirName string) ([]partIds, error) { + partIdList := []partIds{} - curId := 0 var s string + // Assign parts with fixed ids first + for _, p := range parts { + + if p.index == -1 { + continue + } + + if p.partName == "" { + return nil, fmt.Errorf("Invalid part entry") + } + + SPDFileName,ok := partToSPDMap[p.partName] + if !ok { + return nil, fmt.Errorf("Failed to find part ", p.partName, " in SPD Manifest. Please add the part to global part list and regenerate SPD Manifest") + } + + // Extend partIdList with empty entries if needed + for i := len(partIdList) - 1; i < p.index; i++ { + partIdList = append(partIdList, partIds{}) + } + + if partIdList[p.index].SPDFileName != "" { + return nil, fmt.Errorf("Part ", p.partName, " is assigned to an already assigned ID ", p.index) + } + + partIdList[p.index] = partIds{SPDFileName: SPDFileName, memParts: p.partName} + + // SPDToIndexMap should point to first assigned index in the used part list + if SPDToIndexMap[SPDFileName] < 0 { + SPDToIndexMap[SPDFileName] = p.index + } + } + s += fmt.Sprintf("%-30s %s\n", "DRAM Part Name", "ID to assign") + // Assign parts with no fixed id for _, p := range parts { - if p == "" { + if p.partName == "" { + return nil, fmt.Errorf("Invalid part entry") + } + + // Add assigned parts to dram id file in the order they appear + if p.index != -1 { + appendPartIdInfo(&s, p.partName, p.index) continue } - SPDFileName,ok := partToSPDMap[p] + SPDFileName,ok := partToSPDMap[p.partName] 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") + return nil, fmt.Errorf("Failed to find part ", p.partName, " 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) + partIdList[index].memParts += ", " + p.partName + appendPartIdInfo(&s, p.partName, index) continue } - SPDToIndexMap[SPDFileName] = curId + // Find first empty index + for i, partId := range partIdList { + if partId.SPDFileName == "" { + index = i + break + } + } - appendPartIdInfo(&s, p, curId) - entry := partIds{SPDFileName: SPDFileName, memParts: p} - partIdList = append(partIdList, entry) + // Append new entry + if index == -1 { + index = len(partIdList) + partIdList = append(partIdList, partIds{}) + } - curId++ + SPDToIndexMap[SPDFileName] = index + appendPartIdInfo(&s, p.partName, index) + partIdList[index] = partIds{SPDFileName: SPDFileName, memParts: p.partName} } fmt.Printf("%s", s) @@ -177,9 +264,14 @@ func genMakefile(partIdList []partIds, makefileDirName string) error { 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) + if partIdList[i].SPDFileName == "" { + s += fmt.Sprintf("SPD_SOURCES += %s ", "ddr4-spd-empty.hex") + s += fmt.Sprintf(" # ID = %d(0b%04b)\n", i, int64(i)) + } else { + 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) |