]>
git.proxmox.com Git - mirror_edk2.git/blob - BaseTools/Source/Python/GenFds/GenFdsGlobalVariable.py
2 # Global variables for GenFds
4 # Copyright (c) 2007, 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
58 SectionHeader
= struct
.Struct("3B 1B")
62 # @param OutputDir Output directory
63 # @param FdfParser FDF contents parser
64 # @param Workspace The directory of workspace
65 # @param ArchList The Arch list of platform
67 def SetDir (OutputDir
, FdfParser
, WorkSpace
, ArchList
):
68 GenFdsGlobalVariable
.VerboseLogger( "GenFdsGlobalVariable.OutputDir :%s" %OutputDir
)
69 # GenFdsGlobalVariable.OutputDirDict = OutputDir
70 GenFdsGlobalVariable
.FdfParser
= FdfParser
71 GenFdsGlobalVariable
.WorkSpace
= WorkSpace
72 GenFdsGlobalVariable
.FvDir
= os
.path
.join(GenFdsGlobalVariable
.OutputDirDict
[ArchList
[0]], 'FV')
73 if not os
.path
.exists(GenFdsGlobalVariable
.FvDir
) :
74 os
.makedirs(GenFdsGlobalVariable
.FvDir
)
75 GenFdsGlobalVariable
.FfsDir
= os
.path
.join(GenFdsGlobalVariable
.FvDir
, 'Ffs')
76 if not os
.path
.exists(GenFdsGlobalVariable
.FfsDir
) :
77 os
.makedirs(GenFdsGlobalVariable
.FfsDir
)
79 GenFdsGlobalVariable
.ArchList
= ArchList
83 # Create FV Address inf file
85 GenFdsGlobalVariable
.FvAddressFileName
= os
.path
.join(GenFdsGlobalVariable
.FfsDir
, 'FvAddress.inf')
86 FvAddressFile
= open (GenFdsGlobalVariable
.FvAddressFileName
, 'w')
90 FvAddressFile
.writelines("[options]" + T_CHAR_LF
)
93 if GenFdsGlobalVariable
.WorkSpace
.BuildObject
[GenFdsGlobalVariable
.ActivePlatform
, Arch
].BsBaseAddress
:
94 BsAddress
= GenFdsGlobalVariable
.WorkSpace
.BuildObject
[GenFdsGlobalVariable
.ActivePlatform
, Arch
].BsBaseAddress
97 FvAddressFile
.writelines("EFI_BOOT_DRIVER_BASE_ADDRESS = " + \
102 for Arch
in ArchList
:
103 if GenFdsGlobalVariable
.WorkSpace
.BuildObject
[GenFdsGlobalVariable
.ActivePlatform
, Arch
].RtBaseAddress
:
104 RtAddress
= GenFdsGlobalVariable
.WorkSpace
.BuildObject
[GenFdsGlobalVariable
.ActivePlatform
, Arch
].RtBaseAddress
106 FvAddressFile
.writelines("EFI_RUNTIME_DRIVER_BASE_ADDRESS = " + \
110 FvAddressFile
.close()
112 ## ReplaceWorkspaceMacro()
114 # @param String String that may contain macro
116 def ReplaceWorkspaceMacro(String
):
117 Str
= String
.replace('$(WORKSPACE)', GenFdsGlobalVariable
.WorkSpaceDir
)
118 if os
.path
.exists(Str
):
119 if not os
.path
.isabs(Str
):
120 Str
= os
.path
.abspath(Str
)
122 Str
= os
.path
.join(GenFdsGlobalVariable
.WorkSpaceDir
, String
)
123 return os
.path
.normpath(Str
)
125 ## Check if the input files are newer than output files
127 # @param Output Path of output file
128 # @param Input Path list of input files
130 # @retval True if Output doesn't exist, or any Input is newer
131 # @retval False if all Input is older than Output
134 def NeedsUpdate(Output
, Input
):
135 if not os
.path
.exists(Output
):
137 # always update "Output" if no "Input" given
138 if Input
== None or len(Input
) == 0:
141 # if fdf file is changed after the 'Output" is generated, update the 'Output'
142 OutputTime
= os
.path
.getmtime(Output
)
143 if GenFdsGlobalVariable
.FdfFileTimeStamp
> OutputTime
:
147 # always update "Output" if any "Input" doesn't exist
148 if not os
.path
.exists(F
):
150 # always update "Output" if any "Input" is newer than "Output"
151 if os
.path
.getmtime(F
) > OutputTime
:
156 def GenerateSection(Output
, Input
, Type
=None, CompressionType
=None, Guid
=None,
157 GuidHdrLen
=None, GuidAttr
=None, Ui
=None, Ver
=None):
158 if not GenFdsGlobalVariable
.NeedsUpdate(Output
, Input
):
160 GenFdsGlobalVariable
.DebugLogger(EdkLogger
.DEBUG_5
, "%s needs update because of newer %s" % (Output
, Input
))
163 if Type
not in [None, '']:
165 if CompressionType
not in [None, '']:
166 Cmd
+= ["-c", CompressionType
]
169 if GuidHdrLen
not in [None, '']:
170 Cmd
+= ["-l", GuidHdrLen
]
171 if GuidAttr
not in [None, '']:
172 Cmd
+= ["-r", GuidAttr
]
174 if Ui
not in [None, '']:
175 #Cmd += ["-n", '"' + Ui + '"']
176 SectionData
= array
.array('B', [0,0,0,0])
177 SectionData
.fromstring(Ui
.encode("utf_16_le"))
178 SectionData
.append(0)
179 SectionData
.append(0)
180 Len
= len(SectionData
)
181 GenFdsGlobalVariable
.SectionHeader
.pack_into(SectionData
, 0, Len
& 0xff, (Len
>> 8) & 0xff, (Len
>> 16) & 0xff, 0x15)
182 SaveFileOnChange(Output
, SectionData
.tostring())
183 elif Ver
not in [None, '']:
185 SectionData
= array
.array('B', [0,0,0,0])
186 SectionData
.fromstring(Ver
.encode("utf_16_le"))
187 SectionData
.append(0)
188 SectionData
.append(0)
189 Len
= len(SectionData
)
190 GenFdsGlobalVariable
.SectionHeader
.pack_into(SectionData
, 0, Len
& 0xff, (Len
>> 8) & 0xff, (Len
>> 16) & 0xff, 0x14)
191 SaveFileOnChange(Output
, SectionData
.tostring())
193 Cmd
+= ["-o", Output
]
195 GenFdsGlobalVariable
.CallExternalTool(Cmd
, "Failed to generate section")
198 def GenerateFfs(Output
, Input
, Type
, Guid
, Fixed
=False, CheckSum
=False, Align
=None,
200 if not GenFdsGlobalVariable
.NeedsUpdate(Output
, Input
):
202 GenFdsGlobalVariable
.DebugLogger(EdkLogger
.DEBUG_5
, "%s needs update because of newer %s" % (Output
, Input
))
204 Cmd
= ["GenFfs", "-t", Type
, "-g", Guid
]
209 if Align
not in [None, '']:
212 Cmd
+= ["-o", Output
]
213 for I
in range(0, len(Input
)):
214 Cmd
+= ("-i", Input
[I
])
215 if SectionAlign
not in [None, '', []] and SectionAlign
[I
] not in [None, '']:
216 Cmd
+= ("-n", SectionAlign
[I
])
217 GenFdsGlobalVariable
.CallExternalTool(Cmd
, "Failed to generate FFS")
220 def GenerateFirmwareVolume(Output
, Input
, BaseAddress
=None, Capsule
=False, Dump
=False,
221 AddressFile
=None, MapFile
=None, FfsList
=[]):
222 if not GenFdsGlobalVariable
.NeedsUpdate(Output
, Input
+FfsList
):
224 GenFdsGlobalVariable
.DebugLogger(EdkLogger
.DEBUG_5
, "%s needs update because of newer %s" % (Output
, Input
))
227 if BaseAddress
not in [None, '']:
228 Cmd
+= ["-r", BaseAddress
]
233 if AddressFile
not in [None, '']:
234 Cmd
+= ["-a", AddressFile
]
235 if MapFile
not in [None, '']:
236 Cmd
+= ["-m", MapFile
]
237 Cmd
+= ["-o", Output
]
241 GenFdsGlobalVariable
.CallExternalTool(Cmd
, "Failed to generate FV")
244 def GenerateVtf(Output
, Input
, BaseAddress
=None, FvSize
=None):
245 if not GenFdsGlobalVariable
.NeedsUpdate(Output
, Input
):
247 GenFdsGlobalVariable
.DebugLogger(EdkLogger
.DEBUG_5
, "%s needs update because of newer %s" % (Output
, Input
))
250 if BaseAddress
not in [None, ''] and FvSize
not in [None, ''] \
251 and len(BaseAddress
) == len(FvSize
):
252 for I
in range(0, len(BaseAddress
)):
253 Cmd
+= ["-r", BaseAddress
[I
], "-s", FvSize
[I
]]
254 Cmd
+= ["-o", Output
]
258 GenFdsGlobalVariable
.CallExternalTool(Cmd
, "Failed to generate VTF")
261 def GenerateFirmwareImage(Output
, Input
, Type
="efi", SubType
=None, Zero
=False,
262 Strip
=False, Replace
=False, TimeStamp
=None, Join
=False,
263 Align
=None, Padding
=None, Convert
=False):
264 if not GenFdsGlobalVariable
.NeedsUpdate(Output
, Input
):
266 GenFdsGlobalVariable
.DebugLogger(EdkLogger
.DEBUG_5
, "%s needs update because of newer %s" % (Output
, Input
))
269 if Type
.lower() == "te":
271 if SubType
not in [None, '']:
272 Cmd
+= ["-e", SubType
]
273 if TimeStamp
not in [None, '']:
274 Cmd
+= ["-s", TimeStamp
]
275 if Align
not in [None, '']:
277 if Padding
not in [None, '']:
278 Cmd
+= ["-p", Padding
]
289 Cmd
+= ["-o", Output
]
292 GenFdsGlobalVariable
.CallExternalTool(Cmd
, "Failed to generate firmware image")
295 def GenerateOptionRom(Output
, EfiInput
, BinaryInput
, Compress
=False, ClassCode
=None,
296 Revision
=None, DeviceId
=None, VendorId
=None):
297 # if not GenFdsGlobalVariable.NeedsUpdate(Output, Input):
299 # GenFdsGlobalVariable.DebugLogger(EdkLogger.DEBUG_5, "%s needs update because of newer %s" % (Output, Input))
302 if len(EfiInput
) > 0:
309 for EfiFile
in EfiInput
:
312 if len(BinaryInput
) > 0:
314 for BinFile
in BinaryInput
:
317 if ClassCode
!= None:
318 Cmd
+= ["-l", ClassCode
]
320 Cmd
+= ["-r", Revision
]
322 Cmd
+= ["-i", DeviceId
]
324 Cmd
+= ["-f", VendorId
]
326 Cmd
+= ["-o", Output
]
327 GenFdsGlobalVariable
.CallExternalTool(Cmd
, "Failed to generate option rom")
330 def GuidTool(Output
, Input
, ToolPath
, Options
=''):
331 if not GenFdsGlobalVariable
.NeedsUpdate(Output
, Input
):
333 GenFdsGlobalVariable
.DebugLogger(EdkLogger
.DEBUG_5
, "%s needs update because of newer %s" % (Output
, Input
))
335 Cmd
= [ToolPath
, Options
]
336 Cmd
+= ["-o", Output
]
339 GenFdsGlobalVariable
.CallExternalTool(Cmd
, "Failed to call " + ToolPath
)
341 def CallExternalTool (cmd
, errorMess
):
343 if type(cmd
) not in (tuple, list):
344 GenFdsGlobalVariable
.ErrorLogger("ToolError! Invalid parameter type in call to CallExternalTool")
346 if GenFdsGlobalVariable
.DebugLevel
!= -1:
347 cmd
+= ('--debug', str(GenFdsGlobalVariable
.DebugLevel
))
348 GenFdsGlobalVariable
.InfLogger (cmd
)
350 if GenFdsGlobalVariable
.VerboseMode
:
352 GenFdsGlobalVariable
.InfLogger (cmd
)
354 sys
.stdout
.write ('#')
356 GenFdsGlobalVariable
.SharpCounter
= GenFdsGlobalVariable
.SharpCounter
+ 1
357 if GenFdsGlobalVariable
.SharpCounter
% GenFdsGlobalVariable
.SharpNumberPerLine
== 0:
358 sys
.stdout
.write('\n')
361 PopenObject
= subprocess
.Popen(cmd
, stdout
=subprocess
.PIPE
, stderr
= subprocess
.PIPE
)
363 EdkLogger
.error("GenFds", BuildToolError
.COMMAND_FAILURE
, ExtraData
="%s: %s" % (str(X
), cmd
[0]))
364 (out
, error
) = PopenObject
.communicate()
366 while PopenObject
.returncode
== None :
368 if PopenObject
.returncode
!= 0 or GenFdsGlobalVariable
.VerboseMode
or GenFdsGlobalVariable
.DebugLevel
!= -1:
369 GenFdsGlobalVariable
.InfLogger ("Return Value = %d" %PopenObject
.returncode
)
370 GenFdsGlobalVariable
.InfLogger (out
)
371 GenFdsGlobalVariable
.InfLogger (error
)
372 if PopenObject
.returncode
!= 0:
374 EdkLogger
.error("GenFds", BuildToolError
.COMMAND_FAILURE
, errorMess
)
376 def VerboseLogger (msg
):
377 EdkLogger
.verbose(msg
)
382 def ErrorLogger (msg
, File
= None, Line
= None, ExtraData
= None):
383 EdkLogger
.error('GenFds', BuildToolError
.GENFDS_ERROR
, msg
, File
, Line
, ExtraData
)
385 def DebugLogger (Level
, msg
):
386 EdkLogger
.debug(Level
, msg
)
388 ## ReplaceWorkspaceMacro()
390 # @param Str String that may contain macro
391 # @param MacroDict Dictionary that contains macro value pair
393 def MacroExtend (Str
, MacroDict
= {}, Arch
= 'COMMON'):
397 Dict
= {'$(WORKSPACE)' : GenFdsGlobalVariable
.WorkSpaceDir
,
398 '$(EDK_SOURCE)' : GenFdsGlobalVariable
.EdkSourceDir
,
399 # '$(OUTPUT_DIRECTORY)': GenFdsGlobalVariable.OutputDirFromDsc,
400 '$(TARGET)' : GenFdsGlobalVariable
.TargetName
,
401 '$(TOOL_CHAIN_TAG)' : GenFdsGlobalVariable
.ToolChainTag
403 OutputDir
= GenFdsGlobalVariable
.OutputDirFromDscDict
[GenFdsGlobalVariable
.ArchList
[0]]
404 if Arch
!= 'COMMON' and Arch
in GenFdsGlobalVariable
.ArchList
:
405 OutputDir
= GenFdsGlobalVariable
.OutputDirFromDscDict
[Arch
]
407 Dict
['$(OUTPUT_DIRECTORY)'] = OutputDir
409 if MacroDict
!= None and len (MacroDict
) != 0:
410 Dict
.update(MacroDict
)
412 for key
in Dict
.keys():
413 if Str
.find(key
) >= 0 :
414 Str
= Str
.replace (key
, Dict
[key
])
416 if Str
.find('$(ARCH)') >= 0:
417 if len(GenFdsGlobalVariable
.ArchList
) == 1:
418 Str
= Str
.replace('$(ARCH)', GenFdsGlobalVariable
.ArchList
[0])
420 EdkLogger
.error("GenFds", GENFDS_ERROR
, "No way to determine $(ARCH) for %s" % Str
)
426 # @param PcdPattern pattern that labels a PCD.
428 def GetPcdValue (PcdPattern
):
429 if PcdPattern
== None :
431 PcdPair
= PcdPattern
.lstrip('PCD(').rstrip(')').strip().split('.')
432 TokenSpace
= PcdPair
[0]
433 TokenCName
= PcdPair
[1]
436 for Platform
in GenFdsGlobalVariable
.WorkSpace
.PlatformList
:
437 PcdDict
= Platform
.Pcds
439 PcdObj
= PcdDict
[Key
]
440 if (PcdObj
.TokenCName
== TokenCName
) and (PcdObj
.TokenSpaceGuidCName
== TokenSpace
):
441 if PcdObj
.Type
!= 'FixedAtBuild':
442 EdkLogger
.error("GenFds", GENFDS_ERROR
, "%s is not FixedAtBuild type." % PcdPattern
)
443 if PcdObj
.DatumType
!= 'VOID*':
444 EdkLogger
.error("GenFds", GENFDS_ERROR
, "%s is not VOID* datum type." % PcdPattern
)
446 PcdValue
= PcdObj
.DefaultValue
449 for Package
in GenFdsGlobalVariable
.WorkSpace
.PackageList
:
450 PcdDict
= Package
.Pcds
452 PcdObj
= PcdDict
[Key
]
453 if (PcdObj
.TokenCName
== TokenCName
) and (PcdObj
.TokenSpaceGuidCName
== TokenSpace
):
454 if PcdObj
.Type
!= 'FixedAtBuild':
455 EdkLogger
.error("GenFds", GENFDS_ERROR
, "%s is not FixedAtBuild type." % PcdPattern
)
456 if PcdObj
.DatumType
!= 'VOID*':
457 EdkLogger
.error("GenFds", GENFDS_ERROR
, "%s is not VOID* datum type." % PcdPattern
)
459 PcdValue
= PcdObj
.DefaultValue
464 SetDir
= staticmethod(SetDir
)
465 ReplaceWorkspaceMacro
= staticmethod(ReplaceWorkspaceMacro
)
466 CallExternalTool
= staticmethod(CallExternalTool
)
467 VerboseLogger
= staticmethod(VerboseLogger
)
468 InfLogger
= staticmethod(InfLogger
)
469 ErrorLogger
= staticmethod(ErrorLogger
)
470 DebugLogger
= staticmethod(DebugLogger
)
471 MacroExtend
= staticmethod (MacroExtend
)
472 GetPcdValue
= staticmethod(GetPcdValue
)