util/spd_tools: Add ability to override SPD file for parts

This commit adds the ability to override the SPD file that is used for a
specific part.

BUG=b:224884904
TEST=Verified that generated makefile uses specified SPD file and that
it remains unchanged when this capability is not used

Signed-off-by: Robert Zieba <robertzieba@google.com>
Change-Id: I078dd04fead2bf19f53bc6ca8295187d439adc20
Reviewed-on: https://review.coreboot.org/c/coreboot/+/63281
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Rob Barnes <robbarnes@google.com>
This commit is contained in:
Robert Zieba
2022-04-01 09:48:28 -06:00
committed by Felix Held
parent be1a050772
commit 255b1fb38b
2 changed files with 64 additions and 27 deletions

View File

@ -459,14 +459,16 @@ 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 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.
* optional fixed or exclusive ID for each part and an optional SPD override file.
* 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. When using an SPD override file, the file will be searched
* for in the directory where mem_parts_used is located, if it is not found there then it
* will be searched for in the appropriate default spd directory.
* NOTE: Only assign a fixed/exclusive ID if required for legacy reasons.
Example of a CSV file using fixed and exclusive IDs:
Example of a CSV file using fixed and exclusive IDs, and SPD file overrides:
```
K4AAG165WA-BCWE,1
@ -475,6 +477,8 @@ MT40A1G16KD-062E:E
K4A8G165WC-BCWE
H5AN8G6NDJR-XNC,8
H5ANAG6NCMR-XNC,*9
H9HCNNNCPMMLXR-NEE,,H9HCNNNCPMMLXR-NEE.hex
H54G56CYRBX247,4,H54G56CYRBX247.hex
```
Explanation: This will ensure that the SPDs for K4AAG165WA-BCWE and

View File

@ -102,9 +102,10 @@ const (
)
type usedPart struct {
partName string
index int
mapping mappingType
partName string
index int
mapping mappingType
SPDOverride string
}
func readPlatformsManifest(memTech string) (map[string]string, error) {
@ -183,30 +184,44 @@ func readParts(memPartsUsedFileName string) ([]usedPart, error) {
}
if len(fields) == 1 {
parts = append(parts, usedPart{fields[0], -1, Auto})
} else if len(fields) == 2 {
parts = append(parts, usedPart{fields[0], -1, Auto, ""})
} else {
var mapping = Auto
var assignedId = -1
var err error = nil
var spdOverride string = ""
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])
// Second column, ID override
if len(fields) >= 2 {
if len(fields[1]) >= 2 && fields[1][0] == '*' {
// Exclusive mapping
mapping = Exclusive
assignedId, err = strconv.Atoi(fields[1][1:])
} else if fields[1] != "" {
// Fixed mapping
mapping = Fixed
assignedId, err = strconv.Atoi(fields[1])
}
}
// Third column, SPD file override
if len(fields) >= 3 {
if len(fields[2]) == 0 {
err = fmt.Errorf("mem_parts_used_file file is incorrectly formatted, SPD file column is empty")
} else {
spdOverride = fields[2]
}
}
if err != nil {
return nil, err
}
if assignedId > MaxMemoryId || assignedId < 0 {
if assignedId > MaxMemoryId {
return nil, fmt.Errorf("Out of bounds assigned id %d for part %s", assignedId, fields[0])
}
parts = append(parts, usedPart{fields[0], assignedId, mapping})
} else {
return nil, fmt.Errorf("mem_parts_used_file file is incorrectly formatted")
parts = append(parts, usedPart{fields[0], assignedId, mapping, spdOverride})
}
}
@ -288,7 +303,6 @@ func genPartIdInfo(parts []usedPart, partToSPDMap map[string]string, SPDToIndexM
// Assign parts with fixed ids first
for _, p := range parts {
if p.index == -1 {
continue
}
@ -299,7 +313,7 @@ func genPartIdInfo(parts []usedPart, partToSPDMap map[string]string, SPDToIndexM
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")
return nil, fmt.Errorf("Failed to find part %s in SPD Manifest. Please add the part to global part list and regenerate SPD Manifest", p.partName)
}
// Extend partIdList and assignedMapping with empty entries if needed
@ -396,7 +410,7 @@ func genPartIdInfo(parts []usedPart, partToSPDMap map[string]string, SPDToIndexM
* This function generates Makefile.inc under the variant directory path and adds assigned SPDs
* to SPD_SOURCES.
*/
func genMakefile(partIdList []partIds, makefileDirName string, SPDDir string) error {
func genMakefile(partIdList []partIds, makefileDirName string, SPDDir string, partsDir string) error {
s := getFileHeader()
s += fmt.Sprintf("SPD_SOURCES =\n")
@ -405,7 +419,18 @@ func genMakefile(partIdList []partIds, makefileDirName string, SPDDir string) er
s += fmt.Sprintf("SPD_SOURCES += %v ", filepath.Join(SPDDir, SPDEmptyFileName))
s += fmt.Sprintf(" # ID = %d(0b%04b)\n", i, int64(i))
} else {
s += fmt.Sprintf("SPD_SOURCES += %v ", filepath.Join(SPDDir, partIdList[i].SPDFileName))
SPDFileName := partIdList[i].SPDFileName
path := filepath.Join(partsDir, SPDFileName)
// Check if the file exists in the directory of the parts file
if _, err := os.Stat(path); err != nil {
// File doesn't exist, check spd directory
path = filepath.Join(SPDDir, SPDFileName)
if _, err = os.Stat(path); err != nil {
return fmt.Errorf("Failed to write Makefile, SPD file '%s' doesn't exist", SPDFileName)
}
}
s += fmt.Sprintf("SPD_SOURCES += %v ", path)
s += fmt.Sprintf(" # ID = %d(0b%04b) ", i, int64(i))
s += fmt.Sprintf(" Parts = %04s\n", partIdList[i].memParts)
}
@ -442,12 +467,20 @@ func main() {
log.Fatal(err)
}
// Update our SPD maps with part specific overrides
for _, p := range parts {
if p.SPDOverride != "" {
partToSPDMap[p.partName] = p.SPDOverride
SPDToIndexMap[p.SPDOverride] = -1
}
}
partIdList, err := genPartIdInfo(parts, partToSPDMap, SPDToIndexMap, makefileDir)
if err != nil {
log.Fatal(err)
}
if err := genMakefile(partIdList, makefileDir, SPDDir); err != nil {
if err := genMakefile(partIdList, makefileDir, SPDDir, filepath.Dir(memPartsUsedFile)); err != nil {
log.Fatal(err)
}
}