replace "== None" with "is None" and "!= None" with "is not None" Cc: Yonghong Zhu <yonghong.zhu@intel.com> Cc: Liming Gao <liming.gao@intel.com> Contributed-under: TianoCore Contribution Agreement 1.1 Signed-off-by: Jaben Carsey <jaben.carsey@intel.com> Reviewed-by: Yonghong Zhu <yonghong.zhu@intel.com>
		
			
				
	
	
		
			2738 lines
		
	
	
		
			148 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			2738 lines
		
	
	
		
			148 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
| ## @file
 | |
| # This file is used to create a database used by build tool
 | |
| #
 | |
| # Copyright (c) 2008 - 2018, Intel Corporation. All rights reserved.<BR>
 | |
| # (C) Copyright 2016 Hewlett Packard Enterprise Development LP<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.
 | |
| #
 | |
| 
 | |
| ## Platform build information from DSC file
 | |
| #
 | |
| #  This class is used to retrieve information stored in database and convert them
 | |
| # into PlatformBuildClassObject form for easier use for AutoGen.
 | |
| #
 | |
| from Common.String import *
 | |
| from Common.DataType import *
 | |
| from Common.Misc import *
 | |
| from types import *
 | |
| from Common.Expression import *
 | |
| from CommonDataClass.CommonClass import SkuInfoClass
 | |
| from Common.TargetTxtClassObject import *
 | |
| from Common.ToolDefClassObject import *
 | |
| from MetaDataTable import *
 | |
| from MetaFileTable import *
 | |
| from MetaFileParser import *
 | |
| 
 | |
| from WorkspaceCommon import GetDeclaredPcd
 | |
| from Common.Misc import AnalyzeDscPcd
 | |
| from Common.Misc import ProcessDuplicatedInf
 | |
| import re
 | |
| from Common.Parsing import IsValidWord
 | |
| from Common.VariableAttributes import VariableAttributes
 | |
| import Common.GlobalData as GlobalData
 | |
| import subprocess
 | |
| from Common.Misc import SaveFileOnChange
 | |
| from Workspace.BuildClassObject import PlatformBuildClassObject, StructurePcd, PcdClassObject, ModuleBuildClassObject
 | |
| from collections import OrderedDict
 | |
| 
 | |
| #
 | |
| # 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 <string.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
 | |
| #
 | |
| 
 | |
| '''
 | |
| 
 | |
| WindowsCFLAGS = 'CFLAGS = $(CFLAGS) /wd4200 /wd4034 /wd4101 '
 | |
| LinuxCFLAGS = 'BUILD_CFLAGS += -Wno-pointer-to-int-cast -Wno-unused-variable '
 | |
| PcdMakefileEnd = '''
 | |
| !INCLUDE $(BASE_TOOLS_PATH)\Source\C\Makefiles\ms.common
 | |
| 
 | |
| LIBS = $(LIB_PATH)\Common.lib
 | |
| 
 | |
| !INCLUDE $(BASE_TOOLS_PATH)\Source\C\Makefiles\ms.app
 | |
| '''
 | |
| 
 | |
| PcdGccMakefile = '''
 | |
| MAKEROOT ?= $(EDK_TOOLS_PATH)/Source/C
 | |
| LIBS = -lCommon
 | |
