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
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.
18 from Common
.XmlRoutines
import *
20 #"ModuleType"=>(PackageGuid, headerFileName) List
24 HeaderFileContents
= {}
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()
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")
42 def collectPackageInfo(spdFileName
):
43 pkgDirName
= os
.path
.dirname(spdFileName
)
45 spd
= XmlParseFile(spdFileName
)
47 pkgName
= XmlElement(spd
, "/PackageSurfaceArea/SpdHeader/PackageName")
48 pkgGuid
= XmlElement(spd
, "/PackageSurfaceArea/SpdHeader/GuidValue")
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)
56 headerTuple
= HeaderFiles
.get(moduleType
, [])
57 headerTuple
.append((pkgGuid
, headerFilePath
))
58 HeaderFiles
[moduleType
] = headerTuple
60 guidTypes
= ["Guid", "Protocol", "Ppi"]
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
)
67 collectIncludeFolder(pkgDirName
, guidType
, pkgName
)
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
)
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]
84 for GuidCName
in GuidCNames
:
85 if GuidCName
.lower() == GuessGuidCName
.lower():
86 GuidMacro2CName
[GuidMacro
] = GuidCName
90 #print "No matching GuidMacro %s" % GuidMacro
93 def TranslateGuid(GuidMacroMatch
):
94 GuidMacro
= GuidMacroMatch
.group(0)
95 return GuidMacro2CName
.get(GuidMacro
, GuidMacro
)
97 DepexReg
= re
.compile(r
"DEPENDENCY_START(.*?)DEPENDENCY_END", re
.DOTALL
)
99 def TranslateDpxSection(fileContents
):
100 DepexMatch
= DepexReg
.search(fileContents
)
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
)
109 def InitializeAutoGen(workspace
, db
):
112 for spdFile
in XmlList(db
, "/FrameworkDatabase/PackageList/Filename"):
113 spdFileName
= XmlElementData(spdFile
)
114 collectPackageInfo(os
.path
.join(workspace
, spdFileName
))
117 BlockCommentReg
= re
.compile(r
"/\*.*?\*/", re
.DOTALL
)
118 LineCommentReg
= re
.compile(r
"//.*")
119 GuidReg
= re
.compile(r
"\b(" + '|'.join(GuidList
) + r
")\b")
121 for headerFile
in HeaderFileContents
:
122 Contents
= HeaderFileContents
[headerFile
]
123 Contents
= BlockCommentReg
.sub("", Contents
)
124 Contents
= LineCommentReg
.sub("", Contents
)
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])
131 GuidMacros
= GuidMacroReg
.findall(Contents
)
132 GuidCNames
= GuidCNameReg
.findall(Contents
)
134 for GuidAliasMatch
in GuidAliasReg
.finditer(Contents
):
135 Name1
, Name2
= GuidAliasMatch
.group(1), GuidAliasMatch
.group(2)
136 GuidAliasList
.append((Name1
, Name2
))
138 AddGuidMacro2GuidCName(GuidMacros
, GuidCNames
)
140 def AddSystemIncludeStatement(moduleType
, PackageList
):
141 IncludeStatement
= "\n"
143 headerList
= HeaderFiles
.get(moduleType
, [])
145 for pkgGuid
in PackageList
:
147 for pkgTuple
in headerList
:
148 if pkgTuple
[0] == pkgGuid
:
149 IncludeStatement
+= "#include <%s>\n" % pkgTuple
[1]
151 return IncludeStatement
154 def AddLibraryClassStatement(LibraryClassList
):
155 IncludeStatement
= "\n"
156 for LibraryClass
in LibraryClassList
:
157 IncludeStatement
+= "#include <Library/%s.h>\n" % LibraryClass
159 return IncludeStatement
161 def AddGuidStatement(GuidList
):
162 IncludeStatement
= "\n"
164 for Guid
in GuidList
:
166 GuidIncludeSet
[GuidMap
[Guid
]] = 1
168 print "GUID CName: %s cannot be found in any public header file" % Guid
170 for GuidInclude
in GuidIncludeSet
:
171 IncludeStatement
+= "#include <%s>\n" % GuidInclude
173 return IncludeStatement
176 "gEfiDriverBindingProtocolGuid" : "EFI_DRIVER_BINDING_PROTOCOL",
177 "gEfiComponentNameProtocolGuid" : "EFI_COMPONENT_NAME_PROTOCOL",
178 "gEfiDriverConfigurationProtocolGuid" : "EFI_DRIVER_CONFIGURATION_PROTOCOL",
179 "gEfiDriverDiagnosticProtocolGuid" : "EFI_DRIVER_CONFIGURATION_PROTOCOL"
182 def AddDriverBindingProtocolStatement(AutoGenDriverModel
):
183 InstallStatement
= "\n"
184 DBindingHandle
= "ImageHandle"
185 GlobalDeclaration
= "\n"
188 for DriverModelItem
in AutoGenDriverModel
:
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"
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"
208 InstallStatement
+= " ASSERT_EFI_ERROR (Status);\n\n"
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:]
218 DBindingHandle
= "NULL"
220 return (InstallStatement
, "", "", GlobalDeclaration
)
222 EventDeclarationTemplate
= """
224 // Declaration for callback Event.
234 def AddBootServiceEventStatement(EventList
):
236 if len(EventList
) > 1:
238 print "Current prototype does not support multi boot service event"
240 FinalEvent
= EventList
[0]
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"
252 GlobalDefinition
= "\n"
253 GlobalDefinition
+= "STATIC EFI_EVENT mExitBootServicesEvent = NULL;\n"
255 GlobalDeclaration
= EventDeclarationTemplate
% FinalEvent
257 DestroyStatement
= "\n"
258 DestroyStatement
+= " Status = gBS->CloseEvent (mExitBootServicesEvent);\n"
259 DestroyStatement
+= " ASSERT_EFI_ERROR (Status);\n"
260 return (CreateStatement
, "", GlobalDefinition
, GlobalDeclaration
)
262 def AddVirtualAddressEventStatement(EventList
):
264 if len(EventList
) > 1:
265 print "Current prototype does not support multi virtual address change event"
267 FinalEvent
= EventList
[0]
269 CreateStatement
= "\n"
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"
280 GlobalDefinition
= "\n"
281 GlobalDefinition
+= "STATIC EFI_EVENT mVirtualAddressChangedEvent = NULL;\n"
283 GlobalDeclaration
= EventDeclarationTemplate
% FinalEvent
285 DestroyStatement
= "\n"
286 DestroyStatement
+= " Status = gBS->CloseEvent (mVirtualAddressChangedEvent);\n"
287 DestroyStatement
+= " ASSERT_EFI_ERROR (Status);\n"
289 return (CreateStatement
, "", GlobalDefinition
, GlobalDeclaration
)
292 EntryPointDeclarationTemplate
= """
294 // Declaration for original Entry Point.
299 IN EFI_HANDLE ImageHandle,
300 IN EFI_SYSTEM_TABLE *SystemTable
304 EntryPointHeader
= r
"""
306 The user Entry Point for module %s. The user code starts with this function.
308 @param[in] ImageHandle The firmware allocated handle for the EFI image.
309 @param[in] SystemTable A pointer to the EFI System Table.
311 @retval EFI_SUCCESS The entry point is executed successfully.
312 @retval other Some error occurs when executing this entry point.
316 def AddNewEntryPointContentsStatement (moduleName
, EntryPoint
, InstallStatement
= ""):
317 if EntryPoint
!= "Initialize%s" % moduleName
:
318 NewEntryPoint
= "Initialize%s" % moduleName
320 NewEntryPoint
= "NewInitialize%s" % moduleName
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
= ""
335 EntryPointContents
+= " //\n // Call the original Entry Point\n //\n"
336 EntryPointContents
+= " Status = %s (ImageHandle, SystemTable);\n\n" % EntryPoint
337 GlobalDeclaration
+= EntryPointDeclarationTemplate
% EntryPoint
339 EntryPointContents
+= " return Status;\n"
340 EntryPointContents
+= "}\n"
342 return (NewEntryPoint
, EntryPointContents
, GlobalDeclaration
)
344 reFileHeader
= re
.compile(r
"^\s*/\*.*?\*/\s*", re
.DOTALL
)
345 reNext
= re
.compile(r
"#ifndef\s*(\w+)\s*#define\s*\1\s*")
347 def AddCommonInclusionStatement(fileContents
, includeStatement
):
348 if includeStatement
in fileContents
:
352 matchFileHeader
= reFileHeader
.search(fileContents
)
354 insertPos
= matchFileHeader
.end()
356 matchFileHeader
= reNext
.search(fileContents
, insertPos
)
358 insertPos
= matchFileHeader
.end()
360 includeStatement
= "\n%s\n\n" % includeStatement
361 fileContents
= fileContents
[0:insertPos
] + includeStatement
+ fileContents
[insertPos
:]
364 # This acts like the main() function for the script, unless it is 'import'ed into another
366 if __name__
== '__main__':