Files
slimbootloader/BootloaderCorePkg/Tools/GenReport.py
Mike Crowe 990e3e81e6 Use LF line endings in the repository
Convert the line endings stored for all text files in the repository to
LF. The majority previously used DOS-style CRLF line endings. Add a
.gitattributes file to enforce this and treat certain extensions as
never being text files.

Update PatchCheck.py to insist on LF line endings rather than CRLF.
However, its other checks fail on this commit due to lots of
pre-existing complaints that it only notices because the line endings
have changed.

Silicon/QemuSocPkg/FspBin/Patches/0001-Build-QEMU-FSP-2.0-binaries.patch
needs to be treated as binary since it contains a mixture of line
endings.

This change has implications depending on the client platform you are
using the repository from:

* Windows

The usual configuration for Git on Windows means that text files will
be checked out to the work tree with DOS-style CRLF line endings. If
that's not the case then you can configure Git to do so for the entire
machine with:

 git config --global core.autocrlf true

or for just the repository with:

 git config core.autocrlf true

Line endings will be normalised to LF when they are committed to the
repository. If you commit a text file with only LF line endings then it
will be converted to CRLF line endings in your work tree.

* Linux, MacOS and other Unices

The usual configuration for Git on such platforms is to check files out
of the repository with LF line endings. This is probably the right thing
for you. In the unlikely even that you are using Git on Unix but editing
or compiling on Windows for some reason then you may need to tweak your
configuration to force the use of CRLF line endings as described above.

* General

For more information see
https://docs.github.com/en/get-started/getting-started-with-git/configuring-git-to-handle-line-endings .

Fixes: https://github.com/slimbootloader/slimbootloader/issues/1400
Signed-off-by: Mike Crowe <mac@mcrowe.com>
2021-11-10 12:46:42 -08:00

778 lines
26 KiB
Python