| '''
 | |
| 
 | |
| ## Regular expression for finding header file inclusions
 | |
| from AutoGen.GenMake import gIncludePattern
 | |
| 
 | |
| ## Find dependencies for one source file
 | |
| #
 | |
| #  By searching recursively "#include" directive in file, find out all the
 | |
| #  files needed by given source file. The dependecies will be only searched
 | |
| #  in given search path list.
 | |
| #
 | |
| #   @param      SearchPathList  The list of search path
 | |
| #
 | |
| #   @retval     list            The list of files the given source file depends on
 | |
| #
 | |
| def GetDependencyList(FileStack,SearchPathList):
 | |
|     DepDb = dict()
 | |
|     DependencySet = set(FileStack)
 | |
|     while len(FileStack) > 0:
 | |
|         F = FileStack.pop()
 | |
|         FullPathDependList = []
 | |
|         CurrentFileDependencyList = []
 | |
|         if F in DepDb:
 | |
|             CurrentFileDependencyList = DepDb[F]
 | |
|         else:
 | |
|             try:
 | |
|                 Fd = open(F, 'r')
 | |
|                 FileContent = Fd.read()
 | |
|             except BaseException, X:
 | |
|                 EdkLogger.error("build", FILE_OPEN_FAILURE, ExtraData=F + "\n\t" + str(X))
 | |
|             finally:
 | |
|                 if "Fd" in dir(locals()):
 | |
|                     Fd.close()
 | |
| 
 | |
|             if len(FileContent) == 0:
 | |
|                 continue
 | |
| 
 | |
|             if FileContent[0] == 0xff or FileContent[0] == 0xfe:
 | |
|                 FileContent = unicode(FileContent, "utf-16")
 | |
|             IncludedFileList = gIncludePattern.findall(FileContent)
 | |
| 
 | |
|             for Inc in IncludedFileList:
 | |
|                 Inc = Inc.strip()
 | |
|                 Inc = os.path.normpath(Inc)
 | |
|                 CurrentFileDependencyList.append(Inc)
 | |
|             DepDb[F] = CurrentFileDependencyList
 | |
| 
 | |
|         CurrentFilePath = os.path.dirname(F)
 | |
|         PathList = [CurrentFilePath] + SearchPathList
 | |
|         for Inc in CurrentFileDependencyList:
 | |
|             for SearchPath in PathList:
 | |
|                 FilePath = os.path.join(SearchPath, Inc)
 | |
|                 if not os.path.exists(FilePath):
 | |
|                     continue
 | |
|                 if FilePath not in DependencySet:
 | |
|                     FileStack.append(FilePath)
 | |
|                     FullPathDependList.append(FilePath)
 | |
|                 break
 | |
|         DependencySet.update(FullPathDependList)
 | |
|     DependencyList = list(DependencySet)  # remove duplicate ones
 | |
| 
 | |
|     return DependencyList
 | |
| 
 | |
| class DscBuildData(PlatformBuildClassObject):
 | |
|     # dict used to convert PCD type in database to string used by build tool
 | |
|     _PCD_TYPE_STRING_ = {
 | |
|         MODEL_PCD_FIXED_AT_BUILD        :   "FixedAtBuild",
 | |
|         MODEL_PCD_PATCHABLE_IN_MODULE   :   "PatchableInModule",
 | |
|         MODEL_PCD_FEATURE_FLAG          :   "FeatureFlag",
 | |
|         MODEL_PCD_DYNAMIC               :   "Dynamic",
 | |
|         MODEL_PCD_DYNAMIC_DEFAULT       :   "Dynamic",
 | |
|         MODEL_PCD_DYNAMIC_HII           :   "DynamicHii",
 | |
|         MODEL_PCD_DYNAMIC_VPD           :   "DynamicVpd",
 | |
|         MODEL_PCD_DYNAMIC_EX            :   "DynamicEx",
 | |
|         MODEL_PCD_DYNAMIC_EX_DEFAULT    :   "DynamicEx",
 | |
|         MODEL_PCD_DYNAMIC_EX_HII        :   "DynamicExHii",
 | |
|         MODEL_PCD_DYNAMIC_EX_VPD        :   "DynamicExVpd",
 | |
|     }
 | |
| 
 | |
|     # dict used to convert part of [Defines] to members of DscBuildData directly
 | |
|     _PROPERTY_ = {
 | |
|         #
 | |
|         # Required Fields
 | |
|         #
 | |
|         TAB_DSC_DEFINES_PLATFORM_NAME           :   "_PlatformName",
 | |
|         TAB_DSC_DEFINES_PLATFORM_GUID           :   "_Guid",
 | |
|         TAB_DSC_DEFINES_PLATFORM_VERSION        :   "_Version",
 | |
|         TAB_DSC_DEFINES_DSC_SPECIFICATION       :   "_DscSpecification",
 | |
|         # TAB_DSC_DEFINES_OUTPUT_DIRECTORY        :   "_OutputDirectory",
 | |
|         # TAB_DSC_DEFINES_SUPPORTED_ARCHITECTURES :   "_SupArchList",
 | |
|         # TAB_DSC_DEFINES_BUILD_TARGETS           :   "_BuildTargets",
 | |
|         TAB_DSC_DEFINES_SKUID_IDENTIFIER        :   "_SkuName",
 | |
|         # TAB_DSC_DEFINES_FLASH_DEFINITION        :   "_FlashDefinition",
 | |
|         TAB_DSC_DEFINES_BUILD_NUMBER            :   "_BuildNumber",
 | |
|         TAB_DSC_DEFINES_MAKEFILE_NAME           :   "_MakefileName",
 | |
|         TAB_DSC_DEFINES_BS_BASE_ADDRESS         :   "_BsBaseAddress",
 | |
|         TAB_DSC_DEFINES_RT_BASE_ADDRESS         :   "_RtBaseAddress",
 | |
|         # TAB_DSC_DEFINES_RFC_LANGUAGES           :   "_RFCLanguages",
 | |
|         # TAB_DSC_DEFINES_ISO_LANGUAGES           :   "_ISOLanguages",
 | |
|     }
 | |
| 
 | |
|     # used to compose dummy library class name for those forced library instances
 | |
|     _NullLibraryNumber = 0
 | |
| 
 | |
|     ## Constructor of DscBuildData
 | |
|     #
 | |
|     #  Initialize object of DscBuildData
 | |
|     #
 | |
|     #   @param      FilePath        The path of platform description file
 | |
|     #   @param      RawData         The raw data of DSC file
 | |
|     #   @param      BuildDataBase   Database used to retrieve module/package information
 | |
|     #   @param      Arch            The target architecture
 | |
|     #   @param      Platform        (not used for DscBuildData)
 | |
|     #   @param      Macros          Macros used for replacement in DSC file
 | |
|     #
 | |
|     def __init__(self, FilePath, RawData, BuildDataBase, Arch='COMMON', Target=None, Toolchain=None):
 | |
|         self.MetaFile = FilePath
 | |
|         self._RawData = RawData
 | |
|         self._Bdb = BuildDataBase
 | |
|         self._Arch = Arch
 | |
|         self._Target = Target
 | |
|         self._Toolchain = Toolchain
 | |
|         self._ToolChainFamily = None
 | |
|         self._Clear()
 | |
|         self._HandleOverridePath()
 | |
|         self.WorkspaceDir = os.getenv("WORKSPACE") if os.getenv("WORKSPACE") else ""
 | |
|         self.DefaultStores = None
 | |
|         self.SkuIdMgr = SkuClass(self.SkuName, self.SkuIds)
 | |
|     @property
 | |
|     def OutputPath(self):
 | |
|         if os.getenv("WORKSPACE"):
 | |
|             return os.path.join(os.getenv("WORKSPACE"), self.OutputDirectory, self._Target + "_" + self._Toolchain,PcdValueInitName)
 | |
|         else:
 | |
|             return os.path.dirname(self.DscFile)
 | |
| 
 | |
|     ## XXX[key] = value
 | |
|     def __setitem__(self, key, value):
 | |
|         self.__dict__[self._PROPERTY_[key]] = value
 | |
| 
 | |
|     ## value = XXX[key]
 | |
|     def __getitem__(self, key):
 | |
|         return self.__dict__[self._PROPERTY_[key]]
 | |
| 
 | |
|     ## "in" test support
 | |
|     def __contains__(self, key):
 | |
|         return key in self._PROPERTY_
 | |
| 
 | |
|     ## Set all internal used members of DscBuildData to None
 | |
|     def _Clear(self):
 | |
|         self._Header            = None
 | |
|         self._PlatformName      = None
 | |
|         self._Guid              = None
 | |
|         self._Version           = None
 | |
|         self._DscSpecification  = None
 | |
|         self._OutputDirectory   = None
 | |
|         self._SupArchList       = None
 | |
|         self._BuildTargets      = None
 | |
|         self._SkuName           = None
 | |
|         self._PcdInfoFlag       = None
 | |
|         self._VarCheckFlag      = None
 | |
|         self._FlashDefinition   = None
 | |
|         self._Prebuild          = None
 | |
|         self._Postbuild         = None
 | |
|         self._BuildNumber       = None
 | |
|         self._MakefileName      = None
 | |
|         self._BsBaseAddress     = None
 | |
|         self._RtBaseAddress     = None
 | |
|         self._SkuIds            = None
 | |
|         self._Modules           = None
 | |
|         self._LibraryInstances  = None
 | |
|         self._LibraryClasses    = None
 | |
|         self._Pcds              = None
 | |
|         self._DecPcds           = None
 | |
|         self._BuildOptions      = None
 | |
|         self._ModuleTypeOptions = None
 | |
|         self._LoadFixAddress    = None
 | |
|         self._RFCLanguages      = None
 | |
|         self._ISOLanguages      = None
 | |
|         self._VpdToolGuid       = None
 | |
|         self.__Macros           = None
 | |
|         self.DefaultStores      = None
 | |
| 
 | |
| 
 | |
|     ## handle Override Path of Module
 | |
|     def _HandleOverridePath(self):
 | |
|         RecordList = self._RawData[MODEL_META_DATA_COMPONENT, self._Arch]
 | |
|         Macros = self._Macros
 | |
|         Macros["EDK_SOURCE"] = GlobalData.gEcpSource
 | |
|         for Record in RecordList:
 | |
|             ModuleId = Record[6]
 | |
|             LineNo = Record[7]
 | |
|             ModuleFile = PathClass(NormPath(Record[0]), GlobalData.gWorkspace, Arch=self._Arch)
 | |
|             RecordList = self._RawData[MODEL_META_DATA_COMPONENT_SOURCE_OVERRIDE_PATH, self._Arch, None, ModuleId]
 | |
|             if RecordList != []:
 | |
|                 SourceOverridePath = mws.join(GlobalData.gWorkspace, NormPath(RecordList[0][0]))
 | |
| 
 | |
|                 # Check if the source override path exists
 | |
|                 if not os.path.isdir(SourceOverridePath):
 | |
|                     EdkLogger.error('build', FILE_NOT_FOUND, Message='Source override path does not exist:', File=self.MetaFile, ExtraData=SourceOverridePath, Line=LineNo)
 | |
| 
 | |
|                 # Add to GlobalData Variables
 | |
|                 GlobalData.gOverrideDir[ModuleFile.Key] = SourceOverridePath
 | |
| 
 | |
|     ## Get current effective macros
 | |
|     def _GetMacros(self):
 | |
|         if self.__Macros is None:
 | |
|             self.__Macros = {}
 | |
|             self.__Macros.update(GlobalData.gPlatformDefines)
 | |
|             self.__Macros.update(GlobalData.gGlobalDefines)
 | |
|             self.__Macros.update(GlobalData.gCommandLineDefines)
 | |
|         return self.__Macros
 | |
| 
 | |
|     ## Get architecture
 | |
|     def _GetArch(self):
 | |
|         return self._Arch
 | |
| 
 | |
|     ## Set architecture
 | |
|     #
 | |
|     #   Changing the default ARCH to another may affect all other information
 | |
|     # because all information in a platform may be ARCH-related. That's
 | |
|     # why we need to clear all internal used members, in order to cause all
 | |
|     # information to be re-retrieved.
 | |
|     #
 | |
|     #   @param  Value   The value of ARCH
 | |
|     #
 | |
|     def _SetArch(self, Value):
 | |
|         if self._Arch == Value:
 | |
|             return
 | |
|         self._Arch = Value
 | |
|         self._Clear()
 | |
| 
 | |
|     ## Retrieve all information in [Defines] section
 | |
|     #
 | |
|     #   (Retriving all [Defines] information in one-shot is just to save time.)
 | |
|     #
 | |
|     def _GetHeaderInfo(self):
 | |
|         RecordList = self._RawData[MODEL_META_DATA_HEADER, self._Arch]
 | |
|         for Record in RecordList:
 | |
|             Name = Record[1]
 | |
|             # items defined _PROPERTY_ don't need additional processing
 | |
| 
 | |
|             # some special items in [Defines] section need special treatment
 | |
|             if Name == TAB_DSC_DEFINES_OUTPUT_DIRECTORY:
 | |
|                 self._OutputDirectory = NormPath(Record[2], self._Macros)
 | |
|                 if ' ' in self._OutputDirectory:
 | |
|                     EdkLogger.error("build", FORMAT_NOT_SUPPORTED, "No space is allowed in OUTPUT_DIRECTORY",
 | |
|                                     File=self.MetaFile, Line=Record[-1],
 | |
|                                     ExtraData=self._OutputDirectory)
 | |
|             elif Name == TAB_DSC_DEFINES_FLASH_DEFINITION:
 | |
|                 self._FlashDefinition = PathClass(NormPath(Record[2], self._Macros), GlobalData.gWorkspace)
 | |
|                 ErrorCode, ErrorInfo = self._FlashDefinition.Validate('.fdf')
 | |
|                 if ErrorCode != 0:
 | |
|                     EdkLogger.error('build', ErrorCode, File=self.MetaFile, Line=Record[-1],
 | |
|                                     ExtraData=ErrorInfo)
 | |
|             elif Name == TAB_DSC_PREBUILD:
 | |
|                 PrebuildValue = Record[2]
 | |
|                 if Record[2][0] == '"':
 | |
|                     if Record[2][-1] != '"':
 | |
|                         EdkLogger.error('build', FORMAT_INVALID, 'Missing double quotes in the end of %s statement.' % TAB_DSC_PREBUILD,
 | |
|                                     File=self.MetaFile, Line=Record[-1])
 | |
|                     PrebuildValue = Record[2][1:-1]
 | |
|                 self._Prebuild = PrebuildValue
 | |
|             elif Name == TAB_DSC_POSTBUILD:
 | |
|                 PostbuildValue = Record[2]
 | |
|                 if Record[2][0] == '"':
 | |
|                     if Record[2][-1] != '"':
 | |
|                         EdkLogger.error('build', FORMAT_INVALID, 'Missing double quotes in the end of %s statement.' % TAB_DSC_POSTBUILD,
 | |
|                                     File=self.MetaFile, Line=Record[-1])
 | |
|                     PostbuildValue = Record[2][1:-1]
 | |
|                 self._Postbuild = PostbuildValue
 | |
|             elif Name == TAB_DSC_DEFINES_SUPPORTED_ARCHITECTURES:
 | |
|                 self._SupArchList = GetSplitValueList(Record[2], TAB_VALUE_SPLIT)
 | |
|             elif Name == TAB_DSC_DEFINES_BUILD_TARGETS:
 | |
|                 self._BuildTargets = GetSplitValueList(Record[2])
 | |
|             elif Name == TAB_DSC_DEFINES_SKUID_IDENTIFIER:
 | |
|                 if self._SkuName is None:
 | |
|                     self._SkuName = Record[2]
 | |
|                 if GlobalData.gSKUID_CMD:
 | |
|                     self._SkuName = GlobalData.gSKUID_CMD
 | |
|             elif Name == TAB_DSC_DEFINES_PCD_INFO_GENERATION:
 | |
|                 self._PcdInfoFlag = Record[2]
 | |
|             elif Name == TAB_DSC_DEFINES_PCD_VAR_CHECK_GENERATION:
 | |
|                 self._VarCheckFlag = Record[2]
 | |
|             elif Name == TAB_FIX_LOAD_TOP_MEMORY_ADDRESS:
 | |
|                 try:
 | |
|                     self._LoadFixAddress = int (Record[2], 0)
 | |
|                 except:
 | |
|                     EdkLogger.error("build", PARAMETER_INVALID, "FIX_LOAD_TOP_MEMORY_ADDRESS %s is not valid dec or hex string" % (Record[2]))
 | |
|             elif Name == TAB_DSC_DEFINES_RFC_LANGUAGES:
 | |
|                 if not Record[2] or Record[2][0] != '"' or Record[2][-1] != '"' or len(Record[2]) == 1:
 | |
|                     EdkLogger.error('build', FORMAT_NOT_SUPPORTED, 'language code for RFC_LANGUAGES must have double quotes around it, for example: RFC_LANGUAGES = "en-us;zh-hans"',
 | |
|                                     File=self.MetaFile, Line=Record[-1])
 | |
|                 LanguageCodes = Record[2][1:-1]
 | |
|                 if not LanguageCodes:
 | |
|                     EdkLogger.error('build', FORMAT_NOT_SUPPORTED, 'one or more RFC4646 format language code must be provided for RFC_LANGUAGES statement',
 | |
|                                     File=self.MetaFile, Line=Record[-1])
 | |
|                 LanguageList = GetSplitValueList(LanguageCodes, TAB_SEMI_COLON_SPLIT)
 | |
|                 # check whether there is empty entries in the list
 | |
|                 if None in LanguageList:
 | |
|                     EdkLogger.error('build', FORMAT_NOT_SUPPORTED, 'one or more empty language code is in RFC_LANGUAGES statement',
 | |
|                                     File=self.MetaFile, Line=Record[-1])
 | |
|                 self._RFCLanguages = LanguageList
 | |
|             elif Name == TAB_DSC_DEFINES_ISO_LANGUAGES:
 | |
|                 if not Record[2] or Record[2][0] != '"' or Record[2][-1] != '"' or len(Record[2]) == 1:
 | |
|                     EdkLogger.error('build', FORMAT_NOT_SUPPORTED, 'language code for ISO_LANGUAGES must have double quotes around it, for example: ISO_LANGUAGES = "engchn"',
 | |
|                                     File=self.MetaFile, Line=Record[-1])
 | |
|                 LanguageCodes = Record[2][1:-1]
 | |
|                 if not LanguageCodes:
 | |
|                     EdkLogger.error('build', FORMAT_NOT_SUPPORTED, 'one or more ISO639-2 format language code must be provided for ISO_LANGUAGES statement',
 | |
|                                     File=self.MetaFile, Line=Record[-1])
 | |
|                 if len(LanguageCodes) % 3:
 | |
|                     EdkLogger.error('build', FORMAT_NOT_SUPPORTED, 'bad ISO639-2 format for ISO_LANGUAGES',
 | |
|                                     File=self.MetaFile, Line=Record[-1])
 | |
|                 LanguageList = []
 | |
|                 for i in range(0, len(LanguageCodes), 3):
 | |
|                     LanguageList.append(LanguageCodes[i:i + 3])
 | |
|                 self._ISOLanguages = LanguageList
 | |
|             elif Name == TAB_DSC_DEFINES_VPD_TOOL_GUID:
 | |
|                 #
 | |
|                 # try to convert GUID to a real UUID value to see whether the GUID is format
 | |
|                 # for VPD_TOOL_GUID is correct.
 | |
|                 #
 | |
|                 try:
 | |
|                     uuid.UUID(Record[2])
 | |
|                 except:
 | |
|                     EdkLogger.error("build", FORMAT_INVALID, "Invalid GUID format for VPD_TOOL_GUID", File=self.MetaFile)
 | |
|                 self._VpdToolGuid = Record[2]
 | |
|             elif Name in self:
 | |
|                 self[Name] = Record[2]
 | |
|         # set _Header to non-None in order to avoid database re-querying
 | |
|         self._Header = 'DUMMY'
 | |
| 
 | |
|     ## Retrieve platform name
 | |
|     def _GetPlatformName(self):
 | |
|         if self._PlatformName is None:
 | |
|             if self._Header is None:
 | |
|                 self._GetHeaderInfo()
 | |
|             if self._PlatformName is None:
 | |
|                 EdkLogger.error('build', ATTRIBUTE_NOT_AVAILABLE, "No PLATFORM_NAME", File=self.MetaFile)
 | |
|         return self._PlatformName
 | |
| 
 | |
|     ## Retrieve file guid
 | |
|     def _GetFileGuid(self):
 | |
|         if self._Guid is None:
 | |
|             if self._Header is None:
 | |
|                 self._GetHeaderInfo()
 | |
|             if self._Guid is None:
 | |
|                 EdkLogger.error('build', ATTRIBUTE_NOT_AVAILABLE, "No PLATFORM_GUID", File=self.MetaFile)
 | |
|         return self._Guid
 | |
| 
 | |
|     ## Retrieve platform version
 | |
|     def _GetVersion(self):
 | |
|         if self._Version is None:
 | |
|             if self._Header is None:
 | |
|                 self._GetHeaderInfo()
 | |
|             if self._Version is None:
 | |
|                 EdkLogger.error('build', ATTRIBUTE_NOT_AVAILABLE, "No PLATFORM_VERSION", File=self.MetaFile)
 | |
|         return self._Version
 | |
| 
 | |
|     ## Retrieve platform description file version
 | |
|     def _GetDscSpec(self):
 | |
|         if self._DscSpecification is None:
 | |
|             if self._Header is None:
 | |
|                 self._GetHeaderInfo()
 | |
|             if self._DscSpecification is None:
 | |
|                 EdkLogger.error('build', ATTRIBUTE_NOT_AVAILABLE, "No DSC_SPECIFICATION", File=self.MetaFile)
 | |
|         return self._DscSpecification
 | |
| 
 | |
|     ## Retrieve OUTPUT_DIRECTORY
 | |
|     def _GetOutpuDir(self):
 | |
|         if self._OutputDirectory is None:
 | |
|             if self._Header is None:
 | |
|                 self._GetHeaderInfo()
 | |
|             if self._OutputDirectory is None:
 | |
|                 self._OutputDirectory = os.path.join("Build", self._PlatformName)
 | |
|         return self._OutputDirectory
 | |
| 
 | |
|     ## Retrieve SUPPORTED_ARCHITECTURES
 | |
|     def _GetSupArch(self):
 | |
|         if self._SupArchList is None:
 | |
|             if self._Header is None:
 | |
|                 self._GetHeaderInfo()
 | |
|             if self._SupArchList is None:
 | |
|                 EdkLogger.error('build', ATTRIBUTE_NOT_AVAILABLE, "No SUPPORTED_ARCHITECTURES", File=self.MetaFile)
 | |
|         return self._SupArchList
 | |
| 
 | |
|     ## Retrieve BUILD_TARGETS
 | |
|     def _GetBuildTarget(self):
 | |
|         if self._BuildTargets is None:
 | |
|             if self._Header is None:
 | |
|                 self._GetHeaderInfo()
 | |
|             if self._BuildTargets is None:
 | |
|                 EdkLogger.error('build', ATTRIBUTE_NOT_AVAILABLE, "No BUILD_TARGETS", File=self.MetaFile)
 | |
|         return self._BuildTargets
 | |
| 
 | |
|     def _GetPcdInfoFlag(self):
 | |
|         if self._PcdInfoFlag is None or self._PcdInfoFlag.upper() == 'FALSE':
 | |
|             return False
 | |
|         elif self._PcdInfoFlag.upper() == 'TRUE':
 | |
|             return True
 | |
|         else:
 | |
|             return False
 | |
|     def _GetVarCheckFlag(self):
 | |
|         if self._VarCheckFlag is None or self._VarCheckFlag.upper() == 'FALSE':
 | |
|             return False
 | |
|         elif self._VarCheckFlag.upper() == 'TRUE':
 | |
|             return True
 | |
|         else:
 | |
|             return False
 | |
| 
 | |
|     # # Retrieve SKUID_IDENTIFIER
 | |
|     def _GetSkuName(self):
 | |
|         if self._SkuName is None:
 | |
|             if self._Header is None:
 | |
|                 self._GetHeaderInfo()
 | |
|             if self._SkuName is None:
 | |
|                 self._SkuName = 'DEFAULT'
 | |
|         return self._SkuName
 | |
| 
 | |
|     ## Override SKUID_IDENTIFIER
 | |
|     def _SetSkuName(self, Value):
 | |
|         self._SkuName = Value
 | |
| 
 | |
|     def _GetFdfFile(self):
 | |
|         if self._FlashDefinition is None:
 | |
|             if self._Header is None:
 | |
|                 self._GetHeaderInfo()
 | |
|             if self._FlashDefinition is None:
 | |
|                 self._FlashDefinition = ''
 | |
|         return self._FlashDefinition
 | |
| 
 | |
|     def _GetPrebuild(self):
 | |
|         if self._Prebuild is None:
 | |
|             if self._Header is None:
 | |
|                 self._GetHeaderInfo()
 | |
|             if self._Prebuild is None:
 | |
|                 self._Prebuild = ''
 | |
|         return self._Prebuild
 | |
| 
 | |
|     def _GetPostbuild(self):
 | |
|         if self._Postbuild is None:
 | |
|             if self._Header is None:
 | |
|                 self._GetHeaderInfo()
 | |
|             if self._Postbuild is None:
 | |
|                 self._Postbuild = ''
 | |
|         return self._Postbuild
 | |
| 
 | |
|     ## Retrieve FLASH_DEFINITION
 | |
|     def _GetBuildNumber(self):
 | |
|         if self._BuildNumber is None:
 | |
|             if self._Header is None:
 | |
|                 self._GetHeaderInfo()
 | |
|             if self._BuildNumber is None:
 | |
|                 self._BuildNumber = ''
 | |
|         return self._BuildNumber
 | |
| 
 | |
|     ## Retrieve MAKEFILE_NAME
 | |
|     def _GetMakefileName(self):
 | |
|         if self._MakefileName is None:
 | |
|             if self._Header is None:
 | |
|                 self._GetHeaderInfo()
 | |
|             if self._MakefileName is None:
 | |
|                 self._MakefileName = ''
 | |
|         return self._MakefileName
 | |
| 
 | |
|     ## Retrieve BsBaseAddress
 | |
|     def _GetBsBaseAddress(self):
 | |
|         if self._BsBaseAddress is None:
 | |
|             if self._Header is None:
 | |
|                 self._GetHeaderInfo()
 | |
|             if self._BsBaseAddress is None:
 | |
|                 self._BsBaseAddress = ''
 | |
|         return self._BsBaseAddress
 | |
| 
 | |
|     ## Retrieve RtBaseAddress
 | |
|     def _GetRtBaseAddress(self):
 | |
|         if self._RtBaseAddress is None:
 | |
|             if self._Header is None:
 | |
|                 self._GetHeaderInfo()
 | |
|             if self._RtBaseAddress is None:
 | |
|                 self._RtBaseAddress = ''
 | |
|         return self._RtBaseAddress
 | |
| 
 | |
|     ## Retrieve the top address for the load fix address
 | |
|     def _GetLoadFixAddress(self):
 | |
|         if self._LoadFixAddress is None:
 | |
|             if self._Header is None:
 | |
|                 self._GetHeaderInfo()
 | |
| 
 | |
|             if self._LoadFixAddress is None:
 | |
|                 self._LoadFixAddress = self._Macros.get(TAB_FIX_LOAD_TOP_MEMORY_ADDRESS, '0')
 | |
| 
 | |
|             try:
 | |
|                 self._LoadFixAddress = int (self._LoadFixAddress, 0)
 | |
|             except:
 | |
|                 EdkLogger.error("build", PARAMETER_INVALID, "FIX_LOAD_TOP_MEMORY_ADDRESS %s is not valid dec or hex string" % (self._LoadFixAddress))
 | |
| 
 | |
|         #
 | |
|         # If command line defined, should override the value in DSC file.
 | |
|         #
 | |
|         if 'FIX_LOAD_TOP_MEMORY_ADDRESS' in GlobalData.gCommandLineDefines.keys():
 | |
|             try:
 | |
|                 self._LoadFixAddress = int(GlobalData.gCommandLineDefines['FIX_LOAD_TOP_MEMORY_ADDRESS'], 0)
 | |
|             except:
 | |
|                 EdkLogger.error("build", PARAMETER_INVALID, "FIX_LOAD_TOP_MEMORY_ADDRESS %s is not valid dec or hex string" % (GlobalData.gCommandLineDefines['FIX_LOAD_TOP_MEMORY_ADDRESS']))
 | |
| 
 | |
|         if self._LoadFixAddress < 0:
 | |
|             EdkLogger.error("build", PARAMETER_INVALID, "FIX_LOAD_TOP_MEMORY_ADDRESS is set to the invalid negative value 0x%x" % (self._LoadFixAddress))
 | |
|         if self._LoadFixAddress != 0xFFFFFFFFFFFFFFFF and self._LoadFixAddress % 0x1000 != 0:
 | |
|             EdkLogger.error("build", PARAMETER_INVALID, "FIX_LOAD_TOP_MEMORY_ADDRESS is set to the invalid unaligned 4K value 0x%x" % (self._LoadFixAddress))
 | |
| 
 | |
|         return self._LoadFixAddress
 | |
| 
 | |
|     ## Retrieve RFCLanguage filter
 | |
|     def _GetRFCLanguages(self):
 | |
|         if self._RFCLanguages is None:
 | |
|             if self._Header is None:
 | |
|                 self._GetHeaderInfo()
 | |
|             if self._RFCLanguages is None:
 | |
|                 self._RFCLanguages = []
 | |
|         return self._RFCLanguages
 | |
| 
 | |
|     ## Retrieve ISOLanguage filter
 | |
|     def _GetISOLanguages(self):
 | |
|         if self._ISOLanguages is None:
 | |
|             if self._Header is None:
 | |
|                 self._GetHeaderInfo()
 | |
|             if self._ISOLanguages is None:
 | |
|                 self._ISOLanguages = []
 | |
|         return self._ISOLanguages
 | |
|     ## Retrieve the GUID string for VPD tool
 | |
|     def _GetVpdToolGuid(self):
 | |
|         if self._VpdToolGuid is None:
 | |
|             if self._Header is None:
 | |
|                 self._GetHeaderInfo()
 | |
|             if self._VpdToolGuid is None:
 | |
|                 self._VpdToolGuid = ''
 | |
|         return self._VpdToolGuid
 | |
| 
 | |
|     ## Retrieve [SkuIds] section information
 | |
|     def _GetSkuIds(self):
 | |
|         if self._SkuIds is None:
 | |
|             self._SkuIds = sdict()
 | |
|             RecordList = self._RawData[MODEL_EFI_SKU_ID, self._Arch]
 | |
|             for Record in RecordList:
 | |
|                 if Record[0] in [None, '']:
 | |
|                     EdkLogger.error('build', FORMAT_INVALID, 'No Sku ID number',
 | |
|                                     File=self.MetaFile, Line=Record[-1])
 | |
|                 if Record[1] in [None, '']:
 | |
|                     EdkLogger.error('build', FORMAT_INVALID, 'No Sku ID name',
 | |
|                                     File=self.MetaFile, Line=Record[-1])
 | |
|                 Pattern = re.compile('^[1-9]\d*|0$')
 | |
|                 HexPattern = re.compile(r'0[xX][0-9a-fA-F]+$')
 | |
|                 if Pattern.match(Record[0]) is None and HexPattern.match(Record[0]) is None:
 | |
|                     EdkLogger.error('build', FORMAT_INVALID, "The format of the Sku ID number is invalid. It only support Integer and HexNumber",
 | |
|                                     File=self.MetaFile, Line=Record[-1])
 | |
|                 if not IsValidWord(Record[1]):
 | |
|                     EdkLogger.error('build', FORMAT_INVALID, "The format of the Sku ID name is invalid. The correct format is '(a-zA-Z0-9_)(a-zA-Z0-9_-.)*'",
 | |
|                                     File=self.MetaFile, Line=Record[-1])
 | |
|                 self._SkuIds[Record[1].upper()] = (str(self.ToInt(Record[0])), Record[1].upper(), Record[2].upper())
 | |
|             if 'DEFAULT' not in self._SkuIds:
 | |
|                 self._SkuIds['DEFAULT'] = ("0","DEFAULT","DEFAULT")
 | |
|             if 'COMMON' not in self._SkuIds:
 | |
|                 self._SkuIds['COMMON'] = ("0","DEFAULT","DEFAULT")
 | |
|         return self._SkuIds
 | |
|     def ToInt(self,intstr):
 | |
|         return int(intstr,16) if intstr.upper().startswith("0X") else int(intstr)
 | |
|     def _GetDefaultStores(self):
 | |
|         if self.DefaultStores is None:
 | |
|             self.DefaultStores = sdict()
 | |
|             RecordList = self._RawData[MODEL_EFI_DEFAULT_STORES, self._Arch]
 | |
|             for Record in RecordList:
 | |
|                 if Record[0] in [None, '']:
 | |
|                     EdkLogger.error('build', FORMAT_INVALID, 'No DefaultStores ID number',
 | |
|                                     File=self.MetaFile, Line=Record[-1])
 | |
|                 if Record[1] in [None, '']:
 | |
|                     EdkLogger.error('build', FORMAT_INVALID, 'No DefaultStores ID name',
 | |
|                                     File=self.MetaFile, Line=Record[-1])
 | |
|                 Pattern = re.compile('^[1-9]\d*|0$')
 | |
|                 HexPattern = re.compile(r'0[xX][0-9a-fA-F]+$')
 | |
|                 if Pattern.match(Record[0]) is None and HexPattern.match(Record[0]) is None:
 | |
|                     EdkLogger.error('build', FORMAT_INVALID, "The format of the DefaultStores ID number is invalid. It only support Integer and HexNumber",
 | |
|                                     File=self.MetaFile, Line=Record[-1])
 | |
|                 if not IsValidWord(Record[1]):
 | |
|                     EdkLogger.error('build', FORMAT_INVALID, "The format of the DefaultStores ID name is invalid. The correct format is '(a-zA-Z0-9_)(a-zA-Z0-9_-.)*'",
 | |
|                                     File=self.MetaFile, Line=Record[-1])
 | |
|                 self.DefaultStores[Record[1].upper()] = (self.ToInt(Record[0]),Record[1].upper())
 | |
|             if TAB_DEFAULT_STORES_DEFAULT not in self.DefaultStores:
 | |
|                 self.DefaultStores[TAB_DEFAULT_STORES_DEFAULT] = (0,TAB_DEFAULT_STORES_DEFAULT)
 | |
|             GlobalData.gDefaultStores = self.DefaultStores.keys()
 | |
|             if GlobalData.gDefaultStores:
 | |
|                 GlobalData.gDefaultStores.sort()
 | |
|         return self.DefaultStores
 | |
| 
 | |
|     ## Retrieve [Components] section information
 | |
|     def _GetModules(self):
 | |
|         if self._Modules is not None:
 | |
|             return self._Modules
 | |
| 
 | |
|         self._Modules = sdict()
 | |
|         RecordList = self._RawData[MODEL_META_DATA_COMPONENT, self._Arch]
 | |
|         Macros = self._Macros
 | |
|         Macros["EDK_SOURCE"] = GlobalData.gEcpSource
 | |
|         for Record in RecordList:
 | |
|             DuplicatedFile = False
 | |
| 
 | |
|             ModuleFile = PathClass(NormPath(Record[0], Macros), GlobalData.gWorkspace, Arch=self._Arch)
 | |
|             ModuleId = Record[6]
 | |
|             LineNo = Record[7]
 | |
| 
 | |
|             # check the file validation
 | |
|             ErrorCode, ErrorInfo = ModuleFile.Validate('.inf')
 | |
|             if ErrorCode != 0:
 | |
|                 EdkLogger.error('build', ErrorCode, File=self.MetaFile, Line=LineNo,
 | |
|                                 ExtraData=ErrorInfo)
 | |
|             # Check duplication
 | |
|             # If arch is COMMON, no duplicate module is checked since all modules in all component sections are selected
 | |
|             if self._Arch != 'COMMON' and ModuleFile in self._Modules:
 | |
|                 DuplicatedFile = True
 | |
| 
 | |
|             Module = ModuleBuildClassObject()
 | |
|             Module.MetaFile = ModuleFile
 | |
| 
 | |
|             # get module private library instance
 | |
|             RecordList = self._RawData[MODEL_EFI_LIBRARY_CLASS, self._Arch, None, ModuleId]
 | |
|             for Record in RecordList:
 | |
|                 LibraryClass = Record[0]
 | |
|                 LibraryPath = PathClass(NormPath(Record[1], Macros), GlobalData.gWorkspace, Arch=self._Arch)
 | |
|                 LineNo = Record[-1]
 | |
| 
 | |
|                 # check the file validation
 | |
|                 ErrorCode, ErrorInfo = LibraryPath.Validate('.inf')
 | |
|                 if ErrorCode != 0:
 | |
|                     EdkLogger.error('build', ErrorCode, File=self.MetaFile, Line=LineNo,
 | |
|                                     ExtraData=ErrorInfo)
 | |
| 
 | |
|                 if LibraryClass == '' or LibraryClass == 'NULL':
 | |
|                     self._NullLibraryNumber += 1
 | |
|                     LibraryClass = 'NULL%d' % self._NullLibraryNumber
 | |
|                     EdkLogger.verbose("Found forced library for %s\n\t%s [%s]" % (ModuleFile, LibraryPath, LibraryClass))
 | |
|                 Module.LibraryClasses[LibraryClass] = LibraryPath
 | |
|                 if LibraryPath not in self.LibraryInstances:
 | |
|                     self.LibraryInstances.append(LibraryPath)
 | |
| 
 | |
|             # get module private PCD setting
 | |
|             for Type in [MODEL_PCD_FIXED_AT_BUILD, MODEL_PCD_PATCHABLE_IN_MODULE, \
 | |
|                          MODEL_PCD_FEATURE_FLAG, MODEL_PCD_DYNAMIC, MODEL_PCD_DYNAMIC_EX]:
 | |
|                 RecordList = self._RawData[Type, self._Arch, None, ModuleId]
 | |
|                 for TokenSpaceGuid, PcdCName, Setting, Dummy1, Dummy2, Dummy3, Dummy4,Dummy5 in RecordList:
 | |
|                     TokenList = GetSplitValueList(Setting)
 | |
|                     DefaultValue = TokenList[0]
 | |
|                     # the format is PcdName| Value | VOID* | MaxDatumSize
 | |
|                     if len(TokenList) > 2:
 | |
|                         MaxDatumSize = TokenList[2]
 | |
|                     else:
 | |
|                         MaxDatumSize = ''
 | |
|                     TypeString = self._PCD_TYPE_STRING_[Type]
 | |
|                     Pcd = PcdClassObject(
 | |
|                             PcdCName,
 | |
|                             TokenSpaceGuid,
 | |
|                             TypeString,
 | |
|                             '',
 | |
|                             DefaultValue,
 | |
|                             '',
 | |
|                             MaxDatumSize,
 | |
|                             {},
 | |
|                             False,
 | |
|                             None
 | |
|                             )
 | |
|                     Module.Pcds[PcdCName, TokenSpaceGuid] = Pcd
 | |
| 
 | |
|             # get module private build options
 | |
|             RecordList = self._RawData[MODEL_META_DATA_BUILD_OPTION, self._Arch, None, ModuleId]
 | |
|             for ToolChainFamily, ToolChain, Option, Dummy1, Dummy2, Dummy3, Dummy4,Dummy5 in RecordList:
 | |
|                 if (ToolChainFamily, ToolChain) not in Module.BuildOptions:
 | |
|                     Module.BuildOptions[ToolChainFamily, ToolChain] = Option
 | |
|                 else:
 | |
|                     OptionString = Module.BuildOptions[ToolChainFamily, ToolChain]
 | |
|                     Module.BuildOptions[ToolChainFamily, ToolChain] = OptionString + " " + Option
 | |
| 
 | |
|             RecordList = self._RawData[MODEL_META_DATA_HEADER, self._Arch, None, ModuleId]
 | |
|             if DuplicatedFile and not RecordList:
 | |
|                 EdkLogger.error('build', FILE_DUPLICATED, File=self.MetaFile, ExtraData=str(ModuleFile), Line=LineNo)
 | |
|             if RecordList:
 | |
|                 if len(RecordList) != 1:
 | |
|                     EdkLogger.error('build', OPTION_UNKNOWN, 'Only FILE_GUID can be listed in <Defines> section.',
 | |
|                                     File=self.MetaFile, ExtraData=str(ModuleFile), Line=LineNo)
 | |
|                 ModuleFile = ProcessDuplicatedInf(ModuleFile, RecordList[0][2], GlobalData.gWorkspace)
 | |
|                 ModuleFile.Arch = self._Arch
 | |
| 
 | |
|             self._Modules[ModuleFile] = Module
 | |
|         return self._Modules
 | |
| 
 | |
|     ## Retrieve all possible library instances used in this platform
 | |
|     def _GetLibraryInstances(self):
 | |
|         if self._LibraryInstances is None:
 | |
|             self._GetLibraryClasses()
 | |
|         return self._LibraryInstances
 | |
| 
 | |
|     ## Retrieve [LibraryClasses] information
 | |
|     def _GetLibraryClasses(self):
 | |
|         if self._LibraryClasses is None:
 | |
|             self._LibraryInstances = []
 | |
|             #
 | |
|             # tdict is a special dict kind of type, used for selecting correct
 | |
|             # library instance for given library class and module type
 | |
|             #
 | |
|             LibraryClassDict = tdict(True, 3)
 | |
|             # track all library class names
 | |
|             LibraryClassSet = set()
 | |
|             RecordList = self._RawData[MODEL_EFI_LIBRARY_CLASS, self._Arch, None, -1]
 | |
|             Macros = self._Macros
 | |
|             for Record in RecordList:
 | |
|                 LibraryClass, LibraryInstance, Dummy, Arch, ModuleType, Dummy,Dummy, LineNo = Record
 | |
|                 if LibraryClass == '' or LibraryClass == 'NULL':
 | |
|                     self._NullLibraryNumber += 1
 | |
|                     LibraryClass = 'NULL%d' % self._NullLibraryNumber
 | |
|                     EdkLogger.verbose("Found forced library for arch=%s\n\t%s [%s]" % (Arch, LibraryInstance, LibraryClass))
 | |
|                 LibraryClassSet.add(LibraryClass)
 | |
|                 LibraryInstance = PathClass(NormPath(LibraryInstance, Macros), GlobalData.gWorkspace, Arch=self._Arch)
 | |
|                 # check the file validation
 | |
|                 ErrorCode, ErrorInfo = LibraryInstance.Validate('.inf')
 | |
|                 if ErrorCode != 0:
 | |
|                     EdkLogger.error('build', ErrorCode, File=self.MetaFile, Line=LineNo,
 | |
|                                     ExtraData=ErrorInfo)
 | |
| 
 | |
|                 if ModuleType != 'COMMON' and ModuleType not in SUP_MODULE_LIST:
 | |
|                     EdkLogger.error('build', OPTION_UNKNOWN, "Unknown module type [%s]" % ModuleType,
 | |
|                                     File=self.MetaFile, ExtraData=LibraryInstance, Line=LineNo)
 | |
|                 LibraryClassDict[Arch, ModuleType, LibraryClass] = LibraryInstance
 | |
|                 if LibraryInstance not in self._LibraryInstances:
 | |
|                     self._LibraryInstances.append(LibraryInstance)
 | |
| 
 | |
|             # resolve the specific library instance for each class and each module type
 | |
|             self._LibraryClasses = tdict(True)
 | |
|             for LibraryClass in LibraryClassSet:
 | |
|                 # try all possible module types
 | |
|                 for ModuleType in SUP_MODULE_LIST:
 | |
|                     LibraryInstance = LibraryClassDict[self._Arch, ModuleType, LibraryClass]
 | |
|                     if LibraryInstance is None:
 | |
|                         continue
 | |
|                     self._LibraryClasses[LibraryClass, ModuleType] = LibraryInstance
 | |
| 
 | |
|             # for Edk style library instances, which are listed in different section
 | |
|             Macros["EDK_SOURCE"] = GlobalData.gEcpSource
 | |
|             RecordList = self._RawData[MODEL_EFI_LIBRARY_INSTANCE, self._Arch]
 | |
|             for Record in RecordList:
 | |
|                 File = PathClass(NormPath(Record[0], Macros), GlobalData.gWorkspace, Arch=self._Arch)
 | |
|                 LineNo = Record[-1]
 | |
|                 # check the file validation
 | |
|                 ErrorCode, ErrorInfo = File.Validate('.inf')
 | |
|                 if ErrorCode != 0:
 | |
|                     EdkLogger.error('build', ErrorCode, File=self.MetaFile, Line=LineNo,
 | |
|                                     ExtraData=ErrorInfo)
 | |
|                 if File not in self._LibraryInstances:
 | |
|                     self._LibraryInstances.append(File)
 | |
|                 #
 | |
|                 # we need the module name as the library class name, so we have
 | |
|                 # to parse it here. (self._Bdb[] will trigger a file parse if it
 | |
|                 # hasn't been parsed)
 | |
|                 #
 | |
|                 Library = self._Bdb[File, self._Arch, self._Target, self._Toolchain]
 | |
|                 self._LibraryClasses[Library.BaseName, ':dummy:'] = Library
 | |
|         return self._LibraryClasses
 | |
| 
 | |
|     def _ValidatePcd(self, PcdCName, TokenSpaceGuid, Setting, PcdType, LineNo):
 | |
|         if self._DecPcds is None:
 | |
| 
 | |
|             FdfInfList = []
 | |
|             if GlobalData.gFdfParser:
 | |
|                 FdfInfList = GlobalData.gFdfParser.Profile.InfList
 | |
| 
 | |
|             PkgSet = set()
 | |
|             for Inf in FdfInfList:
 | |
|                 ModuleFile = PathClass(NormPath(Inf), GlobalData.gWorkspace, Arch=self._Arch)
 | |
|                 if ModuleFile in self._Modules:
 | |
|                     continue
 | |
|                 ModuleData = self._Bdb[ModuleFile, self._Arch, self._Target, self._Toolchain]
 | |
|                 PkgSet.update(ModuleData.Packages)
 | |
| 
 | |
|             self._DecPcds, self._GuidDict = GetDeclaredPcd(self, self._Bdb, self._Arch, self._Target, self._Toolchain,PkgSet)
 | |
|             self._GuidDict.update(GlobalData.gPlatformPcds)
 | |
| 
 | |
|         if (PcdCName, TokenSpaceGuid) not in self._DecPcds:
 | |
|             EdkLogger.error('build', PARSER_ERROR,
 | |
|                             "Pcd (%s.%s) defined in DSC is not declared in DEC files. Arch: ['%s']" % (TokenSpaceGuid, PcdCName, self._Arch),
 | |
|                             File=self.MetaFile, Line=LineNo)
 | |
|         ValueList, IsValid, Index = AnalyzeDscPcd(Setting, PcdType, self._DecPcds[PcdCName, TokenSpaceGuid].DatumType)
 | |
|         if not IsValid:
 | |
|             if PcdType not in [MODEL_PCD_FEATURE_FLAG, MODEL_PCD_FIXED_AT_BUILD]:
 | |
|                 EdkLogger.error('build', FORMAT_INVALID, "Pcd format incorrect.", File=self.MetaFile, Line=LineNo,
 | |
|                                 ExtraData="%s.%s|%s" % (TokenSpaceGuid, PcdCName, Setting))
 | |
|             else:
 | |
|                 if ValueList[2] == '-1':
 | |
|                     EdkLogger.error('build', FORMAT_INVALID, "Pcd format incorrect.", File=self.MetaFile, Line=LineNo,
 | |
|                                 ExtraData="%s.%s|%s" % (TokenSpaceGuid, PcdCName, Setting))
 | |
|         if ValueList[Index]:
 | |
|             DatumType = self._DecPcds[PcdCName, TokenSpaceGuid].DatumType
 | |
|             try:
 | |
|                 ValueList[Index] = ValueExpressionEx(ValueList[Index], DatumType, self._GuidDict)(True)
 | |
|             except BadExpression, Value:
 | |
|                 EdkLogger.error('Parser', FORMAT_INVALID, Value, File=self.MetaFile, Line=LineNo,
 | |
|                                 ExtraData="PCD [%s.%s] Value \"%s\" " % (
 | |
|                                 TokenSpaceGuid, PcdCName, ValueList[Index]))
 | |
|             except EvaluationException, Excpt:
 | |
|                 if hasattr(Excpt, 'Pcd'):
 | |
|                     if Excpt.Pcd in GlobalData.gPlatformOtherPcds:
 | |
|                         EdkLogger.error('Parser', FORMAT_INVALID, "Cannot use this PCD (%s) in an expression as"
 | |
|                                         " it must be defined in a [PcdsFixedAtBuild] or [PcdsFeatureFlag] section"
 | |
|                                         " of the DSC file" % Excpt.Pcd,
 | |
|                                         File=self.MetaFile, Line=LineNo)
 | |
|                     else:
 | |
|                         EdkLogger.error('Parser', FORMAT_INVALID, "PCD (%s) is not defined in DSC file" % Excpt.Pcd,
 | |
|                                         File=self.MetaFile, Line=LineNo)
 | |
|                 else:
 | |
|                     EdkLogger.error('Parser', FORMAT_INVALID, "Invalid expression: %s" % str(Excpt),
 | |
|                                     File=self.MetaFile, Line=LineNo)
 | |
| 
 | |
|         if ValueList[Index]:
 | |
|             Valid, ErrStr = CheckPcdDatum(self._DecPcds[PcdCName, TokenSpaceGuid].DatumType, ValueList[Index])
 | |
|             if not Valid:
 | |
|                 EdkLogger.error('build', FORMAT_INVALID, ErrStr, File=self.MetaFile, Line=LineNo,
 | |
|                                 ExtraData="%s.%s" % (TokenSpaceGuid, PcdCName))
 | |
|             if PcdType in (MODEL_PCD_DYNAMIC_DEFAULT, MODEL_PCD_DYNAMIC_EX_DEFAULT):
 | |
|                 if self._DecPcds[PcdCName, TokenSpaceGuid].DatumType.strip() != ValueList[1].strip():
 | |
|                     EdkLogger.error('build', FORMAT_INVALID, "Pcd datumtype used in DSC file is not the same as its declaration in DEC file." , File=self.MetaFile, Line=LineNo,
 | |
|                                 ExtraData="%s.%s|%s" % (TokenSpaceGuid, PcdCName, Setting))
 | |
|         if (TokenSpaceGuid + '.' + PcdCName) in GlobalData.gPlatformPcds:
 | |
|             if GlobalData.gPlatformPcds[TokenSpaceGuid + '.' + PcdCName] != ValueList[Index]:
 | |
|                 GlobalData.gPlatformPcds[TokenSpaceGuid + '.' + PcdCName] = ValueList[Index]
 | |
|         return ValueList
 | |
| 
 | |
|     def _FilterPcdBySkuUsage(self,Pcds):
 | |
|         available_sku = self.SkuIdMgr.AvailableSkuIdSet
 | |
|         sku_usage = self.SkuIdMgr.SkuUsageType
 | |
|         if sku_usage == SkuClass.SINGLE:
 | |
|             for pcdname in Pcds:
 | |
|                 pcd = Pcds[pcdname]
 | |
|                 Pcds[pcdname].SkuInfoList = {"DEFAULT":pcd.SkuInfoList[skuid] for skuid in pcd.SkuInfoList if skuid in available_sku}
 | |
|                 if type(pcd) is StructurePcd and pcd.SkuOverrideValues:
 | |
|                     Pcds[pcdname].SkuOverrideValues = {"DEFAULT":pcd.SkuOverrideValues[skuid] for skuid in pcd.SkuOverrideValues if skuid in available_sku}
 | |
|         else:
 | |
|             for pcdname in Pcds:
 | |
|                 pcd = Pcds[pcdname]
 | |
|                 Pcds[pcdname].SkuInfoList = {skuid:pcd.SkuInfoList[skuid] for skuid in pcd.SkuInfoList if skuid in available_sku}
 | |
|                 if type(pcd) is StructurePcd and pcd.SkuOverrideValues:
 | |
|                     Pcds[pcdname].SkuOverrideValues = {skuid:pcd.SkuOverrideValues[skuid] for skuid in pcd.SkuOverrideValues if skuid in available_sku}
 | |
|         return Pcds
 | |
|     def CompleteHiiPcdsDefaultStores(self,Pcds):
 | |
|         HiiPcd = [Pcds[pcd] for pcd in Pcds if Pcds[pcd].Type in [self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII], self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_HII]]]
 | |
|         DefaultStoreMgr = DefaultStore(self.DefaultStores)
 | |
|         for pcd in HiiPcd:
 | |
|             for skuid in pcd.SkuInfoList:
 | |
|                 skuobj = pcd.SkuInfoList.get(skuid)
 | |
|                 if "STANDARD" not in skuobj.DefaultStoreDict:
 | |
|                     PcdDefaultStoreSet = set([defaultstorename  for defaultstorename in skuobj.DefaultStoreDict])
 | |
|                     mindefaultstorename = DefaultStoreMgr.GetMin(PcdDefaultStoreSet)
 | |
|                     skuobj.DefaultStoreDict['STANDARD'] = copy.deepcopy(skuobj.DefaultStoreDict[mindefaultstorename])
 | |
|         return Pcds
 | |
| 
 | |
|     def RecoverCommandLinePcd(self):
 | |
|         def UpdateCommandLineValue(pcd):
 | |
|             if pcd.Type in [self._PCD_TYPE_STRING_[MODEL_PCD_FIXED_AT_BUILD],
 | |
|                                         self._PCD_TYPE_STRING_[MODEL_PCD_PATCHABLE_IN_MODULE]]:
 | |
|                 pcd.PcdValueFromComm = pcd.DefaultValue
 | |
|             elif pcd.Type in [self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII], self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_HII]]:
 | |
|                 pcd.PcdValueFromComm = pcd.SkuInfoList.get("DEFAULT").HiiDefaultValue
 | |
|             else:
 | |
|                 pcd.PcdValueFromComm = pcd.SkuInfoList.get("DEFAULT").DefaultValue
 | |
|         for pcd in self._Pcds:
 | |
|             if isinstance(self._Pcds[pcd],StructurePcd) and (self._Pcds[pcd].PcdValueFromComm or self._Pcds[pcd].PcdFieldValueFromComm):
 | |
|                 UpdateCommandLineValue(self._Pcds[pcd])
 | |
| 
 | |
|     def __ParsePcdFromCommandLine(self):
 | |
|         if GlobalData.BuildOptionPcd:
 | |
|             for i, pcd in enumerate(GlobalData.BuildOptionPcd):
 | |
|                 if type(pcd) is tuple:
 | |
|                     continue
 | |
|                 (pcdname, pcdvalue) = pcd.split('=')
 | |
|                 if not pcdvalue:
 | |
|                     EdkLogger.error('build', AUTOGEN_ERROR, "No Value specified for the PCD %s." % (pcdname))
 | |
|                 if '.' in pcdname:
 | |
|                     (Name1, Name2) = pcdname.split('.',1)
 | |
|                     if "." in Name2:
 | |
|                         (Name3, FieldName) = Name2.split(".",1)
 | |
|                         if ((Name3,Name1)) in self.DecPcds:
 | |
|                             HasTokenSpace = True
 | |
|                             TokenCName = Name3
 | |
|                             TokenSpaceGuidCName = Name1
 | |
|                         else:
 | |
|                             FieldName = Name2
 | |
|                             TokenCName = Name1
 | |
|                             TokenSpaceGuidCName = ''
 | |
|                             HasTokenSpace = False
 | |
|                     else:
 | |
|                         if ((Name2,Name1)) in self.DecPcds:
 | |
|                             HasTokenSpace = True
 | |
|                             TokenCName = Name2
 | |
|                             TokenSpaceGuidCName = Name1
 | |
|                             FieldName =""
 | |
|                         else:
 | |
|                             FieldName = Name2
 | |
|                             TokenCName = Name1
 | |
|                             TokenSpaceGuidCName = ''
 | |
|                             HasTokenSpace = False
 | |
|                 else:
 | |
|                     FieldName = ""
 | |
|                     TokenCName = pcdname
 | |
|                     TokenSpaceGuidCName = ''
 | |
|                     HasTokenSpace = False
 | |
|                 TokenSpaceGuidCNameList = []
 | |
|                 FoundFlag = False
 | |
|                 PcdDatumType = ''
 | |
|                 DisplayName = TokenCName
 | |
|                 if FieldName:
 | |
|                     DisplayName = TokenCName + '.' + FieldName
 | |
|                 if not HasTokenSpace:
 | |
|                     for key in self.DecPcds:
 | |
|                         PcdItem = self.DecPcds[key]
 | |
|                         if TokenCName == PcdItem.TokenCName:
 | |
|                             if not PcdItem.TokenSpaceGuidCName in TokenSpaceGuidCNameList:
 | |
|                                 if len (TokenSpaceGuidCNameList) < 1:
 | |
|                                     TokenSpaceGuidCNameList.append(PcdItem.TokenSpaceGuidCName)
 | |
|                                     TokenSpaceGuidCName = PcdItem.TokenSpaceGuidCName
 | |
|                                     PcdDatumType = PcdItem.DatumType
 | |
|                                     FoundFlag = True
 | |
|                                 else:
 | |
|                                     EdkLogger.error(
 | |
|                                             'build',
 | |
|                                              AUTOGEN_ERROR,
 | |
|                                             "The Pcd %s is found under multiple different TokenSpaceGuid: %s and %s." % (DisplayName, PcdItem.TokenSpaceGuidCName, TokenSpaceGuidCNameList[0])
 | |
|                                             )
 | |
|                 else:
 | |
|                     if (TokenCName, TokenSpaceGuidCName) in self.DecPcds:
 | |
|                         PcdDatumType = self.DecPcds[(TokenCName, TokenSpaceGuidCName)].DatumType
 | |
|                         FoundFlag = True
 | |
|                 if not FoundFlag:
 | |
|                     if HasTokenSpace:
 | |
|                         EdkLogger.error('build', AUTOGEN_ERROR, "The Pcd %s.%s is not found in the DEC file." % (TokenSpaceGuidCName, DisplayName))
 | |
|                     else:
 | |
|                         EdkLogger.error('build', AUTOGEN_ERROR, "The Pcd %s is not found in the DEC file." % (DisplayName))
 | |
|                 pcdvalue = pcdvalue.replace("\\\\\\'", '\\\\\\"').replace('\\\'', '\'').replace('\\\\\\"', "\\'")
 | |
|                 if FieldName:
 | |
|                     pcdvalue = self.HandleFlexiblePcd(TokenSpaceGuidCName, TokenCName, pcdvalue, PcdDatumType, self._GuidDict, FieldName)
 | |
|                 else:
 | |
|                     pcdvalue = self.HandleFlexiblePcd(TokenSpaceGuidCName, TokenCName, pcdvalue, PcdDatumType, self._GuidDict)
 | |
|                     IsValid, Cause = CheckPcdDatum(PcdDatumType, pcdvalue)
 | |
|                     if not IsValid:
 | |
|                         EdkLogger.error("build", FORMAT_INVALID, Cause, ExtraData="%s.%s" % (TokenSpaceGuidCName, TokenCName))
 | |
|                 GlobalData.BuildOptionPcd[i] = (TokenSpaceGuidCName, TokenCName, FieldName, pcdvalue,("build command options",1))
 | |
| 
 | |
|                 for BuildData in self._Bdb._CACHE_.values():
 | |
|                     if BuildData.MetaFile.Ext == '.dec' or BuildData.MetaFile.Ext == '.dsc':
 | |
|                         continue
 | |
|                     for key in BuildData.Pcds:
 | |
|                         PcdItem = BuildData.Pcds[key]
 | |
|                         if (TokenSpaceGuidCName, TokenCName) == (PcdItem.TokenSpaceGuidCName, PcdItem.TokenCName) and FieldName =="":
 | |
|                             PcdItem.DefaultValue = pcdvalue
 | |
| 
 | |
|     def HandleFlexiblePcd(self, TokenSpaceGuidCName, TokenCName, PcdValue, PcdDatumType, GuidDict, FieldName=''):
 | |
|         if FieldName:
 | |
|             IsArray = False
 | |
|             TokenCName += '.' + FieldName
 | |
|         if PcdValue.startswith('H'):
 | |
|             if FieldName and IsFieldValueAnArray(PcdValue[1:]):
 | |
|                 PcdDatumType = 'VOID*'
 | |
|                 IsArray = True
 | |
|             if FieldName and not IsArray:
 | |
|                 return PcdValue
 | |
|             try:
 | |
|                 PcdValue = ValueExpressionEx(PcdValue[1:], PcdDatumType, GuidDict)(True)
 | |
|             except BadExpression, Value:     
 | |
|                 EdkLogger.error('Parser', FORMAT_INVALID, 'PCD [%s.%s] Value "%s",  %s' %
 | |
|                                 (TokenSpaceGuidCName, TokenCName, PcdValue, Value))
 | |
|         elif PcdValue.startswith("L'") or PcdValue.startswith("'"):
 | |
|             if FieldName and IsFieldValueAnArray(PcdValue):
 | |
|                 PcdDatumType = 'VOID*'
 | |
|                 IsArray = True
 | |
|             if FieldName and not IsArray:
 | |
|                 return PcdValue
 | |
|             try:
 | |
|                 PcdValue = ValueExpressionEx(PcdValue, PcdDatumType, GuidDict)(True)
 | |
|             except BadExpression, Value:
 | |
|                 EdkLogger.error('Parser', FORMAT_INVALID, 'PCD [%s.%s] Value "%s",  %s' %
 | |
|                                 (TokenSpaceGuidCName, TokenCName, PcdValue, Value))
 | |
|         elif PcdValue.startswith('L'):
 | |
|             PcdValue = 'L"' + PcdValue[1:] + '"'
 | |
|             if FieldName and IsFieldValueAnArray(PcdValue):
 | |
|                 PcdDatumType = 'VOID*'
 | |
|                 IsArray = True
 | |
|             if FieldName and not IsArray:
 | |
|                 return PcdValue
 | |
|             try:
 | |
|                 PcdValue = ValueExpressionEx(PcdValue, PcdDatumType, GuidDict)(True)
 | |
|             except BadExpression, Value:
 | |
|                 EdkLogger.error('Parser', FORMAT_INVALID, 'PCD [%s.%s] Value "%s",  %s' %
 | |
|                                 (TokenSpaceGuidCName, TokenCName, PcdValue, Value))
 | |
|         else:
 | |
|             if PcdValue.upper() == 'FALSE':
 | |
|                 PcdValue = str(0)
 | |
|             if PcdValue.upper() == 'TRUE':
 | |
|                 PcdValue = str(1)
 | |
|             if not FieldName:
 | |
|                 if PcdDatumType not in ['UINT8','UINT16','UINT32','UINT64','BOOLEAN']:
 | |
|                     PcdValue = '"' + PcdValue + '"'
 | |
|             else:
 | |
|                 IsArray = False
 | |
|                 Base = 10
 | |
|                 if PcdValue.upper().startswith('0X'):
 | |
|                     Base = 16
 | |
|                 try:
 | |
|                     Num = int(PcdValue, Base)
 | |
|                 except:
 | |
|                     PcdValue = '"' + PcdValue + '"'
 | |
|                 if IsFieldValueAnArray(PcdValue):
 | |
|                     PcdDatumType = 'VOID*'
 | |
|                     IsArray = True
 | |
|                 if not IsArray:
 | |
|                     return PcdValue
 | |
|             try:
 | |
|                 PcdValue = ValueExpressionEx(PcdValue, PcdDatumType, GuidDict)(True)
 | |
|             except BadExpression, Value:
 | |
|                 EdkLogger.error('Parser', FORMAT_INVALID, 'PCD [%s.%s] Value "%s",  %s' %
 | |
|                                 (TokenSpaceGuidCName, TokenCName, PcdValue, Value))
 | |
|         return PcdValue
 | |
| 
 | |
|     ## Retrieve all PCD settings in platform
 | |
|     def _GetPcds(self):
 | |
|         if self._Pcds is None:
 | |
|             self._Pcds = sdict()
 | |
|             self.__ParsePcdFromCommandLine()
 | |
|             self._Pcds.update(self._GetPcd(MODEL_PCD_FIXED_AT_BUILD))
 | |
|             self._Pcds.update(self._GetPcd(MODEL_PCD_PATCHABLE_IN_MODULE))
 | |
|             self._Pcds.update(self._GetPcd(MODEL_PCD_FEATURE_FLAG))
 | |
|             self._Pcds.update(self._GetDynamicPcd(MODEL_PCD_DYNAMIC_DEFAULT))
 | |
|             self._Pcds.update(self._GetDynamicHiiPcd(MODEL_PCD_DYNAMIC_HII))
 | |
|             self._Pcds.update(self._GetDynamicVpdPcd(MODEL_PCD_DYNAMIC_VPD))
 | |
|             self._Pcds.update(self._GetDynamicPcd(MODEL_PCD_DYNAMIC_EX_DEFAULT))
 | |
|             self._Pcds.update(self._GetDynamicHiiPcd(MODEL_PCD_DYNAMIC_EX_HII))
 | |
|             self._Pcds.update(self._GetDynamicVpdPcd(MODEL_PCD_DYNAMIC_EX_VPD))
 | |
| 
 | |
|             self._Pcds = self.CompletePcdValues(self._Pcds)
 | |
|             self._Pcds = self.OverrideByFdfCommOverAll(self._Pcds)
 | |
|             self._Pcds = self.UpdateStructuredPcds(MODEL_PCD_TYPE_LIST, self._Pcds)
 | |
|             self._Pcds = self.CompleteHiiPcdsDefaultStores(self._Pcds)
 | |
|             self._Pcds = self._FilterPcdBySkuUsage(self._Pcds)
 | |
| 
 | |
|             self.RecoverCommandLinePcd()
 | |
|         return self._Pcds
 | |
| 
 | |
|     def _dumpPcdInfo(self,Pcds):
 | |
|         for pcd in Pcds:
 | |
|             pcdobj = Pcds[pcd]
 | |
|             if not pcdobj.TokenCName.startswith("Test"):
 | |
|                 continue
 | |
|             for skuid in pcdobj.SkuInfoList:
 | |
|                 if pcdobj.Type in (self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII],self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_HII]):
 | |
|                     for storename in pcdobj.SkuInfoList[skuid].DefaultStoreDict:
 | |
|                         print "PcdCName: %s, SkuName: %s, StoreName: %s, Value: %s" % (".".join((pcdobj.TokenSpaceGuidCName, pcdobj.TokenCName)), skuid,storename,str(pcdobj.SkuInfoList[skuid].DefaultStoreDict[storename]))
 | |
|                 else:
 | |
|                     print "PcdCName: %s, SkuName: %s, Value: %s" % (".".join((pcdobj.TokenSpaceGuidCName, pcdobj.TokenCName)), skuid,str(pcdobj.SkuInfoList[skuid].DefaultValue))
 | |
|     ## Retrieve [BuildOptions]
 | |
|     def _GetBuildOptions(self):
 | |
|         if self._BuildOptions is None:
 | |
|             self._BuildOptions = sdict()
 | |
|             #
 | |
|             # Retrieve build option for EDKII and EDK style module
 | |
|             #
 | |
|             for CodeBase in (EDKII_NAME, EDK_NAME):
 | |
|                 RecordList = self._RawData[MODEL_META_DATA_BUILD_OPTION, self._Arch, CodeBase]
 | |
|                 for ToolChainFamily, ToolChain, Option, Dummy1, Dummy2, Dummy3, Dummy4,Dummy5 in RecordList:
 | |
|                     if Dummy3.upper() != 'COMMON':
 | |
|                         continue
 | |
|                     CurKey = (ToolChainFamily, ToolChain, CodeBase)
 | |
|                     #
 | |
|                     # Only flags can be appended
 | |
|                     #
 | |
|                     if CurKey not in self._BuildOptions or not ToolChain.endswith('_FLAGS') or Option.startswith('='):
 | |
|                         self._BuildOptions[CurKey] = Option
 | |
|                     else:
 | |
|                         if ' ' + Option not in self._BuildOptions[CurKey]:
 | |
|                             self._BuildOptions[CurKey] += ' ' + Option
 | |
|         return self._BuildOptions
 | |
| 
 | |
|     def GetBuildOptionsByModuleType(self, Edk, ModuleType):
 | |
|         if self._ModuleTypeOptions is None:
 | |
|             self._ModuleTypeOptions = sdict()
 | |
|         if (Edk, ModuleType) not in self._ModuleTypeOptions:
 | |
|             options = sdict()
 | |
|             self._ModuleTypeOptions[Edk, ModuleType] = options
 | |
|             DriverType = '%s.%s' % (Edk, ModuleType)
 | |
|             CommonDriverType = '%s.%s' % ('COMMON', ModuleType)
 | |
|             RecordList = self._RawData[MODEL_META_DATA_BUILD_OPTION, self._Arch]
 | |
|             for ToolChainFamily, ToolChain, Option, Dummy1, Dummy2, Dummy3, Dummy4,Dummy5 in RecordList:
 | |
|                 Type = Dummy2 + '.' + Dummy3
 | |
|                 if Type.upper() == DriverType.upper() or Type.upper() == CommonDriverType.upper():
 | |
|                     Key = (ToolChainFamily, ToolChain, Edk)
 | |
|                     if Key not in options or not ToolChain.endswith('_FLAGS') or Option.startswith('='):
 | |
|                         options[Key] = Option
 | |
|                     else:
 | |
|                         if ' ' + Option not in options[Key]:
 | |
|                             options[Key] += ' ' + Option
 | |
|         return self._ModuleTypeOptions[Edk, ModuleType]
 | |
| 
 | |
|     def GetStructurePcdInfo(self, PcdSet):
 | |
|         structure_pcd_data = {}
 | |
|         for item in PcdSet:
 | |
|             if (item[0],item[1]) not in structure_pcd_data:
 | |
|                 structure_pcd_data[(item[0],item[1])] = []
 | |
|             structure_pcd_data[(item[0],item[1])].append(item)
 | |
| 
 | |
|         return structure_pcd_data
 | |
|     def OverrideByFdfComm(self,StruPcds):
 | |
|         StructurePcdInCom = OrderedDict()
 | |
|         for item in GlobalData.BuildOptionPcd:
 | |
|             if len(item) == 5 and (item[1],item[0]) in StruPcds:
 | |
|                 StructurePcdInCom[(item[0],item[1],item[2] )] = (item[3],item[4])
 | |
|         GlobalPcds = set([(item[0],item[1]) for item in StructurePcdInCom.keys()])
 | |
|         for Pcd in StruPcds.values():
 | |
|             if (Pcd.TokenSpaceGuidCName,Pcd.TokenCName) not in GlobalPcds:
 | |
|                 continue
 | |
|             FieldValues = OrderedDict()
 | |
|             for item in StructurePcdInCom:
 | |
|                 if (Pcd.TokenSpaceGuidCName,Pcd.TokenCName) == (item[0],item[1]) and item[2]:
 | |
|                     FieldValues[item[2]] = StructurePcdInCom[item]
 | |
|             for field in FieldValues:
 | |
|                 if field not in Pcd.PcdFieldValueFromComm:
 | |
|                     Pcd.PcdFieldValueFromComm[field] = ["","",""]
 | |
|                 Pcd.PcdFieldValueFromComm[field][0] = FieldValues[field][0]
 | |
|                 Pcd.PcdFieldValueFromComm[field][1] = FieldValues[field][1][0]
 | |
|                 Pcd.PcdFieldValueFromComm[field][2] = FieldValues[field][1][1]
 | |
|         return StruPcds
 | |
|     def OverrideByFdfCommOverAll(self,AllPcds):
 | |
|         def CheckStructureInComm(commpcds):
 | |
|             if not commpcds:
 | |
|                 return False
 | |
|             if len(commpcds[0]) == 5:
 | |
|                 return True
 | |
|             return False
 | |
| 
 | |
|         if CheckStructureInComm(GlobalData.BuildOptionPcd):
 | |
|             StructurePcdInCom = {(item[0],item[1],item[2] ):(item[3],item[4]) for item in GlobalData.BuildOptionPcd } if GlobalData.BuildOptionPcd else {}
 | |
|             NoFiledValues = {(item[0],item[1]):StructurePcdInCom[item] for item in StructurePcdInCom if not item[2]}
 | |
|         else:
 | |
|             NoFiledValues = {(item[0],item[1]):[item[2]] for item in GlobalData.BuildOptionPcd}
 | |
|         for Guid,Name in NoFiledValues:
 | |
|             if (Name,Guid) in AllPcds:
 | |
|                 Pcd = AllPcds.get((Name,Guid))
 | |
|                 if isinstance(self._DecPcds.get((Pcd.TokenCName,Pcd.TokenSpaceGuidCName), None),StructurePcd):
 | |
|                     self._DecPcds.get((Pcd.TokenCName,Pcd.TokenSpaceGuidCName)).PcdValueFromComm = NoFiledValues[(Pcd.TokenSpaceGuidCName,Pcd.TokenCName)][0]
 | |
|                 else:
 | |
|                     Pcd.PcdValueFromComm = NoFiledValues[(Pcd.TokenSpaceGuidCName,Pcd.TokenCName)][0]
 | |
|                     Pcd.DefaultValue = NoFiledValues[(Pcd.TokenSpaceGuidCName,Pcd.TokenCName)][0]
 | |
|                     for sku in Pcd.SkuInfoList:
 | |
|                         SkuInfo = Pcd.SkuInfoList[sku]
 | |
|                         if SkuInfo.DefaultValue:
 | |
|                             SkuInfo.DefaultValue = NoFiledValues[(Pcd.TokenSpaceGuidCName,Pcd.TokenCName)][0]
 | |
|                         else:
 | |
|                             SkuInfo.HiiDefaultValue = NoFiledValues[(Pcd.TokenSpaceGuidCName,Pcd.TokenCName)][0]
 | |
|                             for defaultstore in SkuInfo.DefaultStoreDict:
 | |
|                                 SkuInfo.DefaultStoreDict[defaultstore] = NoFiledValues[(Pcd.TokenSpaceGuidCName,Pcd.TokenCName)][0]
 | |
|                     if Pcd.Type in [self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_HII], self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII]]:
 | |
|                         if Pcd.DatumType == "VOID*":
 | |
|                             if not Pcd.MaxDatumSize:
 | |
|                                 Pcd.MaxDatumSize = '0'
 | |
|                             CurrentSize = int(Pcd.MaxDatumSize,16) if Pcd.MaxDatumSize.upper().startswith("0X") else int(Pcd.MaxDatumSize)
 | |
|                             OptionSize = len((StringToArray(Pcd.PcdValueFromComm)).split(","))
 | |
|                             MaxSize = max(CurrentSize, OptionSize)
 | |
|                             Pcd.MaxDatumSize = str(MaxSize)
 | |
|             else:
 | |
|                 PcdInDec = self.DecPcds.get((Name,Guid))
 | |
|                 if PcdInDec:
 | |
|                     PcdInDec.PcdValueFromComm = NoFiledValues[(Guid,Name)][0]
 | |
|                     if PcdInDec.Type in [self._PCD_TYPE_STRING_[MODEL_PCD_FIXED_AT_BUILD],
 | |
|                                         self._PCD_TYPE_STRING_[MODEL_PCD_PATCHABLE_IN_MODULE],
 | |
|                                         self._PCD_TYPE_STRING_[MODEL_PCD_FEATURE_FLAG]]:
 | |
|                         self.Pcds[Name, Guid] = copy.deepcopy(PcdInDec)
 | |
|                         self.Pcds[Name, Guid].DefaultValue = NoFiledValues[( Guid,Name)][0]
 | |
|         return AllPcds
 | |
|     def UpdateStructuredPcds(self, TypeList, AllPcds):
 | |
| 
 | |
|         DynamicPcdType = [self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_DEFAULT],
 | |
|                         self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII],
 | |
|                         self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_VPD],
 | |
|                         self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_DEFAULT],
 | |
|                         self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_HII],
 | |
|                         self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_VPD]]
 | |
| 
 | |
|         Pcds = AllPcds
 | |
|         DefaultStoreMgr = DefaultStore(self.DefaultStores)
 | |
|         SkuIds = self.SkuIdMgr.AvailableSkuIdSet
 | |
|         SkuIds.update({'DEFAULT':0})
 | |
|         DefaultStores = set([storename for pcdobj in AllPcds.values() for skuobj in pcdobj.SkuInfoList.values() for storename in skuobj.DefaultStoreDict.keys()])
 | |
| 
 | |
|         S_PcdSet = []
 | |
|         # Find out all possible PCD candidates for self._Arch
 | |
|         RecordList = []
 | |
| 
 | |
|         for Type in TypeList:
 | |
|             RecordList.extend(self._RawData[Type, self._Arch])
 | |
| 
 | |
|         for TokenSpaceGuid, PcdCName, Setting, Arch, SkuName, default_store, Dummy4,Dummy5 in RecordList:
 | |
|             SkuName = SkuName.upper()
 | |
|             default_store = default_store.upper()
 | |
|             SkuName = 'DEFAULT' if SkuName == 'COMMON' else SkuName
 | |
|             if SkuName not in SkuIds:
 | |
|                 continue
 | |
| 
 | |
|             if SkuName in SkuIds and "." in TokenSpaceGuid:
 | |
|                 S_PcdSet.append([ TokenSpaceGuid.split(".")[0],TokenSpaceGuid.split(".")[1], PcdCName,SkuName, default_store,Dummy5, AnalyzePcdExpression(Setting)[0]])
 | |
| 
 | |
|         # handle pcd value override
 | |
|         StrPcdSet = self.GetStructurePcdInfo(S_PcdSet)
 | |
|         S_pcd_set = OrderedDict()
 | |
|         for str_pcd in StrPcdSet:
 | |
|             str_pcd_obj = Pcds.get((str_pcd[1], str_pcd[0]), None)
 | |
|             str_pcd_dec = self._DecPcds.get((str_pcd[1], str_pcd[0]), None)
 | |
|             if not isinstance (str_pcd_dec, StructurePcd):
 | |
|                 EdkLogger.error('build', PARSER_ERROR,
 | |
|                             "Pcd (%s.%s) is not declared as Structure PCD in DEC files. Arch: ['%s']" % (str_pcd[0], str_pcd[1], self._Arch),
 | |
|                             File=self.MetaFile,Line = StrPcdSet[str_pcd][0][5])
 | |
|             if str_pcd_dec:
 | |
|                 str_pcd_obj_str = StructurePcd()
 | |
|                 str_pcd_obj_str.copy(str_pcd_dec)
 | |
|                 if str_pcd_obj:
 | |
|                     str_pcd_obj_str.copy(str_pcd_obj)
 | |
|                     if str_pcd_obj.Type in [self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII], self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_HII]]:
 | |
|                         str_pcd_obj_str.DefaultFromDSC = {skuname:{defaultstore: str_pcd_obj.SkuInfoList[skuname].DefaultStoreDict.get(defaultstore, str_pcd_obj.SkuInfoList[skuname].HiiDefaultValue) for defaultstore in DefaultStores} for skuname in str_pcd_obj.SkuInfoList}
 | |
|                     else:
 | |
|                         str_pcd_obj_str.DefaultFromDSC = {skuname:{defaultstore: str_pcd_obj.SkuInfoList[skuname].DefaultStoreDict.get(defaultstore, str_pcd_obj.SkuInfoList[skuname].DefaultValue) for defaultstore in DefaultStores} for skuname in str_pcd_obj.SkuInfoList}
 | |
|                 for str_pcd_data in StrPcdSet[str_pcd]:
 | |
|                     if str_pcd_data[3] in SkuIds:
 | |
|                         str_pcd_obj_str.AddOverrideValue(str_pcd_data[2], str(str_pcd_data[6]), 'DEFAULT' if str_pcd_data[3] == 'COMMON' else str_pcd_data[3],'STANDARD' if str_pcd_data[4] == 'COMMON' else str_pcd_data[4], self.MetaFile.File if self.WorkspaceDir not in self.MetaFile.File else self.MetaFile.File[len(self.WorkspaceDir) if self.WorkspaceDir.endswith(os.path.sep) else len(self.WorkspaceDir)+1:],LineNo=str_pcd_data[5])
 | |
|                 S_pcd_set[str_pcd[1], str_pcd[0]] = str_pcd_obj_str
 | |
|             else:
 | |
|                 EdkLogger.error('build', PARSER_ERROR,
 | |
|                             "Pcd (%s.%s) defined in DSC is not declared in DEC files. Arch: ['%s']" % (str_pcd[0], str_pcd[1], self._Arch),
 | |
|                             File=self.MetaFile,Line = StrPcdSet[str_pcd][0][5])
 | |
|         # Add the Structure PCD that only defined in DEC, don't have override in DSC file
 | |
|         for Pcd in self.DecPcds:
 | |
|             if type (self._DecPcds[Pcd]) is StructurePcd:
 | |
|                 if Pcd not in S_pcd_set:
 | |
|                     str_pcd_obj_str = StructurePcd()
 | |
|                     str_pcd_obj_str.copy(self._DecPcds[Pcd])
 | |
|                     str_pcd_obj = Pcds.get(Pcd, None)
 | |
|                     if str_pcd_obj:
 | |
|                         str_pcd_obj_str.copy(str_pcd_obj)
 | |
|                         if str_pcd_obj.Type in [self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII], self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_HII]]:
 | |
|                             str_pcd_obj_str.DefaultFromDSC = {skuname:{defaultstore: str_pcd_obj.SkuInfoList[skuname].DefaultStoreDict.get(defaultstore, str_pcd_obj.SkuInfoList[skuname].HiiDefaultValue) for defaultstore in DefaultStores} for skuname in str_pcd_obj.SkuInfoList}
 | |
|                         else:
 | |
|                             str_pcd_obj_str.DefaultFromDSC = {skuname:{defaultstore: str_pcd_obj.SkuInfoList[skuname].DefaultStoreDict.get(defaultstore, str_pcd_obj.SkuInfoList[skuname].DefaultValue) for defaultstore in DefaultStores} for skuname in str_pcd_obj.SkuInfoList}
 | |
|                     S_pcd_set[Pcd] = str_pcd_obj_str
 | |
|         if S_pcd_set:
 | |
|             GlobalData.gStructurePcd[self.Arch] = S_pcd_set
 | |
|         for stru_pcd in S_pcd_set.values():
 | |
|             for skuid in SkuIds:
 | |
|                 if skuid in stru_pcd.SkuOverrideValues:
 | |
|                     continue
 | |
|                 nextskuid = self.SkuIdMgr.GetNextSkuId(skuid)
 | |
|                 NoDefault = False
 | |
|                 if skuid not in stru_pcd.SkuOverrideValues:
 | |
|                     while nextskuid not in stru_pcd.SkuOverrideValues:
 | |
|                         if nextskuid == "DEFAULT":
 | |
|                             NoDefault = True
 | |
|                             break
 | |
|                         nextskuid = self.SkuIdMgr.GetNextSkuId(nextskuid)
 | |
|                     stru_pcd.SkuOverrideValues[skuid] = copy.deepcopy(stru_pcd.SkuOverrideValues[nextskuid]) if not NoDefault else copy.deepcopy({defaultstorename: stru_pcd.DefaultValues for defaultstorename in DefaultStores} if DefaultStores else {'STANDARD':stru_pcd.DefaultValues})
 | |
|                     if not NoDefault:
 | |
|                         stru_pcd.ValueChain[(skuid,'')]= (nextskuid,'')
 | |
|             if stru_pcd.Type in [self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII], self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_HII]]:
 | |
|                 for skuid in SkuIds:
 | |
|                     nextskuid = skuid
 | |
|                     NoDefault = False
 | |
|                     if skuid not in stru_pcd.SkuOverrideValues:
 | |
|                         while nextskuid not in stru_pcd.SkuOverrideValues:
 | |
|                             if nextskuid == "DEFAULT":
 | |
|                                 NoDefault = True
 | |
|                                 break
 | |
|                             nextskuid = self.SkuIdMgr.GetNextSkuId(nextskuid)
 | |
|                     if NoDefault:
 | |
|                         continue
 | |
|                     PcdDefaultStoreSet = set([defaultstorename  for defaultstorename in stru_pcd.SkuOverrideValues[nextskuid]])
 | |
|                     mindefaultstorename = DefaultStoreMgr.GetMin(PcdDefaultStoreSet)
 | |
| 
 | |
|                     for defaultstoreid in DefaultStores:
 | |
|                         if defaultstoreid not in stru_pcd.SkuOverrideValues[skuid]:
 | |
|                             stru_pcd.SkuOverrideValues[skuid][defaultstoreid] = copy.deepcopy(stru_pcd.SkuOverrideValues[nextskuid][mindefaultstorename])
 | |
|                             stru_pcd.ValueChain[(skuid,defaultstoreid)]= (nextskuid,mindefaultstorename)
 | |
|         S_pcd_set = self.OverrideByFdfComm(S_pcd_set)
 | |
|         Str_Pcd_Values = self.GenerateByteArrayValue(S_pcd_set)
 | |
|         if Str_Pcd_Values:
 | |
|             for (skuname,StoreName,PcdGuid,PcdName,PcdValue) in Str_Pcd_Values:
 | |
|                 str_pcd_obj = S_pcd_set.get((PcdName, PcdGuid))
 | |
|                 if str_pcd_obj is None:
 | |
|                     print PcdName, PcdGuid
 | |
|                     raise
 | |
|                 if str_pcd_obj.Type in [self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII],
 | |
|                                         self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_HII]]:
 | |
|                     if skuname not in str_pcd_obj.SkuInfoList:
 | |
|                         str_pcd_obj.SkuInfoList[skuname] = SkuInfoClass(SkuIdName=skuname, SkuId=self.SkuIds[skuname][0], HiiDefaultValue=PcdValue, DefaultStore = {StoreName:PcdValue})
 | |
|                     else:
 | |
|                         str_pcd_obj.SkuInfoList[skuname].HiiDefaultValue = PcdValue
 | |
|                         str_pcd_obj.SkuInfoList[skuname].DefaultStoreDict.update({StoreName:PcdValue})
 | |
|                 elif str_pcd_obj.Type in [self._PCD_TYPE_STRING_[MODEL_PCD_FIXED_AT_BUILD],
 | |
|                                         self._PCD_TYPE_STRING_[MODEL_PCD_PATCHABLE_IN_MODULE]]:
 | |
|                     if skuname in (self.SkuIdMgr.SystemSkuId, 'DEFAULT', 'COMMON'):
 | |
|                         str_pcd_obj.DefaultValue = PcdValue
 | |
|                 else:
 | |
|                     if skuname not in str_pcd_obj.SkuInfoList:
 | |
|                         nextskuid = self.SkuIdMgr.GetNextSkuId(skuname)
 | |
|                         NoDefault = False
 | |
|                         while nextskuid not in str_pcd_obj.SkuInfoList:
 | |
|                             if nextskuid == "DEFAULT":
 | |
|                                 NoDefault = True
 | |
|                                 break
 | |
|                             nextskuid = self.SkuIdMgr.GetNextSkuId(nextskuid)
 | |
|                         str_pcd_obj.SkuInfoList[skuname] = copy.deepcopy(str_pcd_obj.SkuInfoList[nextskuid]) if not NoDefault else SkuInfoClass(SkuIdName=skuname, SkuId=self.SkuIds[skuname][0], DefaultValue=PcdValue)
 | |
|                         str_pcd_obj.SkuInfoList[skuname].SkuId = self.SkuIds[skuname][0]
 | |
|                         str_pcd_obj.SkuInfoList[skuname].SkuIdName = skuname
 | |
|                     else:
 | |
|                         str_pcd_obj.SkuInfoList[skuname].DefaultValue = PcdValue
 | |
|             for str_pcd_obj in S_pcd_set.values():
 | |
|                 if str_pcd_obj.Type not in [self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII],
 | |
|                                         self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_HII]]:
 | |
|                     continue
 | |
|                 PcdDefaultStoreSet = set([defaultstorename  for skuobj in str_pcd_obj.SkuInfoList.values() for defaultstorename in skuobj.DefaultStoreDict])
 | |
|                 DefaultStoreObj = DefaultStore(self._GetDefaultStores())
 | |
|                 mindefaultstorename = DefaultStoreObj.GetMin(PcdDefaultStoreSet)
 | |
|                 str_pcd_obj.SkuInfoList[self.SkuIdMgr.SystemSkuId].HiiDefaultValue = str_pcd_obj.SkuInfoList[self.SkuIdMgr.SystemSkuId].DefaultStoreDict[mindefaultstorename]
 | |
| 
 | |
|             for str_pcd_obj in S_pcd_set.values():
 | |
| 
 | |
|                 str_pcd_obj.MaxDatumSize = self.GetStructurePcdMaxSize(str_pcd_obj)
 | |
|                 Pcds[str_pcd_obj.TokenCName, str_pcd_obj.TokenSpaceGuidCName] = str_pcd_obj
 | |
| 
 | |
|             for pcdkey in Pcds:
 | |
|                 pcd = Pcds[pcdkey]
 | |
|                 if 'DEFAULT' not in pcd.SkuInfoList.keys() and 'COMMON' in pcd.SkuInfoList.keys():
 | |
|                     pcd.SkuInfoList['DEFAULT'] = pcd.SkuInfoList['COMMON']
 | |
|                     del(pcd.SkuInfoList['COMMON'])
 | |
|                 elif 'DEFAULT' in pcd.SkuInfoList.keys() and 'COMMON' in pcd.SkuInfoList.keys():
 | |
|                     del(pcd.SkuInfoList['COMMON'])
 | |
| 
 | |
|         map(self.FilterSkuSettings,[Pcds[pcdkey] for pcdkey in Pcds if Pcds[pcdkey].Type in DynamicPcdType])
 | |
|         return Pcds
 | |
| 
 | |
|     ## Retrieve non-dynamic PCD settings
 | |
|     #
 | |
|     #   @param  Type    PCD type
 | |
|     #
 | |
|     #   @retval a dict object contains settings of given PCD type
 | |
|     #
 | |
|     def _GetPcd(self, Type):
 | |
|         Pcds = sdict()
 | |
|         #
 | |
|         # tdict is a special dict kind of type, used for selecting correct
 | |
|         # PCD settings for certain ARCH
 | |
|         #
 | |
|         AvailableSkuIdSet = copy.copy(self.SkuIds)
 | |
| 
 | |
|         PcdDict = tdict(True, 3)
 | |
|         PcdSet = set()
 | |
|         # Find out all possible PCD candidates for self._Arch
 | |
|         RecordList = self._RawData[Type, self._Arch]
 | |
|         PcdValueDict = sdict()
 | |
|         for TokenSpaceGuid, PcdCName, Setting, Arch, SkuName, Dummy3, Dummy4,Dummy5 in RecordList:
 | |
|             SkuName = SkuName.upper()
 | |
|             SkuName = 'DEFAULT' if SkuName == 'COMMON' else SkuName
 | |
|             if SkuName not in AvailableSkuIdSet:
 | |
|                 EdkLogger.error('build ', PARAMETER_INVALID, 'Sku %s is not defined in [SkuIds] section' % SkuName,
 | |
|                                             File=self.MetaFile, Line=Dummy5)
 | |
|             if SkuName in (self.SkuIdMgr.SystemSkuId, 'DEFAULT', 'COMMON'):
 | |
|                 if "." not in TokenSpaceGuid:
 | |
|                     PcdSet.add((PcdCName, TokenSpaceGuid, SkuName, Dummy5))
 | |
|                 PcdDict[Arch, PcdCName, TokenSpaceGuid, SkuName] = Setting
 | |
| 
 | |
|         for PcdCName, TokenSpaceGuid, SkuName, Dummy4 in PcdSet:
 | |
|             Setting = PcdDict[self._Arch, PcdCName, TokenSpaceGuid, SkuName]
 | |
|             if Setting is None:
 | |
|                 continue
 | |
|             PcdValue, DatumType, MaxDatumSize = self._ValidatePcd(PcdCName, TokenSpaceGuid, Setting, Type, Dummy4)
 | |
|             if (PcdCName, TokenSpaceGuid) in PcdValueDict:
 | |
|                 PcdValueDict[PcdCName, TokenSpaceGuid][SkuName] = (PcdValue, DatumType, MaxDatumSize)
 | |
|             else:
 | |
|                 PcdValueDict[PcdCName, TokenSpaceGuid] = {SkuName:(PcdValue, DatumType, MaxDatumSize)}
 | |
| 
 | |
|         PcdsKeys = PcdValueDict.keys()
 | |
|         for PcdCName, TokenSpaceGuid in PcdsKeys:
 | |
| 
 | |
|             PcdSetting = PcdValueDict[PcdCName, TokenSpaceGuid]
 | |
|             PcdValue = None
 | |
|             DatumType = None
 | |
|             MaxDatumSize = None
 | |
|             if 'COMMON' in PcdSetting:
 | |
|                 PcdValue, DatumType, MaxDatumSize = PcdSetting['COMMON']
 | |
|             if 'DEFAULT' in PcdSetting:
 | |
|                 PcdValue, DatumType, MaxDatumSize = PcdSetting['DEFAULT']
 | |
|             if self.SkuIdMgr.SystemSkuId in PcdSetting:
 | |
|                 PcdValue, DatumType, MaxDatumSize = PcdSetting[self.SkuIdMgr.SystemSkuId]
 | |
| 
 | |
|             Pcds[PcdCName, TokenSpaceGuid] = PcdClassObject(
 | |
|                                                 PcdCName,
 | |
|                                                 TokenSpaceGuid,
 | |
|                                                 self._PCD_TYPE_STRING_[Type],
 | |
|                                                 DatumType,
 | |
|                                                 PcdValue,
 | |
|                                                 '',
 | |
|                                                 MaxDatumSize,
 | |
|                                                 {},
 | |
|                                                 False,
 | |
|                                                 None,
 | |
|                                                 IsDsc=True)
 | |
| 
 | |
| 
 | |
|         return Pcds
 | |
| 
 | |
|     def __UNICODE2OCTList(self,Value):
 | |
|         Value = Value.strip()
 | |
|         Value = Value[2:-1]
 | |
|         List = []
 | |
|         for Item in Value:
 | |
|             Temp = '%04X' % ord(Item)
 | |
|             List.append('0x' + Temp[2:4])
 | |
|             List.append('0x' + Temp[0:2])
 | |
|         List.append('0x00')
 | |
|         List.append('0x00')
 | |
|         return List
 | |
|     def __STRING2OCTList(self,Value):
 | |
|         OCTList = []
 | |
|         Value = Value.strip('"')
 | |
|         for char in Value:
 | |
|             Temp = '%02X' % ord(char)
 | |
|             OCTList.append('0x' + Temp)
 | |
|         OCTList.append('0x00')
 | |
|         return OCTList
 | |
| 
 | |
|     def GetStructurePcdMaxSize(self, str_pcd):
 | |
|         pcd_default_value = str_pcd.DefaultValue
 | |
|         sku_values = [skuobj.HiiDefaultValue if str_pcd.Type in [self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII], self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_HII]] else skuobj.DefaultValue for skuobj in str_pcd.SkuInfoList.values()]
 | |
|         sku_values.append(pcd_default_value)
 | |
| 
 | |
|         def get_length(value):
 | |
|             Value = value.strip()
 | |
|             if len(value) > 1:
 | |
|                 if Value.startswith('GUID') and Value.endswith(')'):
 | |
|                     return 16
 | |
|                 if Value.startswith('L"') and Value.endswith('"'):
 | |
|                     return len(Value[2:-1])
 | |
|                 if Value[0] == '"' and Value[-1] == '"':
 | |
|                     return len(Value) - 2
 | |
|                 if Value[0] == '{' and Value[-1] == '}':
 | |
|                     return len(Value.split(","))
 | |
|                 if Value.startswith("L'") and Value.endswith("'") and len(list(Value[2:-1])) > 1:
 | |
|                     return  len(list(Value[2:-1]))
 | |
|                 if Value[0] == "'" and Value[-1] == "'" and len(list(Value[1:-1])) > 1:
 | |
|                     return len(Value) - 2
 | |
|             return len(Value)
 | |
| 
 | |
|         return str(max([pcd_size for pcd_size in [get_length(item) for item in sku_values]]))
 | |
| 
 | |
|     def ExecuteCommand (self, Command):
 | |
|         try:
 | |
|             Process = subprocess.Popen(Command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
 | |
|         except:
 | |
|             EdkLogger.error('Build', COMMAND_FAILURE, 'Can not execute command: %s' % Command)
 | |
|         Result = Process.communicate()
 | |
|         return Process.returncode, Result[0], Result[1]
 | |
| 
 | |
|     def IntToCString(self, 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 GetPcdMaxSize(self,Pcd):
 | |
|         MaxSize = int(Pcd.MaxDatumSize,10) if Pcd.MaxDatumSize else 0
 | |
|         if Pcd.DatumType not in ['BOOLEAN','UINT8','UINT16','UINT32','UINT64']:
 | |
|             if Pcd.PcdValueFromComm:
 | |
|                 if Pcd.PcdValueFromComm.startswith("{") and Pcd.PcdValueFromComm.endswith("}"):
 | |
|                     MaxSize = max([len(Pcd.PcdValueFromComm.split(",")),MaxSize])
 | |
|                 elif Pcd.PcdValueFromComm.startswith("\"") or Pcd.PcdValueFromComm.startswith("\'"):
 | |
|                     MaxSize = max([len(Pcd.PcdValueFromComm)-2+1,MaxSize])
 | |
|                 elif Pcd.PcdValueFromComm.startswith("L\""):
 | |
|                     MaxSize = max([2*(len(Pcd.PcdValueFromComm)-3+1),MaxSize])
 | |
|                 else:
 | |
|                     MaxSize = max([len(Pcd.PcdValueFromComm),MaxSize])
 | |
|         elif Pcd.DatumType not in ['BOOLEAN','UINT8']:
 | |
|             MaxSize = 1
 | |
|         elif Pcd.DatumType  == 'UINT16':
 | |
|             MaxSize = 2
 | |
|         elif Pcd.DatumType  == 'UINT32':
 | |
|             MaxSize = 4
 | |
|         elif Pcd.DatumType  == 'UINT64':
 | |
|             MaxSize = 8
 | |
|         return MaxSize
 | |
|     def GenerateSizeFunction(self,Pcd):
 | |
|         CApp = "// Default Value in Dec \n"
 | |
|         CApp = CApp + "void Cal_%s_%s_Size(UINT32 *Size){\n" % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName)
 | |
|         for FieldList in [Pcd.DefaultValues]:
 | |
|             if not FieldList:
 | |
|                 continue
 | |
|             for FieldName in FieldList:
 | |
|                 FieldName = "." + FieldName
 | |
|                 IsArray = IsFieldValueAnArray(FieldList[FieldName.strip(".")][0])
 | |
|                 if IsArray and not (FieldList[FieldName.strip(".")][0].startswith('{GUID') and FieldList[FieldName.strip(".")][0].endswith('}')):
 | |
|                     try:
 | |
|                         Value = ValueExpressionEx(FieldList[FieldName.strip(".")][0], "VOID*", self._GuidDict)(True)
 | |
|                     except BadExpression:
 | |
|                         EdkLogger.error('Build', FORMAT_INVALID, "Invalid value format for %s. From %s Line %d " %
 | |
|                                         (".".join((Pcd.TokenSpaceGuidCName, Pcd.TokenCName, FieldName.strip('.'))), FieldList[FieldName.strip(".")][1], FieldList[FieldName.strip(".")][2]))
 | |
|                     Value, ValueSize = ParseFieldValue(Value)
 | |
|                     CApp = CApp + '  __FLEXIBLE_SIZE(*Size, %s, %s, %d / __ARRAY_ELEMENT_SIZE(%s, %s) + ((%d %% __ARRAY_ELEMENT_SIZE(%s, %s)) ? 1 : 0));  // From %s Line %d Value %s \n' % (Pcd.DatumType, FieldName.strip("."), ValueSize, Pcd.DatumType, FieldName.strip("."), ValueSize, Pcd.DatumType, FieldName.strip("."), FieldList[FieldName.strip(".")][1], FieldList[FieldName.strip(".")][2], FieldList[FieldName.strip(".")][0]);
 | |
|                 else:
 | |
|                     NewFieldName = ''
 | |
|                     FieldName_ori = FieldName.strip('.')
 | |
|                     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]
 | |
|                         CApp = CApp + '  __FLEXIBLE_SIZE(*Size, %s, %s, %d); // From %s Line %d Value %s\n' % (Pcd.DatumType, FieldName.strip("."), ArrayIndex + 1, FieldList[FieldName_ori][1], FieldList[FieldName_ori][2], FieldList[FieldName_ori][0])
 | |
|         for skuname in Pcd.SkuOverrideValues:
 | |
|             if skuname == "COMMON":
 | |
|                 continue
 | |
|             for defaultstorenameitem in Pcd.SkuOverrideValues[skuname]:
 | |
|                 CApp = CApp + "// SkuName: %s,  DefaultStoreName: %s \n" % (skuname, defaultstorenameitem)
 | |
|                 for FieldList in [Pcd.SkuOverrideValues[skuname].get(defaultstorenameitem)]:
 | |
|                     if not FieldList:
 | |
|                         continue
 | |
|                     for FieldName in FieldList:
 | |
|                         FieldName = "." + FieldName
 | |
|                         IsArray = IsFieldValueAnArray(FieldList[FieldName.strip(".")][0])
 | |
|                         if IsArray and not (FieldList[FieldName.strip(".")][0].startswith('{GUID') and FieldList[FieldName.strip(".")][0].endswith('}')):
 | |
|                             try:
 | |
|                                 Value = ValueExpressionEx(FieldList[FieldName.strip(".")][0], "VOID*", self._GuidDict)(True)
 | |
|                             except BadExpression:
 | |
|                                 EdkLogger.error('Build', FORMAT_INVALID, "Invalid value format for %s. From %s Line %d " %
 | |
|                                                 (".".join((Pcd.TokenSpaceGuidCName, Pcd.TokenCName, FieldName.strip('.'))), FieldList[FieldName.strip(".")][1], FieldList[FieldName.strip(".")][2]))
 | |
|                             Value, ValueSize = ParseFieldValue(Value)
 | |
|                             CApp = CApp + '  __FLEXIBLE_SIZE(*Size, %s, %s, %d / __ARRAY_ELEMENT_SIZE(%s, %s) + ((%d %% __ARRAY_ELEMENT_SIZE(%s, %s)) ? 1 : 0)); // From %s Line %d Value %s\n' % (Pcd.DatumType, FieldName.strip("."), ValueSize, Pcd.DatumType, FieldName.strip("."), ValueSize, Pcd.DatumType, FieldName.strip("."), FieldList[FieldName.strip(".")][1], FieldList[FieldName.strip(".")][2], FieldList[FieldName.strip(".")][0]);
 | |
|                         else:
 | |
|                             NewFieldName = ''
 | |
|                             FieldName_ori = FieldName.strip('.')
 | |
|                             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]
 | |
|                                 CApp = CApp + '  __FLEXIBLE_SIZE(*Size, %s, %s, %d); // From %s Line %d Value %s \n' % (Pcd.DatumType, FieldName.strip("."), ArrayIndex + 1, FieldList[FieldName_ori][1], FieldList[FieldName_ori][2], FieldList[FieldName_ori][0])
 | |
|         if Pcd.PcdFieldValueFromComm:
 | |
|             CApp = CApp + "// From Command Line \n"
 | |
|         for FieldName in Pcd.PcdFieldValueFromComm:
 | |
|             FieldName = "." + FieldName
 | |
|             IsArray = IsFieldValueAnArray(Pcd.PcdFieldValueFromComm[FieldName.strip(".")][0])
 | |
|             if IsArray and not (Pcd.PcdFieldValueFromComm[FieldName.strip(".")][0].startswith('{GUID') and Pcd.PcdFieldValueFromComm[FieldName.strip(".")][0].endswith('}')):
 | |
|                 try:
 | |
|                     Value = ValueExpressionEx(Pcd.PcdFieldValueFromComm[FieldName.strip(".")][0], "VOID*", self._GuidDict)(True)
 | |
|                 except BadExpression:
 | |
|                     EdkLogger.error('Build', FORMAT_INVALID, "Invalid value format for %s. From %s Line %d " %
 | |
|                                     (".".join((Pcd.TokenSpaceGuidCName, Pcd.TokenCName, FieldName.strip('.'))), Pcd.PcdFieldValueFromComm[FieldName.strip(".")][1], Pcd.PcdFieldValueFromComm[FieldName.strip(".")][2]))
 | |
|                 Value, ValueSize = ParseFieldValue(Value)
 | |
|                 CApp = CApp + '  __FLEXIBLE_SIZE(*Size, %s, %s, %d / __ARRAY_ELEMENT_SIZE(%s, %s) + ((%d %% __ARRAY_ELEMENT_SIZE(%s, %s)) ? 1 : 0)); // From %s Line %d Value %s\n' % (Pcd.DatumType, FieldName.strip("."), ValueSize, Pcd.DatumType, FieldName.strip("."), ValueSize, Pcd.DatumType, FieldName.strip("."), Pcd.PcdFieldValueFromComm[FieldName.strip(".")][1], Pcd.PcdFieldValueFromComm[FieldName.strip(".")][2], Pcd.PcdFieldValueFromComm[FieldName.strip(".")][0]);
 | |
|             else:
 | |
|                 NewFieldName = ''
 | |
|                 FieldName_ori = FieldName.strip('.')
 | |
|                 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]
 | |
|                     CApp = CApp + '  __FLEXIBLE_SIZE(*Size, %s, %s, %d); // From %s Line %d Value %s \n' % (Pcd.DatumType, FieldName.strip("."), ArrayIndex + 1, Pcd.PcdFieldValueFromComm[FieldName_ori][1], Pcd.PcdFieldValueFromComm[FieldName_ori][2], Pcd.PcdFieldValueFromComm[FieldName_ori][0])
 | |
|         CApp = CApp + "  *Size = (%d > *Size ? %d : *Size); // The Pcd maxsize is %d \n" % (self.GetPcdMaxSize(Pcd),self.GetPcdMaxSize(Pcd),self.GetPcdMaxSize(Pcd))
 | |
|         CApp = CApp + "}\n"
 | |
|         return CApp
 | |
|     def GenerateSizeStatments(self,Pcd):
 | |
|         CApp = '  Size = sizeof(%s);\n' % (Pcd.DatumType)
 | |
|         CApp = CApp + '  Cal_%s_%s_Size(&Size);\n' % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName)
 | |
|         return CApp
 | |
|     def GenerateDefaultValueAssignFunction(self,Pcd):
 | |
|         CApp = "// Default value in Dec \n"
 | |
|         CApp = CApp + "void Assign_%s_%s_Default_Value(%s *Pcd){\n" % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName,Pcd.DatumType)
 | |
|         CApp = CApp + '  UINT32  FieldSize;\n'
 | |
|         CApp = CApp + '  CHAR8   *Value;\n'
 | |
|         DefaultValueFromDec = Pcd.DefaultValueFromDec
 | |
|         IsArray = IsFieldValueAnArray(Pcd.DefaultValueFromDec)
 | |
|         if IsArray:
 | |
|             try:
 | |
|                 DefaultValueFromDec = ValueExpressionEx(Pcd.DefaultValueFromDec, "VOID*")(True)
 | |
|             except BadExpression:
 | |
|                 EdkLogger.error("Build", FORMAT_INVALID, "Invalid value format for %s.%s, from DEC: %s" %
 | |
|                                 (Pcd.TokenSpaceGuidCName, Pcd.TokenCName, DefaultValueFromDec))
 | |
|         DefaultValueFromDec = StringToArray(DefaultValueFromDec)
 | |
|         Value, ValueSize = ParseFieldValue (DefaultValueFromDec)
 | |
|         if isinstance(Value, str):
 | |
|             CApp = CApp + '  Pcd = %s; // From DEC Default Value %s\n' % (Value, Pcd.DefaultValueFromDec)
 | |
|         elif IsArray:
 | |
|         #
 | |
|         # Use memcpy() to copy value into field
 | |
|         #
 | |
|             CApp = CApp + '  Value     = %s; // From DEC Default Value %s\n' % (self.IntToCString(Value, ValueSize), Pcd.DefaultValueFromDec)
 | |
|             CApp = CApp + '  memcpy (Pcd, Value, %d);\n' % (ValueSize)
 | |
|         for FieldList in [Pcd.DefaultValues]:
 | |
|             if not FieldList:
 | |
|                 continue
 | |
|             for FieldName in FieldList:
 | |
|                 IsArray = IsFieldValueAnArray(FieldList[FieldName][0])
 | |
|                 if IsArray:
 | |
|                     try:
 | |
|                         FieldList[FieldName][0] = ValueExpressionEx(FieldList[FieldName][0], "VOID*", self._GuidDict)(True)
 | |
|                     except BadExpression:
 | |
|                         EdkLogger.error('Build', FORMAT_INVALID, "Invalid value format for %s. From %s Line %d " %
 | |
|                                         (".".join((Pcd.TokenSpaceGuidCName, Pcd.TokenCName, FieldName)), FieldList[FieldName][1],FieldList[FieldName][2]))
 | |
| 
 | |
|                 try:
 | |
|                     Value, ValueSize = ParseFieldValue (FieldList[FieldName][0])
 | |
|                 except Exception:
 | |
|                     EdkLogger.error('Build', FORMAT_INVALID, "Invalid value format for %s. From %s Line %d " % (".".join((Pcd.TokenSpaceGuidCName,Pcd.TokenCName,FieldName)),FieldList[FieldName][1], FieldList[FieldName][2]))
 | |
|                 if isinstance(Value, str):
 | |
|                     CApp = CApp + '  Pcd->%s = %s; // From %s Line %d Value %s\n' % (FieldName, 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.DatumType, FieldName)
 | |
|                     CApp = CApp + '  Value     = %s; // From %s Line %d Value %s\n' % (self.IntToCString(Value, ValueSize), FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])
 | |
|                     CApp = CApp + '  memcpy (&Pcd->%s, Value, (FieldSize > 0 && FieldSize < %d) ? FieldSize : %d);\n' % (FieldName, ValueSize, ValueSize)
 | |
|                 else:
 | |
|                     if ValueSize > 4:
 | |
|                         CApp = CApp + '  Pcd->%s = %dULL; // From %s Line %d Value %s\n' % (FieldName, Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])
 | |
|                     else:
 | |
|                         CApp = CApp + '  Pcd->%s = %d; // From %s Line %d Value %s\n' % (FieldName, Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])
 | |
|         CApp = CApp + "}\n"
 | |
|         return CApp
 | |
|     def GenerateDefaultValueAssignStatement(self,Pcd):
 | |
|         CApp = '  Assign_%s_%s_Default_Value(Pcd);\n' % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName)
 | |
|         return CApp
 | |
|     def GenerateInitValueFunction(self,Pcd,SkuName,DefaultStoreName):
 | |
|         CApp = "// Value in Dsc for Sku: %s, DefaultStore %s\n" % (SkuName,DefaultStoreName)
 | |
|         CApp = CApp + "void Assign_%s_%s_%s_%s_Value(%s *Pcd){\n" % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName,SkuName,DefaultStoreName,Pcd.DatumType)
 | |
|         CApp = CApp + '  UINT32  FieldSize;\n'
 | |
|         CApp = CApp + '  CHAR8   *Value;\n'
 | |
| 
 | |
|         CApp = CApp + "// SkuName: %s,  DefaultStoreName: %s \n" % ('DEFAULT', 'STANDARD')
 | |
|         inherit_OverrideValues = Pcd.SkuOverrideValues[SkuName]
 | |
|         if (SkuName,DefaultStoreName) == ('DEFAULT','STANDARD'):
 | |
|             pcddefaultvalue = Pcd.DefaultFromDSC.get('DEFAULT',{}).get('STANDARD', Pcd.DefaultValue) if Pcd.DefaultFromDSC else Pcd.DefaultValue
 | |
|         else:
 | |
|             if not Pcd.DscRawValue:
 | |
|                 # handle the case that structure pcd is not appear in DSC
 | |
|                 self.CopyDscRawValue(Pcd)
 | |
|             pcddefaultvalue = Pcd.DscRawValue.get(SkuName,{}).get(DefaultStoreName)
 | |
|         for FieldList in [pcddefaultvalue,inherit_OverrideValues.get(DefaultStoreName)]:
 | |
|             if not FieldList:
 | |
|                 continue
 | |
|             if pcddefaultvalue and FieldList == pcddefaultvalue:
 | |
|                 IsArray = IsFieldValueAnArray(FieldList)
 | |
|                 if IsArray:
 | |
|                     try:
 | |
|                         FieldList = ValueExpressionEx(FieldList, "VOID*")(True)
 | |
|                     except BadExpression:
 | |
|                         EdkLogger.error("Build", FORMAT_INVALID, "Invalid value format for %s.%s, from DSC: %s" %
 | |
|                                         (Pcd.TokenSpaceGuidCName, Pcd.TokenCName, FieldList))
 | |
|                 Value, ValueSize = ParseFieldValue (FieldList)
 | |
| 
 | |
|                 if (SkuName,DefaultStoreName) == ('DEFAULT','STANDARD'):
 | |
|                     if isinstance(Value, str):
 | |
|                         CApp = CApp + '  Pcd = %s; // From DSC Default Value %s\n' % (Value, Pcd.DefaultFromDSC.get('DEFAULT',{}).get('STANDARD', Pcd.DefaultValue) if Pcd.DefaultFromDSC else Pcd.DefaultValue)
 | |
|                     elif IsArray:
 | |
|                     #
 | |
|                     # Use memcpy() to copy value into field
 | |
|                     #
 | |
|                         CApp = CApp + '  Value     = %s; // From DSC Default Value %s\n' % (self.IntToCString(Value, ValueSize), Pcd.DefaultFromDSC.get('DEFAULT',{}).get('STANDARD', Pcd.DefaultValue) if Pcd.DefaultFromDSC else Pcd.DefaultValue)
 | |
|                         CApp = CApp + '  memcpy (Pcd, Value, %d);\n' % (ValueSize)
 | |
|                 else:
 | |
|                     if isinstance(Value, str):
 | |
|                         CApp = CApp + '  Pcd = %s; // From DSC Default Value %s\n' % (Value, Pcd.DscRawValue.get(SkuName,{}).get(DefaultStoreName))
 | |
|                     elif IsArray:
 | |
|                     #
 | |
|                     # Use memcpy() to copy value into field
 | |
|                     #
 | |
|                         CApp = CApp + '  Value     = %s; // From DSC Default Value %s\n' % (self.IntToCString(Value, ValueSize), Pcd.DscRawValue.get(SkuName,{}).get(DefaultStoreName))
 | |
|                         CApp = CApp + '  memcpy (Pcd, Value, %d);\n' % (ValueSize)
 | |
|                 continue
 | |
|             if (SkuName,DefaultStoreName) == ('DEFAULT','STANDARD') or (( (SkuName,'') not in Pcd.ValueChain) and ( (SkuName,DefaultStoreName) not in Pcd.ValueChain )):
 | |
|                 for FieldName in FieldList:
 | |
|                     IsArray = IsFieldValueAnArray(FieldList[FieldName][0])
 | |
|                     if IsArray:
 | |
|                         try:
 | |
|                             FieldList[FieldName][0] = ValueExpressionEx(FieldList[FieldName][0], "VOID*", self._GuidDict)(True)
 | |
|                         except BadExpression:
 | |
|                             EdkLogger.error('Build', FORMAT_INVALID, "Invalid value format for %s. From %s Line %d " %
 | |
|                                             (".".join((Pcd.TokenSpaceGuidCName, Pcd.TokenCName, FieldName)), FieldList[FieldName][1], FieldList[FieldName][2]))
 | |
|                     try:
 | |
|                         Value, ValueSize = ParseFieldValue (FieldList[FieldName][0])
 | |
|                     except Exception:
 | |
|                         EdkLogger.error('Build', FORMAT_INVALID, "Invalid value format for %s. From %s Line %d " % (".".join((Pcd.TokenSpaceGuidCName,Pcd.TokenCName,FieldName)),FieldList[FieldName][1], FieldList[FieldName][2]))
 | |
|                     if isinstance(Value, str):
 | |
|                         CApp = CApp + '  Pcd->%s = %s; // From %s Line %d Value %s\n' % (FieldName, 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.DatumType, FieldName)
 | |
|                         CApp = CApp + '  Value     = %s; // From %s Line %d Value %s\n' % (self.IntToCString(Value, ValueSize), FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])
 | |
|                         CApp = CApp + '  memcpy (&Pcd->%s, Value, (FieldSize > 0 && FieldSize < %d) ? FieldSize : %d);\n' % (FieldName, ValueSize, ValueSize)
 | |
|                     else:
 | |
|                         if ValueSize > 4:
 | |
|                             CApp = CApp + '  Pcd->%s = %dULL; // From %s Line %d Value %s\n' % (FieldName, Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])
 | |
|                         else:
 | |
|                             CApp = CApp + '  Pcd->%s = %d; // From %s Line %d Value %s\n' % (FieldName, Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])
 | |
|         CApp = CApp + "}\n"
 | |
|         return CApp
 | |
|     def GenerateInitValueStatement(self,Pcd,SkuName,DefaultStoreName):
 | |
|         CApp = '  Assign_%s_%s_%s_%s_Value(Pcd);\n' % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName,SkuName,DefaultStoreName)
 | |
|         return CApp
 | |
|     def GenerateCommandLineValue(self,Pcd):
 | |
|         CApp = "// Value in CommandLine\n"
 | |
|         CApp = CApp + "void Assign_%s_%s_CommandLine_Value(%s *Pcd){\n" % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName,Pcd.DatumType)
 | |
|         CApp = CApp + '  UINT32  FieldSize;\n'
 | |
|         CApp = CApp + '  CHAR8   *Value;\n'
 | |
| 
 | |
|         pcddefaultvalue = Pcd.PcdValueFromComm
 | |
|         for FieldList in [pcddefaultvalue,Pcd.PcdFieldValueFromComm]:
 | |
|             if not FieldList:
 | |
|                 continue
 | |
|             if pcddefaultvalue and FieldList == pcddefaultvalue:
 | |
|                 IsArray = IsFieldValueAnArray(FieldList)
 | |
|                 if IsArray:
 | |
|                     try:
 | |
|                         FieldList = ValueExpressionEx(FieldList, "VOID*")(True)
 | |
|                     except BadExpression:
 | |
|                         EdkLogger.error("Build", FORMAT_INVALID, "Invalid value format for %s.%s, from Command: %s" %
 | |
|                                         (Pcd.TokenSpaceGuidCName, Pcd.TokenCName, FieldList))
 | |
|                 Value, ValueSize = ParseFieldValue (FieldList)
 | |
| 
 | |
|                 if isinstance(Value, str):
 | |
|                     CApp = CApp + '  Pcd = %s; // From Command Line \n' % (Value)
 | |
|                 elif IsArray:
 | |
|                 #
 | |
|                 # Use memcpy() to copy value into field
 | |
|                 #
 | |
|                     CApp = CApp + '  Value     = %s; // From Command Line.\n' % (self.IntToCString(Value, ValueSize))
 | |
|                     CApp = CApp + '  memcpy (Pcd, Value, %d);\n' % (ValueSize)
 | |
|                 continue
 | |
|             for FieldName in FieldList:
 | |
|                 IsArray = IsFieldValueAnArray(FieldList[FieldName][0])
 | |
|                 if IsArray:
 | |
|                     try:
 | |
|                         FieldList[FieldName][0] = ValueExpressionEx(FieldList[FieldName][0], "VOID*", self._GuidDict)(True)
 | |
|                     except BadExpression:
 | |
|                         EdkLogger.error('Build', FORMAT_INVALID, "Invalid value format for %s. From %s Line %d " %
 | |
|                                         (".".join((Pcd.TokenSpaceGuidCName, Pcd.TokenCName, FieldName)), FieldList[FieldName][1], FieldList[FieldName][2]))
 | |
|                     except:
 | |
|                         print "error"
 | |
|                 try:
 | |
|                     Value, ValueSize = ParseFieldValue (FieldList[FieldName][0])
 | |
|                 except Exception:
 | |
|                     EdkLogger.error('Build', FORMAT_INVALID, "Invalid value format for %s. From %s Line %d " % (".".join((Pcd.TokenSpaceGuidCName,Pcd.TokenCName,FieldName)),FieldList[FieldName][1], FieldList[FieldName][2]))
 | |
|                 if isinstance(Value, str):
 | |
|                     CApp = CApp + '  Pcd->%s = %s; // From %s Line %d Value %s\n' % (FieldName, 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.DatumType, FieldName)
 | |
|                     CApp = CApp + '  Value     = %s; // From %s Line %d Value %s\n' % (self.IntToCString(Value, ValueSize), FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])
 | |
|                     CApp = CApp + '  memcpy (&Pcd->%s, Value, (FieldSize > 0 && FieldSize < %d) ? FieldSize : %d);\n' % (FieldName, ValueSize, ValueSize)
 | |
|                 else:
 | |
|                     if ValueSize > 4:
 | |
|                         CApp = CApp + '  Pcd->%s = %dULL; // From %s Line %d Value %s\n' % (FieldName, Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])
 | |
|                     else:
 | |
|                         CApp = CApp + '  Pcd->%s = %d; // From %s Line %d Value %s\n' % (FieldName, Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])
 | |
|         CApp = CApp + "}\n"
 | |
|         return CApp
 | |
|     def GenerateCommandLineValueStatement(self,Pcd):
 | |
|         CApp = '  Assign_%s_%s_CommandLine_Value(Pcd);\n' % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName)
 | |
|         return CApp
 | |
|     def GenerateInitializeFunc(self, SkuName, DefaultStore, Pcd, InitByteValue, CApp):
 | |
|         OverrideValues = {DefaultStore:""}
 | |
|         if Pcd.SkuOverrideValues:
 | |
|             OverrideValues = Pcd.SkuOverrideValues[SkuName]
 | |
|         for DefaultStoreName in OverrideValues.keys():
 | |
|             CApp = CApp + 'void\n'
 | |
|             CApp = CApp + 'Initialize_%s_%s_%s_%s(\n' % (SkuName, DefaultStoreName, Pcd.TokenSpaceGuidCName, Pcd.TokenCName)
 | |
|             CApp = CApp + '  void\n'
 | |
|             CApp = CApp + '  )\n'
 | |
|             CApp = CApp + '{\n'
 | |
|             CApp = CApp + '  UINT32  Size;\n'
 | |
|             CApp = CApp + '  UINT32  FieldSize;\n'
 | |
|             CApp = CApp + '  CHAR8   *Value;\n'
 | |
|             CApp = CApp + '  UINT32  OriginalSize;\n'
 | |
|             CApp = CApp + '  VOID    *OriginalPcd;\n'
 | |
|             CApp = CApp + '  %s      *Pcd;  // From %s Line %d \n' % (Pcd.DatumType, Pcd.PkgPath, Pcd.PcdDefineLineNo)
 | |
|             CApp = CApp + '\n'
 | |
| 
 | |
|             if SkuName in Pcd.SkuInfoList:
 | |
|                 DefaultValue = Pcd.SkuInfoList[SkuName].DefaultStoreDict.get(DefaultStoreName,Pcd.SkuInfoList[SkuName].HiiDefaultValue if Pcd.SkuInfoList[SkuName].HiiDefaultValue  else Pcd.SkuInfoList[SkuName].DefaultValue)
 | |
|             else:
 | |
|                 DefaultValue = Pcd.DefaultValue
 | |
|             PcdDefaultValue = StringToArray(DefaultValue.strip())
 | |
| 
 | |
|             InitByteValue += '%s.%s.%s.%s|%s|%s\n' % (SkuName, DefaultStoreName, Pcd.TokenSpaceGuidCName, Pcd.TokenCName, Pcd.DatumType, PcdDefaultValue)
 | |
| 
 | |
|             #
 | |
|             # Get current PCD value and size
 | |
|             #
 | |
|             CApp = CApp + '  OriginalPcd = PcdGetPtr (%s, %s, %s, %s, &OriginalSize);\n' % (SkuName, DefaultStoreName, Pcd.TokenSpaceGuidCName, Pcd.TokenCName)
 | |
| 
 | |
|             #
 | |
|             # 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 + self.GenerateSizeStatments(Pcd)
 | |
| 
 | |
|             #
 | |
|             # 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 + '  Pcd     = (%s *)malloc (Size);\n' % (Pcd.DatumType)
 | |
|             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
 | |
|             #
 | |
|             CApp = CApp + self.GenerateDefaultValueAssignStatement(Pcd)
 | |
|             if Pcd.Type not in [self._PCD_TYPE_STRING_[MODEL_PCD_FIXED_AT_BUILD],
 | |
|                         self._PCD_TYPE_STRING_[MODEL_PCD_PATCHABLE_IN_MODULE]]:
 | |
|                 for skuname in self.SkuIdMgr.GetSkuChain(SkuName):
 | |
|                     storeset = [DefaultStoreName] if DefaultStoreName == 'STANDARD' else ['STANDARD', DefaultStoreName]
 | |
|                     for defaultstorenameitem in storeset:
 | |
|                         CApp = CApp + "// SkuName: %s,  DefaultStoreName: %s \n" % (skuname, defaultstorenameitem)
 | |
|                         CApp = CApp + self.GenerateInitValueStatement(Pcd,skuname,defaultstorenameitem)
 | |
|                     if skuname == SkuName:
 | |
|                         break
 | |
|             else:
 | |
|                 CApp = CApp + "// SkuName: %s,  DefaultStoreName: STANDARD \n" % self.SkuIdMgr.SystemSkuId
 | |
|                 CApp = CApp + self.GenerateInitValueStatement(Pcd,self.SkuIdMgr.SystemSkuId,"STANDARD")
 | |
|             CApp = CApp + self.GenerateCommandLineValueStatement(Pcd)
 | |
|             #
 | |
|             # Set new PCD value and size
 | |
|             #
 | |
|             CApp = CApp + '  PcdSetPtr (%s, %s, %s, %s, Size, (UINT8 *)Pcd);\n' % (SkuName, DefaultStoreName, Pcd.TokenSpaceGuidCName, Pcd.TokenCName)
 | |
| 
 | |
|             #
 | |
|             # Free PCD
 | |
|             #
 | |
|             CApp = CApp + '  free (Pcd);\n'
 | |
|             CApp = CApp + '}\n'
 | |
|             CApp = CApp + '\n'
 | |
|         return InitByteValue, CApp
 | |
| 
 | |
|     def GenerateByteArrayValue (self, StructuredPcds):
 | |
|         #
 | |
|         # Generate/Compile/Run C application to determine if there are any flexible array members
 | |
|         #
 | |
|         if not StructuredPcds:
 | |
|             return
 | |
| 
 | |
|         InitByteValue = ""
 | |
|         CApp = PcdMainCHeader
 | |
| 
 | |
|         Includes = {}
 | |
|         IncludeFiles = set()
 | |
|         for PcdName in StructuredPcds:
 | |
|             Pcd = StructuredPcds[PcdName]
 | |
|             for IncludeFile in Pcd.StructuredPcdIncludeFile:
 | |
|                 if IncludeFile not in Includes:
 | |
|                     Includes[IncludeFile] = True
 | |
|                     IncludeFiles.add(IncludeFile)
 | |
|                     CApp = CApp + '#include <%s>\n' % (IncludeFile)
 | |
|         CApp = CApp + '\n'
 | |
|         for PcdName in StructuredPcds:
 | |
|             Pcd = StructuredPcds[PcdName]
 | |
|             CApp = CApp + self.GenerateSizeFunction(Pcd)
 | |
|             CApp = CApp + self.GenerateDefaultValueAssignFunction(Pcd)
 | |
|             CApp = CApp + self.GenerateCommandLineValue(Pcd)
 | |
|             if not Pcd.SkuOverrideValues or Pcd.Type in [self._PCD_TYPE_STRING_[MODEL_PCD_FIXED_AT_BUILD],
 | |
|                         self._PCD_TYPE_STRING_[MODEL_PCD_PATCHABLE_IN_MODULE]]:
 | |
|                 CApp = CApp + self.GenerateInitValueFunction(Pcd,self.SkuIdMgr.SystemSkuId, 'STANDARD')
 | |
|             else:
 | |
|                 for SkuName in self.SkuIdMgr.SkuOverrideOrder():
 | |
|                     if SkuName not in Pcd.SkuOverrideValues:
 | |
|                         continue
 | |
|                     for DefaultStoreName in Pcd.SkuOverrideValues[SkuName]:
 | |
|                         CApp = CApp + self.GenerateInitValueFunction(Pcd,SkuName,DefaultStoreName)
 | |
|             if not Pcd.SkuOverrideValues or Pcd.Type in [self._PCD_TYPE_STRING_[MODEL_PCD_FIXED_AT_BUILD],
 | |
|                         self._PCD_TYPE_STRING_[MODEL_PCD_PATCHABLE_IN_MODULE]]:
 | |
|                 InitByteValue, CApp = self.GenerateInitializeFunc(self.SkuIdMgr.SystemSkuId, 'STANDARD', Pcd, InitByteValue, CApp)
 | |
|             else:
 | |
|                 for SkuName in self.SkuIdMgr.SkuOverrideOrder():
 | |
|                     if SkuName not in Pcd.SkuOverrideValues:
 | |
|                         continue
 | |
|                     for DefaultStoreName in Pcd.DefaultStoreName:
 | |
|                         Pcd = StructuredPcds[PcdName]
 | |
|                         InitByteValue, CApp = self.GenerateInitializeFunc(SkuName, DefaultStoreName, Pcd, InitByteValue, CApp)
 | |
| 
 | |
|         CApp = CApp + 'VOID\n'
 | |
|         CApp = CApp + 'PcdEntryPoint(\n'
 | |
|         CApp = CApp + '  VOID\n'
 | |
|         CApp = CApp + '  )\n'
 | |
|         CApp = CApp + '{\n'
 | |
|         for Pcd in StructuredPcds.values():
 | |
|             if not Pcd.SkuOverrideValues or Pcd.Type in [self._PCD_TYPE_STRING_[MODEL_PCD_FIXED_AT_BUILD],self._PCD_TYPE_STRING_[MODEL_PCD_PATCHABLE_IN_MODULE]]:
 | |
|                 CApp = CApp + '  Initialize_%s_%s_%s_%s();\n' % (self.SkuIdMgr.SystemSkuId, 'STANDARD', Pcd.TokenSpaceGuidCName, Pcd.TokenCName)
 | |
|             else:
 | |
|                 for SkuName in self.SkuIdMgr.SkuOverrideOrder():
 | |
|                     if SkuName not in Pcd.SkuOverrideValues:
 | |
|                         continue
 | |
|                     for DefaultStoreName in Pcd.SkuOverrideValues[SkuName]:
 | |
|                         CApp = CApp + '  Initialize_%s_%s_%s_%s();\n' % (SkuName, DefaultStoreName, Pcd.TokenSpaceGuidCName, Pcd.TokenCName)
 | |
|         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)
 | |
|         SaveFileOnChange(CAppBaseFileName + '.c', CApp, False)
 | |
| 
 | |
|         MakeApp = PcdMakefileHeader
 | |
|         if sys.platform == "win32":
 | |
|             MakeApp = MakeApp + 'APPNAME = %s\n' % (PcdValueInitName) + 'OBJECTS = %s\%s.obj\n' % (self.OutputPath, PcdValueInitName) + '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' + 'INCLUDE +='
 | |
| 
 | |
|         IncSearchList = []
 | |
|         PlatformInc = {}
 | |
|         for Cache in self._Bdb._CACHE_.values():
 | |
|             if Cache.MetaFile.Ext.lower() != '.dec':
 | |
|                 continue
 | |
|             if Cache.Includes:
 | |
|                 if str(Cache.MetaFile.Path) not in PlatformInc:
 | |
|                     PlatformInc[str(Cache.MetaFile.Path)] = []
 | |
|                     PlatformInc[str(Cache.MetaFile.Path)].append (os.path.dirname(Cache.MetaFile.Path))
 | |
|                     PlatformInc[str(Cache.MetaFile.Path)].extend (Cache.CommonIncludes)
 | |
| 
 | |
|         PcdDependDEC = []
 | |
|         for Pcd in StructuredPcds.values():
 | |
|             for PackageDec in Pcd.PackageDecs:
 | |
|                 Package = os.path.normpath(mws.join(GlobalData.gWorkspace, PackageDec))
 | |
|                 if not os.path.exists(Package):
 | |
|                     EdkLogger.error('Build', RESOURCE_NOT_AVAILABLE, "The dependent Package %s of PCD %s.%s is not exist." % (PackageDec, Pcd.TokenSpaceGuidCName, Pcd.TokenCName))
 | |
|                 if Package not in PcdDependDEC:
 | |
|                     PcdDependDEC.append(Package)
 | |
| 
 | |
|         if PlatformInc and PcdDependDEC:
 | |
|             for pkg in PcdDependDEC:
 | |
|                 if pkg in PlatformInc:
 | |
|                     for inc in PlatformInc[pkg]:
 | |
|                         MakeApp += '-I'  + str(inc) + ' '
 | |
|                         IncSearchList.append(inc)
 | |
|         MakeApp = MakeApp + '\n'
 | |
| 
 | |
|         CC_FLAGS = LinuxCFLAGS
 | |
|         if sys.platform == "win32":
 | |
|             CC_FLAGS = WindowsCFLAGS
 | |
|         BuildOptions = {}
 | |
|         for Options in self.BuildOptions:
 | |
|             if Options[2] != EDKII_NAME:
 | |
|                 continue
 | |
|             Family = Options[0]
 | |
|             if Family and Family != self.ToolChainFamily:
 | |
|                 continue
 | |
|             Target, Tag, Arch, Tool, Attr = Options[1].split("_")
 | |
|             if Tool != 'CC':
 | |
|                 continue
 | |
| 
 | |
|             if Target == "*" or Target == self._Target:
 | |
|                 if Tag == "*" or Tag == self._Toolchain:
 | |
|                     if Arch == "*" or Arch == self.Arch:
 | |
|                         if Tool not in BuildOptions:
 | |
|                             BuildOptions[Tool] = {}
 | |
|                         if Attr != "FLAGS" or Attr not in BuildOptions[Tool] or self.BuildOptions[Options].startswith('='):
 | |
|                             BuildOptions[Tool][Attr] = self.BuildOptions[Options]
 | |
|                         else:
 | |
|                             # append options for the same tool except PATH
 | |
|                             if Attr != 'PATH':
 | |
|                                 BuildOptions[Tool][Attr] += " " + self.BuildOptions[Options]
 | |
|                             else:
 | |
|                                 BuildOptions[Tool][Attr] = self.BuildOptions[Options]
 | |
|         if BuildOptions:
 | |
|             for Tool in BuildOptions:
 | |
|                 for Attr in BuildOptions[Tool]:
 | |
|                     if Attr == "FLAGS":
 | |
|                         Value = BuildOptions[Tool][Attr]
 | |
|                         ValueList = Value.split()
 | |
|                         if ValueList:
 | |
|                             for Id, Item in enumerate(ValueList):
 | |
|                                 if Item == '-D' or Item == '/D':
 | |
|                                     CC_FLAGS += ' ' + Item
 | |
|                                     if Id + 1 < len(ValueList):
 | |
|                                         CC_FLAGS += ' ' + ValueList[Id + 1]
 | |
|                                 elif Item.startswith('/D') or Item.startswith('-D'):
 | |
|                                     CC_FLAGS += ' ' + Item
 | |
|         MakeApp += CC_FLAGS
 | |
| 
 | |
|         if sys.platform == "win32":
 | |
|             MakeApp = MakeApp + PcdMakefileEnd
 | |
|         MakeApp = MakeApp + '\n'
 | |
|         IncludeFileFullPaths = []
 | |
|         for includefile in IncludeFiles:
 | |
|             for includepath in IncSearchList:
 | |
|                 includefullpath = os.path.join(str(includepath),includefile)
 | |
|                 if os.path.exists(includefullpath):
 | |
|                     IncludeFileFullPaths.append(os.path.normpath(includefullpath))
 | |
|                     break
 | |
|         SearchPathList = []
 | |
|         SearchPathList.append(os.path.normpath(mws.join(GlobalData.gWorkspace, "BaseTools/Source/C/Include")))
 | |
|         SearchPathList.append(os.path.normpath(mws.join(GlobalData.gWorkspace, "BaseTools/Source/C/Common")))
 | |
|         SearchPathList.extend([str(item) for item in IncSearchList])
 | |
|         IncFileList = GetDependencyList(IncludeFileFullPaths,SearchPathList)
 | |
|         for include_file in IncFileList:
 | |
|             MakeApp += "$(OBJECTS) : %s\n" % include_file
 | |
|         MakeFileName = os.path.join(self.OutputPath, 'Makefile')
 | |
|         MakeApp += "$(OBJECTS) : %s\n" % MakeFileName
 | |
|         SaveFileOnChange(MakeFileName, MakeApp, False)
 | |
| 
 | |
|         InputValueFile = os.path.join(self.OutputPath, 'Input.txt')
 | |
|         OutputValueFile = os.path.join(self.OutputPath, 'Output.txt')
 | |
|         SaveFileOnChange(InputValueFile, InitByteValue, False)
 | |
| 
 | |
|         PcdValueInitExe = PcdValueInitName
 | |
|         if not sys.platform == "win32":
 | |
|             PcdValueInitExe = os.path.join(os.getenv("EDK_TOOLS_PATH"), 'Source', 'C', 'bin', PcdValueInitName)
 | |
|         else:
 | |
|             PcdValueInitExe = os.path.join(os.getenv("EDK_TOOLS_PATH"), 'Bin', 'Win32', PcdValueInitName) +".exe"
 | |
| 
 | |
|         Messages = ''
 | |
|         if sys.platform == "win32":
 | |
|             MakeCommand = 'nmake -f %s' % (MakeFileName)
 | |
|             returncode, StdOut, StdErr = self.ExecuteCommand (MakeCommand)
 | |
|             Messages = StdOut
 | |
|         else:
 | |
|             MakeCommand = 'make -f %s' % (MakeFileName)
 | |
|             returncode, StdOut, StdErr = self.ExecuteCommand (MakeCommand)
 | |
|             Messages = StdErr
 | |
|         Messages = Messages.split('\n')
 | |
|         MessageGroup = []
 | |
|         if returncode <>0:
 | |
|             CAppBaseFileName = os.path.join(self.OutputPath, PcdValueInitName)
 | |
|             File = open (CAppBaseFileName + '.c', 'r')
 | |
|             FileData = File.readlines()
 | |
|             File.close()
 | |
|             for Message in Messages:
 | |
|                 if " error" in Message or "warning" in Message:
 | |
|                     FileInfo = Message.strip().split('(')
 | |
|                     if len (FileInfo) > 1:
 | |
|                         FileName = FileInfo [0]
 | |
|                         FileLine = FileInfo [1].split (')')[0]
 | |
|                     else:
 | |
|                         FileInfo = Message.strip().split(':')
 | |
|                         FileName = FileInfo [0]
 | |
|                         FileLine = FileInfo [1]
 | |
|                     if FileLine.isdigit():
 | |
|                         error_line = FileData[int (FileLine) - 1]
 | |
|                         if r"//" in error_line:
 | |
|                             c_line,dsc_line = error_line.split(r"//")
 | |
|                         else:
 | |
|                             dsc_line = error_line
 | |
|                         message_itmes = Message.split(":")
 | |
|                         Index = 0
 | |
|                         if "PcdValueInit.c" not in Message:
 | |
|                             if not MessageGroup:
 | |
|                                 MessageGroup.append(Message)
 | |
|                             break
 | |
|                         else:
 | |
|                             for item in message_itmes:
 | |
|                                 if "PcdValueInit.c" in item:
 | |
|                                     Index = message_itmes.index(item)
 | |
|                                     message_itmes[Index] = dsc_line.strip()
 | |
|                                     break
 | |
|                             MessageGroup.append(":".join(message_itmes[Index:]).strip())
 | |
|                             continue
 | |
|                     else:
 | |
|                         MessageGroup.append(Message)
 | |
|             if MessageGroup:
 | |
|                 EdkLogger.error("build", PCD_STRUCTURE_PCD_ERROR, "\n".join(MessageGroup) )
 | |
|             else:
 | |
|                 EdkLogger.error('Build', COMMAND_FAILURE, 'Can not execute command: %s' % MakeCommand)
 | |
| 
 | |
|         if self.NeedUpdateOutput(OutputValueFile, PcdValueInitExe ,InputValueFile):
 | |
|             Command = PcdValueInitExe + ' -i %s -o %s' % (InputValueFile, OutputValueFile)
 | |
|             returncode, StdOut, StdErr = self.ExecuteCommand (Command)
 | |
|             if returncode <> 0:
 | |
|                 EdkLogger.warn('Build', COMMAND_FAILURE, 'Can not collect output from command: %s' % Command)
 | |
| 
 | |
|         File = open (OutputValueFile, 'r')
 | |
|         FileBuffer = File.readlines()
 | |
|         File.close()
 | |
| 
 | |
|         StructurePcdSet = []
 | |
|         for Pcd in FileBuffer:
 | |
|             PcdValue = Pcd.split ('|')
 | |
|             PcdInfo = PcdValue[0].split ('.')
 | |
|             StructurePcdSet.append((PcdInfo[0],PcdInfo[1], PcdInfo[2], PcdInfo[3], PcdValue[2].strip()))
 | |
|         return StructurePcdSet
 | |
| 
 | |
|     def NeedUpdateOutput(self,OutputFile, ValueCFile, StructureInput):
 | |
|         if not os.path.exists(OutputFile):
 | |
|             return True
 | |
|         if os.stat(OutputFile).st_mtime <= os.stat(ValueCFile).st_mtime:
 | |
|             return True
 | |
|         if os.stat(OutputFile).st_mtime <= os.stat(StructureInput).st_mtime:
 | |
|             return True
 | |
|         return False
 | |
| 
 | |
|     ## Retrieve dynamic PCD settings
 | |
|     #
 | |
|     #   @param  Type    PCD type
 | |
|     #
 | |
|     #   @retval a dict object contains settings of given PCD type
 | |
|     #
 | |
|     def _GetDynamicPcd(self, Type):
 | |
| 
 | |
| 
 | |
|         Pcds = sdict()
 | |
|         #
 | |
|         # tdict is a special dict kind of type, used for selecting correct
 | |
|         # PCD settings for certain ARCH and SKU
 | |
|         #
 | |
|         PcdDict = tdict(True, 4)
 | |
|         PcdList = []
 | |
|         # Find out all possible PCD candidates for self._Arch
 | |
|         RecordList = self._RawData[Type, self._Arch]
 | |
|         AvailableSkuIdSet = copy.copy(self.SkuIds)
 | |
| 
 | |
| 
 | |
|         for TokenSpaceGuid, PcdCName, Setting, Arch, SkuName, Dummy3, Dummy4,Dummy5 in RecordList:
 | |
|             SkuName = SkuName.upper()
 | |
|             SkuName = 'DEFAULT' if SkuName == 'COMMON' else SkuName
 | |
|             if SkuName not in AvailableSkuIdSet:
 | |
|                 EdkLogger.error('build', PARAMETER_INVALID, 'Sku %s is not defined in [SkuIds] section' % SkuName,
 | |
|                                             File=self.MetaFile, Line=Dummy5)
 | |
|             if "." not in TokenSpaceGuid:
 | |
|                 PcdList.append((PcdCName, TokenSpaceGuid, SkuName, Dummy5))
 | |
|             PcdDict[Arch, SkuName, PcdCName, TokenSpaceGuid] = Setting
 | |
| 
 | |
|         # Remove redundant PCD candidates, per the ARCH and SKU
 | |
|         for PcdCName, TokenSpaceGuid, SkuName, Dummy4 in PcdList:
 | |
| 
 | |
|             Setting = PcdDict[self._Arch, SkuName, PcdCName, TokenSpaceGuid]
 | |
|             if Setting is None:
 | |
|                 continue
 | |
| 
 | |
|             PcdValue, DatumType, MaxDatumSize = self._ValidatePcd(PcdCName, TokenSpaceGuid, Setting, Type, Dummy4)
 | |
|             SkuInfo = SkuInfoClass(SkuName, self.SkuIds[SkuName][0], '', '', '', '', '', PcdValue)
 | |
|             if (PcdCName, TokenSpaceGuid) in Pcds.keys():
 | |
|                 pcdObject = Pcds[PcdCName, TokenSpaceGuid]
 | |
|                 pcdObject.SkuInfoList[SkuName] = SkuInfo
 | |
|                 if MaxDatumSize.strip():
 | |
|                     CurrentMaxSize = int(MaxDatumSize.strip(), 0)
 | |
|                 else:
 | |
|                     CurrentMaxSize = 0
 | |
|                 if pcdObject.MaxDatumSize:
 | |
|                     PcdMaxSize = int(pcdObject.MaxDatumSize, 0)
 | |
|                 else:
 | |
|                     PcdMaxSize = 0
 | |
|                 if CurrentMaxSize > PcdMaxSize:
 | |
|                     pcdObject.MaxDatumSize = str(CurrentMaxSize)
 | |
|             else:
 | |
|                 Pcds[PcdCName, TokenSpaceGuid] = PcdClassObject(
 | |
|                                                     PcdCName,
 | |
|                                                     TokenSpaceGuid,
 | |
|                                                     self._PCD_TYPE_STRING_[Type],
 | |
|                                                     DatumType,
 | |
|                                                     PcdValue,
 | |
|                                                     '',
 | |
|                                                     MaxDatumSize,
 | |
|                                                     {SkuName : SkuInfo},
 | |
|                                                     False,
 | |
|                                                     None,
 | |
|                                                     IsDsc=True)
 | |
| 
 | |
|         for pcd in Pcds.values():
 | |
|             pcdDecObject = self._DecPcds[pcd.TokenCName, pcd.TokenSpaceGuidCName]
 | |
|             # Only fix the value while no value provided in DSC file.
 | |
|             for sku in pcd.SkuInfoList.values():
 | |
|                 if (sku.DefaultValue == "" or sku.DefaultValue==None):
 | |
|                     sku.DefaultValue = pcdDecObject.DefaultValue
 | |
|             if 'DEFAULT' not in pcd.SkuInfoList.keys() and 'COMMON' not in pcd.SkuInfoList.keys():
 | |
|                 valuefromDec = pcdDecObject.DefaultValue
 | |
|                 SkuInfo = SkuInfoClass('DEFAULT', '0', '', '', '', '', '', valuefromDec)
 | |
|                 pcd.SkuInfoList['DEFAULT'] = SkuInfo
 | |
|             elif 'DEFAULT' not in pcd.SkuInfoList.keys() and 'COMMON' in pcd.SkuInfoList.keys():
 | |
|                 pcd.SkuInfoList['DEFAULT'] = pcd.SkuInfoList['COMMON']
 | |
|                 del(pcd.SkuInfoList['COMMON'])
 | |
|             elif 'DEFAULT' in pcd.SkuInfoList.keys() and 'COMMON' in pcd.SkuInfoList.keys():
 | |
|                 del(pcd.SkuInfoList['COMMON'])
 | |
| 
 | |
|         map(self.FilterSkuSettings,Pcds.values())
 | |
| 
 | |
|         return Pcds
 | |
| 
 | |
|     def FilterSkuSettings(self, PcdObj):
 | |
| 
 | |
|         if self.SkuIdMgr.SkuUsageType == self.SkuIdMgr.SINGLE:
 | |
|             if 'DEFAULT' in PcdObj.SkuInfoList.keys() and self.SkuIdMgr.SystemSkuId not in PcdObj.SkuInfoList.keys():
 | |
|                 PcdObj.SkuInfoList[self.SkuIdMgr.SystemSkuId] = PcdObj.SkuInfoList['DEFAULT']
 | |
|             PcdObj.SkuInfoList = {'DEFAULT':PcdObj.SkuInfoList[self.SkuIdMgr.SystemSkuId]}
 | |
|             PcdObj.SkuInfoList['DEFAULT'].SkuIdName = 'DEFAULT'
 | |
|             PcdObj.SkuInfoList['DEFAULT'].SkuId = '0'
 | |
| 
 | |
|         elif self.SkuIdMgr.SkuUsageType == self.SkuIdMgr.DEFAULT:
 | |
|             PcdObj.SkuInfoList = {'DEFAULT':PcdObj.SkuInfoList['DEFAULT']}
 | |
| 
 | |
|         return PcdObj
 | |
| 
 | |
| 
 | |
|     def CompareVarAttr(self, Attr1, Attr2):
 | |
|         if not Attr1 or not Attr2:  # for empty string
 | |
|             return True
 | |
|         Attr1s = [attr.strip() for attr in Attr1.split(",")]
 | |
|         Attr1Set = set(Attr1s)
 | |
|         Attr2s = [attr.strip() for attr in Attr2.split(",")]
 | |
|         Attr2Set = set(Attr2s)
 | |
|         if Attr2Set == Attr1Set:
 | |
|             return True
 | |
|         else:
 | |
|             return False
 | |
|     def CopyDscRawValue(self,Pcd):
 | |
|         if Pcd.DscRawValue is None:
 | |
|             Pcd.DscRawValue = dict()
 | |
|         if Pcd.Type in [self._PCD_TYPE_STRING_[MODEL_PCD_FIXED_AT_BUILD], self._PCD_TYPE_STRING_[MODEL_PCD_PATCHABLE_IN_MODULE]]:
 | |
|             if self.SkuIdMgr.SystemSkuId not in Pcd.DscRawValue:
 | |
|                 Pcd.DscRawValue[self.SkuIdMgr.SystemSkuId] = {}
 | |
|             Pcd.DscRawValue[self.SkuIdMgr.SystemSkuId]['STANDARD'] = Pcd.DefaultValue
 | |
|         for skuname in Pcd.SkuInfoList:
 | |
|             Pcd.DscRawValue[skuname] = {}
 | |
|             if Pcd.Type in [self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII], self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_HII]]:
 | |
|                 for defaultstore in Pcd.SkuInfoList[skuname].DefaultStoreDict:
 | |
|                     Pcd.DscRawValue[skuname][defaultstore] = Pcd.SkuInfoList[skuname].DefaultStoreDict[defaultstore]
 | |
|             else:
 | |
|                 Pcd.DscRawValue[skuname]['STANDARD'] = Pcd.SkuInfoList[skuname].DefaultValue
 | |
|     def CompletePcdValues(self,PcdSet):
 | |
|         Pcds = {}
 | |
|         DefaultStoreObj = DefaultStore(self._GetDefaultStores())
 | |
|         SkuIds = {skuname:skuid for skuname,skuid in self.SkuIdMgr.AvailableSkuIdSet.items() if skuname !='COMMON'}
 | |
|         DefaultStores = set([storename for pcdobj in PcdSet.values() for skuobj in pcdobj.SkuInfoList.values() for storename in skuobj.DefaultStoreDict.keys()])
 | |
|         for PcdCName, TokenSpaceGuid in PcdSet:
 | |
|             PcdObj = PcdSet[(PcdCName, TokenSpaceGuid)]
 | |
|             self.CopyDscRawValue(PcdObj)
 | |
|             if PcdObj.Type not in [self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_DEFAULT],
 | |
|                         self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII],
 | |
|                         self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_VPD],
 | |
|                         self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_DEFAULT],
 | |
|                         self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_HII],
 | |
|                         self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_VPD]]:
 | |
|                 Pcds[PcdCName, TokenSpaceGuid]= PcdObj
 | |
|                 continue
 | |
|             PcdType = PcdObj.Type
 | |
|             if PcdType in [self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII], self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_HII]]:
 | |
|                 for skuid in PcdObj.SkuInfoList:
 | |
|                     skuobj = PcdObj.SkuInfoList[skuid]
 | |
|                     mindefaultstorename = DefaultStoreObj.GetMin(set([defaultstorename  for defaultstorename in skuobj.DefaultStoreDict]))
 | |
|                     for defaultstorename in DefaultStores:
 | |
|                         if defaultstorename not in skuobj.DefaultStoreDict:
 | |
|                             skuobj.DefaultStoreDict[defaultstorename] = copy.deepcopy(skuobj.DefaultStoreDict[mindefaultstorename])
 | |
|                     skuobj.HiiDefaultValue = skuobj.DefaultStoreDict[mindefaultstorename]
 | |
|             for skuname,skuid in SkuIds.items():
 | |
|                 if skuname not in PcdObj.SkuInfoList:
 | |
|                     nextskuid = self.SkuIdMgr.GetNextSkuId(skuname)
 | |
|                     while nextskuid not in PcdObj.SkuInfoList:
 | |
|                         nextskuid = self.SkuIdMgr.GetNextSkuId(nextskuid)
 | |
|                     PcdObj.SkuInfoList[skuname] = copy.deepcopy(PcdObj.SkuInfoList[nextskuid])
 | |
|                     PcdObj.SkuInfoList[skuname].SkuId = skuid
 | |
|                     PcdObj.SkuInfoList[skuname].SkuIdName = skuname
 | |
|             if PcdType in [self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII], self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_HII]]:
 | |
|                 PcdObj.DefaultValue = PcdObj.SkuInfoList.values()[0].HiiDefaultValue if self.SkuIdMgr.SkuUsageType == self.SkuIdMgr.SINGLE else PcdObj.SkuInfoList["DEFAULT"].HiiDefaultValue
 | |
|             Pcds[PcdCName, TokenSpaceGuid]= PcdObj
 | |
|         return Pcds
 | |
|     ## Retrieve dynamic HII PCD settings
 | |
|     #
 | |
|     #   @param  Type    PCD type
 | |
|     #
 | |
|     #   @retval a dict object contains settings of given PCD type
 | |
|     #
 | |
|     def _GetDynamicHiiPcd(self, Type):
 | |
| 
 | |
|         VariableAttrs = {}
 | |
| 
 | |
|         Pcds = sdict()
 | |
|         #
 | |
|         # tdict is a special dict kind of type, used for selecting correct
 | |
|         # PCD settings for certain ARCH and SKU
 | |
|         #
 | |
|         PcdDict = tdict(True, 5)
 | |
|         PcdSet = set()
 | |
|         RecordList = self._RawData[Type, self._Arch]
 | |
|         # Find out all possible PCD candidates for self._Arch
 | |
|         AvailableSkuIdSet = copy.copy(self.SkuIds)
 | |
|         DefaultStoresDefine = self._GetDefaultStores()
 | |
| 
 | |
|         for TokenSpaceGuid, PcdCName, Setting, Arch, SkuName, DefaultStore, Dummy4,Dummy5 in RecordList:
 | |
|             SkuName = SkuName.upper()
 | |
|             SkuName = 'DEFAULT' if SkuName == 'COMMON' else SkuName
 | |
|             DefaultStore = DefaultStore.upper()
 | |
|             if DefaultStore == "COMMON":
 | |
|                 DefaultStore = "STANDARD"
 | |
|             if SkuName not in AvailableSkuIdSet:
 | |
|                 EdkLogger.error('build', PARAMETER_INVALID, 'Sku %s is not defined in [SkuIds] section' % SkuName,
 | |
|                                             File=self.MetaFile, Line=Dummy5)
 | |
|             if DefaultStore not in DefaultStoresDefine:
 | |
|                 EdkLogger.error('build', PARAMETER_INVALID, 'DefaultStores %s is not defined in [DefaultStores] section' % DefaultStore,
 | |
|                                             File=self.MetaFile, Line=Dummy5)
 | |
|             if "." not in TokenSpaceGuid:
 | |
|                 PcdSet.add((PcdCName, TokenSpaceGuid, SkuName,DefaultStore, Dummy5))
 | |
|             PcdDict[Arch, SkuName, PcdCName, TokenSpaceGuid,DefaultStore] = Setting
 | |
| 
 | |
| 
 | |
|         # Remove redundant PCD candidates, per the ARCH and SKU
 | |
|         for PcdCName, TokenSpaceGuid, SkuName,DefaultStore, Dummy4 in PcdSet:
 | |
| 
 | |
|             Setting = PcdDict[self._Arch, SkuName, PcdCName, TokenSpaceGuid,DefaultStore]
 | |
|             if Setting is None:
 | |
|                 continue
 | |
|             VariableName, VariableGuid, VariableOffset, DefaultValue, VarAttribute = self._ValidatePcd(PcdCName, TokenSpaceGuid, Setting, Type, Dummy4)
 | |
| 
 | |
|             rt, Msg = VariableAttributes.ValidateVarAttributes(VarAttribute)
 | |
|             if not rt:
 | |
|                 EdkLogger.error("build", PCD_VARIABLE_ATTRIBUTES_ERROR, "Variable attributes settings for %s is incorrect.\n %s" % (".".join((TokenSpaceGuid, PcdCName)), Msg),
 | |
|                         ExtraData="[%s]" % VarAttribute)
 | |
|             ExceedMax = False
 | |
|             FormatCorrect = True
 | |
|             if VariableOffset.isdigit():
 | |
|                 if int(VariableOffset, 10) > 0xFFFF:
 | |
|                     ExceedMax = True
 | |
|             elif re.match(r'[\t\s]*0[xX][a-fA-F0-9]+$', VariableOffset):
 | |
|                 if int(VariableOffset, 16) > 0xFFFF:
 | |
|                     ExceedMax = True
 | |
|             # For Offset written in "A.B"
 | |
|             elif VariableOffset.find('.') > -1:
 | |
|                 VariableOffsetList = VariableOffset.split(".")
 | |
|                 if not (len(VariableOffsetList) == 2
 | |
|                         and IsValidWord(VariableOffsetList[0])
 | |
|                         and IsValidWord(VariableOffsetList[1])):
 | |
|                     FormatCorrect = False
 | |
|             else:
 | |
|                 FormatCorrect = False
 | |
|             if not FormatCorrect:
 | |
|                 EdkLogger.error('Build', FORMAT_INVALID, "Invalid syntax or format of the variable offset value is incorrect for %s." % ".".join((TokenSpaceGuid, PcdCName)))
 | |
| 
 | |
|             if ExceedMax:
 | |
|                 EdkLogger.error('Build', OPTION_VALUE_INVALID, "The variable offset value must not exceed the maximum value of 0xFFFF (UINT16) for %s." % ".".join((TokenSpaceGuid, PcdCName)))
 | |
|             if (VariableName, VariableGuid) not in VariableAttrs:
 | |
|                 VariableAttrs[(VariableName, VariableGuid)] = VarAttribute
 | |
|             else:
 | |
|                 if not self.CompareVarAttr(VariableAttrs[(VariableName, VariableGuid)], VarAttribute):
 | |
|                     EdkLogger.error('Build', PCD_VARIABLE_ATTRIBUTES_CONFLICT_ERROR, "The variable %s.%s for DynamicHii PCDs has conflicting attributes [%s] and [%s] " % (VariableGuid, VariableName, VarAttribute, VariableAttrs[(VariableName, VariableGuid)]))
 | |
| 
 | |
|             pcdDecObject = self._DecPcds[PcdCName, TokenSpaceGuid]
 | |
|             if (PcdCName, TokenSpaceGuid) in Pcds.keys():
 | |
|                 pcdObject = Pcds[PcdCName, TokenSpaceGuid]
 | |
|                 if SkuName in pcdObject.SkuInfoList:
 | |
|                     Skuitem = pcdObject.SkuInfoList[SkuName]
 | |
|                     Skuitem.DefaultStoreDict.update({DefaultStore:DefaultValue})
 | |
|                 else:
 | |
|                     SkuInfo = SkuInfoClass(SkuName, self.SkuIds[SkuName][0], VariableName, VariableGuid, VariableOffset, DefaultValue, VariableAttribute=VarAttribute,DefaultStore={DefaultStore:DefaultValue})
 | |
|                     pcdObject.SkuInfoList[SkuName] = SkuInfo
 | |
|             else:
 | |
|                 SkuInfo = SkuInfoClass(SkuName, self.SkuIds[SkuName][0], VariableName, VariableGuid, VariableOffset, DefaultValue, VariableAttribute=VarAttribute,DefaultStore={DefaultStore:DefaultValue})
 | |
|                 Pcds[PcdCName, TokenSpaceGuid] = PcdClassObject(
 | |
|                                                 PcdCName,
 | |
|                                                 TokenSpaceGuid,
 | |
|                                                 self._PCD_TYPE_STRING_[Type],
 | |
|                                                 '',
 | |
|                                                 DefaultValue,
 | |
|                                                 '',
 | |
|                                                 '',
 | |
|                                                 {SkuName : SkuInfo},
 | |
|                                                 False,
 | |
|                                                 None,
 | |
|                                                 pcdDecObject.validateranges,
 | |
|                                                 pcdDecObject.validlists,
 | |
|                                                 pcdDecObject.expressions,
 | |
|                                                 IsDsc=True)
 | |
| 
 | |
| 
 | |
|         for pcd in Pcds.values():
 | |
|             SkuInfoObj = pcd.SkuInfoList.values()[0]
 | |
|             pcdDecObject = self._DecPcds[pcd.TokenCName, pcd.TokenSpaceGuidCName]
 | |
|             pcd.DatumType = pcdDecObject.DatumType
 | |
|             # Only fix the value while no value provided in DSC file.
 | |
|             for sku in pcd.SkuInfoList.values():
 | |
|                 if (sku.HiiDefaultValue == "" or sku.HiiDefaultValue is None):
 | |
|                     sku.HiiDefaultValue = pcdDecObject.DefaultValue
 | |
|                     for default_store in sku.DefaultStoreDict:
 | |
|                         sku.DefaultStoreDict[default_store]=pcdDecObject.DefaultValue
 | |
|                     pcd.DefaultValue = pcdDecObject.DefaultValue
 | |
|             if 'DEFAULT' not in pcd.SkuInfoList.keys() and 'COMMON' not in pcd.SkuInfoList.keys():
 | |
|                 valuefromDec = pcdDecObject.DefaultValue
 | |
|                 SkuInfo = SkuInfoClass('DEFAULT', '0', SkuInfoObj.VariableName, SkuInfoObj.VariableGuid, SkuInfoObj.VariableOffset, valuefromDec,VariableAttribute=SkuInfoObj.VariableAttribute,DefaultStore={DefaultStore:valuefromDec})
 | |
|                 pcd.SkuInfoList['DEFAULT'] = SkuInfo
 | |
|             elif 'DEFAULT' not in pcd.SkuInfoList.keys() and 'COMMON' in pcd.SkuInfoList.keys():
 | |
|                 pcd.SkuInfoList['DEFAULT'] = pcd.SkuInfoList['COMMON']
 | |
|                 del(pcd.SkuInfoList['COMMON'])
 | |
|             elif 'DEFAULT' in pcd.SkuInfoList.keys() and 'COMMON' in pcd.SkuInfoList.keys():
 | |
|                 del(pcd.SkuInfoList['COMMON'])
 | |
| 
 | |
|             if pcd.MaxDatumSize.strip():
 | |
|                 MaxSize = int(pcd.MaxDatumSize, 0)
 | |
|             else:
 | |
|                 MaxSize = 0
 | |
|             if pcd.DatumType not in ['BOOLEAN','UINT8','UINT16','UINT32','UINT64']:
 | |
|                 for (_, skuobj) in pcd.SkuInfoList.items():
 | |
|                     datalen = 0
 | |
|                     skuobj.HiiDefaultValue = StringToArray(skuobj.HiiDefaultValue)
 | |
|                     datalen = len(skuobj.HiiDefaultValue.split(","))
 | |
|                     if datalen > MaxSize:
 | |
|                         MaxSize = datalen
 | |
|                     for defaultst in skuobj.DefaultStoreDict:
 | |
|                         skuobj.DefaultStoreDict[defaultst] = StringToArray(skuobj.DefaultStoreDict[defaultst])
 | |
|                 pcd.DefaultValue = StringToArray(pcd.DefaultValue)
 | |
|                 pcd.MaxDatumSize = str(MaxSize)
 | |
|         rt, invalidhii = self.CheckVariableNameAssignment(Pcds)
 | |
|         if not rt:
 | |
|             invalidpcd = ",".join(invalidhii)
 | |
|             EdkLogger.error('build', PCD_VARIABLE_INFO_ERROR, Message='The same HII PCD must map to the same EFI variable for all SKUs', File=self.MetaFile, ExtraData=invalidpcd)
 | |
| 
 | |
|         map(self.FilterSkuSettings,Pcds.values())
 | |
| 
 | |
|         return Pcds
 | |
| 
 | |
|     def CheckVariableNameAssignment(self,Pcds):
 | |
|         invalidhii = []
 | |
|         for pcdname in Pcds:
 | |
|             pcd = Pcds[pcdname]
 | |
|             varnameset = set([sku.VariableName for (skuid,sku) in pcd.SkuInfoList.items()])
 | |
|             if len(varnameset) > 1:
 | |
|                 invalidhii.append(".".join((pcdname[1],pcdname[0])))
 | |
|         if len(invalidhii):
 | |
|             return False,invalidhii
 | |
|         else:
 | |
|             return True, []
 | |
|     ## Retrieve dynamic VPD PCD settings
 | |
|     #
 | |
|     #   @param  Type    PCD type
 | |
|     #
 | |
|     #   @retval a dict object contains settings of given PCD type
 | |
|     #
 | |
|     def _GetDynamicVpdPcd(self, Type):
 | |
| 
 | |
| 
 | |
|         Pcds = sdict()
 | |
|         #
 | |
|         # tdict is a special dict kind of type, used for selecting correct
 | |
|         # PCD settings for certain ARCH and SKU
 | |
|         #
 | |
|         PcdDict = tdict(True, 4)
 | |
|         PcdList = []
 | |
| 
 | |
|         # Find out all possible PCD candidates for self._Arch
 | |
|         RecordList = self._RawData[Type, self._Arch]
 | |
|         AvailableSkuIdSet = copy.copy(self.SkuIds)
 | |
| 
 | |
|         for TokenSpaceGuid, PcdCName, Setting, Arch, SkuName, Dummy3, Dummy4,Dummy5 in RecordList:
 | |
|             SkuName = SkuName.upper()
 | |
|             SkuName = 'DEFAULT' if SkuName == 'COMMON' else SkuName
 | |
|             if SkuName not in AvailableSkuIdSet:
 | |
|                 EdkLogger.error('build', PARAMETER_INVALID, 'Sku %s is not defined in [SkuIds] section' % SkuName,
 | |
|                                             File=self.MetaFile, Line=Dummy5)
 | |
|             if "." not in TokenSpaceGuid:
 | |
|                 PcdList.append((PcdCName, TokenSpaceGuid, SkuName, Dummy5))
 | |
|             PcdDict[Arch, SkuName, PcdCName, TokenSpaceGuid] = Setting
 | |
| 
 | |
|         # Remove redundant PCD candidates, per the ARCH and SKU
 | |
|         for PcdCName, TokenSpaceGuid, SkuName, Dummy4 in PcdList:
 | |
|             Setting = PcdDict[self._Arch, SkuName, PcdCName, TokenSpaceGuid]
 | |
|             if Setting is None:
 | |
|                 continue
 | |
|             #
 | |
|             # For the VOID* type, it can have optional data of MaxDatumSize and InitialValue
 | |
|             # For the Integer & Boolean type, the optional data can only be InitialValue.
 | |
|             # At this point, we put all the data into the PcdClssObject for we don't know the PCD's datumtype
 | |
|             # until the DEC parser has been called.
 | |
|             #
 | |
|             VpdOffset, MaxDatumSize, InitialValue = self._ValidatePcd(PcdCName, TokenSpaceGuid, Setting, Type, Dummy4)
 | |
|             SkuInfo = SkuInfoClass(SkuName, self.SkuIds[SkuName][0], '', '', '', '', VpdOffset, InitialValue)
 | |
|             if (PcdCName, TokenSpaceGuid) in Pcds.keys():
 | |
|                 pcdObject = Pcds[PcdCName, TokenSpaceGuid]
 | |
|                 pcdObject.SkuInfoList[SkuName] = SkuInfo
 | |
|                 if MaxDatumSize.strip():
 | |
|                     CurrentMaxSize = int(MaxDatumSize.strip(), 0)
 | |
|                 else:
 | |
|                     CurrentMaxSize = 0
 | |
|                 if pcdObject.MaxDatumSize:
 | |
|                     PcdMaxSize = int(pcdObject.MaxDatumSize, 0)
 | |
|                 else:
 | |
|                     PcdMaxSize = 0
 | |
|                 if CurrentMaxSize > PcdMaxSize:
 | |
|                     pcdObject.MaxDatumSize = str(CurrentMaxSize)
 | |
|             else:
 | |
|                 Pcds[PcdCName, TokenSpaceGuid] = PcdClassObject(
 | |
|                                                 PcdCName,
 | |
|                                                 TokenSpaceGuid,
 | |
|                                                 self._PCD_TYPE_STRING_[Type],
 | |
|                                                 '',
 | |
|                                                 InitialValue,
 | |
|                                                 '',
 | |
|                                                 MaxDatumSize,
 | |
|                                                 {SkuName : SkuInfo},
 | |
|                                                 False,
 | |
|                                                 None,
 | |
|                                                 IsDsc=True)
 | |
|         for pcd in Pcds.values():
 | |
|             SkuInfoObj = pcd.SkuInfoList.values()[0]
 | |
|             pcdDecObject = self._DecPcds[pcd.TokenCName, pcd.TokenSpaceGuidCName]
 | |
|             pcd.DatumType = pcdDecObject.DatumType
 | |
|             # Only fix the value while no value provided in DSC file.
 | |
|             for sku in pcd.SkuInfoList.values():
 | |
|                 if (sku.DefaultValue == "" or sku.DefaultValue==None):
 | |
|                     sku.DefaultValue = pcdDecObject.DefaultValue
 | |
|             if 'DEFAULT' not in pcd.SkuInfoList.keys() and 'COMMON' not in pcd.SkuInfoList.keys():
 | |
|                 valuefromDec = pcdDecObject.DefaultValue
 | |
|                 SkuInfo = SkuInfoClass('DEFAULT', '0', '', '', '', '', SkuInfoObj.VpdOffset, valuefromDec)
 | |
|                 pcd.SkuInfoList['DEFAULT'] = SkuInfo
 | |
|             elif 'DEFAULT' not in pcd.SkuInfoList.keys() and 'COMMON' in pcd.SkuInfoList.keys():
 | |
|                 pcd.SkuInfoList['DEFAULT'] = pcd.SkuInfoList['COMMON']
 | |
|                 del(pcd.SkuInfoList['COMMON'])
 | |
|             elif 'DEFAULT' in pcd.SkuInfoList.keys() and 'COMMON' in pcd.SkuInfoList.keys():
 | |
|                 del(pcd.SkuInfoList['COMMON'])
 | |
| 
 | |
| 
 | |
|         map(self.FilterSkuSettings,Pcds.values())
 | |
|         return Pcds
 | |
| 
 | |
|     ## Add external modules
 | |
|     #
 | |
|     #   The external modules are mostly those listed in FDF file, which don't
 | |
|     # need "build".
 | |
|     #
 | |
|     #   @param  FilePath    The path of module description file
 | |
|     #
 | |
|     def AddModule(self, FilePath):
 | |
|         FilePath = NormPath(FilePath)
 | |
|         if FilePath not in self.Modules:
 | |
|             Module = ModuleBuildClassObject()
 | |
|             Module.MetaFile = FilePath
 | |
|             self.Modules.append(Module)
 | |
| 
 | |
|     def _GetToolChainFamily(self):
 | |
|         self._ToolChainFamily = "MSFT"
 | |
|         BuildConfigurationFile = os.path.normpath(os.path.join(GlobalData.gConfDirectory, "target.txt"))
 | |
|         if os.path.isfile(BuildConfigurationFile) == True:
 | |
|             TargetTxt      = TargetTxtClassObject()
 | |
|             TargetTxt.LoadTargetTxtFile(BuildConfigurationFile)
 | |
|             ToolDefinitionFile = TargetTxt.TargetTxtDictionary[DataType.TAB_TAT_DEFINES_TOOL_CHAIN_CONF]
 | |
|             if ToolDefinitionFile == '':
 | |
|                 ToolDefinitionFile = "tools_def.txt"
 | |
|                 ToolDefinitionFile = os.path.normpath(mws.join(self.WorkspaceDir, 'Conf', ToolDefinitionFile))
 | |
|             if os.path.isfile(ToolDefinitionFile) == True:
 | |
|                 ToolDef        = ToolDefClassObject()
 | |
|                 ToolDef.LoadToolDefFile(ToolDefinitionFile)
 | |
|                 ToolDefinition = ToolDef.ToolsDefTxtDatabase
 | |
|                 if TAB_TOD_DEFINES_FAMILY not in ToolDefinition \
 | |
|                    or self._Toolchain not in ToolDefinition[TAB_TOD_DEFINES_FAMILY] \
 | |
|                    or not ToolDefinition[TAB_TOD_DEFINES_FAMILY][self._Toolchain]:
 | |
|                     self._ToolChainFamily = "MSFT"
 | |
|                 else:
 | |
|                     self._ToolChainFamily = ToolDefinition[TAB_TOD_DEFINES_FAMILY][self._Toolchain]
 | |
|         return self._ToolChainFamily
 | |
| 
 | |
|     ## Add external PCDs
 | |
|     #
 | |
|     #   The external PCDs are mostly those listed in FDF file to specify address
 | |
|     # or offset information.
 | |
|     #
 | |
|     #   @param  Name    Name of the PCD
 | |
|     #   @param  Guid    Token space guid of the PCD
 | |
|     #   @param  Value   Value of the PCD
 | |
|     #
 | |
|     def AddPcd(self, Name, Guid, Value):
 | |
|         if (Name, Guid) not in self.Pcds:
 | |
|             self.Pcds[Name, Guid] = PcdClassObject(Name, Guid, '', '', '', '', '', {}, False, None)
 | |
|         self.Pcds[Name, Guid].DefaultValue = Value
 | |
|     @property
 | |
|     def DecPcds(self):
 | |
|         if self._DecPcds is None:
 | |
|             FdfInfList = []
 | |
|             if GlobalData.gFdfParser:
 | |
|                 FdfInfList = GlobalData.gFdfParser.Profile.InfList
 | |
|             PkgSet = set()
 | |
|             for Inf in FdfInfList:
 | |
|                 ModuleFile = PathClass(NormPath(Inf), GlobalData.gWorkspace, Arch=self._Arch)
 | |
|                 if ModuleFile in self._Modules:
 | |
|                     continue
 | |
|                 ModuleData = self._Bdb[ModuleFile, self._Arch, self._Target, self._Toolchain]
 | |
|                 PkgSet.update(ModuleData.Packages)
 | |
|             self._DecPcds, self._GuidDict = GetDeclaredPcd(self, self._Bdb, self._Arch, self._Target, self._Toolchain,PkgSet)
 | |
|         return self._DecPcds
 | |
|     _Macros             = property(_GetMacros)
 | |
|     Arch                = property(_GetArch, _SetArch)
 | |
|     Platform            = property(_GetPlatformName)
 | |
|     PlatformName        = property(_GetPlatformName)
 | |
|     Guid                = property(_GetFileGuid)
 | |
|     Version             = property(_GetVersion)
 | |
|     DscSpecification    = property(_GetDscSpec)
 | |
|     OutputDirectory     = property(_GetOutpuDir)
 | |
|     SupArchList         = property(_GetSupArch)
 | |
|     BuildTargets        = property(_GetBuildTarget)
 | |
|     SkuName             = property(_GetSkuName, _SetSkuName)
 | |
|     PcdInfoFlag         = property(_GetPcdInfoFlag)
 | |
|     VarCheckFlag        = property(_GetVarCheckFlag)
 | |
|     FlashDefinition     = property(_GetFdfFile)
 | |
|     Prebuild            = property(_GetPrebuild)
 | |
|     Postbuild           = property(_GetPostbuild)
 | |
|     BuildNumber         = property(_GetBuildNumber)
 | |
|     MakefileName        = property(_GetMakefileName)
 | |
|     BsBaseAddress       = property(_GetBsBaseAddress)
 | |
|     RtBaseAddress       = property(_GetRtBaseAddress)
 | |
|     LoadFixAddress      = property(_GetLoadFixAddress)
 | |
|     RFCLanguages        = property(_GetRFCLanguages)
 | |
|     ISOLanguages        = property(_GetISOLanguages)
 | |
|     VpdToolGuid         = property(_GetVpdToolGuid)
 | |
|     SkuIds              = property(_GetSkuIds)
 | |
|     Modules             = property(_GetModules)
 | |
|     LibraryInstances    = property(_GetLibraryInstances)
 | |
|     LibraryClasses      = property(_GetLibraryClasses)
 | |
|     Pcds                = property(_GetPcds)
 | |
|     BuildOptions        = property(_GetBuildOptions)
 | |
|     ToolChainFamily     = property(_GetToolChainFamily)
 |