aboutsummaryrefslogtreecommitdiff
path: root/util/spd_tools/ddr4/gen_part_id.go
diff options
context:
space:
mode:
Diffstat (limited to 'util/spd_tools/ddr4/gen_part_id.go')
-rw-r--r--util/spd_tools/ddr4/gen_part_id.go138
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)