]> git.proxmox.com Git - mirror_edk2.git/blob - BaseTools/Source/Python/GenFds/GuidSection.py
c55fb34f2b74e0703684622e2b4bed5d4489a8d9
[mirror_edk2.git] / BaseTools / Source / Python / GenFds / GuidSection.py
1 ## @file
2 # process GUIDed section generation
3 #
4 # Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>
5 # Copyright (c) 2018, Hewlett Packard Enterprise Development, L.P.<BR>
6 #
7 # This program and the accompanying materials
8 # are licensed and made available under the terms and conditions of the BSD License
9 # which accompanies this distribution. The full text of the license may be found at
10 # http://opensource.org/licenses/bsd-license.php
11 #
12 # THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
13 # WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
14 #
15
16 ##
17 # Import Modules
18 #
19 import Section
20 import subprocess
21 from Ffs import Ffs
22 import Common.LongFilePathOs as os
23 from GenFdsGlobalVariable import GenFdsGlobalVariable
24 from CommonDataClass.FdfClass import GuidSectionClassObject
25 from Common import ToolDefClassObject
26 import sys
27 from Common import EdkLogger
28 from Common.BuildToolError import *
29 from FvImageSection import FvImageSection
30 from Common.LongFilePathSupport import OpenLongFilePath as open
31 from GenFds import FindExtendTool
32 from Common.DataType import *
33
34 ## generate GUIDed section
35 #
36 #
37 class GuidSection(GuidSectionClassObject) :
38
39 ## The constructor
40 #
41 # @param self The object pointer
42 #
43 def __init__(self):
44 GuidSectionClassObject.__init__(self)
45
46 ## GenSection() method
47 #
48 # Generate GUIDed section
49 #
50 # @param self The object pointer
51 # @param OutputPath Where to place output file
52 # @param ModuleName Which module this section belongs to
53 # @param SecNum Index of section
54 # @param KeyStringList Filter for inputs of section generation
55 # @param FfsInf FfsInfStatement object that contains this section data
56 # @param Dict dictionary contains macro and its value
57 # @retval tuple (Generated file name, section alignment)
58 #
59 def GenSection(self, OutputPath, ModuleName, SecNum, KeyStringList, FfsInf=None, Dict={}, IsMakefile=False):
60 #
61 # Generate all section
62 #
63 self.KeyStringList = KeyStringList
64 self.CurrentArchList = GenFdsGlobalVariable.ArchList
65 if FfsInf is not None:
66 self.Alignment = FfsInf.__ExtendMacro__(self.Alignment)
67 self.NameGuid = FfsInf.__ExtendMacro__(self.NameGuid)
68 self.SectionType = FfsInf.__ExtendMacro__(self.SectionType)
69 self.CurrentArchList = [FfsInf.CurrentArch]
70
71 SectFile = tuple()
72 SectAlign = []
73 Index = 0
74 MaxAlign = None
75 if self.FvAddr != []:
76 FvAddrIsSet = True
77 else:
78 FvAddrIsSet = False
79
80 if self.ProcessRequired in ("TRUE", "1"):
81 if self.FvAddr != []:
82 #no use FvAddr when the image is processed.
83 self.FvAddr = []
84 if self.FvParentAddr is not None:
85 #no use Parent Addr when the image is processed.
86 self.FvParentAddr = None
87
88 for Sect in self.SectionList:
89 Index = Index + 1
90 SecIndex = '%s.%d' % (SecNum, Index)
91 # set base address for inside FvImage
92 if isinstance(Sect, FvImageSection):
93 if self.FvAddr != []:
94 Sect.FvAddr = self.FvAddr.pop(0)
95 self.IncludeFvSection = True
96 elif isinstance(Sect, GuidSection):
97 Sect.FvAddr = self.FvAddr
98 Sect.FvParentAddr = self.FvParentAddr
99 ReturnSectList, align = Sect.GenSection(OutputPath, ModuleName, SecIndex, KeyStringList, FfsInf, Dict, IsMakefile=IsMakefile)
100 if isinstance(Sect, GuidSection):
101 if Sect.IncludeFvSection:
102 self.IncludeFvSection = Sect.IncludeFvSection
103
104 if align is not None:
105 if MaxAlign is None:
106 MaxAlign = align
107 if GenFdsGlobalVariable.GetAlignment (align) > GenFdsGlobalVariable.GetAlignment (MaxAlign):
108 MaxAlign = align
109 if ReturnSectList != []:
110 if align is None:
111 align = "1"
112 for file in ReturnSectList:
113 SectFile += (file,)
114 SectAlign.append(align)
115
116 if MaxAlign is not None:
117 if self.Alignment is None:
118 self.Alignment = MaxAlign
119 else:
120 if GenFdsGlobalVariable.GetAlignment (MaxAlign) > GenFdsGlobalVariable.GetAlignment (self.Alignment):
121 self.Alignment = MaxAlign
122
123 OutputFile = OutputPath + \
124 os.sep + \
125 ModuleName + \
126 SUP_MODULE_SEC + \
127 SecNum + \
128 Ffs.SectionSuffix['GUIDED']
129 OutputFile = os.path.normpath(OutputFile)
130
131 ExternalTool = None
132 ExternalOption = None
133 if self.NameGuid is not None:
134 ExternalTool, ExternalOption = FindExtendTool(self.KeyStringList, self.CurrentArchList, self.NameGuid)
135
136 #
137 # If not have GUID , call default
138 # GENCRC32 section
139 #
140 if self.NameGuid is None :
141 GenFdsGlobalVariable.VerboseLogger("Use GenSection function Generate CRC32 Section")
142 GenFdsGlobalVariable.GenerateSection(OutputFile, SectFile, Section.Section.SectionType[self.SectionType], InputAlign=SectAlign, IsMakefile=IsMakefile)
143 OutputFileList = []
144 OutputFileList.append(OutputFile)
145 return OutputFileList, self.Alignment
146 #or GUID not in External Tool List
147 elif ExternalTool is None:
148 EdkLogger.error("GenFds", GENFDS_ERROR, "No tool found with GUID %s" % self.NameGuid)
149 else:
150 DummyFile = OutputFile + ".dummy"
151 #
152 # Call GenSection with DUMMY section type.
153 #
154 GenFdsGlobalVariable.GenerateSection(DummyFile, SectFile, InputAlign=SectAlign, IsMakefile=IsMakefile)
155 #
156 # Use external tool process the Output
157 #
158 TempFile = OutputPath + \
159 os.sep + \
160 ModuleName + \
161 SUP_MODULE_SEC + \
162 SecNum + \
163 '.tmp'
164 TempFile = os.path.normpath(TempFile)
165 #
166 # Remove temp file if its time stamp is older than dummy file
167 # Just in case the external tool fails at this time but succeeded before
168 # Error should be reported if the external tool does not generate a new output based on new input
169 #
170 if os.path.exists(TempFile) and os.path.exists(DummyFile) and os.path.getmtime(TempFile) < os.path.getmtime(DummyFile):
171 os.remove(TempFile)
172
173 FirstCall = False
174 CmdOption = '-e'
175 if ExternalOption is not None:
176 CmdOption = CmdOption + ' ' + ExternalOption
177 if not GenFdsGlobalVariable.EnableGenfdsMultiThread:
178 if self.ProcessRequired not in ("TRUE", "1") and self.IncludeFvSection and not FvAddrIsSet and self.FvParentAddr is not None:
179 #FirstCall is only set for the encapsulated flash FV image without process required attribute.
180 FirstCall = True
181 #
182 # Call external tool
183 #
184 ReturnValue = [1]
185 if FirstCall:
186 #first try to call the guided tool with -z option and CmdOption for the no process required guided tool.
187 GenFdsGlobalVariable.GuidTool(TempFile, [DummyFile], ExternalTool, '-z' + ' ' + CmdOption, ReturnValue)
188
189 #
190 # when no call or first call failed, ReturnValue are not 1.
191 # Call the guided tool with CmdOption
192 #
193 if ReturnValue[0] != 0:
194 FirstCall = False
195 ReturnValue[0] = 0
196 GenFdsGlobalVariable.GuidTool(TempFile, [DummyFile], ExternalTool, CmdOption)
197 #
198 # There is external tool which does not follow standard rule which return nonzero if tool fails
199 # The output file has to be checked
200 #
201
202 if not os.path.exists(TempFile) :
203 EdkLogger.error("GenFds", COMMAND_FAILURE, 'Fail to call %s, no output file was generated' % ExternalTool)
204
205 FileHandleIn = open(DummyFile, 'rb')
206 FileHandleIn.seek(0, 2)
207 InputFileSize = FileHandleIn.tell()
208
209 FileHandleOut = open(TempFile, 'rb')
210 FileHandleOut.seek(0, 2)
211 TempFileSize = FileHandleOut.tell()
212
213 Attribute = []
214 HeaderLength = None
215 if self.ExtraHeaderSize != -1:
216 HeaderLength = str(self.ExtraHeaderSize)
217
218 if self.ProcessRequired == "NONE" and HeaderLength is None:
219 if TempFileSize > InputFileSize:
220 FileHandleIn.seek(0)
221 BufferIn = FileHandleIn.read()
222 FileHandleOut.seek(0)
223 BufferOut = FileHandleOut.read()
224 if BufferIn == BufferOut[TempFileSize - InputFileSize:]:
225 HeaderLength = str(TempFileSize - InputFileSize)
226 #auto sec guided attribute with process required
227 if HeaderLength is None:
228 Attribute.append('PROCESSING_REQUIRED')
229
230 FileHandleIn.close()
231 FileHandleOut.close()
232
233 if FirstCall and 'PROCESSING_REQUIRED' in Attribute:
234 # Guided data by -z option on first call is the process required data. Call the guided tool with the real option.
235 GenFdsGlobalVariable.GuidTool(TempFile, [DummyFile], ExternalTool, CmdOption)
236
237 #
238 # Call Gensection Add Section Header
239 #
240 if self.ProcessRequired in ("TRUE", "1"):
241 if 'PROCESSING_REQUIRED' not in Attribute:
242 Attribute.append('PROCESSING_REQUIRED')
243
244 if self.AuthStatusValid in ("TRUE", "1"):
245 Attribute.append('AUTH_STATUS_VALID')
246 GenFdsGlobalVariable.GenerateSection(OutputFile, [TempFile], Section.Section.SectionType['GUIDED'],
247 Guid=self.NameGuid, GuidAttr=Attribute, GuidHdrLen=HeaderLength)
248
249 else:
250 #add input file for GenSec get PROCESSING_REQUIRED
251 GenFdsGlobalVariable.GuidTool(TempFile, [DummyFile], ExternalTool, CmdOption, IsMakefile=IsMakefile)
252 Attribute = []
253 HeaderLength = None
254 if self.ExtraHeaderSize != -1:
255 HeaderLength = str(self.ExtraHeaderSize)
256 if self.AuthStatusValid in ("TRUE", "1"):
257 Attribute.append('AUTH_STATUS_VALID')
258 if self.ProcessRequired == "NONE" and HeaderLength is None:
259 GenFdsGlobalVariable.GenerateSection(OutputFile, [TempFile], Section.Section.SectionType['GUIDED'],
260 Guid=self.NameGuid, GuidAttr=Attribute,
261 GuidHdrLen=HeaderLength, DummyFile=DummyFile, IsMakefile=IsMakefile)
262 else:
263 if self.ProcessRequired in ("TRUE", "1"):
264 if 'PROCESSING_REQUIRED' not in Attribute:
265 Attribute.append('PROCESSING_REQUIRED')
266 GenFdsGlobalVariable.GenerateSection(OutputFile, [TempFile], Section.Section.SectionType['GUIDED'],
267 Guid=self.NameGuid, GuidAttr=Attribute,
268 GuidHdrLen=HeaderLength, IsMakefile=IsMakefile)
269
270 OutputFileList = []
271 OutputFileList.append(OutputFile)
272 if 'PROCESSING_REQUIRED' in Attribute:
273 # reset guided section alignment to none for the processed required guided data
274 self.Alignment = None
275 self.IncludeFvSection = False
276 self.ProcessRequired = "TRUE"
277 if IsMakefile and self.Alignment is not None and self.Alignment.strip() == '0':
278 self.Alignment = '1'
279 return OutputFileList, self.Alignment
280
281
282