import StringIO\r
import StringTable as st\r
import array\r
+import re\r
\r
from struct import *\r
import Common.EdkLogger as EdkLogger\r
8: 'Q'\r
}\r
\r
+## The VPD PCD data structure for store and process each VPD PCD entry.\r
+#\r
+# This class contain method to format and pack pcd's value. \r
+#\r
class PcdEntry:\r
- def __init__(self, PcdCName, PcdOffset, PcdSize, PcdValue, Lineno=None, FileName=None, PcdUnpackValue=None, \r
+ def __init__(self, PcdCName, SkuId,PcdOffset, PcdSize, PcdValue, Lineno=None, FileName=None, PcdUnpackValue=None, \r
PcdBinOffset=None, PcdBinSize=None):\r
self.PcdCName = PcdCName.strip()\r
+ self.SkuId = SkuId.strip()\r
self.PcdOffset = PcdOffset.strip()\r
self.PcdSize = PcdSize.strip()\r
self.PcdValue = PcdValue.strip()\r
"Invalid PCD format(Name: %s File: %s Line: %s), no PcdSize specified!" %(self.PcdCName, self.FileName, self.Lineno)) \r
\r
self._GenOffsetValue ()\r
+ \r
+ ## Analyze the string value to judge the PCD's datum type euqal to Boolean or not.\r
+ # \r
+ # @param ValueString PCD's value\r
+ # @param Size PCD's size\r
+ # \r
+ # @retval True PCD's datum type is Boolean\r
+ # @retval False PCD's datum type is not Boolean. \r
+ # \r
+ def _IsBoolean(self, ValueString, Size):\r
+ if (Size == "1"):\r
+ if ValueString.upper() in ["TRUE", "FALSE"]:\r
+ return True\r
+ elif ValueString in ["0", "1", "0x0", "0x1", "0x00", "0x01"]:\r
+ return True \r
\r
- def _IsBoolean(self, ValueString):\r
- if ValueString.upper() in ["TRUE", "FALSE"]:\r
- return True\r
return False\r
\r
+ ## Convert the PCD's value from string to integer.\r
+ # \r
+ # This function will try to convert the Offset value form string to integer\r
+ # for both hexadecimal and decimal.\r
+ # \r
def _GenOffsetValue(self):\r
if self.PcdOffset != "*" :\r
try:\r
except:\r
EdkLogger.error("BPDG", BuildToolError.FORMAT_INVALID, \r
"Invalid offset value %s for PCD %s (File: %s Line: %s)" % (self.PcdOffset, self.PcdCName, self.FileName, self.Lineno)) \r
- \r
+ \r
+ ## Pack Boolean type VPD PCD's value form string to binary type.\r
+ # \r
+ # @param ValueString The boolean type string for pack.\r
+ # \r
+ # \r
def _PackBooleanValue(self, ValueString):\r
- if ValueString.upper() == "TRUE":\r
+ if ValueString.upper() == "TRUE" or ValueString in ["1", "0x1", "0x01"]:\r
try: \r
self.PcdValue = pack(_FORMAT_CHAR[1], 1)\r
except:\r
self.PcdValue = pack(_FORMAT_CHAR[1], 0)\r
except:\r
EdkLogger.error("BPDG", BuildToolError.FORMAT_INVALID, \r
- "Invalid size or value for PCD %s to pack(File: %s Line: %s)." % (self.PcdCName, self.FileName, self.Lineno)) \r
- \r
+ "Invalid size or value for PCD %s to pack(File: %s Line: %s)." % (self.PcdCName, self.FileName, self.Lineno)) \r
+ \r
+ ## Pack Integer type VPD PCD's value form string to binary type.\r
+ # \r
+ # @param ValueString The Integer type string for pack.\r
+ # \r
+ # \r
def _PackIntValue(self, IntValue, Size):\r
if Size not in _FORMAT_CHAR.keys():\r
EdkLogger.error("BPDG", BuildToolError.FORMAT_INVALID, \r
"Invalid size %d for PCD %s in integer datum size(File: %s Line: %s)." % (Size, self.PcdCName, self.FileName, self.Lineno)) \r
+ \r
+ if Size == 1: \r
+ if IntValue < 0:\r
+ EdkLogger.error("BPDG", BuildToolError.FORMAT_INVALID, \r
+ "PCD can't be set to negative value %d for PCD %s in UINT8 datum type(File: %s Line: %s)." % (IntValue, self.PcdCName, self.FileName, self.Lineno))\r
+ elif IntValue >= 0x100:\r
+ EdkLogger.error("BPDG", BuildToolError.FORMAT_INVALID, \r
+ "Too large PCD value %d for datum type UINT8 for PCD %s(File: %s Line: %s)." % (IntValue, self.PcdCName, self.FileName, self.Lineno)) \r
+ elif Size == 2:\r
+ if IntValue < 0:\r
+ EdkLogger.error("BPDG", BuildToolError.FORMAT_INVALID, \r
+ "PCD can't be set to negative value %d for PCD %s in UINT16 datum type(File: %s Line: %s)." % (IntValue, self.PcdCName, self.FileName, self.Lineno))\r
+ elif IntValue >= 0x10000:\r
+ EdkLogger.error("BPDG", BuildToolError.FORMAT_INVALID, \r
+ "Too large PCD value %d for datum type UINT16 for PCD %s(File: %s Line: %s)." % (IntValue, self.PcdCName, self.FileName, self.Lineno)) \r
+ elif Size == 4:\r
+ if IntValue < 0:\r
+ EdkLogger.error("BPDG", BuildToolError.FORMAT_INVALID, \r
+ "PCD can't be set to negative value %d for PCD %s in UINT32 datum type(File: %s Line: %s)." % (IntValue, self.PcdCName, self.FileName, self.Lineno))\r
+ elif IntValue >= 0x100000000:\r
+ EdkLogger.error("BPDG", BuildToolError.FORMAT_INVALID, \r
+ "Too large PCD value %d for datum type UINT32 for PCD %s(File: %s Line: %s)." % (IntValue, self.PcdCName, self.FileName, self.Lineno))\r
+ elif Size == 8:\r
+ if IntValue < 0:\r
+ EdkLogger.error("BPDG", BuildToolError.FORMAT_INVALID, \r
+ "PCD can't be set to negative value %d for PCD %s in UINT32 datum type(File: %s Line: %s)." % (IntValue, self.PcdCName, self.FileName, self.Lineno))\r
+ elif IntValue >= 0x10000000000000000:\r
+ EdkLogger.error("BPDG", BuildToolError.FORMAT_INVALID, \r
+ "Too large PCD value %d for datum type UINT32 for PCD %s(File: %s Line: %s)." % (IntValue, self.PcdCName, self.FileName, self.Lineno))\r
+ else:\r
+ EdkLogger.error("BPDG", BuildToolError.FORMAT_INVALID, \r
+ "Invalid size %d for PCD %s in integer datum size(File: %s Line: %s)." % (Size, self.PcdCName, self.FileName, self.Lineno)) \r
+ \r
try:\r
self.PcdValue = pack(_FORMAT_CHAR[Size], IntValue)\r
except:\r
EdkLogger.error("BPDG", BuildToolError.FORMAT_INVALID, \r
"Invalid size or value for PCD %s to pack(File: %s Line: %s)." % (self.PcdCName, self.FileName, self.Lineno)) \r
- \r
+\r
+ ## Pack VOID* type VPD PCD's value form string to binary type.\r
+ #\r
+ # The VOID* type of string divided into 3 sub-type:\r
+ # 1: L"String", Unicode type string.\r
+ # 2: "String", Ascii type string.\r
+ # 3: {bytearray}, only support byte-array.\r
+ #\r
+ # @param ValueString The Integer type string for pack.\r
+ # \r
def _PackPtrValue(self, ValueString, Size):\r
if ValueString.startswith('L"'):\r
self._PackUnicode(ValueString, Size)\r
else:\r
EdkLogger.error("BPDG", BuildToolError.FORMAT_INVALID, \r
"Invalid VOID* type PCD %s value %s (File: %s Line: %s)" % (self.PcdCName, ValueString, self.FileName, self.Lineno)) \r
- \r
+ \r
+ ## Pack an Ascii PCD value.\r
+ # \r
+ # An Ascii string for a PCD should be in format as "".\r
+ # \r
def _PackString(self, ValueString, Size):\r
if (Size < 0):\r
EdkLogger.error("BPDG", BuildToolError.FORMAT_INVALID, \r
self.PcdValue= pack('%ds' % Size, ValueString)\r
except:\r
EdkLogger.error("BPDG", BuildToolError.FORMAT_INVALID, \r
- "Invalid size or value for PCD %s to pack(File: %s Line: %s)." % (self.PcdCName, self.FileName, self.Lineno)) \r
- \r
+ "Invalid size or value for PCD %s to pack(File: %s Line: %s)." % (self.PcdCName, self.FileName, self.Lineno)) \r
+ \r
+ ## Pack a byte-array PCD value.\r
+ # \r
+ # A byte-array for a PCD should be in format as {0x01, 0x02, ...}.\r
+ # \r
def _PackByteArray(self, ValueString, Size):\r
if (Size < 0): \r
EdkLogger.error("BPDG", BuildToolError.FORMAT_INVALID, "Invalid parameter Size %s of PCD %s!(File: %s Line: %s)" % (self.PcdBinSize, self.PcdCName, self.FileName, self.Lineno))\r
\r
for Index in xrange(len(ValueList)):\r
Value = None\r
- if ValueList[Index].startswith('0x'):\r
+ if ValueList[Index].lower().startswith('0x'):\r
# translate hex value\r
try:\r
Value = int(ValueList[Index], 16)\r
"Invalid unicode character %s in unicode string %s(File: %s Line: %s)" % \\r
(Value, UnicodeString, self.FileName, self.Lineno))\r
\r
- for Index in range(len(UnicodeString) * 2, Size):\r
+ for Index in xrange(len(UnicodeString) * 2, Size):\r
ReturnArray.append(0)\r
\r
self.PcdValue = ReturnArray.tolist() \r
- \r
-class GenVPD :\r
- \r
+\r
+\r
+\r
+## The class implementing the BPDG VPD PCD offset fix process\r
+#\r
+# The VPD PCD offset fix process includes:\r
+# 1. Parse the input guided.txt file and store it in the data structure;\r
+# 2. Format the input file data to remove unused lines;\r
+# 3. Fixed offset if needed;\r
+# 4. Generate output file, including guided.map and guided.bin file;\r
+# \r
+class GenVPD : \r
## Constructor of DscBuildData\r
#\r
# Initialize object of GenVPD\r
line = line.rstrip(os.linesep)\r
\r
# Skip the comment line\r
- if (not line.startswith("#")) and len(line) > 1 : \r
- self.FileLinesList[count] = line.split('|')\r
+ if (not line.startswith("#")) and len(line) > 1 :\r
+ #\r
+ # Enhanced for support "|" character in the string.\r
+ #\r
+ ValueList = ['', '', '', '',''] \r
+ \r
+ ValueRe = re.compile(r'\s*L?\".*\|.*\"\s*$')\r
+ PtrValue = ValueRe.findall(line)\r
+ \r
+ ValueUpdateFlag = False\r
+ \r
+ if len(PtrValue) >= 1:\r
+ line = re.sub(ValueRe, '', line)\r
+ ValueUpdateFlag = True \r
+ \r
+ TokenList = line.split('|')\r
+ ValueList[0:len(TokenList)] = TokenList\r
+ \r
+ if ValueUpdateFlag:\r
+ ValueList[4] = PtrValue[0] \r
+ self.FileLinesList[count] = ValueList\r
# Store the line number\r
self.FileLinesList[count].append(str(count+1))\r
elif len(line) <= 1 :\r
count = 0\r
for line in self.FileLinesList: \r
if line != None :\r
- PCD = PcdEntry(line[0], line[1], line[2], line[3], line[4], self.InputFileName) \r
+ PCD = PcdEntry(line[0], line[1], line[2], line[3], line[4],line[5], self.InputFileName) \r
# Strip the space char\r
PCD.PcdCName = PCD.PcdCName.strip(' ')\r
+ PCD.SkuId = PCD.SkuId.strip(' ')\r
PCD.PcdOffset = PCD.PcdOffset.strip(' ')\r
PCD.PcdSize = PCD.PcdSize.strip(' ')\r
PCD.PcdValue = PCD.PcdValue.strip(' ') \r
except:\r
EdkLogger.error("BPDG", BuildToolError.FORMAT_INVALID, "Invalid PCD size value %s at file: %s line: %s" % (PCD.PcdSize, self.InputFileName, PCD.Lineno))\r
\r
- if PCD._IsBoolean(PCD.PcdValue):\r
+ if PCD._IsBoolean(PCD.PcdValue, PCD.PcdSize):\r
PCD._PackBooleanValue(PCD.PcdValue)\r
self.FileLinesList[count] = PCD\r
count += 1\r
if lenOfUnfixedList != 0 :\r
countOfUnfixedList = 0\r
while(countOfUnfixedList < lenOfUnfixedList) : \r
- #needFixPcdCName, needFixPcdOffset, needFixPcdSize, needFixPcdValue, needFixUnpackValue = self.PcdUnknownOffsetList[countOfUnfixedList][0:6]\r
eachUnfixedPcd = self.PcdUnknownOffsetList[countOfUnfixedList]\r
needFixPcdSize = eachUnfixedPcd.PcdBinSize\r
- needFixPcdOffset = eachUnfixedPcd.PcdOffset\r
# Not been fixed\r
if eachUnfixedPcd.PcdOffset == '*' :\r
# The offset un-fixed pcd can write into this free space\r
FixOffsetSizeListCount += 1\r
\r
# Decrease the un-fixed pcd offset list's length\r
- countOfUnfixedList += 1\r
lenOfUnfixedList -= 1\r
\r
# Modify the last offset value \r
- LastOffset += needFixPcdSize\r
- continue \r
+ LastOffset += needFixPcdSize \r
else :\r
- # It can not insert into those two pcds, need to check stiil has other space can store it.\r
+ # It can not insert into those two pcds, need to check still has other space can store it.\r
+ LastOffset = NowOffset + self.PcdFixedOffsetSizeList[FixOffsetSizeListCount].PcdBinSize\r
FixOffsetSizeListCount += 1\r
- break \r
- else :\r
- continue\r
+ break\r
+ \r
# Set the FixOffsetSizeListCount = lenOfList for quit the loop\r
else :\r
FixOffsetSizeListCount = lenOfList \r
for eachPcd in self.PcdFixedOffsetSizeList :\r
# write map file\r
try :\r
- fMapFile.write("%s | %s | %s | %s \n" % (eachPcd.PcdCName, eachPcd.PcdOffset, eachPcd.PcdSize,eachPcd.PcdUnpackValue))\r
+ fMapFile.write("%s | %s | %s | %s | %s \n" % (eachPcd.PcdCName, eachPcd.SkuId,eachPcd.PcdOffset, eachPcd.PcdSize,eachPcd.PcdUnpackValue))\r
except:\r
EdkLogger.error("BPDG", BuildToolError.FILE_WRITE_FAILURE, "Write data to file %s failed, please check whether the file been locked or using by other applications." %self.MapFileName,None) \r
\r