## @file\r
# parse FDF file\r
#\r
-# Copyright (c) 2007 - 2013, Intel Corporation. All rights reserved.<BR>\r
+# Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.<BR>\r
#\r
# This program and the accompanying materials\r
# are licensed and made available under the terms and conditions of the BSD License\r
from Common.Misc import tdict\r
\r
import re\r
-import os\r
+import Common.LongFilePathOs as os\r
+from Common.LongFilePathSupport import OpenLongFilePath as open\r
\r
##define T_CHAR_SPACE ' '\r
##define T_CHAR_NULL '\0'\r
\r
RegionSizePattern = re.compile("\s*(?P<base>(?:0x|0X)?[a-fA-F0-9]+)\s*\|\s*(?P<size>(?:0x|0X)?[a-fA-F0-9]+)\s*")\r
RegionSizeGuidPattern = re.compile("\s*(?P<base>\w+\.\w+)\s*\|\s*(?P<size>\w+\.\w+)\s*")\r
+RegionOffsetPcdPattern = re.compile("\s*(?P<base>\w+\.\w+)\s*$")\r
ShortcutPcdPattern = re.compile("\s*\w+\s*=\s*(?P<value>(?:0x|0X)?[a-fA-F0-9]+)\s*\|\s*(?P<name>\w+\.\w+)\s*")\r
\r
IncludeFileList = []\r
self.VtfList = []\r
self.RuleDict = {}\r
self.OptRomDict = {}\r
+ self.FmpPayloadDict = {}\r
\r
## The syntax parser for FDF\r
#\r
self.CurrentFvName = None\r
self.__Token = ""\r
self.__SkippedChars = ""\r
+ GlobalData.gFdfParser = self\r
\r
# Used to section info\r
self.__CurSection = []\r
self.__SetMacroValue(Macro, Value)\r
self.__WipeOffArea.append(((DefineLine, DefineOffset), (self.CurrentLineNumber - 1, self.CurrentOffsetWithinLine - 1)))\r
elif self.__Token == 'SET':\r
+ if not self.__GetIfListCurrentItemStat(IfList):\r
+ continue\r
SetLine = self.CurrentLineNumber - 1\r
SetOffset = self.CurrentOffsetWithinLine - len('SET')\r
PcdPair = self.__GetNextPcdName()\r
while self.__GetFv():\r
pass\r
\r
+ while self.__GetFmp():\r
+ pass\r
+\r
while self.__GetCapsule():\r
pass\r
\r
\r
S = self.__Token.upper()\r
if S.startswith("[") and not S.startswith("[FD."):\r
- if not S.startswith("[FV.") and not S.startswith("[CAPSULE.") \\r
+ if not S.startswith("[FV.") and not S.startswith('[FMPPAYLOAD.') and not S.startswith("[CAPSULE.") \\r
and not S.startswith("[VTF.") and not S.startswith("[RULE.") and not S.startswith("[OPTIONROM."):\r
raise Warning("Unknown section", self.FileName, self.CurrentLineNumber)\r
self.__UndoToken()\r
try:\r
return long(\r
ValueExpression(Expr,\r
- dict(['%s.%s' % (Pcd[1], Pcd[0]), Val] \r
- for Pcd, Val in self.Profile.PcdDict.iteritems())\r
+ self.__CollectMacroPcd()\r
)(True),0)\r
except Exception:\r
self.SetFileBufferPos(StartPos)\r
return True\r
\r
if not self.__Token in ("SET", "FV", "FILE", "DATA", "CAPSULE"):\r
+ #\r
+ # If next token is a word which is not a valid FV type, it might be part of [PcdOffset[|PcdSize]]\r
+ # Or it might be next region's offset described by an expression which starts with a PCD.\r
+ # PcdOffset[|PcdSize] or OffsetPcdExpression|Size\r
+ #\r
self.__UndoToken()\r
- RegionObj.PcdOffset = self.__GetNextPcdName()\r
- self.Profile.PcdDict[RegionObj.PcdOffset] = "0x%08X" % (RegionObj.Offset + long(Fd.BaseAddress, 0))\r
- FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)\r
- self.Profile.PcdFileLineDict[RegionObj.PcdOffset] = FileLineTuple\r
- if self.__IsToken( "|"):\r
- RegionObj.PcdSize = self.__GetNextPcdName()\r
- self.Profile.PcdDict[RegionObj.PcdSize] = "0x%08X" % RegionObj.Size\r
+ IsRegionPcd = (RegionSizeGuidPattern.match(self.__CurrentLine()[self.CurrentOffsetWithinLine:]) or\r
+ RegionOffsetPcdPattern.match(self.__CurrentLine()[self.CurrentOffsetWithinLine:]))\r
+ if IsRegionPcd:\r
+ RegionObj.PcdOffset = self.__GetNextPcdName()\r
+ self.Profile.PcdDict[RegionObj.PcdOffset] = "0x%08X" % (RegionObj.Offset + long(Fd.BaseAddress, 0))\r
+ self.__PcdDict['%s.%s' % (RegionObj.PcdOffset[1], RegionObj.PcdOffset[0])] = "0x%x" % RegionObj.Offset\r
FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)\r
- self.Profile.PcdFileLineDict[RegionObj.PcdSize] = FileLineTuple\r
+ self.Profile.PcdFileLineDict[RegionObj.PcdOffset] = FileLineTuple\r
+ if self.__IsToken( "|"):\r
+ RegionObj.PcdSize = self.__GetNextPcdName()\r
+ self.Profile.PcdDict[RegionObj.PcdSize] = "0x%08X" % RegionObj.Size\r
+ self.__PcdDict['%s.%s' % (RegionObj.PcdSize[1], RegionObj.PcdSize[0])] = "0x%x" % RegionObj.Size\r
+ FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)\r
+ self.Profile.PcdFileLineDict[RegionObj.PcdSize] = FileLineTuple\r
\r
if not self.__GetNextWord():\r
return True\r
self.__UndoToken()\r
self.__GetRegionDataType( RegionObj)\r
else:\r
+ self.__UndoToken()\r
+ if self.__GetRegionLayout(Fd):\r
+ return True\r
raise Warning("A valid region type was not found. "\r
"Valid types are [SET, FV, CAPSULE, FILE, DATA]. This error occurred",\r
self.FileName, self.CurrentLineNumber)\r
\r
S = self.__Token.upper()\r
if S.startswith("[") and not S.startswith("[FV."):\r
- if not S.startswith("[CAPSULE.") \\r
+ if not S.startswith('[FMPPAYLOAD.') and not S.startswith("[CAPSULE.") \\r
and not S.startswith("[VTF.") and not S.startswith("[RULE.") and not S.startswith("[OPTIONROM."):\r
raise Warning("Unknown section or section appear sequence error (The correct sequence should be [FD.], [FV.], [Capsule.], [VTF.], [Rule.], [OptionRom.])", self.FileName, self.CurrentLineNumber)\r
self.__UndoToken()\r
# @retval None\r
#\r
def __GetFvAttributes(self, FvObj):\r
-\r
+ IsWordToken = False\r
while self.__GetNextWord():\r
+ IsWordToken = True\r
name = self.__Token\r
if name not in ("ERASE_POLARITY", "MEMORY_MAPPED", \\r
"STICKY_WRITE", "LOCK_CAP", "LOCK_STATUS", "WRITE_ENABLED_CAP", \\r
\r
FvObj.FvAttributeDict[name] = self.__Token\r
\r
- return True\r
+ return IsWordToken\r
\r
## __GetFvNameGuid() method\r
#\r
ffsInf.CurrentLineNum = self.CurrentLineNumber\r
ffsInf.CurrentLineContent = self.__CurrentLine()\r
\r
+ #Replace $(SAPCE) with real space\r
+ ffsInf.InfFileName = ffsInf.InfFileName.replace('$(SPACE)', ' ')\r
+\r
if ffsInf.InfFileName.replace('$(WORKSPACE)', '').find('$') == -1:\r
#do case sensitive check for file path\r
ErrorCode, ErrorInfo = PathClass(NormPath(ffsInf.InfFileName), GenFdsGlobalVariable.WorkSpaceDir).Validate()\r
# @param FfsInfObj for whom option is got\r
#\r
def __GetInfOptions(self, FfsInfObj):\r
+ if self.__IsKeyword("FILE_GUID"):\r
+ if not self.__IsToken("="):\r
+ raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
+ if not self.__GetNextGuid():\r
+ raise Warning("expected GUID value", self.FileName, self.CurrentLineNumber)\r
+ FfsInfObj.OverrideGuid = self.__Token\r
\r
if self.__IsKeyword( "RuleOverride"):\r
if not self.__IsToken( "="):\r
\r
\r
if self.__GetNextToken():\r
- p = re.compile(r'([a-zA-Z0-9\-]+|\$\(TARGET\)|\*)_([a-zA-Z0-9\-]+|\$\(TOOL_CHAIN_TAG\)|\*)_([a-zA-Z0-9\-]+|\$\(ARCH\)|\*)')\r
- if p.match(self.__Token):\r
+ p = re.compile(r'([a-zA-Z0-9\-]+|\$\(TARGET\)|\*)_([a-zA-Z0-9\-]+|\$\(TOOL_CHAIN_TAG\)|\*)_([a-zA-Z0-9\-]+|\$\(ARCH\))')\r
+ if p.match(self.__Token) and p.match(self.__Token).span()[1] == len(self.__Token):\r
FfsInfObj.KeyStringList.append(self.__Token)\r
if not self.__IsToken(","):\r
return\r
else:\r
FfsFileObj.CurrentLineNum = self.CurrentLineNumber\r
FfsFileObj.CurrentLineContent = self.__CurrentLine()\r
- FfsFileObj.FileName = self.__Token\r
- if FfsFileObj.FileName.replace('$(WORKSPACE)', '').find('$') == -1:\r
- #\r
- # For file in OUTPUT_DIRECTORY will not check whether it exist or not at AutoGen phase.\r
- #\r
- if not GlobalData.gAutoGenPhase:\r
- #do case sensitive check for file path\r
- ErrorCode, ErrorInfo = PathClass(NormPath(FfsFileObj.FileName), GenFdsGlobalVariable.WorkSpaceDir).Validate()\r
- if ErrorCode != 0:\r
- EdkLogger.error("GenFds", ErrorCode, ExtraData=ErrorInfo)\r
- else:\r
- if not self.__GetMacroValue("OUTPUT_DIRECTORY") in FfsFileObj.FileName:\r
- #do case sensitive check for file path\r
- ErrorCode, ErrorInfo = PathClass(NormPath(FfsFileObj.FileName), GenFdsGlobalVariable.WorkSpaceDir).Validate()\r
- if ErrorCode != 0:\r
- EdkLogger.error("GenFds", ErrorCode, ExtraData=ErrorInfo) \r
-\r
+ FfsFileObj.FileName = self.__Token.replace('$(SPACE)', ' ')\r
+ self.__VerifyFile(FfsFileObj.FileName)\r
\r
if not self.__IsToken( "}"):\r
raise Warning("expected '}'", self.FileName, self.CurrentLineNumber)\r
if not self.__GetNextToken():\r
raise Warning("expected section file path", self.FileName, self.CurrentLineNumber)\r
DataSectionObj.SectFileName = self.__Token\r
- if DataSectionObj.SectFileName.replace('$(WORKSPACE)', '').find('$') == -1:\r
- #do case sensitive check for file path\r
- ErrorCode, ErrorInfo = PathClass(NormPath(DataSectionObj.SectFileName), GenFdsGlobalVariable.WorkSpaceDir).Validate()\r
- if ErrorCode != 0:\r
- EdkLogger.error("GenFds", ErrorCode, ExtraData=ErrorInfo)\r
+ self.__VerifyFile(DataSectionObj.SectFileName)\r
else:\r
if not self.__GetCglSection(DataSectionObj):\r
return False\r
\r
return True\r
\r
+ ## __VerifyFile\r
+ #\r
+ # Check if file exists or not:\r
+ # If current phase if GenFds, the file must exist;\r
+ # If current phase is AutoGen and the file is not in $(OUTPUT_DIRECTORY), the file must exist\r
+ # @param FileName: File path to be verified.\r
+ #\r
+ def __VerifyFile(self, FileName):\r
+ if FileName.replace('$(WORKSPACE)', '').find('$') != -1:\r
+ return\r
+ if not GlobalData.gAutoGenPhase or not self.__GetMacroValue("OUTPUT_DIRECTORY") in FileName:\r
+ ErrorCode, ErrorInfo = PathClass(NormPath(FileName), GenFdsGlobalVariable.WorkSpaceDir).Validate()\r
+ if ErrorCode != 0:\r
+ EdkLogger.error("GenFds", ErrorCode, ExtraData=ErrorInfo)\r
+\r
## __GetCglSection() method\r
#\r
# Get compressed or GUIDed section for Obj\r
else:\r
return True\r
\r
+ def __GetFmp(self):\r
+ if not self.__GetNextToken():\r
+ return False\r
+ S = self.__Token.upper()\r
+ if not S.startswith("[FMPPAYLOAD."):\r
+ if not S.startswith("[CAPSULE.") and not S.startswith("[VTF.") and not S.startswith("[RULE.") and not S.startswith("[OPTIONROM."):\r
+ raise Warning("Unknown section or section appear sequence error (The correct sequence should be [FD.], [FV.], [FmpPayload.], [Capsule.], [VTF.], [Rule.], [OptionRom.])", self.FileName, self.CurrentLineNumber)\r
+ self.__UndoToken()\r
+ return False\r
+\r
+ self.__UndoToken()\r
+ self.__SkipToToken("[FMPPAYLOAD.", True)\r
+ FmpUiName = self.__GetUiName().upper()\r
+ if FmpUiName in self.Profile.FmpPayloadDict:\r
+ raise Warning("Duplicated FMP UI name found: %s" % FmpUiName, self.FileName, self.CurrentLineNumber)\r
+\r
+ FmpData = CapsuleData.CapsulePayload()\r
+ FmpData.UiName = FmpUiName\r
+\r
+ if not self.__IsToken( "]"):\r
+ raise Warning("expected ']'", self.FileName, self.CurrentLineNumber)\r
+\r
+ if not self.__GetNextToken():\r
+ raise Warning("The FMP payload section is empty!", self.FileName, self.CurrentLineNumber)\r
+ FmpKeyList = ['IMAGE_HEADER_INIT_VERSION', 'IMAGE_TYPE_ID', 'IMAGE_INDEX', 'HARDWARE_INSTANCE']\r
+ while self.__Token in FmpKeyList:\r
+ Name = self.__Token\r
+ FmpKeyList.remove(Name)\r
+ if not self.__IsToken("="):\r
+ raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
+ if Name == 'IMAGE_TYPE_ID':\r
+ if not self.__GetNextGuid():\r
+ raise Warning("expected GUID value for IMAGE_TYPE_ID", self.FileName, self.CurrentLineNumber)\r
+ FmpData.ImageTypeId = self.__Token\r
+ else:\r
+ if not self.__GetNextToken():\r
+ raise Warning("expected value of %s" % Name, self.FileName, self.CurrentLineNumber)\r
+ Value = self.__Token\r
+ if Name == 'IMAGE_HEADER_INIT_VERSION':\r
+ FmpData.Version = Value\r
+ elif Name == 'IMAGE_INDEX':\r
+ FmpData.ImageIndex = Value\r
+ elif Name == 'HARDWARE_INSTANCE':\r
+ FmpData.HardwareInstance = Value\r
+ if not self.__GetNextToken():\r
+ break\r
+ else:\r
+ self.__UndoToken()\r
+\r
+ if FmpKeyList:\r
+ raise Warning("Missing keywords %s in FMP payload section" % ', '.join(FmpKeyList), self.FileName, self.CurrentLineNumber)\r
+ ImageFile = self.__ParseRawFileStatement()\r
+ if not ImageFile:\r
+ raise Warning("Missing image file in FMP payload section", self.FileName, self.CurrentLineNumber)\r
+ FmpData.ImageFile = ImageFile\r
+ VendorCodeFile = self.__ParseRawFileStatement()\r
+ if VendorCodeFile:\r
+ FmpData.VendorCodeFile = VendorCodeFile\r
+ self.Profile.FmpPayloadDict[FmpUiName] = FmpData\r
+ return True\r
+\r
## __GetCapsule() method\r
#\r
# Get capsule section contents and store its data into capsule list of self.Profile\r
def __GetCapsuleTokens(self, Obj):\r
if not self.__GetNextToken():\r
return False\r
- while self.__Token in ("CAPSULE_GUID", "CAPSULE_HEADER_SIZE", "CAPSULE_FLAGS", "OEM_CAPSULE_FLAGS"):\r
+ while self.__Token in ("CAPSULE_GUID", "CAPSULE_HEADER_SIZE", "CAPSULE_FLAGS", "OEM_CAPSULE_FLAGS", "CAPSULE_HEADER_INIT_VERSION"):\r
Name = self.__Token.strip()\r
if not self.__IsToken("="):\r
raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
Value += self.__Token.strip()\r
elif Name == 'OEM_CAPSULE_FLAGS':\r
Value = self.__Token.strip()\r
+ if not Value.upper().startswith('0X'):\r
+ raise Warning("expected hex value between 0x0000 and 0xFFFF", self.FileName, self.CurrentLineNumber)\r
try:\r
Value = int(Value, 0)\r
except ValueError:\r
- raise Warning("expected integer value between 0x0000 and 0xFFFF", self.FileName, self.CurrentLineNumber)\r
+ raise Warning("expected hex value between 0x0000 and 0xFFFF", self.FileName, self.CurrentLineNumber)\r
if not 0x0000 <= Value <= 0xFFFF:\r
- raise Warning("expected integer value between 0x0000 and 0xFFFF", self.FileName, self.CurrentLineNumber)\r
+ raise Warning("expected hex value between 0x0000 and 0xFFFF", self.FileName, self.CurrentLineNumber)\r
Value = self.__Token.strip()\r
else:\r
Value = self.__Token.strip()\r
IsFv = self.__GetFvStatement(Obj)\r
IsFd = self.__GetFdStatement(Obj)\r
IsAnyFile = self.__GetAnyFileStatement(Obj)\r
- if not (IsInf or IsFile or IsFv or IsFd or IsAnyFile):\r
+ IsAfile = self.__GetAfileStatement(Obj)\r
+ IsFmp = self.__GetFmpStatement(Obj)\r
+ if not (IsInf or IsFile or IsFv or IsFd or IsAnyFile or IsAfile or IsFmp):\r
break\r
\r
## __GetFvStatement() method\r
CapsuleObj.CapsuleDataList.append(CapsuleFd)\r
return True\r
\r
- ## __GetAnyFileStatement() method\r
- #\r
- # Get AnyFile for capsule\r
- #\r
- # @param self The object pointer\r
- # @param CapsuleObj for whom AnyFile is got\r
- # @retval True Successfully find a Anyfile statement\r
- # @retval False Not able to find a AnyFile statement\r
- #\r
- def __GetAnyFileStatement(self, CapsuleObj):\r
+ def __GetFmpStatement(self, CapsuleObj):\r
+ if not self.__IsKeyword("FMP"):\r
+ return False\r
\r
- if not self.__IsKeyword("FILE"):\r
+ if not self.__IsKeyword("PAYLOAD"):\r
+ self.__UndoToken()\r
return False\r
\r
+ if not self.__IsToken("="):\r
+ raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
+\r
+ if not self.__GetNextToken():\r
+ raise Warning("expected payload name after FMP PAYLOAD =", self.FileName, self.CurrentLineNumber)\r
+ Payload = self.__Token.upper()\r
+ if Payload not in self.Profile.FmpPayloadDict:\r
+ raise Warning("This FMP Payload does not exist: %s" % self.__Token, self.FileName, self.CurrentLineNumber)\r
+ CapsuleObj.FmpPayloadList.append(self.Profile.FmpPayloadDict[Payload])\r
+ return True\r
+\r
+ def __ParseRawFileStatement(self):\r
+ if not self.__IsKeyword("FILE"):\r
+ return None\r
+\r
if not self.__IsKeyword("DATA"):\r
self.__UndoToken()\r
- return False\r
+ return None\r
\r
if not self.__IsToken("="):\r
raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
AnyFileName = GenFdsGlobalVariable.ReplaceWorkspaceMacro(AnyFileName)\r
if not os.path.exists(AnyFileName):\r
raise Warning("File %s not exists"%AnyFileName, self.FileName, self.CurrentLineNumber)\r
+ return AnyFileName\r
+\r
+ ## __GetAnyFileStatement() method\r
+ #\r
+ # Get AnyFile for capsule\r
+ #\r
+ # @param self The object pointer\r
+ # @param CapsuleObj for whom AnyFile is got\r
+ # @retval True Successfully find a Anyfile statement\r
+ # @retval False Not able to find a AnyFile statement\r
+ #\r
+ def __GetAnyFileStatement(self, CapsuleObj):\r
+ AnyFileName = self.__ParseRawFileStatement()\r
+ if not AnyFileName:\r
+ return False\r
\r
CapsuleAnyFile = CapsuleData.CapsuleAnyFile()\r
CapsuleAnyFile.FileName = AnyFileName\r
CapsuleObj.CapsuleDataList.append(CapsuleAnyFile)\r
return True\r
+ \r
+ ## __GetAfileStatement() method\r
+ #\r
+ # Get Afile for capsule\r
+ #\r
+ # @param self The object pointer\r
+ # @param CapsuleObj for whom Afile is got\r
+ # @retval True Successfully find a Afile statement\r
+ # @retval False Not able to find a Afile statement\r
+ #\r
+ def __GetAfileStatement(self, CapsuleObj):\r
+\r
+ if not self.__IsKeyword("APPEND"):\r
+ return False\r
+\r
+ if not self.__IsToken("="):\r
+ raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
+\r
+ if not self.__GetNextToken():\r
+ raise Warning("expected Afile name", self.FileName, self.CurrentLineNumber)\r
+ \r
+ AfileName = self.__Token\r
+ AfileBaseName = os.path.basename(AfileName)\r
+ \r
+ if os.path.splitext(AfileBaseName)[1] not in [".bin",".BIN",".Bin",".dat",".DAT",".Dat",".data",".DATA",".Data"]:\r
+ raise Warning('invalid binary file type, should be one of "bin","BIN","Bin","dat","DAT","Dat","data","DATA","Data"', \\r
+ self.FileName, self.CurrentLineNumber)\r
+ \r
+ if not os.path.isabs(AfileName):\r
+ AfileName = GenFdsGlobalVariable.ReplaceWorkspaceMacro(AfileName)\r
+ self.__VerifyFile(AfileName)\r
+ else:\r
+ if not os.path.exists(AfileName):\r
+ raise Warning('%s does not exist' % AfileName, self.FileName, self.CurrentLineNumber)\r
+ else:\r
+ pass\r
+\r
+ CapsuleAfile = CapsuleData.CapsuleAfile()\r
+ CapsuleAfile.FileName = AfileName\r
+ CapsuleObj.CapsuleDataList.append(CapsuleAfile)\r
+ return True\r
\r
## __GetRule() method\r
#\r