Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Liming Gao <liming.gao@intel.com>
---
TestPkg/Include/Guid/Test.h | 31 ++
TestPkg/StructuredPcdValueGenerator.py | 702 +++++++++++++++++++++++++++++++++
TestPkg/TestPkg.dec | 44 +++
TestPkg/TestPkg.dsc | 69 ++++
4 files changed, 846 insertions(+)
create mode 100644 TestPkg/Include/Guid/Test.h
create mode 100644 TestPkg/StructuredPcdValueGenerator.py
create mode 100644 TestPkg/TestPkg.dec
create mode 100644 TestPkg/TestPkg.dsc
diff --git a/TestPkg/Include/Guid/Test.h b/TestPkg/Include/Guid/Test.h
new file mode 100644
index 0000000..e988954
--- /dev/null
+++ b/TestPkg/Include/Guid/Test.h
@@ -0,0 +1,31 @@
+//#pragma pack(1)
+
+#define MacroTest2 10
+
+typedef struct {
+ BOOLEAN Bool;
+ UINT8 A:4;
+ UINT8 B:4;
+ UINT32 Unaligned32;
+ UINT16 C;
+ UINT16 D;
+ UINT32 E;
+ UINT32 F;
+ UINT64 G;
+ UINT64 H;
+ UINT8 Reserved;
+ UINT8 Hidden;
+ UINT8 OneLine8;
+ UINT16 OneLine16;
+ UINT32 OneLine32;
+ UINT64 OneLine64;
+ BOOLEAN OneLineBoolA;
+ BOOLEAN OneLineBoolB;
+ BOOLEAN OneLineBoolC;
+ BOOLEAN OneLineBoolD;
+ UINT32 Array[10];
+ UINT8 Array2[2];
+ UINT8 FlexibleArray[0];
+} TEST;
+
+//#pragma pack()
diff --git a/TestPkg/StructuredPcdValueGenerator.py b/TestPkg/StructuredPcdValueGenerator.py
new file mode 100644
index 0000000..a24ccf3
--- /dev/null
+++ b/TestPkg/StructuredPcdValueGenerator.py
@@ -0,0 +1,702 @@
+#
+# Generate C program to convert structure PCD value to byte array.
+#
+
+import os
+import sys
+import argparse
+import subprocess
+from collections import OrderedDict
+import uuid
+
+#
+# Globals for help information
+#
+__prog__ = 'StructuredPcdValueGenerator'
+__version__ = '%s Version %s' % (__prog__, '0.1 ')
+__copyright__ = 'Copyright (c) 2017, Intel Corporation. All rights reserved.'
+__usage__ = '%s [options]' % (__prog__)
+
+#
+# Treat CHAR16 as a synonym for UINT16. CHAR16 support is required for VFR C structs
+#
+PcdValueInitName = 'PcdValueInit'
+PcdSupportedBaseTypes = ['BOOLEAN', 'UINT8', 'UINT16', 'UINT32', 'UINT64', 'CHAR16']
+PcdSupportedBaseTypeWidth = {'BOOLEAN':8, 'UINT8':8, 'UINT16':16, 'UINT32':32, 'UINT64':64}
+PcdUnsupportedBaseTypes = ['INT8', 'INT16', 'INT32', 'INT64', 'CHAR8', 'UINTN', 'INTN', 'VOID']
+
+PcdMainCHeader = '''
+/**
+ DO NOT EDIT
+ FILE auto-generated
+**/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <PcdValueCommon.h>
+'''
+
+PcdMainCEntry = '''
+int
+main (
+ int argc,
+ char *argv[]
+ )
+{
+ return PcdValueMain (argc, argv);
+}
+'''
+
+PcdMakefileHeader = '''
+#
+# DO NOT EDIT
+# This file is auto-generated by build utility
+#
+
+'''
+
+PcdMakefileEnd = '''
+!INCLUDE $(BASE_TOOLS_PATH)\Source\C\Makefiles\ms.common
+
+CFLAGS = $(CFLAGS) /wd4200 /wd4034
+
+LIBS = $(LIB_PATH)\Common.lib
+
+!INCLUDE $(BASE_TOOLS_PATH)\Source\C\Makefiles\ms.app
+'''
+
+PcdGccMakefile = '''
+ARCH ?= IA32
+MAKEROOT ?= $(EDK_TOOLS_PATH)/Source/C
+LIBS = -lCommon
+'''
+
+def GetBitField(Value, Start, Width):
+ Mask = (1 << Width) - 1
+ return (Value >> Start) & Mask
+
+def SetBitField(Value, Start, Width, BitFieldValue):
+ Mask = (1 << Width) - 1
+ if BitFieldValue & (~Mask) <> 0:
+ raise ValueError
+ BitFieldValue = BitFieldValue & Mask
+ Value = (Value & (~(Mask << Start))) | (BitFieldValue << Start)
+ return Value
+
+def IntToArray(Value, Size, Stride = 1, ValuesPerLine = 16, AsciiComment = False):
+ if Stride not in [1,2,4,8]:
+ return ''
+ PostFix = ''
+ if Stride == 8:
+ PostFix = 'ULL'
+ Value = Value & ((1 << Size * 8) - 1)
+ Output = '{\n'
+ Shift = Stride * 8
+ Mask = (1 << Shift) - 1
+ NumValues = 0
+ Ascii = ''
+ for Index in range (0, Size, Stride):
+ Output = Output + '0x%0*X%s' % (Stride * 2, Value & Mask, PostFix)
+ if Index + Stride < Size:
+ Output = Output + ', '
+ else:
+ Output = Output + ' '
+ for CharIndex in range (0, Stride):
+ Char = Value & 0xff
+ if Char in range(0x20, 0x7F):
+ Ascii = Ascii + chr(Value & 0xff)
+ else:
+ Ascii = Ascii + '.'
+ Value = Value >> 8
+ if (NumValues % ValuesPerLine) == (ValuesPerLine - 1):
+ if AsciiComment:
+ Output = Output + ' // %s' % (Ascii)
+ Output = Output + '\n'
+ Ascii = ''
+ NumValues = NumValues + 1
+ if AsciiComment and (NumValues % ValuesPerLine) <> 0:
+ for Index in range((NumValues % ValuesPerLine), ValuesPerLine):
+ Output = Output + ' %*s%*s ' % (Stride * 2, '', len(PostFix), '')
+ Output = Output + ' // %s\n' % (Ascii)
+ Output = Output + '}'
+ return Output
+
+def IntToCString(Value, ValueSize):
+ Result = '"'
+ if not isinstance (Value, str):
+ for Index in range(0, ValueSize):
+ Result = Result + '\\x%02x' % (Value & 0xff)
+ Value = Value >> 8
+ Result = Result + '"'
+ return Result
+
+def ParseFieldValue (Value):
+ if type(Value) == type(0):
+ return Value, (Value.bit_length() + 7) / 8
+ if type(Value) <> type(''):
+ raise ValueError
+ Value = Value.strip()
+ if Value.startswith('UINT8') and Value.endswith(')'):
+ Value, Size = ParseFieldValue(Value.split('(',1)[1][:-1])
+ if Size > 1:
+ raise ValueError
+ return Value, 1
+ if Value.startswith('UINT16') and Value.endswith(')'):
+ Value, Size = ParseFieldValue(Value.split('(',1)[1][:-1])
+ if Size > 2:
+ raise ValueError
+ return Value, 2
+ if Value.startswith('UINT32') and Value.endswith(')'):
+ Value, Size = ParseFieldValue(Value.split('(',1)[1][:-1])
+ if Size > 4:
+ raise ValueError
+ return Value, 4
+ if Value.startswith('UINT64') and Value.endswith(')'):
+ Value, Size = ParseFieldValue(Value.split('(',1)[1][:-1])
+ if Size > 8:
+ raise ValueError
+ return Value, 8
+ if Value.startswith('GUID') and Value.endswith(')'):
+ Value = Value.split('(',1)[1][:-1].strip()
+ if Value[0] == '{' and Value[-1] == '}':
+ Value = Value[1:-1].strip()
+ Value = Value.split('{',1)
+ Value = [Item.strip()[2:] for Item in (Value[0] + Value[1][:-1]).split(',')]
+ Value = '-'.join(Value[0:3]) + '-' + ''.join(Value[3:5]) + '-' + ''.join(Value[5:11])
+ if Value[0] == '"' and Value[-1] == '"':
+ Value = Value[1:-1]
+ Value = "'" + uuid.UUID(Value).get_bytes_le() + "'"
+ Value, Size = ParseFieldValue(Value)
+ return Value, 16
+ if Value.startswith('L"') and Value.endswith('"'):
+ # Unicode String
+ List = list(Value[2:-1])
+ List.reverse()
+ Value = 0
+ for Char in List:
+ Value = (Value << 16) | ord(Char)
+ return Value, (len(List) + 1) * 2
+ if Value.startswith('"') and Value.endswith('"'):
+ # ASCII String
+ List = list(Value[1:-1])
+ List.reverse()
+ Value = 0
+ for Char in List:
+ Value = (Value << 8) | ord(Char)
+ return Value, len(List) + 1
+ if Value.startswith("L'") and Value.endswith("'"):
+ # Unicode Character Constant
+ List = list(Value[2:-1])
+ List.reverse()
+ Value = 0
+ for Char in List:
+ Value = (Value << 16) | ord(Char)
+ return Value, len(List) * 2
+ if Value.startswith("'") and Value.endswith("'"):
+ # Character constant
+ List = list(Value[1:-1])
+ List.reverse()
+ Value = 0
+ for Char in List:
+ Value = (Value << 8) | ord(Char)
+ return Value, len(List)
+ if Value.startswith('{') and Value.endswith('}'):
+ # Byte array
+ Value = Value[1:-1]
+ List = [Item.strip() for Item in Value.split(',')]
+ List.reverse()
+ Value = 0
+ for Item in List:
+ ItemValue, Size = ParseFieldValue(Item)
+ if Size > 1:
+ raise ValueError
+ Value = (Value << 8) | ItemValue
+ return Value, len(List)
+ if Value.lower().startswith('0x'):
+ Value = int(Value, 16)
+ return Value, (Value.bit_length() + 7) / 8
+ if Value[0].isdigit():
+ Value = int(Value, 10)
+ return Value, (Value.bit_length() + 7) / 8
+ if Value.lower() == 'true':
+ return 1, 1
+ if Value.lower() == 'false':
+ return 0, 1
+ return Value, 1
+
+def IsFieldValueAnArray (Value):
+ Value = Value.strip()
+ if Value.startswith('GUID') and Value.endswith(')'):
+ return True
+ if Value.startswith('L"') and Value.endswith('"'):
+ return True
+ if Value[0] == '"' and Value[-1] == '"':
+ return True
+ if Value[0] == '{' and Value[-1] == '}':
+ return True
+ if Value.startswith("L'") and Value.endswith("'") and len(list(Value[2:-1])) > 1:
+ print 'foo = ', list(Value[2:-1])
+ return True
+ if Value[0] == "'" and Value[-1] == "'" and len(list(Value[1:-1])) > 1:
+ print 'bar = ', list(Value[1:-1])
+ return True
+ return False
+
+def ConvertValueToString (Value):
+ Result = ''
+ if Value.startswith('L"') and Value.endswith('"'):
+ for Char in Value[2:-1]:
+ Result = Result + '\\x%02x\\x00' % (ord(Char))
+ Result = Result + '\\x00\\x00'
+ if Value[0] == '"' and Value[-1] == '"':
+ for Char in Value[1:-1]:
+ Result = Result + '\\x%02x' % (ord(Char))
+ Result = Result + '\\x00'
+ if Value[0] == '{' and Value[-1] == '}':
+ Value = [int(Item.strip(),16) for Item in Value[1:-1].split(',')]
+ for Item in Value:
+ Result = Result + '\\x%02x' % (Item)
+ return Result
+
+def ExecuteCommand (Command):
+ try:
+ Process = subprocess.Popen(Command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
+ except:
+ print 'ERROR: Can not execute command:', Command
+ sys.exit(1)
+ Result = Process.communicate()
+ if Process.returncode <> 0:
+ print 'ERROR: Can not collect output from command:', Command
+ return Result[0], Result[1]
+
+class StructuredPcdField:
+ def __init__(self, FieldName, DefaultValue):
+ self.FieldName = FieldName
+ self.DefaultValue = DefaultValue
+
+ def __repr__(self):
+ return self.FieldName
+
+class StructuredPcd:
+ def __init__(self, StructuredPcdIncludeFile, Packages, TokenSpaceGuidName, TokenName, TypeName):
+ self.StructuredPcdIncludeFile = StructuredPcdIncludeFile
+ self.PackageDecs = Packages
+ self.SkuName = 'DEFAULT'
+ self.DefaultStoreName = 'DEFAULT'
+ self.TokenSpaceGuidName = TokenSpaceGuidName
+ self.TokenName = TokenName
+ self.TypeName = TypeName
+ self.DefaultValues = OrderedDict({})
+ self.PcdMode = None
+ self.OverrideValues = OrderedDict({})
+ self.FlexibleFieldName = None
+
+ def __repr__(self):
+ return self.TypeName
+
+ def AddDefaultValue (self, FieldName, Value, FileName="", LineNo=0):
+ self.DefaultValues[FieldName] = [Value.strip(), FileName, LineNo]
+ return self.DefaultValues[FieldName]
+
+ def AddOverrideValue (self, FieldName, Value, FileName="", LineNo=0):
+ self.OverrideValues[FieldName] = [Value.strip(), FileName, LineNo]
+ return self.OverrideValues[FieldName]
+
+ def SetPcdMode (self, PcdMode):
+ self.PcdMode = PcdMode
+
+ def SetFlexibleFieldName (self, FlexibleFieldName):
+ self.FlexibleFieldName = FlexibleFieldName
+
+class Build:
+ def __init__(self, args):
+ self.args = args
+ self.DecFile = args.DecFile
+ self.DscFile = args.DscFile
+ self.Quiet = args.Quiet
+ self.StructuredPcds = []
+ self.PackagePath = os.path.dirname(self.DecFile)
+ if os.getenv("WORKSPACE"):
+ self.OutputPath = os.path.join(os.getenv("WORKSPACE"), 'Build', PcdValueInitName)
+ else:
+ self.OutputPath = os.path.dirname(self.DscFile)
+
+ def __repr__(self):
+ return self.DscFile
+
+ def AddStructuredPcd (self, Include, Packages, TokenSpaceGuidName, TokenName, Type):
+ Pcd = StructuredPcd(Include, Packages, TokenSpaceGuidName, TokenName, Type)
+ self.StructuredPcds.append(Pcd)
+ return Pcd
+
+ def LookupPcd(self, TokenSpaceGuidName, TokenName):
+ for Pcd in self.StructuredPcds:
+ if Pcd.TokenSpaceGuidName == TokenSpaceGuidName and Pcd.TokenName == TokenName:
+ return Pcd
+ return None
+
+ def LookupPcdByTypeName(self, TypeName):
+ for Pcd in self.StructuredPcds:
+ if Pcd.TypeName == TypeName:
+ return Pcd
+ return None
+
+ def ParseDecFile (self):
+ print 'Parse DEC File', self.DecFile
+ File = open (self.DecFile, mode='r')
+ DecFileBuffer = File.readlines()
+ File.close()
+ DecLineNumber = 0
+ Include = None
+ PcdObject = None
+ while (DecLineNumber < len (DecFileBuffer)):
+ Line = DecFileBuffer[DecLineNumber]
+ DecLineNumber = DecLineNumber + 1
+ Line = Line.strip()
+ if Line.startswith('#'):
+ continue
+ if len(Line.split('|')) == 4:
+ Line = Line [:(len(Line)-1)]
+ Line = [Item.strip() for Item in Line.strip().split('|')]
+ Pcd = [Item.strip() for Item in Line[0].split('.',2)]
+ if len(Pcd) < 2:
+ print 'Error: PCD field sytnax error', DecLineNumber, Line
+ sys.exit()
+ elif len(Pcd) == 2:
+ TokenSpaceGuidName = Pcd[0]
+ TokenName = Pcd[1]
+ Type = Line[2]
+ Packages = []
+ NextLine = DecFileBuffer[DecLineNumber].strip()
+ DecLineNumber = DecLineNumber + 1
+ while (NextLine[0] != "}"):
+ if NextLine == "<HeaderFiles>":
+ Include = DecFileBuffer[DecLineNumber].strip()
+ DecLineNumber = DecLineNumber + 1
+ NextLine = DecFileBuffer[DecLineNumber].strip()
+ if NextLine == "<Packages>":
+ DecLineNumber = DecLineNumber + 1
+ NextLine = DecFileBuffer[DecLineNumber].strip()
+ while (NextLine[0] != "}" and NextLine[0] != "<"):
+ Packages.append (NextLine.strip().replace ('\\', '/'))
+ DecLineNumber = DecLineNumber + 1
+ NextLine = DecFileBuffer[DecLineNumber].strip()
+ DecLineNumber = DecLineNumber + 1
+ PcdObject = self.AddStructuredPcd (Include, Packages, TokenSpaceGuidName, TokenName, Type)
+ PcdObject.AddDefaultValue(Line[2], Line[1], self.DecFile, DecLineNumber)
+ elif PcdObject <> None:
+ Line = [Item.strip() for Item in Line.strip().split('|')]
+ Pcd = [Item.strip() for Item in Line[0].split('.',2)]
+ if len (Line) == 2 and len (Pcd) > 2:
+ if Pcd[0] <> PcdObject.TokenSpaceGuidName or Pcd[1] <> PcdObject.TokenName:
+ print 'Error: PCD does not match parent Structured PCD', Pcd[0], Pcd[1], TokenSpaceGuidName, TokenName
+ sys.exit()
+ PcdObject.AddDefaultValue('.' + Pcd[2], Line[1], self.DecFile, DecLineNumber)
+ if not self.args.Quiet:
+ for Pcd in self.StructuredPcds:
+ print 'Include : ', Pcd.StructuredPcdIncludeFile
+ print 'Type : ', Pcd.TypeName
+ print 'SkuName : ', Pcd.SkuName
+ print 'DefaultStoreName : ', Pcd.DefaultStoreName
+ print 'TokenSpaceGuid : ', Pcd.TokenSpaceGuidName
+ print 'TokenName : ', Pcd.TokenName
+ for Field in Pcd.DefaultValues:
+ print ' %40s : %s' % (Field, Pcd.DefaultValues[Field][0])
+ print ''
+
+ def ParseDscFile (self):
+ print 'Parse DSC File', self.DscFile
+ File = open (self.DscFile, mode='r')
+ DscFileBuffer = File.readlines()
+ File.close()
+ PcdMode = None
+ PcdFieldSettings = OrderedDict({})
+ DscLineNumber = 0
+ for Line in DscFileBuffer:
+ DscLineNumber = DscLineNumber + 1
+ if Line.startswith('#'):
+ continue
+ if Line.startswith('['):
+ Mode = Line[1:].split('.',1)[0].split(']',1)[0]
+ continue
+ Line = [Item.strip() for Item in Line.split('|')]
+ Pcd = [Item.strip() for Item in Line[0].split('.',2)]
+ if len(Pcd) >= 2 and len(Line) > 1:
+ PcdObject = self.LookupPcd (Pcd[0], Pcd[1])
+ if not PcdObject:
+ print 'ERROR: DSC file references structured PCD that is not declared in DEC file', Pcd[0], Pcd[1]
+ sys.exit()
+ if len (Pcd) == 2:
+ PcdObject.AddDefaultValue (PcdObject.TypeName, Line[1], self.DscFile, DscLineNumber)
+ else:
+ PcdObject.AddOverrideValue ('.' + Pcd[2], Line[1], self.DscFile, DscLineNumber)
+ if PcdMode and PcdMode <> Mode:
+ print '%d: %s: ERROR: PCD %s.%s has more than one mode %s %s.' % (DscLineNumber, self.DscFile, Pcd[0], Pcd[1], PcdMode, Mode)
+ sys.exit()
+ PcdMode = Mode
+ PcdObject.SetPcdMode(Mode)
+ if not self.args.Quiet:
+ for Pcd in self.StructuredPcds:
+ print 'Include : ', Pcd.StructuredPcdIncludeFile
+ print 'Type : ', Pcd.TypeName
+ print 'SkuName : ', Pcd.SkuName
+ print 'DefaultStoreName : ', Pcd.DefaultStoreName
+ print 'TokenSpaceGuid : ', Pcd.TokenSpaceGuidName
+ print 'TokenName : ', Pcd.TokenName
+ print 'PcdMode : ', Pcd.PcdMode
+ for Field in Pcd.DefaultValues:
+ print ' D %40s : %s' % (Field, Pcd.DefaultValues[Field][0])
+ for Field in Pcd.OverrideValues:
+ print ' O %40s : %s' % (Field, Pcd.OverrideValues[Field][0])
+ print ''
+
+ def GenerateByteArrayValue (self):
+ #
+ # Generate/Compile/Run C application to determine if there are any flexible array members
+ #
+ InitByteValue = ""
+ CApp = PcdMainCHeader
+
+ Includes = {}
+ for Pcd in self.StructuredPcds:
+ IncludeFile = Pcd.StructuredPcdIncludeFile
+ if IncludeFile not in Includes:
+ Includes[IncludeFile] = True
+ CApp = CApp + '#include <%s>\n' % (IncludeFile)
+ CApp = CApp + '\n'
+
+ FieldNames = {}
+ for Pcd in self.StructuredPcds:
+ CApp = CApp + 'void\n'
+ CApp = CApp + 'Initialize_%s_%s_%s_%s(\n' % (Pcd.SkuName, Pcd.DefaultStoreName, Pcd.TokenSpaceGuidName, Pcd.TokenName)
+ CApp = CApp + ' void\n'
+ CApp = CApp + ' )\n'
+ CApp = CApp + '{\n'
+ CApp = CApp + ' UINT32 Size;\n'
+ CApp = CApp + ' UINT32 FieldSize;\n'
+ CApp = CApp + ' UINT8 *Value;\n'
+ CApp = CApp + ' %s *Pcd;\n' % (Pcd.TypeName)
+ CApp = CApp + ' UINT32 OriginalSize;\n'
+ CApp = CApp + ' VOID *OriginalPcd;\n'
+ CApp = CApp + '\n'
+ InitByteValue = '%s.%s.%s.%s|%s|' %(Pcd.SkuName, Pcd.DefaultStoreName, Pcd.TokenSpaceGuidName, Pcd.TokenName, Pcd.TypeName)
+
+ #
+ # Get current PCD value and size
+ #
+ CApp = CApp + ' OriginalPcd = PcdGetPtr (%s, %s, %s, %s, &OriginalSize);\n' % (Pcd.SkuName, Pcd.DefaultStoreName, Pcd.TokenSpaceGuidName, Pcd.TokenName)
+ CApp = CApp + ' printf("OriginalSize = %d\\n", OriginalSize);\n'
+
+
+ #
+ # Determine the size of the PCD. For simple structures, sizeof(TYPE) provides
+ # the correct value. For structures with a flexible array member, the flexible
+ # array member is detected, and the size is based on the highest index used with
+ # the flexible array member. The flexible array member must be the last field
+ # in a structure. The size formula for this case is:
+ # OFFSET_OF(FlexbleArrayField) + sizeof(FlexibleArray[0]) * (HighestIndex + 1)
+ #
+ CApp = CApp + ' Size = sizeof(%s);\n' % (Pcd.TypeName)
+ CApp = CApp + ' printf("Size = %d\\n", Size);\n'
+ for FieldList in [Pcd.DefaultValues, Pcd.OverrideValues]:
+ for FieldName in FieldList:
+ if not FieldName.startswith('.'):
+ continue
+ IsArray = IsFieldValueAnArray(FieldList[FieldName][0])
+ if IsArray:
+ Value, ValueSize = ParseFieldValue (FieldList[FieldName][0])
+ CApp = CApp + ' __FLEXIBLE_SIZE(Size, %s, %s, %d / __ARRAY_ELEMENT_SIZE(%s, %s));\n' % (Pcd.TypeName, FieldName[1:], ValueSize, Pcd.TypeName, FieldName[1:]);
+ CApp = CApp + ' printf("Size = %d\\n", Size);\n'
+ else:
+ NewFieldName = ''
+ while '[' in FieldName:
+ NewFieldName = NewFieldName + FieldName.split('[',1)[0] + '[0]'
+ ArrayIndex = int(FieldName.split('[',1)[1].split(']',1)[0])
+ FieldName = FieldName.split(']',1)[1]
+ FieldName = NewFieldName + FieldName
+ while '[' in FieldName:
+ FieldName = FieldName.rsplit('[',1)[0]
+ #if not self.args.Quiet:
+ # print 'PCD Field: %40s' % (FieldName)
+ if Pcd.TypeName + FieldName not in FieldNames:
+ FieldNames[Pcd.TypeName + FieldName] = True
+ CApp = CApp + ' __FLEXIBLE_SIZE(Size, %s, %s, %d);\n' % (Pcd.TypeName, FieldName[1:], ArrayIndex + 1)
+ CApp = CApp + ' printf("Size = %d\\n", Size);\n'
+ CApp = CApp + ' printf("Size = %d\\n", Size);\n'
+
+ #
+ # Allocate and zero buffer for the PCD
+ # Must handle cases where current value is smaller, larger, or same size
+ # Always keep that larger one as the current size
+ #
+ CApp = CApp + ' Size = (OriginalSize > Size ? OriginalSize : Size);\n'
+ CApp = CApp + ' printf("Size = %d\\n", Size);\n'
+ CApp = CApp + ' Pcd = (%s *)malloc (Size);\n' % (Pcd.TypeName)
+ CApp = CApp + ' memset (Pcd, 0, Size);\n'
+
+ #
+ # Copy current PCD value into allocated buffer.
+ #
+ CApp = CApp + ' memcpy (Pcd, OriginalPcd, OriginalSize);\n'
+
+ #
+ # Assign field values in PCD
+ #
+ for FieldList in [Pcd.DefaultValues, Pcd.OverrideValues]:
+ for FieldName in FieldList:
+ if not FieldName.startswith('.'):
+ InitByteValue = InitByteValue + '%s\n'%(FieldList[FieldName][0])
+ continue
+ IsArray = IsFieldValueAnArray(FieldList[FieldName][0])
+ Value, ValueSize = ParseFieldValue (FieldList[FieldName][0])
+ #print FieldName, Value, ValueSize, IntToCString(Value, ValueSize)
+ if isinstance(Value, str):
+ CApp = CApp + ' Pcd->%s = %s; // From %s Line %d Value %s\n' % (FieldName[1:], Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])
+ elif IsArray:
+ #
+ # Use memcpy() to copy value into field
+ #
+ CApp = CApp + ' FieldSize = __FIELD_SIZE(%s, %s);\n' % (Pcd.TypeName, FieldName[1:])
+ CApp = CApp + ' printf("FieldSize = %d\\n", FieldSize);\n'
+ CApp = CApp + ' Value = %s; // From %s Line %d Value %s\n' % (IntToCString(Value, ValueSize), FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])
+ CApp = CApp + ' memcpy (&Pcd->%s[0], Value, (FieldSize > 0 && FieldSize < %d) ? FieldSize : %d);\n' % (FieldName[1:], ValueSize, ValueSize)
+ else:
+ if ValueSize > 4:
+ CApp = CApp + ' Pcd->%s = %dULL; // From %s Line %d Value %s\n' % (FieldName[1:], Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])
+ else:
+ CApp = CApp + ' Pcd->%s = %d; // From %s Line %d Value %s\n' % (FieldName[1:], Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])
+
+ #
+ # Set new PCD value and size
+ #
+ CApp = CApp + ' PcdSetPtr (%s, %s, %s, %s, Size, (UINT8 *)Pcd);\n' % (Pcd.SkuName, Pcd.DefaultStoreName, Pcd.TokenSpaceGuidName, Pcd.TokenName)
+
+ #
+ # Free PCD
+ #
+ CApp = CApp + ' free (Pcd);\n'
+
+ CApp = CApp + '}\n'
+ CApp = CApp + '\n'
+
+ CApp = CApp + 'VOID\n'
+ CApp = CApp + 'PcdEntryPoint(\n'
+ CApp = CApp + ' VOID\n'
+ CApp = CApp + ' )\n'
+ CApp = CApp + '{\n'
+ for Pcd in self.StructuredPcds:
+ CApp = CApp + ' Initialize_%s_%s_%s_%s();\n' % (Pcd.SkuName, Pcd.DefaultStoreName, Pcd.TokenSpaceGuidName, Pcd.TokenName)
+ CApp = CApp + '}\n'
+
+ CApp = CApp + PcdMainCEntry + '\n'
+
+ if not os.path.exists(self.OutputPath):
+ os.makedirs(self.OutputPath)
+ CAppBaseFileName = os.path.join(self.OutputPath, PcdValueInitName)
+ File = open (CAppBaseFileName + '.c', mode='w')
+ File.write(CApp)
+ File.close()
+
+ MakeApp = PcdMakefileHeader
+ if sys.platform == "win32":
+ MakeApp = MakeApp + 'APPNAME = %s\n' %(PcdValueInitName) + 'OBJECTS = %s\%s.obj\n' %(self.OutputPath, PcdValueInitName) + 'INC = $(INC)'
+ else:
+ MakeApp = MakeApp + PcdGccMakefile
+ MakeApp = MakeApp + 'APPNAME = %s\n' %(PcdValueInitName) + 'OBJECTS = %s/%s.o\n' %(self.OutputPath, PcdValueInitName) + \
+ 'include $(MAKEROOT)/Makefiles/app.makefile\n' + 'BUILD_CFLAGS += -Wno-error\n' + 'INCLUDE +='
+ Packages = {}
+ for Pcd in self.StructuredPcds:
+ for PackageDec in Pcd.PackageDecs:
+ Package = PackageDec.split('/')[0]
+ if Package not in Packages:
+ Packages[Package] = True
+ MakeApp = MakeApp + ' -I $(WORKSPACE)/%s/Include' %(Package)
+ if Package == 'MdePkg':
+ MakeApp = MakeApp + ' -I $(WORKSPACE)/%s/Include/Ia32' %(Package)
+ MakeApp = MakeApp + '\n'
+ if sys.platform == "win32":
+ MakeApp = MakeApp + PcdMakefileEnd
+ MakeFileName = os.path.join(self.OutputPath, 'Makefile')
+ File = open (MakeFileName, mode='w')
+ File.write(MakeApp)
+ File.close()
+
+ InputValueFile = os.path.join(self.OutputPath, 'Input.txt')
+ OutputValueFile = os.path.join(self.OutputPath, 'Output.txt')
+ File = open (InputValueFile, mode='w')
+ File.write(InitByteValue)
+ File.close()
+
+ if sys.platform == "win32":
+ StdOut, StdErr = ExecuteCommand ('nmake -f %s' % (MakeFileName))
+ else:
+ StdOut, StdErr = ExecuteCommand ('make -f %s' % (MakeFileName))
+ Messages = StdOut.split('\r')
+ for Message in Messages:
+ if " error " in Message:
+ FileInfo = Message.strip().split('(')
+ if len (FileInfo) > 0:
+ FileName = FileInfo [0]
+ FileLine = FileInfo [1].split (')')[0]
+ else:
+ FileInfo = Message.strip().split(':')
+ FileName = FileInfo [0]
+ FileLine = FileInfo [1]
+
+ File = open (FileName, mode='r')
+ FileData = File.readlines()
+ File.close()
+ print Message
+ print FileData[int (FileLine) - 1]
+ return
+
+ PcdValueInitExe = PcdValueInitName
+ if not sys.platform == "win32":
+ PcdValueInitExe = os.path.join(os.getenv("EDK_TOOLS_PATH"), 'Source', 'C', 'bin', PcdValueInitName)
+
+ StdOut, StdErr = ExecuteCommand (PcdValueInitExe + ' -i %s -o %s' % (InputValueFile, OutputValueFile))
+ File = open (OutputValueFile, mode='r')
+ FileBuffer = File.readlines()
+ File.close()
+
+ print 'Final Value Output:'
+ for Pcd in FileBuffer:
+ PcdValue = Pcd.split ('|')
+ PcdInfo = PcdValue[0].split ('.')
+ print 'SkuName : ', PcdInfo[0]
+ print 'TokenSpaceGuid : ', PcdInfo[2]
+ print 'TokenName : ', PcdInfo[3]
+ print 'Value : ', PcdValue[2]
+
+def main():
+ #
+ # Create command line argument parser object
+ #
+ parser = argparse.ArgumentParser(prog=__prog__, version=__version__, usage=__usage__, description=__copyright__, conflict_handler='resolve')
+ parser.add_argument("-p", "--dec-file", dest='DecFile', help="DEC File", required = True)
+ parser.add_argument("-d", "--dsc-file", dest='DscFile', help="DSC File", required = True)
+ parser.add_argument("-v", "--verbose", dest='Verbose', action="store_true", help="increase output messages")
+ parser.add_argument("-q", "--quiet", dest='Quiet', action="store_true", help="reduce output messages")
+ parser.add_argument("--debug", dest='Debug', type=int, metavar='[0-9]', choices=range(0,10), default=0, help="set debug level")
+
+ #
+ # Parse command line arguments
+ #
+ args = parser.parse_args()
+
+ #
+ # Get absolute paths
+ #
+ args.DecFile = os.path.abspath(args.DecFile)
+ args.DscFile = os.path.abspath(args.DscFile)
+
+ #
+ #
+ #
+ BuildObject = Build(args)
+ BuildObject.ParseDecFile()
+ BuildObject.ParseDscFile()
+ BuildObject.GenerateByteArrayValue()
+
+if __name__ == '__main__':
+ main()
diff --git a/TestPkg/TestPkg.dec b/TestPkg/TestPkg.dec
new file mode 100644
index 0000000..622678e
--- /dev/null
+++ b/TestPkg/TestPkg.dec
@@ -0,0 +1,44 @@
+## @file TestPkg.dec
+#
+# Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
+# This program and the accompanying materials are licensed and made available under
+# the terms and conditions of the BSD License that accompanies this distribution.
+# The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php.
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+##
+
+
+[Defines]
+ DEC_SPECIFICATION = 0x00010005
+ PACKAGE_NAME = TestPkg
+ PACKAGE_GUID = F05BB314-CD00-4705-BD04-59B1CD9630E1
+ PACKAGE_VERSION = 0.1
+
+[Includes]
+ Include
+
+[LibraryClasses]
+
+[Guids]
+ ## MdeModule package token space guid
+ # Include/Guid/MdeModulePkgTokenSpace.h
+ gEfiStructuredPcdPkgTokenSpaceGuid = { 0x11a81069, 0xa6a2, 0x420a, { 0xa0, 0xe, 0x30, 0xc5, 0xb, 0xfb, 0xe8, 0x13 } }
+
+[PcdsFixedAtBuild, PcdsPatchableInModule, PcdsDynamic, PcdsDynamicEx]
+ # @Prompt Test Strucutre
+ gEfiStructuredPcdPkgTokenSpaceGuid.Test|{0xFF, 0xFF}|TEST|0x00010071 {
+ <HeaderFiles>
+ Guid/Test.h
+ <Packages>
+ MdePkg/MdePkg.dec
+ TestPkg/TestPkg.dec
+ }
+ gEfiStructuredPcdPkgTokenSpaceGuid.Test.A|2
+ gEfiStructuredPcdPkgTokenSpaceGuid.Test.C|20
+ gEfiStructuredPcdPkgTokenSpaceGuid.Test.Array[4]|1
+ gEfiStructuredPcdPkgTokenSpaceGuid.Test.Array2[0]|2
+ gEfiStructuredPcdPkgTokenSpaceGuid.Test.FlexibleArray[7]|5
diff --git a/TestPkg/TestPkg.dsc b/TestPkg/TestPkg.dsc
new file mode 100644
index 0000000..fc61979
--- /dev/null
+++ b/TestPkg/TestPkg.dsc
@@ -0,0 +1,69 @@
+## @file
+# EFI/PI Reference Module Package for All Architectures
+#
+# (C) Copyright 2014 Hewlett-Packard Development Company, L.P.<BR>
+# Copyright (c) 2007 - 2016, Intel Corporation. All rights reserved.<BR>
+#
+# This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+##
+
+[Defines]
+ PLATFORM_NAME = StructuredPcdPkg
+ PLATFORM_GUID = 35B4419B-4CF6-46FA-9A5D-741D0D29CD61
+ PLATFORM_VERSION = 0.1
+ DSC_SPECIFICATION = 0x00010005
+ OUTPUT_DIRECTORY = Build/StructuredPcdPkg
+ SUPPORTED_ARCHITECTURES = IA32|IPF|X64|EBC|ARM|AARCH64
+ BUILD_TARGETS = DEBUG|RELEASE|NOOPT
+ SKUID_IDENTIFIER = DEFAULT
+
+[LibraryClasses]
+
+###################################################################################################
+#
+# Components Section - list of the modules and components that will be processed by compilation
+# tools and the EDK II tools to generate PE32/PE32+/Coff image files.
+#
+# Note: The EDK II DSC file is not used to specify how compiled binary images get placed
+# into firmware volume images. This section is just a list of modules to compile from
+# source into UEFI-compliant binaries.
+# It is the FDF file that contains information on combining binary files into firmware
+# volume images, whose concept is beyond UEFI and is described in PI specification.
+# Binary modules do not need to be listed in this section, as they should be
+# specified in the FDF file. For example: Shell binary (Shell_Full.efi), FAT binary (Fat.efi),
+# Logo (Logo.bmp), and etc.
+# There may also be modules listed in this section that are not required in the FDF file,
+# When a module listed here is excluded from FDF file, then UEFI-compliant binary will be
+# generated for it, but the binary will not be put into any firmware volume.
+#
+###################################################################################################
+
+[PcdsFixedAtBuild]
+ gEfiStructuredPcdPkgTokenSpaceGuid.Test|{0xFF, 0xFF}
+ gEfiStructuredPcdPkgTokenSpaceGuid.Test.A|MacroTest2
+ gEfiStructuredPcdPkgTokenSpaceGuid.Test.C|'a'
+ gEfiStructuredPcdPkgTokenSpaceGuid.Test.Array[4]|1
+ gEfiStructuredPcdPkgTokenSpaceGuid.Test.Array2[0]|2
+ gEfiStructuredPcdPkgTokenSpaceGuid.Test.FlexibleArray[7]|5
+ gEfiStructuredPcdPkgTokenSpaceGuid.Test.FlexibleArray[4]|L'C'
+ gEfiStructuredPcdPkgTokenSpaceGuid.Test.FlexibleArray[3]|'b'
+ gEfiStructuredPcdPkgTokenSpaceGuid.Test.Array|"Hello"
+ gEfiStructuredPcdPkgTokenSpaceGuid.Test.Array|L"Hello"
+ gEfiStructuredPcdPkgTokenSpaceGuid.Test.Array|'Hello'
+ gEfiStructuredPcdPkgTokenSpaceGuid.Test.Array|L'Hello'
+ gEfiStructuredPcdPkgTokenSpaceGuid.Test.Array|GUID("6F08F62E-5C19-498E-9157-B59CE6F362F1")
+# gEfiStructuredPcdPkgTokenSpaceGuid.Test.Array|GUID({ 0x827495c7, 0x636f, 0x4e0c, { 0x9c, 0xcc, 0x93, 0x5e, 0xfb, 0x67, 0xf2, 0x7c } })
+# gEfiStructuredPcdPkgTokenSpaceGuid.Test.Array|{1,2,3}
+ gEfiStructuredPcdPkgTokenSpaceGuid.Test.FlexibleArray|"World"
+ gEfiStructuredPcdPkgTokenSpaceGuid.Test.FlexibleArray|L"World"
+# gEfiStructuredPcdPkgTokenSpaceGuid.Test.FlexibleArray|{4, 5, 6}
+
+
+[Components]
--
2.8.0.windows.1
_______________________________________________
edk2-devel mailing list
edk2-devel@lists.01.org
https://lists.01.org/mailman/listinfo/edk2-devel
© 2016 - 2024 Red Hat, Inc.