]> git.proxmox.com Git - mirror_edk2.git/blame - BaseTools/Source/Python/GenFds/GenFds.py
MdeModulePkg RamDiskDxe: VALID_ARCH cleanup to list supported options
[mirror_edk2.git] / BaseTools / Source / Python / GenFds / GenFds.py
CommitLineData
f51461c8
LG
1## @file\r
2# generate flash image\r
3#\r
3a0f8bde 4# Copyright (c) 2007 - 2016, Intel Corporation. All rights reserved.<BR>\r
f51461c8
LG
5#\r
6# This program and the accompanying materials\r
7# are licensed and made available under the terms and conditions of the BSD License\r
8# which accompanies this distribution. The full text of the license may be found at\r
9# http://opensource.org/licenses/bsd-license.php\r
10#\r
11# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
12# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
13#\r
14\r
15##\r
16# Import Modules\r
17#\r
18from optparse import OptionParser\r
19import sys\r
1be2ed90 20import Common.LongFilePathOs as os\r
f51461c8
LG
21import linecache\r
22import FdfParser\r
23import Common.BuildToolError as BuildToolError\r
24from GenFdsGlobalVariable import GenFdsGlobalVariable\r
25from Workspace.WorkspaceDatabase import WorkspaceDatabase\r
26from Workspace.BuildClassObject import PcdClassObject\r
27from Workspace.BuildClassObject import ModuleBuildClassObject\r
28import RuleComplexFile\r
29from EfiSection import EfiSection\r
30import StringIO\r
31import Common.TargetTxtClassObject as TargetTxtClassObject\r
32import Common.ToolDefClassObject as ToolDefClassObject\r
33import Common.DataType\r
34import Common.GlobalData as GlobalData\r
35from Common import EdkLogger\r
36from Common.String import *\r
47fea6af 37from Common.Misc import DirCache, PathClass\r
f51461c8 38from Common.Misc import SaveFileOnChange\r
97fa0ee9 39from Common.Misc import ClearDuplicatedInf\r
e4ac870f 40from Common.Misc import GuidStructureStringToGuidString\r
6b17c11b 41from Common.Misc import CheckPcdDatum\r
f51461c8 42from Common.BuildVersion import gBUILD_VERSION\r
05cc51ad 43from Common.MultipleWorkspace import MultipleWorkspace as mws\r
f51461c8
LG
44\r
45## Version and Copyright\r
46versionNumber = "1.0" + ' ' + gBUILD_VERSION\r
47__version__ = "%prog Version " + versionNumber\r
6b17c11b 48__copyright__ = "Copyright (c) 2007 - 2016, Intel Corporation All rights reserved."\r
f51461c8
LG
49\r
50## Tool entrance method\r
51#\r
52# This method mainly dispatch specific methods per the command line options.\r
53# If no error found, return zero value so the caller of this tool can know\r
54# if it's executed successfully or not.\r
55#\r
56# @retval 0 Tool was successful\r
57# @retval 1 Tool failed\r
58#\r
59def main():\r
60 global Options\r
61 Options = myOptionParser()\r
62\r
63 global Workspace\r
64 Workspace = ""\r
65 ArchList = None\r
66 ReturnCode = 0\r
67\r
68 EdkLogger.Initialize()\r
69 try:\r
70 if Options.verbose != None:\r
71 EdkLogger.SetLevel(EdkLogger.VERBOSE)\r
72 GenFdsGlobalVariable.VerboseMode = True\r
73 \r
74 if Options.FixedAddress != None:\r
75 GenFdsGlobalVariable.FixedLoadAddress = True\r
76 \r
77 if Options.quiet != None:\r
78 EdkLogger.SetLevel(EdkLogger.QUIET)\r
79 if Options.debug != None:\r
80 EdkLogger.SetLevel(Options.debug + 1)\r
81 GenFdsGlobalVariable.DebugLevel = Options.debug\r
82 else:\r
83 EdkLogger.SetLevel(EdkLogger.INFO)\r
84\r
85 if (Options.Workspace == None):\r
86 EdkLogger.error("GenFds", OPTION_MISSING, "WORKSPACE not defined",\r
87 ExtraData="Please use '-w' switch to pass it or set the WORKSPACE environment variable.")\r
88 elif not os.path.exists(Options.Workspace):\r
89 EdkLogger.error("GenFds", PARAMETER_INVALID, "WORKSPACE is invalid",\r
90 ExtraData="Please use '-w' switch to pass it or set the WORKSPACE environment variable.")\r
91 else:\r
92 Workspace = os.path.normcase(Options.Workspace)\r
93 GenFdsGlobalVariable.WorkSpaceDir = Workspace\r
94 if 'EDK_SOURCE' in os.environ.keys():\r
95 GenFdsGlobalVariable.EdkSourceDir = os.path.normcase(os.environ['EDK_SOURCE'])\r
96 if (Options.debug):\r
47fea6af 97 GenFdsGlobalVariable.VerboseLogger("Using Workspace:" + Workspace)\r
f51461c8 98 os.chdir(GenFdsGlobalVariable.WorkSpaceDir)\r
05cc51ad
LY
99 \r
100 # set multiple workspace\r
101 PackagesPath = os.getenv("PACKAGES_PATH")\r
102 mws.setWs(GenFdsGlobalVariable.WorkSpaceDir, PackagesPath)\r
f51461c8
LG
103\r
104 if (Options.filename):\r
105 FdfFilename = Options.filename\r
106 FdfFilename = GenFdsGlobalVariable.ReplaceWorkspaceMacro(FdfFilename)\r
107\r
108 if FdfFilename[0:2] == '..':\r
109 FdfFilename = os.path.realpath(FdfFilename)\r
47fea6af 110 if not os.path.isabs(FdfFilename):\r
05cc51ad 111 FdfFilename = mws.join(GenFdsGlobalVariable.WorkSpaceDir, FdfFilename)\r
f51461c8
LG
112 if not os.path.exists(FdfFilename):\r
113 EdkLogger.error("GenFds", FILE_NOT_FOUND, ExtraData=FdfFilename)\r
f51461c8
LG
114\r
115 GenFdsGlobalVariable.FdfFile = FdfFilename\r
116 GenFdsGlobalVariable.FdfFileTimeStamp = os.path.getmtime(FdfFilename)\r
117 else:\r
118 EdkLogger.error("GenFds", OPTION_MISSING, "Missing FDF filename")\r
119\r
120 if (Options.BuildTarget):\r
121 GenFdsGlobalVariable.TargetName = Options.BuildTarget\r
122 else:\r
123 EdkLogger.error("GenFds", OPTION_MISSING, "Missing build target")\r
124\r
125 if (Options.ToolChain):\r
126 GenFdsGlobalVariable.ToolChainTag = Options.ToolChain\r
127 else:\r
128 EdkLogger.error("GenFds", OPTION_MISSING, "Missing tool chain tag")\r
129\r
130 if (Options.activePlatform):\r
131 ActivePlatform = Options.activePlatform\r
132 ActivePlatform = GenFdsGlobalVariable.ReplaceWorkspaceMacro(ActivePlatform)\r
133\r
134 if ActivePlatform[0:2] == '..':\r
135 ActivePlatform = os.path.realpath(ActivePlatform)\r
136\r
137 if not os.path.isabs (ActivePlatform):\r
05cc51ad 138 ActivePlatform = mws.join(GenFdsGlobalVariable.WorkSpaceDir, ActivePlatform)\r
f51461c8
LG
139\r
140 if not os.path.exists(ActivePlatform) :\r
141 EdkLogger.error("GenFds", FILE_NOT_FOUND, "ActivePlatform doesn't exist!")\r
f51461c8
LG
142 else:\r
143 EdkLogger.error("GenFds", OPTION_MISSING, "Missing active platform")\r
144\r
e642ceb8 145 GenFdsGlobalVariable.ActivePlatform = PathClass(NormPath(ActivePlatform))\r
f51461c8 146\r
97fa0ee9
YL
147 if (Options.ConfDirectory):\r
148 # Get alternate Conf location, if it is absolute, then just use the absolute directory name\r
149 ConfDirectoryPath = os.path.normpath(Options.ConfDirectory)\r
150 if ConfDirectoryPath.startswith('"'):\r
151 ConfDirectoryPath = ConfDirectoryPath[1:]\r
152 if ConfDirectoryPath.endswith('"'):\r
153 ConfDirectoryPath = ConfDirectoryPath[:-1]\r
154 if not os.path.isabs(ConfDirectoryPath):\r
155 # Since alternate directory name is not absolute, the alternate directory is located within the WORKSPACE\r
156 # This also handles someone specifying the Conf directory in the workspace. Using --conf=Conf\r
157 ConfDirectoryPath = os.path.join(GenFdsGlobalVariable.WorkSpaceDir, ConfDirectoryPath)\r
158 else:\r
159 # Get standard WORKSPACE/Conf, use the absolute path to the WORKSPACE/Conf\r
05cc51ad 160 ConfDirectoryPath = mws.join(GenFdsGlobalVariable.WorkSpaceDir, 'Conf')\r
97fa0ee9
YL
161 GenFdsGlobalVariable.ConfDir = ConfDirectoryPath\r
162 BuildConfigurationFile = os.path.normpath(os.path.join(ConfDirectoryPath, "target.txt"))\r
f51461c8
LG
163 if os.path.isfile(BuildConfigurationFile) == True:\r
164 TargetTxtClassObject.TargetTxtClassObject(BuildConfigurationFile)\r
165 else:\r
166 EdkLogger.error("GenFds", FILE_NOT_FOUND, ExtraData=BuildConfigurationFile)\r
167\r
97fa0ee9
YL
168 #Set global flag for build mode\r
169 GlobalData.gIgnoreSource = Options.IgnoreSources\r
170\r
f51461c8
LG
171 if Options.Macros:\r
172 for Pair in Options.Macros:\r
97fa0ee9
YL
173 if Pair.startswith('"'):\r
174 Pair = Pair[1:]\r
175 if Pair.endswith('"'):\r
176 Pair = Pair[:-1]\r
f51461c8
LG
177 List = Pair.split('=')\r
178 if len(List) == 2:\r
179 if List[0].strip() == "EFI_SOURCE":\r
180 GlobalData.gEfiSource = List[1].strip()\r
181 GlobalData.gGlobalDefines["EFI_SOURCE"] = GlobalData.gEfiSource\r
182 continue\r
183 elif List[0].strip() == "EDK_SOURCE":\r
184 GlobalData.gEdkSource = List[1].strip()\r
185 GlobalData.gGlobalDefines["EDK_SOURCE"] = GlobalData.gEdkSource\r
186 continue\r
187 elif List[0].strip() in ["WORKSPACE", "TARGET", "TOOLCHAIN"]:\r
188 GlobalData.gGlobalDefines[List[0].strip()] = List[1].strip()\r
189 else:\r
190 GlobalData.gCommandLineDefines[List[0].strip()] = List[1].strip()\r
191 else:\r
192 GlobalData.gCommandLineDefines[List[0].strip()] = "TRUE"\r
193 os.environ["WORKSPACE"] = Workspace\r
194\r
195 """call Workspace build create database"""\r
97fa0ee9
YL
196 GlobalData.gDatabasePath = os.path.normpath(os.path.join(ConfDirectoryPath, GlobalData.gDatabasePath))\r
197 BuildWorkSpace = WorkspaceDatabase(GlobalData.gDatabasePath)\r
f51461c8
LG
198 BuildWorkSpace.InitDatabase()\r
199 \r
200 #\r
201 # Get files real name in workspace dir\r
202 #\r
203 GlobalData.gAllFiles = DirCache(Workspace)\r
204 GlobalData.gWorkspace = Workspace\r
205\r
206 if (Options.archList) :\r
207 ArchList = Options.archList.split(',')\r
208 else:\r
209# EdkLogger.error("GenFds", OPTION_MISSING, "Missing build ARCH")\r
210 ArchList = BuildWorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, 'COMMON', Options.BuildTarget, Options.ToolChain].SupArchList\r
211\r
212 TargetArchList = set(BuildWorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, 'COMMON', Options.BuildTarget, Options.ToolChain].SupArchList) & set(ArchList)\r
213 if len(TargetArchList) == 0:\r
214 EdkLogger.error("GenFds", GENFDS_ERROR, "Target ARCH %s not in platform supported ARCH %s" % (str(ArchList), str(BuildWorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, 'COMMON'].SupArchList)))\r
215 \r
216 for Arch in ArchList:\r
217 GenFdsGlobalVariable.OutputDirFromDscDict[Arch] = NormPath(BuildWorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch, Options.BuildTarget, Options.ToolChain].OutputDirectory)\r
218 GenFdsGlobalVariable.PlatformName = BuildWorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch, Options.BuildTarget, Options.ToolChain].PlatformName\r
219\r
220 if (Options.outputDir):\r
221 OutputDirFromCommandLine = GenFdsGlobalVariable.ReplaceWorkspaceMacro(Options.outputDir)\r
222 if not os.path.isabs (OutputDirFromCommandLine):\r
223 OutputDirFromCommandLine = os.path.join(GenFdsGlobalVariable.WorkSpaceDir, OutputDirFromCommandLine)\r
224 for Arch in ArchList:\r
225 GenFdsGlobalVariable.OutputDirDict[Arch] = OutputDirFromCommandLine\r
226 else:\r
227 for Arch in ArchList:\r
228 GenFdsGlobalVariable.OutputDirDict[Arch] = os.path.join(GenFdsGlobalVariable.OutputDirFromDscDict[Arch], GenFdsGlobalVariable.TargetName + '_' + GenFdsGlobalVariable.ToolChainTag)\r
229\r
230 for Key in GenFdsGlobalVariable.OutputDirDict:\r
231 OutputDir = GenFdsGlobalVariable.OutputDirDict[Key]\r
232 if OutputDir[0:2] == '..':\r
233 OutputDir = os.path.realpath(OutputDir)\r
234\r
235 if OutputDir[1] != ':':\r
236 OutputDir = os.path.join (GenFdsGlobalVariable.WorkSpaceDir, OutputDir)\r
237\r
238 if not os.path.exists(OutputDir):\r
239 EdkLogger.error("GenFds", FILE_NOT_FOUND, ExtraData=OutputDir)\r
240 GenFdsGlobalVariable.OutputDirDict[Key] = OutputDir\r
241\r
242 """ Parse Fdf file, has to place after build Workspace as FDF may contain macros from DSC file """\r
243 FdfParserObj = FdfParser.FdfParser(FdfFilename)\r
244 FdfParserObj.ParseFile()\r
245\r
246 if FdfParserObj.CycleReferenceCheck():\r
247 EdkLogger.error("GenFds", FORMAT_NOT_SUPPORTED, "Cycle Reference Detected in FDF file")\r
248\r
249 if (Options.uiFdName) :\r
250 if Options.uiFdName.upper() in FdfParserObj.Profile.FdDict.keys():\r
251 GenFds.OnlyGenerateThisFd = Options.uiFdName\r
252 else:\r
253 EdkLogger.error("GenFds", OPTION_VALUE_INVALID,\r
254 "No such an FD in FDF file: %s" % Options.uiFdName)\r
255\r
256 if (Options.uiFvName) :\r
257 if Options.uiFvName.upper() in FdfParserObj.Profile.FvDict.keys():\r
258 GenFds.OnlyGenerateThisFv = Options.uiFvName\r
259 else:\r
260 EdkLogger.error("GenFds", OPTION_VALUE_INVALID,\r
261 "No such an FV in FDF file: %s" % Options.uiFvName)\r
262\r
263 if (Options.uiCapName) :\r
264 if Options.uiCapName.upper() in FdfParserObj.Profile.CapsuleDict.keys():\r
265 GenFds.OnlyGenerateThisCap = Options.uiCapName\r
266 else:\r
267 EdkLogger.error("GenFds", OPTION_VALUE_INVALID,\r
268 "No such a Capsule in FDF file: %s" % Options.uiCapName)\r
269\r
6b17c11b
YZ
270 GenFdsGlobalVariable.WorkSpace = BuildWorkSpace\r
271 if ArchList != None:\r
272 GenFdsGlobalVariable.ArchList = ArchList\r
273\r
274 if Options.OptionPcd:\r
275 GlobalData.BuildOptionPcd = Options.OptionPcd\r
276 CheckBuildOptionPcd()\r
277\r
f51461c8
LG
278 """Modify images from build output if the feature of loading driver at fixed address is on."""\r
279 if GenFdsGlobalVariable.FixedLoadAddress:\r
280 GenFds.PreprocessImage(BuildWorkSpace, GenFdsGlobalVariable.ActivePlatform)\r
281 """Call GenFds"""\r
282 GenFds.GenFd('', FdfParserObj, BuildWorkSpace, ArchList)\r
283\r
284 """Generate GUID cross reference file"""\r
285 GenFds.GenerateGuidXRefFile(BuildWorkSpace, ArchList)\r
286\r
287 """Display FV space info."""\r
288 GenFds.DisplayFvSpaceInfo(FdfParserObj)\r
289\r
290 except FdfParser.Warning, X:\r
47fea6af 291 EdkLogger.error(X.ToolName, FORMAT_INVALID, File=X.FileName, Line=X.LineNumber, ExtraData=X.Message, RaiseError=False)\r
f51461c8
LG
292 ReturnCode = FORMAT_INVALID\r
293 except FatalError, X:\r
294 if Options.debug != None:\r
295 import traceback\r
296 EdkLogger.quiet(traceback.format_exc())\r
297 ReturnCode = X.args[0]\r
298 except:\r
299 import traceback\r
300 EdkLogger.error(\r
301 "\nPython",\r
302 CODE_ERROR,\r
303 "Tools code failure",\r
3a0f8bde 304 ExtraData="Please send email to edk2-devel@lists.01.org for help, attaching following call stack trace!\n",\r
f51461c8
LG
305 RaiseError=False\r
306 )\r
307 EdkLogger.quiet(traceback.format_exc())\r
308 ReturnCode = CODE_ERROR\r
97fa0ee9
YL
309 finally:\r
310 ClearDuplicatedInf()\r
f51461c8
LG
311 return ReturnCode\r
312\r
313gParamCheck = []\r
314def SingleCheckCallback(option, opt_str, value, parser):\r
315 if option not in gParamCheck:\r
316 setattr(parser.values, option.dest, value)\r
317 gParamCheck.append(option)\r
318 else:\r
319 parser.error("Option %s only allows one instance in command line!" % option)\r
6b17c11b
YZ
320\r
321def CheckBuildOptionPcd():\r
322 for Arch in GenFdsGlobalVariable.ArchList:\r
323 PkgList = GenFdsGlobalVariable.WorkSpace.GetPackageList(GenFdsGlobalVariable.ActivePlatform, Arch, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag)\r
324 for i, pcd in enumerate(GlobalData.BuildOptionPcd):\r
325 if type(pcd) is tuple:\r
326 continue\r
327 (pcdname, pcdvalue) = pcd.split('=')\r
328 if not pcdvalue:\r
329 EdkLogger.error('GenFds', OPTION_MISSING, "No Value specified for the PCD %s." % (pcdname))\r
330 if '.' in pcdname:\r
331 (TokenSpaceGuidCName, TokenCName) = pcdname.split('.')\r
332 HasTokenSpace = True\r
333 else:\r
334 TokenCName = pcdname\r
335 TokenSpaceGuidCName = ''\r
336 HasTokenSpace = False\r
337 TokenSpaceGuidCNameList = []\r
338 FoundFlag = False\r
339 PcdDatumType = ''\r
340 NewValue = ''\r
341 for package in PkgList:\r
342 for key in package.Pcds:\r
343 PcdItem = package.Pcds[key]\r
344 if HasTokenSpace:\r
345 if (PcdItem.TokenCName, PcdItem.TokenSpaceGuidCName) == (TokenCName, TokenSpaceGuidCName):\r
346 PcdDatumType = PcdItem.DatumType\r
347 NewValue = BuildOptionPcdValueFormat(TokenSpaceGuidCName, TokenCName, PcdDatumType, pcdvalue)\r
348 FoundFlag = True\r
349 else:\r
350 if PcdItem.TokenCName == TokenCName:\r
351 if not PcdItem.TokenSpaceGuidCName in TokenSpaceGuidCNameList:\r
352 if len (TokenSpaceGuidCNameList) < 1:\r
353 TokenSpaceGuidCNameList.append(PcdItem.TokenSpaceGuidCName)\r
354 PcdDatumType = PcdItem.DatumType\r
355 TokenSpaceGuidCName = PcdItem.TokenSpaceGuidCName\r
356 NewValue = BuildOptionPcdValueFormat(TokenSpaceGuidCName, TokenCName, PcdDatumType, pcdvalue)\r
357 FoundFlag = True\r
358 else:\r
359 EdkLogger.error(\r
360 'GenFds',\r
361 PCD_VALIDATION_INFO_ERROR,\r
362 "The Pcd %s is found under multiple different TokenSpaceGuid: %s and %s." % (TokenCName, PcdItem.TokenSpaceGuidCName, TokenSpaceGuidCNameList[0])\r
363 )\r
364\r
365 GlobalData.BuildOptionPcd[i] = (TokenSpaceGuidCName, TokenCName, NewValue)\r
366\r
367def BuildOptionPcdValueFormat(TokenSpaceGuidCName, TokenCName, PcdDatumType, Value):\r
368 if PcdDatumType == 'VOID*':\r
369 if Value.startswith('L'):\r
370 if not Value[1]:\r
371 EdkLogger.error('GenFds', OPTION_VALUE_INVALID, 'For Void* type PCD, when specify the Value in the command line, please use the following format: "string", L"string", B"{...}"')\r
372 Value = Value[0] + '"' + Value[1:] + '"'\r
373 elif Value.startswith('B'):\r
374 if not Value[1]:\r
375 EdkLogger.error('GenFds', OPTION_VALUE_INVALID, 'For Void* type PCD, when specify the Value in the command line, please use the following format: "string", L"string", B"{...}"')\r
376 Value = Value[1:]\r
377 else:\r
378 if not Value[0]:\r
379 EdkLogger.error('GenFds', OPTION_VALUE_INVALID, 'For Void* type PCD, when specify the Value in the command line, please use the following format: "string", L"string", B"{...}"')\r
380 Value = '"' + Value + '"'\r
381\r
382 IsValid, Cause = CheckPcdDatum(PcdDatumType, Value)\r
383 if not IsValid:\r
384 EdkLogger.error('build', FORMAT_INVALID, Cause, ExtraData="%s.%s" % (TokenSpaceGuidCName, TokenCName))\r
385 if PcdDatumType == 'BOOLEAN':\r
386 Value = Value.upper()\r
387 if Value == 'TRUE' or Value == '1':\r
388 Value = '1'\r
389 elif Value == 'FALSE' or Value == '0':\r
390 Value = '0'\r
391 return Value\r
392\r
f51461c8
LG
393 \r
394## Parse command line options\r
395#\r
396# Using standard Python module optparse to parse command line option of this tool.\r
397#\r
398# @retval Opt A optparse.Values object containing the parsed options\r
399# @retval Args Target of build command\r
400#\r
401def myOptionParser():\r
402 usage = "%prog [options] -f input_file -a arch_list -b build_target -p active_platform -t tool_chain_tag -D \"MacroName [= MacroValue]\""\r
47fea6af 403 Parser = OptionParser(usage=usage, description=__copyright__, version="%prog " + str(versionNumber))\r
f51461c8
LG
404 Parser.add_option("-f", "--file", dest="filename", type="string", help="Name of FDF file to convert", action="callback", callback=SingleCheckCallback)\r
405 Parser.add_option("-a", "--arch", dest="archList", help="comma separated list containing one or more of: IA32, X64, IPF, ARM, AARCH64 or EBC which should be built, overrides target.txt?s TARGET_ARCH")\r
406 Parser.add_option("-q", "--quiet", action="store_true", type=None, help="Disable all messages except FATAL ERRORS.")\r
407 Parser.add_option("-v", "--verbose", action="store_true", type=None, help="Turn on verbose output with informational messages printed.")\r
408 Parser.add_option("-d", "--debug", action="store", type="int", help="Enable debug messages at specified level.")\r
409 Parser.add_option("-p", "--platform", type="string", dest="activePlatform", help="Set the ACTIVE_PLATFORM, overrides target.txt ACTIVE_PLATFORM setting.",\r
410 action="callback", callback=SingleCheckCallback)\r
411 Parser.add_option("-w", "--workspace", type="string", dest="Workspace", default=os.environ.get('WORKSPACE'), help="Set the WORKSPACE",\r
412 action="callback", callback=SingleCheckCallback)\r
413 Parser.add_option("-o", "--outputDir", type="string", dest="outputDir", help="Name of Build Output directory",\r
414 action="callback", callback=SingleCheckCallback)\r
415 Parser.add_option("-r", "--rom_image", dest="uiFdName", help="Build the image using the [FD] section named by FdUiName.")\r
416 Parser.add_option("-i", "--FvImage", dest="uiFvName", help="Build the FV image using the [FV] section named by UiFvName")\r
417 Parser.add_option("-C", "--CapsuleImage", dest="uiCapName", help="Build the Capsule image using the [Capsule] section named by UiCapName")\r
418 Parser.add_option("-b", "--buildtarget", type="string", dest="BuildTarget", help="Set the build TARGET, overrides target.txt TARGET setting.",\r
419 action="callback", callback=SingleCheckCallback)\r
420 Parser.add_option("-t", "--tagname", type="string", dest="ToolChain", help="Using the tools: TOOL_CHAIN_TAG name to build the platform.",\r
421 action="callback", callback=SingleCheckCallback)\r
422 Parser.add_option("-D", "--define", action="append", type="string", dest="Macros", help="Macro: \"Name [= Value]\".")\r
423 Parser.add_option("-s", "--specifyaddress", dest="FixedAddress", action="store_true", type=None, help="Specify driver load address.")\r
97fa0ee9
YL
424 Parser.add_option("--conf", action="store", type="string", dest="ConfDirectory", help="Specify the customized Conf directory.")\r
425 Parser.add_option("--ignore-sources", action="store_true", dest="IgnoreSources", default=False, help="Focus to a binary build and ignore all source files")\r
6b17c11b 426 Parser.add_option("--pcd", action="append", dest="OptionPcd", help="Set PCD value by command line. Format: \"PcdName=Value\" ")\r
97fa0ee9 427\r
f51461c8
LG
428 (Options, args) = Parser.parse_args()\r
429 return Options\r
430\r
431## The class implementing the EDK2 flash image generation process\r
432#\r
433# This process includes:\r
434# 1. Collect workspace information, includes platform and module information\r
435# 2. Call methods of Fd class to generate FD\r
436# 3. Call methods of Fv class to generate FV that not belong to FD\r
437#\r
438class GenFds :\r
439 FdfParsef = None\r
440 # FvName, FdName, CapName in FDF, Image file name\r
441 ImageBinDict = {}\r
442 OnlyGenerateThisFd = None\r
443 OnlyGenerateThisFv = None\r
444 OnlyGenerateThisCap = None\r
445\r
446 ## GenFd()\r
447 #\r
448 # @param OutputDir Output directory\r
449 # @param FdfParser FDF contents parser\r
450 # @param Workspace The directory of workspace\r
451 # @param ArchList The Arch list of platform\r
452 #\r
453 def GenFd (OutputDir, FdfParser, WorkSpace, ArchList):\r
454 GenFdsGlobalVariable.SetDir ('', FdfParser, WorkSpace, ArchList)\r
455\r
456 GenFdsGlobalVariable.VerboseLogger(" Generate all Fd images and their required FV and Capsule images!")\r
457 if GenFds.OnlyGenerateThisCap != None and GenFds.OnlyGenerateThisCap.upper() in GenFdsGlobalVariable.FdfParser.Profile.CapsuleDict.keys():\r
458 CapsuleObj = GenFdsGlobalVariable.FdfParser.Profile.CapsuleDict.get(GenFds.OnlyGenerateThisCap.upper())\r
459 if CapsuleObj != None:\r
460 CapsuleObj.GenCapsule()\r
461 return\r
462\r
463 if GenFds.OnlyGenerateThisFd != None and GenFds.OnlyGenerateThisFd.upper() in GenFdsGlobalVariable.FdfParser.Profile.FdDict.keys():\r
464 FdObj = GenFdsGlobalVariable.FdfParser.Profile.FdDict.get(GenFds.OnlyGenerateThisFd.upper())\r
465 if FdObj != None:\r
466 FdObj.GenFd()\r
467 return\r
468 elif GenFds.OnlyGenerateThisFd == None and GenFds.OnlyGenerateThisFv == None:\r
469 for FdName in GenFdsGlobalVariable.FdfParser.Profile.FdDict.keys():\r
470 FdObj = GenFdsGlobalVariable.FdfParser.Profile.FdDict[FdName]\r
471 FdObj.GenFd()\r
472\r
473 GenFdsGlobalVariable.VerboseLogger("\n Generate other FV images! ")\r
474 if GenFds.OnlyGenerateThisFv != None and GenFds.OnlyGenerateThisFv.upper() in GenFdsGlobalVariable.FdfParser.Profile.FvDict.keys():\r
475 FvObj = GenFdsGlobalVariable.FdfParser.Profile.FvDict.get(GenFds.OnlyGenerateThisFv.upper())\r
476 if FvObj != None:\r
477 Buffer = StringIO.StringIO()\r
478 FvObj.AddToBuffer(Buffer)\r
479 Buffer.close()\r
480 return\r
481 elif GenFds.OnlyGenerateThisFv == None:\r
482 for FvName in GenFdsGlobalVariable.FdfParser.Profile.FvDict.keys():\r
483 Buffer = StringIO.StringIO('')\r
484 FvObj = GenFdsGlobalVariable.FdfParser.Profile.FvDict[FvName]\r
485 FvObj.AddToBuffer(Buffer)\r
486 Buffer.close()\r
487 \r
488 if GenFds.OnlyGenerateThisFv == None and GenFds.OnlyGenerateThisFd == None and GenFds.OnlyGenerateThisCap == None:\r
489 if GenFdsGlobalVariable.FdfParser.Profile.CapsuleDict != {}:\r
490 GenFdsGlobalVariable.VerboseLogger("\n Generate other Capsule images!")\r
491 for CapsuleName in GenFdsGlobalVariable.FdfParser.Profile.CapsuleDict.keys():\r
492 CapsuleObj = GenFdsGlobalVariable.FdfParser.Profile.CapsuleDict[CapsuleName]\r
493 CapsuleObj.GenCapsule()\r
494\r
495 if GenFdsGlobalVariable.FdfParser.Profile.OptRomDict != {}:\r
496 GenFdsGlobalVariable.VerboseLogger("\n Generate all Option ROM!")\r
497 for DriverName in GenFdsGlobalVariable.FdfParser.Profile.OptRomDict.keys():\r
498 OptRomObj = GenFdsGlobalVariable.FdfParser.Profile.OptRomDict[DriverName]\r
499 OptRomObj.AddToBuffer(None)\r
500\r
501 ## GetFvBlockSize()\r
502 #\r
503 # @param FvObj Whose block size to get\r
504 # @retval int Block size value\r
505 #\r
506 def GetFvBlockSize(FvObj):\r
507 DefaultBlockSize = 0x1\r
508 FdObj = None\r
509 if GenFds.OnlyGenerateThisFd != None and GenFds.OnlyGenerateThisFd.upper() in GenFdsGlobalVariable.FdfParser.Profile.FdDict.keys():\r
510 FdObj = GenFdsGlobalVariable.FdfParser.Profile.FdDict[GenFds.OnlyGenerateThisFd.upper()]\r
511 if FdObj == None:\r
512 for ElementFd in GenFdsGlobalVariable.FdfParser.Profile.FdDict.values():\r
513 for ElementRegion in ElementFd.RegionList:\r
514 if ElementRegion.RegionType == 'FV':\r
515 for ElementRegionData in ElementRegion.RegionDataList:\r
516 if ElementRegionData != None and ElementRegionData.upper() == FvObj.UiFvName:\r
517 if FvObj.BlockSizeList != []:\r
518 return FvObj.BlockSizeList[0][0]\r
519 else:\r
520 return ElementRegion.BlockSizeOfRegion(ElementFd.BlockSizeList)\r
521 if FvObj.BlockSizeList != []:\r
522 return FvObj.BlockSizeList[0][0]\r
523 return DefaultBlockSize\r
524 else:\r
525 for ElementRegion in FdObj.RegionList:\r
526 if ElementRegion.RegionType == 'FV':\r
527 for ElementRegionData in ElementRegion.RegionDataList:\r
528 if ElementRegionData != None and ElementRegionData.upper() == FvObj.UiFvName:\r
529 if FvObj.BlockSizeList != []:\r
530 return FvObj.BlockSizeList[0][0]\r
531 else:\r
532 return ElementRegion.BlockSizeOfRegion(ElementFd.BlockSizeList)\r
533 return DefaultBlockSize\r
534\r
535 ## DisplayFvSpaceInfo()\r
536 #\r
537 # @param FvObj Whose block size to get\r
538 # @retval None\r
539 #\r
540 def DisplayFvSpaceInfo(FdfParser):\r
541 \r
542 FvSpaceInfoList = []\r
543 MaxFvNameLength = 0\r
544 for FvName in FdfParser.Profile.FvDict:\r
545 if len(FvName) > MaxFvNameLength:\r
546 MaxFvNameLength = len(FvName)\r
547 FvSpaceInfoFileName = os.path.join(GenFdsGlobalVariable.FvDir, FvName.upper() + '.Fv.map')\r
548 if os.path.exists(FvSpaceInfoFileName):\r
549 FileLinesList = linecache.getlines(FvSpaceInfoFileName)\r
550 TotalFound = False\r
551 Total = ''\r
552 UsedFound = False\r
553 Used = ''\r
554 FreeFound = False\r
555 Free = ''\r
556 for Line in FileLinesList:\r
557 NameValue = Line.split('=')\r
558 if len(NameValue) == 2:\r
559 if NameValue[0].strip() == 'EFI_FV_TOTAL_SIZE':\r
560 TotalFound = True\r
561 Total = NameValue[1].strip()\r
562 if NameValue[0].strip() == 'EFI_FV_TAKEN_SIZE':\r
563 UsedFound = True\r
564 Used = NameValue[1].strip()\r
565 if NameValue[0].strip() == 'EFI_FV_SPACE_SIZE':\r
566 FreeFound = True\r
567 Free = NameValue[1].strip()\r
568 \r
569 if TotalFound and UsedFound and FreeFound:\r
570 FvSpaceInfoList.append((FvName, Total, Used, Free))\r
571 \r
572 GenFdsGlobalVariable.InfLogger('\nFV Space Information')\r
573 for FvSpaceInfo in FvSpaceInfoList:\r
574 Name = FvSpaceInfo[0]\r
575 TotalSizeValue = long(FvSpaceInfo[1], 0)\r
576 UsedSizeValue = long(FvSpaceInfo[2], 0)\r
577 FreeSizeValue = long(FvSpaceInfo[3], 0)\r
578 if UsedSizeValue == TotalSizeValue:\r
579 Percentage = '100'\r
580 else:\r
47fea6af
YZ
581 Percentage = str((UsedSizeValue + 0.0) / TotalSizeValue)[0:4].lstrip('0.')\r
582\r
f51461c8
LG
583 GenFdsGlobalVariable.InfLogger(Name + ' ' + '[' + Percentage + '%Full] ' + str(TotalSizeValue) + ' total, ' + str(UsedSizeValue) + ' used, ' + str(FreeSizeValue) + ' free')\r
584\r
585 ## PreprocessImage()\r
586 #\r
587 # @param BuildDb Database from build meta data files\r
588 # @param DscFile modules from dsc file will be preprocessed\r
589 # @retval None\r
590 #\r
591 def PreprocessImage(BuildDb, DscFile):\r
592 PcdDict = BuildDb.BuildObject[DscFile, 'COMMON', GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag].Pcds\r
593 PcdValue = ''\r
594 for Key in PcdDict:\r
595 PcdObj = PcdDict[Key]\r
596 if PcdObj.TokenCName == 'PcdBsBaseAddress':\r
597 PcdValue = PcdObj.DefaultValue\r
598 break\r
599 \r
600 if PcdValue == '':\r
601 return\r
602 \r
603 Int64PcdValue = long(PcdValue, 0)\r
604 if Int64PcdValue == 0 or Int64PcdValue < -1: \r
605 return\r
606 \r
607 TopAddress = 0\r
608 if Int64PcdValue > 0:\r
609 TopAddress = Int64PcdValue\r
610 \r
611 ModuleDict = BuildDb.BuildObject[DscFile, 'COMMON', GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag].Modules\r
612 for Key in ModuleDict:\r
613 ModuleObj = BuildDb.BuildObject[Key, 'COMMON', GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag]\r
614 print ModuleObj.BaseName + ' ' + ModuleObj.ModuleType\r
615\r
616 def GenerateGuidXRefFile(BuildDb, ArchList):\r
617 GuidXRefFileName = os.path.join(GenFdsGlobalVariable.FvDir, "Guid.xref")\r
618 GuidXRefFile = StringIO.StringIO('')\r
e4ac870f 619 GuidDict = {}\r
f51461c8
LG
620 for Arch in ArchList:\r
621 PlatformDataBase = BuildDb.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag]\r
622 for ModuleFile in PlatformDataBase.Modules:\r
623 Module = BuildDb.BuildObject[ModuleFile, Arch, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag]\r
624 GuidXRefFile.write("%s %s\n" % (Module.Guid, Module.BaseName))\r
e4ac870f
LG
625 for key, item in Module.Protocols.items():\r
626 GuidDict[key] = item\r
627 for key, item in Module.Guids.items():\r
628 GuidDict[key] = item\r
629 for key, item in Module.Ppis.items():\r
630 GuidDict[key] = item\r
631 # Append GUIDs, Protocols, and PPIs to the Xref file\r
632 GuidXRefFile.write("\n")\r
633 for key, item in GuidDict.items():\r
634 GuidXRefFile.write("%s %s\n" % (GuidStructureStringToGuidString(item).upper(), key))\r
635\r
f51461c8
LG
636 if GuidXRefFile.getvalue():\r
637 SaveFileOnChange(GuidXRefFileName, GuidXRefFile.getvalue(), False)\r
638 GenFdsGlobalVariable.InfLogger("\nGUID cross reference file can be found at %s" % GuidXRefFileName)\r
639 elif os.path.exists(GuidXRefFileName):\r
640 os.remove(GuidXRefFileName)\r
641 GuidXRefFile.close()\r
642\r
643 ##Define GenFd as static function\r
644 GenFd = staticmethod(GenFd)\r
645 GetFvBlockSize = staticmethod(GetFvBlockSize)\r
646 DisplayFvSpaceInfo = staticmethod(DisplayFvSpaceInfo)\r
647 PreprocessImage = staticmethod(PreprocessImage)\r
648 GenerateGuidXRefFile = staticmethod(GenerateGuidXRefFile)\r
649\r
650if __name__ == '__main__':\r
651 r = main()\r
652 ## 0-127 is a safe return range, and 1 is a standard default error\r
653 if r < 0 or r > 127: r = 1\r
654 sys.exit(r)\r
655\r