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>
This commit is contained in:
Robert Zieba
2022-03-17 13:14:12 -06:00
committed by Karthik Ramasubramanian
parent 5d3b1bbce4
commit a6425f170c
2 changed files with 62 additions and 17 deletions

View File

@ -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