## @ GenReport.py
#
# Copyright (c) 2017, Intel Corporation. All rights reserved.<BR>
# SPDX-License-Identifier: BSD-2-Clause-Patent
#
##
import os
import re
import sys
import uuid
from ctypes import *
from functools import reduce
sys.dont_write_bytecode = True
from BuildUtility import STITCH_OPS
def Bytes2Val(bytes):
return reduce(lambda x, y: (x << 8) | y, bytes[::-1])
def Val2Bytes(value, blen):
return [(value >> (i * 8) & 0xff) for i in range(blen)]
def AlignPtrUp(offset, alignment=8):
return (offset + alignment - 1) & ~(alignment - 1)
def AlignPtrDown(offset, alignment=8):
return offset & ~(alignment - 1)
def ExecAssignment (var, val):
namespace = {}
exec ('%s = %s' % (var, val), namespace)
return namespace[var]
class c_uint24(Structure):
_pack_ = 1
_fields_ = [('Data', (c_uint8 * 3))]
def __init__(self, val=0):
self.set_value(val)
def __str__(self, indent=0):
return '0x%.6x' % self.value
def __int__(self):
return self.get_value()
def set_value(self, val):
self.Data[0:3] = Val2Bytes(val, 3)
def get_value(self):
return Bytes2Val(self.Data[0:3])
value = property(get_value, set_value)
class EFI_FIRMWARE_VOLUME_HEADER(Structure):
_fields_ = [
('ZeroVector', ARRAY(c_uint8, 16)),
('FileSystemGuid', ARRAY(c_uint8, 16)),
('FvLength', c_uint64),
('Signature', ARRAY(c_char, 4)),
('Attributes', c_uint32),
('HeaderLength', c_uint16),
('Checksum', c_uint16),
('ExtHeaderOffset', c_uint16),
('Reserved', c_uint8),
('Revision', c_uint8)
]
class EFI_FIRMWARE_VOLUME_EXT_HEADER(Structure):
_fields_ = [
('FvName', ARRAY(c_uint8, 16)),
('ExtHeaderSize', c_uint32)
]
class EFI_FFS_INTEGRITY_CHECK(Structure):
_fields_ = [
('Header', c_uint8),
('File', c_uint8)
]
class EFI_FFS_FILE_HEADER(Structure):
_fields_ = [
('Name', ARRAY(c_uint8, 16)),
('IntegrityCheck', EFI_FFS_INTEGRITY_CHECK),
('Type', c_uint8),
('Attributes', c_uint8),
('Size', c_uint24),
('State', c_uint8)
]
class FSP_INFORMATION_HEADER(Structure):
_fields_ = [
('Signature', ARRAY(c_char, 4)),
('HeaderLength', c_uint32),
('Reserved1', c_uint16),
('SpecVersion', c_uint8),
('HeaderRevision', c_uint8),
('ImageRevision', c_uint32),
('ImageId', ARRAY(c_char, 8)),
('ImageSize', c_uint32),
('ImageBase', c_uint32),
('ImageAttribute', c_uint16),
('ComponentAttribute', c_uint16),
('CfgRegionOffset', c_uint32),
('CfgRegionSize', c_uint32),
('Reserved2', c_uint32),
('TempRamInitEntryOffset', c_uint32),
('Reserved3', c_uint32),
('NotifyPhaseEntryOffset', c_uint32),
('FspMemoryInitEntryOffset', c_uint32),
('TempRamExitEntryOffset', c_uint32),
('FspSiliconInitEntryOffset', c_uint32)
]
class IMG_INFO:
def __init__(self, Type, Name, Offset=0, Length=0, Base=0):
if Type == 'IMG':
self.Level = 0
elif Type == 'FD':
self.Level = 1
elif Type == 'FV' or Type == 'FSP':
self.Level = 2
elif Type == 'FFS':
self.Level = 3
else:
raise Exception('Invalid type "%s" !' % Type)
self.Name = Name
self.Type = Type
self.Offset = Offset
self.Length = Length
self.Base = Base
self.ChildList = []
def __str__(self):
Lines = []
Indent = ' ' * self.Level
Lines.append(Indent + 'Type : %s' % self.Type)
Lines.append(Indent + 'Name : %s' % self.Name)
Lines.append(Indent + 'Offset : 0x%08X' % self.Offset)
Lines.append(Indent + 'Length : 0x%08X' % self.Length)
Lines.append(Indent + 'Base : 0x%08X' % self.Base)
ChildLine = 'ChildList:'
if not len(self.ChildList):
ChildLine = ChildLine + ' []'
Lines.append(Indent + ChildLine)
else:
Lines.append(Indent + ChildLine)
for Child in self.ChildList:
Lines.append(str(Child))
Lines.append('\n')
return '\n'.join(Lines)
class REPORTER:
Cols = [4, 13, 15, 30]
def __init__(self, ImgName, RptType='FD'):
self.ImgName = ImgName
self.RptType = RptType
if RptType == 'FD':
self.Header = ['', 'FD', 'FV', 'FFS']
else:
self.Header = ['', 'Name', 'File', 'Details']
self.Layout = [[], [], [], []]
self.WordWrap = ['STAGE1', 'STAGE1A', 'STAGE1B', 'STAGE2']
self.DictDscDefines = {}
self.DictGuidNameXref = {
'1BA0062E-C779-4582-8566-336AE8F78F09': 'ResetVector',
'E08CA6D5-8D02-43AE-ABB1-952CC787C933': 'VbtBin',
'26FDAA3D-B7ED-4714-8509-EECF1593800D': 'AcmBin',
'5E2D3BE9-AD72-4D1D-AAD5-6B08AF921590': 'Logo',
'3473A022-C3C2-4964-B309-22B3DFB0B6CA': 'VerInfo',
'18EDB1DF-1DBE-4EC5-8E26-C44808B546E1': 'HashStore',
'EFAC3859-B680-4232-A159-F886F2AE0B83': 'PcdDatabase',
'CD17FF5E-7731-4D16-8441-FC7A113C392F': 'FitTable',
'3CEA8EF3-95FC-476F-ABA5-7EC5DFA1D77B': 'FlashMap',
'FFFFFFFF-FFFF-FFFF-FFFF-FFFFFFFFFFFF': 'BLANK'
}
self.ColsWidth = [4, 13, 15, 30]
def GetFspType(self, Attribute):
return "XTMSXXXXOXXXXXXX" [(Attribute >> 12) & 0x0F]
def GetFfsSize(self, FvFile, FfsOffset):
FdIn = open(FvFile, "rb")
FdIn.seek(FfsOffset)
Buffer = bytearray(FdIn.read(sizeof(EFI_FFS_FILE_HEADER)))
FdIn.close()
FfsHdr = EFI_FFS_FILE_HEADER.from_buffer(Buffer)
return int(FfsHdr.Size)
def GetFvFfsList(self, FvData):
FfsList = []
FvHdr = EFI_FIRMWARE_VOLUME_HEADER.from_buffer(FvData, 0)
if FvHdr.ExtHeaderOffset > 0:
FvExtHdr = EFI_FIRMWARE_VOLUME_EXT_HEADER.from_buffer(
Buffer, FvHdr.ExtHeaderOffset)
Offset = FvHdr.ExtHeaderOffset + FvExtHdr.ExtHeaderSize
else:
Offset = FvHdr.HeaderLength
while Offset < FvHdr.FvLength:
Offset = AlignPtrUp(Offset)
FfsHdr = EFI_FFS_FILE_HEADER.from_buffer(FvData, Offset)
FfsName = str(uuid.UUID(bytes_le=bytes(bytearray(FfsHdr.Name)))).upper()
Ffs = IMG_INFO('FFS', FfsName, Offset, int(FfsHdr.Size))
if bytearray(FfsHdr.Name) == b'\xff' * 16:
if (int(FfsHdr.Size) == 0xFFFFFF):
Ffs.Length = FvHdr.FvLength - Offset
Offset += Ffs.Length
FfsList.append(Ffs)
return FfsList
def ParseFdFile(self, FdFile):
FdSize = os.path.getsize(FdFile)
if FdSize < sizeof(EFI_FIRMWARE_VOLUME_HEADER):
return None
Fd = IMG_INFO('FD', os.path.basename(FdFile), 0, FdSize)
FvOffset = 0
FdIn = open(FdFile, "rb")
FdData = bytearray(FdIn.read())
FdIn.close()
while FvOffset < FdSize:
FvHdr = EFI_FIRMWARE_VOLUME_HEADER.from_buffer(FdData, FvOffset)
if b'_FVH' != FvHdr.Signature:
raise Exception("ERROR: Invalid FV header in FD '%s' !" %
FdFile)
FspHdr = FSP_INFORMATION_HEADER.from_buffer(FdData,
FvOffset + 0x94)
OldOffset = FvOffset
if b'FSPH' == FspHdr.Signature:
FvOffset += FspHdr.ImageSize
Fv = IMG_INFO(
'FSP', 'FSP-' + self.GetFspType(FspHdr.ComponentAttribute),
0, FspHdr.ImageSize, FspHdr.ImageBase)
Ffs = IMG_INFO('FFS', Fv.Name, 0, Fv.Length)
Fv.ChildList = [Ffs]
else:
FvOffset += FvHdr.FvLength
Fv = IMG_INFO('FV', 'UNKNOWN', 0, FvHdr.FvLength)
Fv.ChildList = self.GetFvFfsList(FdData[OldOffset:])
FirstFfs = Fv.ChildList[0]
FirstFfsName = self.GuidToModuleName(FirstFfs.Name)
if FirstFfsName.upper() == 'ACMBIN':
# For ACM FV, it contains ACM, BPM, KM, etc
# so let ACM occupy the full FV and ignore all other FFS
while len(Fv.ChildList) > 1:
Fv.ChildList.pop()
Fv.ChildList[0].Offset = 0
Fv.ChildList[0].Length = Fv.Length
if Fd.Name.startswith('STAGE2.'):
if ('STAGE2_LOAD_HIGH' in self.DictDscDefines) and \
(int(self.DictDscDefines['STAGE2_LOAD_HIGH'], 16) == 1):
# Mark FV/FSP will be loaded dynamically
Fv.Base = 0xFFFFFFFF
Fv.Offset = OldOffset
Fd.ChildList.append(Fv)
if FvOffset != FdSize:
raise Exception('Invalid FD format !')
return Fd
def ParseFvTxtFile(self, FvTxtFile):
FvName = os.path.basename(FvTxtFile)[0:-7].upper()
Fv = IMG_INFO('FV', FvName + '.FV')
FdIn = open(FvTxtFile, "r")
Lines = FdIn.readlines()
FdIn.close()
for Line in Lines:
Match = re.match("EFI_FV_TOTAL_SIZE\s+=\s+(0x[a-fA-F0-9]+)", Line)
if Match is not None:
Fv.Length = int(Match.group(1), 16)
continue
Match = re.match("(0x[a-fA-F0-9]+)\s([0-9a-fA-F\-]+)", Line)
if Match is not None:
Ffs = IMG_INFO('FFS', Match.group(2).upper())
Ffs.Offset = int(Match.group(1), 16)
Ffs.Length = self.GetFfsSize(FvTxtFile[:-4], Ffs.Offset)
Fv.ChildList.append(Ffs)
FdIn = open(FvTxtFile[0:-7] + '.inf', "r")
Lines = FdIn.readlines()
FdIn.close()
for Line in Lines:
Match = re.match("EFI_BASE_ADDRESS\s+=\s+(0x[a-fA-F0-9]+)", Line)
if Match is not None:
# Update base if it is not dynamic loading
if Fv.Base != 0xFFFFFFFF:
Fv.Base = int(Match.group(1), 16)
break
return Fv
def ParseGuidXrefFile(self, XrefFile):
FdIn = open(XrefFile, "r")
Lines = FdIn.readlines()
FdIn.close()
for Line in Lines:
Match = re.match("([0-9a-fA-F\-]+)\s(.+)", Line)
if Match:
Guid = Match.group(1).upper()
if Guid not in self.DictGuidNameXref:
Path = Match.group(2).strip()
Name = os.path.basename(Path)
self.DictGuidNameXref[Match.group(1).upper()] = Name
def ParseDscParameter(self, DefineDscFile):
FdIn = open(DefineDscFile, "r")
Lines = FdIn.readlines()
FdIn.close()
IsDefSection = False
for Line in Lines:
Line = Line.strip()
if Line.startswith('#'):
continue
if Line.startswith('['):
if Line.upper().startswith('[DEFINES]'):
IsDefSection = True
else:
IsDefSection = False
if IsDefSection:
Match = re.match("^DEFINE\s+([_\w]+)\s*=\s*([_\w]+)", Line)
if Match is not None:
self.DictDscDefines[Match.group(1).upper()] = Match.group(
2)
def GuidToModuleName(self, Guid):
if Guid in self.DictGuidNameXref:
return self.DictGuidNameXref[Guid]
else:
if len(Guid) < 0x24:
return Guid
else:
return '????'
def Report(self, FdList, CellHeight=3):
Cols = self.ColsWidth
LineHeight = CellHeight
def Center(Idx, ValueIn, Pattern):
Value = ValueIn.strip()
if Value == '':
Value = Pattern[2 * Idx + 1] * (REPORTER.Cols[Idx] - 1)
Space = REPORTER.Cols[Idx] - 1
Blank = Space - len(Value)
if Blank < 0:
Blank = 0
Value = Value[:Space]
Lead = Blank // 2
Tail = Blank - Lead
return ' ' * Lead + Value + ' ' * Tail + Pattern[2 * Idx + 2]
def OutSplitter(Pattern='+-+-+-+-+', Value=['', '', '', '']):
Lines = []
Lines.append(Pattern[0])
for i, j in enumerate(REPORTER.Cols):
Lines.append(Center(i, Value[i], Pattern))
return ' ' + ''.join(Lines)
def FillTable(Table, Base, TotalRow, Col, InputLine):
Lines = InputLine.split('!')
Count = TotalRow - len(Lines)
if Count < 0:
Start = 0
else:
Start = Base + (Count >> 1)
for Line in Lines:
if Start + 1 >= len(Table[Col]):
break
Table[Col][Start] = Line
Start += 1
def GetPattern(Layout, LineIdx):
Pattern = [ord(i) for i in '| + + + |']
for Col in range(len(Layout)):
Cnt = 0
Idx = Col * 2 + 1
for Val in Layout[Col]:
Cnt += Val
if LineIdx == Cnt - 1:
Pattern[Idx] = ord('-')
break
if LineIdx == sum(Layout[0]) - 1:
# Last line
Pattern[0] = ord('+')
Pattern[-1] = ord('+')
for Idx, Char in enumerate(Pattern):
if Char == ord('+') and Idx > 0 and Idx < len(Pattern) - 1:
# Check orphan in a row
if Pattern[Idx - 1] == ord(' ') and Pattern[Idx + 1] == ord(' '):
Pattern[Idx] = ord('|')
Pattern = ''.join(chr(i) for i in Pattern)
return Pattern
def Normalize(Com):
if Com.Type == 'FFS':
Name = self.GuidToModuleName(Com.Name)
else:
Name = Com.Name
if Com.Type in ['FV', 'FSP']:
if Com.Base == 0xFFFFFFFF:
Display = 'DYNAMIC'
else:
Display = '0x%X' % Com.Base
Name = '%s!(0x%X)!%s' % (Name, Com.Length, Display)
else:
Name = '%s!(0x%X)' % (Name, Com.Length)
Lines = Name.split('!')
Output = []
for Line in Lines:
Part = Line.split('.')[0]
Part = Part.replace(',', '.')
if len(Part) + 1 >= REPORTER.Cols[Com.Level]:
Idx = 0
for Word in self.WordWrap:
if Part.startswith(Word):
Idx = len(Word)
break
if Idx == 0:
Idx = len(Part) // 2
Part = '%s!%s' % (Part[:Idx], Part[Idx:])
Output.append(Part)
return '!'.join(Output)
def CalcRows(Image):
Layout = [[], [], [], []]
Idx1 = 0
for Img, FdList in Image:
Idx2 = 0
for Fd, FvList in FdList:
for Fv, FfsList in FvList:
FfsNum = 0
for Ffs in FfsList:
if Ffs.startswith('FSP'):
Adjust = 4
else:
Adjust = LineHeight
FfsNum += Adjust
Layout[3].append(Adjust)
Layout[2].append(FfsNum)
Layout[1].append(sum(Layout[2][Idx2:]))
Idx2 = len(Layout[2])
Layout[0].append(sum(Layout[1][Idx1:]))
Idx1 = len(Layout[1])
Count = sum(Layout[0])
self.Layout = Layout
Table = [[' ' for i in range(Count)] for i in range(len(Layout))]
Index = 0
FfsIdx = 0
FvIdx = 0
FdIdx = 0
for Idx0, (Img, FdList) in enumerate(Image):
FillTable(Table, Index, Layout[0][Idx0], 0, Img)
for Idx1, (Fd, FvList) in enumerate(FdList):
FillTable(Table, Index, Layout[1][FdIdx], 1, Fd)
for Idx2, (Fv, FfsList) in enumerate(FvList):
FillTable(Table, Index, Layout[2][FvIdx], 2, Fv)
for Idx3, Ffs in enumerate(FfsList):
FillTable(Table, Index, Layout[3][FfsIdx], 3, Ffs)
Index += Layout[3][FfsIdx]
FfsIdx += 1
FvIdx += 1
FdIdx += 1
return Table, Layout
def GetComponentLineIdx(Level, ObjIdx):
LineIdx = 0
LineLen = 0
for Idx, Each in enumerate(self.Layout[Level]):
if Idx == ObjIdx:
LineLen = Each
break
LineIdx += Each
return LineIdx, LineLen
def MarkFvInfo(Fv, FvIdx, Lines):
LineIdx, LineNum = GetComponentLineIdx(2, FvIdx)
Index = LineIdx + LineNum
Lines[Index] = Lines[Index] + ' %08X' % Fv.Base
Name = '!'.join(self.ImgName)
Tree = [(Name, [])]
FdParent = Tree[0][1]
for Fd in FdList:
FdParent.append((Normalize(Fd), []))
FvParent = FdParent[-1][1]
for Fv in Fd.ChildList:
FvParent.append((Normalize(Fv), []))
FfsParent = FvParent[-1][1]
for Ffs in Fv.ChildList:
FfsParent.append(Normalize(Ffs))
Table, Layout = CalcRows(Tree)
Rows = len(Table[0])
Lines = []
Header = OutSplitter(' ', self.Header)
Lines.append(OutSplitter())
for Idx in range(Rows):
Pattern = GetPattern(Layout, Idx)
Line = OutSplitter(Pattern, [Table[i][Idx] for i in range(4)])
Lines.append(Line)
FfsIdx = 0
ImgSize = 0
for Fd in FdList:
ImgSize += Fd.Length
Offset = ImgSize
TopOffset = Offset
LineIdx, LineNum = GetComponentLineIdx(3, 0)
Lines[LineIdx] += ' %08X' % (TopOffset)
for Fd in FdList:
for Fv in Fd.ChildList:
for Ffs in Fv.ChildList:
LineIdx, LineNum = GetComponentLineIdx(3, FfsIdx)
Index = LineIdx + LineNum
Offset -= Ffs.Length
Offset = AlignPtrDown(Offset)
if Ffs == Fv.ChildList[-1]:
if Fv.Type == 'FV':
Offset -= Ffs.Offset
Lines[Index] = Lines[Index] + ' %08X' % (Offset)
FfsIdx += 1
Lines.insert(0, Header)
print('\n'.join(Lines))
def ReportFd(FvDir, Title, FdNames):
# Parse all xref
Reporter = REPORTER(Title)
Reporter.ParseGuidXrefFile(os.path.join(FvDir, 'Guid.xref'))
Reporter.ParseDscParameter(os.path.join(
os.path.dirname(sys.argv[0]), '../Platform.dsc'))
# Get FVs
FvList = []
for File in os.listdir(FvDir):
if not File.lower().endswith('fv.txt'):
continue
Fv = Reporter.ParseFvTxtFile(os.path.join(FvDir, File))
FvList.append(Fv)
# Get FDs
FdList = []
for File in FdNames:
Fd = Reporter.ParseFdFile(os.path.join(FvDir, File + '.fd'))
if Fd is not None:
FdList.append(Fd)
# Reverse FD/FV/FFS
if True:
FdList.reverse()
for Fd in FdList:
Fd.ChildList.reverse()
for Fv in Fd.ChildList:
Fv.ChildList.reverse()
# Match FV binary into its FV Name/Base
for Fd in FdList:
for FvIndex, Fv1 in enumerate(Fd.ChildList):
if Fv1.Type == 'FSP':
continue
Found = False
for Fv2 in FvList:
if Fv2.Type != Fv1.Type or Fv2.Length != Fv1.Length:
continue
Match = 0
for FfsIndex, Child2 in enumerate(Fv2.ChildList):
for Child1 in Fv1.ChildList:
if Child1.Name == Child2.Name:
Match += 1
break
if Match == FfsIndex + 1:
Found = True
break
if Found:
if Fv1.Base != 0xFFFFFFFF:
Fv1.Base = Fv2.Base
Fv1.Name = Fv2.Name
else:
raise Exception("FV in FD could not be identified !")
if len(FdList):
Reporter.Report(FdList)
print('\n')
def ReportImageLayout(FvDir, ImgPath, ImgList, ImgStart, TopDown):
Name = os.path.splitext(os.path.basename(ImgPath))[0]
Name = Name.upper().replace('_', ' ')
Reporter = REPORTER(Name, 'IMG')
FdList = []
Offset = 0
FfsNum = 0
for Name, Algo, Val, Mode, Pos in ImgList:
BaseName = os.path.splitext(Name)[0]
Fd = IMG_INFO('FD', BaseName)
if Algo:
FileName = BaseName + '.lz'
Compressed = True
else:
FileName = Name
Compressed = False
OrgName = FileName
OrgSize = Val if Name == 'EMPTY' else os.path.getsize(os.path.join(FvDir, FileName))
if OrgSize == 0:
continue
if Mode != STITCH_OPS.MODE_FILE_NOP:
Padded = True
FileName = BaseName + '.pad'
else:
Padded = False
Fd.Offset = Offset
Fd.Length = Val if Name == 'EMPTY' else os.path.getsize(os.path.join(FvDir, FileName))
Offset += Fd.Length
FvName = FileName.replace('.', ',')
Fv = IMG_INFO('FV', FvName)
Fv.Offset = 0
Fv.Length = Fd.Length
FileSize = Fd.Length
OrgSize = AlignPtrUp(OrgSize, 8)
FfsName = OrgName.replace('.', ',')
NameList = [FfsName, 'BLANK']
if Compressed:
NameList[0] = 'Compressed!' + NameList[0]
elif Padded:
pass
else:
del NameList[1]
if NameList is None:
NameList = ['IMAGE', 'BLANK']
if Pos == STITCH_OPS.MODE_POS_HEAD:
if FileSize != OrgSize:
NameList.reverse()
OrgSize = FileSize - OrgSize
for Idx, Name in enumerate(NameList):
if Idx == 0:
Len = OrgSize
Ffs = IMG_INFO('FFS', Name, 0, Len)
else:
Len = FileSize - OrgSize
Ffs = IMG_INFO('FFS', Name, OrgSize, Len)
if Len:
Fv.ChildList.append(Ffs)
FfsNum += 1
Fd.ChildList.append(Fv)
FdList.append(Fd)
FinalSize = os.path.getsize(ImgPath)
if Offset < FinalSize:
Length = FinalSize - Offset
Fd = IMG_INFO('FD', 'BLANK', 0, Length)
Fv = IMG_INFO('FV', 'BLANK', 0, Length)
Ffs = IMG_INFO('FFS', 'BLANK', 0, Length)
Fv.ChildList.append(Ffs)
Fd.ChildList.append(Fv)
if TopDown:
FdList.insert(0, Fd)
else:
FdList.append(Fd)
FfsNum += 1
Base = None
for Fd in FdList:
for Fv in Fd.ChildList:
if Base is None:
if TopDown:
Base = ImgStart - FinalSize
else:
Base = ImgStart
Fv.Base = Base
Base += Fv.Length
# Reverse FD/FV/FFS
FdList.reverse()
for Fd in FdList:
Fd.ChildList.reverse()
for Fv in Fd.ChildList:
Fv.ChildList.reverse()
FfsHeight = 6
MinHeight = len(Reporter.ImgName) + 2
if FfsNum * FfsHeight <= MinHeight:
FfsHeight = (MinHeight + FfsNum - 1) // FfsNum
Reporter.Report(FdList, FfsHeight)
def Usage():
print("Usage: \n\tGenReport FvBuildDir [StitchInput]")
def Main():
if len(sys.argv) < 2:
Usage()
return 1
if len(sys.argv) < 3:
StitchInput = 'ImgStitch.txt'
else:
StitchInput = sys.argv[2]
FvDir = sys.argv[1]
ImgLayoutPath = os.path.join(FvDir, StitchInput)
if not os.path.exists(ImgLayoutPath):
raise Exception("No layout file '%s' found !" % StitchInput)
return 0
FdIn = open(ImgLayoutPath, 'r')
Lines = FdIn.readlines()
FdIn.close()
FdReported = False
FdNames = ['STAGE2', 'STAGE1B', 'STAGE1A']
for Line in Lines:
Line = Line.strip()
Parts = Line.split('=')
if len(Parts) == 2:
if Parts[0].strip() == 'BOARD_INFO':
BrdInfo = ExecAssignment ('BrdInfo', Parts[1])
Title = 'Flash Layout for Board %s' % BrdInfo[0]
Padding = (sum(REPORTER.Cols) - len(Title)) // 2
if Padding < 0:
Padding = 0
print('')
print(' %s%s' % (' ' * Padding, Title))
print(' %s%s' % (' ' * Padding, '=' * len(Title)))
if Parts[0].strip() == 'IMAGE_INFO':
ImgInfo = ExecAssignment ('ImgInfo', Parts[1])
ImgPath = os.path.join(FvDir, ImgInfo[0])
Start = ImgInfo[1]
TopDown = ImgInfo[2]
if not FdReported:
for Name in FdNames:
ReportFd(FvDir, '', [Name])
FdReported = True
elif Parts[0].strip() == 'IMAGE_LIST':
ImgList = ExecAssignment ('ImgList', Parts[1])
ReportImageLayout(FvDir, ImgPath, ImgList, Start, TopDown)
print('\n')
return 0
if __name__ == '__main__':
sys.exit(Main())