summaryrefslogtreecommitdiffstats
path: root/BaseTools/Source/Python/MigrationMsa2Inf/AutoGenExterns.py
diff options
context:
space:
mode:
Diffstat (limited to 'BaseTools/Source/Python/MigrationMsa2Inf/AutoGenExterns.py')
-rw-r--r--BaseTools/Source/Python/MigrationMsa2Inf/AutoGenExterns.py369
1 files changed, 369 insertions, 0 deletions
diff --git a/BaseTools/Source/Python/MigrationMsa2Inf/AutoGenExterns.py b/BaseTools/Source/Python/MigrationMsa2Inf/AutoGenExterns.py
new file mode 100644
index 0000000000..37fff885a8
--- /dev/null
+++ b/BaseTools/Source/Python/MigrationMsa2Inf/AutoGenExterns.py
@@ -0,0 +1,369 @@
+#!/usr/bin/env python
+#
+#
+# Copyright (c) 2007, Intel Corporation. All rights reserved.<BR>
+# This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+
+#
+# Import Modules
+#
+import re, os, glob
+from Common.XmlRoutines import *
+
+#"ModuleType"=>(PackageGuid, headerFileName) List
+HeaderFiles = {}
+GuidList = []
+GuidMap = {}
+HeaderFileContents = {}
+gTest = {}
+GuidMacro2CName = {}
+GuidAliasList = []
+
+def collectIncludeFolder(pkgDirName, guidType, pkgName):
+ includeFolder = os.path.join(pkgDirName, "Include", guidType)
+ if os.path.exists(includeFolder) and os.path.isdir(includeFolder):
+ for headerFileName in os.listdir(includeFolder):
+ if headerFileName[-2:] == ".h":
+ headerFile = open(os.path.join(includeFolder, headerFileName))
+ HeaderFileContents[(guidType, headerFileName, pkgName)] = headerFile.read()
+ headerFile.close()
+
+GuidMacroReg = re.compile(r"\b(?!EFI_GUID\b)[A-Z0-9_]+_GUID\b")
+GuidCNameReg = re.compile(r"\bg\w+Guid\b")
+GuidAliasReg = re.compile(r"#define\s+([A-Z0-9_]+_GUID)\s+([A-Z0-9_]+_GUID)\b")
+
+def collectPackageInfo(spdFileName):
+ pkgDirName = os.path.dirname(spdFileName)
+
+ spd = XmlParseFile(spdFileName)
+
+ pkgName = XmlElement(spd, "/PackageSurfaceArea/SpdHeader/PackageName")
+ pkgGuid = XmlElement(spd, "/PackageSurfaceArea/SpdHeader/GuidValue")
+
+
+ for IncludePkgHeader in XmlList(spd, "/PackageSurfaceArea/PackageHeaders/IncludePkgHeader"):
+ moduleType = XmlAttribute(IncludePkgHeader, "ModuleType")
+ headerFilePath = XmlElementData(IncludePkgHeader)
+ headerFilePath = re.sub("Include/", "", headerFilePath, 1)
+
+ headerTuple = HeaderFiles.get(moduleType, [])
+ headerTuple.append((pkgGuid, headerFilePath))
+ HeaderFiles[moduleType] = headerTuple
+
+ guidTypes = ["Guid", "Protocol", "Ppi"]
+
+ for guidType in guidTypes:
+ for guidEntry in XmlList(spd, "/PackageSurfaceArea/" + guidType + "Declarations/Entry"):
+ guidCName = XmlElement(guidEntry, "Entry/C_Name")
+ GuidList.append(guidCName)
+
+ collectIncludeFolder(pkgDirName, guidType, pkgName)
+
+ for DecFile in glob.glob(os.path.join(pkgDirName, "*.dec")):
+ fileContents = open(DecFile).read()
+ for GuidCNameMatch in GuidCNameReg.finditer(fileContents):
+ GuidCName = GuidCNameMatch.group(0)
+ if GuidCName not in GuidList:
+ GuidList.append(GuidCName)
+
+def AddGuidMacro2GuidCName(GuidMacros, GuidCNames):
+ for GuidMacro in GuidMacros:
+ GuessGuidCName = "g" + GuidMacro.lower().title().replace("_", "")
+ if GuessGuidCName in GuidCNames:
+ GuidMacro2CName[GuidMacro] = GuessGuidCName
+ elif len(GuidCNames) == 1:
+ GuidMacro2CName[GuidMacro] = GuidCNames[0]
+ else:
+ for GuidCName in GuidCNames:
+ if GuidCName.lower() == GuessGuidCName.lower():
+ GuidMacro2CName[GuidMacro] = GuidCName
+ break
+ else:
+ pass
+ #print "No matching GuidMacro %s" % GuidMacro
+
+
+def TranslateGuid(GuidMacroMatch):
+ GuidMacro = GuidMacroMatch.group(0)
+ return GuidMacro2CName.get(GuidMacro, GuidMacro)
+
+DepexReg = re.compile(r"DEPENDENCY_START(.*?)DEPENDENCY_END", re.DOTALL)
+
+def TranslateDpxSection(fileContents):
+ DepexMatch = DepexReg.search(fileContents)
+ if not DepexMatch:
+ return "", []
+
+ fileContents = DepexMatch.group(1)
+ fileContents = re.sub(r"\s+", " ", fileContents).strip()
+ fileContents = GuidMacroReg.sub(TranslateGuid, fileContents)
+ return fileContents, GuidMacroReg.findall(fileContents)
+
+def InitializeAutoGen(workspace, db):
+
+
+ for spdFile in XmlList(db, "/FrameworkDatabase/PackageList/Filename"):
+ spdFileName = XmlElementData(spdFile)
+ collectPackageInfo(os.path.join(workspace, spdFileName))
+
+
+ BlockCommentReg = re.compile(r"/\*.*?\*/", re.DOTALL)
+ LineCommentReg = re.compile(r"//.*")
+ GuidReg = re.compile(r"\b(" + '|'.join(GuidList) + r")\b")
+
+ for headerFile in HeaderFileContents:
+ Contents = HeaderFileContents[headerFile]
+ Contents = BlockCommentReg.sub("", Contents)
+ Contents = LineCommentReg.sub("", Contents)
+
+ FoundGuids = GuidReg.findall(Contents)
+ for FoundGuid in FoundGuids:
+ GuidMap[FoundGuid] = "%s/%s" % (headerFile[0], headerFile[1])
+ #print "%-40s %s/%s" % (FoundGuid, headerFile[0], headerFile[1])
+
+ GuidMacros = GuidMacroReg.findall(Contents)
+ GuidCNames = GuidCNameReg.findall(Contents)
+
+ for GuidAliasMatch in GuidAliasReg.finditer(Contents):
+ Name1, Name2 = GuidAliasMatch.group(1), GuidAliasMatch.group(2)
+ GuidAliasList.append((Name1, Name2))
+
+ AddGuidMacro2GuidCName(GuidMacros, GuidCNames)
+
+def AddSystemIncludeStatement(moduleType, PackageList):
+ IncludeStatement = "\n"
+
+ headerList = HeaderFiles.get(moduleType, [])
+
+ for pkgGuid in PackageList:
+
+ for pkgTuple in headerList:
+ if pkgTuple[0] == pkgGuid:
+ IncludeStatement += "#include <%s>\n" % pkgTuple[1]
+
+ return IncludeStatement
+
+
+def AddLibraryClassStatement(LibraryClassList):
+ IncludeStatement = "\n"
+ for LibraryClass in LibraryClassList:
+ IncludeStatement += "#include <Library/%s.h>\n" % LibraryClass
+
+ return IncludeStatement
+
+def AddGuidStatement(GuidList):
+ IncludeStatement = "\n"
+ GuidIncludeSet = {}
+ for Guid in GuidList:
+ if Guid in GuidMap:
+ GuidIncludeSet[GuidMap[Guid]] = 1
+ else:
+ print "GUID CName: %s cannot be found in any public header file" % Guid
+
+ for GuidInclude in GuidIncludeSet:
+ IncludeStatement += "#include <%s>\n" % GuidInclude
+
+ return IncludeStatement
+
+DriverBindingMap = {
+ "gEfiDriverBindingProtocolGuid" : "EFI_DRIVER_BINDING_PROTOCOL",
+ "gEfiComponentNameProtocolGuid" : "EFI_COMPONENT_NAME_PROTOCOL",
+ "gEfiDriverConfigurationProtocolGuid" : "EFI_DRIVER_CONFIGURATION_PROTOCOL",
+ "gEfiDriverDiagnosticProtocolGuid" : "EFI_DRIVER_CONFIGURATION_PROTOCOL"
+ }
+
+def AddDriverBindingProtocolStatement(AutoGenDriverModel):
+ InstallStatement = "\n"
+ DBindingHandle = "ImageHandle"
+ GlobalDeclaration = "\n"
+
+
+ for DriverModelItem in AutoGenDriverModel:
+
+ if DriverModelItem[1] == "NULL" and DriverModelItem[2] == "NULL" and DriverModelItem[3] == "NULL":
+ InstallStatement += " Status = EfiLibInstallDriverBinding (\n"
+ InstallStatement += " ImageHandle,\n"
+ InstallStatement += " SystemTable,\n"
+ InstallStatement += " %s,\n" % DriverModelItem[0]
+ InstallStatement += " %s\n" % DBindingHandle
+ InstallStatement += " );\n"
+ else:
+ InstallStatement += " Status = EfiLibInstallAllDriverProtocols (\n"
+ InstallStatement += " ImageHandle,\n"
+ InstallStatement += " SystemTable,\n"
+ InstallStatement += " %s,\n" % DriverModelItem[0]
+ InstallStatement += " %s,\n" % DBindingHandle
+ InstallStatement += " %s,\n" % DriverModelItem[1]
+ InstallStatement += " %s,\n" % DriverModelItem[2]
+ InstallStatement += " %s\n" % DriverModelItem[3]
+ InstallStatement += " );\n"
+
+ InstallStatement += " ASSERT_EFI_ERROR (Status);\n\n"
+
+ GlobalDeclaration += "extern EFI_DRIVER_BINDING_PROTOCOL %s;\n" % DriverModelItem[0][1:]
+ if (DriverModelItem[1] != "NULL"):
+ GlobalDeclaration += "extern EFI_COMPONENT_NAME_PROTOCOL %s;\n" % DriverModelItem[1][1:]
+ if (DriverModelItem[2] != "NULL"):
+ GlobalDeclaration += "extern EFI_DRIVER_CONFIGURATION_PROTOCOL %s;\n" % DriverModelItem[2][1:]
+ if (DriverModelItem[3] != "NULL"):
+ GlobalDeclaration += "extern EFI_DRIVER_CONFIGURATION_PROTOCOL %s;\n" % DriverModelItem[3][1:]
+
+ DBindingHandle = "NULL"
+
+ return (InstallStatement, "", "", GlobalDeclaration)
+
+EventDeclarationTemplate = """
+//
+// Declaration for callback Event.
+//
+VOID
+EFIAPI
+%s (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ );
+"""
+
+def AddBootServiceEventStatement(EventList):
+ FinalEvent = ""
+ if len(EventList) > 1:
+
+ print "Current prototype does not support multi boot service event"
+ else:
+ FinalEvent = EventList[0]
+
+ CreateStatement = "\n"
+ CreateStatement += " Status = gBS->CreateEvent (\n"
+ CreateStatement += " EVT_SIGNAL_EXIT_BOOT_SERVICES,\n"
+ CreateStatement += " EFI_TPL_NOTIFY,\n"
+ CreateStatement += " " + FinalEvent + ",\n"
+ CreateStatement += " NULL,\n"
+ CreateStatement += " &mExitBootServicesEvent\n"
+ CreateStatement += " );\n"
+ CreateStatement += " ASSERT_EFI_ERROR (Status);\n"
+
+ GlobalDefinition = "\n"
+ GlobalDefinition += "STATIC EFI_EVENT mExitBootServicesEvent = NULL;\n"
+
+ GlobalDeclaration = EventDeclarationTemplate % FinalEvent
+
+ DestroyStatement = "\n"
+ DestroyStatement += " Status = gBS->CloseEvent (mExitBootServicesEvent);\n"
+ DestroyStatement += " ASSERT_EFI_ERROR (Status);\n"
+ return (CreateStatement, "", GlobalDefinition, GlobalDeclaration)
+
+def AddVirtualAddressEventStatement(EventList):
+ FinalEvent = ""
+ if len(EventList) > 1:
+ print "Current prototype does not support multi virtual address change event"
+ else:
+ FinalEvent = EventList[0]
+
+ CreateStatement = "\n"
+
+ CreateStatement += " Status = gBS->CreateEvent (\n"
+ CreateStatement += " EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE,\n"
+ CreateStatement += " TPL_NOTIFY,\n"
+ CreateStatement += " " + FinalEvent + ",\n"
+ CreateStatement += " NULL,\n"
+ CreateStatement += " &mVirtualAddressChangedEvent\n"
+ CreateStatement += " );\n"
+ CreateStatement += " ASSERT_EFI_ERROR (Status);\n"
+
+ GlobalDefinition = "\n"
+ GlobalDefinition += "STATIC EFI_EVENT mVirtualAddressChangedEvent = NULL;\n"
+
+ GlobalDeclaration = EventDeclarationTemplate % FinalEvent
+
+ DestroyStatement = "\n"
+ DestroyStatement += " Status = gBS->CloseEvent (mVirtualAddressChangedEvent);\n"
+ DestroyStatement += " ASSERT_EFI_ERROR (Status);\n"
+
+ return (CreateStatement, "", GlobalDefinition, GlobalDeclaration)
+
+
+EntryPointDeclarationTemplate = """
+//
+// Declaration for original Entry Point.
+//
+EFI_STATUS
+EFIAPI
+%s (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ );
+"""
+
+EntryPointHeader = r"""
+/**
+ The user Entry Point for module %s. The user code starts with this function.
+
+ @param[in] ImageHandle The firmware allocated handle for the EFI image.
+ @param[in] SystemTable A pointer to the EFI System Table.
+
+ @retval EFI_SUCCESS The entry point is executed successfully.
+ @retval other Some error occurs when executing this entry point.
+
+**/
+"""
+def AddNewEntryPointContentsStatement (moduleName, EntryPoint, InstallStatement = ""):
+ if EntryPoint != "Initialize%s" % moduleName:
+ NewEntryPoint = "Initialize%s" % moduleName
+ else:
+ NewEntryPoint = "NewInitialize%s" % moduleName
+
+ EntryPointContents = EntryPointHeader % moduleName
+ EntryPointContents += "EFI_STATUS\n"
+ EntryPointContents += "EFIAPI\n"
+ EntryPointContents += NewEntryPoint + "(\n"
+ EntryPointContents += " IN EFI_HANDLE ImageHandle,\n"
+ EntryPointContents += " IN EFI_SYSTEM_TABLE *SystemTable\n"
+ EntryPointContents += " )\n"
+ EntryPointContents += "{\n"
+ EntryPointContents += " EFI_STATUS Status;\n"
+ EntryPointContents += InstallStatement + "\n"
+ GlobalDeclaration = ""
+
+ if EntryPoint != "":
+ EntryPointContents += " //\n // Call the original Entry Point\n //\n"
+ EntryPointContents += " Status = %s (ImageHandle, SystemTable);\n\n" % EntryPoint
+ GlobalDeclaration += EntryPointDeclarationTemplate % EntryPoint
+
+ EntryPointContents += " return Status;\n"
+ EntryPointContents += "}\n"
+
+ return (NewEntryPoint, EntryPointContents, GlobalDeclaration)
+
+reFileHeader = re.compile(r"^\s*/\*.*?\*/\s*", re.DOTALL)
+reNext = re.compile(r"#ifndef\s*(\w+)\s*#define\s*\1\s*")
+
+def AddCommonInclusionStatement(fileContents, includeStatement):
+ if includeStatement in fileContents:
+ return fileContents
+
+ insertPos = 0
+ matchFileHeader = reFileHeader.search(fileContents)
+ if matchFileHeader:
+ insertPos = matchFileHeader.end()
+
+ matchFileHeader = reNext.search(fileContents, insertPos)
+ if matchFileHeader:
+ insertPos = matchFileHeader.end()
+
+ includeStatement = "\n%s\n\n" % includeStatement
+ fileContents = fileContents[0:insertPos] + includeStatement + fileContents[insertPos:]
+ return fileContents
+
+# This acts like the main() function for the script, unless it is 'import'ed into another
+# script.
+if __name__ == '__main__':
+
+ pass
+