]>
git.proxmox.com Git - mirror_edk2.git/blob - BaseTools/Source/Python/GenFds/GenFdsGlobalVariable.py
2 # Global variables for GenFds
4 # Copyright (c) 2007 - 2010, Intel Corporation
6 # All rights reserved. This program and the accompanying materials
7 # are licensed and made available under the terms and conditions of the BSD License
8 # which accompanies this distribution. The full text of the license may be found at
9 # http://opensource.org/licenses/bsd-license.php
11 # THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
12 # WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
24 from Common
.BuildToolError
import *
25 from Common
import EdkLogger
26 from Common
.Misc
import SaveFileOnChange
31 class GenFdsGlobalVariable
:
35 # will be FvDir + os.sep + 'Ffs'
42 OutputDirFromDscDict
= {}
49 FvAddressFileName
= ''
53 SharpNumberPerLine
= 40
56 FixedLoadAddress
= False
59 SectionHeader
= struct
.Struct("3B 1B")
63 # @param OutputDir Output directory
64 # @param FdfParser FDF contents parser
65 # @param Workspace The directory of workspace
66 # @param ArchList The Arch list of platform
68 def SetDir (OutputDir
, FdfParser
, WorkSpace
, ArchList
):
69 GenFdsGlobalVariable
.VerboseLogger( "GenFdsGlobalVariable.OutputDir :%s" %OutputDir
)
70 # GenFdsGlobalVariable.OutputDirDict = OutputDir
71 GenFdsGlobalVariable
.FdfParser
= FdfParser
72 GenFdsGlobalVariable
.WorkSpace
= WorkSpace
73 GenFdsGlobalVariable
.FvDir
= os
.path
.join(GenFdsGlobalVariable
.OutputDirDict
[ArchList
[0]], 'FV')
74 if not os
.path
.exists(GenFdsGlobalVariable
.FvDir
) :
75 os
.makedirs(GenFdsGlobalVariable
.FvDir
)
76 GenFdsGlobalVariable
.FfsDir
= os
.path
.join(GenFdsGlobalVariable
.FvDir
, 'Ffs')
77 if not os
.path
.exists(GenFdsGlobalVariable
.FfsDir
) :
78 os
.makedirs(GenFdsGlobalVariable
.FfsDir
)
80 GenFdsGlobalVariable
.ArchList
= ArchList
84 # Create FV Address inf file
86 GenFdsGlobalVariable
.FvAddressFileName
= os
.path
.join(GenFdsGlobalVariable
.FfsDir
, 'FvAddress.inf')
87 FvAddressFile
= open (GenFdsGlobalVariable
.FvAddressFileName
, 'w')
91 FvAddressFile
.writelines("[options]" + T_CHAR_LF
)
94 if GenFdsGlobalVariable
.WorkSpace
.BuildObject
[GenFdsGlobalVariable
.ActivePlatform
, Arch
].BsBaseAddress
:
95 BsAddress
= GenFdsGlobalVariable
.WorkSpace
.BuildObject
[GenFdsGlobalVariable
.ActivePlatform
, Arch
].BsBaseAddress
98 FvAddressFile
.writelines("EFI_BOOT_DRIVER_BASE_ADDRESS = " + \
103 for Arch
in ArchList
:
104 if GenFdsGlobalVariable
.WorkSpace
.BuildObject
[GenFdsGlobalVariable
.ActivePlatform
, Arch
].RtBaseAddress
:
105 RtAddress
= GenFdsGlobalVariable
.WorkSpace
.BuildObject
[GenFdsGlobalVariable
.ActivePlatform
, Arch
].RtBaseAddress
107 FvAddressFile
.writelines("EFI_RUNTIME_DRIVER_BASE_ADDRESS = " + \
111 FvAddressFile
.close()
113 ## ReplaceWorkspaceMacro()
115 # @param String String that may contain macro
117 def ReplaceWorkspaceMacro(String
):
118 Str
= String
.replace('$(WORKSPACE)', GenFdsGlobalVariable
.WorkSpaceDir
)
119 if os
.path
.exists(Str
):
120 if not os
.path
.isabs(Str
):
121 Str
= os
.path
.abspath(Str
)
123 Str
= os
.path
.join(GenFdsGlobalVariable
.WorkSpaceDir
, String
)
124 return os
.path
.normpath(Str
)
126 ## Check if the input files are newer than output files
128 # @param Output Path of output file
129 # @param Input Path list of input files
131 # @retval True if Output doesn't exist, or any Input is newer
132 # @retval False if all Input is older than Output
135 def NeedsUpdate(Output
, Input
):
136 if not os
.path
.exists(Output
):
138 # always update "Output" if no "Input" given
139 if Input
== None or len(Input
) == 0:
142 # if fdf file is changed after the 'Output" is generated, update the 'Output'
143 OutputTime
= os
.path
.getmtime(Output
)
144 if GenFdsGlobalVariable
.FdfFileTimeStamp
> OutputTime
:
148 # always update "Output" if any "Input" doesn't exist
149 if not os
.path
.exists(F
):
151 # always update "Output" if any "Input" is newer than "Output"
152 if os
.path
.getmtime(F
) > OutputTime
:
157 def GenerateSection(Output
, Input
, Type
=None, CompressionType
=None, Guid
=None,
158 GuidHdrLen
=None, GuidAttr
=[], Ui
=None, Ver
=None, InputAlign
=None):
159 if not GenFdsGlobalVariable
.NeedsUpdate(Output
, Input
):
161 GenFdsGlobalVariable
.DebugLogger(EdkLogger
.DEBUG_5
, "%s needs update because of newer %s" % (Output
, Input
))
164 if Type
not in [None, '']:
166 if CompressionType
not in [None, '']:
167 Cmd
+= ["-c", CompressionType
]
170 if GuidHdrLen
not in [None, '']:
171 Cmd
+= ["-l", GuidHdrLen
]
172 if len(GuidAttr
) != 0:
173 #Add each guided attribute
174 for Attr
in GuidAttr
:
176 if InputAlign
!= None:
177 #Section Align is only for dummy section without section type
178 for SecAlign
in InputAlign
:
179 Cmd
+= ["--sectionalign", SecAlign
]
181 if Ui
not in [None, '']:
182 #Cmd += ["-n", '"' + Ui + '"']
183 SectionData
= array
.array('B', [0,0,0,0])
184 SectionData
.fromstring(Ui
.encode("utf_16_le"))
185 SectionData
.append(0)
186 SectionData
.append(0)
187 Len
= len(SectionData
)
188 GenFdsGlobalVariable
.SectionHeader
.pack_into(SectionData
, 0, Len
& 0xff, (Len
>> 8) & 0xff, (Len
>> 16) & 0xff, 0x15)
189 SaveFileOnChange(Output
, SectionData
.tostring())
190 elif Ver
not in [None, '']:
192 SectionData
= array
.array('B', [0,0,0,0])
193 SectionData
.fromstring(Ver
.encode("utf_16_le"))
194 SectionData
.append(0)
195 SectionData
.append(0)
196 Len
= len(SectionData
)
197 GenFdsGlobalVariable
.SectionHeader
.pack_into(SectionData
, 0, Len
& 0xff, (Len
>> 8) & 0xff, (Len
>> 16) & 0xff, 0x14)
198 SaveFileOnChange(Output
, SectionData
.tostring())
200 Cmd
+= ["-o", Output
]
202 GenFdsGlobalVariable
.CallExternalTool(Cmd
, "Failed to generate section")
205 def GetAlignment (AlignString
):
206 if AlignString
== None:
208 if AlignString
in ("1K", "2K", "4K", "8K", "16K", "32K", "64K"):
209 return int (AlignString
.rstrip('K')) * 1024
211 return int (AlignString
)
214 def GenerateFfs(Output
, Input
, Type
, Guid
, Fixed
=False, CheckSum
=False, Align
=None,
216 if not GenFdsGlobalVariable
.NeedsUpdate(Output
, Input
):
218 GenFdsGlobalVariable
.DebugLogger(EdkLogger
.DEBUG_5
, "%s needs update because of newer %s" % (Output
, Input
))
220 Cmd
= ["GenFfs", "-t", Type
, "-g", Guid
]
225 if Align
not in [None, '']:
228 Cmd
+= ["-o", Output
]
229 for I
in range(0, len(Input
)):
230 Cmd
+= ("-i", Input
[I
])
231 if SectionAlign
not in [None, '', []] and SectionAlign
[I
] not in [None, '']:
232 Cmd
+= ("-n", SectionAlign
[I
])
233 GenFdsGlobalVariable
.CallExternalTool(Cmd
, "Failed to generate FFS")
236 def GenerateFirmwareVolume(Output
, Input
, BaseAddress
=None, Capsule
=False, Dump
=False,
237 AddressFile
=None, MapFile
=None, FfsList
=[]):
238 if not GenFdsGlobalVariable
.NeedsUpdate(Output
, Input
+FfsList
):
240 GenFdsGlobalVariable
.DebugLogger(EdkLogger
.DEBUG_5
, "%s needs update because of newer %s" % (Output
, Input
))
243 if BaseAddress
not in [None, '']:
244 Cmd
+= ["-r", BaseAddress
]
249 if AddressFile
not in [None, '']:
250 Cmd
+= ["-a", AddressFile
]
251 if MapFile
not in [None, '']:
252 Cmd
+= ["-m", MapFile
]
253 Cmd
+= ["-o", Output
]
257 GenFdsGlobalVariable
.CallExternalTool(Cmd
, "Failed to generate FV")
260 def GenerateVtf(Output
, Input
, BaseAddress
=None, FvSize
=None):
261 if not GenFdsGlobalVariable
.NeedsUpdate(Output
, Input
):
263 GenFdsGlobalVariable
.DebugLogger(EdkLogger
.DEBUG_5
, "%s needs update because of newer %s" % (Output
, Input
))
266 if BaseAddress
not in [None, ''] and FvSize
not in [None, ''] \
267 and len(BaseAddress
) == len(FvSize
):
268 for I
in range(0, len(BaseAddress
)):
269 Cmd
+= ["-r", BaseAddress
[I
], "-s", FvSize
[I
]]
270 Cmd
+= ["-o", Output
]
274 GenFdsGlobalVariable
.CallExternalTool(Cmd
, "Failed to generate VTF")
277 def GenerateFirmwareImage(Output
, Input
, Type
="efi", SubType
=None, Zero
=False,
278 Strip
=False, Replace
=False, TimeStamp
=None, Join
=False,
279 Align
=None, Padding
=None, Convert
=False):
280 if not GenFdsGlobalVariable
.NeedsUpdate(Output
, Input
):
282 GenFdsGlobalVariable
.DebugLogger(EdkLogger
.DEBUG_5
, "%s needs update because of newer %s" % (Output
, Input
))
285 if Type
.lower() == "te":
287 if SubType
not in [None, '']:
288 Cmd
+= ["-e", SubType
]
289 if TimeStamp
not in [None, '']:
290 Cmd
+= ["-s", TimeStamp
]
291 if Align
not in [None, '']:
293 if Padding
not in [None, '']:
294 Cmd
+= ["-p", Padding
]
305 Cmd
+= ["-o", Output
]
308 GenFdsGlobalVariable
.CallExternalTool(Cmd
, "Failed to generate firmware image")
311 def GenerateOptionRom(Output
, EfiInput
, BinaryInput
, Compress
=False, ClassCode
=None,
312 Revision
=None, DeviceId
=None, VendorId
=None):
315 if len(EfiInput
) > 0:
322 for EfiFile
in EfiInput
:
324 InputList
.append (EfiFile
)
326 if len(BinaryInput
) > 0:
328 for BinFile
in BinaryInput
:
330 InputList
.append (BinFile
)
333 if not GenFdsGlobalVariable
.NeedsUpdate(Output
, InputList
):
335 GenFdsGlobalVariable
.DebugLogger(EdkLogger
.DEBUG_5
, "%s needs update because of newer %s" % (Output
, InputList
))
337 if ClassCode
!= None:
338 Cmd
+= ["-l", ClassCode
]
340 Cmd
+= ["-r", Revision
]
342 Cmd
+= ["-i", DeviceId
]
344 Cmd
+= ["-f", VendorId
]
346 Cmd
+= ["-o", Output
]
347 GenFdsGlobalVariable
.CallExternalTool(Cmd
, "Failed to generate option rom")
350 def GuidTool(Output
, Input
, ToolPath
, Options
='', returnValue
=[]):
351 if not GenFdsGlobalVariable
.NeedsUpdate(Output
, Input
):
353 GenFdsGlobalVariable
.DebugLogger(EdkLogger
.DEBUG_5
, "%s needs update because of newer %s" % (Output
, Input
))
356 Cmd
+= Options
.split(' ')
357 Cmd
+= ["-o", Output
]
360 GenFdsGlobalVariable
.CallExternalTool(Cmd
, "Failed to call " + ToolPath
, returnValue
)
362 def CallExternalTool (cmd
, errorMess
, returnValue
=[]):
364 if type(cmd
) not in (tuple, list):
365 GenFdsGlobalVariable
.ErrorLogger("ToolError! Invalid parameter type in call to CallExternalTool")
367 if GenFdsGlobalVariable
.DebugLevel
!= -1:
368 cmd
+= ('--debug', str(GenFdsGlobalVariable
.DebugLevel
))
369 GenFdsGlobalVariable
.InfLogger (cmd
)
371 if GenFdsGlobalVariable
.VerboseMode
:
373 GenFdsGlobalVariable
.InfLogger (cmd
)
375 sys
.stdout
.write ('#')
377 GenFdsGlobalVariable
.SharpCounter
= GenFdsGlobalVariable
.SharpCounter
+ 1
378 if GenFdsGlobalVariable
.SharpCounter
% GenFdsGlobalVariable
.SharpNumberPerLine
== 0:
379 sys
.stdout
.write('\n')
382 PopenObject
= subprocess
.Popen(cmd
, stdout
=subprocess
.PIPE
, stderr
= subprocess
.PIPE
)
384 EdkLogger
.error("GenFds", COMMAND_FAILURE
, ExtraData
="%s: %s" % (str(X
), cmd
[0]))
385 (out
, error
) = PopenObject
.communicate()
387 while PopenObject
.returncode
== None :
389 if returnValue
!= [] and returnValue
[0] != 0:
390 #get command return value
391 returnValue
[0] = PopenObject
.returncode
393 if PopenObject
.returncode
!= 0 or GenFdsGlobalVariable
.VerboseMode
or GenFdsGlobalVariable
.DebugLevel
!= -1:
394 GenFdsGlobalVariable
.InfLogger ("Return Value = %d" %PopenObject
.returncode
)
395 GenFdsGlobalVariable
.InfLogger (out
)
396 GenFdsGlobalVariable
.InfLogger (error
)
397 if PopenObject
.returncode
!= 0:
399 EdkLogger
.error("GenFds", COMMAND_FAILURE
, errorMess
)
401 def VerboseLogger (msg
):
402 EdkLogger
.verbose(msg
)
407 def ErrorLogger (msg
, File
= None, Line
= None, ExtraData
= None):
408 EdkLogger
.error('GenFds', GENFDS_ERROR
, msg
, File
, Line
, ExtraData
)
410 def DebugLogger (Level
, msg
):
411 EdkLogger
.debug(Level
, msg
)
413 ## ReplaceWorkspaceMacro()
415 # @param Str String that may contain macro
416 # @param MacroDict Dictionary that contains macro value pair
418 def MacroExtend (Str
, MacroDict
= {}, Arch
= 'COMMON'):
422 Dict
= {'$(WORKSPACE)' : GenFdsGlobalVariable
.WorkSpaceDir
,
423 '$(EDK_SOURCE)' : GenFdsGlobalVariable
.EdkSourceDir
,
424 # '$(OUTPUT_DIRECTORY)': GenFdsGlobalVariable.OutputDirFromDsc,
425 '$(TARGET)' : GenFdsGlobalVariable
.TargetName
,
426 '$(TOOL_CHAIN_TAG)' : GenFdsGlobalVariable
.ToolChainTag
428 OutputDir
= GenFdsGlobalVariable
.OutputDirFromDscDict
[GenFdsGlobalVariable
.ArchList
[0]]
429 if Arch
!= 'COMMON' and Arch
in GenFdsGlobalVariable
.ArchList
:
430 OutputDir
= GenFdsGlobalVariable
.OutputDirFromDscDict
[Arch
]
432 Dict
['$(OUTPUT_DIRECTORY)'] = OutputDir
434 if MacroDict
!= None and len (MacroDict
) != 0:
435 Dict
.update(MacroDict
)
437 for key
in Dict
.keys():
438 if Str
.find(key
) >= 0 :
439 Str
= Str
.replace (key
, Dict
[key
])
441 if Str
.find('$(ARCH)') >= 0:
442 if len(GenFdsGlobalVariable
.ArchList
) == 1:
443 Str
= Str
.replace('$(ARCH)', GenFdsGlobalVariable
.ArchList
[0])
445 EdkLogger
.error("GenFds", GENFDS_ERROR
, "No way to determine $(ARCH) for %s" % Str
)
451 # @param PcdPattern pattern that labels a PCD.
453 def GetPcdValue (PcdPattern
):
454 if PcdPattern
== None :
456 PcdPair
= PcdPattern
.lstrip('PCD(').rstrip(')').strip().split('.')
457 TokenSpace
= PcdPair
[0]
458 TokenCName
= PcdPair
[1]
461 for Platform
in GenFdsGlobalVariable
.WorkSpace
.PlatformList
:
462 PcdDict
= Platform
.Pcds
464 PcdObj
= PcdDict
[Key
]
465 if (PcdObj
.TokenCName
== TokenCName
) and (PcdObj
.TokenSpaceGuidCName
== TokenSpace
):
466 if PcdObj
.Type
!= 'FixedAtBuild':
467 EdkLogger
.error("GenFds", GENFDS_ERROR
, "%s is not FixedAtBuild type." % PcdPattern
)
468 if PcdObj
.DatumType
!= 'VOID*':
469 EdkLogger
.error("GenFds", GENFDS_ERROR
, "%s is not VOID* datum type." % PcdPattern
)
471 PcdValue
= PcdObj
.DefaultValue
474 for Package
in GenFdsGlobalVariable
.WorkSpace
.PackageList
:
475 PcdDict
= Package
.Pcds
477 PcdObj
= PcdDict
[Key
]
478 if (PcdObj
.TokenCName
== TokenCName
) and (PcdObj
.TokenSpaceGuidCName
== TokenSpace
):
479 if PcdObj
.Type
!= 'FixedAtBuild':
480 EdkLogger
.error("GenFds", GENFDS_ERROR
, "%s is not FixedAtBuild type." % PcdPattern
)
481 if PcdObj
.DatumType
!= 'VOID*':
482 EdkLogger
.error("GenFds", GENFDS_ERROR
, "%s is not VOID* datum type." % PcdPattern
)
484 PcdValue
= PcdObj
.DefaultValue
489 SetDir
= staticmethod(SetDir
)
490 ReplaceWorkspaceMacro
= staticmethod(ReplaceWorkspaceMacro
)
491 CallExternalTool
= staticmethod(CallExternalTool
)
492 VerboseLogger
= staticmethod(VerboseLogger
)
493 InfLogger
= staticmethod(InfLogger
)
494 ErrorLogger
= staticmethod(ErrorLogger
)
495 DebugLogger
= staticmethod(DebugLogger
)
496 MacroExtend
= staticmethod (MacroExtend
)
497 GetPcdValue
= staticmethod(GetPcdValue
)