BaseTools:Add the spare space FV image size checker

REF:https://bugzilla.tianocore.org/show_bug.cgi?id=2654

If FV is placed in FD region, its FV image size is fixed.
When FV image size exceeds it, it will trig the build break.
To alert the developer to adjust FV image size earlier,
I request to add new checker for the the spare FV space.
When the spare FV space is less than the specified threshold,
build tool will report the error.

This checker is the optional.
It can be enabled by -D FV_SPARE_SPACE_THRESHOLD=10000.
Macro is the value of the spare space threshold size.
It can be decimal or hex format. If it is enabled,
BaseTools will check every FV with the fixed size.
If FV doesn't meet with the size requirement,
Build tool will report error message to say there is no
enough spare space.

Cc: Liming Gao <liming.gao@intel.com>
Cc: Bob Feng <bob.c.feng@intel.com>
Signed-off-by: Zhiju.Fan <zhijux.fan@intel.com>
Reviewed-by: Bob Feng <bob.c.feng@intel.com>
This commit is contained in:
Fan, Zhiju 2020-04-20 09:20:52 +08:00 committed by mergify[bot]
parent 93f6df5f3b
commit 3a3a3af4a2
2 changed files with 49 additions and 0 deletions

View File

@ -64,6 +64,8 @@ COMMAND_FAILURE = 0x7000
PERMISSION_FAILURE = 0x8000
FV_FREESIZE_ERROR = 0x9000
CODE_ERROR = 0xC0DE
AUTOGEN_ERROR = 0xF000

View File

@ -25,6 +25,7 @@ import traceback
import multiprocessing
from threading import Thread,Event,BoundedSemaphore
import threading
from linecache import getlines
from subprocess import Popen,PIPE, STDOUT
from collections import OrderedDict, defaultdict
@ -1413,6 +1414,9 @@ class Build():
if Target == 'fds':
if GenFdsApi(AutoGenObject.GenFdsCommandDict, self.Db):
EdkLogger.error("build", COMMAND_FAILURE)
Threshold = self.GetFreeSizeThreshold()
if Threshold:
self.CheckFreeSizeThreshold(Threshold, AutoGenObject.FvDir)
return True
# run
@ -2311,6 +2315,9 @@ class Build():
GenFdsStart = time.time()
if GenFdsApi(Wa.GenFdsCommandDict, self.Db):
EdkLogger.error("build", COMMAND_FAILURE)
Threshold = self.GetFreeSizeThreshold()
if Threshold:
self.CheckFreeSizeThreshold(Threshold, Wa.FvDir)
#
# Create MAP file for all platform FVs after GenFds.
@ -2322,6 +2329,46 @@ class Build():
#
self._SaveMapFile(MapBuffer, Wa)
self.CreateGuidedSectionToolsFile(Wa)
## GetFreeSizeThreshold()
#
# @retval int Threshold value
#
def GetFreeSizeThreshold(self):
Threshold = None
Threshold_Str = GlobalData.gCommandLineDefines.get('FV_SPARE_SPACE_THRESHOLD')
if Threshold_Str:
try:
if Threshold_Str.lower().startswith('0x'):
Threshold = int(Threshold_Str, 16)
else:
Threshold = int(Threshold_Str)
except:
EdkLogger.warn("build", 'incorrect value for FV_SPARE_SPACE_THRESHOLD %s.Only decimal or hex format is allowed.' % Threshold_Str)
return Threshold
def CheckFreeSizeThreshold(self, Threshold=None, FvDir=None):
if not isinstance(Threshold, int):
return
if not isinstance(FvDir, str) or not FvDir:
return
FdfParserObject = GlobalData.gFdfParser
FvRegionNameList = [FvName for FvName in FdfParserObject.Profile.FvDict if FdfParserObject.Profile.FvDict[FvName].FvRegionInFD]
for FvName in FdfParserObject.Profile.FvDict:
if FvName in FvRegionNameList:
FvSpaceInfoFileName = os.path.join(FvDir, FvName.upper() + '.Fv.map')
if os.path.exists(FvSpaceInfoFileName):
FileLinesList = getlines(FvSpaceInfoFileName)
for Line in FileLinesList:
NameValue = Line.split('=')
if len(NameValue) == 2 and NameValue[0].strip() == 'EFI_FV_SPACE_SIZE':
FreeSizeValue = int(NameValue[1].strip(), 0)
if FreeSizeValue < Threshold:
EdkLogger.error("build", FV_FREESIZE_ERROR,
'%s FV free space %d is not enough to meet with the required spare space %d set by -D FV_SPARE_SPACE_THRESHOLD option.' % (
FvName, FreeSizeValue, Threshold))
break
## Generate GuidedSectionTools.txt in the FV directories.
#
def CreateGuidedSectionToolsFile(self,Wa):