]> git.proxmox.com Git - mirror_edk2.git/blob - BaseTools/Source/Python/MigrationMsa2Inf/AutoGenExterns.py
Sync EDKII BaseTools to BaseTools project r1971
[mirror_edk2.git] / BaseTools / Source / Python / MigrationMsa2Inf / AutoGenExterns.py
1 #!/usr/bin/env python
2 #
3 #
4 # Copyright (c) 2007, Intel Corporation. All rights reserved.<BR>
5 # This program and the accompanying materials
6 # are licensed and made available under the terms and conditions of the BSD License
7 # which accompanies this distribution. The full text of the license may be found at
8 # http://opensource.org/licenses/bsd-license.php
9 #
10 # THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
12
13
14 #
15 # Import Modules
16 #
17 import re, os, glob
18 from Common.XmlRoutines import *
19
20 #"ModuleType"=>(PackageGuid, headerFileName) List
21 HeaderFiles = {}
22 GuidList = []
23 GuidMap = {}
24 HeaderFileContents = {}
25 gTest = {}
26 GuidMacro2CName = {}
27 GuidAliasList = []
28
29 def collectIncludeFolder(pkgDirName, guidType, pkgName):
30 includeFolder = os.path.join(pkgDirName, "Include", guidType)
31 if os.path.exists(includeFolder) and os.path.isdir(includeFolder):
32 for headerFileName in os.listdir(includeFolder):
33 if headerFileName[-2:] == ".h":
34 headerFile = open(os.path.join(includeFolder, headerFileName))
35 HeaderFileContents[(guidType, headerFileName, pkgName)] = headerFile.read()
36 headerFile.close()
37
38 GuidMacroReg = re.compile(r"\b(?!EFI_GUID\b)[A-Z0-9_]+_GUID\b")
39 GuidCNameReg = re.compile(r"\bg\w+Guid\b")
40 GuidAliasReg = re.compile(r"#define\s+([A-Z0-9_]+_GUID)\s+([A-Z0-9_]+_GUID)\b")
41
42 def collectPackageInfo(spdFileName):
43 pkgDirName = os.path.dirname(spdFileName)
44
45 spd = XmlParseFile(spdFileName)
46
47 pkgName = XmlElement(spd, "/PackageSurfaceArea/SpdHeader/PackageName")
48 pkgGuid = XmlElement(spd, "/PackageSurfaceArea/SpdHeader/GuidValue")
49
50
51 for IncludePkgHeader in XmlList(spd, "/PackageSurfaceArea/PackageHeaders/IncludePkgHeader"):
52 moduleType = XmlAttribute(IncludePkgHeader, "ModuleType")
53 headerFilePath = XmlElementData(IncludePkgHeader)
54 headerFilePath = re.sub("Include/", "", headerFilePath, 1)
55
56 headerTuple = HeaderFiles.get(moduleType, [])
57 headerTuple.append((pkgGuid, headerFilePath))
58 HeaderFiles[moduleType] = headerTuple
59
60 guidTypes = ["Guid", "Protocol", "Ppi"]
61
62 for guidType in guidTypes:
63 for guidEntry in XmlList(spd, "/PackageSurfaceArea/" + guidType + "Declarations/Entry"):
64 guidCName = XmlElement(guidEntry, "Entry/C_Name")
65 GuidList.append(guidCName)
66
67 collectIncludeFolder(pkgDirName, guidType, pkgName)
68
69 for DecFile in glob.glob(os.path.join(pkgDirName, "*.dec")):
70 fileContents = open(DecFile).read()
71 for GuidCNameMatch in GuidCNameReg.finditer(fileContents):
72 GuidCName = GuidCNameMatch.group(0)
73 if GuidCName not in GuidList:
74 GuidList.append(GuidCName)
75
76 def AddGuidMacro2GuidCName(GuidMacros, GuidCNames):
77 for GuidMacro in GuidMacros:
78 GuessGuidCName = "g" + GuidMacro.lower().title().replace("_", "")
79 if GuessGuidCName in GuidCNames:
80 GuidMacro2CName[GuidMacro] = GuessGuidCName
81 elif len(GuidCNames) == 1:
82 GuidMacro2CName[GuidMacro] = GuidCNames[0]
83 else:
84 for GuidCName in GuidCNames:
85 if GuidCName.lower() == GuessGuidCName.lower():
86 GuidMacro2CName[GuidMacro] = GuidCName
87 break
88 else:
89 pass
90 #print "No matching GuidMacro %s" % GuidMacro
91
92
93 def TranslateGuid(GuidMacroMatch):
94 GuidMacro = GuidMacroMatch.group(0)
95 return GuidMacro2CName.get(GuidMacro, GuidMacro)
96
97 DepexReg = re.compile(r"DEPENDENCY_START(.*?)DEPENDENCY_END", re.DOTALL)
98
99 def TranslateDpxSection(fileContents):
100 DepexMatch = DepexReg.search(fileContents)
101 if not DepexMatch:
102 return "", []
103
104 fileContents = DepexMatch.group(1)
105 fileContents = re.sub(r"\s+", " ", fileContents).strip()
106 fileContents = GuidMacroReg.sub(TranslateGuid, fileContents)
107 return fileContents, GuidMacroReg.findall(fileContents)
108
109 def InitializeAutoGen(workspace, db):
110
111
112 for spdFile in XmlList(db, "/FrameworkDatabase/PackageList/Filename"):
113 spdFileName = XmlElementData(spdFile)
114 collectPackageInfo(os.path.join(workspace, spdFileName))
115
116
117 BlockCommentReg = re.compile(r"/\*.*?\*/", re.DOTALL)
118 LineCommentReg = re.compile(r"//.*")
119 GuidReg = re.compile(r"\b(" + '|'.join(GuidList) + r")\b")
120
121 for headerFile in HeaderFileContents:
122 Contents = HeaderFileContents[headerFile]
123 Contents = BlockCommentReg.sub("", Contents)
124 Contents = LineCommentReg.sub("", Contents)
125
126 FoundGuids = GuidReg.findall(Contents)
127 for FoundGuid in FoundGuids:
128 GuidMap[FoundGuid] = "%s/%s" % (headerFile[0], headerFile[1])
129 #print "%-40s %s/%s" % (FoundGuid, headerFile[0], headerFile[1])
130
131 GuidMacros = GuidMacroReg.findall(Contents)
132 GuidCNames = GuidCNameReg.findall(Contents)
133
134 for GuidAliasMatch in GuidAliasReg.finditer(Contents):
135 Name1, Name2 = GuidAliasMatch.group(1), GuidAliasMatch.group(2)
136 GuidAliasList.append((Name1, Name2))
137
138 AddGuidMacro2GuidCName(GuidMacros, GuidCNames)
139
140 def AddSystemIncludeStatement(moduleType, PackageList):
141 IncludeStatement = "\n"
142
143 headerList = HeaderFiles.get(moduleType, [])
144
145 for pkgGuid in PackageList:
146
147 for pkgTuple in headerList:
148 if pkgTuple[0] == pkgGuid:
149 IncludeStatement += "#include <%s>\n" % pkgTuple[1]
150
151 return IncludeStatement
152
153
154 def AddLibraryClassStatement(LibraryClassList):
155 IncludeStatement = "\n"
156 for LibraryClass in LibraryClassList:
157 IncludeStatement += "#include <Library/%s.h>\n" % LibraryClass
158
159 return IncludeStatement
160
161 def AddGuidStatement(GuidList):
162 IncludeStatement = "\n"
163 GuidIncludeSet = {}
164 for Guid in GuidList:
165 if Guid in GuidMap:
166 GuidIncludeSet[GuidMap[Guid]] = 1
167 else:
168 print "GUID CName: %s cannot be found in any public header file" % Guid
169
170 for GuidInclude in GuidIncludeSet:
171 IncludeStatement += "#include <%s>\n" % GuidInclude
172
173 return IncludeStatement
174
175 DriverBindingMap = {
176 "gEfiDriverBindingProtocolGuid" : "EFI_DRIVER_BINDING_PROTOCOL",
177 "gEfiComponentNameProtocolGuid" : "EFI_COMPONENT_NAME_PROTOCOL",
178 "gEfiDriverConfigurationProtocolGuid" : "EFI_DRIVER_CONFIGURATION_PROTOCOL",
179 "gEfiDriverDiagnosticProtocolGuid" : "EFI_DRIVER_CONFIGURATION_PROTOCOL"
180 }
181
182 def AddDriverBindingProtocolStatement(AutoGenDriverModel):
183 InstallStatement = "\n"
184 DBindingHandle = "ImageHandle"
185 GlobalDeclaration = "\n"
186
187
188 for DriverModelItem in AutoGenDriverModel:
189
190 if DriverModelItem[1] == "NULL" and DriverModelItem[2] == "NULL" and DriverModelItem[3] == "NULL":
191 InstallStatement += " Status = EfiLibInstallDriverBinding (\n"
192 InstallStatement += " ImageHandle,\n"
193 InstallStatement += " SystemTable,\n"
194 InstallStatement += " %s,\n" % DriverModelItem[0]
195 InstallStatement += " %s\n" % DBindingHandle
196 InstallStatement += " );\n"
197 else:
198 InstallStatement += " Status = EfiLibInstallAllDriverProtocols (\n"
199 InstallStatement += " ImageHandle,\n"
200 InstallStatement += " SystemTable,\n"
201 InstallStatement += " %s,\n" % DriverModelItem[0]
202 InstallStatement += " %s,\n" % DBindingHandle
203 InstallStatement += " %s,\n" % DriverModelItem[1]
204 InstallStatement += " %s,\n" % DriverModelItem[2]
205 InstallStatement += " %s\n" % DriverModelItem[3]
206 InstallStatement += " );\n"
207
208 InstallStatement += " ASSERT_EFI_ERROR (Status);\n\n"
209
210 GlobalDeclaration += "extern EFI_DRIVER_BINDING_PROTOCOL %s;\n" % DriverModelItem[0][1:]
211 if (DriverModelItem[1] != "NULL"):
212 GlobalDeclaration += "extern EFI_COMPONENT_NAME_PROTOCOL %s;\n" % DriverModelItem[1][1:]
213 if (DriverModelItem[2] != "NULL"):
214 GlobalDeclaration += "extern EFI_DRIVER_CONFIGURATION_PROTOCOL %s;\n" % DriverModelItem[2][1:]
215 if (DriverModelItem[3] != "NULL"):
216 GlobalDeclaration += "extern EFI_DRIVER_CONFIGURATION_PROTOCOL %s;\n" % DriverModelItem[3][1:]
217
218 DBindingHandle = "NULL"
219
220 return (InstallStatement, "", "", GlobalDeclaration)
221
222 EventDeclarationTemplate = """
223 //
224 // Declaration for callback Event.
225 //
226 VOID
227 EFIAPI
228 %s (
229 IN EFI_EVENT Event,
230 IN VOID *Context
231 );
232 """
233
234 def AddBootServiceEventStatement(EventList):
235 FinalEvent = ""
236 if len(EventList) > 1:
237
238 print "Current prototype does not support multi boot service event"
239 else:
240 FinalEvent = EventList[0]
241
242 CreateStatement = "\n"
243 CreateStatement += " Status = gBS->CreateEvent (\n"
244 CreateStatement += " EVT_SIGNAL_EXIT_BOOT_SERVICES,\n"
245 CreateStatement += " EFI_TPL_NOTIFY,\n"
246 CreateStatement += " " + FinalEvent + ",\n"
247 CreateStatement += " NULL,\n"
248 CreateStatement += " &mExitBootServicesEvent\n"
249 CreateStatement += " );\n"
250 CreateStatement += " ASSERT_EFI_ERROR (Status);\n"
251
252 GlobalDefinition = "\n"
253 GlobalDefinition += "STATIC EFI_EVENT mExitBootServicesEvent = NULL;\n"
254
255 GlobalDeclaration = EventDeclarationTemplate % FinalEvent
256
257 DestroyStatement = "\n"
258 DestroyStatement += " Status = gBS->CloseEvent (mExitBootServicesEvent);\n"
259 DestroyStatement += " ASSERT_EFI_ERROR (Status);\n"
260 return (CreateStatement, "", GlobalDefinition, GlobalDeclaration)
261
262 def AddVirtualAddressEventStatement(EventList):
263 FinalEvent = ""
264 if len(EventList) > 1:
265 print "Current prototype does not support multi virtual address change event"
266 else:
267 FinalEvent = EventList[0]
268
269 CreateStatement = "\n"
270
271 CreateStatement += " Status = gBS->CreateEvent (\n"
272 CreateStatement += " EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE,\n"
273 CreateStatement += " TPL_NOTIFY,\n"
274 CreateStatement += " " + FinalEvent + ",\n"
275 CreateStatement += " NULL,\n"
276 CreateStatement += " &mVirtualAddressChangedEvent\n"
277 CreateStatement += " );\n"
278 CreateStatement += " ASSERT_EFI_ERROR (Status);\n"
279
280 GlobalDefinition = "\n"
281 GlobalDefinition += "STATIC EFI_EVENT mVirtualAddressChangedEvent = NULL;\n"
282
283 GlobalDeclaration = EventDeclarationTemplate % FinalEvent
284
285 DestroyStatement = "\n"
286 DestroyStatement += " Status = gBS->CloseEvent (mVirtualAddressChangedEvent);\n"
287 DestroyStatement += " ASSERT_EFI_ERROR (Status);\n"
288
289 return (CreateStatement, "", GlobalDefinition, GlobalDeclaration)
290
291
292 EntryPointDeclarationTemplate = """
293 //
294 // Declaration for original Entry Point.
295 //
296 EFI_STATUS
297 EFIAPI
298 %s (
299 IN EFI_HANDLE ImageHandle,
300 IN EFI_SYSTEM_TABLE *SystemTable
301 );
302 """
303
304 EntryPointHeader = r"""
305 /**
306 The user Entry Point for module %s. The user code starts with this function.
307
308 @param[in] ImageHandle The firmware allocated handle for the EFI image.
309 @param[in] SystemTable A pointer to the EFI System Table.
310
311 @retval EFI_SUCCESS The entry point is executed successfully.
312 @retval other Some error occurs when executing this entry point.
313
314 **/
315 """
316 def AddNewEntryPointContentsStatement (moduleName, EntryPoint, InstallStatement = ""):
317 if EntryPoint != "Initialize%s" % moduleName:
318 NewEntryPoint = "Initialize%s" % moduleName
319 else:
320 NewEntryPoint = "NewInitialize%s" % moduleName
321
322 EntryPointContents = EntryPointHeader % moduleName
323 EntryPointContents += "EFI_STATUS\n"
324 EntryPointContents += "EFIAPI\n"
325 EntryPointContents += NewEntryPoint + "(\n"
326 EntryPointContents += " IN EFI_HANDLE ImageHandle,\n"
327 EntryPointContents += " IN EFI_SYSTEM_TABLE *SystemTable\n"
328 EntryPointContents += " )\n"
329 EntryPointContents += "{\n"
330 EntryPointContents += " EFI_STATUS Status;\n"
331 EntryPointContents += InstallStatement + "\n"
332 GlobalDeclaration = ""
333
334 if EntryPoint != "":
335 EntryPointContents += " //\n // Call the original Entry Point\n //\n"
336 EntryPointContents += " Status = %s (ImageHandle, SystemTable);\n\n" % EntryPoint
337 GlobalDeclaration += EntryPointDeclarationTemplate % EntryPoint
338
339 EntryPointContents += " return Status;\n"
340 EntryPointContents += "}\n"
341
342 return (NewEntryPoint, EntryPointContents, GlobalDeclaration)
343
344 reFileHeader = re.compile(r"^\s*/\*.*?\*/\s*", re.DOTALL)
345 reNext = re.compile(r"#ifndef\s*(\w+)\s*#define\s*\1\s*")
346
347 def AddCommonInclusionStatement(fileContents, includeStatement):
348 if includeStatement in fileContents:
349 return fileContents
350
351 insertPos = 0
352 matchFileHeader = reFileHeader.search(fileContents)
353 if matchFileHeader:
354 insertPos = matchFileHeader.end()
355
356 matchFileHeader = reNext.search(fileContents, insertPos)
357 if matchFileHeader:
358 insertPos = matchFileHeader.end()
359
360 includeStatement = "\n%s\n\n" % includeStatement
361 fileContents = fileContents[0:insertPos] + includeStatement + fileContents[insertPos:]
362 return fileContents
363
364 # This acts like the main() function for the script, unless it is 'import'ed into another
365 # script.
366 if __name__ == '__main__':
367
368 pass
369