summaryrefslogtreecommitdiffstats
path: root/util
diff options
context:
space:
mode:
authorRobert Zieba <robertzieba@google.com>2022-03-17 13:14:12 -0600
committerKarthik Ramasubramanian <kramasub@google.com>2022-03-22 16:17:06 +0000
commita6425f170c858a75a24ec9c522a85876eb9daa43 (patch)
treec1e82b281aceb010c913bdd5ab96e67ad48d505c /util
parent5d3b1bbce4b3aefaee66e1d96be058397a9d7840 (diff)
downloadcoreboot-a6425f170c858a75a24ec9c522a85876eb9daa43.tar.gz
coreboot-a6425f170c858a75a24ec9c522a85876eb9daa43.tar.bz2
coreboot-a6425f170c858a75a24ec9c522a85876eb9daa43.zip
util/spd_tools: Add support for exclusive IDs
Currently memory parts that use the same SPD are assigned the same ID by spd_tools. This commit adds support for exclusive IDs. When given an exclusive ID a memory part will not share its ID with other parts unless they also have the same exclusive ID. BUG=b:225161910 TEST=Ran part_id_gen and checked that exclusive IDs work correctly and that the current behavior still works in their abscence. Signed-off-by: Robert Zieba <robertzieba@google.com> Change-Id: Ife5afe32337f69bc06451ce16238c7a83bc983c8 Reviewed-on: https://review.coreboot.org/c/coreboot/+/62905 Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: Karthik Ramasubramanian <kramasub@google.com>
Diffstat (limited to 'util')
-rw-r--r--util/spd_tools/README.md20
-rw-r--r--util/spd_tools/src/part_id_gen/part_id_gen.go59
2 files changed, 62 insertions, 17 deletions
diff --git a/util/spd_tools/README.md b/util/spd_tools/README.md
index 3a1342c85ab1..01bc417c8b14 100644
--- a/util/spd_tools/README.md
+++ b/util/spd_tools/README.md
@@ -459,10 +459,14 @@ This program takes the following inputs:
* The memory technology used by the board, e.g. lp4x.
* The path to the directory where the generated Makefile.inc should be placed.
* A CSV file containing a list of the memory parts used by the board, with an
- optional fixed ID for each part. NOTE: Only assign a fixed ID if required
- for legacy reasons.
+* optional fixed or exclusive ID for each part. A fixed ID is simply an integer
+* and it ensure that part (and any that share the same SPD) will be assigned
+* that ID. An exclusive ID is prefixed with `*` and ensures that only parts with
+* the same exclusive ID will be assigned that ID, even if they would otherwise
+* share the same ID.
+* NOTE: Only assign a fixed/exclusive ID if required for legacy reasons.
-Example of a CSV file using fixed IDs:
+Example of a CSV file using fixed and exclusive IDs:
```
K4AAG165WA-BCWE,1
@@ -470,13 +474,15 @@ MT40A512M16TB-062E:J
MT40A1G16KD-062E:E
K4A8G165WC-BCWE
H5AN8G6NDJR-XNC,8
-H5ANAG6NCMR-XNC
+H5ANAG6NCMR-XNC,*9
```
Explanation: This will ensure that the SPDs for K4AAG165WA-BCWE and
-H5AN8G6NDJR-XNC are assigned to IDs 1 and 8 respectively. The SPDs for all other
-memory parts will be assigned to the first compatible ID. Assigning fixed IDs
-may result in duplicate SPD entries or gaps in the ID mapping.
+H5AN8G6NDJR-XNC are assigned to IDs 1 and 8 respectively. H5ANAG6NCMR-XNC
+will be assigned ID 9 and no other part will be assigned ID 9 even if it
+shares the same SPD. The SPDs for all other memory parts will be assigned to
+the first compatible ID. Assigning fixed/exclusive IDs may result in duplicate
+SPD entries or gaps in the ID mapping.
### Output
diff --git a/util/spd_tools/src/part_id_gen/part_id_gen.go b/util/spd_tools/src/part_id_gen/part_id_gen.go
index 750b825e4e25..65e07f426f99 100644
--- a/util/spd_tools/src/part_id_gen/part_id_gen.go
+++ b/util/spd_tools/src/part_id_gen/part_id_gen.go
@@ -93,9 +93,18 @@ func checkArgs(platform string, memTech string, makefileDir string, memPartsUsed
return nil
}
+type mappingType int
+
+const (
+ Auto mappingType = iota
+ Fixed
+ Exclusive
+)
+
type usedPart struct {
partName string
index int
+ mapping mappingType
}
func readPlatformsManifest(memTech string) (map[string]string, error) {
@@ -174,16 +183,28 @@ func readParts(memPartsUsedFileName string) ([]usedPart, error) {
}
if len(fields) == 1 {
- parts = append(parts, usedPart{fields[0], -1})
+ parts = append(parts, usedPart{fields[0], -1, Auto})
} else if len(fields) == 2 {
- assignedId, err := strconv.Atoi(fields[1])
+ var mapping = Auto
+ var assignedId = -1
+ var err error = nil
+
+ if len(fields[1]) >= 2 && fields[1][0] == '*' {
+ // Exclusive mapping
+ mapping = Exclusive
+ assignedId, err = strconv.Atoi(fields[1][1:])
+ } else {
+ mapping = Fixed
+ 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})
+ parts = append(parts, usedPart{fields[0], assignedId, mapping})
} else {
return nil, fmt.Errorf("mem_parts_used_file file is incorrectly formatted")
}
@@ -245,7 +266,7 @@ type partIds struct {
}
func getFileHeader() string {
- return `# SPDX-License-Identifier: GPL-2.0-or-later
+ return `# SPDX-License-Identifier: GPL-2.0-or-later
# This is an auto-generated file. Do not edit!!
# Generated by:
` + fmt.Sprintf("# %s\n\n", strings.Join(os.Args[0:], " "))
@@ -262,6 +283,7 @@ func getFileHeader() string {
*/
func genPartIdInfo(parts []usedPart, partToSPDMap map[string]string, SPDToIndexMap map[string]int, makefileDirName string) ([]partIds, error) {
partIdList := []partIds{}
+ assignedMapping := []mappingType{}
var s string
// Assign parts with fixed ids first
@@ -280,19 +302,34 @@ func genPartIdInfo(parts []usedPart, partToSPDMap map[string]string, SPDToIndexM
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
+ // Extend partIdList and assignedMapping with empty entries if needed
for i := len(partIdList) - 1; i < p.index; i++ {
partIdList = append(partIdList, partIds{})
+ assignedMapping = append(assignedMapping, Auto)
}
- if partIdList[p.index].SPDFileName != "" {
- return nil, fmt.Errorf("Part ", p.partName, " is assigned to an already assigned ID ", p.index)
+ // Only allow parts with the same index if they share the same SPD
+ assignedSPD := partIdList[p.index].SPDFileName
+ if assignedSPD != "" && assignedSPD != partToSPDMap[p.partName] {
+ return nil, fmt.Errorf("ID %d is already assigned to %s, conflicting with %s(%s)", p.index, assignedSPD, p.partName, SPDFileName)
}
- partIdList[p.index] = partIds{SPDFileName: SPDFileName, memParts: p.partName}
+ mapping := assignedMapping[p.index]
+ if (mapping == Fixed && p.mapping == Exclusive) || (mapping == Exclusive && p.mapping == Fixed) {
+ return nil, fmt.Errorf("Exclusive/non-exclusive conflict in assigning %s to ID %d", p.partName, p.index)
+ } else {
+ assignedMapping[p.index] = p.mapping
+ }
+
+ if partIdList[p.index].memParts == "" {
+ partIdList[p.index] = partIds{SPDFileName: SPDFileName, memParts: p.partName}
+ } else {
+ partIdList[p.index].memParts += ", " + p.partName
+ }
// SPDToIndexMap should point to first assigned index in the used part list
- if SPDToIndexMap[SPDFileName] < 0 {
+ // Exclusive entries don't update the map because they're not valid for auto assigning
+ if SPDToIndexMap[SPDFileName] < 0 && p.mapping != Exclusive {
SPDToIndexMap[SPDFileName] = p.index
}
}
@@ -317,7 +354,8 @@ func genPartIdInfo(parts []usedPart, partToSPDMap map[string]string, SPDToIndexM
}
index := SPDToIndexMap[SPDFileName]
- if index != -1 {
+ // Only Exclusive mappings don't allow automatic assigning of parts
+ if index != -1 && assignedMapping[index] != Exclusive {
partIdList[index].memParts += ", " + p.partName
appendPartIdInfo(&s, p.partName, index)
continue
@@ -338,6 +376,7 @@ func genPartIdInfo(parts []usedPart, partToSPDMap map[string]string, SPDToIndexM
return nil, fmt.Errorf("Maximum part ID %d exceeded.", MaxMemoryId)
}
partIdList = append(partIdList, partIds{})
+ assignedMapping = append(assignedMapping, Auto)
}
SPDToIndexMap[SPDFileName] = index