Last active
April 1, 2018 19:17
-
-
Save warexify/6dde7d24d12948101d1a62b896fc7ce5 to your computer and use it in GitHub Desktop.
Patch for edk2 sources to build Clover
This file has been truncated, but you can view the full file.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/MdeModulePkg/MdeModulePkg.dec b/MdeModulePkg/MdeModulePkgSample.dec | |
similarity index 74% | |
copy from MdeModulePkg/MdeModulePkg.dec | |
copy to MdeModulePkg/MdeModulePkgSample.dec | |
index cc397185f7b9..c7dc172d305d 100644 | |
--- a/MdeModulePkg/MdeModulePkg.dec | |
+++ b/MdeModulePkg/MdeModulePkgSample.dec | |
@@ -54,9 +53,6 @@ [LibraryClasses] | |
## @libraryclass Defines a set of methods to reset whole system. | |
ResetSystemLib|Include/Library/ResetSystemLib.h | |
- ## @libraryclass Defines a set of helper functions for resetting the system. | |
- ResetUtilityLib|Include/Library/ResetUtilityLib.h | |
- | |
## @libraryclass Defines a set of methods related do S3 mode. | |
# This library class is no longer used and modules using this library should | |
# directly locate EFI_PEI_S3_RESUME_PPI defined in PI 1.2 specification. | |
@@ -142,6 +138,10 @@ [LibraryClasses] | |
# | |
FileExplorerLib|Include/Library/FileExplorerLib.h | |
+ ## @libraryclass Provides image decoding service. | |
+ # | |
+ ImageDecoderLib|Include/Library/ImageDecoderLib.h | |
+ | |
## @libraryclass Provides interfaces about logo display. | |
# | |
BootLogoLib|Include/Library/BootLogoLib.h | |
@@ -154,27 +154,6 @@ [LibraryClasses] | |
# | |
PciHostBridgeLib|Include/Library/PciHostBridgeLib.h | |
- ## @libraryclass Provides services to record memory profile of multilevel caller. | |
- # | |
- MemoryProfileLib|Include/Library/MemoryProfileLib.h | |
- | |
- ## @libraryclass Provides an interface for performing UEFI Graphics Output Protocol Video blt operations. | |
- ## | |
- FrameBufferBltLib|Include/Library/FrameBufferBltLib.h | |
- | |
- ## @libraryclass Provides services to authenticate a UEFI defined FMP Capsule. | |
- # | |
- FmpAuthenticationLib|Include/Library/FmpAuthenticationLib.h | |
- | |
- ## @libraryclass Provides a service to register non-discoverable device | |
- ## | |
- NonDiscoverableDeviceRegistrationLib|Include/Library/NonDiscoverableDeviceRegistrationLib.h | |
- | |
- ## @libraryclass Provides services to convert a BMP graphics image to a GOP BLT buffer | |
- # and to convert a GOP BLT buffer to a BMP graphics image. | |
- # | |
- BmpSupportLib|Include/Library/BmpSupportLib.h | |
- | |
[Guids] | |
## MdeModule package token space guid | |
# Include/Guid/MdeModulePkgTokenSpace.h | |
@@ -192,10 +171,6 @@ [Guids] | |
# Include/Guid/MdeModuleHii.h | |
gEfiIfrTianoGuid = { 0xf0b1735, 0x87a0, 0x4193, {0xb2, 0x66, 0x53, 0x8c, 0x38, 0xaf, 0x48, 0xce }} | |
- ## Guid for EDKII implementation extension, used to indaicate there are bit fields in the varstore. | |
- # Include/Guid/MdeModuleHii.h | |
- gEdkiiIfrBitVarstoreGuid = {0x82DDD68B, 0x9163, 0x4187, {0x9B, 0x27, 0x20, 0xA8, 0xFD, 0x60,0xA7, 0x1D}} | |
- | |
## Guid for Framework vfr GUIDed opcodes. | |
# Include/Guid/MdeModuleHii.h | |
gEfiIfrFrameworkGuid = { 0x31ca5d1a, 0xd511, 0x4931, { 0xb7, 0x82, 0xae, 0x6b, 0x2b, 0x17, 0x8c, 0xd7 }} | |
@@ -258,6 +233,9 @@ [Guids] | |
# Include/Guid/Crc32GuidedSectionExtraction.h | |
gEfiCrc32GuidedSectionExtractionGuid = { 0xFC1BCDB0, 0x7D31, 0x49aa, {0x93, 0x6A, 0xA4, 0x60, 0x0D, 0x9D, 0xD0, 0x83 } } | |
+ ## Include/Guid/NicIp4ConfigNvData.h | |
+ gEfiNicIp4ConfigVariableGuid = {0xd8944553, 0xc4dd, 0x41f4, { 0x9b, 0x30, 0xe1, 0x39, 0x7c, 0xfb, 0x26, 0x7b }} | |
+ | |
## Include/Guid/StatusCodeCallbackGuid.h | |
gStatusCodeCallbackGuid = {0xe701458c, 0x4900, 0x4ca5, {0xb7, 0x72, 0x3d, 0x37, 0x94, 0x9f, 0x79, 0x27}} | |
@@ -321,6 +299,9 @@ [Guids] | |
## Include/Guid/PlatDriOverrideHii.h | |
gPlatformOverridesManagerGuid = { 0x8614567d, 0x35be, 0x4415, { 0x8d, 0x88, 0xbd, 0x7d, 0xc, 0x9c, 0x70, 0xc0 }} | |
+ ## Include/Guid/Ip4ConfigHii.h | |
+ gNicIp4ConfigNvDataGuid = { 0x9d5b53f, 0xf4b0, 0x4f59, { 0xa0, 0xb1, 0x7b, 0x57, 0xd3, 0x5c, 0xe, 0x5 }} | |
+ | |
## Include/Guid/Ip4Config2Hii.h | |
gIp4Config2NvDataGuid = { 0x9b942747, 0x154e, 0x4d29, { 0xa4, 0x36, 0xbf, 0x71, 0x0, 0xc8, 0xb5, 0x3b }} | |
@@ -353,14 +334,10 @@ [Guids] | |
## Include/Guid/MemoryProfile.h | |
gEdkiiMemoryProfileGuid = { 0x821c9a09, 0x541a, 0x40f6, { 0x9f, 0x43, 0xa, 0xd1, 0x93, 0xa1, 0x2c, 0xfe }} | |
- gEdkiiSmmMemoryProfileGuid = { 0xe22bbcca, 0x516a, 0x46a8, { 0x80, 0xe2, 0x67, 0x45, 0xe8, 0x36, 0x93, 0xbd }} | |
## Include/Protocol/VarErrorFlag.h | |
gEdkiiVarErrorFlagGuid = { 0x4b37fe8, 0xf6ae, 0x480b, { 0xbd, 0xd5, 0x37, 0xd9, 0x8c, 0x5e, 0x89, 0xaa } } | |
- ## GUID indicates the BROTLI custom compress/decompress algorithm. | |
- gBrotliCustomDecompressGuid = { 0x3D532050, 0x5CDA, 0x4FD0, { 0x87, 0x9E, 0x0F, 0x7F, 0x63, 0x0D, 0x5A, 0xFB }} | |
- | |
## GUID indicates the LZMA custom compress/decompress algorithm. | |
# Include/Guid/LzmaDecompress.h | |
gLzmaCustomDecompressGuid = { 0xEE4E5898, 0x3914, 0x4259, { 0x9D, 0x6E, 0xDC, 0x7B, 0xD7, 0x94, 0x03, 0xCF }} | |
@@ -377,37 +354,6 @@ [Guids] | |
## Include/Guid/RamDiskHii.h | |
gRamDiskFormSetGuid = { 0x2a46715f, 0x3581, 0x4a55, { 0x8e, 0x73, 0x2b, 0x76, 0x9a, 0xaa, 0x30, 0xc5 }} | |
- ## Include/Guid/PiSmmCommunicationRegionTable.h | |
- gEdkiiPiSmmCommunicationRegionTableGuid = { 0x4e28ca50, 0xd582, 0x44ac, {0xa1, 0x1f, 0xe3, 0xd5, 0x65, 0x26, 0xdb, 0x34}} | |
- | |
- ## Include/Guid/PiSmmMemoryAttributesTable.h | |
- gEdkiiPiSmmMemoryAttributesTableGuid = { 0x6b9fd3f7, 0x16df, 0x45e8, {0xbd, 0x39, 0xb9, 0x4a, 0x66, 0x54, 0x1a, 0x5d}} | |
- | |
- ## Include/Guid/SmiHandlerProfile.h | |
- gSmiHandlerProfileGuid = {0x49174342, 0x7108, 0x409b, {0x8b, 0xbe, 0x65, 0xfd, 0xa8, 0x53, 0x89, 0xf5}} | |
- | |
- ## Include/Guid/NonDiscoverableDevice.h | |
- gEdkiiNonDiscoverableAhciDeviceGuid = { 0xC7D35798, 0xE4D2, 0x4A93, {0xB1, 0x45, 0x54, 0x88, 0x9F, 0x02, 0x58, 0x4B } } | |
- gEdkiiNonDiscoverableAmbaDeviceGuid = { 0x94440339, 0xCC93, 0x4506, {0xB4, 0xC6, 0xEE, 0x8D, 0x0F, 0x4C, 0xA1, 0x91 } } | |
- gEdkiiNonDiscoverableEhciDeviceGuid = { 0xEAEE5615, 0x0CFD, 0x45FC, {0x87, 0x69, 0xA0, 0xD8, 0x56, 0x95, 0xAF, 0x85 } } | |
- gEdkiiNonDiscoverableNvmeDeviceGuid = { 0xC5F25542, 0x2A79, 0x4A26, {0x81, 0xBB, 0x4E, 0xA6, 0x32, 0x33, 0xB3, 0x09 } } | |
- gEdkiiNonDiscoverableOhciDeviceGuid = { 0xB20005B0, 0xBB2D, 0x496F, {0x86, 0x9C, 0x23, 0x0B, 0x44, 0x79, 0xE7, 0xD1 } } | |
- gEdkiiNonDiscoverableSdhciDeviceGuid = { 0x1DD1D619, 0xF9B8, 0x463E, {0x86, 0x81, 0xD1, 0xDC, 0x7C, 0x07, 0xB7, 0x2C } } | |
- gEdkiiNonDiscoverableUfsDeviceGuid = { 0x2EA77912, 0x80A8, 0x4947, {0xBE, 0x69, 0xCD, 0xD0, 0x0A, 0xFB, 0xE5, 0x56 } } | |
- gEdkiiNonDiscoverableUhciDeviceGuid = { 0xA8CDA0A2, 0x4F37, 0x4A1B, {0x8E, 0x10, 0x8E, 0xF3, 0xCC, 0x3B, 0xF3, 0xA8 } } | |
- gEdkiiNonDiscoverableXhciDeviceGuid = { 0xB1BE0BC5, 0x6C28, 0x442D, {0xAA, 0x37, 0x15, 0x1B, 0x42, 0x57, 0xBD, 0x78 } } | |
- | |
- ## Include/Guid/PlatformHasAcpi.h | |
- gEdkiiPlatformHasAcpiGuid = { 0xf0966b41, 0xc23f, 0x41b9, { 0x96, 0x04, 0x0f, 0xf7, 0xe1, 0x11, 0x96, 0x5a } } | |
- | |
- ## Include/Guid/ExtendedFirmwarePerformance.h | |
- gEdkiiFpdtExtendedFirmwarePerformanceGuid = { 0x3b387bfd, 0x7abc, 0x4cf2, { 0xa0, 0xca, 0xb6, 0xa1, 0x6c, 0x1b, 0x1b, 0x25 } } | |
- | |
- ## Include/Guid/EndofS3Resume.h | |
- gEdkiiEndOfS3ResumeGuid = { 0x96f5296d, 0x05f7, 0x4f3c, {0x84, 0x67, 0xe4, 0x56, 0x89, 0x0e, 0x0c, 0xb5 } } | |
- | |
- ## Include/Guid/S3SmmInitDone.h | |
- gEdkiiS3SmmInitDoneGuid = { 0x8f9d4825, 0x797d, 0x48fc, { 0x84, 0x71, 0x84, 0x50, 0x25, 0x79, 0x2e, 0xf6 } } | |
[Ppis] | |
## Include/Ppi/AtaController.h | |
@@ -425,6 +371,9 @@ [Ppis] | |
## Include/Ppi/UsbIo.h | |
gPeiUsbIoPpiGuid = { 0x7C29785C, 0x66B9, 0x49FC, { 0xB7, 0x97, 0x1C, 0xA5, 0x55, 0x0E, 0xF2, 0x83 }} | |
+ ## Include/Ppi/Capsule.h | |
+ gPeiCapsulePpiGuid = { 0x3acf33ee, 0xd892, 0x40f4, { 0xa2, 0xfc, 0x38, 0x54, 0xd2, 0xe1, 0x32, 0x3d }} | |
+ | |
## Include/Ppi/SecPerformance.h | |
gPeiSecPerformancePpiGuid = { 0x0ecc666b, 0x4662, 0x47f9, { 0x9d, 0xd5, 0xd0, 0x96, 0xff, 0x7d, 0xa4, 0x9e }} | |
@@ -452,18 +401,6 @@ [Ppis] | |
## Include/Ppi/SdMmcHostController.h | |
gEdkiiPeiSdMmcHostControllerPpiGuid = { 0xb30dfeed, 0x947f, 0x4396, { 0xb1, 0x5a, 0xdf, 0xbd, 0xb9, 0x16, 0xdc, 0x24 }} | |
- ## Include/Ppi/IoMmu.h | |
- gEdkiiIoMmuPpiGuid = { 0x70b0af26, 0xf847, 0x4bb6, { 0xaa, 0xb9, 0xcd, 0xe8, 0x4f, 0xc6, 0x14, 0x31 } } | |
- | |
- ## Include/Ppi/PlatformSpecificResetFilter.h | |
- gEdkiiPlatformSpecificResetFilterPpiGuid = { 0x8c9f4de3, 0x7b90, 0x47ef, { 0x93, 0x8, 0x28, 0x7c, 0xec, 0xd6, 0x6d, 0xe8 } } | |
- | |
- ## Include/Ppi/PlatformSpecificResetNotification.h | |
- gEdkiiPlatformSpecificResetNotificationPpiGuid = { 0xe09f355d, 0xdae8, 0x4910, { 0xb1, 0x4a, 0x92, 0x78, 0xf, 0xdc, 0xf7, 0xcb } } | |
- | |
- ## Include/Ppi/PlatformSpecificResetHandler.h | |
- gEdkiiPlatformSpecificResetHandlerPpiGuid = { 0x75cf14ae, 0x3441, 0x49dc, { 0xaa, 0x10, 0xbb, 0x35, 0xa7, 0xba, 0x8b, 0xab } } | |
- | |
[Protocols] | |
## Load File protocol provides capability to load and unload EFI image into memory and execute it. | |
# Include/Protocol/LoadPe32Image.h | |
@@ -471,19 +408,14 @@ [Protocols] | |
# If developer need implement such functionality, they should use BasePeCoffLib. | |
gEfiLoadPeImageProtocolGuid = { 0x5CB5C776, 0x60D5, 0x45EE, { 0x88, 0x3C, 0x45, 0x27, 0x08, 0xCD, 0x74, 0x3F }} | |
- ## Print protocols define basic print functions to print the format unicode and ascii string. | |
+ ## Print protocol defines basic print functions to print the format unicode and ascii string. | |
# Include/Protocol/Print2.h | |
gEfiPrint2ProtocolGuid = { 0xf05976ef, 0x83f1, 0x4f3d, { 0x86, 0x19, 0xf7, 0x59, 0x5d, 0x41, 0xe5, 0x38 } } | |
- gEfiPrint2SProtocolGuid = { 0xcc252d2, 0xc106, 0x4661, { 0xb5, 0xbd, 0x31, 0x47, 0xa4, 0xf8, 0x1f, 0x92 } } | |
## This protocol defines the generic memory test interfaces in Dxe phase. | |
# Include/Protocol/GenericMemoryTest.h | |
gEfiGenericMemTestProtocolGuid = { 0x309DE7F1, 0x7F5E, 0x4ACE, { 0xB4, 0x9C, 0x53, 0x1B, 0xE5, 0xAA, 0x95, 0xEF }} | |
- ## This protocol defines the Debugger Configuration interface. | |
- # Include/Protocol/DebuggerConfiguration.h | |
- gEfiDebuggerConfigurationProtocolGuid = { 0x577d959c, 0xe967, 0x4546, { 0x86, 0x20, 0xc7, 0x78, 0xfa, 0xe5, 0xda, 0x05 }} | |
- | |
## Include/Protocol/Dpc.h | |
gEfiDpcProtocolGuid = {0x480f8ae9, 0xc46, 0x4aa9, { 0xbc, 0x89, 0xdb, 0x9f, 0xba, 0x61, 0x98, 0x6 }} | |
@@ -530,7 +462,6 @@ [Protocols] | |
## Include/Protocol/FormBrowserEx.h | |
gEfiFormBrowserExProtocolGuid = { 0x1f73b18d, 0x4630, 0x43c1, { 0xa1, 0xde, 0x6f, 0x80, 0x85, 0x5d, 0x7d, 0xa4 } } | |
- gEdkiiFormBrowserExProtocolGuid = { 0x1f73b18d, 0x4630, 0x43c1, { 0xa1, 0xde, 0x6f, 0x80, 0x85, 0x5d, 0x7d, 0xa4 } } | |
## Include/Protocol/EbcVmTest.h | |
gEfiEbcVmTestProtocolGuid = { 0xAAEACCFD, 0xF27B, 0x4C17, { 0xB6, 0x10, 0x75, 0xCA, 0x1F, 0x2D, 0xFB, 0x52 } } | |
@@ -541,9 +472,6 @@ [Protocols] | |
## Include/Protocol/BootLogo.h | |
gEfiBootLogoProtocolGuid = { 0xcdea2bd3, 0xfc25, 0x4c1c, { 0xb9, 0x7c, 0xb3, 0x11, 0x86, 0x6, 0x49, 0x90 } } | |
- # Include/Protocol/BootLogo2.h | |
- gEdkiiBootLogo2ProtocolGuid = { 0x4b5dc1df, 0x1eaa, 0x48b2, { 0xa7, 0xe9, 0xea, 0xc4, 0x89, 0xa0, 0xb, 0x5c } } | |
- | |
## Include/Protocol/DisplayProtocol.h | |
gEdkiiFormDisplayEngineProtocolGuid = { 0x9bbe29e9, 0xfda1, 0x41ec, { 0xad, 0x52, 0x45, 0x22, 0x13, 0x74, 0x2d, 0x2e } } | |
@@ -566,7 +494,7 @@ [Protocols] | |
gEdkiiSmmReadyToBootProtocolGuid = { 0x6e057ecf, 0xfa99, 0x4f39, { 0x95, 0xbc, 0x59, 0xf9, 0x92, 0x1d, 0x17, 0xe4 } } | |
## Include/Protocol/PlatformLogo.h | |
- gEdkiiPlatformLogoProtocolGuid = { 0x53cd299f, 0x2bc1, 0x40c0, { 0x8c, 0x07, 0x23, 0xf6, 0x4f, 0xdb, 0x30, 0xe0 } } | |
+ gEdkiiPlatformLogoProtocolGuid = { 0x9b517978, 0xeba1, 0x44e7, { 0xba, 0x65, 0x7c, 0x2c, 0xd0, 0x8b, 0xf8, 0xe9 } } | |
## Include/Protocol/FileExplorer.h | |
gEfiFileExplorerProtocolGuid = { 0x2C03C536, 0x4594, 0x4515, { 0x9E, 0x7A, 0xD3, 0xD2, 0x04, 0xFE, 0x13, 0x63 } } | |
@@ -575,26 +503,6 @@ [Protocols] | |
gIpmiProtocolGuid = { 0xdbc6381f, 0x5554, 0x4d14, { 0x8f, 0xfd, 0x76, 0xd7, 0x87, 0xb8, 0xac, 0xbf } } | |
gSmmIpmiProtocolGuid = { 0x5169af60, 0x8c5a, 0x4243, { 0xb3, 0xe9, 0x56, 0xc5, 0x6d, 0x18, 0xee, 0x26 } } | |
- ## PS/2 policy protocol abstracts the specific platform initialization and setting. | |
- # Include/Protocol/Ps2Policy.h | |
- gEfiPs2PolicyProtocolGuid = { 0x4DF19259, 0xDC71, 0x4D46, { 0xBE, 0xF1, 0x35, 0x7B, 0xB5, 0x78, 0xC4, 0x18 } } | |
- | |
- ## Include/Protocol/NonDiscoverableDevice.h | |
- gEdkiiNonDiscoverableDeviceProtocolGuid = { 0x0d51905b, 0xb77e, 0x452a, {0xa2, 0xc0, 0xec, 0xa0, 0xcc, 0x8d, 0x51, 0x4a } } | |
- | |
- ## Include/Protocol/IoMmu.h | |
- gEdkiiIoMmuProtocolGuid = { 0x4e939de9, 0xd948, 0x4b0f, { 0x88, 0xed, 0xe6, 0xe1, 0xce, 0x51, 0x7c, 0x1e } } | |
- | |
- ## Include/Protocol/SmmMemoryAttribute.h | |
- gEdkiiSmmMemoryAttributeProtocolGuid = { 0x69b792ea, 0x39ce, 0x402d, { 0xa2, 0xa6, 0xf7, 0x21, 0xde, 0x35, 0x1d, 0xfe } } | |
- | |
- ## Include/Protocol/SdMmcOverride.h | |
- gEdkiiSdMmcOverrideProtocolGuid = { 0xeaf9e3c1, 0xc9cd, 0x46db, { 0xa5, 0xe5, 0x5a, 0x12, 0x4c, 0x83, 0x23, 0x23 } } | |
- | |
- ## Include/Protocol/PlatformSpecificResetFilter.h | |
- gEdkiiPlatformSpecificResetFilterProtocolGuid = { 0x695d7835, 0x8d47, 0x4c11, { 0xab, 0x22, 0xfa, 0x8a, 0xcc, 0xe7, 0xae, 0x7a } } | |
- ## Include/Protocol/PlatformSpecificResetHandler.h | |
- gEdkiiPlatformSpecificResetHandlerProtocolGuid = { 0x2df6ba0b, 0x7092, 0x440d, { 0xbd, 0x4, 0xfb, 0x9, 0x1e, 0xc3, 0xf3, 0xc1 } } | |
# | |
# [Error.gEfiMdeModulePkgTokenSpaceGuid] | |
# 0x80000001 | Invalid value provided. | |
@@ -741,7 +649,7 @@ [PcdsFeatureFlag] | |
# TRUE - Reports StatusCode via Serial port.<BR> | |
# FALSE - Does not report StatusCode via Serial port.<BR> | |
# @Prompt Enable StatusCode via Serial port. | |
- gEfiMdeModulePkgTokenSpaceGuid.PcdStatusCodeUseSerial|TRUE|BOOLEAN|0x00010022 | |
+ gEfiMdeModulePkgTokenSpaceGuid.PcdStatusCodeUseSerial|FALSE|BOOLEAN|0x00010022 | |
## Indicates if StatusCode is stored in memory. | |
# The memory is boot time memory in PEI Phase and is runtime memory in DXE Phase.<BR><BR> | |
@@ -791,7 +699,7 @@ [PcdsFeatureFlag] | |
# TRUE - Supports recovery from FAT floppy disk.<BR> | |
# FALSE - Does not support recovery from FAT floppy disk.<BR> | |
# @Prompt Enable recovery on FAT floppy disk. | |
- gEfiMdeModulePkgTokenSpaceGuid.PcdRecoveryOnFatFloppyDisk|TRUE|BOOLEAN|0x00010061 | |
+ gEfiMdeModulePkgTokenSpaceGuid.PcdRecoveryOnFatFloppyDisk|FALSE|BOOLEAN|0x00010061 | |
## Indicates if recovery from data CD will be supported.<BR><BR> | |
# TRUE - Supports recovery from data CD.<BR> | |
@@ -809,15 +717,7 @@ [PcdsFeatureFlag] | |
# TRUE - S3 performance data will be supported in ACPI FPDT table.<BR> | |
# FALSE - S3 performance data will not be supported in ACPI FPDT table.<BR> | |
# @Prompt Enable S3 performance data support. | |
- gEfiMdeModulePkgTokenSpaceGuid.PcdFirmwarePerformanceDataTableS3Support|TRUE|BOOLEAN|0x00010064 | |
- | |
- ## Indicates if PS2 keyboard does a extended verification during start. | |
- # Add this PCD mainly consider the use case of simulator. This PCD maybe set to FALSE for | |
- # Extended verification will take some performance. It can be set to FALSE for boot performance.<BR><BR> | |
- # TRUE - Turn on PS2 keyboard extended verification.<BR> | |
- # FALSE - Turn off PS2 keyboard extended verification.<BR> | |
- # @Prompt Turn on PS2 Keyboard Extended Verification | |
- gEfiMdeModulePkgTokenSpaceGuid.PcdPs2KbdExtendedVerification|TRUE|BOOLEAN|0x00010072 | |
+ gEfiMdeModulePkgTokenSpaceGuid.PcdFirmwarePerformanceDataTableS3Support|FALSE|BOOLEAN|0x00010064 | |
## Indicates if Serial device uses half hand shake.<BR><BR> | |
# TRUE - Serial device uses half hand shake.<BR> | |
@@ -833,24 +733,6 @@ [PcdsFeatureFlag] | |
# @Prompt Enable export HII data and configuration to be used in OS runtime. | |
gEfiMdeModulePkgTokenSpaceGuid.PcdHiiOsRuntimeSupport|TRUE|BOOLEAN|0x00010074 | |
- ## Indicates if PS2 mouse does a extended verification during start. | |
- # Extended verification will take some performance. It can be set to FALSE for boot performance.<BR><BR> | |
- # TRUE - Turn on PS2 mouse extended verification. <BR> | |
- # FALSE - Turn off PS2 mouse extended verification. <BR> | |
- # @Prompt Turn on PS2 Mouse Extended Verification | |
- gEfiMdeModulePkgTokenSpaceGuid.PcdPs2MouseExtendedVerification|TRUE|BOOLEAN|0x00010075 | |
- | |
- ## Indicates whether 64-bit PCI MMIO BARs should degrade to 32-bit in the presence of an option ROM | |
- # On X64 platforms, Option ROMs may contain code that executes in the context of a legacy BIOS (CSM), | |
- # which requires that all PCI MMIO BARs are located below 4 GB | |
- # TRUE - All PCI MMIO BARs of a device will be located below 4 GB if it has an option ROM | |
- # FALSE - PCI MMIO BARs of a device may be located above 4 GB even if it has an option ROM | |
- # @Prompt Degrade 64-bit PCI MMIO BARs for legacy BIOS option ROMs | |
- gEfiMdeModulePkgTokenSpaceGuid.PcdPciDegradeResourceForOptionRom|TRUE|BOOLEAN|0x0001003a | |
- | |
-[PcdsFeatureFlag.IA32, PcdsFeatureFlag.ARM, PcdsFeatureFlag.AARCH64] | |
- gEfiMdeModulePkgTokenSpaceGuid.PcdPciDegradeResourceForOptionRom|FALSE|BOOLEAN|0x0001003a | |
- | |
[PcdsFeatureFlag.IA32, PcdsFeatureFlag.X64] | |
## Indicates if DxeIpl should switch to long mode to enter DXE phase. | |
# It is assumed that 64-bit DxeCore is built in firmware if it is true; otherwise 32-bit DxeCore | |
@@ -906,105 +788,6 @@ [PcdsFixedAtBuild] | |
# @ValidList 0x80000006 | 0x03058002 | |
gEfiMdeModulePkgTokenSpaceGuid.PcdErrorCodeSetVariable|0x03058002|UINT32|0x30001040 | |
- ## Mask to control the NULL address detection in code for different phases. | |
- # If enabled, accessing NULL address in UEFI or SMM code can be caught.<BR><BR> | |
- # BIT0 - Enable NULL pointer detection for UEFI.<BR> | |
- # BIT1 - Enable NULL pointer detection for SMM.<BR> | |
- # BIT2..6 - Reserved for future uses.<BR> | |
- # BIT7 - Disable NULL pointer detection just after EndOfDxe. <BR> | |
- # This is a workaround for those unsolvable NULL access issues in | |
- # OptionROM, boot loader, etc. It can also help to avoid unnecessary | |
- # exception caused by legacy memory (0-4095) access after EndOfDxe, | |
- # such as Windows 7 boot on Qemu.<BR> | |
- # @Prompt Enable NULL address detection. | |
- gEfiMdeModulePkgTokenSpaceGuid.PcdNullPointerDetectionPropertyMask|0x0|UINT8|0x30001050 | |
- | |
- ## Init Value in Temp Stack to be shared between SEC and PEI_CORE | |
- # SEC fills the full temp stack with this values. When switch stack, PeiCore can check | |
- # this value in the temp stack to know how many stack has been used. | |
- # @Prompt Init Value in Temp Stack | |
- gEfiMdeModulePkgTokenSpaceGuid.PcdInitValueInTempStack|0x5AA55AA5|UINT32|0x30001051 | |
- | |
- ## Indicates which type allocation need guard page. | |
- # | |
- # If a bit is set, a head guard page and a tail guard page will be added just | |
- # before and after corresponding type of pages allocated if there's enough | |
- # free pages for all of them. The page allocation for the type related to | |
- # cleared bits keeps the same as ususal. | |
- # | |
- # Below is bit mask for this PCD: (Order is same as UEFI spec)<BR> | |
- # EfiReservedMemoryType 0x0000000000000001<BR> | |
- # EfiLoaderCode 0x0000000000000002<BR> | |
- # EfiLoaderData 0x0000000000000004<BR> | |
- # EfiBootServicesCode 0x0000000000000008<BR> | |
- # EfiBootServicesData 0x0000000000000010<BR> | |
- # EfiRuntimeServicesCode 0x0000000000000020<BR> | |
- # EfiRuntimeServicesData 0x0000000000000040<BR> | |
- # EfiConventionalMemory 0x0000000000000080<BR> | |
- # EfiUnusableMemory 0x0000000000000100<BR> | |
- # EfiACPIReclaimMemory 0x0000000000000200<BR> | |
- # EfiACPIMemoryNVS 0x0000000000000400<BR> | |
- # EfiMemoryMappedIO 0x0000000000000800<BR> | |
- # EfiMemoryMappedIOPortSpace 0x0000000000001000<BR> | |
- # EfiPalCode 0x0000000000002000<BR> | |
- # EfiPersistentMemory 0x0000000000004000<BR> | |
- # OEM Reserved 0x4000000000000000<BR> | |
- # OS Reserved 0x8000000000000000<BR> | |
- # e.g. LoaderCode+LoaderData+BootServicesCode+BootServicesData are needed, 0x1E should be used.<BR> | |
- # @Prompt The memory type mask for Page Guard. | |
- gEfiMdeModulePkgTokenSpaceGuid.PcdHeapGuardPageType|0x0|UINT64|0x30001052 | |
- | |
- ## Indicates which type allocation need guard page. | |
- # | |
- # If a bit is set, a head guard page and a tail guard page will be added just | |
- # before and after corresponding type of pages which the allocated pool occupies, | |
- # if there's enough free memory for all of them. The pool allocation for the | |
- # type related to cleared bits keeps the same as ususal. | |
- # | |
- # Below is bit mask for this PCD: (Order is same as UEFI spec)<BR> | |
- # EfiReservedMemoryType 0x0000000000000001<BR> | |
- # EfiLoaderCode 0x0000000000000002<BR> | |
- # EfiLoaderData 0x0000000000000004<BR> | |
- # EfiBootServicesCode 0x0000000000000008<BR> | |
- # EfiBootServicesData 0x0000000000000010<BR> | |
- # EfiRuntimeServicesCode 0x0000000000000020<BR> | |
- # EfiRuntimeServicesData 0x0000000000000040<BR> | |
- # EfiConventionalMemory 0x0000000000000080<BR> | |
- # EfiUnusableMemory 0x0000000000000100<BR> | |
- # EfiACPIReclaimMemory 0x0000000000000200<BR> | |
- # EfiACPIMemoryNVS 0x0000000000000400<BR> | |
- # EfiMemoryMappedIO 0x0000000000000800<BR> | |
- # EfiMemoryMappedIOPortSpace 0x0000000000001000<BR> | |
- # EfiPalCode 0x0000000000002000<BR> | |
- # EfiPersistentMemory 0x0000000000004000<BR> | |
- # OEM Reserved 0x4000000000000000<BR> | |
- # OS Reserved 0x8000000000000000<BR> | |
- # e.g. LoaderCode+LoaderData+BootServicesCode+BootServicesData are needed, 0x1E should be used.<BR> | |
- # @Prompt The memory type mask for Pool Guard. | |
- gEfiMdeModulePkgTokenSpaceGuid.PcdHeapGuardPoolType|0x0|UINT64|0x30001053 | |
- | |
- ## This mask is to control Heap Guard behavior. | |
- # Note that due to the limit of pool memory implementation and the alignment | |
- # requirement of UEFI spec, BIT7 is a try-best setting which cannot guarantee | |
- # that the returned pool is exactly adjacent to head guard page or tail guard | |
- # page. | |
- # BIT0 - Enable UEFI page guard.<BR> | |
- # BIT1 - Enable UEFI pool guard.<BR> | |
- # BIT2 - Enable SMM page guard.<BR> | |
- # BIT3 - Enable SMM pool guard.<BR> | |
- # BIT7 - The direction of Guard Page for Pool Guard. | |
- # 0 - The returned pool is near the tail guard page.<BR> | |
- # 1 - The returned pool is near the head guard page.<BR> | |
- # @Prompt The Heap Guard feature mask | |
- gEfiMdeModulePkgTokenSpaceGuid.PcdHeapGuardPropertyMask|0x0|UINT8|0x30001054 | |
- | |
- ## Indicates if UEFI Stack Guard will be enabled. | |
- # If enabled, stack overflow in UEFI can be caught, preventing chaotic consequences.<BR><BR> | |
- # TRUE - UEFI Stack Guard will be enabled.<BR> | |
- # FALSE - UEFI Stack Guard will be disabled.<BR> | |
- # @Prompt Enable UEFI Stack Guard. | |
- gEfiMdeModulePkgTokenSpaceGuid.PcdCpuStackGuard|FALSE|BOOLEAN|0x30001055 | |
- | |
[PcdsFixedAtBuild, PcdsPatchableInModule] | |
## Dynamic type PCD can be registered callback function for Pcd setting action. | |
# PcdMaxPeiPcdCallBackNumberPerPcdEntry indicates the maximum number of callback function | |
@@ -1043,14 +826,6 @@ [PcdsFixedAtBuild, PcdsPatchableInModule] | |
# @Prompt Maximum authenticated variable size. | |
gEfiMdeModulePkgTokenSpaceGuid.PcdMaxAuthVariableSize|0x00|UINT32|0x30000009 | |
- ## The maximum size of a single non-authenticated volatile variable. | |
- # The default value is 0 for compatibility: in that case, the maximum | |
- # non-authenticated volatile variable size remains specified by | |
- # PcdMaxVariableSize. Only the MdeModulePkg/Universal/Variable/RuntimeDxe | |
- # driver supports this PCD. | |
- # @Prompt Maximum non-authenticated volatile variable size. | |
- gEfiMdeModulePkgTokenSpaceGuid.PcdMaxVolatileVariableSize|0x00|UINT32|0x3000000a | |
- | |
## The maximum size of single hardware error record variable.<BR><BR> | |
# In IA32/X64 platforms, this value should be larger than 1KB.<BR> | |
# In IA64 platforms, this value should be larger than 128KB.<BR> | |
@@ -1209,17 +984,10 @@ [PcdsFixedAtBuild, PcdsPatchableInModule] | |
## The mask is used to control memory profile behavior.<BR><BR> | |
# BIT0 - Enable UEFI memory profile.<BR> | |
# BIT1 - Enable SMRAM profile.<BR> | |
- # BIT7 - Disable recording at the start.<BR> | |
# @Prompt Memory Profile Property. | |
- # @Expression 0x80000002 | (gEfiMdeModulePkgTokenSpaceGuid.PcdMemoryProfilePropertyMask & 0x7C) == 0 | |
+ # @Expression 0x80000002 | (gEfiMdeModulePkgTokenSpaceGuid.PcdMemoryProfilePropertyMask & 0xFC) == 0 | |
gEfiMdeModulePkgTokenSpaceGuid.PcdMemoryProfilePropertyMask|0x0|UINT8|0x30001041 | |
- ## The mask is used to control SmiHandlerProfile behavior.<BR><BR> | |
- # BIT0 - Enable SmiHandlerProfile.<BR> | |
- # @Prompt SmiHandlerProfile Property. | |
- # @Expression 0x80000002 | (gEfiMdeModulePkgTokenSpaceGuid.PcdSmiHandlerProfilePropertyMask & 0xFE) == 0 | |
- gEfiMdeModulePkgTokenSpaceGuid.PcdSmiHandlerProfilePropertyMask|0|UINT8|0x00000108 | |
- | |
## This flag is to control which memory types of alloc info will be recorded by DxeCore & SmmCore.<BR><BR> | |
# For SmmCore, only EfiRuntimeServicesCode and EfiRuntimeServicesData are valid.<BR> | |
# | |
@@ -1247,62 +1015,6 @@ [PcdsFixedAtBuild, PcdsPatchableInModule] | |
# @Prompt Memory profile memory type. | |
gEfiMdeModulePkgTokenSpaceGuid.PcdMemoryProfileMemoryType|0x0|UINT64|0x30001042 | |
- ## This PCD is to control which drivers need memory profile data.<BR><BR> | |
- # For example:<BR> | |
- # One image only (Shell):<BR> | |
- # Header GUID<BR> | |
- # {0x04, 0x06, 0x14, 0x00, 0x83, 0xA5, 0x04, 0x7C, 0x3E, 0x9E, 0x1C, 0x4F, 0xAD, 0x65, 0xE0, 0x52, 0x68, 0xD0, 0xB4, 0xD1,<BR> | |
- # 0x7F, 0xFF, 0x04, 0x00}<BR> | |
- # Two or more images (Shell + WinNtSimpleFileSystem):<BR> | |
- # {0x04, 0x06, 0x14, 0x00, 0x83, 0xA5, 0x04, 0x7C, 0x3E, 0x9E, 0x1C, 0x4F, 0xAD, 0x65, 0xE0, 0x52, 0x68, 0xD0, 0xB4, 0xD1,<BR> | |
- # 0x7F, 0x01, 0x04, 0x00,<BR> | |
- # 0x04, 0x06, 0x14, 0x00, 0x8B, 0xE1, 0x25, 0x9C, 0xBA, 0x76, 0xDA, 0x43, 0xA1, 0x32, 0xDB, 0xB0, 0x99, 0x7C, 0xEF, 0xEF,<BR> | |
- # 0x7F, 0xFF, 0x04, 0x00}<BR> | |
- # @Prompt Memory profile driver path. | |
- gEfiMdeModulePkgTokenSpaceGuid.PcdMemoryProfileDriverPath|{0x0}|VOID*|0x00001043 | |
- | |
- ## Set image protection policy. The policy is bitwise. | |
- # If a bit is set, the image will be protected by DxeCore if it is aligned. | |
- # The code section becomes read-only, and the data section becomes non-executable. | |
- # If a bit is clear, the image will not be protected.<BR><BR> | |
- # BIT0 - Image from unknown device. <BR> | |
- # BIT1 - Image from firmware volume.<BR> | |
- # @Prompt Set image protection policy. | |
- # @ValidRange 0x80000002 | 0x00000000 - 0x0000001F | |
- gEfiMdeModulePkgTokenSpaceGuid.PcdImageProtectionPolicy|0x00000002|UINT32|0x00001047 | |
- | |
- ## Set DXE memory protection policy. The policy is bitwise. | |
- # If a bit is set, memory regions of the associated type will be mapped | |
- # non-executable.<BR><BR> | |
- # | |
- # Below is bit mask for this PCD: (Order is same as UEFI spec)<BR> | |
- # EfiReservedMemoryType 0x0001<BR> | |
- # EfiLoaderCode 0x0002<BR> | |
- # EfiLoaderData 0x0004<BR> | |
- # EfiBootServicesCode 0x0008<BR> | |
- # EfiBootServicesData 0x0010<BR> | |
- # EfiRuntimeServicesCode 0x0020<BR> | |
- # EfiRuntimeServicesData 0x0040<BR> | |
- # EfiConventionalMemory 0x0080<BR> | |
- # EfiUnusableMemory 0x0100<BR> | |
- # EfiACPIReclaimMemory 0x0200<BR> | |
- # EfiACPIMemoryNVS 0x0400<BR> | |
- # EfiMemoryMappedIO 0x0800<BR> | |
- # EfiMemoryMappedIOPortSpace 0x1000<BR> | |
- # EfiPalCode 0x2000<BR> | |
- # EfiPersistentMemory 0x4000<BR> | |
- # OEM Reserved 0x4000000000000000<BR> | |
- # OS Reserved 0x8000000000000000<BR> | |
- # | |
- # NOTE: User must NOT set NX protection for EfiLoaderCode / EfiBootServicesCode / EfiRuntimeServicesCode. <BR> | |
- # User MUST set the same NX protection for EfiBootServicesData and EfiConventionalMemory. <BR> | |
- # | |
- # e.g. 0x7FD5 can be used for all memory except Code. <BR> | |
- # e.g. 0x7BD4 can be used for all memory except Code and ACPINVS/Reserved. <BR> | |
- # | |
- # @Prompt Set DXE memory protection policy. | |
- gEfiMdeModulePkgTokenSpaceGuid.PcdDxeNxMemoryProtectionPolicy|0x0000000|UINT64|0x00001048 | |
- | |
## PCI Serial Device Info. It is an array of Device, Function, and Power Management | |
# information that describes the path that contains zero or more PCI to PCI briges | |
# followed by a PCI serial device. Each array entry is 4-bytes in length. The | |
@@ -1382,101 +1094,26 @@ [PcdsFixedAtBuild, PcdsPatchableInModule] | |
# @Prompt Exposed ACPI table versions. | |
gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiExposedTableVersions|0x3E|UINT32|0x0001004c | |
- ## This PCD defines the MAX repair count. | |
- # The default value is 0 that means infinite. | |
- # @Prompt MAX repair count | |
- gEfiMdeModulePkgTokenSpaceGuid.PcdMaxRepairCount|0x00|UINT32|0x00010076 | |
- | |
- ## Status Code for Capsule subclass definitions.<BR><BR> | |
- # EFI_OEM_SPECIFIC_SUBCLASS_CAPSULE = 0x00810000<BR> | |
- # NOTE: The default value of this PCD may collide with other OEM specific status codes. | |
- # Override the value of this PCD in the platform DSC file as needed. | |
- # @Prompt Status Code for Capsule subclass definitions | |
- # @ValidList 0x80000003 | 0x00810000 | |
- gEfiMdeModulePkgTokenSpaceGuid.PcdStatusCodeSubClassCapsule|0x00810000|UINT32|0x00000100 | |
- | |
- ## Status Code for Capsule Process Begin.<BR><BR> | |
- # EFI_CAPSULE_PROCESS_CAPSULES_BEGIN = (EFI_OEM_SPECIFIC | 0x00000001) = 0x00008001<BR> | |
- # NOTE: The default value of this PCD may collide with other OEM specific status codes. | |
- # Override the value of this PCD in the platform DSC file as needed. | |
- # @Prompt Status Code for Capsule Process Begin | |
- # @ValidList 0x80000003 | 0x00008001 | |
- gEfiMdeModulePkgTokenSpaceGuid.PcdCapsuleStatusCodeProcessCapsulesBegin|0x00008001|UINT32|0x00000101 | |
- | |
- ## Status Code for Capsule Process End.<BR><BR> | |
- # EFI_CAPSULE_PROCESS_CAPSULES_END = (EFI_OEM_SPECIFIC | 0x00000002) = 0x00008002<BR> | |
- # NOTE: The default value of this PCD may collide with other OEM specific status codes. | |
- # Override the value of this PCD in the platform DSC file as needed. | |
- # @Prompt Status Code for Capsule Process End | |
- # @ValidList 0x80000003 | 0x00008002 | |
- gEfiMdeModulePkgTokenSpaceGuid.PcdCapsuleStatusCodeProcessCapsulesEnd|0x00008002|UINT32|0x00000102 | |
- | |
- ## Status Code for Capsule Process Updating Firmware.<BR><BR> | |
- # EFI_CAPSULE_UPDATING_FIRMWARE = (EFI_OEM_SPECIFIC | 0x00000003) = 0x00008003<BR> | |
- # NOTE: The default value of this PCD may collide with other OEM specific status codes. | |
- # Override the value of this PCD in the platform DSC file as needed. | |
- # @Prompt Status Code for Capsule Process Updating Firmware | |
- # @ValidList 0x80000003 | 0x00008003 | |
- gEfiMdeModulePkgTokenSpaceGuid.PcdCapsuleStatusCodeUpdatingFirmware|0x00008003|UINT32|0x00000103 | |
- | |
- ## Status Code for Capsule Process Update Firmware Success.<BR><BR> | |
- # EFI_CAPSULE_UPDATE_FIRMWARE_SUCCESS = (EFI_OEM_SPECIFIC | 0x00000004) = 0x00008004<BR> | |
- # NOTE: The default value of this PCD may collide with other OEM specific status codes. | |
- # Override the value of this PCD in the platform DSC file as needed. | |
- # @Prompt Status Code for Capsule Process Update Firmware Success | |
- # @ValidList 0x80000003 | 0x00008004 | |
- gEfiMdeModulePkgTokenSpaceGuid.PcdCapsuleStatusCodeUpdateFirmwareSuccess|0x00008004|UINT32|0x00000104 | |
- | |
- ## Status Code for Capsule Process Update Firmware Failed.<BR><BR> | |
- # EFI_CAPSULE_UPDATE_FIRMWARE_FAILED = (EFI_OEM_SPECIFIC | 0x00000005) = 0x00008005<BR> | |
- # NOTE: The default value of this PCD may collide with other OEM specific status codes. | |
- # Override the value of this PCD in the platform DSC file as needed. | |
- # @Prompt Status Code for Capsule Process Update Firmware Failed | |
- # @ValidList 0x80000003 | 0x00008005 | |
- gEfiMdeModulePkgTokenSpaceGuid.PcdCapsuleStatusCodeUpdateFirmwareFailed|0x00008005|UINT32|0x00000105 | |
- | |
- ## Status Code for Capsule Resetting System.<BR><BR> | |
- # EFI_CAPSULE_RESETTING_SYSTEM = (EFI_OEM_SPECIFIC | 0x00000006) = 0x00008006<BR> | |
- # NOTE: The default value of this PCD may collide with other OEM specific status codes. | |
- # Override the value of this PCD in the platform DSC file as needed. | |
- # @Prompt Status Code for Capsule Resetting System | |
- # @ValidList 0x80000003 | 0x00008006 | |
- gEfiMdeModulePkgTokenSpaceGuid.PcdCapsuleStatusCodeResettingSystem|0x00008006|UINT32|0x00000106 | |
- | |
- ## CapsuleMax value in capsule report variable. | |
- # @Prompt CapsuleMax value in capsule report variable. | |
- gEfiMdeModulePkgTokenSpaceGuid.PcdCapsuleMax|0xFFFF|UINT16|0x00000107 | |
- | |
- ## Control which FPDT record format will be used to store the performance entry. | |
- # On TRUE, the string FPDT record will be used to store every performance entry. | |
- # On FALSE, the different FPDT record will be used to store the different performance entries. | |
- # @Prompt String FPDT Record Enable Only | |
- gEfiMdeModulePkgTokenSpaceGuid.PcdEdkiiFpdtStringRecordEnableOnly|FALSE|BOOLEAN|0x00000109 | |
- | |
- ## Indicates the allowable maximum number of Reset Filters, Reset Notifications or Reset Handlers in PEI phase. | |
- # @Prompt Maximum Number of PEI Reset Filters, Reset Notifications or Reset Handlers. | |
- gEfiMdeModulePkgTokenSpaceGuid.PcdMaximumPeiResetNotifies|0x10|UINT32|0x0000010A | |
- | |
[PcdsPatchableInModule, PcdsDynamic, PcdsDynamicEx] | |
## This PCD defines the Console output row. The default value is 25 according to UEFI spec. | |
# This PCD could be set to 0 then console output would be at max column and max row. | |
# @Prompt Console output row. | |
- gEfiMdeModulePkgTokenSpaceGuid.PcdConOutRow|25|UINT32|0x40000006 | |
+ gEfiMdeModulePkgTokenSpaceGuid.PcdConOutRow|0|UINT32|0x40000006 | |
## This PCD defines the Console output column. The default value is 80 according to UEFI spec. | |
# This PCD could be set to 0 then console output would be at max column and max row. | |
# @Prompt Console output column. | |
- gEfiMdeModulePkgTokenSpaceGuid.PcdConOutColumn|80|UINT32|0x40000007 | |
+ gEfiMdeModulePkgTokenSpaceGuid.PcdConOutColumn|0|UINT32|0x40000007 | |
## This PCD defines the video horizontal resolution. | |
# If this PCD is set to 0 then video resolution would be at highest resolution. | |
# @Prompt Video horizontal resolution. | |
- gEfiMdeModulePkgTokenSpaceGuid.PcdVideoHorizontalResolution|800|UINT32|0x40000009 | |
+ gEfiMdeModulePkgTokenSpaceGuid.PcdVideoHorizontalResolution|0|UINT32|0x40000009 | |
## This PCD defines the video vertical resolution. | |
# If this PCD is set to 0 then video resolution would be at highest resolution. | |
# @Prompt Video vertical resolution. | |
- gEfiMdeModulePkgTokenSpaceGuid.PcdVideoVerticalResolution|600|UINT32|0x4000000a | |
+ gEfiMdeModulePkgTokenSpaceGuid.PcdVideoVerticalResolution|0|UINT32|0x4000000a | |
# The 4 PCDs below are used to specify the video resolution and text mode of text setup. | |
# To make text setup work in this resolution, PcdVideoHorizontalResolution, PcdVideoVerticalResolution, | |
@@ -1562,6 +1199,9 @@ [PcdsFixedAtBuild, PcdsPatchableInModule, PcdsDynamic, PcdsDynamicEx] | |
# @Prompt Reserved memory range for EMU variable NV storage. | |
gEfiMdeModulePkgTokenSpaceGuid.PcdEmuVariableNvStoreReserved|0|UINT64|0x40000008 | |
+ | |
+[PcdsFixedAtBuild, PcdsPatchableInModule, PcdsDynamic, PcdsDynamicEx] | |
+ | |
## This PCD defines the times to print hello world string. | |
# This PCD is a sample to explain UINT32 PCD usage. | |
# @Prompt HellowWorld print times. | |
@@ -1570,7 +1210,7 @@ [PcdsFixedAtBuild, PcdsPatchableInModule, PcdsDynamic, PcdsDynamicEx] | |
## This PCD defines the HelloWorld print string. | |
# This PCD is a sample to explain String typed PCD usage. | |
# @Prompt HelloWorld print string. | |
- gEfiMdeModulePkgTokenSpaceGuid.PcdHelloWorldPrintString|L"UEFI Hello World!\n"|VOID*|0x40000004 | |
+ gEfiMdeModulePkgTokenSpaceGuid.PcdHelloWorldPrintString|L"UEFI Hello Clover!\n"|VOID*|0x40000004 | |
## Indicates the maximum size of the capsule image with a reset flag that the platform can support. | |
# The default max size is 100MB (0x6400000) for more than one large capsule images. | |
@@ -1584,11 +1224,11 @@ [PcdsFixedAtBuild, PcdsPatchableInModule, PcdsDynamic, PcdsDynamicEx] | |
## Null-terminated Unicode string of the firmware vendor name that is the default name filled into the EFI System Table. | |
# @Prompt Firmware vendor. | |
- gEfiMdeModulePkgTokenSpaceGuid.PcdFirmwareVendor|L"EDK II"|VOID*|0x00010050 | |
+ gEfiMdeModulePkgTokenSpaceGuid.PcdFirmwareVendor|L"CLOVER"|VOID*|0x00010050 | |
## Firmware revision that is the default revision filled into the EFI System Table. | |
# @Prompt Firmware revision. | |
- gEfiMdeModulePkgTokenSpaceGuid.PcdFirmwareRevision|0x00010000|UINT32|0x00010051 | |
+ gEfiMdeModulePkgTokenSpaceGuid.PcdFirmwareRevision|0x00010010|UINT32|0x00010051 | |
## Null-terminated Unicode string that describes the firmware version. | |
# @Prompt Firmware version string. | |
@@ -1741,11 +1381,11 @@ [PcdsFixedAtBuild, PcdsPatchableInModule, PcdsDynamic, PcdsDynamicEx] | |
## SMBIOS version. | |
# @Prompt SMBIOS version. | |
- gEfiMdeModulePkgTokenSpaceGuid.PcdSmbiosVersion|0x0301|UINT16|0x00010055 | |
+ gEfiMdeModulePkgTokenSpaceGuid.PcdSmbiosVersion|0x0204|UINT16|0x00010055 | |
## SMBIOS Docrev field in SMBIOS 3.0 (64-bit) Entry Point Structure. | |
# @Prompt SMBIOS Docrev field in SMBIOS 3.0 (64-bit) Entry Point Structure. | |
- gEfiMdeModulePkgTokenSpaceGuid.PcdSmbiosDocRev|0x1|UINT8|0x0001006A | |
+ gEfiMdeModulePkgTokenSpaceGuid.PcdSmbiosDocRev|0x0|UINT8|0x0001006A | |
## SMBIOS produce method. | |
# BIT0 set indicates 32-bit entry point and table are produced.<BR> | |
@@ -1756,7 +1396,7 @@ [PcdsFixedAtBuild, PcdsPatchableInModule, PcdsDynamic, PcdsDynamicEx] | |
## This PCD specifies the additional pad size in FPDT Basic Boot Performance Table for | |
# the extension FPDT boot records received after ReadyToBoot and before ExitBootService. | |
# @Prompt Pad size for extension FPDT boot records. | |
- gEfiMdeModulePkgTokenSpaceGuid.PcdExtFpdtBootRecordPadSize|0x20000|UINT32|0x0001005F | |
+ gEfiMdeModulePkgTokenSpaceGuid.PcdExtFpdtBootRecordPadSize|0x0|UINT32|0x0001005F | |
## Indicates if ConIn device are connected on demand.<BR><BR> | |
# TRUE - ConIn device are not connected during BDS and ReadKeyStroke/ReadKeyStrokeEx produced | |
@@ -1877,43 +1517,6 @@ [PcdsFixedAtBuild, PcdsPatchableInModule, PcdsDynamic, PcdsDynamicEx] | |
# @Prompt Mmio base address of pci-based SD/MMC host controller. | |
gEfiMdeModulePkgTokenSpaceGuid.PcdSdMmcPciHostControllerMmioBase|0xd0000000|UINT32|0x30001043 | |
- ## Indicates if ACPI S3 will be enabled.<BR><BR> | |
- # TRUE - ACPI S3 will be enabled.<BR> | |
- # FALSE - ACPI S3 will be disabled.<BR> | |
- # @Prompt ACPI S3 Enable. | |
- gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiS3Enable|TRUE|BOOLEAN|0x01100000 | |
- | |
- ## Specify memory size for boot script executor stack usage in S3 phase. | |
- # The default size 32K. When changing the value make sure the memory size is large enough | |
- # to meet boot script executor requirement in the S3 phase. | |
- # @Prompt Reserved S3 Boot Script Stack ACPI Memory Size | |
- gEfiMdeModulePkgTokenSpaceGuid.PcdS3BootScriptStackSize|0x8000|UINT32|0x02000000 | |
- | |
- ## Indicates if to use the optimized timing for best PS2 detection performance. | |
- # Note this PCD could be set to TRUE for best boot performance and set to FALSE for best device compatibility.<BR><BR> | |
- # TRUE - Use the optimized timing for best PS2 detection performance.<BR> | |
- # FALSE - Use the normal timing to detect PS2.<BR> | |
- # @Prompt Enable fast PS2 detection | |
- gEfiMdeModulePkgTokenSpaceGuid.PcdFastPS2Detection|FALSE|BOOLEAN|0x30001044 | |
- | |
- ## This is recover file name in PEI phase. | |
- # The file must be in the root directory. | |
- # The file name must be the 8.3 format. | |
- # The PCD data must be in UNICODE format. | |
- # @Prompt Recover file name in PEI phase | |
- gEfiMdeModulePkgTokenSpaceGuid.PcdRecoveryFileName|L"FVMAIN.FV"|VOID*|0x30001045 | |
- | |
- ## This PCD hold a list GUIDs for the ImageTypeId to indicate the | |
- # FMP capsule is a system FMP. | |
- # @Prompt A list of system FMP ImageTypeId GUIDs | |
- gEfiMdeModulePkgTokenSpaceGuid.PcdSystemFmpCapsuleImageTypeIdGuid|{0x0}|VOID*|0x30001046 | |
- | |
- ## This PCD holds the address mask for page table entries when memory encryption is | |
- # enabled on AMD processors supporting the Secure Encrypted Virtualization (SEV) feature. | |
- # This mask should be applied when creating 1:1 virtual to physical mapping tables. | |
- # @Prompt The address mask when memory encryption is enabled. | |
- gEfiMdeModulePkgTokenSpaceGuid.PcdPteMemoryEncryptionAddressOrMask|0x0|UINT64|0x30001047 | |
- | |
[PcdsPatchableInModule] | |
## Specify memory size with page number for PEI code when | |
# Loading Module at Fixed Address feature is enabled. | |
@@ -1966,20 +1569,5 @@ [PcdsDynamic, PcdsDynamicEx] | |
# @ValidList 0x80000001 | 0x0 | |
gEfiMdeModulePkgTokenSpaceGuid.PcdIdentifyMappingPageTablePtr|0x0|UINT64|0x00030002 | |
- ## This dynamic PCD holds the information if there is any test key used by the platform. | |
- # @Prompt If there is any test key used by the platform. | |
- gEfiMdeModulePkgTokenSpaceGuid.PcdTestKeyUsed|FALSE|BOOLEAN|0x00030003 | |
- | |
-[PcdsDynamicEx] | |
- ## This dynamic PCD enables the default variable setting. | |
- # Its value is the default store ID value. The default value is zero as Standard default. | |
- # When its value is set in PEI, it will trig the default setting to be applied as the default EFI variable. | |
- # @Prompt NV Storage DefaultId | |
- gEfiMdeModulePkgTokenSpaceGuid.PcdSetNvStoreDefaultId|0x0|UINT16|0x00030004 | |
- | |
- ## This dynamic PCD holds the DynamicHii PCD value. Its value is the auto generated. | |
- # @Prompt NV Storage Default Value Buffer | |
- gEfiMdeModulePkgTokenSpaceGuid.PcdNvStoreDefaultValueBuffer|{0x0}|VOID*|0x00030005 | |
- | |
[UserExtensions.TianoCore."ExtraFiles"] | |
MdeModulePkgExtra.uni | |
diff --git a/ShellPkg/ShellPkg.dec b/ShellPkg/ShellPkg.dec | |
index 0c4f74ff4172..620ba81afa85 100644 | |
--- a/ShellPkg/ShellPkg.dec | |
+++ b/ShellPkg/ShellPkg.dec | |
@@ -18,7 +18,7 @@ [Defines] | |
DEC_SPECIFICATION = 0x00010005 | |
PACKAGE_NAME = ShellPkg | |
PACKAGE_GUID = C1014BB7-4092-43D4-984F-0738EB424DBF | |
- PACKAGE_VERSION = 1.02 | |
+ PACKAGE_VERSION = 1.0 | |
[Includes] | |
Include | |
@@ -57,12 +57,12 @@ [Guids] | |
gShellTftpHiiGuid = {0x738a9314, 0x82c1, 0x4592, {0x8f, 0xf7, 0xc1, 0xbd, 0xf1, 0xb2, 0x0e, 0xd4}} | |
gShellBcfgHiiGuid = {0x5f5f605d, 0x1583, 0x4a2d, {0xa6, 0xb2, 0xeb, 0x12, 0xda, 0xb4, 0xa2, 0xb6}} | |
- # FILE_GUID as defined in ShellPkg/Application/Shell/Shell.inf | |
- gUefiShellFileGuid = {0x7c04a583, 0x9e3e, 0x4f1c, {0xad, 0x65, 0xe0, 0x52, 0x68, 0xd0, 0xb4, 0xd1}} | |
- | |
[Protocols] | |
+ gEfiShellProtocolGuid = {0x6302d008, 0x7f9b, 0x4f30, {0x87, 0xac, 0x60, 0xc9, 0xfe, 0xf5, 0xda, 0x4e}} | |
+ gEfiShellParametersProtocolGuid = {0x752f3136, 0x4e16, 0x4fdc, {0xa2, 0x2a, 0xe5, 0xf4, 0x68, 0x12, 0xf4, 0xca}} | |
gEfiShellEnvironment2Guid = {0x47c7b221, 0xc42a, 0x11d2, {0x8e, 0x57, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b}} | |
gEfiShellInterfaceGuid = {0x47c7b223, 0xc42a, 0x11d2, {0x8e, 0x57, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b}} | |
+ gEfiShellDynamicCommandProtocolGuid = {0x3c7200e9, 0x005f, 0x4ea4, {0x87, 0xde, 0xa3, 0xdf, 0xac, 0x8a, 0x27, 0xc3}} | |
[PcdsFeatureFlag] | |
## This flag is used to control whether the shell includes NT32 platform Guids | |
diff --git a/OvmfPkg/OvmfCloverX64.dsc b/OvmfPkg/OvmfCloverX64.dsc | |
new file mode 100644 | |
index 000000000000..0533e2dfc485 | |
--- /dev/null | |
+++ b/OvmfPkg/OvmfCloverX64.dsc | |
@@ -0,0 +1,849 @@ | |
+## @file | |
+# EFI/Framework Open Virtual Machine Firmware (OVMF) platform | |
+# | |
+# Copyright (c) 2006 - 2016, 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. | |
+# | |
+## | |
+ | |
+################################################################################ | |
+# | |
+# Defines Section - statements that will be processed to create a Makefile. | |
+# | |
+################################################################################ | |
+[Defines] | |
+ PLATFORM_NAME = Ovmf | |
+ PLATFORM_GUID = 5a9e7754-d81b-49ea-85ad-69eaa7b1539b | |
+ PLATFORM_VERSION = 0.1 | |
+ DSC_SPECIFICATION = 0x00010005 | |
+ OUTPUT_DIRECTORY = Build/OvmfX64 | |
+ SUPPORTED_ARCHITECTURES = X64 | |
+ BUILD_TARGETS = DEBUG|RELEASE | |
+ SKUID_IDENTIFIER = DEFAULT | |
+ FLASH_DEFINITION = OvmfPkg/OvmfCloverX64.fdf | |
+ | |
+ # | |
+ # Defines for default states. These can be changed on the command line. | |
+ # -D FLAG=VALUE | |
+ # | |
+ DEFINE SECURE_BOOT_ENABLE = FALSE | |
+ DEFINE NETWORK_IP6_ENABLE = FALSE | |
+ DEFINE HTTP_BOOT_ENABLE = FALSE | |
+ DEFINE SMM_REQUIRE = FALSE | |
+ | |
+[BuildOptions] | |
+ GCC:*_UNIXGCC_*_CC_FLAGS = -DMDEPKG_NDEBUG | |
+ GCC:RELEASE_*_*_CC_FLAGS = -DMDEPKG_NDEBUG | |
+ INTEL:RELEASE_*_*_CC_FLAGS = /D MDEPKG_NDEBUG | |
+ MSFT:RELEASE_*_*_CC_FLAGS = /D MDEPKG_NDEBUG | |
+ GCC:*_*_*_CC_FLAGS = -Os -mno-mmx -mno-sse -DMDEPKG_NDEBUG | |
+!ifdef $(SOURCE_DEBUG_ENABLE) | |
+ MSFT:*_*_X64_GENFW_FLAGS = --keepexceptiontable | |
+ GCC:*_*_X64_GENFW_FLAGS = --keepexceptiontable | |
+ INTEL:*_*_X64_GENFW_FLAGS = --keepexceptiontable | |
+!endif | |
+ | |
+[BuildOptions.common.EDKII.DXE_RUNTIME_DRIVER] | |
+# GCC:*_*_*_DLINK_FLAGS = -z common-page-size=0x1000 | |
+ | |
+################################################################################ | |
+# | |
+# SKU Identification section - list of all SKU IDs supported by this Platform. | |
+# | |
+################################################################################ | |
+[SkuIds] | |
+ 0|DEFAULT | |
+ | |
+################################################################################ | |
+# | |
+# Library Class section - list of all Library Classes needed by this Platform. | |
+# | |
+################################################################################ | |
+[LibraryClasses] | |
+ PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf | |
+ TimerLib|OvmfPkg/Library/AcpiTimerLib/BaseAcpiTimerLib.inf | |
+ PrintLib|MdePkg/Library/BasePrintLib/BasePrintLib.inf | |
+ BaseMemoryLib|MdePkg/Library/BaseMemoryLibRepStr/BaseMemoryLibRepStr.inf | |
+ BaseLib|MdePkg/Library/BaseLib/BaseLib.inf | |
+ SynchronizationLib|MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLib.inf | |
+ CpuLib|MdePkg/Library/BaseCpuLib/BaseCpuLib.inf | |
+ PerformanceLib|MdePkg/Library/BasePerformanceLibNull/BasePerformanceLibNull.inf | |
+ PeCoffLib|MdePkg/Library/BasePeCoffLib/BasePeCoffLib.inf | |
+ #PeCoffLib|Clover/Library/VBoxPeCoffLib/VBoxPeCoffLib.inf | |
+ CacheMaintenanceLib|MdePkg/Library/BaseCacheMaintenanceLib/BaseCacheMaintenanceLib.inf | |
+ UefiDecompressLib|MdePkg/Library/BaseUefiDecompressLib/BaseUefiDecompressLib.inf | |
+ UefiHiiServicesLib|MdeModulePkg/Library/UefiHiiServicesLib/UefiHiiServicesLib.inf | |
+ #UefiHiiServicesLib|Clover/Library/UefiHiiServicesLib/UefiHiiServicesLib.inf | |
+ HiiLib|MdeModulePkg/Library/UefiHiiLib/UefiHiiLib.inf | |
+ SortLib|MdeModulePkg/Library/UefiSortLib/UefiSortLib.inf | |
+ UefiBootManagerLib|MdeModulePkg/Library/UefiBootManagerLib/UefiBootManagerLib.inf | |
+ BootLogoLib|MdeModulePkg/Library/BootLogoLib/BootLogoLib.inf | |
+ ImageDecoderLib|MdeModulePkg/Library/ImageDecoderLib/ImageDecoderLib.inf | |
+ FileExplorerLib|MdeModulePkg/Library/FileExplorerLib/FileExplorerLib.inf | |
+ CapsuleLib|MdeModulePkg/Library/DxeCapsuleLibNull/DxeCapsuleLibNull.inf | |
+ DxeServicesLib|MdePkg/Library/DxeServicesLib/DxeServicesLib.inf | |
+ DxeServicesTableLib|MdePkg/Library/DxeServicesTableLib/DxeServicesTableLib.inf | |
+ PeCoffGetEntryPointLib|MdePkg/Library/BasePeCoffGetEntryPointLib/BasePeCoffGetEntryPointLib.inf | |
+ PciCf8Lib|MdePkg/Library/BasePciCf8Lib/BasePciCf8Lib.inf | |
+ PciExpressLib|MdePkg/Library/BasePciExpressLib/BasePciExpressLib.inf | |
+ PciLib|MdePkg/Library/BasePciLibCf8/BasePciLibCf8.inf | |
+ PciSegmentLib|MdePkg/Library/BasePciSegmentLibPci/BasePciSegmentLibPci.inf | |
+ IoLib|MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsic.inf | |
+ OemHookStatusCodeLib|MdeModulePkg/Library/OemHookStatusCodeLibNull/OemHookStatusCodeLibNull.inf | |
+ SerialPortLib|PcAtChipsetPkg/Library/SerialIoLib/SerialIoLib.inf | |
+ MtrrLib|UefiCpuPkg/Library/MtrrLib/MtrrLib.inf | |
+ UefiLib|MdePkg/Library/UefiLib/UefiLib.inf | |
+ UefiBootServicesTableLib|MdePkg/Library/UefiBootServicesTableLib/UefiBootServicesTableLib.inf | |
+ UefiRuntimeServicesTableLib|MdePkg/Library/UefiRuntimeServicesTableLib/UefiRuntimeServicesTableLib.inf | |
+ UefiDriverEntryPoint|MdePkg/Library/UefiDriverEntryPoint/UefiDriverEntryPoint.inf | |
+ UefiApplicationEntryPoint|MdePkg/Library/UefiApplicationEntryPoint/UefiApplicationEntryPoint.inf | |
+ DevicePathLib|MdePkg/Library/UefiDevicePathLibDevicePathProtocol/UefiDevicePathLibDevicePathProtocol.inf | |
+ NvVarsFileLib|OvmfPkg/Library/NvVarsFileLib/NvVarsFileLib.inf | |
+ FileHandleLib|MdePkg/Library/UefiFileHandleLib/UefiFileHandleLib.inf | |
+ UefiCpuLib|UefiCpuPkg/Library/BaseUefiCpuLib/BaseUefiCpuLib.inf | |
+ SecurityManagementLib|MdeModulePkg/Library/DxeSecurityManagementLib/DxeSecurityManagementLib.inf | |
+ NetLib|MdeModulePkg/Library/DxeNetLib/DxeNetLib.inf | |
+ IpIoLib|MdeModulePkg/Library/DxeIpIoLib/DxeIpIoLib.inf | |
+ UdpIoLib|MdeModulePkg/Library/DxeUdpIoLib/DxeUdpIoLib.inf | |
+ DpcLib|MdeModulePkg/Library/DxeDpcLib/DxeDpcLib.inf | |
+ UefiUsbLib|MdePkg/Library/UefiUsbLib/UefiUsbLib.inf | |
+ SerializeVariablesLib|OvmfPkg/Library/SerializeVariablesLib/SerializeVariablesLib.inf | |
+ QemuFwCfgLib|OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgLib.inf | |
+ VirtioLib|OvmfPkg/Library/VirtioLib/VirtioLib.inf | |
+ LoadLinuxLib|OvmfPkg/Library/LoadLinuxLib/LoadLinuxLib.inf | |
+!if $(SMM_REQUIRE) == FALSE | |
+ LockBoxLib|OvmfPkg/Library/LockBoxLib/LockBoxBaseLib.inf | |
+!endif | |
+ CustomizedDisplayLib|MdeModulePkg/Library/CustomizedDisplayLib/CustomizedDisplayLib.inf | |
+# MemLogLib|Clover/Library/MemLogLibDefault/MemLogLibDefault.inf | |
+ | |
+!ifdef $(SOURCE_DEBUG_ENABLE) | |
+ PeCoffExtraActionLib|SourceLevelDebugPkg/Library/PeCoffExtraActionLibDebug/PeCoffExtraActionLibDebug.inf | |
+ DebugCommunicationLib|SourceLevelDebugPkg/Library/DebugCommunicationLibSerialPort/DebugCommunicationLibSerialPort.inf | |
+!else | |
+ PeCoffExtraActionLib|MdePkg/Library/BasePeCoffExtraActionLibNull/BasePeCoffExtraActionLibNull.inf | |
+ DebugAgentLib|MdeModulePkg/Library/DebugAgentLibNull/DebugAgentLibNull.inf | |
+!endif | |
+ | |
+ ResetSystemLib|OvmfPkg/Library/ResetSystemLib/ResetSystemLib.inf | |
+ LocalApicLib|UefiCpuPkg/Library/BaseXApicX2ApicLib/BaseXApicX2ApicLib.inf | |
+ DebugPrintErrorLevelLib|MdePkg/Library/BaseDebugPrintErrorLevelLib/BaseDebugPrintErrorLevelLib.inf | |
+ | |
+!if $(SECURE_BOOT_ENABLE) == TRUE | |
+ PlatformSecureLib|OvmfPkg/Library/PlatformSecureLib/PlatformSecureLib.inf | |
+ IntrinsicLib|CryptoPkg/Library/IntrinsicLib/IntrinsicLib.inf | |
+ OpensslLib|CryptoPkg/Library/OpensslLib/OpensslLib.inf | |
+ TpmMeasurementLib|SecurityPkg/Library/DxeTpmMeasurementLib/DxeTpmMeasurementLib.inf | |
+ AuthVariableLib|SecurityPkg/Library/AuthVariableLib/AuthVariableLib.inf | |
+!if $(NETWORK_IP6_ENABLE) == TRUE | |
+ TcpIoLib|MdeModulePkg/Library/DxeTcpIoLib/DxeTcpIoLib.inf | |
+!endif | |
+!else | |
+ TpmMeasurementLib|MdeModulePkg/Library/TpmMeasurementLibNull/TpmMeasurementLibNull.inf | |
+ AuthVariableLib|MdeModulePkg/Library/AuthVariableLibNull/AuthVariableLibNull.inf | |
+!endif | |
+ VarCheckLib|MdeModulePkg/Library/VarCheckLib/VarCheckLib.inf | |
+ | |
+!if $(HTTP_BOOT_ENABLE) == TRUE | |
+ HttpLib|MdeModulePkg/Library/DxeHttpLib/DxeHttpLib.inf | |
+!endif | |
+ | |
+ S3BootScriptLib|MdeModulePkg/Library/PiDxeS3BootScriptLib/DxeS3BootScriptLib.inf | |
+ SmbusLib|MdePkg/Library/BaseSmbusLibNull/BaseSmbusLibNull.inf | |
+ OrderedCollectionLib|MdePkg/Library/BaseOrderedCollectionRedBlackTreeLib/BaseOrderedCollectionRedBlackTreeLib.inf | |
+ XenHypercallLib|OvmfPkg/Library/XenHypercallLib/XenHypercallLib.inf | |
+ | |
+[LibraryClasses.common] | |
+!if $(SECURE_BOOT_ENABLE) == TRUE | |
+ BaseCryptLib|CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf | |
+!endif | |
+ | |
+[LibraryClasses.common.SEC] | |
+ TimerLib|OvmfPkg/Library/AcpiTimerLib/BaseRomAcpiTimerLib.inf | |
+ QemuFwCfgLib|OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgSecLib.inf | |
+!ifdef $(DEBUG_ON_SERIAL_PORT) | |
+ DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf | |
+!else | |
+ DebugLib|OvmfPkg/Library/PlatformDebugLibIoPort/PlatformDebugLibIoPort.inf | |
+!endif | |
+ ReportStatusCodeLib|MdeModulePkg/Library/PeiReportStatusCodeLib/PeiReportStatusCodeLib.inf | |
+ ExtractGuidedSectionLib|MdePkg/Library/BaseExtractGuidedSectionLib/BaseExtractGuidedSectionLib.inf | |
+!ifdef $(SOURCE_DEBUG_ENABLE) | |
+ DebugAgentLib|SourceLevelDebugPkg/Library/DebugAgent/SecPeiDebugAgentLib.inf | |
+!endif | |
+ HobLib|MdePkg/Library/PeiHobLib/PeiHobLib.inf | |
+ PeiServicesLib|MdePkg/Library/PeiServicesLib/PeiServicesLib.inf | |
+ PeiServicesTablePointerLib|MdePkg/Library/PeiServicesTablePointerLibIdt/PeiServicesTablePointerLibIdt.inf | |
+ MemoryAllocationLib|MdePkg/Library/PeiMemoryAllocationLib/PeiMemoryAllocationLib.inf | |
+ CpuExceptionHandlerLib|UefiCpuPkg/Library/CpuExceptionHandlerLib/SecPeiCpuExceptionHandlerLib.inf | |
+ | |
+[LibraryClasses.common.PEI_CORE] | |
+ HobLib|MdePkg/Library/PeiHobLib/PeiHobLib.inf | |
+ PeiServicesTablePointerLib|MdePkg/Library/PeiServicesTablePointerLibIdt/PeiServicesTablePointerLibIdt.inf | |
+ PeiServicesLib|MdePkg/Library/PeiServicesLib/PeiServicesLib.inf | |
+ MemoryAllocationLib|MdePkg/Library/PeiMemoryAllocationLib/PeiMemoryAllocationLib.inf | |
+ PeiCoreEntryPoint|MdePkg/Library/PeiCoreEntryPoint/PeiCoreEntryPoint.inf | |
+ ReportStatusCodeLib|MdeModulePkg/Library/PeiReportStatusCodeLib/PeiReportStatusCodeLib.inf | |
+ OemHookStatusCodeLib|MdeModulePkg/Library/OemHookStatusCodeLibNull/OemHookStatusCodeLibNull.inf | |
+ PeCoffGetEntryPointLib|MdePkg/Library/BasePeCoffGetEntryPointLib/BasePeCoffGetEntryPointLib.inf | |
+!ifdef $(DEBUG_ON_SERIAL_PORT) | |
+ DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf | |
+!else | |
+ DebugLib|OvmfPkg/Library/PlatformDebugLibIoPort/PlatformDebugLibIoPort.inf | |
+!endif | |
+ PeCoffLib|MdePkg/Library/BasePeCoffLib/BasePeCoffLib.inf | |
+ | |
+[LibraryClasses.common.PEIM] | |
+ HobLib|MdePkg/Library/PeiHobLib/PeiHobLib.inf | |
+ PeiServicesTablePointerLib|MdePkg/Library/PeiServicesTablePointerLibIdt/PeiServicesTablePointerLibIdt.inf | |
+ PeiServicesLib|MdePkg/Library/PeiServicesLib/PeiServicesLib.inf | |
+ MemoryAllocationLib|MdePkg/Library/PeiMemoryAllocationLib/PeiMemoryAllocationLib.inf | |
+ PeimEntryPoint|MdePkg/Library/PeimEntryPoint/PeimEntryPoint.inf | |
+ ReportStatusCodeLib|MdeModulePkg/Library/PeiReportStatusCodeLib/PeiReportStatusCodeLib.inf | |
+ OemHookStatusCodeLib|MdeModulePkg/Library/OemHookStatusCodeLibNull/OemHookStatusCodeLibNull.inf | |
+ PeCoffGetEntryPointLib|MdePkg/Library/BasePeCoffGetEntryPointLib/BasePeCoffGetEntryPointLib.inf | |
+!ifdef $(DEBUG_ON_SERIAL_PORT) | |
+ DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf | |
+!else | |
+ DebugLib|OvmfPkg/Library/PlatformDebugLibIoPort/PlatformDebugLibIoPort.inf | |
+!endif | |
+ PeCoffLib|MdePkg/Library/BasePeCoffLib/BasePeCoffLib.inf | |
+ PeiResourcePublicationLib|MdePkg/Library/PeiResourcePublicationLib/PeiResourcePublicationLib.inf | |
+ ExtractGuidedSectionLib|MdePkg/Library/PeiExtractGuidedSectionLib/PeiExtractGuidedSectionLib.inf | |
+!ifdef $(SOURCE_DEBUG_ENABLE) | |
+ DebugAgentLib|SourceLevelDebugPkg/Library/DebugAgent/SecPeiDebugAgentLib.inf | |
+!endif | |
+ CpuExceptionHandlerLib|UefiCpuPkg/Library/CpuExceptionHandlerLib/PeiCpuExceptionHandlerLib.inf | |
+ | |
+[LibraryClasses.common.DXE_CORE] | |
+ HobLib|MdePkg/Library/DxeCoreHobLib/DxeCoreHobLib.inf | |
+ DxeCoreEntryPoint|MdePkg/Library/DxeCoreEntryPoint/DxeCoreEntryPoint.inf | |
+ MemoryAllocationLib|MdeModulePkg/Library/DxeCoreMemoryAllocationLib/DxeCoreMemoryAllocationLib.inf | |
+ ReportStatusCodeLib|MdeModulePkg/Library/DxeReportStatusCodeLib/DxeReportStatusCodeLib.inf | |
+!ifdef $(DEBUG_ON_SERIAL_PORT) | |
+ DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf | |
+!else | |
+ DebugLib|OvmfPkg/Library/PlatformDebugLibIoPort/PlatformDebugLibIoPort.inf | |
+!endif | |
+ ExtractGuidedSectionLib|MdePkg/Library/DxeExtractGuidedSectionLib/DxeExtractGuidedSectionLib.inf | |
+!ifdef $(SOURCE_DEBUG_ENABLE) | |
+ DebugAgentLib|SourceLevelDebugPkg/Library/DebugAgent/DxeDebugAgentLib.inf | |
+!endif | |
+ CpuExceptionHandlerLib|UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeCpuExceptionHandlerLib.inf | |
+ PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf | |
+ | |
+[LibraryClasses.common.DXE_RUNTIME_DRIVER] | |
+ PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf | |
+ TimerLib|OvmfPkg/Library/AcpiTimerLib/DxeAcpiTimerLib.inf | |
+ HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf | |
+ DxeCoreEntryPoint|MdePkg/Library/DxeCoreEntryPoint/DxeCoreEntryPoint.inf | |
+ MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf | |
+ ReportStatusCodeLib|MdeModulePkg/Library/RuntimeDxeReportStatusCodeLib/RuntimeDxeReportStatusCodeLib.inf | |
+!ifdef $(DEBUG_ON_SERIAL_PORT) | |
+ DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf | |
+!else | |
+ DebugLib|OvmfPkg/Library/PlatformDebugLibIoPort/PlatformDebugLibIoPort.inf | |
+!endif | |
+ UefiRuntimeLib|MdePkg/Library/UefiRuntimeLib/UefiRuntimeLib.inf | |
+!if $(SECURE_BOOT_ENABLE) == TRUE | |
+ BaseCryptLib|CryptoPkg/Library/BaseCryptLib/RuntimeCryptLib.inf | |
+!endif | |
+ PciLib|OvmfPkg/Library/DxePciLibI440FxQ35/DxePciLibI440FxQ35.inf | |
+ | |
+[LibraryClasses.common.UEFI_DRIVER] | |
+ PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf | |
+ TimerLib|OvmfPkg/Library/AcpiTimerLib/DxeAcpiTimerLib.inf | |
+ HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf | |
+ DxeCoreEntryPoint|MdePkg/Library/DxeCoreEntryPoint/DxeCoreEntryPoint.inf | |
+ MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf | |
+ ReportStatusCodeLib|MdeModulePkg/Library/DxeReportStatusCodeLib/DxeReportStatusCodeLib.inf | |
+!ifdef $(DEBUG_ON_SERIAL_PORT) | |
+ DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf | |
+!else | |
+ DebugLib|OvmfPkg/Library/PlatformDebugLibIoPort/PlatformDebugLibIoPort.inf | |
+!endif | |
+ UefiScsiLib|MdePkg/Library/UefiScsiLib/UefiScsiLib.inf | |
+ PciLib|OvmfPkg/Library/DxePciLibI440FxQ35/DxePciLibI440FxQ35.inf | |
+ | |
+[LibraryClasses.common.DXE_DRIVER] | |
+ PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf | |
+ TimerLib|OvmfPkg/Library/AcpiTimerLib/DxeAcpiTimerLib.inf | |
+ HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf | |
+ MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf | |
+ ReportStatusCodeLib|MdeModulePkg/Library/DxeReportStatusCodeLib/DxeReportStatusCodeLib.inf | |
+ UefiScsiLib|MdePkg/Library/UefiScsiLib/UefiScsiLib.inf | |
+!ifdef $(DEBUG_ON_SERIAL_PORT) | |
+ DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf | |
+!else | |
+ DebugLib|OvmfPkg/Library/PlatformDebugLibIoPort/PlatformDebugLibIoPort.inf | |
+!endif | |
+ NetLib|MdeModulePkg/Library/DxeNetLib/DxeNetLib.inf | |
+ IpIoLib|MdeModulePkg/Library/DxeIpIoLib/DxeIpIoLib.inf | |
+ UdpIoLib|MdeModulePkg/Library/DxeUdpIoLib/DxeUdpIoLib.inf | |
+ DpcLib|MdeModulePkg/Library/DxeDpcLib/DxeDpcLib.inf | |
+ PlatformBootManagerLib|OvmfPkg/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf | |
+ QemuBootOrderLib|OvmfPkg/Library/QemuBootOrderLib/QemuBootOrderLib.inf | |
+ CpuExceptionHandlerLib|UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeCpuExceptionHandlerLib.inf | |
+!if $(SMM_REQUIRE) == TRUE | |
+ LockBoxLib|MdeModulePkg/Library/SmmLockBoxLib/SmmLockBoxDxeLib.inf | |
+!else | |
+ LockBoxLib|OvmfPkg/Library/LockBoxLib/LockBoxDxeLib.inf | |
+!endif | |
+!ifdef $(SOURCE_DEBUG_ENABLE) | |
+ DebugAgentLib|SourceLevelDebugPkg/Library/DebugAgent/DxeDebugAgentLib.inf | |
+!endif | |
+ PciLib|OvmfPkg/Library/DxePciLibI440FxQ35/DxePciLibI440FxQ35.inf | |
+ | |
+[LibraryClasses.common.UEFI_APPLICATION] | |
+ PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf | |
+ TimerLib|OvmfPkg/Library/AcpiTimerLib/DxeAcpiTimerLib.inf | |
+ HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf | |
+ MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf | |
+ ReportStatusCodeLib|MdeModulePkg/Library/DxeReportStatusCodeLib/DxeReportStatusCodeLib.inf | |
+!ifdef $(DEBUG_ON_SERIAL_PORT) | |
+ DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf | |
+!else | |
+ DebugLib|OvmfPkg/Library/PlatformDebugLibIoPort/PlatformDebugLibIoPort.inf | |
+!endif | |
+ PciLib|OvmfPkg/Library/DxePciLibI440FxQ35/DxePciLibI440FxQ35.inf | |
+ | |
+[LibraryClasses.common.DXE_SMM_DRIVER] | |
+ PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf | |
+ TimerLib|OvmfPkg/Library/AcpiTimerLib/DxeAcpiTimerLib.inf | |
+ MemoryAllocationLib|MdePkg/Library/SmmMemoryAllocationLib/SmmMemoryAllocationLib.inf | |
+ ReportStatusCodeLib|MdeModulePkg/Library/DxeReportStatusCodeLib/DxeReportStatusCodeLib.inf | |
+ HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf | |
+ SmmMemLib|MdePkg/Library/SmmMemLib/SmmMemLib.inf | |
+ SmmServicesTableLib|MdePkg/Library/SmmServicesTableLib/SmmServicesTableLib.inf | |
+!ifdef $(DEBUG_ON_SERIAL_PORT) | |
+ DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf | |
+!else | |
+ DebugLib|OvmfPkg/Library/PlatformDebugLibIoPort/PlatformDebugLibIoPort.inf | |
+!endif | |
+ CpuExceptionHandlerLib|UefiCpuPkg/Library/CpuExceptionHandlerLib/SmmCpuExceptionHandlerLib.inf | |
+!ifdef $(SOURCE_DEBUG_ENABLE) | |
+ DebugAgentLib|SourceLevelDebugPkg/Library/DebugAgent/SmmDebugAgentLib.inf | |
+!endif | |
+ BaseCryptLib|CryptoPkg/Library/BaseCryptLib/SmmCryptLib.inf | |
+ PciLib|OvmfPkg/Library/DxePciLibI440FxQ35/DxePciLibI440FxQ35.inf | |
+ | |
+[LibraryClasses.common.SMM_CORE] | |
+ PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf | |
+ TimerLib|OvmfPkg/Library/AcpiTimerLib/DxeAcpiTimerLib.inf | |
+ SmmCorePlatformHookLib|MdeModulePkg/Library/SmmCorePlatformHookLibNull/SmmCorePlatformHookLibNull.inf | |
+ MemoryAllocationLib|MdeModulePkg/Library/PiSmmCoreMemoryAllocationLib/PiSmmCoreMemoryAllocationLib.inf | |
+ ReportStatusCodeLib|MdeModulePkg/Library/DxeReportStatusCodeLib/DxeReportStatusCodeLib.inf | |
+ HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf | |
+ SmmMemLib|MdePkg/Library/SmmMemLib/SmmMemLib.inf | |
+ SmmServicesTableLib|MdeModulePkg/Library/PiSmmCoreSmmServicesTableLib/PiSmmCoreSmmServicesTableLib.inf | |
+!ifdef $(DEBUG_ON_SERIAL_PORT) | |
+ DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf | |
+!else | |
+ DebugLib|OvmfPkg/Library/PlatformDebugLibIoPort/PlatformDebugLibIoPort.inf | |
+!endif | |
+ PciLib|OvmfPkg/Library/DxePciLibI440FxQ35/DxePciLibI440FxQ35.inf | |
+ | |
+################################################################################ | |
+# | |
+# Pcd Section - list of all EDK II PCD Entries defined by this Platform. | |
+# | |
+################################################################################ | |
+[PcdsFeatureFlag] | |
+ gEfiMdeModulePkgTokenSpaceGuid.PcdHiiOsRuntimeSupport|FALSE | |
+ gEfiMdeModulePkgTokenSpaceGuid.PcdStatusCodeUseSerial|FALSE | |
+ gEfiMdeModulePkgTokenSpaceGuid.PcdStatusCodeUseMemory|TRUE | |
+ gEfiMdeModulePkgTokenSpaceGuid.PcdDxeIplSupportUefiDecompress|FALSE | |
+ gEfiMdeModulePkgTokenSpaceGuid.PcdDxeIplSwitchToLongMode|FALSE | |
+ gEfiMdeModulePkgTokenSpaceGuid.PcdConOutGopSupport|TRUE | |
+ gEfiMdeModulePkgTokenSpaceGuid.PcdConOutUgaSupport|FALSE | |
+ gEfiMdeModulePkgTokenSpaceGuid.PcdInstallAcpiSdtProtocol|TRUE | |
+!if $(SECURE_BOOT_ENABLE) == TRUE | |
+ gUefiOvmfPkgTokenSpaceGuid.PcdSecureBootEnable|TRUE | |
+!endif | |
+!if $(SMM_REQUIRE) == TRUE | |
+ gUefiOvmfPkgTokenSpaceGuid.PcdSmmSmramRequire|TRUE | |
+ gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmEnableBspElection|FALSE | |
+!endif | |
+ | |
+[PcdsFixedAtBuild] | |
+ gEfiMdeModulePkgTokenSpaceGuid.PcdStatusCodeMemorySize|1 | |
+ gEfiMdeModulePkgTokenSpaceGuid.PcdResetOnMemoryTypeInformationChange|FALSE | |
+ gEfiMdePkgTokenSpaceGuid.PcdMaximumGuidedExtractHandler|0x10 | |
+ gEfiMdeModulePkgTokenSpaceGuid.PcdPeiCoreMaxFvSupported|6 | |
+ gEfiMdeModulePkgTokenSpaceGuid.PcdPeiCoreMaxPeimPerFv|32 | |
+ gEfiMdeModulePkgTokenSpaceGuid.PcdMaxVariableSize|0x2000 | |
+ gEfiMdeModulePkgTokenSpaceGuid.PcdMaxAuthVariableSize|0x2800 | |
+ gEfiMdeModulePkgTokenSpaceGuid.PcdVariableStoreSize|0xe000 | |
+ | |
+ gEfiMdeModulePkgTokenSpaceGuid.PcdVpdBaseAddress|0x0 | |
+# gEfiMdeModulePkgTokenSpaceGuid.PcdSmbiosVersion|0x0208 | |
+ | |
+ gEfiMdePkgTokenSpaceGuid.PcdReportStatusCodePropertyMask|0x07 | |
+ | |
+ # DEBUG_INIT 0x00000001 // Initialization | |
+ # DEBUG_WARN 0x00000002 // Warnings | |
+ # DEBUG_LOAD 0x00000004 // Load events | |
+ # DEBUG_FS 0x00000008 // EFI File system | |
+ # DEBUG_POOL 0x00000010 // Alloc & Free (pool) | |
+ # DEBUG_PAGE 0x00000020 // Alloc & Free (page) | |
+ # DEBUG_INFO 0x00000040 // Informational debug messages | |
+ # DEBUG_DISPATCH 0x00000080 // PEI/DXE/SMM Dispatchers | |
+ # DEBUG_VARIABLE 0x00000100 // Variable | |
+ # DEBUG_BM 0x00000400 // Boot Manager | |
+ # DEBUG_BLKIO 0x00001000 // BlkIo Driver | |
+ # DEBUG_NET 0x00004000 // SNP Driver | |
+ # DEBUG_UNDI 0x00010000 // UNDI Driver | |
+ # DEBUG_LOADFILE 0x00020000 // LoadFile | |
+ # DEBUG_EVENT 0x00080000 // Event messages | |
+ # DEBUG_GCD 0x00100000 // Global Coherency Database changes | |
+ # DEBUG_CACHE 0x00200000 // Memory range cachability changes | |
+ # DEBUG_VERBOSE 0x00400000 // Detailed debug messages that may | |
+ # // significantly impact boot performance | |
+ # DEBUG_ERROR 0x80000000 // Error | |
+ gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0x8000004F | |
+ | |
+!ifdef $(SOURCE_DEBUG_ENABLE) | |
+ gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0x17 | |
+!else | |
+ gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0x2F | |
+!endif | |
+ | |
+ # This PCD is used to set the base address of the PCI express hierarchy. It | |
+ # is only consulted when OVMF runs on Q35. In that case it is programmed into | |
+ # the PCIEXBAR register. | |
+ # | |
+ # On Q35 machine types that QEMU intends to support in the long term, QEMU | |
+ # never lets the RAM below 4 GB exceed 2 GB. | |
+ gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress|0x80000000 | |
+ | |
+!ifdef $(SOURCE_DEBUG_ENABLE) | |
+ gEfiSourceLevelDebugPkgTokenSpaceGuid.PcdDebugLoadImageMethod|0x2 | |
+!endif | |
+ | |
+!ifndef $(USE_OLD_SHELL) | |
+ gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdShellFile|{ 0x83, 0xA5, 0x04, 0x7C, 0x3E, 0x9E, 0x1C, 0x4F, 0xAD, 0x65, 0xE0, 0x52, 0x68, 0xD0, 0xB4, 0xD1 } | |
+!endif | |
+ | |
+!if $(SMM_REQUIRE) == TRUE | |
+ gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmSyncMode|0x01 | |
+ gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmApSyncTimeout|100000 | |
+ gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmStackSize|0x4000 | |
+!endif | |
+ | |
+!if $(SECURE_BOOT_ENABLE) == TRUE | |
+ gEfiSecurityPkgTokenSpaceGuid.PcdOptionRomImageVerificationPolicy|0x00 | |
+!endif | |
+ | |
+ # IRQs 5, 9, 10, 11 are level-triggered | |
+ gPcAtChipsetPkgTokenSpaceGuid.Pcd8259LegacyModeEdgeLevel|0x0E20 | |
+ | |
+ # Point to the MdeModulePkg/Application/UiApp/UiApp.inf | |
+ gEfiMdeModulePkgTokenSpaceGuid.PcdBootManagerMenuFile|{ 0x21, 0xaa, 0x2c, 0x46, 0x14, 0x76, 0x03, 0x45, 0x83, 0x6e, 0x8a, 0xb6, 0xf4, 0x66, 0x23, 0x31 } | |
+ | |
+################################################################################ | |
+# | |
+# Pcd Dynamic Section - list of all EDK II PCD Entries defined by this Platform | |
+# | |
+################################################################################ | |
+ | |
+[PcdsDynamicDefault] | |
+ gEfiMdeModulePkgTokenSpaceGuid.PcdEmuVariableNvStoreReserved|0 | |
+ gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase64|0 | |
+ gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingBase|0 | |
+ gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareBase|0 | |
+ gEfiMdeModulePkgTokenSpaceGuid.PcdPciDisableBusEnumeration|FALSE | |
+ gEfiMdeModulePkgTokenSpaceGuid.PcdVideoHorizontalResolution|1024 | |
+ gEfiMdeModulePkgTokenSpaceGuid.PcdVideoVerticalResolution|768 | |
+ gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiS3Enable|FALSE | |
+ gUefiOvmfPkgTokenSpaceGuid.PcdOvmfHostBridgePciDevId|0 | |
+ gUefiOvmfPkgTokenSpaceGuid.PcdPciIoBase|0x0 | |
+ gUefiOvmfPkgTokenSpaceGuid.PcdPciIoSize|0x0 | |
+ gUefiOvmfPkgTokenSpaceGuid.PcdPciMmio32Base|0x0 | |
+ gUefiOvmfPkgTokenSpaceGuid.PcdPciMmio32Size|0x0 | |
+ gUefiOvmfPkgTokenSpaceGuid.PcdPciMmio64Base|0x0 | |
+ gUefiOvmfPkgTokenSpaceGuid.PcdPciMmio64Size|0x800000000 | |
+ | |
+ gEfiMdePkgTokenSpaceGuid.PcdPlatformBootTimeOut|0 | |
+ | |
+ # Set video resolution for text setup. | |
+ gEfiMdeModulePkgTokenSpaceGuid.PcdSetupVideoHorizontalResolution|0 | |
+ gEfiMdeModulePkgTokenSpaceGuid.PcdSetupVideoVerticalResolution|0 | |
+ | |
+ gEfiMdeModulePkgTokenSpaceGuid.PcdSmbiosVersion|0x0204 | |
+ gEfiMdeModulePkgTokenSpaceGuid.PcdSmbiosDocRev|0x0 | |
+ gUefiOvmfPkgTokenSpaceGuid.PcdQemuSmbiosValidated|TRUE | |
+ | |
+ # Noexec settings for DXE. | |
+ gEfiMdeModulePkgTokenSpaceGuid.PcdSetNxForStack|FALSE | |
+ gEfiMdeModulePkgTokenSpaceGuid.PcdPropertiesTableEnable|FALSE | |
+ | |
+################################################################################ | |
+# | |
+# Components Section - list of all EDK II Modules needed by this Platform. | |
+# | |
+################################################################################ | |
+[Components] | |
+ OvmfPkg/ResetVector/ResetVector.inf | |
+ | |
+ # | |
+ # SEC Phase modules | |
+ # | |
+ OvmfPkg/Sec/SecMain.inf { | |
+ <LibraryClasses> | |
+ NULL|IntelFrameworkModulePkg/Library/LzmaCustomDecompressLib/LzmaCustomDecompressLib.inf | |
+ } | |
+ | |
+ # | |
+ # PEI Phase modules | |
+ # | |
+ MdeModulePkg/Core/Pei/PeiMain.inf | |
+ MdeModulePkg/Universal/PCD/Pei/Pcd.inf { | |
+ <LibraryClasses> | |
+ PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf | |
+ } | |
+ IntelFrameworkModulePkg/Universal/StatusCode/Pei/StatusCodePei.inf | |
+ MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf { | |
+ <LibraryClasses> | |
+ PcdLib|MdePkg/Library/PeiPcdLib/PeiPcdLib.inf | |
+ } | |
+ | |
+ OvmfPkg/PlatformPei/PlatformPei.inf { | |
+ <LibraryClasses> | |
+ PcdLib|MdePkg/Library/PeiPcdLib/PeiPcdLib.inf | |
+ } | |
+ UefiCpuPkg/Universal/Acpi/S3Resume2Pei/S3Resume2Pei.inf { | |
+ <LibraryClasses> | |
+ PcdLib|MdePkg/Library/PeiPcdLib/PeiPcdLib.inf | |
+!if $(SMM_REQUIRE) == TRUE | |
+ LockBoxLib|MdeModulePkg/Library/SmmLockBoxLib/SmmLockBoxPeiLib.inf | |
+!endif | |
+ } | |
+!if $(SMM_REQUIRE) == TRUE | |
+ OvmfPkg/SmmAccess/SmmAccessPei.inf { | |
+ <LibraryClasses> | |
+ PcdLib|MdePkg/Library/PeiPcdLib/PeiPcdLib.inf | |
+ } | |
+!endif | |
+# UefiCpuPkg/CpuMpPei/CpuMpPei.inf { | |
+# <LibraryClasses> | |
+# PcdLib|MdePkg/Library/PeiPcdLib/PeiPcdLib.inf | |
+# } | |
+ | |
+ # | |
+ # DXE Phase modules | |
+ # | |
+ MdeModulePkg/Core/Dxe/DxeMain.inf { | |
+ <LibraryClasses> | |
+ NULL|IntelFrameworkModulePkg/Library/LzmaCustomDecompressLib/LzmaCustomDecompressLib.inf | |
+ DevicePathLib|MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.inf | |
+ } | |
+ | |
+ IntelFrameworkModulePkg/Universal/StatusCode/RuntimeDxe/StatusCodeRuntimeDxe.inf | |
+ MdeModulePkg/Universal/PCD/Dxe/Pcd.inf { | |
+ <LibraryClasses> | |
+ PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf | |
+ } | |
+ | |
+ MdeModulePkg/Core/RuntimeDxe/RuntimeDxe.inf | |
+ | |
+!if $(SECURE_BOOT_ENABLE) == TRUE | |
+ MdeModulePkg/Universal/SecurityStubDxe/SecurityStubDxe.inf { | |
+ <LibraryClasses> | |
+ NULL|SecurityPkg/Library/DxeImageVerificationLib/DxeImageVerificationLib.inf | |
+ } | |
+!else | |
+ MdeModulePkg/Universal/SecurityStubDxe/SecurityStubDxe.inf | |
+!endif | |
+ | |
+ MdeModulePkg/Universal/EbcDxe/EbcDxe.inf | |
+ PcAtChipsetPkg/8259InterruptControllerDxe/8259.inf | |
+ UefiCpuPkg/CpuIo2Dxe/CpuIo2Dxe.inf | |
+ #Clover/UefiCpuPkg/CpuIo2Dxe/CpuIo2Dxe.inf | |
+ UefiCpuPkg/CpuDxe/CpuDxe.inf | |
+# Clover/UefiCpuPkg/CpuDxe/CpuDxe.inf | |
+# Clover/CpuDxe/Cpu.inf | |
+ PcAtChipsetPkg/8254TimerDxe/8254Timer.inf | |
+ OvmfPkg/IncompatiblePciDeviceSupportDxe/IncompatiblePciDeviceSupport.inf | |
+ OvmfPkg/PciHotPlugInitDxe/PciHotPlugInit.inf | |
+ MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostBridgeDxe.inf { | |
+ <LibraryClasses> | |
+ PciHostBridgeLib|OvmfPkg/Library/PciHostBridgeLib/PciHostBridgeLib.inf | |
+ } | |
+ MdeModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.inf { | |
+ <LibraryClasses> | |
+ PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf | |
+ } | |
+ PcAtChipsetPkg/KbcResetDxe/Reset.inf | |
+ MdeModulePkg/Universal/Metronome/Metronome.inf | |
+ PcAtChipsetPkg/PcatRealTimeClockRuntimeDxe/PcatRealTimeClockRuntimeDxe.inf | |
+ MdeModulePkg/Universal/DriverHealthManagerDxe/DriverHealthManagerDxe.inf | |
+ MdeModulePkg/Universal/BdsDxe/BdsDxe.inf { | |
+ <LibraryClasses> | |
+ NULL|MdeModulePkg/Library/BmpImageDecoderLib/BmpImageDecoderLib.inf | |
+!ifdef $(CSM_ENABLE) | |
+ NULL|OvmfPkg/Csm/CsmSupportLib/CsmSupportLib.inf | |
+ NULL|IntelFrameworkModulePkg/Library/LegacyBootManagerLib/LegacyBootManagerLib.inf | |
+!endif | |
+ } | |
+ MdeModulePkg/Application/UiApp/UiApp.inf { | |
+ <LibraryClasses> | |
+ NULL|MdeModulePkg/Library/DeviceManagerUiLib/DeviceManagerUiLib.inf | |
+ NULL|MdeModulePkg/Library/BootManagerUiLib/BootManagerUiLib.inf | |
+ NULL|MdeModulePkg/Library/BootMaintenanceManagerUiLib/BootMaintenanceManagerUiLib.inf | |
+!ifdef $(CSM_ENABLE) | |
+ NULL|IntelFrameworkModulePkg/Library/LegacyBootManagerLib/LegacyBootManagerLib.inf | |
+ NULL|IntelFrameworkModulePkg/Library/LegacyBootMaintUiLib/LegacyBootMaintUiLib.inf | |
+!endif | |
+ } | |
+ | |
+ OvmfPkg/BlockMmioToBlockIoDxe/BlockIo.inf | |
+ OvmfPkg/VirtioPciDeviceDxe/VirtioPciDeviceDxe.inf | |
+ OvmfPkg/Virtio10Dxe/Virtio10.inf | |
+ OvmfPkg/VirtioBlkDxe/VirtioBlk.inf | |
+ OvmfPkg/VirtioScsiDxe/VirtioScsi.inf | |
+ OvmfPkg/VirtioRngDxe/VirtioRng.inf | |
+ OvmfPkg/XenIoPciDxe/XenIoPciDxe.inf | |
+ OvmfPkg/XenBusDxe/XenBusDxe.inf | |
+ OvmfPkg/XenPvBlkDxe/XenPvBlkDxe.inf | |
+ MdeModulePkg/Universal/WatchdogTimerDxe/WatchdogTimer.inf | |
+ MdeModulePkg/Universal/MonotonicCounterRuntimeDxe/MonotonicCounterRuntimeDxe.inf | |
+ MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleRuntimeDxe.inf | |
+ MdeModulePkg/Universal/Console/ConPlatformDxe/ConPlatformDxe.inf | |
+ MdeModulePkg/Universal/Console/ConSplitterDxe/ConSplitterDxe.inf { | |
+ <PcdsPatchableInModule> | |
+ gEfiMdeModulePkgTokenSpaceGuid.PcdConOutRow|0 | |
+ gEfiMdeModulePkgTokenSpaceGuid.PcdConOutColumn|0 | |
+ } | |
+ MdeModulePkg/Universal/Console/GraphicsConsoleDxe/GraphicsConsoleDxe.inf { | |
+ <LibraryClasses> | |
+ PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf | |
+ } | |
+ MdeModulePkg/Universal/Console/TerminalDxe/TerminalDxe.inf | |
+ MdeModulePkg/Universal/DevicePathDxe/DevicePathDxe.inf { | |
+ <LibraryClasses> | |
+ DevicePathLib|MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.inf | |
+ PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf | |
+ } | |
+ MdeModulePkg/Universal/PrintDxe/PrintDxe.inf | |
+ MdeModulePkg/Universal/Disk/DiskIoDxe/DiskIoDxe.inf | |
+ MdeModulePkg/Universal/Disk/PartitionDxe/PartitionDxe.inf | |
+ #Clover/PartitionDxe/PartitionDxe.inf | |
+ MdeModulePkg/Universal/Disk/RamDiskDxe/RamDiskDxe.inf | |
+ MdeModulePkg/Universal/Disk/UnicodeCollation/EnglishDxe/EnglishDxe.inf | |
+# FatPkg/EnhancedFatDxe/Fat.inf | |
+ MdeModulePkg/Bus/Scsi/ScsiBusDxe/ScsiBusDxe.inf | |
+ MdeModulePkg/Bus/Scsi/ScsiDiskDxe/ScsiDiskDxe.inf | |
+ OvmfPkg/SataControllerDxe/SataControllerDxe.inf | |
+ MdeModulePkg/Bus/Ata/AtaAtapiPassThru/AtaAtapiPassThru.inf | |
+ MdeModulePkg/Bus/Ata/AtaBusDxe/AtaBusDxe.inf | |
+# MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpressDxe.inf | |
+ MdeModulePkg/Universal/HiiDatabaseDxe/HiiDatabaseDxe.inf | |
+ MdeModulePkg/Universal/SetupBrowserDxe/SetupBrowserDxe.inf | |
+ MdeModulePkg/Universal/DisplayEngineDxe/DisplayEngineDxe.inf | |
+ MdeModulePkg/Universal/MemoryTest/NullMemoryTestDxe/NullMemoryTestDxe.inf | |
+ | |
+ OvmfPkg/QemuVideoDxe/QemuVideoDxe.inf { | |
+ <LibraryClasses> | |
+ BltLib|OptionRomPkg/Library/FrameBufferBltLib/FrameBufferBltLib.inf | |
+ } | |
+ | |
+ # | |
+ # Clover | |
+ # | |
+ IntelFrameworkModulePkg/Universal/DataHubDxe/DataHubDxe.inf | |
+ #Clover/VBoxFsDxe/VBoxHfs.inf | |
+ #Clover/VBoxFsDxe/VBoxIso9660.inf | |
+ #Clover/VBoxFsDxe/VBoxFsDxe.inf | |
+ #Clover/VBoxFsDxe/VBoxExt2.inf | |
+ #Clover/VBoxFsDxe/VBoxExt4.inf | |
+ #Clover/MsgLog/MsgLog.inf | |
+ | |
+ # | |
+ # ISA Support | |
+ # | |
+ PcAtChipsetPkg/IsaAcpiDxe/IsaAcpi.inf | |
+ IntelFrameworkModulePkg/Bus/Isa/IsaBusDxe/IsaBusDxe.inf | |
+ IntelFrameworkModulePkg/Bus/Isa/IsaSerialDxe/IsaSerialDxe.inf | |
+ IntelFrameworkModulePkg/Bus/Isa/Ps2KeyboardDxe/Ps2keyboardDxe.inf | |
+ IntelFrameworkModulePkg/Bus/Isa/IsaFloppyDxe/IsaFloppyDxe.inf | |
+ #IntelFrameworkModulePkg/Bus/Isa/Ps2MouseDxe/Ps2MouseDxe.inf | |
+ #Clover/Ps2MouseDxe/Ps2MouseDxe.inf | |
+ | |
+ # | |
+ # SMBIOS Support | |
+ # | |
+ MdeModulePkg/Universal/SmbiosDxe/SmbiosDxe.inf | |
+# { | |
+# <LibraryClasses> | |
+# NULL|OvmfPkg/Library/SmbiosVersionLib/DetectSmbiosVersionLib.inf | |
+# } | |
+ OvmfPkg/QemuSmbiosPlatformDxe/SmbiosPlatformDxe.inf | |
+# DuetPkg/SmbiosGenDxe/SmbiosGen.inf | |
+ | |
+ # | |
+ # ACPI Support | |
+ # | |
+ MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableDxe.inf | |
+ OvmfPkg/AcpiPlatformDxe/AcpiPlatformDxe.inf | |
+ OvmfPkg/AcpiTables/AcpiTables.inf | |
+# MdeModulePkg/Universal/Acpi/S3SaveStateDxe/S3SaveStateDxe.inf | |
+# MdeModulePkg/Universal/Acpi/BootScriptExecutorDxe/BootScriptExecutorDxe.inf | |
+ | |
+ # | |
+ # Network Support | |
+ # | |
+ MdeModulePkg/Universal/Network/SnpDxe/SnpDxe.inf | |
+ MdeModulePkg/Universal/Network/DpcDxe/DpcDxe.inf | |
+ MdeModulePkg/Universal/Network/MnpDxe/MnpDxe.inf | |
+ MdeModulePkg/Universal/Network/VlanConfigDxe/VlanConfigDxe.inf | |
+ MdeModulePkg/Universal/Network/ArpDxe/ArpDxe.inf | |
+ MdeModulePkg/Universal/Network/Dhcp4Dxe/Dhcp4Dxe.inf | |
+ MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Dxe.inf | |
+ MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Dxe.inf | |
+ MdeModulePkg/Universal/Network/Udp4Dxe/Udp4Dxe.inf | |
+!if $(NETWORK_IP6_ENABLE) == TRUE | |
+ NetworkPkg/Ip6Dxe/Ip6Dxe.inf | |
+ NetworkPkg/TcpDxe/TcpDxe.inf | |
+ NetworkPkg/Udp6Dxe/Udp6Dxe.inf | |
+ NetworkPkg/Dhcp6Dxe/Dhcp6Dxe.inf | |
+ NetworkPkg/Mtftp6Dxe/Mtftp6Dxe.inf | |
+ NetworkPkg/UefiPxeBcDxe/UefiPxeBcDxe.inf | |
+!if $(SECURE_BOOT_ENABLE) == TRUE | |
+ NetworkPkg/IScsiDxe/IScsiDxe.inf | |
+!else | |
+ MdeModulePkg/Universal/Network/IScsiDxe/IScsiDxe.inf | |
+!endif | |
+!else | |
+ MdeModulePkg/Universal/Network/Tcp4Dxe/Tcp4Dxe.inf | |
+ MdeModulePkg/Universal/Network/UefiPxeBcDxe/UefiPxeBcDxe.inf | |
+ MdeModulePkg/Universal/Network/IScsiDxe/IScsiDxe.inf | |
+!endif | |
+!if $(HTTP_BOOT_ENABLE) == TRUE | |
+ NetworkPkg/DnsDxe/DnsDxe.inf | |
+ NetworkPkg/HttpUtilitiesDxe/HttpUtilitiesDxe.inf | |
+ NetworkPkg/HttpDxe/HttpDxe.inf | |
+ NetworkPkg/HttpBootDxe/HttpBootDxe.inf | |
+!endif | |
+ OvmfPkg/VirtioNetDxe/VirtioNet.inf | |
+ | |
+ # | |
+ # Usb Support | |
+ # | |
+ MdeModulePkg/Bus/Pci/UhciDxe/UhciDxe.inf | |
+ MdeModulePkg/Bus/Pci/EhciDxe/EhciDxe.inf | |
+# MdeModulePkg/Bus/Pci/XhciDxe/XhciDxe.inf | |
+ MdeModulePkg/Bus/Usb/UsbBusDxe/UsbBusDxe.inf | |
+ MdeModulePkg/Bus/Usb/UsbKbDxe/UsbKbDxe.inf | |
+ MdeModulePkg/Bus/Usb/UsbMassStorageDxe/UsbMassStorageDxe.inf | |
+ MdeModulePkg/Bus/Usb/UsbMouseDxe/UsbMouseDxe.inf | |
+ | |
+!ifdef $(CSM_ENABLE) | |
+ IntelFrameworkModulePkg/Csm/BiosThunk/VideoDxe/VideoDxe.inf { | |
+ #OvmfPkg/Csm/VideoDxe/VideoDxe.inf { | |
+ <LibraryClasses> | |
+ PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf | |
+ } | |
+ IntelFrameworkModulePkg/Csm/LegacyBiosDxe/LegacyBiosDxe.inf | |
+ #OvmfPkg/Csm/LegacyBiosDxe/LegacyBiosDxe.inf | |
+ OvmfPkg/Csm/Csm16/Csm16.inf | |
+!endif | |
+ | |
+!ifndef $(USE_OLD_SHELL) | |
+ ShellPkg/Application/Shell/Shell.inf { | |
+ <LibraryClasses> | |
+ ShellCommandLib|ShellPkg/Library/UefiShellCommandLib/UefiShellCommandLib.inf | |
+ NULL|ShellPkg/Library/UefiShellLevel2CommandsLib/UefiShellLevel2CommandsLib.inf | |
+ NULL|ShellPkg/Library/UefiShellLevel1CommandsLib/UefiShellLevel1CommandsLib.inf | |
+ NULL|ShellPkg/Library/UefiShellLevel3CommandsLib/UefiShellLevel3CommandsLib.inf | |
+ NULL|ShellPkg/Library/UefiShellDriver1CommandsLib/UefiShellDriver1CommandsLib.inf | |
+ NULL|ShellPkg/Library/UefiShellDebug1CommandsLib/UefiShellDebug1CommandsLib.inf | |
+ NULL|ShellPkg/Library/UefiShellInstall1CommandsLib/UefiShellInstall1CommandsLib.inf | |
+ NULL|ShellPkg/Library/UefiShellNetwork1CommandsLib/UefiShellNetwork1CommandsLib.inf | |
+!if $(NETWORK_IP6_ENABLE) == TRUE | |
+ NULL|ShellPkg/Library/UefiShellNetwork2CommandsLib/UefiShellNetwork2CommandsLib.inf | |
+!endif | |
+ NULL|ShellPkg/Library/UefiShellTftpCommandLib/UefiShellTftpCommandLib.inf | |
+ HandleParsingLib|ShellPkg/Library/UefiHandleParsingLib/UefiHandleParsingLib.inf | |
+ ShellLib|ShellPkg/Library/UefiShellLib/UefiShellLib.inf | |
+ FileHandleLib|MdePkg/Library/UefiFileHandleLib/UefiFileHandleLib.inf | |
+ PrintLib|MdePkg/Library/BasePrintLib/BasePrintLib.inf | |
+# SafeBlockIoLib|ShellPkg/Library/SafeBlockIoLib/SafeBlockIoLib.inf | |
+# SafeOpenProtocolLib|ShellPkg/Library/SafeOpenProtocolLib/SafeOpenProtocolLib.inf | |
+ BcfgCommandLib|ShellPkg/Library/UefiShellBcfgCommandLib/UefiShellBcfgCommandLib.inf | |
+ | |
+ <PcdsFixedAtBuild> | |
+ gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0xFF | |
+ gEfiShellPkgTokenSpaceGuid.PcdShellLibAutoInitialize|FALSE | |
+ gEfiMdePkgTokenSpaceGuid.PcdUefiLibMaxPrintBufferSize|8000 | |
+ } | |
+!endif | |
+ | |
+!if $(SECURE_BOOT_ENABLE) == TRUE | |
+ SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigDxe.inf | |
+!endif | |
+ | |
+ OvmfPkg/PlatformDxe/Platform.inf | |
+ | |
+!if $(SMM_REQUIRE) == TRUE | |
+ OvmfPkg/SmmAccess/SmmAccess2Dxe.inf | |
+ OvmfPkg/SmmControl2Dxe/SmmControl2Dxe.inf | |
+ UefiCpuPkg/CpuS3DataDxe/CpuS3DataDxe.inf | |
+ | |
+ # | |
+ # SMM Initial Program Load (a DXE_RUNTIME_DRIVER) | |
+ # | |
+ MdeModulePkg/Core/PiSmmCore/PiSmmIpl.inf | |
+ | |
+ # | |
+ # SMM_CORE | |
+ # | |
+ MdeModulePkg/Core/PiSmmCore/PiSmmCore.inf | |
+ | |
+ # | |
+ # Privileged drivers (DXE_SMM_DRIVER modules) | |
+ # | |
+ UefiCpuPkg/CpuIo2Smm/CpuIo2Smm.inf | |
+ MdeModulePkg/Universal/LockBox/SmmLockBox/SmmLockBox.inf { | |
+ <LibraryClasses> | |
+ LockBoxLib|MdeModulePkg/Library/SmmLockBoxLib/SmmLockBoxSmmLib.inf | |
+ } | |
+ UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.inf { | |
+ <LibraryClasses> | |
+ SmmCpuPlatformHookLib|UefiCpuPkg/Library/SmmCpuPlatformHookLibNull/SmmCpuPlatformHookLibNull.inf | |
+ SmmCpuFeaturesLib|OvmfPkg/Library/SmmCpuFeaturesLib/SmmCpuFeaturesLib.inf | |
+ } | |
+ | |
+ # | |
+ # Variable driver stack (SMM) | |
+ # | |
+ OvmfPkg/QemuFlashFvbServicesRuntimeDxe/FvbServicesSmm.inf | |
+ MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteSmm.inf | |
+ MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmm.inf { | |
+ <LibraryClasses> | |
+ NULL|MdeModulePkg/Library/VarCheckUefiLib/VarCheckUefiLib.inf | |
+ } | |
+ MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmmRuntimeDxe.inf | |
+ | |
+!else | |
+ | |
+ # | |
+ # Variable driver stack (non-SMM) | |
+ # | |
+ OvmfPkg/QemuFlashFvbServicesRuntimeDxe/FvbServicesRuntimeDxe.inf | |
+ OvmfPkg/EmuVariableFvbRuntimeDxe/Fvb.inf { | |
+ <LibraryClasses> | |
+ PlatformFvbLib|OvmfPkg/Library/EmuVariableFvbLib/EmuVariableFvbLib.inf | |
+ } | |
+ MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteDxe.inf | |
+ MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf { | |
+ <LibraryClasses> | |
+ NULL|MdeModulePkg/Library/VarCheckUefiLib/VarCheckUefiLib.inf | |
+ } | |
+!endif | |
diff --git a/ShellPkg/ShellPkgX64.dsc b/ShellPkg/ShellPkgX64.dsc | |
new file mode 100644 | |
index 000000000000..fb47d774bceb | |
--- /dev/null | |
+++ b/ShellPkg/ShellPkgX64.dsc | |
@@ -0,0 +1,142 @@ | |
+## @file | |
+# Shell Package | |
+# | |
+# Copyright (c) 2007 - 2016, 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. | |
+# | |
+## | |
+ | |
+[Defines] | |
+ PLATFORM_NAME = Shell | |
+ PLATFORM_GUID = E1DC9BF8-7013-4c99-9437-795DAA45F3BD | |
+ PLATFORM_VERSION = 1.0 | |
+ DSC_SPECIFICATION = 0x00010006 | |
+ OUTPUT_DIRECTORY = Build/Shell | |
+ SUPPORTED_ARCHITECTURES = IA32|IPF|X64|EBC|ARM|AARCH64 | |
+ BUILD_TARGETS = DEBUG|RELEASE|NOOPT | |
+ SKUID_IDENTIFIER = DEFAULT | |
+ | |
+[LibraryClasses.common] | |
+ UefiApplicationEntryPoint|MdePkg/Library/UefiApplicationEntryPoint/UefiApplicationEntryPoint.inf | |
+ UefiBootServicesTableLib|MdePkg/Library/UefiBootServicesTableLib/UefiBootServicesTableLib.inf | |
+ DevicePathLib|MdePkg/Library/UefiDevicePathLib/UefiDevicePathLibOptionalDevicePathProtocol.inf | |
+!if $(TARGET) == RELEASE | |
+ DebugLib|MdePkg/Library/BaseDebugLibNull/BaseDebugLibNull.inf | |
+!else | |
+ DebugLib|MdePkg/Library/UefiDebugLibConOut/UefiDebugLibConOut.inf | |
+!endif | |
+ DebugPrintErrorLevelLib|MdePkg/Library/BaseDebugPrintErrorLevelLib/BaseDebugPrintErrorLevelLib.inf | |
+ ReportStatusCodeLib|MdePkg/Library/BaseReportStatusCodeLibNull/BaseReportStatusCodeLibNull.inf | |
+ PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf | |
+ MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf | |
+ UefiLib|MdePkg/Library/UefiLib/UefiLib.inf | |
+ BaseLib|MdePkg/Library/BaseLib/BaseLib.inf | |
+ BaseMemoryLib|MdePkg/Library/BaseMemoryLib/BaseMemoryLib.inf | |
+ PrintLib|MdePkg/Library/BasePrintLib/BasePrintLib.inf | |
+ TimerLib|MdePkg/Library/BaseTimerLibNullTemplate/BaseTimerLibNullTemplate.inf | |
+ PerformanceLib|MdePkg/Library/BasePerformanceLibNull/BasePerformanceLibNull.inf | |
+ DxeServicesLib|MdePkg/Library/DxeServicesLib/DxeServicesLib.inf | |
+ DxeServicesTableLib|MdePkg/Library/DxeServicesTableLib/DxeServicesTableLib.inf | |
+ #HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf | |
+ UefiRuntimeServicesTableLib|MdePkg/Library/UefiRuntimeServicesTableLib/UefiRuntimeServicesTableLib.inf | |
+ UefiHiiServicesLib|MdeModulePkg/Library/UefiHiiServicesLib/UefiHiiServicesLib.inf | |
+ HiiLib|MdeModulePkg/Library/UefiHiiLib/UefiHiiLib.inf | |
+ NetLib|MdeModulePkg/Library/DxeNetLib/DxeNetLib.inf | |
+ | |
+ UefiBootManagerLib|MdeModulePkg/Library/UefiBootManagerLib/UefiBootManagerLib.inf | |
+ FileHandleLib|MdePkg/Library/UefiFileHandleLib/UefiFileHandleLib.inf | |
+ SortLib|MdeModulePkg/Library/UefiSortLib/UefiSortLib.inf | |
+ HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf | |
+ | |
+ | |
+ ShellLib|ShellPkg/Library/UefiShellLib/UefiShellLib.inf | |
+ ShellCommandLib|ShellPkg/Library/UefiShellCommandLib/UefiShellCommandLib.inf | |
+ ShellCEntryLib|ShellPkg/Library/UefiShellCEntryLib/UefiShellCEntryLib.inf | |
+ HandleParsingLib|ShellPkg/Library/UefiHandleParsingLib/UefiHandleParsingLib.inf | |
+ | |
+ PeCoffGetEntryPointLib|MdePkg/Library/BasePeCoffGetEntryPointLib/BasePeCoffGetEntryPointLib.inf | |
+ BcfgCommandLib|ShellPkg/Library/UefiShellBcfgCommandLib/UefiShellBcfgCommandLib.inf | |
+ IoLib|MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsic.inf | |
+ | |
+[LibraryClasses.ARM] | |
+ # | |
+ # It is not possible to prevent the ARM compiler for generic intrinsic functions. | |
+ # This library provides the instrinsic functions generate by a given compiler. | |
+ # [LibraryClasses.ARM] and NULL mean link this library into all ARM images. | |
+ # | |
+ NULL|ArmPkg/Library/CompilerIntrinsicsLib/CompilerIntrinsicsLib.inf | |
+ | |
+ # Add support for GCC stack protector | |
+ NULL|MdePkg/Library/BaseStackCheckLib/BaseStackCheckLib.inf | |
+ | |
+[LibraryClasses.AARCH64] | |
+ NULL|ArmPkg/Library/CompilerIntrinsicsLib/CompilerIntrinsicsLib.inf | |
+ | |
+[PcdsFixedAtBuild] | |
+ gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0xFF | |
+ gEfiShellPkgTokenSpaceGuid.PcdShellLibAutoInitialize|FALSE | |
+ gEfiMdePkgTokenSpaceGuid.PcdUefiLibMaxPrintBufferSize|16000 | |
+!ifdef $(NO_SHELL_PROFILES) | |
+ gEfiShellPkgTokenSpaceGuid.PcdShellProfileMask|0x00 | |
+!endif #$(NO_SHELL_PROFILES) | |
+ | |
+[Components] | |
+ # | |
+ # Build all the libraries when building this package. | |
+ # This helps developers test changes and how they affect the package. | |
+ # | |
+ ShellPkg/Library/UefiShellLib/UefiShellLib.inf | |
+ ShellPkg/Library/UefiShellCommandLib/UefiShellCommandLib.inf | |
+ ShellPkg/Library/UefiShellCEntryLib/UefiShellCEntryLib.inf | |
+ ShellPkg/Library/UefiHandleParsingLib/UefiHandleParsingLib.inf | |
+ ShellPkg/Library/UefiShellBcfgCommandLib/UefiShellBcfgCommandLib.inf | |
+ ShellPkg/Library/UefiShellLevel1CommandsLib/UefiShellLevel1CommandsLib.inf | |
+ ShellPkg/Library/UefiShellLevel2CommandsLib/UefiShellLevel2CommandsLib.inf | |
+ ShellPkg/Library/UefiShellLevel3CommandsLib/UefiShellLevel3CommandsLib.inf | |
+ ShellPkg/Library/UefiShellDriver1CommandsLib/UefiShellDriver1CommandsLib.inf | |
+ ShellPkg/Library/UefiShellInstall1CommandsLib/UefiShellInstall1CommandsLib.inf | |
+ ShellPkg/Library/UefiShellDebug1CommandsLib/UefiShellDebug1CommandsLib.inf | |
+ ShellPkg/Library/UefiShellNetwork1CommandsLib/UefiShellNetwork1CommandsLib.inf | |
+ ShellPkg/Library/UefiShellNetwork2CommandsLib/UefiShellNetwork2CommandsLib.inf | |
+ ShellPkg/Library/UefiShellTftpCommandLib/UefiShellTftpCommandLib.inf | |
+ | |
+ ShellPkg/Library/UefiDpLib/UefiDpLib.inf { | |
+ <LibraryClasses> | |
+ TimerLib|MdePkg/Library/BaseTimerLibNullTemplate/BaseTimerLibNullTemplate.inf | |
+ PerformanceLib|MdePkg/Library/BasePerformanceLibNull/BasePerformanceLibNull.inf | |
+ DxeServicesLib|MdePkg/Library/DxeServicesLib/DxeServicesLib.inf | |
+ } | |
+ | |
+ ShellPkg/Application/Shell/Shell.inf { | |
+ <LibraryClasses> | |
+ NULL|ShellPkg/Library/UefiShellLevel2CommandsLib/UefiShellLevel2CommandsLib.inf | |
+ NULL|ShellPkg/Library/UefiShellLevel1CommandsLib/UefiShellLevel1CommandsLib.inf | |
+ NULL|ShellPkg/Library/UefiShellLevel3CommandsLib/UefiShellLevel3CommandsLib.inf | |
+!ifndef $(NO_SHELL_PROFILES) | |
+ NULL|ShellPkg/Library/UefiShellDriver1CommandsLib/UefiShellDriver1CommandsLib.inf | |
+ NULL|ShellPkg/Library/UefiShellInstall1CommandsLib/UefiShellInstall1CommandsLib.inf | |
+ NULL|ShellPkg/Library/UefiShellDebug1CommandsLib/UefiShellDebug1CommandsLib.inf | |
+ NULL|ShellPkg/Library/UefiShellNetwork1CommandsLib/UefiShellNetwork1CommandsLib.inf | |
+ NULL|ShellPkg/Library/UefiShellNetwork2CommandsLib/UefiShellNetwork2CommandsLib.inf | |
+!ifdef $(INCLUDE_DP) | |
+ NULL|ShellPkg/Library/UefiDpLib/UefiDpLib.inf | |
+!endif #$(INCLUDE_DP) | |
+!ifdef $(INCLUDE_TFTP_COMMAND) | |
+ NULL|ShellPkg/Library/UefiShellTftpCommandLib/UefiShellTftpCommandLib.inf | |
+!endif #$(INCLUDE_TFTP_COMMAND) | |
+!endif #$(NO_SHELL_PROFILES) | |
+ } | |
+ | |
+[BuildOptions] | |
+XCODE:*_*_*_DLINK_FLAGS = -Wl,-no_compact_unwind | |
+XCODE:*_*_*_CC_FLAGS = -Os -DMDEPKG_NDEBUG -D DISABLE_NEW_DEPRECATED_INTERFACES | |
+GCC:*_*_*_CC_FLAGS = -Os -flto -DMDEPKG_NDEBUG -D DISABLE_NEW_DEPRECATED_INTERFACES | |
+MSFT:*_*_*_CC_FLAGS = /D MDEPKG_NDEBUG | |
+ | |
diff --git a/OvmfPkg/OvmfCloverX64.fdf b/OvmfPkg/OvmfCloverX64.fdf | |
new file mode 100644 | |
index 000000000000..727f0ae5892c | |
--- /dev/null | |
+++ b/OvmfPkg/OvmfCloverX64.fdf | |
@@ -0,0 +1,552 @@ | |
+## @file | |
+# Open Virtual Machine Firmware: FDF | |
+# | |
+# Copyright (c) 2006 - 2016, 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. | |
+# | |
+## | |
+ | |
+################################################################################ | |
+ | |
+[Defines] | |
+!include OvmfPkg.fdf.inc | |
+ | |
+# | |
+# Build the variable store and the firmware code as one unified flash device | |
+# image. | |
+# | |
+[FD.OVMF] | |
+BaseAddress = $(FW_BASE_ADDRESS) | |
+Size = $(FW_SIZE) | |
+ErasePolarity = 1 | |
+BlockSize = $(BLOCK_SIZE) | |
+NumBlocks = $(FW_BLOCKS) | |
+ | |
+!include VarStore.fdf.inc | |
+ | |
+$(VARS_SIZE)|$(FVMAIN_SIZE) | |
+FV = FVMAIN_COMPACT | |
+ | |
+$(SECFV_OFFSET)|$(SECFV_SIZE) | |
+FV = SECFV | |
+ | |
+# | |
+# Build the variable store and the firmware code as separate flash device | |
+# images. | |
+# | |
+[FD.OVMF_VARS] | |
+BaseAddress = $(FW_BASE_ADDRESS) | |
+Size = $(VARS_SIZE) | |
+ErasePolarity = 1 | |
+BlockSize = $(BLOCK_SIZE) | |
+NumBlocks = $(VARS_BLOCKS) | |
+ | |
+!include VarStore.fdf.inc | |
+ | |
+[FD.OVMF_CODE] | |
+BaseAddress = $(CODE_BASE_ADDRESS) | |
+Size = $(CODE_SIZE) | |
+ErasePolarity = 1 | |
+BlockSize = $(BLOCK_SIZE) | |
+NumBlocks = $(CODE_BLOCKS) | |
+ | |
+0x00000000|$(FVMAIN_SIZE) | |
+FV = FVMAIN_COMPACT | |
+ | |
+$(FVMAIN_SIZE)|$(SECFV_SIZE) | |
+FV = SECFV | |
+ | |
+################################################################################ | |
+ | |
+[FD.MEMFD] | |
+BaseAddress = $(MEMFD_BASE_ADDRESS) | |
+Size = 0xB00000 | |
+ErasePolarity = 1 | |
+BlockSize = 0x10000 | |
+NumBlocks = 0xB0 | |
+ | |
+0x000000|0x006000 | |
+gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPageTablesBase|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPageTablesSize | |
+ | |
+0x006000|0x001000 | |
+gUefiOvmfPkgTokenSpaceGuid.PcdOvmfLockBoxStorageBase|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfLockBoxStorageSize | |
+ | |
+0x007000|0x001000 | |
+gEfiMdePkgTokenSpaceGuid.PcdGuidedExtractHandlerTableAddress|gUefiOvmfPkgTokenSpaceGuid.PcdGuidedExtractHandlerTableSize | |
+ | |
+0x010000|0x008000 | |
+gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPeiTempRamBase|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPeiTempRamSize | |
+ | |
+0x020000|0x0E0000 | |
+gUefiOvmfPkgTokenSpaceGuid.PcdOvmfPeiMemFvBase|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfPeiMemFvSize | |
+FV = PEIFV | |
+ | |
+0x100000|0xA00000 | |
+gUefiOvmfPkgTokenSpaceGuid.PcdOvmfDxeMemFvBase|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfDxeMemFvSize | |
+FV = DXEFV | |
+ | |
+################################################################################ | |
+ | |
+[FV.SECFV] | |
+FvNameGuid = 763BED0D-DE9F-48F5-81F1-3E90E1B1A015 | |
+BlockSize = 0x1000 | |
+FvAlignment = 16 | |
+ERASE_POLARITY = 1 | |
+MEMORY_MAPPED = TRUE | |
+STICKY_WRITE = TRUE | |
+LOCK_CAP = TRUE | |
+LOCK_STATUS = TRUE | |
+WRITE_DISABLED_CAP = TRUE | |
+WRITE_ENABLED_CAP = TRUE | |
+WRITE_STATUS = TRUE | |
+WRITE_LOCK_CAP = TRUE | |
+WRITE_LOCK_STATUS = TRUE | |
+READ_DISABLED_CAP = TRUE | |
+READ_ENABLED_CAP = TRUE | |
+READ_STATUS = TRUE | |
+READ_LOCK_CAP = TRUE | |
+READ_LOCK_STATUS = TRUE | |
+ | |
+# | |
+# SEC Phase modules | |
+# | |
+# The code in this FV handles the initial firmware startup, and | |
+# decompresses the PEI and DXE FVs which handles the rest of the boot sequence. | |
+# | |
+INF OvmfPkg/Sec/SecMain.inf | |
+ | |
+INF RuleOverride=RESET_VECTOR OvmfPkg/ResetVector/ResetVector.inf | |
+ | |
+################################################################################ | |
+[FV.PEIFV] | |
+FvNameGuid = 6938079B-B503-4E3D-9D24-B28337A25806 | |
+BlockSize = 0x10000 | |
+FvAlignment = 16 | |
+ERASE_POLARITY = 1 | |
+MEMORY_MAPPED = TRUE | |
+STICKY_WRITE = TRUE | |
+LOCK_CAP = TRUE | |
+LOCK_STATUS = TRUE | |
+WRITE_DISABLED_CAP = TRUE | |
+WRITE_ENABLED_CAP = TRUE | |
+WRITE_STATUS = TRUE | |
+WRITE_LOCK_CAP = TRUE | |
+WRITE_LOCK_STATUS = TRUE | |
+READ_DISABLED_CAP = TRUE | |
+READ_ENABLED_CAP = TRUE | |
+READ_STATUS = TRUE | |
+READ_LOCK_CAP = TRUE | |
+READ_LOCK_STATUS = TRUE | |
+ | |
+APRIORI PEI { | |
+ INF MdeModulePkg/Universal/PCD/Pei/Pcd.inf | |
+} | |
+ | |
+# | |
+# PEI Phase modules | |
+# | |
+INF MdeModulePkg/Core/Pei/PeiMain.inf | |
+INF MdeModulePkg/Universal/PCD/Pei/Pcd.inf | |
+INF IntelFrameworkModulePkg/Universal/StatusCode/Pei/StatusCodePei.inf | |
+INF OvmfPkg/PlatformPei/PlatformPei.inf | |
+INF MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf | |
+INF UefiCpuPkg/Universal/Acpi/S3Resume2Pei/S3Resume2Pei.inf | |
+!if $(SMM_REQUIRE) == TRUE | |
+INF OvmfPkg/SmmAccess/SmmAccessPei.inf | |
+!endif | |
+#INF UefiCpuPkg/CpuMpPei/CpuMpPei.inf | |
+ | |
+################################################################################ | |
+ | |
+[FV.DXEFV] | |
+FvNameGuid = 7CB8BDC9-F8EB-4F34-AAEA-3EE4AF6516A1 | |
+BlockSize = 0x10000 | |
+FvAlignment = 16 | |
+ERASE_POLARITY = 1 | |
+MEMORY_MAPPED = TRUE | |
+STICKY_WRITE = TRUE | |
+LOCK_CAP = TRUE | |
+LOCK_STATUS = TRUE | |
+WRITE_DISABLED_CAP = TRUE | |
+WRITE_ENABLED_CAP = TRUE | |
+WRITE_STATUS = TRUE | |
+WRITE_LOCK_CAP = TRUE | |
+WRITE_LOCK_STATUS = TRUE | |
+READ_DISABLED_CAP = TRUE | |
+READ_ENABLED_CAP = TRUE | |
+READ_STATUS = TRUE | |
+READ_LOCK_CAP = TRUE | |
+READ_LOCK_STATUS = TRUE | |
+ | |
+APRIORI DXE { | |
+ INF MdeModulePkg/Universal/DevicePathDxe/DevicePathDxe.inf | |
+ INF MdeModulePkg/Universal/PCD/Dxe/Pcd.inf | |
+!if $(SMM_REQUIRE) == FALSE | |
+ INF OvmfPkg/QemuFlashFvbServicesRuntimeDxe/FvbServicesRuntimeDxe.inf | |
+!endif | |
+} | |
+ | |
+# | |
+# DXE Phase modules | |
+# | |
+INF MdeModulePkg/Core/Dxe/DxeMain.inf | |
+ | |
+INF IntelFrameworkModulePkg/Universal/StatusCode/RuntimeDxe/StatusCodeRuntimeDxe.inf | |
+INF MdeModulePkg/Universal/PCD/Dxe/Pcd.inf | |
+ | |
+INF MdeModulePkg/Core/RuntimeDxe/RuntimeDxe.inf | |
+INF MdeModulePkg/Universal/SecurityStubDxe/SecurityStubDxe.inf | |
+INF MdeModulePkg/Universal/EbcDxe/EbcDxe.inf | |
+INF PcAtChipsetPkg/8259InterruptControllerDxe/8259.inf | |
+INF UefiCpuPkg/CpuIo2Dxe/CpuIo2Dxe.inf | |
+#INF Clover/UefiCpuPkg/CpuIo2Dxe/CpuIo2Dxe.inf | |
+## Only working in the Ovmf. Why? | |
+INF UefiCpuPkg/CpuDxe/CpuDxe.inf | |
+#INF Clover/UefiCpuPkg/CpuDxe/CpuDxe.inf | |
+#INF Clover/CpuDxe/Cpu.inf | |
+INF PcAtChipsetPkg/8254TimerDxe/8254Timer.inf | |
+INF OvmfPkg/IncompatiblePciDeviceSupportDxe/IncompatiblePciDeviceSupport.inf | |
+INF OvmfPkg/PciHotPlugInitDxe/PciHotPlugInit.inf | |
+INF MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostBridgeDxe.inf | |
+INF MdeModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.inf | |
+INF PcAtChipsetPkg/KbcResetDxe/Reset.inf | |
+INF MdeModulePkg/Universal/Metronome/Metronome.inf | |
+INF PcAtChipsetPkg/PcatRealTimeClockRuntimeDxe/PcatRealTimeClockRuntimeDxe.inf | |
+ | |
+INF OvmfPkg/BlockMmioToBlockIoDxe/BlockIo.inf | |
+INF OvmfPkg/VirtioPciDeviceDxe/VirtioPciDeviceDxe.inf | |
+INF OvmfPkg/Virtio10Dxe/Virtio10.inf | |
+INF OvmfPkg/VirtioBlkDxe/VirtioBlk.inf | |
+INF OvmfPkg/VirtioScsiDxe/VirtioScsi.inf | |
+INF OvmfPkg/VirtioRngDxe/VirtioRng.inf | |
+INF OvmfPkg/XenIoPciDxe/XenIoPciDxe.inf | |
+INF OvmfPkg/XenBusDxe/XenBusDxe.inf | |
+INF OvmfPkg/XenPvBlkDxe/XenPvBlkDxe.inf | |
+ | |
+!if $(SECURE_BOOT_ENABLE) == TRUE | |
+ INF SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigDxe.inf | |
+!endif | |
+ | |
+INF MdeModulePkg/Universal/WatchdogTimerDxe/WatchdogTimer.inf | |
+INF MdeModulePkg/Universal/MonotonicCounterRuntimeDxe/MonotonicCounterRuntimeDxe.inf | |
+INF MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleRuntimeDxe.inf | |
+INF MdeModulePkg/Universal/Console/ConPlatformDxe/ConPlatformDxe.inf | |
+INF MdeModulePkg/Universal/Console/ConSplitterDxe/ConSplitterDxe.inf | |
+INF MdeModulePkg/Universal/Console/GraphicsConsoleDxe/GraphicsConsoleDxe.inf | |
+INF MdeModulePkg/Universal/Console/TerminalDxe/TerminalDxe.inf | |
+INF MdeModulePkg/Universal/DriverHealthManagerDxe/DriverHealthManagerDxe.inf | |
+INF MdeModulePkg/Universal/BdsDxe/BdsDxe.inf | |
+INF MdeModulePkg/Application/UiApp/UiApp.inf | |
+INF MdeModulePkg/Universal/DevicePathDxe/DevicePathDxe.inf | |
+INF MdeModulePkg/Universal/PrintDxe/PrintDxe.inf | |
+INF MdeModulePkg/Universal/Disk/DiskIoDxe/DiskIoDxe.inf | |
+INF MdeModulePkg/Universal/Disk/PartitionDxe/PartitionDxe.inf | |
+#INF Clover/PartitionDxe/PartitionDxe.inf | |
+INF MdeModulePkg/Universal/Disk/RamDiskDxe/RamDiskDxe.inf | |
+INF MdeModulePkg/Universal/Disk/UnicodeCollation/EnglishDxe/EnglishDxe.inf | |
+INF MdeModulePkg/Bus/Scsi/ScsiBusDxe/ScsiBusDxe.inf | |
+INF MdeModulePkg/Bus/Scsi/ScsiDiskDxe/ScsiDiskDxe.inf | |
+INF OvmfPkg/SataControllerDxe/SataControllerDxe.inf | |
+INF MdeModulePkg/Bus/Ata/AtaAtapiPassThru/AtaAtapiPassThru.inf | |
+INF MdeModulePkg/Bus/Ata/AtaBusDxe/AtaBusDxe.inf | |
+#INF MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpressDxe.inf | |
+INF MdeModulePkg/Universal/HiiDatabaseDxe/HiiDatabaseDxe.inf | |
+INF MdeModulePkg/Universal/SetupBrowserDxe/SetupBrowserDxe.inf | |
+INF MdeModulePkg/Universal/DisplayEngineDxe/DisplayEngineDxe.inf | |
+INF MdeModulePkg/Universal/MemoryTest/NullMemoryTestDxe/NullMemoryTestDxe.inf | |
+ | |
+# | |
+# Clover | |
+# | |
+INF IntelFrameworkModulePkg/Universal/DataHubDxe/DataHubDxe.inf | |
+#INF RuleOverride=BINARY Clover/HFSPlus/HFSPlus.inf | |
+#INF Clover/VBoxFsDxe/VBoxHfs.inf | |
+#INF Clover/VBoxFsDxe/VBoxIso9660.inf | |
+#INF Clover/VBoxFsDxe/VBoxFsDxe.inf | |
+#INF Clover/VBoxFsDxe/VBoxExt2.inf | |
+#INF Clover/VBoxFsDxe/VBoxExt4.inf | |
+#INF Clover/MsgLog/MsgLog.inf | |
+ | |
+INF PcAtChipsetPkg/IsaAcpiDxe/IsaAcpi.inf | |
+INF IntelFrameworkModulePkg/Bus/Isa/IsaBusDxe/IsaBusDxe.inf | |
+ | |
+!ifndef $(SOURCE_DEBUG_ENABLE) | |
+INF IntelFrameworkModulePkg/Bus/Isa/IsaSerialDxe/IsaSerialDxe.inf | |
+!endif | |
+ | |
+INF IntelFrameworkModulePkg/Bus/Isa/Ps2KeyboardDxe/Ps2keyboardDxe.inf | |
+#INF IntelFrameworkModulePkg/Bus/Isa/IsaFloppyDxe/IsaFloppyDxe.inf | |
+#INF IntelFrameworkModulePkg/Bus/Isa/Ps2MouseDxe/Ps2MouseDxe.inf | |
+#INF Clover/Ps2MouseDxe/Ps2MouseDxe.inf | |
+ | |
+INF MdeModulePkg/Universal/SmbiosDxe/SmbiosDxe.inf | |
+INF OvmfPkg/QemuSmbiosPlatformDxe/SmbiosPlatformDxe.inf | |
+#INF DuetPkg/SmbiosGenDxe/SmbiosGen.inf | |
+ | |
+INF MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableDxe.inf | |
+INF OvmfPkg/AcpiPlatformDxe/AcpiPlatformDxe.inf | |
+INF RuleOverride=ACPITABLE OvmfPkg/AcpiTables/AcpiTables.inf | |
+#INF OvmfPkg/AcpiS3SaveDxe/AcpiS3SaveDxe.inf | |
+#INF MdeModulePkg/Universal/Acpi/S3SaveStateDxe/S3SaveStateDxe.inf | |
+#INF MdeModulePkg/Universal/Acpi/BootScriptExecutorDxe/BootScriptExecutorDxe.inf | |
+ | |
+#INF RuleOverride=BINARY Clover/HFSPlus/HFSPlus.inf | |
+INF RuleOverride = BINARY FatBinPkg/EnhancedFatDxe/Fat.inf | |
+ | |
+!ifndef $(USE_OLD_SHELL) | |
+INF ShellPkg/Application/Shell/Shell.inf | |
+!else | |
+#INF RuleOverride = BINARY EdkShellBinPkg/FullShell/FullShell.inf | |
+INF RuleOverride = BINARY Clover/CloverPackage/CloverV2/EFI/CLOVER/tools/Shell.inf | |
+!endif | |
+ | |
+FILE FREEFORM = PCD(gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdLogoFile) { | |
+# SECTION RAW = MdeModulePkg/Logo/Logo.bmp | |
+ SECTION RAW = OvmfPkg/Qemu/Logo/qemu-icon.bmp | |
+} | |
+ | |
+# | |
+# Network modules | |
+# | |
+!if $(E1000_ENABLE) | |
+ FILE DRIVER = 5D695E11-9B3F-4b83-B25F-4A8D5D69BE07 { | |
+ SECTION PE32 = Intel3.5/EFIX64/E3507X2.EFI | |
+ } | |
+!endif | |
+ INF MdeModulePkg/Universal/Network/SnpDxe/SnpDxe.inf | |
+ INF MdeModulePkg/Universal/Network/DpcDxe/DpcDxe.inf | |
+ INF MdeModulePkg/Universal/Network/MnpDxe/MnpDxe.inf | |
+ INF MdeModulePkg/Universal/Network/VlanConfigDxe/VlanConfigDxe.inf | |
+ INF MdeModulePkg/Universal/Network/ArpDxe/ArpDxe.inf | |
+ INF MdeModulePkg/Universal/Network/Dhcp4Dxe/Dhcp4Dxe.inf | |
+ INF MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Dxe.inf | |
+ INF MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Dxe.inf | |
+ INF MdeModulePkg/Universal/Network/Udp4Dxe/Udp4Dxe.inf | |
+!if $(NETWORK_IP6_ENABLE) == TRUE | |
+ INF NetworkPkg/Ip6Dxe/Ip6Dxe.inf | |
+ INF NetworkPkg/TcpDxe/TcpDxe.inf | |
+ INF NetworkPkg/Udp6Dxe/Udp6Dxe.inf | |
+ INF NetworkPkg/Dhcp6Dxe/Dhcp6Dxe.inf | |
+ INF NetworkPkg/Mtftp6Dxe/Mtftp6Dxe.inf | |
+ INF NetworkPkg/UefiPxeBcDxe/UefiPxeBcDxe.inf | |
+!if $(SECURE_BOOT_ENABLE) == TRUE | |
+ INF NetworkPkg/IScsiDxe/IScsiDxe.inf | |
+!else | |
+ INF MdeModulePkg/Universal/Network/IScsiDxe/IScsiDxe.inf | |
+!endif | |
+!else | |
+ INF MdeModulePkg/Universal/Network/Tcp4Dxe/Tcp4Dxe.inf | |
+ INF MdeModulePkg/Universal/Network/UefiPxeBcDxe/UefiPxeBcDxe.inf | |
+ INF MdeModulePkg/Universal/Network/IScsiDxe/IScsiDxe.inf | |
+!endif | |
+!if $(HTTP_BOOT_ENABLE) == TRUE | |
+ INF NetworkPkg/DnsDxe/DnsDxe.inf | |
+ INF NetworkPkg/HttpUtilitiesDxe/HttpUtilitiesDxe.inf | |
+ INF NetworkPkg/HttpDxe/HttpDxe.inf | |
+ INF NetworkPkg/HttpBootDxe/HttpBootDxe.inf | |
+!endif | |
+ INF OvmfPkg/VirtioNetDxe/VirtioNet.inf | |
+ | |
+# | |
+# Usb Support | |
+# | |
+INF MdeModulePkg/Bus/Pci/UhciDxe/UhciDxe.inf | |
+INF MdeModulePkg/Bus/Pci/EhciDxe/EhciDxe.inf | |
+#INF MdeModulePkg/Bus/Pci/XhciDxe/XhciDxe.inf | |
+INF MdeModulePkg/Bus/Usb/UsbBusDxe/UsbBusDxe.inf | |
+INF MdeModulePkg/Bus/Usb/UsbKbDxe/UsbKbDxe.inf | |
+INF MdeModulePkg/Bus/Usb/UsbMouseDxe/UsbMouseDxe.inf | |
+INF MdeModulePkg/Bus/Usb/UsbMassStorageDxe/UsbMassStorageDxe.inf | |
+ | |
+!ifdef $(CSM_ENABLE) | |
+#INF IntelFrameworkModulePkg/Csm/BiosThunk/VideoDxe/VideoDxe.inf | |
+INF OvmfPkg/Csm/VideoDxe/VideoDxe.inf | |
+#INF IntelFrameworkModulePkg/Csm/LegacyBiosDxe/LegacyBiosDxe.inf | |
+INF OvmfPkg/Csm/LegacyBiosDxe/LegacyBiosDxe.inf | |
+INF RuleOverride=CSM OvmfPkg/Csm/Csm16/Csm16.inf | |
+!else | |
+INF OvmfPkg/QemuVideoDxe/QemuVideoDxe.inf | |
+!endif | |
+ | |
+INF OvmfPkg/PlatformDxe/Platform.inf | |
+ | |
+!if $(SMM_REQUIRE) == TRUE | |
+INF OvmfPkg/SmmAccess/SmmAccess2Dxe.inf | |
+INF OvmfPkg/SmmControl2Dxe/SmmControl2Dxe.inf | |
+INF UefiCpuPkg/CpuS3DataDxe/CpuS3DataDxe.inf | |
+INF MdeModulePkg/Core/PiSmmCore/PiSmmIpl.inf | |
+INF MdeModulePkg/Core/PiSmmCore/PiSmmCore.inf | |
+INF UefiCpuPkg/CpuIo2Smm/CpuIo2Smm.inf | |
+INF MdeModulePkg/Universal/LockBox/SmmLockBox/SmmLockBox.inf | |
+INF UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.inf | |
+ | |
+# | |
+# Variable driver stack (SMM) | |
+# | |
+INF OvmfPkg/QemuFlashFvbServicesRuntimeDxe/FvbServicesSmm.inf | |
+INF MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteSmm.inf | |
+INF MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmm.inf | |
+INF MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmmRuntimeDxe.inf | |
+ | |
+!else | |
+ | |
+# | |
+# Variable driver stack (non-SMM) | |
+# | |
+INF OvmfPkg/QemuFlashFvbServicesRuntimeDxe/FvbServicesRuntimeDxe.inf | |
+INF OvmfPkg/EmuVariableFvbRuntimeDxe/Fvb.inf | |
+INF MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteDxe.inf | |
+INF MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf | |
+!endif | |
+ | |
+################################################################################ | |
+ | |
+[FV.FVMAIN_COMPACT] | |
+FvNameGuid = 48DB5E17-707C-472D-91CD-1613E7EF51B0 | |
+FvAlignment = 16 | |
+ERASE_POLARITY = 1 | |
+MEMORY_MAPPED = TRUE | |
+STICKY_WRITE = TRUE | |
+LOCK_CAP = TRUE | |
+LOCK_STATUS = TRUE | |
+WRITE_DISABLED_CAP = TRUE | |
+WRITE_ENABLED_CAP = TRUE | |
+WRITE_STATUS = TRUE | |
+WRITE_LOCK_CAP = TRUE | |
+WRITE_LOCK_STATUS = TRUE | |
+READ_DISABLED_CAP = TRUE | |
+READ_ENABLED_CAP = TRUE | |
+READ_STATUS = TRUE | |
+READ_LOCK_CAP = TRUE | |
+READ_LOCK_STATUS = TRUE | |
+ | |
+FILE FV_IMAGE = 9E21FD93-9C72-4c15-8C4B-E77F1DB2D792 { | |
+ SECTION GUIDED EE4E5898-3914-4259-9D6E-DC7BD79403CF PROCESSING_REQUIRED = TRUE { | |
+ # | |
+ # These firmware volumes will have files placed in them uncompressed, | |
+ # and then both firmware volumes will be compressed in a single | |
+ # compression operation in order to achieve better overall compression. | |
+ # | |
+ SECTION FV_IMAGE = PEIFV | |
+ SECTION FV_IMAGE = DXEFV | |
+ } | |
+ } | |
+ | |
+!include DecomprScratchEnd.fdf.inc | |
+ | |
+################################################################################ | |
+ | |
+[Rule.Common.SEC] | |
+ FILE SEC = $(NAMED_GUID) { | |
+ PE32 PE32 $(INF_OUTPUT)/$(MODULE_NAME).efi | |
+ UI STRING ="$(MODULE_NAME)" Optional | |
+ VERSION STRING ="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER) | |
+ } | |
+ | |
+[Rule.Common.PEI_CORE] | |
+ FILE PEI_CORE = $(NAMED_GUID) { | |
+ PE32 PE32 Align=Auto $(INF_OUTPUT)/$(MODULE_NAME).efi | |
+ UI STRING ="$(MODULE_NAME)" Optional | |
+ VERSION STRING ="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER) | |
+ } | |
+ | |
+[Rule.Common.PEIM] | |
+ FILE PEIM = $(NAMED_GUID) { | |
+ PEI_DEPEX PEI_DEPEX Optional $(INF_OUTPUT)/$(MODULE_NAME).depex | |
+ PE32 PE32 Align=Auto $(INF_OUTPUT)/$(MODULE_NAME).efi | |
+ UI STRING="$(MODULE_NAME)" Optional | |
+ VERSION STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER) | |
+ } | |
+ | |
+[Rule.Common.DXE_CORE] | |
+ FILE DXE_CORE = $(NAMED_GUID) { | |
+ PE32 PE32 $(INF_OUTPUT)/$(MODULE_NAME).efi | |
+ UI STRING="$(MODULE_NAME)" Optional | |
+ VERSION STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER) | |
+ } | |
+ | |
+[Rule.Common.DXE_DRIVER] | |
+ FILE DRIVER = $(NAMED_GUID) { | |
+ DXE_DEPEX DXE_DEPEX Optional $(INF_OUTPUT)/$(MODULE_NAME).depex | |
+ PE32 PE32 $(INF_OUTPUT)/$(MODULE_NAME).efi | |
+ UI STRING="$(MODULE_NAME)" Optional | |
+ VERSION STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER) | |
+ RAW ACPI Optional |.acpi | |
+ RAW ASL Optional |.aml | |
+ } | |
+ | |
+[Rule.Common.DXE_RUNTIME_DRIVER] | |
+ FILE DRIVER = $(NAMED_GUID) { | |
+ DXE_DEPEX DXE_DEPEX Optional $(INF_OUTPUT)/$(MODULE_NAME).depex | |
+ PE32 PE32 $(INF_OUTPUT)/$(MODULE_NAME).efi | |
+ UI STRING="$(MODULE_NAME)" Optional | |
+ VERSION STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER) | |
+ } | |
+ | |
+[Rule.Common.UEFI_DRIVER] | |
+ FILE DRIVER = $(NAMED_GUID) { | |
+ DXE_DEPEX DXE_DEPEX Optional $(INF_OUTPUT)/$(MODULE_NAME).depex | |
+ PE32 PE32 $(INF_OUTPUT)/$(MODULE_NAME).efi | |
+ UI STRING="$(MODULE_NAME)" Optional | |
+ VERSION STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER) | |
+ } | |
+ | |
+[Rule.Common.UEFI_DRIVER.BINARY] | |
+ FILE DRIVER = $(NAMED_GUID) { | |
+ DXE_DEPEX DXE_DEPEX Optional |.depex | |
+ PE32 PE32 |.efi | |
+ UI STRING="$(MODULE_NAME)" Optional | |
+ VERSION STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER) | |
+ } | |
+ | |
+[Rule.Common.UEFI_APPLICATION] | |
+ FILE APPLICATION = $(NAMED_GUID) { | |
+ PE32 PE32 $(INF_OUTPUT)/$(MODULE_NAME).efi | |
+ UI STRING="$(MODULE_NAME)" Optional | |
+ VERSION STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER) | |
+ } | |
+ | |
+[Rule.Common.UEFI_APPLICATION.BINARY] | |
+ FILE APPLICATION = $(NAMED_GUID) { | |
+ PE32 PE32 |.efi | |
+ UI STRING="$(MODULE_NAME)" Optional | |
+ VERSION STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER) | |
+ } | |
+ | |
+[Rule.Common.USER_DEFINED.ACPITABLE] | |
+ FILE FREEFORM = $(NAMED_GUID) { | |
+ RAW ACPI |.acpi | |
+ RAW ASL |.aml | |
+ } | |
+ | |
+[Rule.Common.USER_DEFINED.CSM] | |
+ FILE FREEFORM = $(NAMED_GUID) { | |
+ RAW BIN |.bin | |
+ } | |
+ | |
+[Rule.Common.SEC.RESET_VECTOR] | |
+ FILE RAW = $(NAMED_GUID) { | |
+ RAW BIN Align = 16 |.bin | |
+ } | |
+ | |
+[Rule.Common.SMM_CORE] | |
+ FILE SMM_CORE = $(NAMED_GUID) { | |
+ PE32 PE32 $(INF_OUTPUT)/$(MODULE_NAME).efi | |
+ UI STRING="$(MODULE_NAME)" Optional | |
+ VERSION STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER) | |
+ } | |
+ | |
+[Rule.Common.DXE_SMM_DRIVER] | |
+ FILE SMM = $(NAMED_GUID) { | |
+ SMM_DEPEX SMM_DEPEX Optional $(INF_OUTPUT)/$(MODULE_NAME).depex | |
+ PE32 PE32 $(INF_OUTPUT)/$(MODULE_NAME).efi | |
+ UI STRING="$(MODULE_NAME)" Optional | |
+ VERSION STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER) | |
+ } | |
diff --git a/MdePkg/Library/BaseLib/BaseLib.inf b/MdePkg/Library/BaseLib/BaseLib.inf | |
index 80d00ebed75b..0af047372791 100644 | |
--- a/MdePkg/Library/BaseLib/BaseLib.inf | |
+++ b/MdePkg/Library/BaseLib/BaseLib.inf | |
@@ -758,7 +758,7 @@ [Sources.X64] | |
X86DisablePaging32.c | |
X86RdRand.c | |
X64/GccInline.c | GCC | |
- X64/Thunk16.S | XCODE | |
+# X64/Thunk16.S | XCODE | |
X64/SwitchStack.nasm| GCC | |
X64/SwitchStack.S | GCC | |
X64/SetJump.nasm| GCC | |
diff --git a/OvmfPkg/CsmOld/LegacyBiosDxe/LegacyBiosDxe.inf b/OvmfPkg/CsmOld/LegacyBiosDxe/LegacyBiosDxe.inf | |
new file mode 100644 | |
index 000000000000..1c5a17fed769 | |
--- /dev/null | |
+++ b/OvmfPkg/CsmOld/LegacyBiosDxe/LegacyBiosDxe.inf | |
@@ -0,0 +1,151 @@ | |
+## @file | |
+# Legacy Bios Module to support CSM. | |
+# | |
+# This driver installs Legacy Bios Protocol to support CSM module work in EFI system. | |
+# | |
+# Copyright (c) 2006 - 2014, 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. | |
+# | |
+## | |
+ | |
+[Defines] | |
+ INF_VERSION = 0x00010005 | |
+ BASE_NAME = LegacyBiosDxe | |
+ MODULE_UNI_FILE = LegacyBiosDxe.uni | |
+ FILE_GUID = F122A15C-C10B-4d54-8F48-60F4F06DD1AD | |
+ MODULE_TYPE = DXE_DRIVER | |
+ VERSION_STRING = 1.0 | |
+ | |
+ ENTRY_POINT = LegacyBiosInstall | |
+ | |
+# | |
+# The following information is for reference only and not required by the build tools. | |
+# | |
+# VALID_ARCHITECTURES = IA32 X64 IPF | |
+# | |
+ | |
+[Sources] | |
+ LegacyCmos.c | |
+ LegacyIde.c | |
+ LegacyBios.c | |
+ LegacyBda.c | |
+ LegacyBiosInterface.h | |
+ LegacyPci.c | |
+ | |
+[Sources.Ia32] | |
+ IA32/InterruptTable.S | |
+ IA32/InterruptTable.asm | |
+ Thunk.c | |
+ LegacyBootSupport.c | |
+ LegacyBbs.c | |
+ LegacySio.c | |
+ | |
+[Sources.X64] | |
+ X64/InterruptTable.asm | |
+ X64/InterruptTable.S | |
+ Thunk.c | |
+ LegacyBootSupport.c | |
+ LegacyBbs.c | |
+ LegacySio.c | |
+ | |
+[Sources.IPF] | |
+ Ipf/IpfThunk.s | |
+ Ipf/Thunk.c | |
+ Ipf/IpfThunk.i | |
+ Ipf/IpfBootSupport.c | |
+ Ipf/IpfThunk.h | |
+ | |
+[Packages] | |
+ MdePkg/MdePkg.dec | |
+ MdeModulePkg/MdeModulePkg.dec | |
+ IntelFrameworkPkg/IntelFrameworkPkg.dec | |
+ IntelFrameworkModulePkg/IntelFrameworkModulePkg.dec | |
+ | |
+ | |
+[LibraryClasses] | |
+ DevicePathLib | |
+ UefiBootServicesTableLib | |
+ MemoryAllocationLib | |
+ UefiDriverEntryPoint | |
+ BaseMemoryLib | |
+ UefiLib | |
+ DebugLib | |
+ DxeServicesTableLib | |
+ PcdLib | |
+ ReportStatusCodeLib | |
+ PeCoffLib | |
+ CacheMaintenanceLib | |
+ DebugAgentLib | |
+ | |
+[LibraryClasses.IA32] | |
+ IoLib | |
+ HobLib | |
+ UefiRuntimeServicesTableLib | |
+ BaseLib | |
+ | |
+[LibraryClasses.X64] | |
+ IoLib | |
+ HobLib | |
+ UefiRuntimeServicesTableLib | |
+ BaseLib | |
+ | |
+[LibraryClasses.IPF] | |
+ IoLib | |
+ UefiRuntimeServicesTableLib | |
+ | |
+ | |
+[Guids] | |
+ gEfiDiskInfoIdeInterfaceGuid ## SOMETIMES_CONSUMES ##GUID #Used in LegacyBiosBuildIdeData() to assure device is a disk | |
+ gEfiDiskInfoAhciInterfaceGuid ## SOMETIMES_CONSUMES ##GUID #Used in LegacyBiosBuildIdeData() to assure device is a disk | |
+ gEfiSmbiosTableGuid ## SOMETIMES_CONSUMES ##SystemTable | |
+ gEfiLegacyBiosGuid ## SOMETIMES_CONSUMES ##GUID #Used in LegacyBiosInstallVgaRom() to locate handle buffer | |
+ | |
+[Guids.IA32] | |
+ gEfiAcpi20TableGuid ## SOMETIMES_CONSUMES ##SystemTable | |
+ gEfiAcpi10TableGuid ## SOMETIMES_CONSUMES ##SystemTable | |
+ | |
+[Guids.X64] | |
+ gEfiAcpi20TableGuid ## SOMETIMES_CONSUMES ##SystemTable | |
+ gEfiAcpi10TableGuid ## SOMETIMES_CONSUMES ##SystemTable | |
+ | |
+ | |
+[Protocols] | |
+ gEfiLoadedImageProtocolGuid ## SOMETIMES_CONSUMES | |
+ gEfiDevicePathProtocolGuid ## SOMETIMES_CONSUMES | |
+ gEfiPciRootBridgeIoProtocolGuid ## SOMETIMES_CONSUMES | |
+ gEfiCpuArchProtocolGuid ## CONSUMES | |
+ gEfiTimerArchProtocolGuid ## CONSUMES | |
+ gEfiIsaIoProtocolGuid ## SOMETIMES_CONSUMES | |
+ gEfiBlockIoProtocolGuid ## SOMETIMES_CONSUMES | |
+ gEfiPciIoProtocolGuid ## SOMETIMES_CONSUMES | |
+ gEfiGenericMemTestProtocolGuid ## CONSUMES | |
+ gEfiDiskInfoProtocolGuid ## SOMETIMES_CONSUMES | |
+ gEfiSimpleTextInProtocolGuid ## SOMETIMES_CONSUMES | |
+ gEfiLegacy8259ProtocolGuid ## CONSUMES | |
+ gEfiLegacyBiosPlatformProtocolGuid ## CONSUMES | |
+ gEfiLegacyInterruptProtocolGuid ## CONSUMES | |
+ gEfiLegacyRegion2ProtocolGuid ## CONSUMES | |
+ gEfiLegacyBiosProtocolGuid ## PRODUCES | |
+ | |
+[Pcd] | |
+ gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdLegacyBiosCacheLegacyRegion ## CONSUMES | |
+ gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdEbdaReservedMemorySize ## CONSUMES | |
+ gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdEndOpromShadowAddress ## SOMETIMES_CONSUMES | |
+ gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdLowPmmMemorySize ## CONSUMES | |
+ gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdHighPmmMemorySize ## CONSUMES | |
+ gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdOpromReservedMemoryBase ## CONSUMES | |
+ gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdOpromReservedMemorySize ## CONSUMES | |
+ | |
+[Depex] | |
+ gEfiLegacyRegion2ProtocolGuid AND gEfiLegacyInterruptProtocolGuid AND gEfiLegacyBiosPlatformProtocolGuid AND gEfiLegacy8259ProtocolGuid AND gEfiGenericMemTestProtocolGuid AND gEfiCpuArchProtocolGuid AND gEfiTimerArchProtocolGuid AND gEfiVariableWriteArchProtocolGuid | |
+ | |
+[UserExtensions.TianoCore."ExtraFiles"] | |
+ LegacyBiosDxeExtra.uni | |
diff --git a/OvmfPkg/CsmOld/VideoDxe/VideoDxe.inf b/OvmfPkg/CsmOld/VideoDxe/VideoDxe.inf | |
new file mode 100644 | |
index 000000000000..4a89066052ca | |
--- /dev/null | |
+++ b/OvmfPkg/CsmOld/VideoDxe/VideoDxe.inf | |
@@ -0,0 +1,82 @@ | |
+## @file | |
+# Video driver based on legacy bios. | |
+# | |
+# This driver by using Legacy Bios protocol service to support csm Video | |
+# and produce Graphics Output Protocol. | |
+# | |
+# Copyright (c) 2007 - 2011, 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. | |
+# | |
+## | |
+ | |
+[Defines] | |
+ INF_VERSION = 0x00010005 | |
+ BASE_NAME = BiosVideoDxe | |
+ FILE_GUID = 0B04B2ED-861C-42cd-A22F-C3AAFACCB896 | |
+ MODULE_TYPE = UEFI_DRIVER | |
+ VERSION_STRING = 1.0 | |
+ | |
+ ENTRY_POINT = BiosVideoEntryPoint | |
+ | |
+# | |
+# The following information is for reference only and not required by the build tools. | |
+# | |
+# VALID_ARCHITECTURES = IA32 X64 IPF EBC | |
+# | |
+# DRIVER_BINDING = gBiosVideoDriverBinding | |
+# COMPONENT_NAME = gBiosVideoComponentName | |
+# | |
+ | |
+[Sources] | |
+ BiosVideo.c | |
+ BiosVideo.h | |
+ ComponentName.c | |
+ VesaBiosExtensions.h | |
+ | |
+[Packages] | |
+ MdePkg/MdePkg.dec | |
+ MdeModulePkg/MdeModulePkg.dec | |
+ IntelFrameworkPkg/IntelFrameworkPkg.dec | |
+ IntelFrameworkModulePkg/IntelFrameworkModulePkg.dec | |
+ | |
+ | |
+[LibraryClasses] | |
+ MemoryAllocationLib | |
+ DevicePathLib | |
+ UefiLib | |
+ UefiBootServicesTableLib | |
+ UefiDriverEntryPoint | |
+ BaseMemoryLib | |
+ ReportStatusCodeLib | |
+ DebugLib | |
+ PcdLib | |
+ | |
+ | |
+[Guids] | |
+ gEfiLegacyBiosGuid # ALWAYS_PRODUCED | |
+ gEfiEventExitBootServicesGuid | |
+ | |
+[Protocols] | |
+ gEfiVgaMiniPortProtocolGuid # PROTOCOL BY_START | |
+ gEfiEdidDiscoveredProtocolGuid # PROTOCOL BY_START | |
+ gEfiGraphicsOutputProtocolGuid # PROTOCOL BY_START | |
+ gEfiEdidActiveProtocolGuid # PROTOCOL BY_START | |
+ gEfiLegacyBiosProtocolGuid # PROTOCOL TO_START | |
+ gEfiPciIoProtocolGuid # PROTOCOL TO_START | |
+ gEfiDevicePathProtocolGuid # PROTOCOL TO_START | |
+ gEfiEdidOverrideProtocolGuid # PROTOCOL TO_START | |
+ | |
+[Pcd] | |
+ gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdBiosVideoSetTextVgaModeEnable | |
+ gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdBiosVideoCheckVbeEnable | |
+ gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdBiosVideoCheckVgaEnable | |
+ gEfiMdeModulePkgTokenSpaceGuid.PcdVideoHorizontalResolution | |
+ gEfiMdeModulePkgTokenSpaceGuid.PcdVideoVerticalResolution | |
diff --git a/OvmfPkg/GccBugReproducer/GccBugReproducer-O0.inf b/OvmfPkg/GccBugReproducer/GccBugReproducer-O0.inf | |
new file mode 100644 | |
index 000000000000..5ed4058d151e | |
--- /dev/null | |
+++ b/OvmfPkg/GccBugReproducer/GccBugReproducer-O0.inf | |
@@ -0,0 +1,43 @@ | |
+## @file | |
+# An application reproducing local variable corruption in recursive calls with | |
+# gcc-4.8 on the X64 target. | |
+# | |
+# Copyright (C) 2014, Red Hat, Inc. | |
+# Copyright (c) 2010, 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. | |
+# | |
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, | |
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR | |
+# IMPLIED. | |
+# | |
+## | |
+ | |
+[Defines] | |
+ INF_VERSION = 0x00010006 | |
+ BASE_NAME = GccBugReproducer-O0 | |
+ FILE_GUID = 8b779522-e8c8-44c9-a8fb-6472d5323808 | |
+ MODULE_TYPE = UEFI_APPLICATION | |
+ VERSION_STRING = 0.1 | |
+ ENTRY_POINT = ShellCEntryLib | |
+ | |
+# | |
+# VALID_ARCHITECTURES = X64 | |
+# | |
+ | |
+[Sources] | |
+ GccBugReproducer.c | |
+ | |
+[Packages] | |
+ MdePkg/MdePkg.dec | |
+ ShellPkg/ShellPkg.dec | |
+ | |
+[LibraryClasses] | |
+ UefiLib | |
+ ShellCEntryLib | |
+ | |
+[BuildOptions] | |
+ GCC:*_GCC49_X64_CC_FLAGS = -O0 | |
diff --git a/OvmfPkg/GccBugReproducer/GccBugReproducer-Os.inf b/OvmfPkg/GccBugReproducer/GccBugReproducer-Os.inf | |
new file mode 100644 | |
index 000000000000..db99a9142b56 | |
--- /dev/null | |
+++ b/OvmfPkg/GccBugReproducer/GccBugReproducer-Os.inf | |
@@ -0,0 +1,43 @@ | |
+## @file | |
+# An application reproducing local variable corruption in recursive calls with | |
+# gcc-4.8 on the X64 target. | |
+# | |
+# Copyright (C) 2014, Red Hat, Inc. | |
+# Copyright (c) 2010, 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. | |
+# | |
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, | |
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR | |
+# IMPLIED. | |
+# | |
+## | |
+ | |
+[Defines] | |
+ INF_VERSION = 0x00010006 | |
+ BASE_NAME = GccBugReproducer-Os | |
+ FILE_GUID = 76bda6c5-c09b-498c-a1c5-699ab23e5c03 | |
+ MODULE_TYPE = UEFI_APPLICATION | |
+ VERSION_STRING = 0.1 | |
+ ENTRY_POINT = ShellCEntryLib | |
+ | |
+# | |
+# VALID_ARCHITECTURES = X64 | |
+# | |
+ | |
+[Sources] | |
+ GccBugReproducer.c | |
+ | |
+[Packages] | |
+ MdePkg/MdePkg.dec | |
+ ShellPkg/ShellPkg.dec | |
+ | |
+[LibraryClasses] | |
+ UefiLib | |
+ ShellCEntryLib | |
+ | |
+[BuildOptions] | |
+ GCC:*_GCC49_X64_CC_FLAGS = -Os | |
diff --git a/OvmfPkg/QemuSmbiosPlatformDxe/SmbiosPlatformDxe.inf b/OvmfPkg/QemuSmbiosPlatformDxe/SmbiosPlatformDxe.inf | |
new file mode 100644 | |
index 000000000000..644e9977700b | |
--- /dev/null | |
+++ b/OvmfPkg/QemuSmbiosPlatformDxe/SmbiosPlatformDxe.inf | |
@@ -0,0 +1,59 @@ | |
+## @file | |
+# This driver installs SMBIOS information for OVMF | |
+# | |
+# Copyright (C) 2013, Red Hat, Inc. | |
+# Copyright (c) 2011, Bei Guan <[email protected]> | |
+# Copyright (c) 2011, 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. | |
+# | |
+## | |
+ | |
+[Defines] | |
+ INF_VERSION = 0x00010005 | |
+ BASE_NAME = SmbiosPlatformDxe | |
+ FILE_GUID = 4110465d-5ff3-4f4b-b580-24ed0d06747a | |
+ MODULE_TYPE = DXE_DRIVER | |
+ VERSION_STRING = 1.0 | |
+ | |
+ ENTRY_POINT = SmbiosTablePublishEntry | |
+ | |
+# | |
+# The following information is for reference only and not required by the build tools. | |
+# | |
+# VALID_ARCHITECTURES = IA32 X64 IPF EBC | |
+# | |
+ | |
+[Sources] | |
+ SmbiosPlatformDxe.h | |
+ SmbiosPlatformDxe.c | |
+ Qemu.c | |
+ QemuType0.c | |
+ QemuType1.c | |
+ | |
+[Packages] | |
+ MdePkg/MdePkg.dec | |
+ MdeModulePkg/MdeModulePkg.dec | |
+ OvmfPkg/OvmfPkg.dec | |
+ | |
+[LibraryClasses] | |
+ UefiBootServicesTableLib | |
+ BaseMemoryLib | |
+ BaseLib | |
+ UefiDriverEntryPoint | |
+ DebugLib | |
+ HobLib | |
+ QemuFwCfgLib | |
+ MemoryAllocationLib | |
+ | |
+[Protocols] | |
+ gEfiSmbiosProtocolGuid # PROTOCOL ALWAYS_CONSUMED | |
+ | |
+[Depex] | |
+ gEfiSmbiosProtocolGuid | |
+ | |
diff --git a/OvmfPkg/QemuVideoDxe/QemuVideoDxe.inf b/OvmfPkg/QemuVideoDxe/QemuVideoDxe.inf | |
index bec37975bafc..5054ff987350 100644 | |
--- a/OvmfPkg/QemuVideoDxe/QemuVideoDxe.inf | |
+++ b/OvmfPkg/QemuVideoDxe/QemuVideoDxe.inf | |
@@ -38,18 +38,9 @@ [Sources.common] | |
DriverSupportedEfiVersion.c | |
Gop.c | |
Initialize.c | |
- Qemu.h | |
- UnalignedIoInternal.h | |
[Sources.Ia32, Sources.X64] | |
- UnalignedIoGcc.c | GCC | |
- UnalignedIoIcc.c | INTEL | |
- UnalignedIoMsc.c | MSFT | |
VbeShim.c | |
- VbeShim.h | |
- | |
-[Sources.IPF, Sources.EBC] | |
- UnalignedIoUnsupported.c | |
[Packages] | |
MdePkg/MdePkg.dec | |
@@ -63,7 +54,6 @@ [LibraryClasses] | |
DebugLib | |
DevicePathLib | |
MemoryAllocationLib | |
- PcdLib | |
PciLib | |
PrintLib | |
TimerLib | |
@@ -79,5 +69,3 @@ [Protocols] | |
[Pcd] | |
gOptionRomPkgTokenSpaceGuid.PcdDriverSupportedEfiVersion | |
- gUefiOvmfPkgTokenSpaceGuid.PcdOvmfHostBridgePciDevId | |
- gEfiMdeModulePkgTokenSpaceGuid.PcdNullPointerDetectionPropertyMask | |
diff --git a/ShellPkg/Application/Shell/Shell.inf b/ShellPkg/Application/Shell/Shell.inf | |
index 102a12e9a47b..3fe2b87f5434 100644 | |
--- a/ShellPkg/Application/Shell/Shell.inf | |
+++ b/ShellPkg/Application/Shell/Shell.inf | |
@@ -19,7 +19,7 @@ [Defines] | |
BASE_NAME = Shell | |
FILE_GUID = 7C04A583-9E3E-4f1c-AD65-E05268D0B4D1 # gUefiShellFileGuid | |
MODULE_TYPE = UEFI_APPLICATION | |
- VERSION_STRING = 1.0 | |
+ VERSION_STRING = 1.1 | |
ENTRY_POINT = UefiMain | |
# | |
@@ -74,8 +74,10 @@ [LibraryClasses] | |
[Guids] | |
gShellVariableGuid ## SOMETIMES_CONSUMES ## GUID | |
+ gShellMapGuid ## CONSUMES ## GUID | |
gShellAliasGuid ## SOMETIMES_CONSUMES ## GUID | |
gShellAliasGuid ## SOMETIMES_PRODUCES ## GUID | |
+ gEfiGlobalVariableGuid | |
[Protocols] | |
gEfiShellProtocolGuid ## PRODUCES | |
@@ -92,6 +94,7 @@ [Protocols] | |
gEfiSimpleFileSystemProtocolGuid ## SOMETIMES_CONSUMES | |
gEfiLoadedImageProtocolGuid ## CONSUMES | |
gEfiComponentName2ProtocolGuid ## SOMETIMES_CONSUMES | |
+ gEfiUnicodeCollationProtocolGuid ## ALWAYS_CONSUMED | |
gEfiUnicodeCollation2ProtocolGuid ## CONSUMES | |
gEfiDevicePathProtocolGuid ## CONSUMES | |
gEfiHiiPackageListProtocolGuid ## SOMETIMES_PRODUCES | |
@@ -110,3 +113,14 @@ [Pcd] | |
gEfiShellPkgTokenSpaceGuid.PcdShellForceConsole ## CONSUMES | |
gEfiShellPkgTokenSpaceGuid.PcdShellSupplier ## CONSUMES | |
gEfiShellPkgTokenSpaceGuid.PcdShellMaxHistoryCommandCount ## CONSUMES | |
+ gEfiShellPkgTokenSpaceGuid.PcdShellPrintBufferSize ## CONSUMES | |
+ gEfiShellPkgTokenSpaceGuid.PcdShellForceConsole ## CONSUMES | |
+ gEfiShellPkgTokenSpaceGuid.PcdShellSupplier ## CONSUMES | |
+ gEfiShellPkgTokenSpaceGuid.PcdShellMaxHistoryCommandCount ## CONSUMES | |
+ | |
+ | |
+[BuildOptions] | |
+ XCODE:*_*_*_CC_FLAGS = -Os | |
+ GCC:*_*_*_CC_FLAGS = -Os | |
+ #-fPIC -fno-omit-frame-pointer -maccumulate-outgoing-args | |
+ MSFT:*_*_*_CC_FLAGS = /Os | |
diff --git a/ShellPkg/Library/UefiShellCommandLib/UefiShellCommandLib.inf b/ShellPkg/Library/UefiShellCommandLib/UefiShellCommandLib.inf | |
index b73b5c0e0611..70333fdd0cd9 100644 | |
--- a/ShellPkg/Library/UefiShellCommandLib/UefiShellCommandLib.inf | |
+++ b/ShellPkg/Library/UefiShellCommandLib/UefiShellCommandLib.inf | |
@@ -50,6 +50,7 @@ [LibraryClasses] | |
[Protocols] | |
gEfiUnicodeCollation2ProtocolGuid ## CONSUMES | |
+ gEfiUnicodeCollationProtocolGuid ## SOMETIMES_CONSUMES | |
gEfiShellProtocolGuid ## CONSUMES | |
gEfiShellParametersProtocolGuid ## CONSUMES | |
gEfiShellDynamicCommandProtocolGuid ## SOMETIMES_CONSUMES | |
@@ -66,4 +67,4 @@ [Pcd.common] | |
gEfiShellPkgTokenSpaceGuid.PcdShellVendorExtendedDecode ## SOMETIMES_CONSUMES | |
[Depex] | |
- gEfiUnicodeCollation2ProtocolGuid | |
+# gEfiUnicodeCollation2ProtocolGuid | |
diff --git a/MdeModulePkg/Application/UiApp/FrontPageCustomizedUiSupport.h b/MdeModulePkg/Application/UiApp/FrontPageCustomizedUiSupport.h | |
index 9dda98adeac0..0b055d7cd071 100644 | |
--- a/MdeModulePkg/Application/UiApp/FrontPageCustomizedUiSupport.h | |
+++ b/MdeModulePkg/Application/UiApp/FrontPageCustomizedUiSupport.h | |
@@ -15,6 +15,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. | |
#ifndef __FRONTPAGE_CUSTOMIZE_UI_SUPPORT_UI_H__ | |
#define __FRONTPAGE_CUSTOMIZE_UI_SUPPORT_UI_H__ | |
+extern EFI_GUID gEfiIfrFrontPageGuid; | |
/** | |
Create continue menu in the front page. | |
diff --git a/MdeModulePkg/Include/Guid/Performance.h b/MdeModulePkg/Include/Guid/Performance.h | |
index 6e21ed03e686..6393540d1949 100644 | |
--- a/MdeModulePkg/Include/Guid/Performance.h | |
+++ b/MdeModulePkg/Include/Guid/Performance.h | |
@@ -51,6 +51,31 @@ typedef struct { | |
} PEI_PERFORMANCE_LOG_HEADER; | |
+// | |
+// The data structure for performance data in ACPI memory. | |
+// | |
+#define PERFORMANCE_SIGNATURE SIGNATURE_32 ('P', 'e', 'r', 'f') | |
+#define PERF_TOKEN_SIZE 28 | |
+#define PERF_TOKEN_LENGTH (PERF_TOKEN_SIZE - 1) | |
+#define PERF_PEI_ENTRY_MAX_NUM 50 | |
+#define PERF_DATA_MAX_LENGTH 0x4000 | |
+ | |
+typedef struct { | |
+ CHAR8 Token[PERF_TOKEN_SIZE]; | |
+ UINT32 Duration; | |
+} PERF_DATA; | |
+ | |
+typedef struct { | |
+ UINT64 BootToOs; | |
+ UINT64 S3Resume; | |
+ UINT32 S3EntryNum; | |
+ PERF_DATA S3Entry[PERF_PEI_ENTRY_MAX_NUM]; | |
+ UINT64 CpuFreq; | |
+ UINT64 BDSRaw; | |
+ UINT32 Count; | |
+ UINT32 Signiture; | |
+} PERF_HEADER; | |
+ | |
#define PERFORMANCE_PROTOCOL_GUID \ | |
{ 0x76b6bdfa, 0x2acd, 0x4462, { 0x9E, 0x3F, 0xcb, 0x58, 0xC9, 0x69, 0xd9, 0x37 } } | |
diff --git a/MdeModulePkg/Library/BootMaintenanceManagerUiLib/BootMaintenanceManagerCustomizedUiSupport.h b/MdeModulePkg/Library/BootMaintenanceManagerUiLib/BootMaintenanceManagerCustomizedUiSupport.h | |
index 9f04bf573f49..ef97f7fbfeb4 100644 | |
--- a/MdeModulePkg/Library/BootMaintenanceManagerUiLib/BootMaintenanceManagerCustomizedUiSupport.h | |
+++ b/MdeModulePkg/Library/BootMaintenanceManagerUiLib/BootMaintenanceManagerCustomizedUiSupport.h | |
@@ -15,6 +15,9 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. | |
#ifndef __BOOT_MAINTENANCE_MANAGER_UI_LIB_H__ | |
#define __BOOT_MAINTENANCE_MANAGER_UI_LIB_H__ | |
+//## Include/Guid/HiiBootMaintenanceFormset.h | |
+extern EFI_GUID gEfiIfrBootMaintenanceGuid; // = { 0xb2dedc91, 0xd59f, 0x48d2, { 0x89, 0x8a, 0x12, 0x49, 0xc, 0x74, 0xa4, 0xe0 }}; | |
+ | |
/** | |
Create Time Out Menu in the page. | |
diff --git a/MdePkg/Include/Base.h b/MdePkg/Include/Base.h | |
index 4f7bd4449c36..1b2d60e2a906 100644 | |
--- a/MdePkg/Include/Base.h | |
+++ b/MdePkg/Include/Base.h | |
@@ -638,6 +638,27 @@ struct _LIST_ENTRY { | |
**/ | |
#define _INT_SIZE_OF(n) ((sizeof (n) + sizeof (UINTN) - 1) &~(sizeof (UINTN) - 1)) | |
+#define GCC_VERSION (__GNUC__ * 10 + __GNUC_MINOR__) | |
+ | |
+/* | |
+ * clang defines __MACH__ if the target is OS X, but not if the target is Windows | |
+ */ | |
+#if defined(__clang__) && !defined(__MACH__) && defined(__x86_64__) | |
+#define CLANG_VERSION (__clang_major__ * 0x100 + __clang_minor__) | |
+#ifdef __apple_build_version__ // Apple clang | |
+#if CLANG_VERSION >= 0x0703 && CLANG_VERSION < 0x0801 | |
+// Use __builtin_ms_va_list if Apple clang ver >= 7.3.0 and < 8.1.0 | |
+#define USE_CLANG_BUILTIN_MS_VA_LIST | |
+#endif | |
+#else // Generic clang | |
+// Use __builtin_ms_va_list if Generic clang ver >= 3.7.0 and < 3.9.0 | |
+#if CLANG_VERSION >= 0x0307 && CLANG_VERSION < 0x0309 | |
+#define USE_CLANG_BUILTIN_MS_VA_LIST | |
+#endif | |
+#endif // end Apple/Generic clang | |
+#undef CLANG_VERSION | |
+#endif // end __clang__ && !__MACH__ && __x86_64__ | |
+ | |
#if defined(__CC_ARM) | |
// | |
// RVCT ARM variable argument list support. | |
@@ -682,7 +703,8 @@ typedef char* VA_LIST; | |
#elif defined(__GNUC__) | |
-#if defined(MDE_CPU_X64) && !defined(NO_MSABI_VA_FUNCS) | |
+// #if defined(MDE_CPU_X64) && !defined(NO_MSABI_VA_FUNCS) | |
+#if defined(USE_CLANG_BUILTIN_MS_VA_LIST) || (defined(__x86_64__) && !defined(NO_MSABI_VA_FUNCS) && (GCC_VERSION >= 48)) | |
// | |
// X64 only. Use MS ABI version of GCC built-in macros for variable argument lists. | |
// | |
diff --git a/MdePkg/Include/Library/PeCoffLib.h b/MdePkg/Include/Library/PeCoffLib.h | |
index 5a3f98810af6..d506fee08ca8 100644 | |
--- a/MdePkg/Include/Library/PeCoffLib.h | |
+++ b/MdePkg/Include/Library/PeCoffLib.h | |
@@ -197,6 +197,8 @@ typedef struct { | |
/// Private storage for implementation specific data. | |
/// | |
UINT64 Context; | |
+ UINT32 FatOffset; | |
+ BOOLEAN IsFat; | |
} PE_COFF_LOADER_IMAGE_CONTEXT; | |
/** | |
diff --git a/MdePkg/Include/Library/UefiLib.h b/MdePkg/Include/Library/UefiLib.h | |
index 54bc2cc5a334..92e0f679eac7 100644 | |
--- a/MdePkg/Include/Library/UefiLib.h | |
+++ b/MdePkg/Include/Library/UefiLib.h | |
@@ -819,6 +819,7 @@ EFIAPI | |
GetBestLanguage ( | |
IN CONST CHAR8 *SupportedLanguages, | |
IN BOOLEAN Iso639Language, | |
+ IN CONST CHAR8 *Lang, | |
... | |
); | |
diff --git a/MdePkg/Include/Uefi/UefiBaseType.h b/MdePkg/Include/Uefi/UefiBaseType.h | |
index d9556cd2ec4e..4efa21e09697 100644 | |
--- a/MdePkg/Include/Uefi/UefiBaseType.h | |
+++ b/MdePkg/Include/Uefi/UefiBaseType.h | |
@@ -214,7 +214,7 @@ typedef union { | |
by Pages. | |
**/ | |
-#define EFI_PAGES_TO_SIZE(Pages) ((Pages) << EFI_PAGE_SHIFT) | |
+#define EFI_PAGES_TO_SIZE(Pages) (((UINTN)Pages) << EFI_PAGE_SHIFT) | |
/// | |
/// PE32+ Machine type for IA32 UEFI images. | |
diff --git a/MdePkg/Include/X64/ProcessorBind.h b/MdePkg/Include/X64/ProcessorBind.h | |
index 38ef2665390f..91a897411c94 100644 | |
--- a/MdePkg/Include/X64/ProcessorBind.h | |
+++ b/MdePkg/Include/X64/ProcessorBind.h | |
@@ -27,7 +27,7 @@ | |
#pragma pack() | |
#endif | |
-#if defined(__GNUC__) && defined(__pic__) && !defined(USING_LTO) | |
+#if defined(__GNUC__) && defined(__pic__) && !defined(USING_LTO) && !defined(__clang__) | |
// | |
// Mark all symbol declarations and references as hidden, meaning they will | |
// not be subject to symbol preemption. This allows the compiler to refer to | |
diff --git a/OvmfPkg/CsmOld/LegacyBiosDxe/Ipf/IpfThunk.h b/OvmfPkg/CsmOld/LegacyBiosDxe/Ipf/IpfThunk.h | |
new file mode 100644 | |
index 000000000000..26aa3a694b7b | |
--- /dev/null | |
+++ b/OvmfPkg/CsmOld/LegacyBiosDxe/Ipf/IpfThunk.h | |
@@ -0,0 +1,102 @@ | |
+/** @file | |
+ | |
+Copyright (c) 2007 - 2010, 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. | |
+ | |
+**/ | |
+ | |
+#ifndef _IPF_THUNK_H_ | |
+#define _IPF_THUNK_H_ | |
+ | |
+#include "LegacyBiosInterface.h" | |
+#include <IndustryStandard/Sal.h> | |
+ | |
+/** | |
+ Template of real mode code. | |
+ | |
+ @param CodeStart Start address of code. | |
+ @param CodeEnd End address of code | |
+ @param ReverseThunkStart Start of reverse thunk. | |
+ @param IntThunk Low memory thunk. | |
+ | |
+**/ | |
+VOID | |
+RealModeTemplate ( | |
+ OUT UINTN *CodeStart, | |
+ OUT UINTN *CodeEnd, | |
+ OUT UINTN *ReverseThunkStart, | |
+ LOW_MEMORY_THUNK *IntThunk | |
+ ); | |
+ | |
+/** | |
+ Register physical address of Esal Data Area | |
+ | |
+ @param ReverseThunkCodeAddress Reverse Thunk Address | |
+ @param IntThunkAddress IntThunk Address | |
+ | |
+ @retval EFI_SUCCESS ESAL data area set successfully. | |
+ | |
+**/ | |
+EFI_STATUS | |
+EsalSetSalDataArea ( | |
+ IN UINTN ReverseThunkCodeAddress, | |
+ IN UINTN IntThunkAddress | |
+ ); | |
+ | |
+/** | |
+ Get address of reverse thunk. | |
+ | |
+ @retval EFI_SAL_SUCCESS Address of reverse thunk returned successfully. | |
+ | |
+**/ | |
+SAL_RETURN_REGS | |
+EsalGetReverseThunkAddress ( | |
+ VOID | |
+ ); | |
+ | |
+typedef struct { | |
+ UINT32 Eax; // 0 | |
+ UINT32 Ecx; // 4 | |
+ UINT32 Edx; // 8 | |
+ UINT32 Ebx; // 12 | |
+ UINT32 Esp; // 16 | |
+ UINT32 Ebp; // 20 | |
+ UINT32 Esi; // 24 | |
+ UINT32 Edi; // 28 | |
+ UINT32 Eflag; // 32 | |
+ UINT32 Eip; // 36 | |
+ UINT16 Cs; // 40 | |
+ UINT16 Ds; // 42 | |
+ UINT16 Es; // 44 | |
+ UINT16 Fs; // 46 | |
+ UINT16 Gs; // 48 | |
+ UINT16 Ss; // 50 | |
+} IPF_DWORD_REGS; | |
+ | |
+/** | |
+ Entrypoint of IA32 code. | |
+ | |
+ @param CallTypeData Data of call type | |
+ @param DwordRegister Register set of IA32 general registers | |
+ and segment registers | |
+ @param StackPointer Stack pointer. | |
+ @param StackSize Size of stack. | |
+ | |
+**/ | |
+VOID | |
+EfiIaEntryPoint ( | |
+ UINT64 CallTypeData, | |
+ IPF_DWORD_REGS *DwordRegister, | |
+ UINT64 StackPointer, | |
+ UINT64 StackSize | |
+ ); | |
+ | |
+#endif | |
diff --git a/OvmfPkg/CsmOld/LegacyBiosDxe/LegacyBios.h b/OvmfPkg/CsmOld/LegacyBiosDxe/LegacyBios.h | |
new file mode 100644 | |
index 000000000000..dbaf08896349 | |
--- /dev/null | |
+++ b/OvmfPkg/CsmOld/LegacyBiosDxe/LegacyBios.h | |
@@ -0,0 +1,1518 @@ | |
+/** @file | |
+ The EFI Legacy BIOS Protocol is used to abstract legacy Option ROM usage | |
+ under EFI and Legacy OS boot. This file also includes all the related | |
+ COMPATIBILIY16 structures and defintions. | |
+ | |
+ Note: The names for EFI_IA32_REGISTER_SET elements were picked to follow | |
+ well known naming conventions. | |
+ | |
+ Thunk is the code that switches from 32-bit protected environment into the 16-bit real-mode | |
+ environment. Reverse thunk is the code that does the opposite. | |
+ | |
+Copyright (c) 2007 - 2010, 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 that 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. | |
+ | |
+ @par Revision Reference: | |
+ This protocol is defined in Framework for EFI Compatibility Support Module spec | |
+ Version 0.97. | |
+ | |
+**/ | |
+ | |
+#ifndef _EFI_LEGACY_BIOS_H_ | |
+#define _EFI_LEGACY_BIOS_H_ | |
+ | |
+/// | |
+/// | |
+/// | |
+#pragma pack(1) | |
+ | |
+typedef UINT8 SERIAL_MODE; | |
+typedef UINT8 PARALLEL_MODE; | |
+ | |
+#define EFI_COMPATIBILITY16_TABLE_SIGNATURE SIGNATURE_32 ('I', 'F', 'E', '$') | |
+ | |
+/// | |
+/// There is a table located within the traditional BIOS in either the 0xF000:xxxx or 0xE000:xxxx | |
+/// physical address range. It is located on a 16-byte boundary and provides the physical address of the | |
+/// entry point for the Compatibility16 functions. These functions provide the platform-specific | |
+/// information that is required by the generic EfiCompatibility code. The functions are invoked via | |
+/// thunking by using EFI_LEGACY_BIOS_PROTOCOL.FarCall86() with the 32-bit physical | |
+/// entry point. | |
+/// | |
+typedef struct { | |
+ /// | |
+ /// The string "$EFI" denotes the start of the EfiCompatibility table. Byte 0 is "I," byte | |
+ /// 1 is "F," byte 2 is "E," and byte 3 is "$" and is normally accessed as a DWORD or UINT32. | |
+ /// | |
+ UINT32 Signature; | |
+ | |
+ /// | |
+ /// The value required such that byte checksum of TableLength equals zero. | |
+ /// | |
+ UINT8 TableChecksum; | |
+ | |
+ /// | |
+ /// The length of this table. | |
+ /// | |
+ UINT8 TableLength; | |
+ | |
+ /// | |
+ /// The major EFI revision for which this table was generated. | |
+ /// | |
+ UINT8 EfiMajorRevision; | |
+ | |
+ /// | |
+ /// The minor EFI revision for which this table was generated. | |
+ /// | |
+ UINT8 EfiMinorRevision; | |
+ | |
+ /// | |
+ /// The major revision of this table. | |
+ /// | |
+ UINT8 TableMajorRevision; | |
+ | |
+ /// | |
+ /// The minor revision of this table. | |
+ /// | |
+ UINT8 TableMinorRevision; | |
+ | |
+ /// | |
+ /// Reserved for future usage. | |
+ /// | |
+ UINT16 Reserved; | |
+ | |
+ /// | |
+ /// The segment of the entry point within the traditional BIOS for Compatibility16 functions. | |
+ /// | |
+ UINT16 Compatibility16CallSegment; | |
+ | |
+ /// | |
+ /// The offset of the entry point within the traditional BIOS for Compatibility16 functions. | |
+ /// | |
+ UINT16 Compatibility16CallOffset; | |
+ | |
+ /// | |
+ /// The segment of the entry point within the traditional BIOS for EfiCompatibility | |
+ /// to invoke the PnP installation check. | |
+ /// | |
+ UINT16 PnPInstallationCheckSegment; | |
+ | |
+ /// | |
+ /// The Offset of the entry point within the traditional BIOS for EfiCompatibility | |
+ /// to invoke the PnP installation check. | |
+ /// | |
+ UINT16 PnPInstallationCheckOffset; | |
+ | |
+ /// | |
+ /// EFI system resources table. Type EFI_SYSTEM_TABLE is defined in the IntelPlatform | |
+ ///Innovation Framework for EFI Driver Execution Environment Core Interface Specification (DXE CIS). | |
+ /// | |
+ UINT32 EfiSystemTable; | |
+ | |
+ /// | |
+ /// The address of an OEM-provided identifier string. The string is null terminated. | |
+ /// | |
+ UINT32 OemIdStringPointer; | |
+ | |
+ /// | |
+ /// The 32-bit physical address where ACPI RSD PTR is stored within the traditional | |
+ /// BIOS. The remained of the ACPI tables are located at their EFI addresses. The size | |
+ /// reserved is the maximum for ACPI 2.0. The EfiCompatibility will fill in the ACPI | |
+ /// RSD PTR with either the ACPI 1.0b or 2.0 values. | |
+ /// | |
+ UINT32 AcpiRsdPtrPointer; | |
+ | |
+ /// | |
+ /// The OEM revision number. Usage is undefined but provided for OEM module usage. | |
+ /// | |
+ UINT16 OemRevision; | |
+ | |
+ /// | |
+ /// The 32-bit physical address where INT15 E820 data is stored within the traditional | |
+ /// BIOS. The EfiCompatibility code will fill in the E820Pointer value and copy the | |
+ /// data to the indicated area. | |
+ /// | |
+ UINT32 E820Pointer; | |
+ | |
+ /// | |
+ /// The length of the E820 data and is filled in by the EfiCompatibility code. | |
+ /// | |
+ UINT32 E820Length; | |
+ | |
+ /// | |
+ /// The 32-bit physical address where the $PIR table is stored in the traditional BIOS. | |
+ /// The EfiCompatibility code will fill in the IrqRoutingTablePointer value and | |
+ /// copy the data to the indicated area. | |
+ /// | |
+ UINT32 IrqRoutingTablePointer; | |
+ | |
+ /// | |
+ /// The length of the $PIR table and is filled in by the EfiCompatibility code. | |
+ /// | |
+ UINT32 IrqRoutingTableLength; | |
+ | |
+ /// | |
+ /// The 32-bit physical address where the MP table is stored in the traditional BIOS. | |
+ /// The EfiCompatibility code will fill in the MpTablePtr value and copy the data | |
+ /// to the indicated area. | |
+ /// | |
+ UINT32 MpTablePtr; | |
+ | |
+ /// | |
+ /// The length of the MP table and is filled in by the EfiCompatibility code. | |
+ /// | |
+ UINT32 MpTableLength; | |
+ | |
+ /// | |
+ /// The segment of the OEM-specific INT table/code. | |
+ /// | |
+ UINT16 OemIntSegment; | |
+ | |
+ /// | |
+ /// The offset of the OEM-specific INT table/code. | |
+ /// | |
+ UINT16 OemIntOffset; | |
+ | |
+ /// | |
+ /// The segment of the OEM-specific 32-bit table/code. | |
+ /// | |
+ UINT16 Oem32Segment; | |
+ | |
+ /// | |
+ /// The offset of the OEM-specific 32-bit table/code. | |
+ /// | |
+ UINT16 Oem32Offset; | |
+ | |
+ /// | |
+ /// The segment of the OEM-specific 16-bit table/code. | |
+ /// | |
+ UINT16 Oem16Segment; | |
+ | |
+ /// | |
+ /// The offset of the OEM-specific 16-bit table/code. | |
+ /// | |
+ UINT16 Oem16Offset; | |
+ | |
+ /// | |
+ /// The segment of the TPM binary passed to 16-bit CSM. | |
+ /// | |
+ UINT16 TpmSegment; | |
+ | |
+ /// | |
+ /// The offset of the TPM binary passed to 16-bit CSM. | |
+ /// | |
+ UINT16 TpmOffset; | |
+ | |
+ /// | |
+ /// A pointer to a string identifying the independent BIOS vendor. | |
+ /// | |
+ UINT32 IbvPointer; | |
+ | |
+ /// | |
+ /// This field is NULL for all systems not supporting PCI Express. This field is the base | |
+ /// value of the start of the PCI Express memory-mapped configuration registers and | |
+ /// must be filled in prior to EfiCompatibility code issuing the Compatibility16 function | |
+ /// Compatibility16InitializeYourself(). | |
+ /// Compatibility16InitializeYourself() is defined in Compatability16 | |
+ /// Functions. | |
+ /// | |
+ UINT32 PciExpressBase; | |
+ | |
+ /// | |
+ /// Maximum PCI bus number assigned. | |
+ /// | |
+ UINT8 LastPciBus; | |
+ | |
+ /// | |
+ /// Start address of UMB RAM | |
+ /// | |
+ UINT32 UmaAddress; | |
+ | |
+ /// | |
+ /// Size of UMB RAM | |
+ /// | |
+ UINT32 UmaSize; | |
+ | |
+ /// | |
+ /// Start address of persistent allocation in high (>1MiB) memory | |
+ /// | |
+ UINT32 HiPermanentMemoryAddress; | |
+ | |
+ /// | |
+ /// Size of persistent allocation in high (>1MiB) memory | |
+ /// | |
+ UINT32 HiPermanentMemorySize; | |
+} EFI_COMPATIBILITY16_TABLE; | |
+ | |
+/// | |
+/// Functions provided by the CSM binary which communicate between the EfiCompatibility | |
+/// and Compatability16 code. | |
+/// | |
+/// Inconsistent with the specification here: | |
+/// The member's name started with "Compatibility16" [defined in Intel Framework | |
+/// Compatibility Support Module Specification / 0.97 version] | |
+/// has been changed to "Legacy16" since keeping backward compatible. | |
+/// | |
+typedef enum { | |
+ /// | |
+ /// Causes the Compatibility16 code to do any internal initialization required. | |
+ /// Input: | |
+ /// AX = Compatibility16InitializeYourself | |
+ /// ES:BX = Pointer to EFI_TO_COMPATIBILITY16_INIT_TABLE | |
+ /// Return: | |
+ /// AX = Return Status codes | |
+ /// | |
+ Legacy16InitializeYourself = 0x0000, | |
+ | |
+ /// | |
+ /// Causes the Compatibility16 BIOS to perform any drive number translations to match the boot sequence. | |
+ /// Input: | |
+ /// AX = Compatibility16UpdateBbs | |
+ /// ES:BX = Pointer to EFI_TO_COMPATIBILITY16_BOOT_TABLE | |
+ /// Return: | |
+ /// AX = Returned status codes | |
+ /// | |
+ Legacy16UpdateBbs = 0x0001, | |
+ | |
+ /// | |
+ /// Allows the Compatibility16 code to perform any final actions before booting. The Compatibility16 | |
+ /// code is read/write. | |
+ /// Input: | |
+ /// AX = Compatibility16PrepareToBoot | |
+ /// ES:BX = Pointer to EFI_TO_COMPATIBILITY16_BOOT_TABLE structure | |
+ /// Return: | |
+ /// AX = Returned status codes | |
+ /// | |
+ Legacy16PrepareToBoot = 0x0002, | |
+ | |
+ /// | |
+ /// Causes the Compatibility16 BIOS to boot. The Compatibility16 code is Read/Only. | |
+ /// Input: | |
+ /// AX = Compatibility16Boot | |
+ /// Output: | |
+ /// AX = Returned status codes | |
+ /// | |
+ Legacy16Boot = 0x0003, | |
+ | |
+ /// | |
+ /// Allows the Compatibility16 code to get the last device from which a boot was attempted. This is | |
+ /// stored in CMOS and is the priority number of the last attempted boot device. | |
+ /// Input: | |
+ /// AX = Compatibility16RetrieveLastBootDevice | |
+ /// Output: | |
+ /// AX = Returned status codes | |
+ /// BX = Priority number of the boot device. | |
+ /// | |
+ Legacy16RetrieveLastBootDevice = 0x0004, | |
+ | |
+ /// | |
+ /// Allows the Compatibility16 code rehook INT13, INT18, and/or INT19 after dispatching a legacy OpROM. | |
+ /// Input: | |
+ /// AX = Compatibility16DispatchOprom | |
+ /// ES:BX = Pointer to EFI_DISPATCH_OPROM_TABLE | |
+ /// Output: | |
+ /// AX = Returned status codes | |
+ /// BX = Number of non-BBS-compliant devices found. Equals 0 if BBS compliant. | |
+ /// | |
+ Legacy16DispatchOprom = 0x0005, | |
+ | |
+ /// | |
+ /// Finds a free area in the 0xFxxxx or 0xExxxx region of the specified length and returns the address | |
+ /// of that region. | |
+ /// Input: | |
+ /// AX = Compatibility16GetTableAddress | |
+ /// BX = Allocation region | |
+ /// 00 = Allocate from either 0xE0000 or 0xF0000 64 KB blocks. | |
+ /// Bit 0 = 1 Allocate from 0xF0000 64 KB block | |
+ /// Bit 1 = 1 Allocate from 0xE0000 64 KB block | |
+ /// CX = Requested length in bytes. | |
+ /// DX = Required address alignment. Bit mapped. First non-zero bit from the right is the alignment. | |
+ /// Output: | |
+ /// AX = Returned status codes | |
+ /// DS:BX = Address of the region | |
+ /// | |
+ Legacy16GetTableAddress = 0x0006, | |
+ | |
+ /// | |
+ /// Enables the EfiCompatibility module to do any nonstandard processing of keyboard LEDs or state. | |
+ /// Input: | |
+ /// AX = Compatibility16SetKeyboardLeds | |
+ /// CL = LED status. | |
+ /// Bit 0 Scroll Lock 0 = Off | |
+ /// Bit 1 NumLock | |
+ /// Bit 2 Caps Lock | |
+ /// Output: | |
+ /// AX = Returned status codes | |
+ /// | |
+ Legacy16SetKeyboardLeds = 0x0007, | |
+ | |
+ /// | |
+ /// Enables the EfiCompatibility module to install an interrupt handler for PCI mass media devices that | |
+ /// do not have an OpROM associated with them. An example is SATA. | |
+ /// Input: | |
+ /// AX = Compatibility16InstallPciHandler | |
+ /// ES:BX = Pointer to EFI_LEGACY_INSTALL_PCI_HANDLER structure | |
+ /// Output: | |
+ /// AX = Returned status codes | |
+ /// | |
+ Legacy16InstallPciHandler = 0x0008 | |
+} EFI_COMPATIBILITY_FUNCTIONS; | |
+ | |
+ | |
+/// | |
+/// EFI_DISPATCH_OPROM_TABLE | |
+/// | |
+typedef struct { | |
+ UINT16 PnPInstallationCheckSegment; ///< A pointer to the PnpInstallationCheck data structure. | |
+ UINT16 PnPInstallationCheckOffset; ///< A pointer to the PnpInstallationCheck data structure. | |
+ UINT16 OpromSegment; ///< The segment where the OpROM was placed. Offset is assumed to be 3. | |
+ UINT8 PciBus; ///< The PCI bus. | |
+ UINT8 PciDeviceFunction; ///< The PCI device * 0x08 | PCI function. | |
+ UINT8 NumberBbsEntries; ///< The number of valid BBS table entries upon entry and exit. The IBV code may | |
+ ///< increase this number, if BBS-compliant devices also hook INTs in order to force the | |
+ ///< OpROM BIOS Setup to be executed. | |
+ UINT32 BbsTablePointer; ///< A pointer to the BBS table. | |
+ UINT16 RuntimeSegment; ///< The segment where the OpROM can be relocated to. If this value is 0x0000, this | |
+ ///< means that the relocation of this run time code is not supported. | |
+ ///< Inconsistent with specification here: | |
+ ///< The member's name "OpromDestinationSegment" [defined in Intel Framework Compatibility Support Module Specification / 0.97 version] | |
+ ///< has been changed to "RuntimeSegment" since keeping backward compatible. | |
+ | |
+} EFI_DISPATCH_OPROM_TABLE; | |
+ | |
+/// | |
+/// EFI_TO_COMPATIBILITY16_INIT_TABLE | |
+/// | |
+typedef struct { | |
+ /// | |
+ /// Starting address of memory under 1 MB. The ending address is assumed to be 640 KB or 0x9FFFF. | |
+ /// | |
+ UINT32 BiosLessThan1MB; | |
+ | |
+ /// | |
+ /// The starting address of the high memory block. | |
+ /// | |
+ UINT32 HiPmmMemory; | |
+ | |
+ /// | |
+ /// The length of high memory block. | |
+ /// | |
+ UINT32 HiPmmMemorySizeInBytes; | |
+ | |
+ /// | |
+ /// The segment of the reverse thunk call code. | |
+ /// | |
+ UINT16 ReverseThunkCallSegment; | |
+ | |
+ /// | |
+ /// The offset of the reverse thunk call code. | |
+ /// | |
+ UINT16 ReverseThunkCallOffset; | |
+ | |
+ /// | |
+ /// The number of E820 entries copied to the Compatibility16 BIOS. | |
+ /// | |
+ UINT32 NumberE820Entries; | |
+ | |
+ /// | |
+ /// The amount of usable memory above 1 MB, e.g., E820 type 1 memory. | |
+ /// | |
+ UINT32 OsMemoryAbove1Mb; | |
+ | |
+ /// | |
+ /// The start of thunk code in main memory. Memory cannot be used by BIOS or PMM. | |
+ /// | |
+ UINT32 ThunkStart; | |
+ | |
+ /// | |
+ /// The size of the thunk code. | |
+ /// | |
+ UINT32 ThunkSizeInBytes; | |
+ | |
+ /// | |
+ /// Starting address of memory under 1 MB. | |
+ /// | |
+ UINT32 LowPmmMemory; | |
+ | |
+ /// | |
+ /// The length of low Memory block. | |
+ /// | |
+ UINT32 LowPmmMemorySizeInBytes; | |
+} EFI_TO_COMPATIBILITY16_INIT_TABLE; | |
+ | |
+/// | |
+/// DEVICE_PRODUCER_SERIAL. | |
+/// | |
+typedef struct { | |
+ UINT16 Address; ///< I/O address assigned to the serial port. | |
+ UINT8 Irq; ///< IRQ assigned to the serial port. | |
+ SERIAL_MODE Mode; ///< Mode of serial port. Values are defined below. | |
+} DEVICE_PRODUCER_SERIAL; | |
+ | |
+/// | |
+/// DEVICE_PRODUCER_SERIAL's modes. | |
+///@{ | |
+#define DEVICE_SERIAL_MODE_NORMAL 0x00 | |
+#define DEVICE_SERIAL_MODE_IRDA 0x01 | |
+#define DEVICE_SERIAL_MODE_ASK_IR 0x02 | |
+#define DEVICE_SERIAL_MODE_DUPLEX_HALF 0x00 | |
+#define DEVICE_SERIAL_MODE_DUPLEX_FULL 0x10 | |
+///@) | |
+ | |
+/// | |
+/// DEVICE_PRODUCER_PARALLEL. | |
+/// | |
+typedef struct { | |
+ UINT16 Address; ///< I/O address assigned to the parallel port. | |
+ UINT8 Irq; ///< IRQ assigned to the parallel port. | |
+ UINT8 Dma; ///< DMA assigned to the parallel port. | |
+ PARALLEL_MODE Mode; ///< Mode of the parallel port. Values are defined below. | |
+} DEVICE_PRODUCER_PARALLEL; | |
+ | |
+/// | |
+/// DEVICE_PRODUCER_PARALLEL's modes. | |
+///@{ | |
+#define DEVICE_PARALLEL_MODE_MODE_OUTPUT_ONLY 0x00 | |
+#define DEVICE_PARALLEL_MODE_MODE_BIDIRECTIONAL 0x01 | |
+#define DEVICE_PARALLEL_MODE_MODE_EPP 0x02 | |
+#define DEVICE_PARALLEL_MODE_MODE_ECP 0x03 | |
+///@} | |
+ | |
+/// | |
+/// DEVICE_PRODUCER_FLOPPY | |
+/// | |
+typedef struct { | |
+ UINT16 Address; ///< I/O address assigned to the floppy. | |
+ UINT8 Irq; ///< IRQ assigned to the floppy. | |
+ UINT8 Dma; ///< DMA assigned to the floppy. | |
+ UINT8 NumberOfFloppy; ///< Number of floppies in the system. | |
+} DEVICE_PRODUCER_FLOPPY; | |
+ | |
+/// | |
+/// LEGACY_DEVICE_FLAGS | |
+/// | |
+typedef struct { | |
+ UINT32 A20Kybd : 1; ///< A20 controller by keyboard controller. | |
+ UINT32 A20Port90 : 1; ///< A20 controlled by port 0x92. | |
+ UINT32 Reserved : 30; ///< Reserved for future usage. | |
+} LEGACY_DEVICE_FLAGS; | |
+ | |
+/// | |
+/// DEVICE_PRODUCER_DATA_HEADER | |
+/// | |
+typedef struct { | |
+ DEVICE_PRODUCER_SERIAL Serial[4]; ///< Data for serial port x. Type DEVICE_PRODUCER_SERIAL is defined below. | |
+ DEVICE_PRODUCER_PARALLEL Parallel[3]; ///< Data for parallel port x. Type DEVICE_PRODUCER_PARALLEL is defined below. | |
+ DEVICE_PRODUCER_FLOPPY Floppy; ///< Data for floppy. Type DEVICE_PRODUCER_FLOPPY is defined below. | |
+ UINT8 MousePresent; ///< Flag to indicate if mouse is present. | |
+ LEGACY_DEVICE_FLAGS Flags; ///< Miscellaneous Boolean state information passed to CSM. | |
+} DEVICE_PRODUCER_DATA_HEADER; | |
+ | |
+/// | |
+/// ATAPI_IDENTIFY | |
+/// | |
+typedef struct { | |
+ UINT16 Raw[256]; ///< Raw data from the IDE IdentifyDrive command. | |
+} ATAPI_IDENTIFY; | |
+ | |
+/// | |
+/// HDD_INFO | |
+/// | |
+typedef struct { | |
+ /// | |
+ /// Status of IDE device. Values are defined below. There is one HDD_INFO structure | |
+ /// per IDE controller. The IdentifyDrive is per drive. Index 0 is master and index | |
+ /// 1 is slave. | |
+ /// | |
+ UINT16 Status; | |
+ | |
+ /// | |
+ /// PCI bus of IDE controller. | |
+ /// | |
+ UINT32 Bus; | |
+ | |
+ /// | |
+ /// PCI device of IDE controller. | |
+ /// | |
+ UINT32 Device; | |
+ | |
+ /// | |
+ /// PCI function of IDE controller. | |
+ /// | |
+ UINT32 Function; | |
+ | |
+ /// | |
+ /// Command ports base address. | |
+ /// | |
+ UINT16 CommandBaseAddress; | |
+ | |
+ /// | |
+ /// Control ports base address. | |
+ /// | |
+ UINT16 ControlBaseAddress; | |
+ | |
+ /// | |
+ /// Bus master address. | |
+ /// | |
+ UINT16 BusMasterAddress; | |
+ | |
+ UINT8 HddIrq; | |
+ | |
+ /// | |
+ /// Data that identifies the drive data; one per possible attached drive. | |
+ /// | |
+ ATAPI_IDENTIFY IdentifyDrive[2]; | |
+} HDD_INFO; | |
+ | |
+/// | |
+/// HDD_INFO status bits | |
+/// | |
+#define HDD_PRIMARY 0x01 | |
+#define HDD_SECONDARY 0x02 | |
+#define HDD_MASTER_ATAPI_CDROM 0x04 | |
+#define HDD_SLAVE_ATAPI_CDROM 0x08 | |
+#define HDD_MASTER_IDE 0x20 | |
+#define HDD_SLAVE_IDE 0x40 | |
+#define HDD_MASTER_ATAPI_ZIPDISK 0x10 | |
+#define HDD_SLAVE_ATAPI_ZIPDISK 0x80 | |
+ | |
+/// | |
+/// BBS_STATUS_FLAGS;\. | |
+/// | |
+typedef struct { | |
+ UINT16 OldPosition : 4; ///< Prior priority. | |
+ UINT16 Reserved1 : 4; ///< Reserved for future use. | |
+ UINT16 Enabled : 1; ///< If 0, ignore this entry. | |
+ UINT16 Failed : 1; ///< 0 = Not known if boot failure occurred. | |
+ ///< 1 = Boot attempted failed. | |
+ | |
+ /// | |
+ /// State of media present. | |
+ /// 00 = No bootable media is present in the device. | |
+ /// 01 = Unknown if a bootable media present. | |
+ /// 10 = Media is present and appears bootable. | |
+ /// 11 = Reserved. | |
+ /// | |
+ UINT16 MediaPresent : 2; | |
+ UINT16 Reserved2 : 4; ///< Reserved for future use. | |
+} BBS_STATUS_FLAGS; | |
+ | |
+/// | |
+/// BBS_TABLE, device type values & boot priority values. | |
+/// | |
+typedef struct { | |
+ /// | |
+ /// The boot priority for this boot device. Values are defined below. | |
+ /// | |
+ UINT16 BootPriority; | |
+ | |
+ /// | |
+ /// The PCI bus for this boot device. | |
+ /// | |
+ UINT32 Bus; | |
+ | |
+ /// | |
+ /// The PCI device for this boot device. | |
+ /// | |
+ UINT32 Device; | |
+ | |
+ /// | |
+ /// The PCI function for the boot device. | |
+ /// | |
+ UINT32 Function; | |
+ | |
+ /// | |
+ /// The PCI class for this boot device. | |
+ /// | |
+ UINT8 Class; | |
+ | |
+ /// | |
+ /// The PCI Subclass for this boot device. | |
+ /// | |
+ UINT8 SubClass; | |
+ | |
+ /// | |
+ /// Segment:offset address of an ASCIIZ description string describing the manufacturer. | |
+ /// | |
+ UINT16 MfgStringOffset; | |
+ | |
+ /// | |
+ /// Segment:offset address of an ASCIIZ description string describing the manufacturer. | |
+ /// | |
+ UINT16 MfgStringSegment; | |
+ | |
+ /// | |
+ /// BBS device type. BBS device types are defined below. | |
+ /// | |
+ UINT16 DeviceType; | |
+ | |
+ /// | |
+ /// Status of this boot device. Type BBS_STATUS_FLAGS is defined below. | |
+ /// | |
+ BBS_STATUS_FLAGS StatusFlags; | |
+ | |
+ /// | |
+ /// Segment:Offset address of boot loader for IPL devices or install INT13 handler for | |
+ /// BCV devices. | |
+ /// | |
+ UINT16 BootHandlerOffset; | |
+ | |
+ /// | |
+ /// Segment:Offset address of boot loader for IPL devices or install INT13 handler for | |
+ /// BCV devices. | |
+ /// | |
+ UINT16 BootHandlerSegment; | |
+ | |
+ /// | |
+ /// Segment:offset address of an ASCIIZ description string describing this device. | |
+ /// | |
+ UINT16 DescStringOffset; | |
+ | |
+ /// | |
+ /// Segment:offset address of an ASCIIZ description string describing this device. | |
+ /// | |
+ UINT16 DescStringSegment; | |
+ | |
+ /// | |
+ /// Reserved. | |
+ /// | |
+ UINT32 InitPerReserved; | |
+ | |
+ /// | |
+ /// The use of these fields is IBV dependent. They can be used to flag that an OpROM | |
+ /// has hooked the specified IRQ. The OpROM may be BBS compliant as some SCSI | |
+ /// BBS-compliant OpROMs also hook IRQ vectors in order to run their BIOS Setup | |
+ /// | |
+ UINT32 AdditionalIrq13Handler; | |
+ | |
+ /// | |
+ /// The use of these fields is IBV dependent. They can be used to flag that an OpROM | |
+ /// has hooked the specified IRQ. The OpROM may be BBS compliant as some SCSI | |
+ /// BBS-compliant OpROMs also hook IRQ vectors in order to run their BIOS Setup | |
+ /// | |
+ UINT32 AdditionalIrq18Handler; | |
+ | |
+ /// | |
+ /// The use of these fields is IBV dependent. They can be used to flag that an OpROM | |
+ /// has hooked the specified IRQ. The OpROM may be BBS compliant as some SCSI | |
+ /// BBS-compliant OpROMs also hook IRQ vectors in order to run their BIOS Setup | |
+ /// | |
+ UINT32 AdditionalIrq19Handler; | |
+ | |
+ /// | |
+ /// The use of these fields is IBV dependent. They can be used to flag that an OpROM | |
+ /// has hooked the specified IRQ. The OpROM may be BBS compliant as some SCSI | |
+ /// BBS-compliant OpROMs also hook IRQ vectors in order to run their BIOS Setup | |
+ /// | |
+ UINT32 AdditionalIrq40Handler; | |
+ UINT8 AssignedDriveNumber; | |
+ UINT32 AdditionalIrq41Handler; | |
+ UINT32 AdditionalIrq46Handler; | |
+ UINT32 IBV1; | |
+ UINT32 IBV2; | |
+} BBS_TABLE; | |
+ | |
+/// | |
+/// BBS device type values | |
+///@{ | |
+#define BBS_FLOPPY 0x01 | |
+#define BBS_HARDDISK 0x02 | |
+#define BBS_CDROM 0x03 | |
+#define BBS_PCMCIA 0x04 | |
+#define BBS_USB 0x05 | |
+#define BBS_EMBED_NETWORK 0x06 | |
+#define BBS_BEV_DEVICE 0x80 | |
+#define BBS_UNKNOWN 0xff | |
+///@} | |
+ | |
+/// | |
+/// BBS boot priority values | |
+///@{ | |
+#define BBS_DO_NOT_BOOT_FROM 0xFFFC | |
+#define BBS_LOWEST_PRIORITY 0xFFFD | |
+#define BBS_UNPRIORITIZED_ENTRY 0xFFFE | |
+#define BBS_IGNORE_ENTRY 0xFFFF | |
+///@} | |
+ | |
+/// | |
+/// SMM_ATTRIBUTES | |
+/// | |
+typedef struct { | |
+ /// | |
+ /// Access mechanism used to generate the soft SMI. Defined types are below. The other | |
+ /// values are reserved for future usage. | |
+ /// | |
+ UINT16 Type : 3; | |
+ | |
+ /// | |
+ /// The size of "port" in bits. Defined values are below. | |
+ /// | |
+ UINT16 PortGranularity : 3; | |
+ | |
+ /// | |
+ /// The size of data in bits. Defined values are below. | |
+ /// | |
+ UINT16 DataGranularity : 3; | |
+ | |
+ /// | |
+ /// Reserved for future use. | |
+ /// | |
+ UINT16 Reserved : 7; | |
+} SMM_ATTRIBUTES; | |
+ | |
+/// | |
+/// SMM_ATTRIBUTES type values. | |
+///@{ | |
+#define STANDARD_IO 0x00 | |
+#define STANDARD_MEMORY 0x01 | |
+///@} | |
+ | |
+/// | |
+/// SMM_ATTRIBUTES port size constants. | |
+///@{ | |
+#define PORT_SIZE_8 0x00 | |
+#define PORT_SIZE_16 0x01 | |
+#define PORT_SIZE_32 0x02 | |
+#define PORT_SIZE_64 0x03 | |
+///@} | |
+ | |
+/// | |
+/// SMM_ATTRIBUTES data size constants. | |
+///@{ | |
+#define DATA_SIZE_8 0x00 | |
+#define DATA_SIZE_16 0x01 | |
+#define DATA_SIZE_32 0x02 | |
+#define DATA_SIZE_64 0x03 | |
+///@} | |
+ | |
+/// | |
+/// SMM_FUNCTION & relating constants. | |
+/// | |
+typedef struct { | |
+ UINT16 Function : 15; | |
+ UINT16 Owner : 1; | |
+} SMM_FUNCTION; | |
+ | |
+/// | |
+/// SMM_FUNCTION Function constants. | |
+///@{ | |
+#define INT15_D042 0x0000 | |
+#define GET_USB_BOOT_INFO 0x0001 | |
+#define DMI_PNP_50_57 0x0002 | |
+///@} | |
+ | |
+/// | |
+/// SMM_FUNCTION Owner constants. | |
+///@{ | |
+#define STANDARD_OWNER 0x0 | |
+#define OEM_OWNER 0x1 | |
+///@} | |
+ | |
+/// | |
+/// This structure assumes both port and data sizes are 1. SmmAttribute must be | |
+/// properly to reflect that assumption. | |
+/// | |
+typedef struct { | |
+ /// | |
+ /// Describes the access mechanism, SmmPort, and SmmData sizes. Type | |
+ /// SMM_ATTRIBUTES is defined below. | |
+ /// | |
+ SMM_ATTRIBUTES SmmAttributes; | |
+ | |
+ /// | |
+ /// Function Soft SMI is to perform. Type SMM_FUNCTION is defined below. | |
+ /// | |
+ SMM_FUNCTION SmmFunction; | |
+ | |
+ /// | |
+ /// SmmPort size depends upon SmmAttributes and ranges from2 bytes to 16 bytes. | |
+ /// | |
+ UINT8 SmmPort; | |
+ | |
+ /// | |
+ /// SmmData size depends upon SmmAttributes and ranges from2 bytes to 16 bytes. | |
+ /// | |
+ UINT8 SmmData; | |
+} SMM_ENTRY; | |
+ | |
+/// | |
+/// SMM_TABLE | |
+/// | |
+typedef struct { | |
+ UINT16 NumSmmEntries; ///< Number of entries represented by SmmEntry. | |
+ SMM_ENTRY SmmEntry; ///< One entry per function. Type SMM_ENTRY is defined below. | |
+} SMM_TABLE; | |
+ | |
+/// | |
+/// UDC_ATTRIBUTES | |
+/// | |
+typedef struct { | |
+ /// | |
+ /// This bit set indicates that the ServiceAreaData is valid. | |
+ /// | |
+ UINT8 DirectoryServiceValidity : 1; | |
+ | |
+ /// | |
+ /// This bit set indicates to use the Reserve Area Boot Code Address (RACBA) only if | |
+ /// DirectoryServiceValidity is 0. | |
+ /// | |
+ UINT8 RabcaUsedFlag : 1; | |
+ | |
+ /// | |
+ /// This bit set indicates to execute hard disk diagnostics. | |
+ /// | |
+ UINT8 ExecuteHddDiagnosticsFlag : 1; | |
+ | |
+ /// | |
+ /// Reserved for future use. Set to 0. | |
+ /// | |
+ UINT8 Reserved : 5; | |
+} UDC_ATTRIBUTES; | |
+ | |
+/// | |
+/// UD_TABLE | |
+/// | |
+typedef struct { | |
+ /// | |
+ /// This field contains the bit-mapped attributes of the PARTIES information. Type | |
+ /// UDC_ATTRIBUTES is defined below. | |
+ /// | |
+ UDC_ATTRIBUTES Attributes; | |
+ | |
+ /// | |
+ /// This field contains the zero-based device on which the selected | |
+ /// ServiceDataArea is present. It is 0 for master and 1 for the slave device. | |
+ /// | |
+ UINT8 DeviceNumber; | |
+ | |
+ /// | |
+ /// This field contains the zero-based index into the BbsTable for the parent device. | |
+ /// This index allows the user to reference the parent device information such as PCI | |
+ /// bus, device function. | |
+ /// | |
+ UINT8 BbsTableEntryNumberForParentDevice; | |
+ | |
+ /// | |
+ /// This field contains the zero-based index into the BbsTable for the boot entry. | |
+ /// | |
+ UINT8 BbsTableEntryNumberForBoot; | |
+ | |
+ /// | |
+ /// This field contains the zero-based index into the BbsTable for the HDD diagnostics entry. | |
+ /// | |
+ UINT8 BbsTableEntryNumberForHddDiag; | |
+ | |
+ /// | |
+ /// The raw Beer data. | |
+ /// | |
+ UINT8 BeerData[128]; | |
+ | |
+ /// | |
+ /// The raw data of selected service area. | |
+ /// | |
+ UINT8 ServiceAreaData[64]; | |
+} UD_TABLE; | |
+ | |
+#define EFI_TO_LEGACY_MAJOR_VERSION 0x02 | |
+#define EFI_TO_LEGACY_MINOR_VERSION 0x00 | |
+#define MAX_IDE_CONTROLLER 8 | |
+ | |
+/// | |
+/// EFI_TO_COMPATIBILITY16_BOOT_TABLE | |
+/// | |
+typedef struct { | |
+ UINT16 MajorVersion; ///< The EfiCompatibility major version number. | |
+ UINT16 MinorVersion; ///< The EfiCompatibility minor version number. | |
+ UINT32 AcpiTable; ///< The location of the RSDT ACPI table. < 4G range. | |
+ UINT32 SmbiosTable; ///< The location of the SMBIOS table in EFI memory. < 4G range. | |
+ UINT32 SmbiosTableLength; | |
+ // | |
+ // Legacy SIO state | |
+ // | |
+ DEVICE_PRODUCER_DATA_HEADER SioData; ///< Standard traditional device information. | |
+ UINT16 DevicePathType; ///< The default boot type. | |
+ UINT16 PciIrqMask; ///< Mask of which IRQs have been assigned to PCI. | |
+ UINT32 NumberE820Entries; ///< Number of E820 entries. The number can change from the | |
+ ///< Compatibility16InitializeYourself() function. | |
+ // | |
+ // Controller & Drive Identify[2] per controller information | |
+ // | |
+ HDD_INFO HddInfo[MAX_IDE_CONTROLLER]; ///< Hard disk drive information, including raw Identify Drive data. | |
+ UINT32 NumberBbsEntries; ///< Number of entries in the BBS table | |
+ UINT32 BbsTable; ///< A pointer to the BBS table. Type BBS_TABLE is defined below. | |
+ UINT32 SmmTable; ///< A pointer to the SMM table. Type SMM_TABLE is defined below. | |
+ UINT32 OsMemoryAbove1Mb; ///< The amount of usable memory above 1 MB, i.e. E820 type 1 memory. This value can | |
+ ///< differ from the value in EFI_TO_COMPATIBILITY16_INIT_TABLE as more | |
+ ///< memory may have been discovered. | |
+ UINT32 UnconventionalDeviceTable; ///< Information to boot off an unconventional device like a PARTIES partition. Type | |
+ ///< UD_TABLE is defined below. | |
+} EFI_TO_COMPATIBILITY16_BOOT_TABLE; | |
+ | |
+/// | |
+/// EFI_LEGACY_INSTALL_PCI_HANDLER | |
+/// | |
+typedef struct { | |
+ UINT8 PciBus; ///< The PCI bus of the device. | |
+ UINT8 PciDeviceFun; ///< The PCI device in bits 7:3 and function in bits 2:0. | |
+ UINT8 PciSegment; ///< The PCI segment of the device. | |
+ UINT8 PciClass; ///< The PCI class code of the device. | |
+ UINT8 PciSubclass; ///< The PCI subclass code of the device. | |
+ UINT8 PciInterface; ///< The PCI interface code of the device. | |
+ // | |
+ // Primary section | |
+ // | |
+ UINT8 PrimaryIrq; ///< The primary device IRQ. | |
+ UINT8 PrimaryReserved; ///< Reserved. | |
+ UINT16 PrimaryControl; ///< The primary device control I/O base. | |
+ UINT16 PrimaryBase; ///< The primary device I/O base. | |
+ UINT16 PrimaryBusMaster; ///< The primary device bus master I/O base. | |
+ // | |
+ // Secondary Section | |
+ // | |
+ UINT8 SecondaryIrq; ///< The secondary device IRQ. | |
+ UINT8 SecondaryReserved; ///< Reserved. | |
+ UINT16 SecondaryControl; ///< The secondary device control I/O base. | |
+ UINT16 SecondaryBase; ///< The secondary device I/O base. | |
+ UINT16 SecondaryBusMaster; ///< The secondary device bus master I/O base. | |
+} EFI_LEGACY_INSTALL_PCI_HANDLER; | |
+ | |
+// | |
+// Restore default pack value | |
+// | |
+#pragma pack() | |
+ | |
+#define EFI_LEGACY_BIOS_PROTOCOL_GUID \ | |
+ { \ | |
+ 0xdb9a1e3d, 0x45cb, 0x4abb, {0x85, 0x3b, 0xe5, 0x38, 0x7f, 0xdb, 0x2e, 0x2d } \ | |
+ } | |
+ | |
+typedef struct _EFI_LEGACY_BIOS_PROTOCOL EFI_LEGACY_BIOS_PROTOCOL; | |
+ | |
+/// | |
+/// Flags returned by CheckPciRom(). | |
+/// | |
+#define NO_ROM 0x00 | |
+#define ROM_FOUND 0x01 | |
+#define VALID_LEGACY_ROM 0x02 | |
+#define ROM_WITH_CONFIG 0x04 ///< Not defined in the Framework CSM Specification. | |
+ | |
+/// | |
+/// The following macros do not appear in the Framework CSM Specification and | |
+/// are kept for backward compatibility only. They convert 32-bit address (_Adr) | |
+/// to Segment:Offset 16-bit form. | |
+/// | |
+///@{ | |
+#define EFI_SEGMENT(_Adr) (UINT16) ((UINT16) (((UINTN) (_Adr)) >> 4) & 0xf000) | |
+#define EFI_OFFSET(_Adr) (UINT16) (((UINT16) ((UINTN) (_Adr))) & 0xffff) | |
+///@} | |
+ | |
+#define CARRY_FLAG 0x01 | |
+ | |
+/// | |
+/// EFI_EFLAGS_REG | |
+/// | |
+typedef struct { | |
+ UINT32 CF:1; | |
+ UINT32 Reserved1:1; | |
+ UINT32 PF:1; | |
+ UINT32 Reserved2:1; | |
+ UINT32 AF:1; | |
+ UINT32 Reserved3:1; | |
+ UINT32 ZF:1; | |
+ UINT32 SF:1; | |
+ UINT32 TF:1; | |
+ UINT32 IF:1; | |
+ UINT32 DF:1; | |
+ UINT32 OF:1; | |
+ UINT32 IOPL:2; | |
+ UINT32 NT:1; | |
+ UINT32 Reserved4:2; | |
+ UINT32 VM:1; | |
+ UINT32 Reserved5:14; | |
+} EFI_EFLAGS_REG; | |
+ | |
+/// | |
+/// EFI_DWORD_REGS | |
+/// | |
+typedef struct { | |
+ UINT32 EAX; | |
+ UINT32 EBX; | |
+ UINT32 ECX; | |
+ UINT32 EDX; | |
+ UINT32 ESI; | |
+ UINT32 EDI; | |
+ EFI_EFLAGS_REG EFlags; | |
+ UINT16 ES; | |
+ UINT16 CS; | |
+ UINT16 SS; | |
+ UINT16 DS; | |
+ UINT16 FS; | |
+ UINT16 GS; | |
+ UINT32 EBP; | |
+ UINT32 ESP; | |
+} EFI_DWORD_REGS; | |
+ | |
+/// | |
+/// EFI_FLAGS_REG | |
+/// | |
+typedef struct { | |
+ UINT16 CF:1; | |
+ UINT16 Reserved1:1; | |
+ UINT16 PF:1; | |
+ UINT16 Reserved2:1; | |
+ UINT16 AF:1; | |
+ UINT16 Reserved3:1; | |
+ UINT16 ZF:1; | |
+ UINT16 SF:1; | |
+ UINT16 TF:1; | |
+ UINT16 IF:1; | |
+ UINT16 DF:1; | |
+ UINT16 OF:1; | |
+ UINT16 IOPL:2; | |
+ UINT16 NT:1; | |
+ UINT16 Reserved4:1; | |
+} EFI_FLAGS_REG; | |
+ | |
+/// | |
+/// EFI_WORD_REGS | |
+/// | |
+typedef struct { | |
+ UINT16 AX; | |
+ UINT16 ReservedAX; | |
+ UINT16 BX; | |
+ UINT16 ReservedBX; | |
+ UINT16 CX; | |
+ UINT16 ReservedCX; | |
+ UINT16 DX; | |
+ UINT16 ReservedDX; | |
+ UINT16 SI; | |
+ UINT16 ReservedSI; | |
+ UINT16 DI; | |
+ UINT16 ReservedDI; | |
+ EFI_FLAGS_REG Flags; | |
+ UINT16 ReservedFlags; | |
+ UINT16 ES; | |
+ UINT16 CS; | |
+ UINT16 SS; | |
+ UINT16 DS; | |
+ UINT16 FS; | |
+ UINT16 GS; | |
+ UINT16 BP; | |
+ UINT16 ReservedBP; | |
+ UINT16 SP; | |
+ UINT16 ReservedSP; | |
+} EFI_WORD_REGS; | |
+ | |
+/// | |
+/// EFI_BYTE_REGS | |
+/// | |
+typedef struct { | |
+ UINT8 AL, AH; | |
+ UINT16 ReservedAX; | |
+ UINT8 BL, BH; | |
+ UINT16 ReservedBX; | |
+ UINT8 CL, CH; | |
+ UINT16 ReservedCX; | |
+ UINT8 DL, DH; | |
+ UINT16 ReservedDX; | |
+} EFI_BYTE_REGS; | |
+ | |
+/// | |
+/// EFI_IA32_REGISTER_SET | |
+/// | |
+typedef union { | |
+ EFI_DWORD_REGS E; | |
+ EFI_WORD_REGS X; | |
+ EFI_BYTE_REGS H; | |
+} EFI_IA32_REGISTER_SET; | |
+ | |
+/** | |
+ Thunk to 16-bit real mode and execute a software interrupt with a vector | |
+ of BiosInt. Regs will contain the 16-bit register context on entry and | |
+ exit. | |
+ | |
+ @param[in] This The protocol instance pointer. | |
+ @param[in] BiosInt The processor interrupt vector to invoke. | |
+ @param[in,out] Reg Register contexted passed into (and returned) from thunk to | |
+ 16-bit mode. | |
+ | |
+ @retval TRUE Thunk completed with no BIOS errors in the target code. See Regs for status. | |
+ @retval FALSE There was a BIOS error in the target code. | |
+**/ | |
+typedef | |
+BOOLEAN | |
+(EFIAPI *EFI_LEGACY_BIOS_INT86)( | |
+ IN EFI_LEGACY_BIOS_PROTOCOL *This, | |
+ IN UINT8 BiosInt, | |
+ IN OUT EFI_IA32_REGISTER_SET *Regs | |
+ ); | |
+ | |
+/** | |
+ Thunk to 16-bit real mode and call Segment:Offset. Regs will contain the | |
+ 16-bit register context on entry and exit. Arguments can be passed on | |
+ the Stack argument | |
+ | |
+ @param[in] This The protocol instance pointer. | |
+ @param[in] Segment The segemnt of 16-bit mode call. | |
+ @param[in] Offset The offset of 16-bit mdoe call. | |
+ @param[in] Reg Register contexted passed into (and returned) from thunk to | |
+ 16-bit mode. | |
+ @param[in] Stack The caller allocated stack used to pass arguments. | |
+ @param[in] StackSize The size of Stack in bytes. | |
+ | |
+ @retval FALSE Thunk completed with no BIOS errors in the target code. See Regs for status. @retval TRUE There was a BIOS error in the target code. | |
+**/ | |
+typedef | |
+BOOLEAN | |
+(EFIAPI *EFI_LEGACY_BIOS_FARCALL86)( | |
+ IN EFI_LEGACY_BIOS_PROTOCOL *This, | |
+ IN UINT16 Segment, | |
+ IN UINT16 Offset, | |
+ IN EFI_IA32_REGISTER_SET *Regs, | |
+ IN VOID *Stack, | |
+ IN UINTN StackSize | |
+ ); | |
+ | |
+/** | |
+ Test to see if a legacy PCI ROM exists for this device. Optionally return | |
+ the Legacy ROM instance for this PCI device. | |
+ | |
+ @param[in] This The protocol instance pointer. | |
+ @param[in] PciHandle The PCI PC-AT OPROM from this devices ROM BAR will be loaded | |
+ @param[out] RomImage Return the legacy PCI ROM for this device. | |
+ @param[out] RomSize The size of ROM Image. | |
+ @param[out] Flags Indicates if ROM found and if PC-AT. Multiple bits can be set as follows: | |
+ - 00 = No ROM. | |
+ - 01 = ROM Found. | |
+ - 02 = ROM is a valid legacy ROM. | |
+ | |
+ @retval EFI_SUCCESS The Legacy Option ROM availible for this device | |
+ @retval EFI_UNSUPPORTED The Legacy Option ROM is not supported. | |
+ | |
+**/ | |
+typedef | |
+EFI_STATUS | |
+(EFIAPI *EFI_LEGACY_BIOS_CHECK_ROM)( | |
+ IN EFI_LEGACY_BIOS_PROTOCOL *This, | |
+ IN EFI_HANDLE PciHandle, | |
+ OUT VOID **RomImage, OPTIONAL | |
+ OUT UINTN *RomSize, OPTIONAL | |
+ OUT UINTN *Flags | |
+ ); | |
+ | |
+/** | |
+ Load a legacy PC-AT OPROM on the PciHandle device. Return information | |
+ about how many disks were added by the OPROM and the shadow address and | |
+ size. DiskStart & DiskEnd are INT 13h drive letters. Thus 0x80 is C: | |
+ | |
+ @param[in] This The protocol instance pointer. | |
+ @param[in] PciHandle The PCI PC-AT OPROM from this devices ROM BAR will be loaded. | |
+ This value is NULL if RomImage is non-NULL. This is the normal | |
+ case. | |
+ @param[in] RomImage A PCI PC-AT ROM image. This argument is non-NULL if there is | |
+ no hardware associated with the ROM and thus no PciHandle, | |
+ otherwise is must be NULL. | |
+ Example is PXE base code. | |
+ @param[out] Flags The type of ROM discovered. Multiple bits can be set, as follows: | |
+ - 00 = No ROM. | |
+ - 01 = ROM found. | |
+ - 02 = ROM is a valid legacy ROM. | |
+ @param[out] DiskStart The disk number of first device hooked by the ROM. If DiskStart | |
+ is the same as DiskEnd no disked were hooked. | |
+ @param[out] DiskEnd disk number of the last device hooked by the ROM. | |
+ @param[out] RomShadowAddress Shadow address of PC-AT ROM. | |
+ @param[out] RomShadowSize Size of RomShadowAddress in bytes. | |
+ | |
+ @retval EFI_SUCCESS Thunk completed, see Regs for status. | |
+ @retval EFI_INVALID_PARAMETER PciHandle not found | |
+ | |
+**/ | |
+typedef | |
+EFI_STATUS | |
+(EFIAPI *EFI_LEGACY_BIOS_INSTALL_ROM)( | |
+ IN EFI_LEGACY_BIOS_PROTOCOL *This, | |
+ IN EFI_HANDLE PciHandle, | |
+ IN VOID **RomImage, | |
+ OUT UINTN *Flags, | |
+ OUT UINT8 *DiskStart, OPTIONAL | |
+ OUT UINT8 *DiskEnd, OPTIONAL | |
+ OUT VOID **RomShadowAddress, OPTIONAL | |
+ OUT UINT32 *ShadowedRomSize OPTIONAL | |
+ ); | |
+ | |
+/** | |
+ This function attempts to traditionally boot the specified BootOption. If the EFI context has | |
+ been compromised, this function will not return. This procedure is not used for loading an EFI-aware | |
+ OS off a traditional device. The following actions occur: | |
+ - Get EFI SMBIOS data structures, convert them to a traditional format, and copy to | |
+ Compatibility16. | |
+ - Get a pointer to ACPI data structures and copy the Compatibility16 RSD PTR to F0000 block. | |
+ - Find the traditional SMI handler from a firmware volume and register the traditional SMI | |
+ handler with the EFI SMI handler. | |
+ - Build onboard IDE information and pass this information to the Compatibility16 code. | |
+ - Make sure all PCI Interrupt Line registers are programmed to match 8259. | |
+ - Reconfigure SIO devices from EFI mode (polled) into traditional mode (interrupt driven). | |
+ - Shadow all PCI ROMs. | |
+ - Set up BDA and EBDA standard areas before the legacy boot. | |
+ - Construct the Compatibility16 boot memory map and pass it to the Compatibility16 code. | |
+ - Invoke the Compatibility16 table function Compatibility16PrepareToBoot(). This | |
+ invocation causes a thunk into the Compatibility16 code, which sets all appropriate internal | |
+ data structures. The boot device list is a parameter. | |
+ - Invoke the Compatibility16 Table function Compatibility16Boot(). This invocation | |
+ causes a thunk into the Compatibility16 code, which does an INT19. | |
+ - If the Compatibility16Boot() function returns, then the boot failed in a graceful | |
+ manner--meaning that the EFI code is still valid. An ungraceful boot failure causes a reset because the state | |
+ of EFI code is unknown. | |
+ | |
+ @param[in] This The protocol instance pointer. | |
+ @param[in] BootOption The EFI Device Path from BootXXXX variable. | |
+ @param[in] LoadOptionSize The size of LoadOption in size. | |
+ @param[in] LoadOption LThe oadOption from BootXXXX variable. | |
+ | |
+ @retval EFI_DEVICE_ERROR Failed to boot from any boot device and memory is uncorrupted. Note: This function normally does not returns. It will either boot the OS or reset the system if memory has been "corrupted" by loading a boot sector and passing control to it. | |
+**/ | |
+typedef | |
+EFI_STATUS | |
+(EFIAPI *EFI_LEGACY_BIOS_BOOT)( | |
+ IN EFI_LEGACY_BIOS_PROTOCOL *This, | |
+ IN BBS_BBS_DEVICE_PATH *BootOption, | |
+ IN UINT32 LoadOptionsSize, | |
+ IN VOID *LoadOptions | |
+ ); | |
+ | |
+/** | |
+ This function takes the Leds input parameter and sets/resets the BDA accordingly. | |
+ Leds is also passed to Compatibility16 code, in case any special processing is required. | |
+ This function is normally called from EFI Setup drivers that handle user-selectable | |
+ keyboard options such as boot with NUM LOCK on/off. This function does not | |
+ touch the keyboard or keyboard LEDs but only the BDA. | |
+ | |
+ @param[in] This The protocol instance pointer. | |
+ @param[in] Leds The status of current Scroll, Num & Cap lock LEDS: | |
+ - Bit 0 is Scroll Lock 0 = Not locked. | |
+ - Bit 1 is Num Lock. | |
+ - Bit 2 is Caps Lock. | |
+ | |
+ @retval EFI_SUCCESS The BDA was updated successfully. | |
+ | |
+**/ | |
+typedef | |
+EFI_STATUS | |
+(EFIAPI *EFI_LEGACY_BIOS_UPDATE_KEYBOARD_LED_STATUS)( | |
+ IN EFI_LEGACY_BIOS_PROTOCOL *This, | |
+ IN UINT8 Leds | |
+ ); | |
+ | |
+/** | |
+ Retrieve legacy BBS info and assign boot priority. | |
+ | |
+ @param[in] This The protocol instance pointer. | |
+ @param[out] HddCount The number of HDD_INFO structures. | |
+ @param[out] HddInfo Onboard IDE controller information. | |
+ @param[out] BbsCount The number of BBS_TABLE structures. | |
+ @param[in,out] BbsTable Points to List of BBS_TABLE. | |
+ | |
+ @retval EFI_SUCCESS Tables were returned. | |
+ | |
+**/ | |
+typedef | |
+EFI_STATUS | |
+(EFIAPI *EFI_LEGACY_BIOS_GET_BBS_INFO)( | |
+ IN EFI_LEGACY_BIOS_PROTOCOL *This, | |
+ OUT UINT16 *HddCount, | |
+ OUT HDD_INFO **HddInfo, | |
+ OUT UINT16 *BbsCount, | |
+ IN OUT BBS_TABLE **BbsTable | |
+ ); | |
+ | |
+/** | |
+ Assign drive number to legacy HDD drives prior to booting an EFI | |
+ aware OS so the OS can access drives without an EFI driver. | |
+ | |
+ @param[in] This The protocol instance pointer. | |
+ @param[out] BbsCount The number of BBS_TABLE structures | |
+ @param[out] BbsTable List of BBS entries | |
+ | |
+ @retval EFI_SUCCESS Drive numbers assigned. | |
+ | |
+**/ | |
+typedef | |
+EFI_STATUS | |
+(EFIAPI *EFI_LEGACY_BIOS_PREPARE_TO_BOOT_EFI)( | |
+ IN EFI_LEGACY_BIOS_PROTOCOL *This, | |
+ OUT UINT16 *BbsCount, | |
+ OUT BBS_TABLE **BbsTable | |
+ ); | |
+ | |
+/** | |
+ To boot from an unconventional device like parties and/or execute | |
+ HDD diagnostics. | |
+ | |
+ @param[in] This The protocol instance pointer. | |
+ @param[in] Attributes How to interpret the other input parameters. | |
+ @param[in] BbsEntry The 0-based index into the BbsTable for the parent | |
+ device. | |
+ @param[in] BeerData A pointer to the 128 bytes of ram BEER data. | |
+ @param[in] ServiceAreaData A pointer to the 64 bytes of raw Service Area data. The | |
+ caller must provide a pointer to the specific Service | |
+ Area and not the start all Service Areas. | |
+ | |
+ @retval EFI_INVALID_PARAMETER If error. Does NOT return if no error. | |
+ | |
+**/ | |
+typedef | |
+EFI_STATUS | |
+(EFIAPI *EFI_LEGACY_BIOS_BOOT_UNCONVENTIONAL_DEVICE)( | |
+ IN EFI_LEGACY_BIOS_PROTOCOL *This, | |
+ IN UDC_ATTRIBUTES Attributes, | |
+ IN UINTN BbsEntry, | |
+ IN VOID *BeerData, | |
+ IN VOID *ServiceAreaData | |
+ ); | |
+ | |
+/** | |
+ Shadow all legacy16 OPROMs that haven't been shadowed. | |
+ Warning: Use this with caution. This routine disconnects all EFI | |
+ drivers. If used externally, then the caller must re-connect EFI | |
+ drivers. | |
+ | |
+ @param[in] This The protocol instance pointer. | |
+ | |
+ @retval EFI_SUCCESS OPROMs were shadowed. | |
+ | |
+**/ | |
+typedef | |
+EFI_STATUS | |
+(EFIAPI *EFI_LEGACY_BIOS_SHADOW_ALL_LEGACY_OPROMS)( | |
+ IN EFI_LEGACY_BIOS_PROTOCOL *This | |
+ ); | |
+ | |
+/** | |
+ Get a region from the LegacyBios for S3 usage. | |
+ | |
+ @param[in] This The protocol instance pointer. | |
+ @param[in] LegacyMemorySize The size of required region. | |
+ @param[in] Region The region to use. | |
+ 00 = Either 0xE0000 or 0xF0000 block. | |
+ - Bit0 = 1 0xF0000 block. | |
+ - Bit1 = 1 0xE0000 block. | |
+ @param[in] Alignment Address alignment. Bit mapped. The first non-zero | |
+ bit from right is alignment. | |
+ @param[out] LegacyMemoryAddress The Region Assigned | |
+ | |
+ @retval EFI_SUCCESS The Region was assigned. | |
+ @retval EFI_ACCESS_DENIED The function was previously invoked. | |
+ @retval Other The Region was not assigned. | |
+ | |
+**/ | |
+typedef | |
+EFI_STATUS | |
+(EFIAPI *EFI_LEGACY_BIOS_GET_LEGACY_REGION)( | |
+ IN EFI_LEGACY_BIOS_PROTOCOL *This, | |
+ IN UINTN LegacyMemorySize, | |
+ IN UINTN Region, | |
+ IN UINTN Alignment, | |
+ OUT VOID **LegacyMemoryAddress | |
+ ); | |
+ | |
+/** | |
+ Get a region from the LegacyBios for Tiano usage. Can only be invoked once. | |
+ | |
+ @param[in] This The protocol instance pointer. | |
+ @param[in] LegacyMemorySize The size of data to copy. | |
+ @param[in] LegacyMemoryAddress The Legacy Region destination address. | |
+ Note: must be in region assigned by | |
+ LegacyBiosGetLegacyRegion. | |
+ @param[in] LegacyMemorySourceAddress The source of the data to copy. | |
+ | |
+ @retval EFI_SUCCESS The Region assigned. | |
+ @retval EFI_ACCESS_DENIED Destination was outside an assigned region. | |
+ | |
+**/ | |
+typedef | |
+EFI_STATUS | |
+(EFIAPI *EFI_LEGACY_BIOS_COPY_LEGACY_REGION)( | |
+ IN EFI_LEGACY_BIOS_PROTOCOL *This, | |
+ IN UINTN LegacyMemorySize, | |
+ IN VOID *LegacyMemoryAddress, | |
+ IN VOID *LegacyMemorySourceAddress | |
+ ); | |
+ | |
+/// | |
+/// Abstracts the traditional BIOS from the rest of EFI. The LegacyBoot() | |
+/// member function allows the BDS to support booting a traditional OS. | |
+/// EFI thunks drivers that make EFI bindings for BIOS INT services use | |
+/// all the other member functions. | |
+/// | |
+struct _EFI_LEGACY_BIOS_PROTOCOL { | |
+ /// | |
+ /// Performs traditional software INT. See the Int86() function description. | |
+ /// | |
+ EFI_LEGACY_BIOS_INT86 Int86; | |
+ | |
+ /// | |
+ /// Performs a far call into Compatibility16 or traditional OpROM code. | |
+ /// | |
+ EFI_LEGACY_BIOS_FARCALL86 FarCall86; | |
+ | |
+ /// | |
+ /// Checks if a traditional OpROM exists for this device. | |
+ /// | |
+ EFI_LEGACY_BIOS_CHECK_ROM CheckPciRom; | |
+ | |
+ /// | |
+ /// Loads a traditional OpROM in traditional OpROM address space. | |
+ /// | |
+ EFI_LEGACY_BIOS_INSTALL_ROM InstallPciRom; | |
+ | |
+ /// | |
+ /// Boots a traditional OS. | |
+ /// | |
+ EFI_LEGACY_BIOS_BOOT LegacyBoot; | |
+ | |
+ /// | |
+ /// Updates BDA to reflect the current EFI keyboard LED status. | |
+ /// | |
+ EFI_LEGACY_BIOS_UPDATE_KEYBOARD_LED_STATUS UpdateKeyboardLedStatus; | |
+ | |
+ /// | |
+ /// Allows an external agent, such as BIOS Setup, to get the BBS data. | |
+ /// | |
+ EFI_LEGACY_BIOS_GET_BBS_INFO GetBbsInfo; | |
+ | |
+ /// | |
+ /// Causes all legacy OpROMs to be shadowed. | |
+ /// | |
+ EFI_LEGACY_BIOS_SHADOW_ALL_LEGACY_OPROMS ShadowAllLegacyOproms; | |
+ | |
+ /// | |
+ /// Performs all actions prior to boot. Used when booting an EFI-aware OS | |
+ /// rather than a legacy OS. | |
+ /// | |
+ EFI_LEGACY_BIOS_PREPARE_TO_BOOT_EFI PrepareToBootEfi; | |
+ | |
+ /// | |
+ /// Allows EFI to reserve an area in the 0xE0000 or 0xF0000 block. | |
+ /// | |
+ EFI_LEGACY_BIOS_GET_LEGACY_REGION GetLegacyRegion; | |
+ | |
+ /// | |
+ /// Allows EFI to copy data to the area specified by GetLegacyRegion. | |
+ /// | |
+ EFI_LEGACY_BIOS_COPY_LEGACY_REGION CopyLegacyRegion; | |
+ | |
+ /// | |
+ /// Allows the user to boot off an unconventional device such as a PARTIES partition. | |
+ /// | |
+ EFI_LEGACY_BIOS_BOOT_UNCONVENTIONAL_DEVICE BootUnconventionalDevice; | |
+}; | |
+ | |
+extern EFI_GUID gEfiLegacyBiosProtocolGuid; | |
+ | |
+#endif | |
diff --git a/OvmfPkg/CsmOld/LegacyBiosDxe/LegacyBiosInterface.h b/OvmfPkg/CsmOld/LegacyBiosDxe/LegacyBiosInterface.h | |
new file mode 100644 | |
index 000000000000..a4212064566e | |
--- /dev/null | |
+++ b/OvmfPkg/CsmOld/LegacyBiosDxe/LegacyBiosInterface.h | |
@@ -0,0 +1,1540 @@ | |
+/** @file | |
+ | |
+Copyright (c) 2006 - 2013, 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. | |
+ | |
+**/ | |
+ | |
+#ifndef _LEGACY_BIOS_INTERFACE_ | |
+#define _LEGACY_BIOS_INTERFACE_ | |
+ | |
+ | |
+#include <FrameworkDxe.h> | |
+#include <IndustryStandard/Pci.h> | |
+#include <IndustryStandard/SmBios.h> | |
+ | |
+#include <Guid/SmBios.h> | |
+#include <Guid/Acpi.h> | |
+#include <Guid/DxeServices.h> | |
+#include <Guid/LegacyBios.h> | |
+#include <Guid/StatusCodeDataTypeId.h> | |
+#include <Guid/ImageAuthentication.h> | |
+ | |
+#include <Protocol/BlockIo.h> | |
+#include <Protocol/LoadedImage.h> | |
+#include <Protocol/PciIo.h> | |
+#include <Protocol/Cpu.h> | |
+#include <Protocol/Timer.h> | |
+#include <Protocol/IsaIo.h> | |
+#include <Protocol/LegacyRegion2.h> | |
+#include <Protocol/SimpleTextIn.h> | |
+#include <Protocol/LegacyInterrupt.h> | |
+#include "LegacyBios.h" | |
+#include <Protocol/DiskInfo.h> | |
+#include <Protocol/GenericMemoryTest.h> | |
+#include <Protocol/LegacyBiosPlatform.h> | |
+#include <Protocol/DevicePath.h> | |
+#include <Protocol/Legacy8259.h> | |
+#include <Protocol/PciRootBridgeIo.h> | |
+ | |
+#include <Library/BaseLib.h> | |
+#include <Library/DebugLib.h> | |
+#include <Library/UefiLib.h> | |
+#include <Library/BaseMemoryLib.h> | |
+#include <Library/ReportStatusCodeLib.h> | |
+#include <Library/UefiRuntimeServicesTableLib.h> | |
+#include <Library/HobLib.h> | |
+#include <Library/UefiDriverEntryPoint.h> | |
+#include <Library/MemoryAllocationLib.h> | |
+#include <Library/UefiBootServicesTableLib.h> | |
+#include <Library/IoLib.h> | |
+#include <Library/PcdLib.h> | |
+#include <Library/DevicePathLib.h> | |
+#include <Library/DxeServicesTableLib.h> | |
+#include <Library/PeCoffLib.h> | |
+#include <Library/CacheMaintenanceLib.h> | |
+#include <Library/DebugAgentLib.h> | |
+ | |
+// | |
+// BUGBUG: This entry maybe changed to PCD in future and wait for | |
+// redesign of BDS library | |
+// | |
+#define MAX_BBS_ENTRIES 0x100 | |
+ | |
+// | |
+// Thunk Status Codes | |
+// (These apply only to errors with the thunk and not to the code that was | |
+// thunked to.) | |
+// | |
+#define THUNK_OK 0x00 | |
+#define THUNK_ERR_A20_UNSUP 0x01 | |
+#define THUNK_ERR_A20_FAILED 0x02 | |
+ | |
+// | |
+// Vector base definitions | |
+// | |
+// | |
+// 8259 Hardware definitions | |
+// | |
+#define LEGACY_MODE_BASE_VECTOR_MASTER 0x08 | |
+#define LEGACY_MODE_BASE_VECTOR_SLAVE 0x70 | |
+ | |
+// | |
+// The original PC used INT8-F for master PIC. Since these mapped over | |
+// processor exceptions TIANO moved the master PIC to INT68-6F. | |
+// | |
+// The vector base for slave PIC is set as 0x70 for PC-AT compatibility. | |
+// | |
+#define PROTECTED_MODE_BASE_VECTOR_MASTER 0x68 | |
+#define PROTECTED_MODE_BASE_VECTOR_SLAVE 0x70 | |
+ | |
+// | |
+// When we call CSM16 functions, some CSM16 use es:[offset + 0xabcd] to get data passed from CSM32, | |
+// offset + 0xabcd could overflow which exceeds 0xFFFF which is invalid in real mode. | |
+// So this will keep offset as small as possible to avoid offset overflow in real mode. | |
+// | |
+#define NORMALIZE_EFI_SEGMENT(_Adr) (UINT16) (((UINTN) (_Adr)) >> 4) | |
+#define NORMALIZE_EFI_OFFSET(_Adr) (UINT16) (((UINT16) ((UINTN) (_Adr))) & 0xf) | |
+ | |
+// | |
+// Trace defines | |
+// | |
+// | |
+#define LEGACY_BDA_TRACE 0x000 | |
+#define LEGACY_BIOS_TRACE 0x040 | |
+#define LEGACY_BOOT_TRACE 0x080 | |
+#define LEGACY_CMOS_TRACE 0x0C0 | |
+#define LEGACY_IDE_TRACE 0x100 | |
+#define LEGACY_MP_TRACE 0x140 | |
+#define LEGACY_PCI_TRACE 0x180 | |
+#define LEGACY_SIO_TRACE 0x1C0 | |
+ | |
+#define LEGACY_PCI_TRACE_000 LEGACY_PCI_TRACE + 0x00 | |
+#define LEGACY_PCI_TRACE_001 LEGACY_PCI_TRACE + 0x01 | |
+#define LEGACY_PCI_TRACE_002 LEGACY_PCI_TRACE + 0x02 | |
+#define LEGACY_PCI_TRACE_003 LEGACY_PCI_TRACE + 0x03 | |
+#define LEGACY_PCI_TRACE_004 LEGACY_PCI_TRACE + 0x04 | |
+#define LEGACY_PCI_TRACE_005 LEGACY_PCI_TRACE + 0x05 | |
+#define LEGACY_PCI_TRACE_006 LEGACY_PCI_TRACE + 0x06 | |
+#define LEGACY_PCI_TRACE_007 LEGACY_PCI_TRACE + 0x07 | |
+#define LEGACY_PCI_TRACE_008 LEGACY_PCI_TRACE + 0x08 | |
+#define LEGACY_PCI_TRACE_009 LEGACY_PCI_TRACE + 0x09 | |
+#define LEGACY_PCI_TRACE_00A LEGACY_PCI_TRACE + 0x0A | |
+#define LEGACY_PCI_TRACE_00B LEGACY_PCI_TRACE + 0x0B | |
+#define LEGACY_PCI_TRACE_00C LEGACY_PCI_TRACE + 0x0C | |
+#define LEGACY_PCI_TRACE_00D LEGACY_PCI_TRACE + 0x0D | |
+#define LEGACY_PCI_TRACE_00E LEGACY_PCI_TRACE + 0x0E | |
+#define LEGACY_PCI_TRACE_00F LEGACY_PCI_TRACE + 0x0F | |
+ | |
+#define BDA_VIDEO_MODE 0x49 | |
+ | |
+#define IDE_PI_REGISTER_PNE BIT0 | |
+#define IDE_PI_REGISTER_SNE BIT2 | |
+ | |
+typedef struct { | |
+ UINTN PciSegment; | |
+ UINTN PciBus; | |
+ UINTN PciDevice; | |
+ UINTN PciFunction; | |
+ UINT32 ShadowAddress; | |
+ UINT32 ShadowedSize; | |
+ UINT8 DiskStart; | |
+ UINT8 DiskEnd; | |
+} ROM_INSTANCE_ENTRY; | |
+ | |
+// | |
+// Values for RealModeGdt | |
+// | |
+#if defined (MDE_CPU_IA32) | |
+ | |
+#define NUM_REAL_GDT_ENTRIES 3 | |
+#define CONVENTIONAL_MEMORY_TOP 0xA0000 // 640 KB | |
+#define INITIAL_VALUE_BELOW_1K 0x0 | |
+ | |
+#elif defined (MDE_CPU_X64) | |
+ | |
+#define NUM_REAL_GDT_ENTRIES 8 | |
+#define CONVENTIONAL_MEMORY_TOP 0xA0000 // 640 KB | |
+#define INITIAL_VALUE_BELOW_1K 0x0 | |
+ | |
+#elif defined (MDE_CPU_IPF) | |
+ | |
+#define NUM_REAL_GDT_ENTRIES 3 | |
+#define CONVENTIONAL_MEMORY_TOP 0x80000 // 512 KB | |
+#define INITIAL_VALUE_BELOW_1K 0xff | |
+ | |
+#endif | |
+ | |
+#pragma pack(1) | |
+ | |
+// | |
+// Define what a processor GDT looks like | |
+// | |
+typedef struct { | |
+ UINT32 LimitLo : 16; | |
+ UINT32 BaseLo : 16; | |
+ UINT32 BaseMid : 8; | |
+ UINT32 Type : 4; | |
+ UINT32 System : 1; | |
+ UINT32 Dpl : 2; | |
+ UINT32 Present : 1; | |
+ UINT32 LimitHi : 4; | |
+ UINT32 Software : 1; | |
+ UINT32 Reserved : 1; | |
+ UINT32 DefaultSize : 1; | |
+ UINT32 Granularity : 1; | |
+ UINT32 BaseHi : 8; | |
+} GDT32; | |
+ | |
+typedef struct { | |
+ UINT16 LimitLow; | |
+ UINT16 BaseLow; | |
+ UINT8 BaseMid; | |
+ UINT8 Attribute; | |
+ UINT8 LimitHi; | |
+ UINT8 BaseHi; | |
+} GDT64; | |
+ | |
+// | |
+// Define what a processor descriptor looks like | |
+// This data structure must be kept in sync with ASM STRUCT in Thunk.inc | |
+// | |
+typedef struct { | |
+ UINT16 Limit; | |
+ UINT64 Base; | |
+} DESCRIPTOR64; | |
+ | |
+typedef struct { | |
+ UINT16 Limit; | |
+ UINT32 Base; | |
+} DESCRIPTOR32; | |
+ | |
+// | |
+// Low stub lay out | |
+// | |
+#define LOW_STACK_SIZE (8 * 1024) // 8k? | |
+#define EFI_MAX_E820_ENTRY 100 | |
+#define FIRST_INSTANCE 1 | |
+#define NOT_FIRST_INSTANCE 0 | |
+ | |
+#if defined (MDE_CPU_IA32) | |
+typedef struct { | |
+ // | |
+ // Space for the code | |
+ // The address of Code is also the beginning of the relocated Thunk code | |
+ // | |
+ CHAR8 Code[4096]; // ? | |
+ // | |
+ // The address of the Reverse Thunk code | |
+ // Note that this member CONTAINS the address of the relocated reverse thunk | |
+ // code unlike the member variable 'Code', which IS the address of the Thunk | |
+ // code. | |
+ // | |
+ UINT32 LowReverseThunkStart; | |
+ | |
+ // | |
+ // Data for the code (cs releative) | |
+ // | |
+ DESCRIPTOR32 GdtDesc; // Protected mode GDT | |
+ DESCRIPTOR32 IdtDesc; // Protected mode IDT | |
+ UINT32 FlatSs; | |
+ UINT32 FlatEsp; | |
+ | |
+ UINT32 LowCodeSelector; // Low code selector in GDT | |
+ UINT32 LowDataSelector; // Low data selector in GDT | |
+ UINT32 LowStack; | |
+ DESCRIPTOR32 RealModeIdtDesc; | |
+ | |
+ // | |
+ // real-mode GDT (temporary GDT with two real mode segment descriptors) | |
+ // | |
+ GDT32 RealModeGdt[NUM_REAL_GDT_ENTRIES]; | |
+ DESCRIPTOR32 RealModeGdtDesc; | |
+ | |
+ // | |
+ // Members specifically for the reverse thunk | |
+ // The RevReal* members are used to store the current state of real mode | |
+ // before performing the reverse thunk. The RevFlat* members must be set | |
+ // before calling the reverse thunk assembly code. | |
+ // | |
+ UINT16 RevRealDs; | |
+ UINT16 RevRealSs; | |
+ UINT32 RevRealEsp; | |
+ DESCRIPTOR32 RevRealIdtDesc; | |
+ UINT16 RevFlatDataSelector; // Flat data selector in GDT | |
+ UINT32 RevFlatStack; | |
+ | |
+ // | |
+ // A low memory stack | |
+ // | |
+ CHAR8 Stack[LOW_STACK_SIZE]; | |
+ | |
+ // | |
+ // Stack for flat mode after reverse thunk | |
+ // @bug - This may no longer be necessary if the reverse thunk interface | |
+ // is changed to have the flat stack in a different location. | |
+ // | |
+ CHAR8 RevThunkStack[LOW_STACK_SIZE]; | |
+ | |
+ // | |
+ // Legacy16 Init memory map info | |
+ // | |
+ EFI_TO_COMPATIBILITY16_INIT_TABLE EfiToLegacy16InitTable; | |
+ | |
+ EFI_TO_COMPATIBILITY16_BOOT_TABLE EfiToLegacy16BootTable; | |
+ | |
+ CHAR8 InterruptRedirectionCode[32]; | |
+ EFI_LEGACY_INSTALL_PCI_HANDLER PciHandler; | |
+ EFI_DISPATCH_OPROM_TABLE DispatchOpromTable; | |
+ BBS_TABLE BbsTable[MAX_BBS_ENTRIES]; | |
+} LOW_MEMORY_THUNK; | |
+ | |
+#elif defined (MDE_CPU_X64) | |
+ | |
+typedef struct { | |
+ // | |
+ // Space for the code | |
+ // The address of Code is also the beginning of the relocated Thunk code | |
+ // | |
+ CHAR8 Code[4096]; // ? | |
+ | |
+ // | |
+ // Data for the code (cs releative) | |
+ // | |
+ DESCRIPTOR64 X64GdtDesc; // Protected mode GDT | |
+ DESCRIPTOR64 X64IdtDesc; // Protected mode IDT | |
+ UINTN X64Ss; | |
+ UINTN X64Esp; | |
+ | |
+ UINTN RealStack; | |
+ DESCRIPTOR32 RealModeIdtDesc; | |
+ DESCRIPTOR32 RealModeGdtDesc; | |
+ | |
+ // | |
+ // real-mode GDT (temporary GDT with two real mode segment descriptors) | |
+ // | |
+ GDT64 RealModeGdt[NUM_REAL_GDT_ENTRIES]; | |
+ UINT64 PageMapLevel4; | |
+ | |
+ // | |
+ // A low memory stack | |
+ // | |
+ CHAR8 Stack[LOW_STACK_SIZE]; | |
+ | |
+ // | |
+ // Legacy16 Init memory map info | |
+ // | |
+ EFI_TO_COMPATIBILITY16_INIT_TABLE EfiToLegacy16InitTable; | |
+ | |
+ EFI_TO_COMPATIBILITY16_BOOT_TABLE EfiToLegacy16BootTable; | |
+ | |
+ CHAR8 InterruptRedirectionCode[32]; | |
+ EFI_LEGACY_INSTALL_PCI_HANDLER PciHandler; | |
+ EFI_DISPATCH_OPROM_TABLE DispatchOpromTable; | |
+ BBS_TABLE BbsTable[MAX_BBS_ENTRIES]; | |
+} LOW_MEMORY_THUNK; | |
+ | |
+#elif defined (MDE_CPU_IPF) | |
+ | |
+typedef struct { | |
+ // | |
+ // Space for the code | |
+ // The address of Code is also the beginning of the relocated Thunk code | |
+ // | |
+ CHAR8 Code[4096]; // ? | |
+ // | |
+ // The address of the Reverse Thunk code | |
+ // Note that this member CONTAINS the address of the relocated reverse thunk | |
+ // code unlike the member variable 'Code', which IS the address of the Thunk | |
+ // code. | |
+ // | |
+ UINT32 LowReverseThunkStart; | |
+ | |
+ // | |
+ // Data for the code (cs releative) | |
+ // | |
+ DESCRIPTOR32 GdtDesc; // Protected mode GDT | |
+ DESCRIPTOR32 IdtDesc; // Protected mode IDT | |
+ UINT32 FlatSs; | |
+ UINT32 FlatEsp; | |
+ | |
+ UINT32 LowCodeSelector; // Low code selector in GDT | |
+ UINT32 LowDataSelector; // Low data selector in GDT | |
+ UINT32 LowStack; | |
+ DESCRIPTOR32 RealModeIdtDesc; | |
+ | |
+ // | |
+ // real-mode GDT (temporary GDT with two real mode segment descriptors) | |
+ // | |
+ GDT32 RealModeGdt[NUM_REAL_GDT_ENTRIES]; | |
+ DESCRIPTOR32 RealModeGdtDesc; | |
+ | |
+ // | |
+ // Members specifically for the reverse thunk | |
+ // The RevReal* members are used to store the current state of real mode | |
+ // before performing the reverse thunk. The RevFlat* members must be set | |
+ // before calling the reverse thunk assembly code. | |
+ // | |
+ UINT16 RevRealDs; | |
+ UINT16 RevRealSs; | |
+ UINT32 RevRealEsp; | |
+ DESCRIPTOR32 RevRealIdtDesc; | |
+ UINT16 RevFlatDataSelector; // Flat data selector in GDT | |
+ UINT32 RevFlatStack; | |
+ | |
+ // | |
+ // A low memory stack | |
+ // | |
+ CHAR8 Stack[LOW_STACK_SIZE]; | |
+ | |
+ // | |
+ // Stack for flat mode after reverse thunk | |
+ // @bug - This may no longer be necessary if the reverse thunk interface | |
+ // is changed to have the flat stack in a different location. | |
+ // | |
+ CHAR8 RevThunkStack[LOW_STACK_SIZE]; | |
+ | |
+ // | |
+ // Legacy16 Init memory map info | |
+ // | |
+ EFI_TO_COMPATIBILITY16_INIT_TABLE EfiToLegacy16InitTable; | |
+ | |
+ EFI_TO_COMPATIBILITY16_BOOT_TABLE EfiToLegacy16BootTable; | |
+ | |
+ CHAR8 InterruptRedirectionCode[32]; | |
+ EFI_LEGACY_INSTALL_PCI_HANDLER PciHandler; | |
+ EFI_DISPATCH_OPROM_TABLE DispatchOpromTable; | |
+ BBS_TABLE BbsTable[MAX_BBS_ENTRIES]; | |
+} LOW_MEMORY_THUNK; | |
+ | |
+#endif | |
+ | |
+// | |
+// PnP Expansion Header | |
+// | |
+typedef struct { | |
+ UINT32 PnpSignature; | |
+ UINT8 Revision; | |
+ UINT8 Length; | |
+ UINT16 NextHeader; | |
+ UINT8 Reserved1; | |
+ UINT8 Checksum; | |
+ UINT32 DeviceId; | |
+ UINT16 MfgPointer; | |
+ UINT16 ProductNamePointer; | |
+ UINT8 Class; | |
+ UINT8 SubClass; | |
+ UINT8 Interface; | |
+ UINT8 DeviceIndicators; | |
+ UINT16 Bcv; | |
+ UINT16 DisconnectVector; | |
+ UINT16 Bev; | |
+ UINT16 Reserved2; | |
+ UINT16 StaticResourceVector; | |
+} LEGACY_PNP_EXPANSION_HEADER; | |
+ | |
+typedef struct { | |
+ UINT8 PciSegment; | |
+ UINT8 PciBus; | |
+ UINT8 PciDevice; | |
+ UINT8 PciFunction; | |
+ UINT16 Vid; | |
+ UINT16 Did; | |
+ UINT16 SysSid; | |
+ UINT16 SVid; | |
+ UINT8 Class; | |
+ UINT8 SubClass; | |
+ UINT8 Interface; | |
+ UINT8 Reserved; | |
+ UINTN RomStart; | |
+ UINTN ManufacturerString; | |
+ UINTN ProductNameString; | |
+} LEGACY_ROM_AND_BBS_TABLE; | |
+ | |
+// | |
+// Structure how EFI has mapped a devices HDD drive numbers. | |
+// Boot to EFI aware OS or shell requires this mapping when | |
+// 16-bit CSM assigns drive numbers. | |
+// This mapping is ignored booting to a legacy OS. | |
+// | |
+typedef struct { | |
+ UINT8 PciSegment; | |
+ UINT8 PciBus; | |
+ UINT8 PciDevice; | |
+ UINT8 PciFunction; | |
+ UINT8 StartDriveNumber; | |
+ UINT8 EndDriveNumber; | |
+} LEGACY_EFI_HDD_TABLE; | |
+ | |
+// | |
+// This data is passed to Leacy16Boot | |
+// | |
+typedef enum { | |
+ EfiAcpiAddressRangeMemory = 1, | |
+ EfiAcpiAddressRangeReserved = 2, | |
+ EfiAcpiAddressRangeACPI = 3, | |
+ EfiAcpiAddressRangeNVS = 4 | |
+} EFI_ACPI_MEMORY_TYPE; | |
+ | |
+typedef struct { | |
+ UINT64 BaseAddr; | |
+ UINT64 Length; | |
+ EFI_ACPI_MEMORY_TYPE Type; | |
+} EFI_E820_ENTRY64; | |
+ | |
+typedef struct { | |
+ UINT32 BassAddrLow; | |
+ UINT32 BaseAddrHigh; | |
+ UINT32 LengthLow; | |
+ UINT32 LengthHigh; | |
+ EFI_ACPI_MEMORY_TYPE Type; | |
+} EFI_E820_ENTRY; | |
+ | |
+#pragma pack() | |
+ | |
+extern BBS_TABLE *mBbsTable; | |
+ | |
+extern EFI_GENERIC_MEMORY_TEST_PROTOCOL *gGenMemoryTest; | |
+ | |
+#define PORT_70 0x70 | |
+#define PORT_71 0x71 | |
+ | |
+#define CMOS_0A 0x0a ///< Status register A | |
+#define CMOS_0D 0x0d ///< Status register D | |
+#define CMOS_0E 0x0e ///< Diagnostic Status | |
+#define CMOS_0F 0x0f ///< Shutdown status | |
+#define CMOS_10 0x10 ///< Floppy type | |
+#define CMOS_12 0x12 ///< IDE type | |
+#define CMOS_14 0x14 ///< Same as BDA 40:10 | |
+#define CMOS_15 0x15 ///< Low byte of base memory in 1k increments | |
+#define CMOS_16 0x16 ///< High byte of base memory in 1k increments | |
+#define CMOS_17 0x17 ///< Low byte of 1MB+ memory in 1k increments - max 15 MB | |
+#define CMOS_18 0x18 ///< High byte of 1MB+ memory in 1k increments - max 15 MB | |
+#define CMOS_19 0x19 ///< C: extended drive type | |
+#define CMOS_1A 0x1a ///< D: extended drive type | |
+#define CMOS_2E 0x2e ///< Most significient byte of standard checksum | |
+#define CMOS_2F 0x2f ///< Least significient byte of standard checksum | |
+#define CMOS_30 0x30 ///< CMOS 0x17 | |
+#define CMOS_31 0x31 ///< CMOS 0x18 | |
+#define CMOS_32 0x32 ///< Century byte | |
+ | |
+// | |
+// 8254 Timer registers | |
+// | |
+#define TIMER0_COUNT_PORT 0x40 | |
+#define TIMER1_COUNT_PORT 0x41 | |
+#define TIMER2_COUNT_PORT 0x42 | |
+#define TIMER_CONTROL_PORT 0x43 | |
+ | |
+// | |
+// Timer 0, Read/Write LSB then MSB, Square wave output, binary count use. | |
+// | |
+#define TIMER0_CONTROL_WORD 0x36 | |
+ | |
+#define LEGACY_BIOS_INSTANCE_SIGNATURE SIGNATURE_32 ('L', 'B', 'I', 'T') | |
+typedef struct { | |
+ UINTN Signature; | |
+ | |
+ EFI_HANDLE Handle; | |
+ EFI_LEGACY_BIOS_PROTOCOL LegacyBios; | |
+ | |
+ EFI_HANDLE ImageHandle; | |
+ | |
+ // | |
+ // CPU Architectural Protocol | |
+ // | |
+ EFI_CPU_ARCH_PROTOCOL *Cpu; | |
+ | |
+ // | |
+ // Timer Architectural Protocol | |
+ // | |
+ EFI_TIMER_ARCH_PROTOCOL *Timer; | |
+ BOOLEAN TimerUses8254; | |
+ | |
+ // | |
+ // Protocol to Lock and Unlock 0xc0000 - 0xfffff | |
+ // | |
+ EFI_LEGACY_REGION2_PROTOCOL *LegacyRegion; | |
+ | |
+ EFI_LEGACY_BIOS_PLATFORM_PROTOCOL *LegacyBiosPlatform; | |
+ | |
+ // | |
+ // Interrupt control for thunk and PCI IRQ | |
+ // | |
+ EFI_LEGACY_8259_PROTOCOL *Legacy8259; | |
+ | |
+ // | |
+ // PCI Interrupt PIRQ control | |
+ // | |
+ EFI_LEGACY_INTERRUPT_PROTOCOL *LegacyInterrupt; | |
+ | |
+ // | |
+ // Generic Memory Test | |
+ // | |
+ EFI_GENERIC_MEMORY_TEST_PROTOCOL *GenericMemoryTest; | |
+ | |
+ // | |
+ // TRUE if PCI Interupt Line registers have been programmed. | |
+ // | |
+ BOOLEAN PciInterruptLine; | |
+ | |
+ // | |
+ // Code space below 1MB needed by thunker to transition to real mode. | |
+ // Contains stack and real mode code fragments | |
+ // | |
+ LOW_MEMORY_THUNK *IntThunk; | |
+ | |
+ // | |
+ // Starting shadow address of the Legacy BIOS | |
+ // | |
+ UINT32 BiosStart; | |
+ UINT32 LegacyBiosImageSize; | |
+ | |
+ // | |
+ // Start of variables used by CsmItp.mac ITP macro file and/os LegacyBios | |
+ // | |
+ UINT8 Dump[4]; | |
+ | |
+ // | |
+ // $EFI Legacy16 code entry info in memory < 1 MB; | |
+ // | |
+ EFI_COMPATIBILITY16_TABLE *Legacy16Table; | |
+ VOID *Legacy16InitPtr; | |
+ VOID *Legacy16BootPtr; | |
+ VOID *InternalIrqRoutingTable; | |
+ UINT32 NumberIrqRoutingEntries; | |
+ VOID *BbsTablePtr; | |
+ VOID *HddTablePtr; | |
+ UINT32 NumberHddControllers; | |
+ | |
+ // | |
+ // Cached copy of Legacy16 entry point | |
+ // | |
+ UINT16 Legacy16CallSegment; | |
+ UINT16 Legacy16CallOffset; | |
+ | |
+ // | |
+ // Returned from $EFI and passed in to OPROMS | |
+ // | |
+ UINT16 PnPInstallationCheckSegment; | |
+ UINT16 PnPInstallationCheckOffset; | |
+ | |
+ // | |
+ // E820 table | |
+ // | |
+ EFI_E820_ENTRY E820Table[EFI_MAX_E820_ENTRY]; | |
+ UINT32 NumberE820Entries; | |
+ | |
+ // | |
+ // True if legacy VGA INT 10h handler installed | |
+ // | |
+ BOOLEAN VgaInstalled; | |
+ | |
+ // | |
+ // Number of IDE drives | |
+ // | |
+ UINT8 IdeDriveCount; | |
+ | |
+ // | |
+ // Current Free Option ROM space. An option ROM must NOT go past | |
+ // BiosStart. | |
+ // | |
+ UINT32 OptionRom; | |
+ | |
+ // | |
+ // Save Legacy16 unexpected interrupt vector. Reprogram INT 68-6F from | |
+ // EFI values to legacy value just before boot. | |
+ // | |
+ UINT32 BiosUnexpectedInt; | |
+ UINT32 ThunkSavedInt[8]; | |
+ UINT16 ThunkSeg; | |
+ LEGACY_EFI_HDD_TABLE *LegacyEfiHddTable; | |
+ UINT16 LegacyEfiHddTableIndex; | |
+ UINT8 DiskEnd; | |
+ UINT8 Disk4075; | |
+ UINT16 TraceIndex; | |
+ UINT16 Trace[0x200]; | |
+ | |
+ // | |
+ // Indicate that whether GenericLegacyBoot is entered or not | |
+ // | |
+ BOOLEAN LegacyBootEntered; | |
+ | |
+ // | |
+ // CSM16 PCI Interface Version | |
+ // | |
+ UINT16 Csm16PciInterfaceVersion; | |
+ | |
+} LEGACY_BIOS_INSTANCE; | |
+ | |
+ | |
+#pragma pack(1) | |
+ | |
+/* | |
+ 40:00-01 Com1 | |
+ 40:02-03 Com2 | |
+ 40:04-05 Com3 | |
+ 40:06-07 Com4 | |
+ 40:08-09 Lpt1 | |
+ 40:0A-0B Lpt2 | |
+ 40:0C-0D Lpt3 | |
+ 40:0E-0E Ebda segment | |
+ 40:10-11 MachineConfig | |
+ 40:12 Bda12 - skip | |
+ 40:13-14 MemSize below 1MB | |
+ 40:15-16 Bda15_16 - skip | |
+ 40:17 Keyboard Shift status | |
+ 40:18-19 Bda18_19 - skip | |
+ 40:1A-1B Key buffer head | |
+ 40:1C-1D Key buffer tail | |
+ 40:1E-3D Bda1E_3D- key buffer -skip | |
+ 40:3E-3F FloppyData 3E = Calibration status 3F = Motor status | |
+ 40:40 FloppyTimeout | |
+ 40:41-74 Bda41_74 - skip | |
+ 40:75 Number of HDD drives | |
+ 40:76-77 Bda76_77 - skip | |
+ 40:78-79 78 = Lpt1 timeout, 79 = Lpt2 timeout | |
+ 40:7A-7B 7A = Lpt3 timeout, 7B = Lpt4 timeout | |
+ 40:7C-7D 7C = Com1 timeout, 7D = Com2 timeout | |
+ 40:7E-7F 7E = Com3 timeout, 7F = Com4 timeout | |
+ 40:80-81 Pointer to start of key buffer | |
+ 40:82-83 Pointer to end of key buffer | |
+ 40:84-87 Bda84_87 - skip | |
+ 40:88 HDD Data Xmit rate | |
+ 40:89-8f skip | |
+ 40:90 Floppy data rate | |
+ 40:91-95 skip | |
+ 40:96 Keyboard Status | |
+ 40:97 LED Status | |
+ 40:98-101 skip | |
+*/ | |
+typedef struct { | |
+ UINT16 Com1; | |
+ UINT16 Com2; | |
+ UINT16 Com3; | |
+ UINT16 Com4; | |
+ UINT16 Lpt1; | |
+ UINT16 Lpt2; | |
+ UINT16 Lpt3; | |
+ UINT16 Ebda; | |
+ UINT16 MachineConfig; | |
+ UINT8 Bda12; | |
+ UINT16 MemSize; | |
+ UINT8 Bda15_16[0x02]; | |
+ UINT8 ShiftStatus; | |
+ UINT8 Bda18_19[0x02]; | |
+ UINT16 KeyHead; | |
+ UINT16 KeyTail; | |
+ UINT16 Bda1E_3D[0x10]; | |
+ UINT16 FloppyData; | |
+ UINT8 FloppyTimeout; | |
+ UINT8 Bda41_74[0x34]; | |
+ UINT8 NumberOfDrives; | |
+ UINT8 Bda76_77[0x02]; | |
+ UINT16 Lpt1_2Timeout; | |
+ UINT16 Lpt3_4Timeout; | |
+ UINT16 Com1_2Timeout; | |
+ UINT16 Com3_4Timeout; | |
+ UINT16 KeyStart; | |
+ UINT16 KeyEnd; | |
+ UINT8 Bda84_87[0x4]; | |
+ UINT8 DataXmit; | |
+ UINT8 Bda89_8F[0x07]; | |
+ UINT8 FloppyXRate; | |
+ UINT8 Bda91_95[0x05]; | |
+ UINT8 KeyboardStatus; | |
+ UINT8 LedStatus; | |
+} BDA_STRUC; | |
+#pragma pack() | |
+ | |
+#define LEGACY_BIOS_INSTANCE_FROM_THIS(this) CR (this, LEGACY_BIOS_INSTANCE, LegacyBios, LEGACY_BIOS_INSTANCE_SIGNATURE) | |
+ | |
+/** | |
+ Thunk to 16-bit real mode and execute a software interrupt with a vector | |
+ of BiosInt. Regs will contain the 16-bit register context on entry and | |
+ exit. | |
+ | |
+ @param This Protocol instance pointer. | |
+ @param BiosInt Processor interrupt vector to invoke | |
+ @param Regs Register contexted passed into (and returned) from thunk to | |
+ 16-bit mode | |
+ | |
+ @retval FALSE Thunk completed, and there were no BIOS errors in the target code. | |
+ See Regs for status. | |
+ @retval TRUE There was a BIOS erro in the target code. | |
+ | |
+**/ | |
+BOOLEAN | |
+EFIAPI | |
+LegacyBiosInt86 ( | |
+ IN EFI_LEGACY_BIOS_PROTOCOL *This, | |
+ IN UINT8 BiosInt, | |
+ IN EFI_IA32_REGISTER_SET *Regs | |
+ ); | |
+ | |
+ | |
+/** | |
+ Thunk to 16-bit real mode and call Segment:Offset. Regs will contain the | |
+ 16-bit register context on entry and exit. Arguments can be passed on | |
+ the Stack argument | |
+ | |
+ @param This Protocol instance pointer. | |
+ @param Segment Segemnt of 16-bit mode call | |
+ @param Offset Offset of 16-bit mdoe call | |
+ @param Regs Register contexted passed into (and returned) from | |
+ thunk to 16-bit mode | |
+ @param Stack Caller allocated stack used to pass arguments | |
+ @param StackSize Size of Stack in bytes | |
+ | |
+ @retval FALSE Thunk completed, and there were no BIOS errors in | |
+ the target code. See Regs for status. | |
+ @retval TRUE There was a BIOS erro in the target code. | |
+ | |
+**/ | |
+BOOLEAN | |
+EFIAPI | |
+LegacyBiosFarCall86 ( | |
+ IN EFI_LEGACY_BIOS_PROTOCOL *This, | |
+ IN UINT16 Segment, | |
+ IN UINT16 Offset, | |
+ IN EFI_IA32_REGISTER_SET *Regs, | |
+ IN VOID *Stack, | |
+ IN UINTN StackSize | |
+ ); | |
+ | |
+ | |
+/** | |
+ Test to see if a legacy PCI ROM exists for this device. Optionally return | |
+ the Legacy ROM instance for this PCI device. | |
+ | |
+ @param This Protocol instance pointer. | |
+ @param PciHandle The PCI PC-AT OPROM from this devices ROM BAR will | |
+ be loaded | |
+ @param RomImage Return the legacy PCI ROM for this device | |
+ @param RomSize Size of ROM Image | |
+ @param Flags Indicates if ROM found and if PC-AT. | |
+ | |
+ @retval EFI_SUCCESS Legacy Option ROM availible for this device | |
+ @retval EFI_UNSUPPORTED Legacy Option ROM not supported. | |
+ | |
+**/ | |
+EFI_STATUS | |
+EFIAPI | |
+LegacyBiosCheckPciRom ( | |
+ IN EFI_LEGACY_BIOS_PROTOCOL *This, | |
+ IN EFI_HANDLE PciHandle, | |
+ OUT VOID **RomImage, OPTIONAL | |
+ OUT UINTN *RomSize, OPTIONAL | |
+ OUT UINTN *Flags | |
+ ); | |
+ | |
+ | |
+/** | |
+ Assign drive number to legacy HDD drives prior to booting an EFI | |
+ aware OS so the OS can access drives without an EFI driver. | |
+ Note: BBS compliant drives ARE NOT available until this call by | |
+ either shell or EFI. | |
+ | |
+ @param This Protocol instance pointer. | |
+ @param BbsCount Number of BBS_TABLE structures | |
+ @param BbsTable List BBS entries | |
+ | |
+ @retval EFI_SUCCESS Drive numbers assigned | |
+ | |
+**/ | |
+EFI_STATUS | |
+EFIAPI | |
+LegacyBiosPrepareToBootEfi ( | |
+ IN EFI_LEGACY_BIOS_PROTOCOL *This, | |
+ OUT UINT16 *BbsCount, | |
+ OUT BBS_TABLE **BbsTable | |
+ ); | |
+ | |
+ | |
+/** | |
+ To boot from an unconventional device like parties and/or execute | |
+ HDD diagnostics. | |
+ | |
+ @param This Protocol instance pointer. | |
+ @param Attributes How to interpret the other input parameters | |
+ @param BbsEntry The 0-based index into the BbsTable for the parent | |
+ device. | |
+ @param BeerData Pointer to the 128 bytes of ram BEER data. | |
+ @param ServiceAreaData Pointer to the 64 bytes of raw Service Area data. | |
+ The caller must provide a pointer to the specific | |
+ Service Area and not the start all Service Areas. | |
+ EFI_INVALID_PARAMETER if error. Does NOT return if no error. | |
+ | |
+**/ | |
+EFI_STATUS | |
+EFIAPI | |
+LegacyBiosBootUnconventionalDevice ( | |
+ IN EFI_LEGACY_BIOS_PROTOCOL *This, | |
+ IN UDC_ATTRIBUTES Attributes, | |
+ IN UINTN BbsEntry, | |
+ IN VOID *BeerData, | |
+ IN VOID *ServiceAreaData | |
+ ); | |
+ | |
+ | |
+/** | |
+ Load a legacy PC-AT OPROM on the PciHandle device. Return information | |
+ about how many disks were added by the OPROM and the shadow address and | |
+ size. DiskStart & DiskEnd are INT 13h drive letters. Thus 0x80 is C: | |
+ | |
+ @param This Protocol instance pointer. | |
+ @param PciHandle The PCI PC-AT OPROM from this devices ROM BAR will | |
+ be loaded. This value is NULL if RomImage is | |
+ non-NULL. This is the normal case. | |
+ @param RomImage A PCI PC-AT ROM image. This argument is non-NULL | |
+ if there is no hardware associated with the ROM | |
+ and thus no PciHandle, otherwise is must be NULL. | |
+ Example is PXE base code. | |
+ @param Flags Indicates if ROM found and if PC-AT. | |
+ @param DiskStart Disk number of first device hooked by the ROM. If | |
+ DiskStart is the same as DiskEnd no disked were | |
+ hooked. | |
+ @param DiskEnd Disk number of the last device hooked by the ROM. | |
+ @param RomShadowAddress Shadow address of PC-AT ROM | |
+ @param RomShadowedSize Size of RomShadowAddress in bytes | |
+ | |
+ @retval EFI_SUCCESS Legacy ROM loaded for this device | |
+ @retval EFI_INVALID_PARAMETER PciHandle not found | |
+ @retval EFI_UNSUPPORTED There is no PCI ROM in the ROM BAR or no onboard | |
+ ROM | |
+ | |
+**/ | |
+EFI_STATUS | |
+EFIAPI | |
+LegacyBiosInstallPciRom ( | |
+ IN EFI_LEGACY_BIOS_PROTOCOL * This, | |
+ IN EFI_HANDLE PciHandle, | |
+ IN VOID **RomImage, | |
+ OUT UINTN *Flags, | |
+ OUT UINT8 *DiskStart, OPTIONAL | |
+ OUT UINT8 *DiskEnd, OPTIONAL | |
+ OUT VOID **RomShadowAddress, OPTIONAL | |
+ OUT UINT32 *RomShadowedSize OPTIONAL | |
+ ); | |
+ | |
+ | |
+/** | |
+ Fill in the standard BDA for Keyboard LEDs | |
+ | |
+ @param This Protocol instance pointer. | |
+ @param Leds Current LED status | |
+ | |
+ @retval EFI_SUCCESS It should always work. | |
+ | |
+**/ | |
+EFI_STATUS | |
+EFIAPI | |
+LegacyBiosUpdateKeyboardLedStatus ( | |
+ IN EFI_LEGACY_BIOS_PROTOCOL *This, | |
+ IN UINT8 Leds | |
+ ); | |
+ | |
+ | |
+/** | |
+ Get all BBS info | |
+ | |
+ @param This Protocol instance pointer. | |
+ @param HddCount Number of HDD_INFO structures | |
+ @param HddInfo Onboard IDE controller information | |
+ @param BbsCount Number of BBS_TABLE structures | |
+ @param BbsTable List BBS entries | |
+ | |
+ @retval EFI_SUCCESS Tables returned | |
+ @retval EFI_NOT_FOUND resource not found | |
+ @retval EFI_DEVICE_ERROR can not get BBS table | |
+ | |
+**/ | |
+EFI_STATUS | |
+EFIAPI | |
+LegacyBiosGetBbsInfo ( | |
+ IN EFI_LEGACY_BIOS_PROTOCOL *This, | |
+ OUT UINT16 *HddCount, | |
+ OUT HDD_INFO **HddInfo, | |
+ OUT UINT16 *BbsCount, | |
+ OUT BBS_TABLE **BbsTable | |
+ ); | |
+ | |
+ | |
+/** | |
+ Shadow all legacy16 OPROMs that haven't been shadowed. | |
+ Warning: Use this with caution. This routine disconnects all EFI | |
+ drivers. If used externally then caller must re-connect EFI | |
+ drivers. | |
+ | |
+ @param This Protocol instance pointer. | |
+ | |
+ @retval EFI_SUCCESS OPROMs shadowed | |
+ | |
+**/ | |
+EFI_STATUS | |
+EFIAPI | |
+LegacyBiosShadowAllLegacyOproms ( | |
+ IN EFI_LEGACY_BIOS_PROTOCOL *This | |
+ ); | |
+ | |
+ | |
+/** | |
+ Attempt to legacy boot the BootOption. If the EFI contexted has been | |
+ compromised this function will not return. | |
+ | |
+ @param This Protocol instance pointer. | |
+ @param BbsDevicePath EFI Device Path from BootXXXX variable. | |
+ @param LoadOptionsSize Size of LoadOption in size. | |
+ @param LoadOptions LoadOption from BootXXXX variable | |
+ | |
+ @retval EFI_SUCCESS Removable media not present | |
+ | |
+**/ | |
+EFI_STATUS | |
+EFIAPI | |
+LegacyBiosLegacyBoot ( | |
+ IN EFI_LEGACY_BIOS_PROTOCOL *This, | |
+ IN BBS_BBS_DEVICE_PATH *BbsDevicePath, | |
+ IN UINT32 LoadOptionsSize, | |
+ IN VOID *LoadOptions | |
+ ); | |
+ | |
+ | |
+/** | |
+ Allocate memory < 1 MB and copy the thunker code into low memory. Se up | |
+ all the descriptors. | |
+ | |
+ @param Private Private context for Legacy BIOS | |
+ | |
+ @retval EFI_SUCCESS Should only pass. | |
+ | |
+**/ | |
+EFI_STATUS | |
+LegacyBiosInitializeThunk ( | |
+ IN LEGACY_BIOS_INSTANCE *Private | |
+ ); | |
+ | |
+ | |
+/** | |
+ Fill in the standard BDA and EBDA stuff before Legacy16 load | |
+ | |
+ @param Private Legacy BIOS Instance data | |
+ | |
+ @retval EFI_SUCCESS It should always work. | |
+ | |
+**/ | |
+EFI_STATUS | |
+LegacyBiosInitBda ( | |
+ IN LEGACY_BIOS_INSTANCE *Private | |
+ ); | |
+ | |
+ | |
+/** | |
+ Collect IDE Inquiry data from the IDE disks | |
+ | |
+ @param Private Legacy BIOS Instance data | |
+ @param HddInfo Hdd Information | |
+ @param Flag Reconnect IdeController or not | |
+ | |
+ @retval EFI_SUCCESS It should always work. | |
+ | |
+**/ | |
+EFI_STATUS | |
+LegacyBiosBuildIdeData ( | |
+ IN LEGACY_BIOS_INSTANCE *Private, | |
+ IN HDD_INFO **HddInfo, | |
+ IN UINT16 Flag | |
+ ); | |
+ | |
+ | |
+/** | |
+ Enable ide controller. This gets disabled when LegacyBoot.c is about | |
+ to run the Option ROMs. | |
+ | |
+ @param Private Legacy BIOS Instance data | |
+ | |
+ | |
+**/ | |
+VOID | |
+EnableIdeController ( | |
+ IN LEGACY_BIOS_INSTANCE *Private | |
+ ); | |
+ | |
+ | |
+/** | |
+ If the IDE channel is in compatibility (legacy) mode, remove all | |
+ PCI I/O BAR addresses from the controller. | |
+ | |
+ @param IdeController The handle of target IDE controller | |
+ | |
+ | |
+**/ | |
+VOID | |
+InitLegacyIdeController ( | |
+ IN EFI_HANDLE IdeController | |
+ ); | |
+ | |
+ | |
+/** | |
+ Program the interrupt routing register in all the PCI devices. On a PC AT system | |
+ this register contains the 8259 IRQ vector that matches it's PCI interrupt. | |
+ | |
+ @param Private Legacy BIOS Instance data | |
+ | |
+ @retval EFI_SUCCESS Succeed. | |
+ @retval EFI_ALREADY_STARTED All PCI devices have been processed. | |
+ | |
+**/ | |
+EFI_STATUS | |
+PciProgramAllInterruptLineRegisters ( | |
+ IN LEGACY_BIOS_INSTANCE *Private | |
+ ); | |
+ | |
+ | |
+/** | |
+ Collect EFI Info about legacy devices. | |
+ | |
+ @param Private Legacy BIOS Instance data | |
+ | |
+ @retval EFI_SUCCESS It should always work. | |
+ | |
+**/ | |
+EFI_STATUS | |
+LegacyBiosBuildSioData ( | |
+ IN LEGACY_BIOS_INSTANCE *Private | |
+ ); | |
+ | |
+ | |
+/** | |
+ Shadow all the PCI legacy ROMs. Use data from the Legacy BIOS Protocol | |
+ to chose the order. Skip any devices that have already have legacy | |
+ BIOS run. | |
+ | |
+ @param Private Protocol instance pointer. | |
+ | |
+ @retval EFI_SUCCESS Succeed. | |
+ @retval EFI_UNSUPPORTED Cannot get VGA device handle. | |
+ | |
+**/ | |
+EFI_STATUS | |
+PciShadowRoms ( | |
+ IN LEGACY_BIOS_INSTANCE *Private | |
+ ); | |
+ | |
+ | |
+/** | |
+ Fill in the standard BDA and EBDA stuff prior to legacy Boot | |
+ | |
+ @param Private Legacy BIOS Instance data | |
+ | |
+ @retval EFI_SUCCESS It should always work. | |
+ | |
+**/ | |
+EFI_STATUS | |
+LegacyBiosCompleteBdaBeforeBoot ( | |
+ IN LEGACY_BIOS_INSTANCE *Private | |
+ ); | |
+ | |
+ | |
+/** | |
+ Fill in the standard CMOS stuff before Legacy16 load | |
+ | |
+ @param Private Legacy BIOS Instance data | |
+ | |
+ @retval EFI_SUCCESS It should always work. | |
+ | |
+**/ | |
+EFI_STATUS | |
+LegacyBiosInitCmos ( | |
+ IN LEGACY_BIOS_INSTANCE *Private | |
+ ); | |
+ | |
+ | |
+/** | |
+ Fill in the standard CMOS stuff prior to legacy Boot | |
+ | |
+ @param Private Legacy BIOS Instance data | |
+ | |
+ @retval EFI_SUCCESS It should always work. | |
+ | |
+**/ | |
+EFI_STATUS | |
+LegacyBiosCompleteStandardCmosBeforeBoot ( | |
+ IN LEGACY_BIOS_INSTANCE *Private | |
+ ); | |
+ | |
+ | |
+/** | |
+ Contains the code that is copied into low memory (below 640K). | |
+ This code reflects interrupts 0x68-0x6f to interrupts 0x08-0x0f. | |
+ This template must be copied into low memory, and the IDT entries | |
+ 0x68-0x6F must be point to the low memory copy of this code. Each | |
+ entry is 4 bytes long, so IDT entries 0x68-0x6F can be easily | |
+ computed. | |
+ | |
+**/ | |
+VOID | |
+InterruptRedirectionTemplate ( | |
+ VOID | |
+ ); | |
+ | |
+ | |
+/** | |
+ Build the E820 table. | |
+ | |
+ @param Private Legacy BIOS Instance data | |
+ @param Size Size of E820 Table | |
+ | |
+ @retval EFI_SUCCESS It should always work. | |
+ | |
+**/ | |
+EFI_STATUS | |
+LegacyBiosBuildE820 ( | |
+ IN LEGACY_BIOS_INSTANCE *Private, | |
+ OUT UINTN *Size | |
+ ); | |
+ | |
+/** | |
+ This function is to put all AP in halt state. | |
+ | |
+ @param Private Legacy BIOS Instance data | |
+ | |
+**/ | |
+VOID | |
+ShutdownAPs ( | |
+ IN LEGACY_BIOS_INSTANCE *Private | |
+ ); | |
+ | |
+/** | |
+ Worker function for LegacyBiosGetFlatDescs, retrieving content of | |
+ specific registers. | |
+ | |
+ @param IntThunk Pointer to IntThunk of Legacy BIOS context. | |
+ | |
+**/ | |
+VOID | |
+GetRegisters ( | |
+ LOW_MEMORY_THUNK *IntThunk | |
+ ); | |
+ | |
+/** | |
+ Routine for calling real thunk code. | |
+ | |
+ @param RealCode The address of thunk code. | |
+ @param BiosInt The Bios interrupt vector number. | |
+ @param CallAddress The address of 16-bit mode call. | |
+ | |
+ @return Status returned by real thunk code | |
+ | |
+**/ | |
+UINTN | |
+CallRealThunkCode ( | |
+ UINT8 *RealCode, | |
+ UINT8 BiosInt, | |
+ UINT32 CallAddress | |
+ ); | |
+ | |
+/** | |
+ Routine for generating soft interrupt. | |
+ | |
+ @param Vector The interrupt vector number. | |
+ | |
+**/ | |
+VOID | |
+GenerateSoftInit ( | |
+ UINT8 Vector | |
+ ); | |
+ | |
+/** | |
+ Do an AllocatePages () of type AllocateMaxAddress for EfiBootServicesCode | |
+ memory. | |
+ | |
+ @param AllocateType Allocated Legacy Memory Type | |
+ @param StartPageAddress Start address of range | |
+ @param Pages Number of pages to allocate | |
+ @param Result Result of allocation | |
+ | |
+ @retval EFI_SUCCESS Legacy16 code loaded | |
+ @retval Other No protocol installed, unload driver. | |
+ | |
+**/ | |
+EFI_STATUS | |
+AllocateLegacyMemory ( | |
+ IN EFI_ALLOCATE_TYPE AllocateType, | |
+ IN EFI_PHYSICAL_ADDRESS StartPageAddress, | |
+ IN UINTN Pages, | |
+ OUT EFI_PHYSICAL_ADDRESS *Result | |
+ ); | |
+ | |
+/** | |
+ Get a region from the LegacyBios for Tiano usage. Can only be invoked once. | |
+ | |
+ @param This Protocol instance pointer. | |
+ @param LegacyMemorySize Size of required region | |
+ @param Region Region to use. 00 = Either 0xE0000 or 0xF0000 | |
+ block Bit0 = 1 0xF0000 block Bit1 = 1 0xE0000 | |
+ block | |
+ @param Alignment Address alignment. Bit mapped. First non-zero | |
+ bit from right is alignment. | |
+ @param LegacyMemoryAddress Region Assigned | |
+ | |
+ @retval EFI_SUCCESS Region assigned | |
+ @retval EFI_ACCESS_DENIED Procedure previously invoked | |
+ @retval Other Region not assigned | |
+ | |
+**/ | |
+EFI_STATUS | |
+EFIAPI | |
+LegacyBiosGetLegacyRegion ( | |
+ IN EFI_LEGACY_BIOS_PROTOCOL *This, | |
+ IN UINTN LegacyMemorySize, | |
+ IN UINTN Region, | |
+ IN UINTN Alignment, | |
+ OUT VOID **LegacyMemoryAddress | |
+ ); | |
+ | |
+/** | |
+ Get a region from the LegacyBios for Tiano usage. Can only be invoked once. | |
+ | |
+ @param This Protocol instance pointer. | |
+ @param LegacyMemorySize Size of data to copy | |
+ @param LegacyMemoryAddress Legacy Region destination address Note: must | |
+ be in region assigned by | |
+ LegacyBiosGetLegacyRegion | |
+ @param LegacyMemorySourceAddress Source of data | |
+ | |
+ @retval EFI_SUCCESS Region assigned | |
+ @retval EFI_ACCESS_DENIED Destination outside assigned region | |
+ | |
+**/ | |
+EFI_STATUS | |
+EFIAPI | |
+LegacyBiosCopyLegacyRegion ( | |
+ IN EFI_LEGACY_BIOS_PROTOCOL *This, | |
+ IN UINTN LegacyMemorySize, | |
+ IN VOID *LegacyMemoryAddress, | |
+ IN VOID *LegacyMemorySourceAddress | |
+ ); | |
+ | |
+/** | |
+ Find Legacy16 BIOS image in the FLASH device and shadow it into memory. Find | |
+ the $EFI table in the shadow area. Thunk into the Legacy16 code after it had | |
+ been shadowed. | |
+ | |
+ @param Private Legacy BIOS context data | |
+ | |
+ @retval EFI_SUCCESS Legacy16 code loaded | |
+ @retval Other No protocol installed, unload driver. | |
+ | |
+**/ | |
+EFI_STATUS | |
+ShadowAndStartLegacy16 ( | |
+ IN LEGACY_BIOS_INSTANCE *Private | |
+ ); | |
+ | |
+/** | |
+ Checks the state of the floppy and if media is inserted. | |
+ | |
+ This routine checks the state of the floppy and if media is inserted. | |
+ There are 3 cases: | |
+ No floppy present - Set BBS entry to ignore | |
+ Floppy present & no media - Set BBS entry to lowest priority. We cannot | |
+ set it to ignore since 16-bit CSM will | |
+ indicate no floppy and thus drive A: is | |
+ unusable. CSM-16 will not try floppy since | |
+ lowest priority and thus not incur boot | |
+ time penality. | |
+ Floppy present & media - Set BBS entry to some priority. | |
+ | |
+ @return State of floppy media | |
+ | |
+**/ | |
+UINT8 | |
+HasMediaInFloppy ( | |
+ VOID | |
+ ); | |
+ | |
+/** | |
+ Identify drive data must be updated to actual parameters before boot. | |
+ This requires updating the checksum, if it exists. | |
+ | |
+ @param IdentifyDriveData ATA Identify Data | |
+ @param Checksum checksum of the ATA Identify Data | |
+ | |
+ @retval EFI_SUCCESS checksum calculated | |
+ @retval EFI_SECURITY_VIOLATION IdentifyData invalid | |
+ | |
+**/ | |
+EFI_STATUS | |
+CalculateIdentifyDriveChecksum ( | |
+ IN UINT8 *IdentifyDriveData, | |
+ OUT UINT8 *Checksum | |
+ ); | |
+ | |
+/** | |
+ Identify drive data must be updated to actual parameters before boot. | |
+ | |
+ @param IdentifyDriveData ATA Identify Data | |
+ | |
+**/ | |
+VOID | |
+UpdateIdentifyDriveData ( | |
+ IN UINT8 *IdentifyDriveData | |
+ ); | |
+ | |
+/** | |
+ Complete build of BBS TABLE. | |
+ | |
+ @param Private Legacy BIOS Instance data | |
+ @param BbsTable BBS Table passed to 16-bit code | |
+ | |
+ @retval EFI_SUCCESS Removable media not present | |
+ | |
+**/ | |
+EFI_STATUS | |
+LegacyBiosBuildBbs ( | |
+ IN LEGACY_BIOS_INSTANCE *Private, | |
+ IN BBS_TABLE *BbsTable | |
+ ); | |
+ | |
+/** | |
+ Read CMOS register through index/data port. | |
+ | |
+ @param[in] Index The index of the CMOS register to read. | |
+ | |
+ @return The data value from the CMOS register specified by Index. | |
+ | |
+**/ | |
+UINT8 | |
+LegacyReadStandardCmos ( | |
+ IN UINT8 Index | |
+ ); | |
+ | |
+/** | |
+ Write CMOS register through index/data port. | |
+ | |
+ @param[in] Index The index of the CMOS register to write. | |
+ @param[in] Value The value of CMOS register to write. | |
+ | |
+ @return The value written to the CMOS register specified by Index. | |
+ | |
+**/ | |
+UINT8 | |
+LegacyWriteStandardCmos ( | |
+ IN UINT8 Index, | |
+ IN UINT8 Value | |
+ ); | |
+ | |
+/** | |
+ Calculate the new standard CMOS checksum and write it. | |
+ | |
+ @param Private Legacy BIOS Instance data | |
+ | |
+ @retval EFI_SUCCESS Calculate 16-bit checksum successfully | |
+ | |
+**/ | |
+EFI_STATUS | |
+LegacyCalculateWriteStandardCmosChecksum ( | |
+ VOID | |
+ ); | |
+ | |
+/** | |
+ Test to see if a legacy PCI ROM exists for this device. Optionally return | |
+ the Legacy ROM instance for this PCI device. | |
+ | |
+ @param[in] This Protocol instance pointer. | |
+ @param[in] PciHandle The PCI PC-AT OPROM from this devices ROM BAR will be loaded | |
+ @param[out] RomImage Return the legacy PCI ROM for this device | |
+ @param[out] RomSize Size of ROM Image | |
+ @param[out] RuntimeImageLength Runtime size of ROM Image | |
+ @param[out] Flags Indicates if ROM found and if PC-AT. | |
+ @param[out] OpromRevision Revision of the PCI Rom | |
+ @param[out] ConfigUtilityCodeHeaderPointer of Configuration Utility Code Header | |
+ | |
+ @return EFI_SUCCESS Legacy Option ROM availible for this device | |
+ @return EFI_ALREADY_STARTED This device is already managed by its Oprom | |
+ @return EFI_UNSUPPORTED Legacy Option ROM not supported. | |
+ | |
+**/ | |
+EFI_STATUS | |
+LegacyBiosCheckPciRomEx ( | |
+ IN EFI_LEGACY_BIOS_PROTOCOL *This, | |
+ IN EFI_HANDLE PciHandle, | |
+ OUT VOID **RomImage, OPTIONAL | |
+ OUT UINTN *RomSize, OPTIONAL | |
+ OUT UINTN *RuntimeImageLength, OPTIONAL | |
+ OUT UINTN *Flags, OPTIONAL | |
+ OUT UINT8 *OpromRevision, OPTIONAL | |
+ OUT VOID **ConfigUtilityCodeHeader OPTIONAL | |
+ ); | |
+ | |
+/** | |
+ Relocate this image under 4G memory for IPF. | |
+ | |
+ @param ImageHandle Handle of driver image. | |
+ @param SystemTable Pointer to system table. | |
+ | |
+ @retval EFI_SUCCESS Image successfully relocated. | |
+ @retval EFI_ABORTED Failed to relocate image. | |
+ | |
+**/ | |
+EFI_STATUS | |
+RelocateImageUnder4GIfNeeded ( | |
+ IN EFI_HANDLE ImageHandle, | |
+ IN EFI_SYSTEM_TABLE *SystemTable | |
+ ); | |
+ | |
+/** | |
+ Thunk to 16-bit real mode and call Segment:Offset. Regs will contain the | |
+ 16-bit register context on entry and exit. Arguments can be passed on | |
+ the Stack argument | |
+ | |
+ @param This Protocol instance pointer. | |
+ @param Segment Segemnt of 16-bit mode call | |
+ @param Offset Offset of 16-bit mdoe call | |
+ @param Regs Register contexted passed into (and returned) from thunk to | |
+ 16-bit mode | |
+ @param Stack Caller allocated stack used to pass arguments | |
+ @param StackSize Size of Stack in bytes | |
+ | |
+ @retval FALSE Thunk completed, and there were no BIOS errors in the target code. | |
+ See Regs for status. | |
+ @retval TRUE There was a BIOS erro in the target code. | |
+ | |
+**/ | |
+BOOLEAN | |
+EFIAPI | |
+InternalLegacyBiosFarCall ( | |
+ IN EFI_LEGACY_BIOS_PROTOCOL *This, | |
+ IN UINT16 Segment, | |
+ IN UINT16 Offset, | |
+ IN EFI_IA32_REGISTER_SET *Regs, | |
+ IN VOID *Stack, | |
+ IN UINTN StackSize | |
+ ); | |
+ | |
+/** | |
+ Load a legacy PC-AT OpROM for VGA controller. | |
+ | |
+ @param Private Driver private data. | |
+ | |
+ @retval EFI_SUCCESS Legacy ROM successfully installed for this device. | |
+ @retval EFI_DEVICE_ERROR No VGA device handle found, or native EFI video | |
+ driver cannot be successfully disconnected, or VGA | |
+ thunk driver cannot be successfully connected. | |
+ | |
+**/ | |
+EFI_STATUS | |
+LegacyBiosInstallVgaRom ( | |
+ IN LEGACY_BIOS_INSTANCE *Private | |
+ ); | |
+ | |
+#endif | |
diff --git a/OvmfPkg/CsmOld/VideoDxe/BiosVideo.h b/OvmfPkg/CsmOld/VideoDxe/BiosVideo.h | |
new file mode 100644 | |
index 000000000000..88ab1d7cf400 | |
--- /dev/null | |
+++ b/OvmfPkg/CsmOld/VideoDxe/BiosVideo.h | |
@@ -0,0 +1,539 @@ | |
+/** @file | |
+ | |
+Copyright (c) 2006 - 2012, 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. | |
+ | |
+**/ | |
+ | |
+#ifndef _BIOS_GRAPHICS_OUTPUT_H_ | |
+#define _BIOS_GRAPHICS_OUTPUT_H_ | |
+ | |
+#include <FrameworkDxe.h> | |
+ | |
+#include <Protocol/PciIo.h> | |
+#include <Protocol/EdidActive.h> | |
+#include <Protocol/DevicePath.h> | |
+#include <Protocol/EdidDiscovered.h> | |
+#include <Protocol/LegacyBios.h> | |
+#include <Protocol/VgaMiniPort.h> | |
+#include <Protocol/GraphicsOutput.h> | |
+#include <Protocol/EdidOverride.h> | |
+ | |
+#include <Guid/StatusCodeDataTypeId.h> | |
+#include <Guid/LegacyBios.h> | |
+#include <Guid/EventGroup.h> | |
+ | |
+#include <Library/PcdLib.h> | |
+#include <Library/DebugLib.h> | |
+#include <Library/ReportStatusCodeLib.h> | |
+#include <Library/BaseMemoryLib.h> | |
+#include <Library/UefiDriverEntryPoint.h> | |
+#include <Library/UefiBootServicesTableLib.h> | |
+#include <Library/UefiLib.h> | |
+#include <Library/DevicePathLib.h> | |
+#include <Library/MemoryAllocationLib.h> | |
+ | |
+#include <IndustryStandard/Pci.h> | |
+#include "VesaBiosExtensions.h" | |
+ | |
+// | |
+// Packed format support: The number of bits reserved for each of the colors and the actual | |
+// position of RGB in the frame buffer is specified in the VBE Mode information | |
+// | |
+typedef struct { | |
+ UINT8 Position; // Position of the color | |
+ UINT8 Mask; // The number of bits expressed as a mask | |
+} BIOS_VIDEO_COLOR_PLACEMENT; | |
+ | |
+// | |
+// BIOS Graphics Output Graphical Mode Data | |
+// | |
+typedef struct { | |
+ UINT16 VbeModeNumber; | |
+ UINT16 BytesPerScanLine; | |
+ VOID *LinearFrameBuffer; | |
+ UINTN FrameBufferSize; | |
+ UINT32 HorizontalResolution; | |
+ UINT32 VerticalResolution; | |
+ UINT32 ColorDepth; | |
+ UINT32 RefreshRate; | |
+ UINT32 BitsPerPixel; | |
+ BIOS_VIDEO_COLOR_PLACEMENT Red; | |
+ BIOS_VIDEO_COLOR_PLACEMENT Green; | |
+ BIOS_VIDEO_COLOR_PLACEMENT Blue; | |
+ BIOS_VIDEO_COLOR_PLACEMENT Reserved; | |
+ EFI_GRAPHICS_PIXEL_FORMAT PixelFormat; | |
+ EFI_PIXEL_BITMASK PixelBitMask; | |
+} BIOS_VIDEO_MODE_DATA; | |
+ | |
+// | |
+// BIOS video child handle private data Structure | |
+// | |
+#define BIOS_VIDEO_DEV_SIGNATURE SIGNATURE_32 ('B', 'V', 'M', 'p') | |
+ | |
+typedef struct { | |
+ UINTN Signature; | |
+ EFI_HANDLE Handle; | |
+ | |
+ // | |
+ // Consumed Protocols | |
+ // | |
+ EFI_PCI_IO_PROTOCOL *PciIo; | |
+ EFI_LEGACY_BIOS_PROTOCOL *LegacyBios; | |
+ | |
+ // | |
+ // Produced Protocols | |
+ // | |
+ EFI_GRAPHICS_OUTPUT_PROTOCOL GraphicsOutput; | |
+ EFI_EDID_DISCOVERED_PROTOCOL EdidDiscovered; | |
+ EFI_EDID_ACTIVE_PROTOCOL EdidActive; | |
+ EFI_VGA_MINI_PORT_PROTOCOL VgaMiniPort; | |
+ | |
+ // | |
+ // General fields | |
+ // | |
+ BOOLEAN VgaCompatible; | |
+ BOOLEAN ProduceGraphicsOutput; | |
+ | |
+ // | |
+ // Graphics Output Protocol related fields | |
+ // | |
+ BOOLEAN HardwareNeedsStarting; | |
+ UINTN CurrentMode; | |
+ UINTN MaxMode; | |
+ BIOS_VIDEO_MODE_DATA *ModeData; | |
+ UINT8 *LineBuffer; | |
+ EFI_GRAPHICS_OUTPUT_BLT_PIXEL *VbeFrameBuffer; | |
+ UINT8 *VgaFrameBuffer; | |
+ | |
+ // | |
+ // VESA Bios Extensions related fields | |
+ // | |
+ UINTN NumberOfPagesBelow1MB; // Number of 4KB pages in PagesBelow1MB | |
+ EFI_PHYSICAL_ADDRESS PagesBelow1MB; // Buffer for all VBE Information Blocks | |
+ VESA_BIOS_EXTENSIONS_INFORMATION_BLOCK *VbeInformationBlock; // 0x200 bytes. Must be allocated below 1MB | |
+ VESA_BIOS_EXTENSIONS_MODE_INFORMATION_BLOCK *VbeModeInformationBlock; // 0x100 bytes. Must be allocated below 1MB | |
+ VESA_BIOS_EXTENSIONS_EDID_DATA_BLOCK *VbeEdidDataBlock; // 0x80 bytes. Must be allocated below 1MB | |
+ VESA_BIOS_EXTENSIONS_CRTC_INFORMATION_BLOCK *VbeCrtcInformationBlock; // 59 bytes. Must be allocated below 1MB | |
+ UINTN VbeSaveRestorePages; // Number of 4KB pages in VbeSaveRestoreBuffer | |
+ EFI_PHYSICAL_ADDRESS VbeSaveRestoreBuffer; // Must be allocated below 1MB | |
+ // | |
+ // Status code | |
+ // | |
+ EFI_DEVICE_PATH_PROTOCOL *GopDevicePath; | |
+ | |
+ EFI_EVENT ExitBootServicesEvent; | |
+} BIOS_VIDEO_DEV; | |
+ | |
+#define BIOS_VIDEO_DEV_FROM_PCI_IO_THIS(a) CR (a, BIOS_VIDEO_DEV, PciIo, BIOS_VIDEO_DEV_SIGNATURE) | |
+#define BIOS_VIDEO_DEV_FROM_GRAPHICS_OUTPUT_THIS(a) CR (a, BIOS_VIDEO_DEV, GraphicsOutput, BIOS_VIDEO_DEV_SIGNATURE) | |
+#define BIOS_VIDEO_DEV_FROM_VGA_MINI_PORT_THIS(a) CR (a, BIOS_VIDEO_DEV, VgaMiniPort, BIOS_VIDEO_DEV_SIGNATURE) | |
+ | |
+#define GRAPHICS_OUTPUT_INVALIDE_MODE_NUMBER 0xffff | |
+ | |
+// | |
+// Global Variables | |
+// | |
+extern EFI_DRIVER_BINDING_PROTOCOL gBiosVideoDriverBinding; | |
+extern EFI_COMPONENT_NAME_PROTOCOL gBiosVideoComponentName; | |
+extern EFI_COMPONENT_NAME2_PROTOCOL gBiosVideoComponentName2; | |
+ | |
+// | |
+// Driver Binding Protocol functions | |
+// | |
+ | |
+/** | |
+ Supported. | |
+ | |
+ @param This Pointer to driver binding protocol | |
+ @param Controller Controller handle to connect | |
+ @param RemainingDevicePath A pointer to the remaining portion of a device | |
+ path | |
+ | |
+ @retval EFI_STATUS EFI_SUCCESS:This controller can be managed by this | |
+ driver, Otherwise, this controller cannot be | |
+ managed by this driver | |
+ | |
+**/ | |
+EFI_STATUS | |
+EFIAPI | |
+BiosVideoDriverBindingSupported ( | |
+ IN EFI_DRIVER_BINDING_PROTOCOL *This, | |
+ IN EFI_HANDLE Controller, | |
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath | |
+ ); | |
+ | |
+ | |
+/** | |
+ Install Graphics Output Protocol onto VGA device handles. | |
+ | |
+ @param This Pointer to driver binding protocol | |
+ @param Controller Controller handle to connect | |
+ @param RemainingDevicePath A pointer to the remaining portion of a device | |
+ path | |
+ | |
+ @return EFI_STATUS | |
+ | |
+**/ | |
+EFI_STATUS | |
+EFIAPI | |
+BiosVideoDriverBindingStart ( | |
+ IN EFI_DRIVER_BINDING_PROTOCOL *This, | |
+ IN EFI_HANDLE Controller, | |
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath | |
+ ); | |
+ | |
+ | |
+/** | |
+ Stop. | |
+ | |
+ @param This Pointer to driver binding protocol | |
+ @param Controller Controller handle to connect | |
+ @param NumberOfChildren Number of children handle created by this driver | |
+ @param ChildHandleBuffer Buffer containing child handle created | |
+ | |
+ @retval EFI_SUCCESS Driver disconnected successfully from controller | |
+ @retval EFI_UNSUPPORTED Cannot find BIOS_VIDEO_DEV structure | |
+ | |
+**/ | |
+EFI_STATUS | |
+EFIAPI | |
+BiosVideoDriverBindingStop ( | |
+ IN EFI_DRIVER_BINDING_PROTOCOL *This, | |
+ IN EFI_HANDLE Controller, | |
+ IN UINTN NumberOfChildren, | |
+ IN EFI_HANDLE *ChildHandleBuffer | |
+ ); | |
+ | |
+// | |
+// Private worker functions | |
+// | |
+ | |
+/** | |
+ Check for VBE device. | |
+ | |
+ @param BiosVideoPrivate Pointer to BIOS_VIDEO_DEV structure | |
+ | |
+ @retval EFI_SUCCESS VBE device found | |
+ | |
+**/ | |
+EFI_STATUS | |
+BiosVideoCheckForVbe ( | |
+ IN OUT BIOS_VIDEO_DEV *BiosVideoPrivate | |
+ ); | |
+ | |
+ | |
+/** | |
+ Check for VGA device. | |
+ | |
+ @param BiosVideoPrivate Pointer to BIOS_VIDEO_DEV structure | |
+ | |
+ @retval EFI_SUCCESS Standard VGA device found | |
+ | |
+**/ | |
+EFI_STATUS | |
+BiosVideoCheckForVga ( | |
+ IN OUT BIOS_VIDEO_DEV *BiosVideoPrivate | |
+ ); | |
+ | |
+ | |
+ | |
+ | |
+/** | |
+ Release resource for biso video instance. | |
+ | |
+ @param BiosVideoPrivate Video child device private data structure | |
+ | |
+**/ | |
+VOID | |
+BiosVideoDeviceReleaseResource ( | |
+ BIOS_VIDEO_DEV *BiosVideoPrivate | |
+ ); | |
+ | |
+// | |
+// BIOS Graphics Output Protocol functions | |
+// | |
+ | |
+/** | |
+ Graphics Output protocol interface to get video mode. | |
+ | |
+ @param This Protocol instance pointer. | |
+ @param ModeNumber The mode number to return information on. | |
+ @param SizeOfInfo A pointer to the size, in bytes, of the Info | |
+ buffer. | |
+ @param Info Caller allocated buffer that returns information | |
+ about ModeNumber. | |
+ | |
+ @retval EFI_SUCCESS Mode information returned. | |
+ @retval EFI_BUFFER_TOO_SMALL The Info buffer was too small. | |
+ @retval EFI_DEVICE_ERROR A hardware error occurred trying to retrieve the | |
+ video mode. | |
+ @retval EFI_NOT_STARTED Video display is not initialized. Call SetMode () | |
+ @retval EFI_INVALID_PARAMETER One of the input args was NULL. | |
+ | |
+**/ | |
+EFI_STATUS | |
+EFIAPI | |
+BiosVideoGraphicsOutputQueryMode ( | |
+ IN EFI_GRAPHICS_OUTPUT_PROTOCOL *This, | |
+ IN UINT32 ModeNumber, | |
+ OUT UINTN *SizeOfInfo, | |
+ OUT EFI_GRAPHICS_OUTPUT_MODE_INFORMATION **Info | |
+ ); | |
+ | |
+ | |
+/** | |
+ Graphics Output protocol interface to set video mode. | |
+ | |
+ @param This Protocol instance pointer. | |
+ @param ModeNumber The mode number to be set. | |
+ | |
+ @retval EFI_SUCCESS Graphics mode was changed. | |
+ @retval EFI_DEVICE_ERROR The device had an error and could not complete the | |
+ request. | |
+ @retval EFI_UNSUPPORTED ModeNumber is not supported by this device. | |
+ | |
+**/ | |
+EFI_STATUS | |
+EFIAPI | |
+BiosVideoGraphicsOutputSetMode ( | |
+ IN EFI_GRAPHICS_OUTPUT_PROTOCOL * This, | |
+ IN UINT32 ModeNumber | |
+ ); | |
+ | |
+ | |
+/** | |
+ Graphics Output protocol instance to block transfer for VBE device. | |
+ | |
+ @param This Pointer to Graphics Output protocol instance | |
+ @param BltBuffer The data to transfer to screen | |
+ @param BltOperation The operation to perform | |
+ @param SourceX The X coordinate of the source for BltOperation | |
+ @param SourceY The Y coordinate of the source for BltOperation | |
+ @param DestinationX The X coordinate of the destination for | |
+ BltOperation | |
+ @param DestinationY The Y coordinate of the destination for | |
+ BltOperation | |
+ @param Width The width of a rectangle in the blt rectangle in | |
+ pixels | |
+ @param Height The height of a rectangle in the blt rectangle in | |
+ pixels | |
+ @param Delta Not used for EfiBltVideoFill and | |
+ EfiBltVideoToVideo operation. If a Delta of 0 is | |
+ used, the entire BltBuffer will be operated on. If | |
+ a subrectangle of the BltBuffer is used, then | |
+ Delta represents the number of bytes in a row of | |
+ the BltBuffer. | |
+ | |
+ @retval EFI_INVALID_PARAMETER Invalid parameter passed in | |
+ @retval EFI_SUCCESS Blt operation success | |
+ | |
+**/ | |
+EFI_STATUS | |
+EFIAPI | |
+BiosVideoGraphicsOutputVbeBlt ( | |
+ IN EFI_GRAPHICS_OUTPUT_PROTOCOL *This, | |
+ IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer, OPTIONAL | |
+ IN EFI_GRAPHICS_OUTPUT_BLT_OPERATION BltOperation, | |
+ IN UINTN SourceX, | |
+ IN UINTN SourceY, | |
+ IN UINTN DestinationX, | |
+ IN UINTN DestinationY, | |
+ IN UINTN Width, | |
+ IN UINTN Height, | |
+ IN UINTN Delta | |
+ ); | |
+ | |
+ | |
+/** | |
+ Grahpics Output protocol instance to block transfer for VGA device. | |
+ | |
+ @param This Pointer to Grahpics Output protocol instance | |
+ @param BltBuffer The data to transfer to screen | |
+ @param BltOperation The operation to perform | |
+ @param SourceX The X coordinate of the source for BltOperation | |
+ @param SourceY The Y coordinate of the source for BltOperation | |
+ @param DestinationX The X coordinate of the destination for | |
+ BltOperation | |
+ @param DestinationY The Y coordinate of the destination for | |
+ BltOperation | |
+ @param Width The width of a rectangle in the blt rectangle in | |
+ pixels | |
+ @param Height The height of a rectangle in the blt rectangle in | |
+ pixels | |
+ @param Delta Not used for EfiBltVideoFill and | |
+ EfiBltVideoToVideo operation. If a Delta of 0 is | |
+ used, the entire BltBuffer will be operated on. If | |
+ a subrectangle of the BltBuffer is used, then | |
+ Delta represents the number of bytes in a row of | |
+ the BltBuffer. | |
+ | |
+ @retval EFI_INVALID_PARAMETER Invalid parameter passed in | |
+ @retval EFI_SUCCESS Blt operation success | |
+ | |
+**/ | |
+EFI_STATUS | |
+EFIAPI | |
+BiosVideoGraphicsOutputVgaBlt ( | |
+ IN EFI_GRAPHICS_OUTPUT_PROTOCOL *This, | |
+ IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer, OPTIONAL | |
+ IN EFI_GRAPHICS_OUTPUT_BLT_OPERATION BltOperation, | |
+ IN UINTN SourceX, | |
+ IN UINTN SourceY, | |
+ IN UINTN DestinationX, | |
+ IN UINTN DestinationY, | |
+ IN UINTN Width, | |
+ IN UINTN Height, | |
+ IN UINTN Delta | |
+ ); | |
+ | |
+// | |
+// BIOS VGA Mini Port Protocol functions | |
+// | |
+ | |
+/** | |
+ VgaMiniPort protocol interface to set mode. | |
+ | |
+ @param This Pointer to VgaMiniPort protocol instance | |
+ @param ModeNumber The index of the mode | |
+ | |
+ @retval EFI_UNSUPPORTED The requested mode is not supported | |
+ @retval EFI_SUCCESS The requested mode is set successfully | |
+ | |
+**/ | |
+EFI_STATUS | |
+EFIAPI | |
+BiosVideoVgaMiniPortSetMode ( | |
+ IN EFI_VGA_MINI_PORT_PROTOCOL *This, | |
+ IN UINTN ModeNumber | |
+ ); | |
+ | |
+/** | |
+ Event handler for Exit Boot Service. | |
+ | |
+ @param Event The event that be siganlled when exiting boot service. | |
+ @param Context Pointer to instance of BIOS_VIDEO_DEV. | |
+ | |
+**/ | |
+VOID | |
+EFIAPI | |
+BiosVideoNotifyExitBootServices ( | |
+ IN EFI_EVENT Event, | |
+ IN VOID *Context | |
+ ); | |
+ | |
+// | |
+// Standard VGA Definitions | |
+// | |
+#define VGA_HORIZONTAL_RESOLUTION 640 | |
+#define VGA_VERTICAL_RESOLUTION 480 | |
+#define VGA_NUMBER_OF_BIT_PLANES 4 | |
+#define VGA_PIXELS_PER_BYTE 8 | |
+#define VGA_BYTES_PER_SCAN_LINE (VGA_HORIZONTAL_RESOLUTION / VGA_PIXELS_PER_BYTE) | |
+#define VGA_BYTES_PER_BIT_PLANE (VGA_VERTICAL_RESOLUTION * VGA_BYTES_PER_SCAN_LINE) | |
+ | |
+#define VGA_GRAPHICS_CONTROLLER_ADDRESS_REGISTER 0x3ce | |
+#define VGA_GRAPHICS_CONTROLLER_DATA_REGISTER 0x3cf | |
+ | |
+#define VGA_GRAPHICS_CONTROLLER_SET_RESET_REGISTER 0x00 | |
+ | |
+#define VGA_GRAPHICS_CONTROLLER_ENABLE_SET_RESET_REGISTER 0x01 | |
+ | |
+#define VGA_GRAPHICS_CONTROLLER_COLOR_COMPARE_REGISTER 0x02 | |
+ | |
+#define VGA_GRAPHICS_CONTROLLER_DATA_ROTATE_REGISTER 0x03 | |
+#define VGA_GRAPHICS_CONTROLLER_FUNCTION_REPLACE 0x00 | |
+#define VGA_GRAPHICS_CONTROLLER_FUNCTION_AND 0x08 | |
+#define VGA_GRAPHICS_CONTROLLER_FUNCTION_OR 0x10 | |
+#define VGA_GRAPHICS_CONTROLLER_FUNCTION_XOR 0x18 | |
+ | |
+#define VGA_GRAPHICS_CONTROLLER_READ_MAP_SELECT_REGISTER 0x04 | |
+ | |
+#define VGA_GRAPHICS_CONTROLLER_MODE_REGISTER 0x05 | |
+#define VGA_GRAPHICS_CONTROLLER_READ_MODE_0 0x00 | |
+#define VGA_GRAPHICS_CONTROLLER_READ_MODE_1 0x08 | |
+#define VGA_GRAPHICS_CONTROLLER_WRITE_MODE_0 0x00 | |
+#define VGA_GRAPHICS_CONTROLLER_WRITE_MODE_1 0x01 | |
+#define VGA_GRAPHICS_CONTROLLER_WRITE_MODE_2 0x02 | |
+#define VGA_GRAPHICS_CONTROLLER_WRITE_MODE_3 0x03 | |
+ | |
+#define VGA_GRAPHICS_CONTROLLER_MISCELLANEOUS_REGISTER 0x06 | |
+ | |
+#define VGA_GRAPHICS_CONTROLLER_COLOR_DONT_CARE_REGISTER 0x07 | |
+ | |
+#define VGA_GRAPHICS_CONTROLLER_BIT_MASK_REGISTER 0x08 | |
+ | |
+/** | |
+ Install child handles if the Handle supports MBR format. | |
+ | |
+ @param This Calling context. | |
+ @param ParentHandle Parent Handle | |
+ @param ParentPciIo Parent PciIo interface | |
+ @param ParentLegacyBios Parent LegacyBios interface | |
+ @param ParentDevicePath Parent Device Path | |
+ @param RemainingDevicePath Remaining Device Path | |
+ | |
+ @retval EFI_SUCCESS If a child handle was added | |
+ @retval other A child handle was not added | |
+ | |
+**/ | |
+EFI_STATUS | |
+BiosVideoChildHandleInstall ( | |
+ IN EFI_DRIVER_BINDING_PROTOCOL *This, | |
+ IN EFI_HANDLE ParentHandle, | |
+ IN EFI_PCI_IO_PROTOCOL *ParentPciIo, | |
+ IN EFI_LEGACY_BIOS_PROTOCOL *ParentLegacyBios, | |
+ IN EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath, | |
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath | |
+ ); | |
+ | |
+/** | |
+ Deregister an video child handle and free resources. | |
+ | |
+ @param This Protocol instance pointer. | |
+ @param Controller Video controller handle | |
+ @param Handle Video child handle | |
+ | |
+ @return EFI_STATUS | |
+ | |
+**/ | |
+EFI_STATUS | |
+BiosVideoChildHandleUninstall ( | |
+ EFI_DRIVER_BINDING_PROTOCOL *This, | |
+ EFI_HANDLE Controller, | |
+ EFI_HANDLE Handle | |
+ ); | |
+ | |
+/** | |
+ Release resource for biso video instance. | |
+ | |
+ @param BiosVideoPrivate Video child device private data structure | |
+ | |
+**/ | |
+VOID | |
+BiosVideoDeviceReleaseResource ( | |
+ BIOS_VIDEO_DEV *BiosVideoPrivate | |
+ ); | |
+ | |
+/** | |
+ Check if all video child handles have been uninstalled. | |
+ | |
+ @param Controller Video controller handle | |
+ | |
+ @return TRUE Child handles exist. | |
+ @return FALSE All video child handles have been uninstalled. | |
+ | |
+**/ | |
+BOOLEAN | |
+HasChildHandle ( | |
+ IN EFI_HANDLE Controller | |
+ ); | |
+#endif | |
diff --git a/OvmfPkg/CsmOld/VideoDxe/VesaBiosExtensions.h b/OvmfPkg/CsmOld/VideoDxe/VesaBiosExtensions.h | |
new file mode 100644 | |
index 000000000000..25eee6921d51 | |
--- /dev/null | |
+++ b/OvmfPkg/CsmOld/VideoDxe/VesaBiosExtensions.h | |
@@ -0,0 +1,466 @@ | |
+/** @file | |
+ | |
+Copyright (c) 2006 - 2013, 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. | |
+ | |
+**/ | |
+ | |
+#ifndef _VESA_BIOS_EXTENSIONS_H_ | |
+#define _VESA_BIOS_EXTENSIONS_H_ | |
+ | |
+// | |
+// Turn on byte packing of data structures | |
+// | |
+#pragma pack(1) | |
+// | |
+// VESA BIOS Extensions status codes | |
+// | |
+#define VESA_BIOS_EXTENSIONS_STATUS_SUCCESS 0x004f | |
+ | |
+// | |
+// VESA BIOS Extensions Services | |
+// | |
+#define VESA_BIOS_EXTENSIONS_RETURN_CONTROLLER_INFORMATION 0x4f00 | |
+ | |
+/*++ | |
+ | |
+ Routine Description: | |
+ Function 00 : Return Controller Information | |
+ | |
+ Arguments: | |
+ Inputs: | |
+ AX = 0x4f00 | |
+ ES:DI = Pointer to buffer to place VESA_BIOS_EXTENSIONS_INFORMATION_BLOCK structure | |
+ Outputs: | |
+ AX = Return Status | |
+ | |
+--*/ | |
+#define VESA_BIOS_EXTENSIONS_RETURN_MODE_INFORMATION 0x4f01 | |
+ | |
+/*++ | |
+ | |
+ Routine Description: | |
+ Function 01 : Return Mode Information | |
+ | |
+ Arguments: | |
+ Inputs: | |
+ AX = 0x4f01 | |
+ CX = Mode Number | |
+ ES:DI = Pointer to buffer to place VESA_BIOS_EXTENSIONS_MODE_INFORMATION_BLOCK structure | |
+ Outputs: | |
+ AX = Return Status | |
+ | |
+--*/ | |
+#define VESA_BIOS_EXTENSIONS_SET_MODE 0x4f02 | |
+ | |
+/*++ | |
+ | |
+ Routine Description: | |
+ Function 02 : Set Mode | |
+ | |
+ Arguments: | |
+ Inputs: | |
+ AX = 0x4f02 | |
+ BX = Desired mode to set | |
+ D0-D8 = Mode Number | |
+ D9-D10 = Reserved (must be 0) | |
+ D11 = 0 - Use current default refresh rate | |
+ = 1 - Use user specfieid CRTC values for refresh rate | |
+ D12-D13 = Reserved (must be 0) | |
+ D14 = 0 - Use windowed frame buffer model | |
+ = 1 - Use linear/flat frame buffer model | |
+ D15 = 0 - Clear display memory | |
+ = 1 - Don't clear display memory | |
+ ES:DI = Pointer to buffer to the VESA_BIOS_EXTENSIONS_CRTC_INFORMATION_BLOCK structure | |
+ Outputs: | |
+ AX = Return Status | |
+ | |
+--*/ | |
+#define VESA_BIOS_EXTENSIONS_RETURN_CURRENT_MODE 0x4f03 | |
+ | |
+/*++ | |
+ | |
+ Routine Description: | |
+ Function 03 : Return Current Mode | |
+ | |
+ Arguments: | |
+ Inputs: | |
+ AX = 0x4f03 | |
+ Outputs: | |
+ AX = Return Status | |
+ BX = Current mode | |
+ D0-D13 = Mode Number | |
+ D14 = 0 - Windowed frame buffer model | |
+ = 1 - Linear/flat frame buffer model | |
+ D15 = 0 - Memory cleared at last mode set | |
+ = 1 - Memory not cleared at last mode set | |
+ | |
+--*/ | |
+#define VESA_BIOS_EXTENSIONS_SAVE_RESTORE_STATE 0x4f04 | |
+ | |
+/*++ | |
+ | |
+ Routine Description: | |
+ Function 04 : Save/Restore State | |
+ | |
+ Arguments: | |
+ Inputs: | |
+ AX = 0x4f03 | |
+ DL = 0x00 - Return Save/Restore State buffer size | |
+ = 0x01 - Save State | |
+ = 0x02 - Restore State | |
+ CX = Requested Status | |
+ D0 = Save/Restore controller hardware state | |
+ D1 = Save/Restore BIOS data state | |
+ D2 = Save/Restore DAC state | |
+ D3 = Save/Restore Regsiter state | |
+ ES:BX = Pointer to buffer if DL=1 or DL=2 | |
+ Outputs: | |
+ AX = Return Status | |
+ BX = Number of 64 byte blocks to hold the state buffer if DL=0 | |
+ | |
+--*/ | |
+#define VESA_BIOS_EXTENSIONS_EDID 0x4f15 | |
+ | |
+/*++ | |
+ | |
+ Routine Description: | |
+ Function 15 : implement VBE/DDC service | |
+ | |
+ Arguments: | |
+ Inputs: | |
+ AX = 0x4f15 | |
+ BL = 0x00 - Report VBE/DDC Capabilities | |
+ CX = 0x00 - Controller unit number (00 = primary controller) | |
+ ES:DI = Null pointer, must be 0:0 in version 1.0 | |
+ Outputs: | |
+ AX = Return Status | |
+ BH = Approx. time in seconds, rounded up, to transfer one EDID block(128 bytes) | |
+ BL = DDC level supported | |
+ D0 = 0 DDC1 not supported | |
+ = 1 DDC1 supported | |
+ D1 = 0 DDC2 not supported | |
+ = 1 DDC2 supported | |
+ D2 = 0 Screen not blanked during data transfer | |
+ = 1 Screen blanked during data transfer | |
+ | |
+ Inputs: | |
+ AX = 0x4f15 | |
+ BL = 0x01 - Read EDID | |
+ CX = 0x00 - Controller unit number (00 = primary controller) | |
+ DX = 0x00 - EDID block number | |
+ ES:DI = Pointer to buffer in which the EDID block is returned | |
+ Outputs: | |
+ AX = Return Status | |
+--*/ | |
+ | |
+// | |
+// Timing data from EDID data block | |
+// | |
+#define VESA_BIOS_EXTENSIONS_EDID_BLOCK_SIZE 128 | |
+#define VESA_BIOS_EXTENSIONS_EDID_ESTABLISHED_TIMING_MAX_NUMBER 17 | |
+ | |
+// | |
+// Established Timings: 24 possible resolutions | |
+// Standard Timings: 8 possible resolutions | |
+// Detailed Timings: 4 possible resolutions | |
+// | |
+#define VESA_BIOS_EXTENSIONS_EDID_TIMING_MAX_NUMBER 36 | |
+ | |
+// | |
+// Timing data size for Established Timings, Standard Timings and Detailed Timings | |
+// | |
+#define VESA_BIOS_EXTENSIONS_ESTABLISHED_TIMING_SIZE 3 | |
+#define VESA_BIOS_EXTENSIONS_STANDARD_TIMING_SIZE 16 | |
+#define VESA_BIOS_EXTENSIONS_DETAILED_TIMING_EACH_DESCRIPTOR_SIZE 18 | |
+#define VESA_BIOS_EXTENSIONS_DETAILED_TIMING_DESCRIPTOR_MAX_SIZE 72 | |
+ | |
+typedef struct { | |
+ UINT16 HorizontalResolution; | |
+ UINT16 VerticalResolution; | |
+ UINT16 RefreshRate; | |
+} VESA_BIOS_EXTENSIONS_EDID_TIMING; | |
+ | |
+typedef struct { | |
+ UINT32 ValidNumber; | |
+ UINT32 Key[VESA_BIOS_EXTENSIONS_EDID_TIMING_MAX_NUMBER]; | |
+} VESA_BIOS_EXTENSIONS_VALID_EDID_TIMING; | |
+ | |
+typedef struct { | |
+ UINT8 Header[8]; //EDID header "00 FF FF FF FF FF FF 00" | |
+ UINT16 ManufactureName; //EISA 3-character ID | |
+ UINT16 ProductCode; //Vendor assigned code | |
+ UINT32 SerialNumber; //32-bit serial number | |
+ UINT8 WeekOfManufacture; //Week number | |
+ UINT8 YearOfManufacture; //Year | |
+ UINT8 EdidVersion; //EDID Structure Version | |
+ UINT8 EdidRevision; //EDID Structure Revision | |
+ UINT8 VideoInputDefinition; | |
+ UINT8 MaxHorizontalImageSize; //cm | |
+ UINT8 MaxVerticalImageSize; //cm | |
+ UINT8 DisplayTransferCharacteristic; | |
+ UINT8 FeatureSupport; | |
+ UINT8 RedGreenLowBits; //Rx1 Rx0 Ry1 Ry0 Gx1 Gx0 Gy1Gy0 | |
+ UINT8 BlueWhiteLowBits; //Bx1 Bx0 By1 By0 Wx1 Wx0 Wy1 Wy0 | |
+ UINT8 RedX; //Red-x Bits 9 - 2 | |
+ UINT8 RedY; //Red-y Bits 9 - 2 | |
+ UINT8 GreenX; //Green-x Bits 9 - 2 | |
+ UINT8 GreenY; //Green-y Bits 9 - 2 | |
+ UINT8 BlueX; //Blue-x Bits 9 - 2 | |
+ UINT8 BlueY; //Blue-y Bits 9 - 2 | |
+ UINT8 WhiteX; //White-x Bits 9 - 2 | |
+ UINT8 WhiteY; //White-x Bits 9 - 2 | |
+ UINT8 EstablishedTimings[VESA_BIOS_EXTENSIONS_ESTABLISHED_TIMING_SIZE]; | |
+ UINT8 StandardTimingIdentification[VESA_BIOS_EXTENSIONS_STANDARD_TIMING_SIZE]; | |
+ UINT8 DetailedTimingDescriptions[VESA_BIOS_EXTENSIONS_DETAILED_TIMING_DESCRIPTOR_MAX_SIZE]; | |
+ UINT8 ExtensionFlag; //Number of (optional) 128-byte EDID extension blocks to follow | |
+ UINT8 Checksum; | |
+} VESA_BIOS_EXTENSIONS_EDID_DATA_BLOCK; | |
+ | |
+// | |
+// Super VGA Information Block | |
+// | |
+typedef struct { | |
+ UINT32 VESASignature; // 'VESA' 4 byte signature | |
+ UINT16 VESAVersion; // VBE version number | |
+ UINT32 OEMStringPtr; // Pointer to OEM string | |
+ UINT32 Capabilities; // Capabilities of video card | |
+ UINT32 VideoModePtr; // Pointer to an array of 16-bit supported modes values terminated by 0xFFFF | |
+ UINT16 TotalMemory; // Number of 64kb memory blocks | |
+ UINT16 OemSoftwareRev; // VBE implementation Software revision | |
+ UINT32 OemVendorNamePtr; // VbeFarPtr to Vendor Name String | |
+ UINT32 OemProductNamePtr; // VbeFarPtr to Product Name String | |
+ UINT32 OemProductRevPtr; // VbeFarPtr to Product Revision String | |
+ UINT8 Reserved[222]; // Reserved for VBE implementation scratch area | |
+ UINT8 OemData[256]; // Data area for OEM strings. Pad to 512 byte block size | |
+} VESA_BIOS_EXTENSIONS_INFORMATION_BLOCK; | |
+ | |
+// | |
+// Super VGA Information Block VESASignature values | |
+// | |
+#define VESA_BIOS_EXTENSIONS_VESA_SIGNATURE SIGNATURE_32 ('V', 'E', 'S', 'A') | |
+#define VESA_BIOS_EXTENSIONS_VBE2_SIGNATURE SIGNATURE_32 ('V', 'B', 'E', '2') | |
+ | |
+// | |
+// Super VGA Information Block VESAVersion values | |
+// | |
+#define VESA_BIOS_EXTENSIONS_VERSION_1_2 0x0102 | |
+#define VESA_BIOS_EXTENSIONS_VERSION_2_0 0x0200 | |
+#define VESA_BIOS_EXTENSIONS_VERSION_3_0 0x0300 | |
+ | |
+// | |
+// Super VGA Information Block Capabilities field bit defintions | |
+// | |
+#define VESA_BIOS_EXTENSIONS_CAPABILITY_8_BIT_DAC 0x01 // 0: DAC width is fixed at 6 bits/color | |
+// 1: DAC width switchable to 8 bits/color | |
+// | |
+#define VESA_BIOS_EXTENSIONS_CAPABILITY_NOT_VGA 0x02 // 0: Controller is VGA compatible | |
+// 1: Controller is not VGA compatible | |
+// | |
+#define VESA_BIOS_EXTENSIONS_CAPABILITY_NOT_NORMAL_RAMDAC 0x04 // 0: Normal RAMDAC operation | |
+// 1: Use blank bit in function 9 to program RAMDAC | |
+// | |
+#define VESA_BIOS_EXTENSIONS_CAPABILITY_STEREOSCOPIC 0x08 // 0: No hardware stereoscopic signal support | |
+// 1: Hardware stereoscopic signal support | |
+// | |
+#define VESA_BIOS_EXTENSIONS_CAPABILITY_VESA_EVC 0x10 // 0: Stero signaling supported via external VESA stereo connector | |
+// 1: Stero signaling supported via VESA EVC connector | |
+// | |
+// Super VGA mode number bite field definitions | |
+// | |
+#define VESA_BIOS_EXTENSIONS_MODE_NUMBER_VESA 0x0100 // 0: Not a VESA defined VBE mode | |
+// 1: A VESA defined VBE mode | |
+// | |
+#define VESA_BIOS_EXTENSIONS_MODE_NUMBER_REFRESH_CONTROL_USER 0x0800 // 0: Use current BIOS default referesh rate | |
+// 1: Use the user specified CRTC values for refresh rate | |
+// | |
+#define VESA_BIOS_EXTENSIONS_MODE_NUMBER_LINEAR_FRAME_BUFFER 0x4000 // 0: Use a banked/windowed frame buffer | |
+// 1: Use a linear/flat frame buffer | |
+// | |
+#define VESA_BIOS_EXTENSIONS_MODE_NUMBER_PRESERVE_MEMORY 0x8000 // 0: Clear display memory | |
+// 1: Preseve display memory | |
+// | |
+// Super VGA Information Block mode list terminator value | |
+// | |
+#define VESA_BIOS_EXTENSIONS_END_OF_MODE_LIST 0xffff | |
+ | |
+// | |
+// Window Function | |
+// | |
+typedef | |
+VOID | |
+(*VESA_BIOS_EXTENSIONS_WINDOW_FUNCTION) ( | |
+ VOID | |
+ ); | |
+ | |
+// | |
+// Super VGA Mode Information Block | |
+// | |
+typedef struct { | |
+ // | |
+ // Manadory fields for all VESA Bios Extensions revisions | |
+ // | |
+ UINT16 ModeAttributes; // Mode attributes | |
+ UINT8 WinAAttributes; // Window A attributes | |
+ UINT8 WinBAttributes; // Window B attributes | |
+ UINT16 WinGranularity; // Window granularity in k | |
+ UINT16 WinSize; // Window size in k | |
+ UINT16 WinASegment; // Window A segment | |
+ UINT16 WinBSegment; // Window B segment | |
+ UINT32 WindowFunction; // Pointer to window function | |
+ UINT16 BytesPerScanLine; // Bytes per scanline | |
+ // | |
+ // Manadory fields for VESA Bios Extensions 1.2 and above | |
+ // | |
+ UINT16 XResolution; // Horizontal resolution | |
+ UINT16 YResolution; // Vertical resolution | |
+ UINT8 XCharSize; // Character cell width | |
+ UINT8 YCharSize; // Character cell height | |
+ UINT8 NumberOfPlanes; // Number of memory planes | |
+ UINT8 BitsPerPixel; // Bits per pixel | |
+ UINT8 NumberOfBanks; // Number of CGA style banks | |
+ UINT8 MemoryModel; // Memory model type | |
+ UINT8 BankSize; // Size of CGA style banks | |
+ UINT8 NumberOfImagePages; // Number of images pages | |
+ UINT8 Reserved1; // Reserved | |
+ UINT8 RedMaskSize; // Size of direct color red mask | |
+ UINT8 RedFieldPosition; // Bit posn of lsb of red mask | |
+ UINT8 GreenMaskSize; // Size of direct color green mask | |
+ UINT8 GreenFieldPosition; // Bit posn of lsb of green mask | |
+ UINT8 BlueMaskSize; // Size of direct color blue mask | |
+ UINT8 BlueFieldPosition; // Bit posn of lsb of blue mask | |
+ UINT8 RsvdMaskSize; // Size of direct color res mask | |
+ UINT8 RsvdFieldPosition; // Bit posn of lsb of res mask | |
+ UINT8 DirectColorModeInfo; // Direct color mode attributes | |
+ // | |
+ // Manadory fields for VESA Bios Extensions 2.0 and above | |
+ // | |
+ UINT32 PhysBasePtr; // Physical Address for flat memory frame buffer | |
+ UINT32 Reserved2; // Reserved | |
+ UINT16 Reserved3; // Reserved | |
+ // | |
+ // Manadory fields for VESA Bios Extensions 3.0 and above | |
+ // | |
+ UINT16 LinBytesPerScanLine; // Bytes/scan line for linear modes | |
+ UINT8 BnkNumberOfImagePages; // Number of images for banked modes | |
+ UINT8 LinNumberOfImagePages; // Number of images for linear modes | |
+ UINT8 LinRedMaskSize; // Size of direct color red mask (linear mode) | |
+ UINT8 LinRedFieldPosition; // Bit posiiton of lsb of red mask (linear modes) | |
+ UINT8 LinGreenMaskSize; // Size of direct color green mask (linear mode) | |
+ UINT8 LinGreenFieldPosition; // Bit posiiton of lsb of green mask (linear modes) | |
+ UINT8 LinBlueMaskSize; // Size of direct color blue mask (linear mode) | |
+ UINT8 LinBlueFieldPosition; // Bit posiiton of lsb of blue mask (linear modes) | |
+ UINT8 LinRsvdMaskSize; // Size of direct color reserved mask (linear mode) | |
+ UINT8 LinRsvdFieldPosition; // Bit posiiton of lsb of reserved mask (linear modes) | |
+ UINT32 MaxPixelClock; // Maximum pixel clock (in Hz) for graphics mode | |
+ UINT8 Pad[190]; // Pad to 256 byte block size | |
+} VESA_BIOS_EXTENSIONS_MODE_INFORMATION_BLOCK; | |
+ | |
+// | |
+// Super VGA Mode Information Block ModeAttributes field bit defintions | |
+// | |
+#define VESA_BIOS_EXTENSIONS_MODE_ATTRIBUTE_HARDWARE 0x0001 // 0: Mode not supported in handware | |
+// 1: Mode supported in handware | |
+// | |
+#define VESA_BIOS_EXTENSIONS_MODE_ATTRIBUTE_TTY 0x0004 // 0: TTY Output functions not supported by BIOS | |
+// 1: TTY Output functions supported by BIOS | |
+// | |
+#define VESA_BIOS_EXTENSIONS_MODE_ATTRIBUTE_COLOR 0x0008 // 0: Monochrome mode | |
+// 1: Color mode | |
+// | |
+#define VESA_BIOS_EXTENSIONS_MODE_ATTRIBUTE_GRAPHICS 0x0010 // 0: Text mode | |
+// 1: Graphics mode | |
+// | |
+#define VESA_BIOS_EXTENSIONS_MODE_ATTRIBUTE_NOT_VGA 0x0020 // 0: VGA compatible mode | |
+// 1: Not a VGA compatible mode | |
+// | |
+#define VESA_BIOS_EXTENSIONS_MODE_ATTRIBUTE_NOT_WINDOWED 0x0040 // 0: VGA compatible windowed memory mode | |
+// 1: Not a VGA compatible windowed memory mode | |
+// | |
+#define VESA_BIOS_EXTENSIONS_MODE_ATTRIBUTE_LINEAR_FRAME_BUFFER 0x0080 // 0: No linear fram buffer mode available | |
+// 1: Linear frame buffer mode available | |
+// | |
+#define VESA_BIOS_EXTENSIONS_MODE_ATTRIBUTE_DOUBLE_SCAN 0x0100 // 0: No double scan mode available | |
+// 1: Double scan mode available | |
+// | |
+#define VESA_BIOS_EXTENSIONS_MODE_ATTRIBUTE_INTERLACED 0x0200 // 0: No interlaced mode is available | |
+// 1: Interlaced mode is available | |
+// | |
+#define VESA_BIOS_EXTENSIONS_MODE_ATTRIBUTE_NO_TRIPPLE_BUFFER 0x0400 // 0: No hardware triple buffer mode support available | |
+// 1: Hardware triple buffer mode support available | |
+// | |
+#define VESA_BIOS_EXTENSIONS_MODE_ATTRIBUTE_STEREOSCOPIC 0x0800 // 0: No hardware steroscopic display support | |
+// 1: Hardware steroscopic display support | |
+// | |
+#define VESA_BIOS_EXTENSIONS_MODE_ATTRIBUTE_DUAL_DISPLAY 0x1000 // 0: No dual display start address support | |
+// 1: Dual display start address support | |
+// | |
+// Super VGA Mode Information Block WinAAttribite/WinBAttributes field bit defintions | |
+// | |
+#define VESA_BIOS_EXTENSIONS_WINX_ATTRIBUTE_RELOCATABLE 0x01 // 0: Single non-relocatable window only | |
+// 1: Relocatable window(s) are supported | |
+// | |
+#define VESA_BIOS_EXTENSIONS_WINX_ATTRIBUTE_READABLE 0x02 // 0: Window is not readable | |
+// 1: Window is readable | |
+// | |
+#define VESA_BIOS_EXTENSIONS_WINX_ATTRIBUTE_WRITABLE 0x04 // 0: Window is not writable | |
+// 1: Window is writable | |
+// | |
+// Super VGA Mode Information Block DirectColorMode field bit defintions | |
+// | |
+#define VESA_BIOS_EXTENSIONS_DIRECT_COLOR_MODE_PROG_COLOR_RAMP 0x01 // 0: Color ram is fixed | |
+// 1: Color ramp is programmable | |
+// | |
+#define VESA_BIOS_EXTENSIONS_DIRECT_COLOR_MODE_RSVD_USABLE 0x02 // 0: Bits in Rsvd field are reserved | |
+// 1: Bits in Rsdv field are usable | |
+// | |
+// Super VGA Memory Models | |
+// | |
+typedef enum { | |
+ MemPL = 3, // Planar memory model | |
+ MemPK = 4, // Packed pixel memory model | |
+ MemRGB= 6, // Direct color RGB memory model | |
+ MemYUV= 7 // Direct color YUV memory model | |
+} VESA_BIOS_EXTENSIONS_MEMORY_MODELS; | |
+ | |
+// | |
+// Super VGA CRTC Information Block | |
+// | |
+typedef struct { | |
+ UINT16 HorizontalTotal; // Horizontal total in pixels | |
+ UINT16 HorizontalSyncStart; // Horizontal sync start in pixels | |
+ UINT16 HorizontalSyncEnd; // Horizontal sync end in pixels | |
+ UINT16 VericalTotal; // Vertical total in pixels | |
+ UINT16 VericalSyncStart; // Vertical sync start in pixels | |
+ UINT16 VericalSyncEnd; // Vertical sync end in pixels | |
+ UINT8 Flags; // Flags (Interlaced/DoubleScan/etc). | |
+ UINT32 PixelClock; // Pixel clock in units of Hz | |
+ UINT16 RefreshRate; // Refresh rate in units of 0.01 Hz | |
+ UINT8 Reserved[40]; // Pad | |
+} VESA_BIOS_EXTENSIONS_CRTC_INFORMATION_BLOCK; | |
+ | |
+#define VESA_BIOS_EXTENSIONS_CRTC_FLAGS_DOUBLE_SCAN 0x01 // 0: Graphics mode is not souble scanned | |
+// 1: Graphics mode is double scanned | |
+// | |
+#define VESA_BIOS_EXTENSIONS_CRTC_FLAGSINTERLACED 0x02 // 0: Graphics mode is not interlaced | |
+// 1: Graphics mode is interlaced | |
+// | |
+#define VESA_BIOS_EXTENSIONS_CRTC_HORIZONTAL_SYNC_NEGATIVE 0x04 // 0: Horizontal sync polarity is positive(+) | |
+// 0: Horizontal sync polarity is negative(-) | |
+// | |
+#define VESA_BIOS_EXTENSIONS_CRTC_VERITICAL_SYNC_NEGATIVE 0x08 // 0: Verical sync polarity is positive(+) | |
+// 0: Verical sync polarity is negative(-) | |
+// | |
+// Turn off byte packing of data structures | |
+// | |
+#pragma pack() | |
+ | |
+#endif | |
diff --git a/OvmfPkg/QemuSmbiosPlatformDxe/Qemu.h b/OvmfPkg/QemuSmbiosPlatformDxe/Qemu.h | |
new file mode 100644 | |
index 000000000000..bc5fe866843b | |
--- /dev/null | |
+++ b/OvmfPkg/QemuSmbiosPlatformDxe/Qemu.h | |
@@ -0,0 +1,52 @@ | |
+/** @file | |
+ This header file provides QEMU-specific public prototypes for the main driver | |
+ file, "SmbiosPlatformDxe.c". | |
+ | |
+ Copyright (C) 2013, Red Hat, Inc. | |
+ | |
+ 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. | |
+**/ | |
+ | |
+#ifndef _QEMU_H_ | |
+#define _QEMU_H_ | |
+ | |
+#include <Protocol/Smbios.h> | |
+ | |
+ | |
+/** | |
+ Fetch and install SMBIOS tables on the QEMU hypervisor. | |
+ | |
+ First, tables provided by QEMU in entirety are installed verbatim. | |
+ | |
+ Then the function prepares some of the remaining tables required by the | |
+ SMBIOS-2.7.1 specification. For each such table, | |
+ - if QEMU provides any fields for the table, they take effect verbatim, | |
+ - remaining fields are set by this function. | |
+ | |
+ @param[in] Smbios The EFI_SMBIOS_PROTOCOL instance used for installing | |
+ the SMBIOS tables. | |
+ @param[in] ImageHandle The image handle of the calling module, passed as | |
+ ProducerHandle to the Smbios->Add() call. | |
+ | |
+ @retval EFI_SUCCESS All tables have been installed. | |
+ @retval EFI_UNSUPPORTED The pair (Smbios->MajorVersion, | |
+ Smbios->MinorVersion) precedes (2, 3) | |
+ lexicographically. | |
+ @return Error codes returned by Smbios->Add() or | |
+ internal functions. Some tables may not have | |
+ been installed or fully patched. | |
+**/ | |
+EFI_STATUS | |
+EFIAPI | |
+InstallQemuSmbiosTables ( | |
+ IN EFI_SMBIOS_PROTOCOL *Smbios, | |
+ IN EFI_HANDLE ImageHandle | |
+ ); | |
+ | |
+#endif | |
diff --git a/OvmfPkg/QemuSmbiosPlatformDxe/QemuInternal.h b/OvmfPkg/QemuSmbiosPlatformDxe/QemuInternal.h | |
new file mode 100644 | |
index 000000000000..f89d7744ca92 | |
--- /dev/null | |
+++ b/OvmfPkg/QemuSmbiosPlatformDxe/QemuInternal.h | |
@@ -0,0 +1,281 @@ | |
+/** @file | |
+ This header provides common includes, and communicates internal types, | |
+ function prototypes and macros between "Qemu.c" and "QemuTypeXX.c", that | |
+ relate to the installation and patching of SMBIOS tables on the QEMU | |
+ platform. | |
+ | |
+ Copyright (C) 2013, Red Hat, Inc. | |
+ | |
+ 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. | |
+**/ | |
+ | |
+#ifndef _QEMU_INTERNAL_H_ | |
+#define _QEMU_INTERNAL_H_ | |
+ | |
+#include <IndustryStandard/SmBios.h> | |
+#include <Library/BaseLib.h> | |
+#include <Library/BaseMemoryLib.h> | |
+#include <Library/DebugLib.h> | |
+#include <Library/QemuFwCfgLib.h> | |
+#include <Protocol/Smbios.h> | |
+ | |
+ | |
+// | |
+// Type identifiers of all tables mandated by the SMBIOS-2.7.1 specification | |
+// fall strictly under this limit. | |
+// | |
+#define TABLE_TYPE_LIMIT (EFI_SMBIOS_TYPE_SYSTEM_BOOT_INFORMATION + 1) | |
+ | |
+ | |
+// | |
+// Track a patch in dynamic memory, originating from a QEMU SMBIOS firmware | |
+// configuration entry with ET_FIELD type. | |
+// | |
+typedef struct { | |
+ UINT8 *Base; | |
+ UINT16 Size; | |
+} PATCH; | |
+ | |
+ | |
+#define FIELD_OFFSET_MINIMUM ((INT32) sizeof(SMBIOS_STRUCTURE)) | |
+#define PATCH_SUBSCRIPT_LIMIT (255 - FIELD_OFFSET_MINIMUM) | |
+ | |
+// | |
+// The following structure tracks the installation of each SMBIOS table with a | |
+// type below TABLE_TYPE_LIMIT, and captures QEMU SMBIOS firmware configuration | |
+// entries with ET_FIELD type that target the default table for the same type. | |
+// | |
+typedef struct { | |
+ BOOLEAN Installed; // at least one instance of the type has been installed | |
+ | |
+ PATCH Patch[PATCH_SUBSCRIPT_LIMIT]; // Patches indexed by the field offset | |
+ // that they target in this specific | |
+ // table type. Patching the SMBIOS table | |
+ // header is not allowed, hence we can | |
+ // shift down field offsets. An unused | |
+ // element has zeroed-out fields. | |
+} TABLE_CONTEXT; | |
+ | |
+ | |
+// | |
+// Track the installation of, and stored patches for, all table types below | |
+// TABLE_TYPE_LIMIT. | |
+// | |
+typedef struct { | |
+ TABLE_CONTEXT Table[TABLE_TYPE_LIMIT]; | |
+} BUILD_CONTEXT; | |
+ | |
+ | |
+// | |
+// Convenience / safety macro for defining C structure types for default SMBIOS | |
+// tables. | |
+// | |
+// Rules of use: | |
+// - Use only within #pragma pack(1). | |
+// - This macro depends on the macro | |
+// "OVMF_TYPE ## TableType ## _STRINGS" specifying the text strings | |
+// (unformatted area) for TableType. Each "QemuTypeXX.c" file needs to | |
+// provide said macro before using the one below. | |
+// | |
+#define OVMF_SMBIOS(TableType) \ | |
+ typedef struct { \ | |
+ SMBIOS_TABLE_TYPE##TableType Base; \ | |
+ UINT8 Strings[sizeof OVMF_TYPE##TableType##_STRINGS]; \ | |
+ } OVMF_TYPE##TableType | |
+ | |
+ | |
+// | |
+// Convenience / safety macro for patching a field in the formatted area of | |
+// an SMBIOS table. | |
+// | |
+#define PATCH_FORMATTED(Context, TableType, OvmfTablePtr, FieldName) \ | |
+ PatchSmbiosFormatted ( \ | |
+ Context, \ | |
+ TableType, \ | |
+ (UINT16) OFFSET_OF (SMBIOS_TABLE_TYPE##TableType, FieldName), \ | |
+ (UINT16) sizeof (OvmfTablePtr)->Base.FieldName, \ | |
+ (UINT8 *) (OvmfTablePtr) \ | |
+ ) | |
+ | |
+ | |
+/** | |
+ Apply a saved patch to a field located in the formatted are of a not yet | |
+ installed SMBIOS table. | |
+ | |
+ The patch is looked up based on (Context, TableType, FieldOffset). | |
+ | |
+ @param[in] Context The BUILD_CONTEXT object storing saved patches. | |
+ @param[in] TableType Selects the table type for which the patch has been | |
+ saved. It is assumed that the caller has validated | |
+ TableType against TABLE_TYPE_LIMIT (upper | |
+ exclusive). | |
+ @param[in] FieldOffset Selects the SMBIOS field for which the patch has | |
+ been saved. It is assumed that the caller has | |
+ validated FieldOffset against FIELD_OFFSET_MINIMUM | |
+ (lower inclusive) and 255 (upper exclusive). | |
+ @param[in] FieldSize The caller supplies the size of the field to patch | |
+ in FieldSize. The patch saved for | |
+ TableType:FieldOffset, if any, is only applied if | |
+ its size equals FieldSize. | |
+ @param[out] TableBase Base of the SMBIOS table of type TableType in which | |
+ the field starting at FieldOffset needs to be | |
+ patched. | |
+ | |
+ @retval EFI_NOT_FOUND No patch found for TableType:FieldOffset in | |
+ Context. This return value is considered | |
+ informative (ie. non-fatal). | |
+ @retval EFI_INVALID_PARAMETER Patch found for TableType:FieldOffset, but its | |
+ size doesn't match FieldSize. This result is | |
+ considered a fatal error of the patch origin. | |
+ @retval EFI_SUCCESS The SMBIOS table at TableBase has been patched | |
+ starting at FieldOffset for a length of | |
+ FieldSize. | |
+**/ | |
+EFI_STATUS | |
+EFIAPI | |
+PatchSmbiosFormatted ( | |
+ IN BUILD_CONTEXT *Context, | |
+ IN UINT8 TableType, | |
+ IN UINT16 FieldOffset, | |
+ IN UINT16 FieldSize, | |
+ OUT UINT8 *TableBase | |
+ ); | |
+ | |
+ | |
+// | |
+// Convenience / safety macro for patching a string in the unformatted area of | |
+// an SMBIOS table. | |
+// | |
+#define PATCH_UNFORMATTED(Smbios, SmbiosHandle, Context, TableType, \ | |
+ OvmfTablePtr, FieldName) \ | |
+ \ | |
+ PatchSmbiosUnformatted ( \ | |
+ Smbios, \ | |
+ SmbiosHandle, \ | |
+ Context, \ | |
+ TableType, \ | |
+ (UINT16) OFFSET_OF (SMBIOS_TABLE_TYPE##TableType, FieldName), \ | |
+ (UINT8 *) (OvmfTablePtr) \ | |
+ ) | |
+ | |
+ | |
+/** | |
+ Apply a saved patch to a text string located in the unformatted area of an | |
+ already installed SMBIOS table. | |
+ | |
+ The patch is looked up based on (Context, TableType, FieldOffset). | |
+ | |
+ @param[in] Smbios The EFI_SMBIOS_PROTOCOL instance used previously | |
+ for installing the SMBIOS table. | |
+ @param[in] SmbiosHandle The EFI_SMBIOS_HANDLE previously returned by | |
+ Smbios->Add(). | |
+ @param[in] Context The BUILD_CONTEXT object storing saved patches. | |
+ @param[in] TableType Selects the table type for which the patch has been | |
+ saved. It is assumed that the caller has validated | |
+ TableType against TABLE_TYPE_LIMIT (upper | |
+ exclusive). | |
+ @param[in] FieldOffset Selects the SMBIOS field for which the patch has | |
+ been saved. It is assumed that the caller has | |
+ validated FieldOffset against FIELD_OFFSET_MINIMUM | |
+ (lower inclusive) and 255 (upper exclusive). | |
+ It is also assumed that TableBase[FieldOffset] | |
+ accesses a field of type SMBIOS_TABLE_STRING, ie. a | |
+ field in the formatted area that identifies an | |
+ existent text string in the unformatted area. Text | |
+ string identifiers are one-based. | |
+ @param[out] TableBase Base of the SMBIOS table of type TableType in which | |
+ the SMBIOS_TABLE_STRING field at FieldOffset | |
+ identifies the existent text string to update. | |
+ | |
+ @retval EFI_NOT_FOUND No patch found for TableType:FieldOffset in | |
+ Context. This return value is considered | |
+ informative (ie. non-fatal). | |
+ @retval EFI_INVALID_PARAMETER Patch found for TableType:FieldOffset, but it | |
+ doesn't end with a NUL character. This result | |
+ is considered a fatal error of the patch | |
+ origin. | |
+ @retval EFI_SUCCESS The text string identified by | |
+ TableBase[FieldOffset] has been replaced in | |
+ the installed SMBIOS table under SmbiosHandle. | |
+ @return Error codes returned by | |
+ Smbios->UpdateString(). EFI_NOT_FOUND shall | |
+ not be returned. | |
+**/ | |
+EFI_STATUS | |
+EFIAPI | |
+PatchSmbiosUnformatted ( | |
+ IN EFI_SMBIOS_PROTOCOL *Smbios, | |
+ IN EFI_SMBIOS_HANDLE SmbiosHandle, | |
+ IN BUILD_CONTEXT *Context, | |
+ IN UINT8 TableType, | |
+ IN UINT16 FieldOffset, | |
+ IN UINT8 *TableBase | |
+ ); | |
+ | |
+ | |
+/** | |
+ Install default (fallback) table for SMBIOS Type 0. | |
+ | |
+ In case QEMU has provided no Type 0 SMBIOS table in whole, prepare one here, | |
+ patch it with any referring saved patches, and install it. | |
+ | |
+ @param[in] Smbios The EFI_SMBIOS_PROTOCOL instance used for | |
+ installing SMBIOS tables. | |
+ @param[in] ProducerHandle Passed on to Smbios->Add(), ProducerHandle | |
+ tracks the origin of installed SMBIOS tables. | |
+ @param[in,out] Context The BUILD_CONTEXT object tracking installed | |
+ tables and saved patches. | |
+ | |
+ @retval EFI_SUCCESS A Type 0 table has already been installed from the | |
+ SMBIOS firmware configuration blob. | |
+ @retval EFI_SUCCESS No Type 0 table was installed previously, and installing | |
+ the default here has succeeded. | |
+ @return Error codes from the PATCH_FORMATTED() and | |
+ PATCH_UNFORMATTED() macros, except EFI_NOT_FOUND, which | |
+ is only an informative result of theirs. | |
+**/ | |
+EFI_STATUS | |
+EFIAPI | |
+InstallSmbiosType0 ( | |
+ IN EFI_SMBIOS_PROTOCOL *Smbios, | |
+ IN EFI_HANDLE ProducerHandle, | |
+ IN OUT BUILD_CONTEXT *Context | |
+ ); | |
+ | |
+ | |
+/** | |
+ Install default (fallback) table for SMBIOS Type 1. | |
+ | |
+ In case QEMU has provided no Type 1 SMBIOS table in whole, prepare one here, | |
+ patch it with any referring saved patches, and install it. | |
+ | |
+ @param[in] Smbios The EFI_SMBIOS_PROTOCOL instance used for | |
+ installing SMBIOS tables. | |
+ @param[in] ProducerHandle Passed on to Smbios->Add(), ProducerHandle | |
+ tracks the origin of installed SMBIOS tables. | |
+ @param[in,out] Context The BUILD_CONTEXT object tracking installed | |
+ tables and saved patches. | |
+ | |
+ @retval EFI_SUCCESS A Type 1 table has already been installed from the | |
+ SMBIOS firmware configuration blob. | |
+ @retval EFI_SUCCESS No Type 1 table was installed previously, and installing | |
+ the default here has succeeded. | |
+ @return Error codes from the PATCH_FORMATTED() and | |
+ PATCH_UNFORMATTED() macros, except EFI_NOT_FOUND, which | |
+ is only an informative result of theirs. | |
+**/ | |
+EFI_STATUS | |
+EFIAPI | |
+InstallSmbiosType1 ( | |
+ IN EFI_SMBIOS_PROTOCOL *Smbios, | |
+ IN EFI_HANDLE ProducerHandle, | |
+ IN OUT BUILD_CONTEXT *Context | |
+ ); | |
+ | |
+#endif | |
diff --git a/OvmfPkg/QemuSmbiosPlatformDxe/SmbiosPlatformDxe.h b/OvmfPkg/QemuSmbiosPlatformDxe/SmbiosPlatformDxe.h | |
new file mode 100644 | |
index 000000000000..871d532f338d | |
--- /dev/null | |
+++ b/OvmfPkg/QemuSmbiosPlatformDxe/SmbiosPlatformDxe.h | |
@@ -0,0 +1,44 @@ | |
+/** @file | |
+ This driver installs SMBIOS information for OVMF | |
+ | |
+ Copyright (c) 2011, Bei Guan <[email protected]> | |
+ Copyright (c) 2011, 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. | |
+ | |
+**/ | |
+ | |
+#ifndef _SMBIOS_PLATFORM_DXE_H_ | |
+#define _SMBIOS_PLATFORM_DXE_H_ | |
+ | |
+#include <PiDxe.h> | |
+ | |
+#include <Protocol/Smbios.h> | |
+#include <IndustryStandard/SmBios.h> | |
+#include <Library/DebugLib.h> | |
+#include <Library/BaseLib.h> | |
+#include <Library/BaseMemoryLib.h> | |
+#include <Library/UefiBootServicesTableLib.h> | |
+ | |
+ | |
+/** | |
+ Validates the SMBIOS entry point structure | |
+ | |
+ @param EntryPointStructure SMBIOS entry point structure | |
+ | |
+ @retval TRUE The entry point structure is valid | |
+ @retval FALSE The entry point structure is not valid | |
+ | |
+**/ | |
+BOOLEAN | |
+IsEntryPointStructureValid ( | |
+ IN SMBIOS_TABLE_ENTRY_POINT *EntryPointStructure | |
+ ); | |
+ | |
+#endif | |
diff --git a/OvmfPkg/XenBusDxe/XenHypercall.h b/OvmfPkg/XenBusDxe/XenHypercall.h | |
new file mode 100644 | |
index 000000000000..23467517c2a3 | |
--- /dev/null | |
+++ b/OvmfPkg/XenBusDxe/XenHypercall.h | |
@@ -0,0 +1,116 @@ | |
+/** @file | |
+ Functions declarations to make Xen hypercalls. | |
+ | |
+ Copyright (C) 2014, Citrix Ltd. | |
+ | |
+ 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. | |
+ | |
+**/ | |
+ | |
+#ifndef __XENBUS_DXE_HYPERCALL_H__ | |
+#define __XENBUS_DXE_HYPERCALL_H__ | |
+ | |
+//typedef struct _XENBUS_DEVICE XENBUS_DEVICE; | |
+#include "XenBusDxe.h" | |
+ | |
+/** | |
+ This function will put the two arguments in the right place (registers) and | |
+ call HypercallAddr, which correspond to an entry in the hypercall pages. | |
+ | |
+ @param HypercallAddr A memory address where the hypercall to call is. | |
+ @param Arg1 First argument. | |
+ @param Arg2 Second argument. | |
+ | |
+ @return Return 0 if success otherwise it return an errno. | |
+**/ | |
+INTN | |
+EFIAPI | |
+XenHypercall2 ( | |
+ IN VOID *HypercallAddr, | |
+ IN OUT INTN Arg1, | |
+ IN OUT INTN Arg2 | |
+ ); | |
+ | |
+/** | |
+ Get the page where all hypercall are from the XenInfo hob. | |
+ | |
+ @param Dev A XENBUS_DEVICE instance. | |
+ | |
+ @retval EFI_NOT_FOUND hyperpage could not be found. | |
+ @retval EFI_SUCCESS Successfully retrieve the hyperpage pointer. | |
+**/ | |
+EFI_STATUS | |
+XenHyperpageInit ( | |
+ XENBUS_DEVICE *Dev | |
+ ); | |
+ | |
+/** | |
+ Return the value of the HVM parameter Index. | |
+ | |
+ @param Dev A XENBUS_DEVICE instance. | |
+ @param Index The parameter to get, e.g. HVM_PARAM_STORE_EVTCHN. | |
+ | |
+ @return The value of the asked parameter or 0 in case of error. | |
+**/ | |
+UINT64 | |
+XenHypercallHvmGetParam ( | |
+ XENBUS_DEVICE *Dev, | |
+ UINT32 Index | |
+ ); | |
+ | |
+/** | |
+ Hypercall to do different operation on the memory. | |
+ | |
+ @param Dev A XENBUS_DEVICE instance. | |
+ @param Operation The operation number, e.g. XENMEM_add_to_physmap. | |
+ @param Arguments The arguments associated to the operation. | |
+ | |
+ @return Return the return value from the hypercall, 0 in case of success | |
+ otherwise, an error code. | |
+**/ | |
+INTN | |
+XenHypercallMemoryOp ( | |
+ IN XENBUS_DEVICE *Dev, | |
+ IN UINTN Operation, | |
+ IN OUT VOID *Arguments | |
+ ); | |
+ | |
+/** | |
+ Do an operation on the event channels. | |
+ | |
+ @param Dev A XENBUS_DEVICE instance. | |
+ @param Operation The operation number, e.g. EVTCHNOP_send. | |
+ @param Arguments The argument associated to the operation. | |
+ | |
+ @return Return the return value from the hypercall, 0 in case of success | |
+ otherwise, an error code. | |
+**/ | |
+INTN | |
+XenHypercallEventChannelOp ( | |
+ IN XENBUS_DEVICE *Dev, | |
+ IN INTN Operation, | |
+ IN OUT VOID *Arguments | |
+ ); | |
+ | |
+/** | |
+ Map the shared_info_t page into memory. | |
+ | |
+ @param Dev A XENBUS_DEVICE instance. | |
+ | |
+ @retval EFI_SUCCESS Dev->SharedInfo whill contain a pointer to | |
+ the shared info page | |
+ @retval EFI_LOAD_ERROR The shared info page could not be mapped. The | |
+ hypercall returned an error. | |
+**/ | |
+EFI_STATUS | |
+XenGetSharedInfoPage ( | |
+ IN OUT XENBUS_DEVICE *Dev | |
+ ); | |
+ | |
+#endif | |
diff --git a/ShellPkg/Include/Protocol/EfiShell.h b/ShellPkg/Include/Protocol/EfiShell.h | |
index 8e3c2fe4de69..e0afb334c34f 100644 | |
--- a/ShellPkg/Include/Protocol/EfiShell.h | |
+++ b/ShellPkg/Include/Protocol/EfiShell.h | |
@@ -13,9 +13,1126 @@ | |
**/ | |
-#ifndef __EFI_SHELL_PROTOCOL_H__WRAPPER__ | |
-#define __EFI_SHELL_PROTOCOL_H__WRAPPER__ | |
+#ifndef __EFI_SHELL_PROTOCOL__ | |
+#define __EFI_SHELL_PROTOCOL__ | |
-#include <Protocol/Shell.h> | |
+#include <ShellBase.h> | |
+#include <Guid/FileInfo.h> | |
+ | |
+#define EFI_SHELL_PROTOCOL_GUID \ | |
+ { \ | |
+ 0x6302d008, 0x7f9b, 0x4f30, { 0x87, 0xac, 0x60, 0xc9, 0xfe, 0xf5, 0xda, 0x4e } \ | |
+ } | |
+ | |
+// replaced EFI_LIST_ENTRY with LIST_ENTRY for simplicity. | |
+// they are identical outside of the name. | |
+typedef struct { | |
+ LIST_ENTRY Link; ///< Linked list members. | |
+ EFI_STATUS Status; ///< Status of opening the file. Valid only if Handle != NULL. | |
+ CONST CHAR16 *FullName; ///< Fully qualified filename. | |
+ CONST CHAR16 *FileName; ///< name of this file. | |
+ SHELL_FILE_HANDLE Handle; ///< Handle for interacting with the opened file or NULL if closed. | |
+ EFI_FILE_INFO *Info; ///< Pointer to the FileInfo struct for this file or NULL. | |
+} EFI_SHELL_FILE_INFO; | |
+ | |
+/** | |
+ Returns whether any script files are currently being processed. | |
+ | |
+ @retval TRUE There is at least one script file active. | |
+ @retval FALSE No script files are active now. | |
+ | |
+**/ | |
+typedef | |
+BOOLEAN | |
+(EFIAPI *EFI_SHELL_BATCH_IS_ACTIVE) ( | |
+ VOID | |
+ ); | |
+ | |
+/** | |
+ Closes the file handle. | |
+ | |
+ This function closes a specified file handle. All 'dirty' cached file data is | |
+ flushed to the device, and the file is closed. In all cases, the handle is | |
+ closed. | |
+ | |
+ @param[in] FileHandle The file handle to be closed. | |
+ | |
+ @retval EFI_SUCCESS The file closed sucessfully. | |
+**/ | |
+typedef | |
+EFI_STATUS | |
+(EFIAPI *EFI_SHELL_CLOSE_FILE)( | |
+ IN SHELL_FILE_HANDLE FileHandle | |
+ ); | |
+ | |
+/** | |
+ Creates a file or directory by name. | |
+ | |
+ This function creates an empty new file or directory with the specified attributes and | |
+ returns the new file's handle. If the file already exists and is read-only, then | |
+ EFI_INVALID_PARAMETER will be returned. | |
+ | |
+ If the file already existed, it is truncated and its attributes updated. If the file is | |
+ created successfully, the FileHandle is the file's handle, else, the FileHandle is NULL. | |
+ | |
+ If the file name begins with >v, then the file handle which is returned refers to the | |
+ shell environment variable with the specified name. If the shell environment variable | |
+ already exists and is non-volatile then EFI_INVALID_PARAMETER is returned. | |
+ | |
+ @param[in] FileName Pointer to NULL-terminated file path. | |
+ @param[in] FileAttribs The new file's attrbiutes. The different attributes are | |
+ described in EFI_FILE_PROTOCOL.Open(). | |
+ @param[out] FileHandle On return, points to the created file handle or directory's handle. | |
+ | |
+ @retval EFI_SUCCESS The file was opened. FileHandle points to the new file's handle. | |
+ @retval EFI_INVALID_PARAMETER One of the parameters has an invalid value. | |
+ @retval EFI_UNSUPPORTED The file path could not be opened. | |
+ @retval EFI_NOT_FOUND The specified file could not be found on the device, or could not | |
+ file the file system on the device. | |
+ @retval EFI_NO_MEDIA The device has no medium. | |
+ @retval EFI_MEDIA_CHANGED The device has a different medium in it or the medium is no | |
+ longer supported. | |
+ @retval EFI_DEVICE_ERROR The device reported an error or can't get the file path according | |
+ the DirName. | |
+ @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted. | |
+ @retval EFI_WRITE_PROTECTED An attempt was made to create a file, or open a file for write | |
+ when the media is write-protected. | |
+ @retval EFI_ACCESS_DENIED The service denied access to the file. | |
+ @retval EFI_OUT_OF_RESOURCES Not enough resources were available to open the file. | |
+ @retval EFI_VOLUME_FULL The volume is full. | |
+**/ | |
+typedef | |
+EFI_STATUS | |
+(EFIAPI *EFI_SHELL_CREATE_FILE)( | |
+ IN CONST CHAR16 *FileName, | |
+ IN UINT64 FileAttribs, | |
+ OUT SHELL_FILE_HANDLE *FileHandle | |
+ ); | |
+ | |
+/** | |
+ Deletes the file specified by the file handle. | |
+ | |
+ This function closes and deletes a file. In all cases, the file handle is closed. If the file | |
+ cannot be deleted, the warning code EFI_WARN_DELETE_FAILURE is returned, but the | |
+ handle is still closed. | |
+ | |
+ @param[in] FileHandle The file handle to delete. | |
+ | |
+ @retval EFI_SUCCESS The file was closed and deleted and the handle was closed. | |
+ @retval EFI_WARN_DELETE_FAILURE The handle was closed but the file was not deleted. | |
+**/ | |
+typedef | |
+EFI_STATUS | |
+(EFIAPI *EFI_SHELL_DELETE_FILE)( | |
+ IN SHELL_FILE_HANDLE FileHandle | |
+ ); | |
+ | |
+/** | |
+ Deletes the file specified by the file name. | |
+ | |
+ This function deletes a file. | |
+ | |
+ @param[in] FileName Points to the NULL-terminated file name. | |
+ | |
+ @retval EFI_SUCCESS The file was deleted. | |
+ @retval EFI_WARN_DELETE_FAILURE The handle was closed but the file was not deleted. | |
+**/ | |
+typedef | |
+EFI_STATUS | |
+(EFIAPI *EFI_SHELL_DELETE_FILE_BY_NAME)( | |
+ IN CONST CHAR16 *FileName | |
+ ); | |
+ | |
+/** | |
+ Disables the page break output mode. | |
+**/ | |
+typedef | |
+VOID | |
+(EFIAPI *EFI_SHELL_DISABLE_PAGE_BREAK) ( | |
+ VOID | |
+ ); | |
+ | |
+/** | |
+ Enables the page break output mode. | |
+**/ | |
+typedef | |
+VOID | |
+(EFIAPI *EFI_SHELL_ENABLE_PAGE_BREAK) ( | |
+ VOID | |
+ ); | |
+ | |
+/** | |
+ Execute the command line. | |
+ | |
+ This function creates a nested instance of the shell and executes the specified | |
+ command (CommandLine) with the specified environment (Environment). Upon return, | |
+ the status code returned by the specified command is placed in StatusCode. | |
+ | |
+ If Environment is NULL, then the current environment is used and all changes made | |
+ by the commands executed will be reflected in the current environment. If the | |
+ Environment is non-NULL, then the changes made will be discarded. | |
+ | |
+ The CommandLine is executed from the current working directory on the current | |
+ device. | |
+ | |
+ @param[in] ParentImageHandle A handle of the image that is executing the specified | |
+ command line. | |
+ @param[in] CommandLine Points to the NULL-terminated UCS-2 encoded string | |
+ containing the command line. If NULL then the command- | |
+ line will be empty. | |
+ @param[in] Environment Points to a NULL-terminated array of environment | |
+ variables with the format 'x=y', where x is the | |
+ environment variable name and y is the value. If this | |
+ is NULL, then the current shell environment is used. | |
+ @param[out] ErrorCode Points to the status code returned by the command. | |
+ | |
+ @retval EFI_SUCCESS The command executed successfully. The status code | |
+ returned by the command is pointed to by StatusCode. | |
+ @retval EFI_INVALID_PARAMETER The parameters are invalid. | |
+ @retval EFI_OUT_OF_RESOURCES Out of resources. | |
+ @retval EFI_UNSUPPORTED Nested shell invocations are not allowed. | |
+**/ | |
+typedef | |
+EFI_STATUS | |
+(EFIAPI *EFI_SHELL_EXECUTE) ( | |
+ IN EFI_HANDLE *ParentImageHandle, | |
+ IN CHAR16 *CommandLine OPTIONAL, | |
+ IN CHAR16 **Environment OPTIONAL, | |
+ OUT EFI_STATUS *StatusCode OPTIONAL | |
+ ); | |
+ | |
+/** | |
+ Find files that match a specified pattern. | |
+ | |
+ This function searches for all files and directories that match the specified | |
+ FilePattern. The FilePattern can contain wild-card characters. The resulting file | |
+ information is placed in the file list FileList. | |
+ | |
+ The files in the file list are not opened. The OpenMode field is set to 0 and the FileInfo | |
+ field is set to NULL. | |
+ | |
+ @param[in] FilePattern Points to a NULL-terminated shell file path, including wildcards. | |
+ @param[out] FileList On return, points to the start of a file list containing the names | |
+ of all matching files or else points to NULL if no matching files | |
+ were found. | |
+ | |
+ @retval EFI_SUCCESS Files found. | |
+ @retval EFI_NOT_FOUND No files found. | |
+ @retval EFI_NO_MEDIA The device has no media. | |
+ @retval EFI_DEVICE_ERROR The device reported an error. | |
+ @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted. | |
+**/ | |
+typedef | |
+EFI_STATUS | |
+(EFIAPI *EFI_SHELL_FIND_FILES)( | |
+ IN CONST CHAR16 *FilePattern, | |
+ OUT EFI_SHELL_FILE_INFO **FileList | |
+ ); | |
+ | |
+/** | |
+ Find all files in a specified directory. | |
+ | |
+ @param[in] FileDirHandle Handle of the directory to search. | |
+ @param[out] FileList On return, points to the list of files in the directory | |
+ or NULL if there are no files in the directory. | |
+ | |
+ @retval EFI_SUCCESS File information was returned successfully. | |
+ @retval EFI_VOLUME_CORRUPTED The file system structures have been corrupted. | |
+ @retval EFI_DEVICE_ERROR The device reported an error. | |
+ @retval EFI_NO_MEDIA The device media is not present. | |
+**/ | |
+typedef | |
+EFI_STATUS | |
+(EFIAPI *EFI_SHELL_FIND_FILES_IN_DIR)( | |
+IN SHELL_FILE_HANDLE FileDirHandle, | |
+OUT EFI_SHELL_FILE_INFO **FileList | |
+); | |
+ | |
+/** | |
+ Flushes data back to a device. | |
+ | |
+ This function flushes all modified data associated with a file to a device. | |
+ | |
+ @param[in] FileHandle The handle of the file to flush. | |
+ | |
+ @retval EFI_SUCCESS The data was flushed. | |
+ @retval EFI_NO_MEDIA The device has no medium. | |
+ @retval EFI_DEVICE_ERROR The device reported an error. | |
+ @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted. | |
+ @retval EFI_WRITE_PROTECTED The file or medium is write-protected. | |
+ @retval EFI_ACCESS_DENIED The file was opened read-only. | |
+ @retval EFI_VOLUME_FULL The volume is full. | |
+**/ | |
+typedef | |
+EFI_STATUS | |
+(EFIAPI *EFI_SHELL_FLUSH_FILE)( | |
+ IN SHELL_FILE_HANDLE FileHandle | |
+ ); | |
+ | |
+/** | |
+ Frees the file list. | |
+ | |
+ This function cleans up the file list and any related data structures. It has no | |
+ impact on the files themselves. | |
+ | |
+ @param[in] FileList The file list to free. Type EFI_SHELL_FILE_INFO is | |
+ defined in OpenFileList(). | |
+ | |
+ @retval EFI_SUCCESS Free the file list successfully. | |
+**/ | |
+typedef | |
+EFI_STATUS | |
+(EFIAPI *EFI_SHELL_FREE_FILE_LIST) ( | |
+ IN EFI_SHELL_FILE_INFO **FileList | |
+ ); | |
+ | |
+/** | |
+ Returns the current directory on the specified device. | |
+ | |
+ If FileSystemMapping is NULL, it returns the current working directory. If the | |
+ FileSystemMapping is not NULL, it returns the current directory associated with the | |
+ FileSystemMapping. In both cases, the returned name includes the file system | |
+ mapping (i.e. fs0:\current-dir). | |
+ | |
+ Note that the current directory string should exclude the tailing backslash character. | |
+ | |
+ @param[in] FileSystemMapping A pointer to the file system mapping. If NULL, | |
+ then the current working directory is returned. | |
+ | |
+ @retval !=NULL The current directory. | |
+ @retval NULL Current directory does not exist. | |
+**/ | |
+typedef | |
+CONST CHAR16 * | |
+(EFIAPI *EFI_SHELL_GET_CUR_DIR) ( | |
+ IN CONST CHAR16 *FileSystemMapping OPTIONAL | |
+ ); | |
+ | |
+typedef UINT32 EFI_SHELL_DEVICE_NAME_FLAGS; | |
+#define EFI_DEVICE_NAME_USE_COMPONENT_NAME 0x00000001 | |
+#define EFI_DEVICE_NAME_USE_DEVICE_PATH 0x00000002 | |
+ | |
+/** | |
+ Gets the name of the device specified by the device handle. | |
+ | |
+ This function gets the user-readable name of the device specified by the device | |
+ handle. If no user-readable name could be generated, then *BestDeviceName will be | |
+ NULL and EFI_NOT_FOUND will be returned. | |
+ | |
+ If EFI_DEVICE_NAME_USE_COMPONENT_NAME is set, then the function will return the | |
+ device's name using the EFI_COMPONENT_NAME2_PROTOCOL, if present on | |
+ DeviceHandle. | |
+ | |
+ If EFI_DEVICE_NAME_USE_DEVICE_PATH is set, then the function will return the | |
+ device's name using the EFI_DEVICE_PATH_PROTOCOL, if present on DeviceHandle. | |
+ If both EFI_DEVICE_NAME_USE_COMPONENT_NAME and | |
+ EFI_DEVICE_NAME_USE_DEVICE_PATH are set, then | |
+ EFI_DEVICE_NAME_USE_COMPONENT_NAME will have higher priority. | |
+ | |
+ @param[in] DeviceHandle The handle of the device. | |
+ @param[in] Flags Determines the possible sources of component names. | |
+ @param[in] Language A pointer to the language specified for the device | |
+ name, in the same format as described in the UEFI | |
+ specification, Appendix M. | |
+ @param[out] BestDeviceName On return, points to the callee-allocated NULL- | |
+ terminated name of the device. If no device name | |
+ could be found, points to NULL. The name must be | |
+ freed by the caller... | |
+ | |
+ @retval EFI_SUCCESS Get the name successfully. | |
+ @retval EFI_NOT_FOUND Fail to get the device name. | |
+**/ | |
+typedef | |
+EFI_STATUS | |
+(EFIAPI *EFI_SHELL_GET_DEVICE_NAME) ( | |
+ IN EFI_HANDLE DeviceHandle, | |
+ IN EFI_SHELL_DEVICE_NAME_FLAGS Flags, | |
+ IN CHAR8 *Language, | |
+ OUT CHAR16 **BestDeviceName | |
+ ); | |
+ | |
+/** | |
+ Gets the device path from the mapping. | |
+ | |
+ This function gets the device path associated with a mapping. | |
+ | |
+ @param[in] Mapping A pointer to the mapping | |
+ | |
+ @retval !=NULL Pointer to the device path that corresponds to the | |
+ device mapping. The returned pointer does not need | |
+ to be freed. | |
+ @retval NULL There is no device path associated with the | |
+ specified mapping. | |
+**/ | |
+typedef | |
+CONST EFI_DEVICE_PATH_PROTOCOL * | |
+(EFIAPI *EFI_SHELL_GET_DEVICE_PATH_FROM_MAP) ( | |
+ IN CONST CHAR16 *Mapping | |
+ ); | |
+ | |
+/** | |
+ Converts a file system style name to a device path. | |
+ | |
+ This function converts a file system style name to a device path, by replacing any | |
+ mapping references to the associated device path. | |
+ | |
+ @param[in] Path The pointer to the path. | |
+ | |
+ @return The pointer of the file path. The file path is callee | |
+ allocated and should be freed by the caller. | |
+**/ | |
+typedef | |
+EFI_DEVICE_PATH_PROTOCOL * | |
+(EFIAPI *EFI_SHELL_GET_DEVICE_PATH_FROM_FILE_PATH) ( | |
+ IN CONST CHAR16 *Path | |
+ ); | |
+ | |
+/** | |
+ Gets either a single or list of environment variables. | |
+ | |
+ If name is not NULL then this function returns the current value of the specified | |
+ environment variable. | |
+ | |
+ If Name is NULL than a list of all environment variable names is returned. Each a | |
+ NULL terminated string with a double NULL terminating the list. | |
+ | |
+ @param[in] Name A pointer to the environment variable name. If | |
+ Name is NULL, then the function will return all | |
+ of the defined shell environment variables. In | |
+ the case where multiple environment variables are | |
+ being returned, each variable will be terminated by | |
+ a NULL, and the list will be terminated by a double | |
+ NULL. | |
+ | |
+ @return A pointer to the returned string. | |
+ The returned pointer does not need to be freed by the caller. | |
+ | |
+ @retval NULL The environment variable doesn't exist or there are | |
+ no environment variables. | |
+**/ | |
+typedef | |
+CONST CHAR16 * | |
+(EFIAPI *EFI_SHELL_GET_ENV) ( | |
+ IN CONST CHAR16 *Name OPTIONAL | |
+ ); | |
+ | |
+/** | |
+ Gets the environment variable and Attributes, or list of environment variables. Can be | |
+ used instead of GetEnv(). | |
+ | |
+ This function returns the current value of the specified environment variable and | |
+ the Attributes. If no variable name was specified, then all of the known | |
+ variables will be returned. | |
+ | |
+ @param[in] Name A pointer to the environment variable name. If Name is NULL, | |
+ then the function will return all of the defined shell | |
+ environment variables. In the case where multiple environment | |
+ variables are being returned, each variable will be terminated | |
+ by a NULL, and the list will be terminated by a double NULL. | |
+ @param[out] Attributes If not NULL, a pointer to the returned attributes bitmask for | |
+ the environment variable. In the case where Name is NULL, and | |
+ multiple environment variables are being returned, Attributes | |
+ is undefined. | |
+ | |
+ @retval NULL The environment variable doesn't exist. | |
+ @return The environment variable's value. The returned pointer does not | |
+ need to be freed by the caller. | |
+**/ | |
+typedef | |
+CONST CHAR16 * | |
+(EFIAPI *EFI_SHELL_GET_ENV_EX) ( | |
+ IN CONST CHAR16 *Name, | |
+ OUT UINT32 *Attributes OPTIONAL | |
+ ); | |
+ | |
+/** | |
+ Gets the file information from an open file handle. | |
+ | |
+ This function allocates a buffer to store the file's information. It's the caller's | |
+ responsibility to free the buffer. | |
+ | |
+ @param[in] FileHandle A File Handle. | |
+ | |
+ @retval NULL Cannot get the file info. | |
+ @return A pointer to a buffer with file information. | |
+**/ | |
+typedef | |
+EFI_FILE_INFO * | |
+(EFIAPI *EFI_SHELL_GET_FILE_INFO)( | |
+ IN SHELL_FILE_HANDLE FileHandle | |
+ ); | |
+ | |
+/** | |
+ Converts a device path to a file system-style path. | |
+ | |
+ This function converts a device path to a file system path by replacing part, or all, of | |
+ the device path with the file-system mapping. If there are more than one application | |
+ file system mappings, the one that most closely matches Path will be used. | |
+ | |
+ @param[in] Path The pointer to the device path. | |
+ | |
+ @return The pointer of the NULL-terminated file path. The path | |
+ is callee-allocated and should be freed by the caller. | |
+**/ | |
+typedef | |
+CHAR16 * | |
+(EFIAPI *EFI_SHELL_GET_FILE_PATH_FROM_DEVICE_PATH) ( | |
+ IN CONST EFI_DEVICE_PATH_PROTOCOL *Path | |
+ ); | |
+ | |
+/** | |
+ Gets a file's current position. | |
+ | |
+ This function returns the current file position for the file handle. For directories, the | |
+ current file position has no meaning outside of the file system driver and as such, the | |
+ operation is not supported. | |
+ | |
+ @param[in] FileHandle The file handle on which to get the current position. | |
+ @param[out] Position Byte position from the start of the file. | |
+ | |
+ @retval EFI_SUCCESS Data was accessed. | |
+ @retval EFI_UNSUPPORTED The request is not valid on open directories. | |
+**/ | |
+typedef | |
+EFI_STATUS | |
+(EFIAPI *EFI_SHELL_GET_FILE_POSITION)( | |
+ IN SHELL_FILE_HANDLE FileHandle, | |
+ OUT UINT64 *Position | |
+ ); | |
+ | |
+/** | |
+ Gets the size of a file. | |
+ | |
+ This function returns the size of the file specified by FileHandle. | |
+ | |
+ @param[in] FileHandle The handle of the file. | |
+ @param[out] Size The size of this file. | |
+ | |
+ @retval EFI_SUCCESS Get the file's size. | |
+ @retval EFI_DEVICE_ERROR Can't access the file. | |
+**/ | |
+typedef | |
+EFI_STATUS | |
+(EFIAPI *EFI_SHELL_GET_FILE_SIZE)( | |
+ IN SHELL_FILE_HANDLE FileHandle, | |
+ OUT UINT64 *Size | |
+ ); | |
+ | |
+/** | |
+ Get the GUID value from a human readable name. | |
+ | |
+ If GuidName is a known GUID name, then update Guid to have the correct value for | |
+ that GUID. | |
+ | |
+ This function is only available when the major and minor versions in the | |
+ EfiShellProtocol are greater than or equal to 2 and 1, respectively. | |
+ | |
+ @param[in] GuidName A pointer to the localized name for the GUID being queried. | |
+ @param[out] Guid A pointer to the GUID structure to be filled in. | |
+ | |
+ @retval EFI_SUCCESS The operation was successful. | |
+ @retval EFI_INVALID_PARAMETER Guid was NULL. | |
+ @retval EFI_INVALID_PARAMETER GuidName was NULL. | |
+ @retval EFI_NOT_FOUND GuidName is not a known GUID Name. | |
+**/ | |
+typedef | |
+EFI_STATUS | |
+(EFIAPI *EFI_SHELL_GET_GUID_FROM_NAME)( | |
+ IN CONST CHAR16 *GuidName, | |
+ OUT EFI_GUID *Guid | |
+ ); | |
+ | |
+/** | |
+ Get the human readable name for a GUID from the value. | |
+ | |
+ If Guid is assigned a name, then update *GuidName to point to the name. The callee | |
+ should not modify the value. | |
+ | |
+ This function is only available when the major and minor versions in the | |
+ EfiShellProtocol are greater than or equal to 2 and 1, respectively. | |
+ | |
+ @param[in] Guid A pointer to the GUID being queried. | |
+ @param[out] GuidName A pointer to a pointer the localized to name for the GUID being requested | |
+ | |
+ @retval EFI_SUCCESS The operation was successful. | |
+ @retval EFI_INVALID_PARAMETER Guid was NULL. | |
+ @retval EFI_INVALID_PARAMETER GuidName was NULL. | |
+ @retval EFI_NOT_FOUND Guid is not assigned a name. | |
+**/ | |
+typedef | |
+EFI_STATUS | |
+(EFIAPI *EFI_SHELL_GET_GUID_NAME)( | |
+ IN CONST EFI_GUID *Guid, | |
+ OUT CONST CHAR16 **GuidName | |
+ ); | |
+ | |
+/** | |
+ Return help information about a specific command. | |
+ | |
+ This function returns the help information for the specified command. The help text | |
+ can be internal to the shell or can be from a UEFI Shell manual page. | |
+ | |
+ If Sections is specified, then each section name listed will be compared in a casesensitive | |
+ manner, to the section names described in Appendix B. If the section exists, | |
+ it will be appended to the returned help text. If the section does not exist, no | |
+ information will be returned. If Sections is NULL, then all help text information | |
+ available will be returned. | |
+ | |
+ @param[in] Command Points to the NULL-terminated UEFI Shell command name. | |
+ @param[in] Sections Points to the NULL-terminated comma-delimited | |
+ section names to return. If NULL, then all | |
+ sections will be returned. | |
+ @param[out] HelpText On return, points to a callee-allocated buffer | |
+ containing all specified help text. | |
+ | |
+ @retval EFI_SUCCESS The help text was returned. | |
+ @retval EFI_OUT_OF_RESOURCES The necessary buffer could not be allocated to hold the | |
+ returned help text. | |
+ @retval EFI_INVALID_PARAMETER HelpText is NULL. | |
+ @retval EFI_NOT_FOUND There is no help text available for Command. | |
+**/ | |
+typedef | |
+EFI_STATUS | |
+(EFIAPI *EFI_SHELL_GET_HELP_TEXT) ( | |
+ IN CONST CHAR16 *Command, | |
+ IN CONST CHAR16 *Sections OPTIONAL, | |
+ OUT CHAR16 **HelpText | |
+ ); | |
+ | |
+/** | |
+ Gets the mapping(s) that most closely matches the device path. | |
+ | |
+ This function gets the mapping which corresponds to the device path *DevicePath. If | |
+ there is no exact match, then the mapping which most closely matches *DevicePath | |
+ is returned, and *DevicePath is updated to point to the remaining portion of the | |
+ device path. If there is an exact match, the mapping is returned and *DevicePath | |
+ points to the end-of-device-path node. | |
+ | |
+ If there are multiple map names they will be semi-colon seperated in the | |
+ NULL-terminated string. | |
+ | |
+ @param[in, out] DevicePath On entry, points to a device path pointer. On | |
+ exit, updates the pointer to point to the | |
+ portion of the device path after the mapping. | |
+ | |
+ @retval NULL No mapping was found. | |
+ @retval !=NULL Pointer to NULL-terminated mapping. The buffer | |
+ is callee allocated and should be freed by the caller. | |
+**/ | |
+typedef | |
+CONST CHAR16 * | |
+(EFIAPI *EFI_SHELL_GET_MAP_FROM_DEVICE_PATH) ( | |
+ IN OUT EFI_DEVICE_PATH_PROTOCOL **DevicePath | |
+ ); | |
+ | |
+/** | |
+ Gets the enable status of the page break output mode. | |
+ | |
+ User can use this function to determine current page break mode. | |
+ | |
+ @retval TRUE The page break output mode is enabled. | |
+ @retval FALSE The page break output mode is disabled. | |
+**/ | |
+typedef | |
+BOOLEAN | |
+(EFIAPI *EFI_SHELL_GET_PAGE_BREAK) ( | |
+ VOID | |
+ ); | |
+ | |
+/** | |
+ Judges whether the active shell is the root shell. | |
+ | |
+ This function makes the user to know that whether the active Shell is the root shell. | |
+ | |
+ @retval TRUE The active Shell is the root Shell. | |
+ @retval FALSE The active Shell is NOT the root Shell. | |
+**/ | |
+typedef | |
+BOOLEAN | |
+(EFIAPI *EFI_SHELL_IS_ROOT_SHELL) ( | |
+VOID | |
+); | |
+ | |
+/** | |
+ Opens a file or a directory by file name. | |
+ | |
+ This function opens the specified file in the specified OpenMode and returns a file | |
+ handle. | |
+ If the file name begins with '>v', then the file handle which is returned refers to the | |
+ shell environment variable with the specified name. If the shell environment variable | |
+ exists, is non-volatile and the OpenMode indicates EFI_FILE_MODE_WRITE, then | |
+ EFI_INVALID_PARAMETER is returned. | |
+ | |
+ If the file name is '>i', then the file handle which is returned refers to the standard | |
+ input. If the OpenMode indicates EFI_FILE_MODE_WRITE, then EFI_INVALID_PARAMETER | |
+ is returned. | |
+ | |
+ If the file name is '>o', then the file handle which is returned refers to the standard | |
+ output. If the OpenMode indicates EFI_FILE_MODE_READ, then EFI_INVALID_PARAMETER | |
+ is returned. | |
+ | |
+ If the file name is '>e', then the file handle which is returned refers to the standard | |
+ error. If the OpenMode indicates EFI_FILE_MODE_READ, then EFI_INVALID_PARAMETER | |
+ is returned. | |
+ | |
+ If the file name is 'NUL', then the file handle that is returned refers to the standard NUL | |
+ file. If the OpenMode indicates EFI_FILE_MODE_READ, then EFI_INVALID_PARAMETER is | |
+ returned. | |
+ | |
+ If return EFI_SUCCESS, the FileHandle is the opened file's handle, else, the | |
+ FileHandle is NULL. | |
+ | |
+ @param[in] FileName Points to the NULL-terminated UCS-2 encoded file name. | |
+ @param[out] FileHandle On return, points to the file handle. | |
+ @param[in] OpenMode File open mode. Either EFI_FILE_MODE_READ or | |
+ EFI_FILE_MODE_WRITE from section 12.4 of the UEFI | |
+ Specification. | |
+ @retval EFI_SUCCESS The file was opened. FileHandle has the opened file's handle. | |
+ @retval EFI_INVALID_PARAMETER One of the parameters has an invalid value. FileHandle is NULL. | |
+ @retval EFI_UNSUPPORTED Could not open the file path. FileHandle is NULL. | |
+ @retval EFI_NOT_FOUND The specified file could not be found on the device or the file | |
+ system could not be found on the device. FileHandle is NULL. | |
+ @retval EFI_NO_MEDIA The device has no medium. FileHandle is NULL. | |
+ @retval EFI_MEDIA_CHANGED The device has a different medium in it or the medium is no | |
+ longer supported. FileHandle is NULL. | |
+ @retval EFI_DEVICE_ERROR The device reported an error or can't get the file path according | |
+ the FileName. FileHandle is NULL. | |
+ @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted. FileHandle is NULL. | |
+ @retval EFI_WRITE_PROTECTED An attempt was made to create a file, or open a file for write | |
+ when the media is write-protected. FileHandle is NULL. | |
+ @retval EFI_ACCESS_DENIED The service denied access to the file. FileHandle is NULL. | |
+ @retval EFI_OUT_OF_RESOURCES Not enough resources were available to open the file. FileHandle | |
+ is NULL. | |
+ @retval EFI_VOLUME_FULL The volume is full. FileHandle is NULL. | |
+**/ | |
+typedef | |
+EFI_STATUS | |
+(EFIAPI *EFI_SHELL_OPEN_FILE_BY_NAME) ( | |
+ IN CONST CHAR16 *FileName, | |
+ OUT SHELL_FILE_HANDLE *FileHandle, | |
+ IN UINT64 OpenMode | |
+ ); | |
+ | |
+/** | |
+ Opens the files that match the path specified. | |
+ | |
+ This function opens all of the files specified by Path. Wildcards are processed | |
+ according to the rules specified in UEFI Shell 2.0 spec section 3.7.1. Each | |
+ matching file has an EFI_SHELL_FILE_INFO structure created in a linked list. | |
+ | |
+ @param[in] Path A pointer to the path string. | |
+ @param[in] OpenMode Specifies the mode used to open each file, EFI_FILE_MODE_READ or | |
+ EFI_FILE_MODE_WRITE. | |
+ @param[in, out] FileList Points to the start of a list of files opened. | |
+ | |
+ @retval EFI_SUCCESS Create the file list successfully. | |
+ @return Can't create the file list. | |
+**/ | |
+typedef | |
+EFI_STATUS | |
+(EFIAPI *EFI_SHELL_OPEN_FILE_LIST) ( | |
+ IN CHAR16 *Path, | |
+ IN UINT64 OpenMode, | |
+ IN OUT EFI_SHELL_FILE_INFO **FileList | |
+ ); | |
+ | |
+/** | |
+ Opens the root directory of a device. | |
+ | |
+ This function opens the root directory of a device and returns a file handle to it. | |
+ | |
+ @param[in] DevicePath Points to the device path corresponding to the device where the | |
+ EFI_SIMPLE_FILE_SYSTEM_PROTOCOL is installed. | |
+ @param[out] FileHandle On exit, points to the file handle corresponding to the root directory on the | |
+ device. | |
+ | |
+ @retval EFI_SUCCESS Root opened successfully. | |
+ @retval EFI_NOT_FOUND EFI_SIMPLE_FILE_SYSTEM could not be found or the root directory | |
+ could not be opened. | |
+ @retval EFI_VOLUME_CORRUPTED The data structures in the volume were corrupted. | |
+ @retval EFI_DEVICE_ERROR The device had an error. | |
+**/ | |
+typedef | |
+EFI_STATUS | |
+(EFIAPI *EFI_SHELL_OPEN_ROOT)( | |
+ IN EFI_DEVICE_PATH_PROTOCOL *DevicePath, | |
+ OUT SHELL_FILE_HANDLE *FileHandle | |
+ ); | |
+ | |
+/** | |
+ Opens the root directory of a device on a handle. | |
+ | |
+ This function opens the root directory of a device and returns a file handle to it. | |
+ | |
+ @param[in] DeviceHandle The handle of the device that contains the volume. | |
+ @param[out] FileHandle On exit, points to the file handle corresponding to the root directory on the | |
+ device. | |
+ | |
+ @retval EFI_SUCCESS Root opened successfully. | |
+ @retval EFI_NOT_FOUND EFI_SIMPLE_FILE_SYSTEM could not be found or the root directory | |
+ could not be opened. | |
+ @retval EFI_VOLUME_CORRUPTED The data structures in the volume were corrupted. | |
+ @retval EFI_DEVICE_ERROR The device had an error. | |
+**/ | |
+typedef | |
+EFI_STATUS | |
+(EFIAPI *EFI_SHELL_OPEN_ROOT_BY_HANDLE)( | |
+ IN EFI_HANDLE DeviceHandle, | |
+ OUT SHELL_FILE_HANDLE *FileHandle | |
+ ); | |
+ | |
+/** | |
+ Reads data from the file. | |
+ | |
+ If FileHandle is not a directory, the function reads the requested number of bytes | |
+ from the file at the file's current position and returns them in Buffer. If the read goes | |
+ beyond the end of the file, the read length is truncated to the end of the file. The file's | |
+ current position is increased by the number of bytes returned. | |
+ If FileHandle is a directory, then an error is returned. | |
+ | |
+ @param[in] FileHandle The opened file handle for read. | |
+ @param[in] ReadSize On input, the size of Buffer, in bytes. On output, the amount of data read. | |
+ @param[in, out] Buffer The buffer in which data is read. | |
+ | |
+ @retval EFI_SUCCESS Data was read. | |
+ @retval EFI_NO_MEDIA The device has no media. | |
+ @retval EFI_DEVICE_ERROR The device reported an error. | |
+ @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted. | |
+ @retval EFI_BUFFER_TO_SMALL Buffer is too small. ReadSize contains required size. | |
+**/ | |
+typedef | |
+EFI_STATUS | |
+(EFIAPI *EFI_SHELL_READ_FILE) ( | |
+ IN SHELL_FILE_HANDLE FileHandle, | |
+ IN OUT UINTN *ReadSize, | |
+ IN OUT VOID *Buffer | |
+ ); | |
+ | |
+/** | |
+ Register a GUID and a localized human readable name for it. | |
+ | |
+ If Guid is not assigned a name, then assign GuidName to Guid. This list of GUID | |
+ names must be used whenever a shell command outputs GUID information. | |
+ | |
+ This function is only available when the major and minor versions in the | |
+ EfiShellProtocol are greater than or equal to 2 and 1, respectively. | |
+ | |
+ @param[in] Guid A pointer to the GUID being registered. | |
+ @param[in] GuidName A pointer to the localized name for the GUID being registered. | |
+ | |
+ @retval EFI_SUCCESS The operation was successful. | |
+ @retval EFI_INVALID_PARAMETER Guid was NULL. | |
+ @retval EFI_INVALID_PARAMETER GuidName was NULL. | |
+ @retval EFI_ACCESS_DENIED Guid already is assigned a name. | |
+**/ | |
+typedef | |
+EFI_STATUS | |
+(EFIAPI *EFI_SHELL_REGISTER_GUID_NAME)( | |
+ IN CONST EFI_GUID *Guid, | |
+ IN CONST CHAR16 *GuidName | |
+ ); | |
+ | |
+/** | |
+ Deletes the duplicate file names files in the given file list. | |
+ | |
+ @param[in] FileList A pointer to the first entry in the file list. | |
+ | |
+ @retval EFI_SUCCESS Always success. | |
+**/ | |
+typedef | |
+EFI_STATUS | |
+(EFIAPI *EFI_SHELL_REMOVE_DUP_IN_FILE_LIST) ( | |
+ IN EFI_SHELL_FILE_INFO **FileList | |
+ ); | |
+ | |
+/** | |
+ Changes a shell command alias. | |
+ | |
+ This function creates an alias for a shell command. | |
+ | |
+ @param[in] Command Points to the NULL-terminated shell command or existing alias. | |
+ @param[in] Alias Points to the NULL-terminated alias for the shell command. If this is NULL, and | |
+ Command refers to an alias, that alias will be deleted. | |
+ @param[in] Replace If TRUE and the alias already exists, then the existing alias will be replaced. If | |
+ FALSE and the alias already exists, then the existing alias is unchanged and | |
+ EFI_ACCESS_DENIED is returned. | |
+ @param[in] Volatile if TRUE the Alias being set will be stored in a volatile fashion. if FALSE the | |
+ Alias being set will be stored in a non-volatile fashion. | |
+ | |
+ @retval EFI_SUCCESS Alias created or deleted successfully. | |
+ @retval EFI_ACCESS_DENIED The alias is a built-in alias or already existed and Replace was set to | |
+ FALSE. | |
+**/ | |
+typedef | |
+EFI_STATUS | |
+(EFIAPI *EFI_SHELL_SET_ALIAS)( | |
+ IN CONST CHAR16 *Command, | |
+ IN CONST CHAR16 *Alias, | |
+ IN BOOLEAN Replace, | |
+ IN BOOLEAN Volatile | |
+ ); | |
+ | |
+/** | |
+ This function returns the command associated with a alias or a list of all | |
+ alias'. | |
+ | |
+ @param[in] Alias Points to the NULL-terminated shell alias. | |
+ If this parameter is NULL, then all | |
+ aliases will be returned in ReturnedData. | |
+ @param[out] Volatile Upon return of a single command if TRUE indicates | |
+ this is stored in a volatile fashion. FALSE otherwise. | |
+ @return If Alias is not NULL, it will return a pointer to | |
+ the NULL-terminated command for that alias. | |
+ If Alias is NULL, ReturnedData points to a ';' | |
+ delimited list of alias (e.g. | |
+ ReturnedData = "dir;del;copy;mfp") that is NULL-terminated. | |
+ @retval NULL An error ocurred. | |
+ @retval NULL Alias was not a valid Alias. | |
+**/ | |
+typedef | |
+CONST CHAR16 * | |
+(EFIAPI *EFI_SHELL_GET_ALIAS)( | |
+ IN CONST CHAR16 *Alias, | |
+ OUT BOOLEAN *Volatile OPTIONAL | |
+ ); | |
+ | |
+/** | |
+ Changes the current directory on the specified device. | |
+ | |
+ If the FileSystem is NULL, and the directory Dir does not contain a file system's | |
+ mapped name, this function changes the current working directory. If FileSystem is | |
+ NULL and the directory Dir contains a mapped name, then the current file system and | |
+ the current directory on that file system are changed. | |
+ | |
+ If FileSystem is not NULL, and Dir is NULL, then this changes the current working file | |
+ system. | |
+ | |
+ If FileSystem is not NULL and Dir is not NULL, then this function changes the current | |
+ directory on the specified file system. | |
+ | |
+ If the current working directory or the current working file system is changed then the | |
+ %cwd% environment variable will be updated. | |
+ | |
+ @param[in] FileSystem A pointer to the file system's mapped name. If NULL, then the current working | |
+ directory is changed. | |
+ @param[in] Dir Points to the NULL-terminated directory on the device specified by FileSystem. | |
+ | |
+ @retval NULL Current directory does not exist. | |
+ @return The current directory. | |
+**/ | |
+typedef | |
+EFI_STATUS | |
+(EFIAPI *EFI_SHELL_SET_CUR_DIR) ( | |
+ IN CONST CHAR16 *FileSystem OPTIONAL, | |
+ IN CONST CHAR16 *Dir | |
+ ); | |
+ | |
+/** | |
+ Sets the environment variable. | |
+ | |
+ This function changes the current value of the specified environment variable. If the | |
+ environment variable exists and the Value is an empty string, then the environment | |
+ variable is deleted. If the environment variable exists and the Value is not an empty | |
+ string, then the value of the environment variable is changed. If the environment | |
+ variable does not exist and the Value is an empty string, there is no action. If the | |
+ environment variable does not exist and the Value is a non-empty string, then the | |
+ environment variable is created and assigned the specified value. | |
+ | |
+ For a description of volatile and non-volatile environment variables, see UEFI Shell | |
+ 2.0 specification section 3.6.1. | |
+ | |
+ @param[in] Name Points to the NULL-terminated environment variable name. | |
+ @param[in] Value Points to the NULL-terminated environment variable value. If the value is an | |
+ empty string then the environment variable is deleted. | |
+ @param[in] Volatile Indicates whether the variable is non-volatile (FALSE) or volatile (TRUE). | |
+ | |
+ @retval EFI_SUCCESS The environment variable was successfully updated. | |
+**/ | |
+typedef | |
+EFI_STATUS | |
+(EFIAPI *EFI_SHELL_SET_ENV) ( | |
+ IN CONST CHAR16 *Name, | |
+ IN CONST CHAR16 *Value, | |
+ IN BOOLEAN Volatile | |
+ ); | |
+ | |
+/** | |
+ Sets the file information to an opened file handle. | |
+ | |
+ This function changes file information. All file information in the EFI_FILE_INFO | |
+ struct will be updated to the passed in data. | |
+ | |
+ @param[in] FileHandle A file handle. | |
+ @param[in] FileInfo Points to new file information. | |
+ | |
+ @retval EFI_SUCCESS The information was set. | |
+ @retval EFI_NO_MEDIA The device has no medium. | |
+ @retval EFI_DEVICE_ERROR The device reported an error. | |
+ @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted. | |
+ @retval EFI_WRITE_PROTECTED The file or medium is write-protected. | |
+ @retval EFI_ACCESS_DENIED The file was opened read-only. | |
+ @retval EFI_VOLUME_FULL The volume is full. | |
+ @retval EFI_BAD_BUFFER_SIZE BufferSize is smaller than the size of EFI_FILE_INFO. | |
+**/ | |
+typedef | |
+EFI_STATUS | |
+(EFIAPI *EFI_SHELL_SET_FILE_INFO)( | |
+ IN SHELL_FILE_HANDLE FileHandle, | |
+ IN CONST EFI_FILE_INFO *FileInfo | |
+ ); | |
+ | |
+/** | |
+ Sets a file's current position. | |
+ | |
+ This function sets the current file position for the handle to the position supplied. With | |
+ the exception of seeking to position 0xFFFFFFFFFFFFFFFF, only absolute positioning is | |
+ supported, and seeking past the end of the file is allowed (a subsequent write would | |
+ grow the file). Seeking to position 0xFFFFFFFFFFFFFFFF causes the current position | |
+ to be set to the end of the file. | |
+ | |
+ @param[in] FileHandle The file handle on which requested position will be set. | |
+ @param[in] Position Byte position from the start of the file. | |
+ | |
+ @retval EFI_SUCCESS Data was written. | |
+ @retval EFI_UNSUPPORTED The seek request for nonzero is not valid on open directories. | |
+**/ | |
+typedef | |
+EFI_STATUS | |
+(EFIAPI *EFI_SHELL_SET_FILE_POSITION)( | |
+ IN SHELL_FILE_HANDLE FileHandle, | |
+ IN UINT64 Position | |
+ ); | |
+ | |
+/** | |
+ This function creates a mapping for a device path. | |
+ | |
+ @param[in] DevicePath Points to the device path. If this is NULL and Mapping points to a valid mapping, | |
+ then the mapping will be deleted. | |
+ @param[in] Mapping Points to the NULL-terminated mapping for the device path. | |
+ | |
+ @retval EFI_SUCCESS Mapping created or deleted successfully. | |
+ @retval EFI_NO_MAPPING There is no handle that corresponds exactly to DevicePath. See the | |
+ boot service function LocateDevicePath(). | |
+ @retval EFI_ACCESS_DENIED The mapping is a built-in alias. | |
+**/ | |
+typedef | |
+EFI_STATUS | |
+(EFIAPI *EFI_SHELL_SET_MAP)( | |
+ IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath, | |
+ IN CONST CHAR16 *Mapping | |
+ ); | |
+ | |
+/** | |
+ Writes data to the file. | |
+ | |
+ This function writes the specified number of bytes to the file at the current file position. | |
+ The current file position is advanced the actual number of bytes written, which is | |
+ returned in BufferSize. Partial writes only occur when there has been a data error | |
+ during the write attempt (such as "volume space full"). The file automatically grows to | |
+ hold the data, if required. | |
+ | |
+ Direct writes to opened directories are not supported. | |
+ | |
+ @param[in] FileHandle The opened file handle for writing. | |
+ @param[in, out] BufferSize On input, size of Buffer. | |
+ @param[in] Buffer The buffer in which data to write. | |
+ | |
+ @retval EFI_SUCCESS Data was written. | |
+ @retval EFI_UNSUPPORTED Writes to open directory are not supported. | |
+ @retval EFI_NO_MEDIA The device has no media. | |
+ @retval EFI_DEVICE_ERROR The device reported an error. | |
+ @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted. | |
+ @retval EFI_WRITE_PROTECTED The device is write-protected. | |
+ @retval EFI_ACCESS_DENIED The file was open for read only. | |
+ @retval EFI_VOLUME_FULL The volume is full. | |
+**/ | |
+typedef | |
+EFI_STATUS | |
+(EFIAPI *EFI_SHELL_WRITE_FILE)( | |
+ IN SHELL_FILE_HANDLE FileHandle, | |
+ IN OUT UINTN *BufferSize, | |
+ IN VOID *Buffer | |
+ ); | |
+ | |
+// | |
+// EFI_SHELL_PROTOCOL has been updated since UEFI Shell Spec 2.0 | |
+// Usage of this protocol will require version checking before attempting | |
+// to use any new members. There is no need to check the version for | |
+// members that existed in UEFI Shell Spec 2.0. | |
+// | |
+// Update below for any future UEFI Shell spec changes to this protocol. | |
+// | |
+// Check EFI_SHELL_PROTOCOL MajorVersion and MinorVersion: | |
+// if ((2 == gEfiShellProtocol->MajorVersion) && | |
+// (0 == gEfiShellProtocol->MinorVersion)) { | |
+// // | |
+// // Cannot call: | |
+// // RegisterGuidName - UEFI Shell 2.1 | |
+// // GetGuidName - UEFI Shell 2.1 | |
+// // GetGuidFromName - UEFI Shell 2.1 | |
+// // GetEnvEx - UEFI Shell 2.1 | |
+// // | |
+// } else { | |
+// // | |
+// // Can use all members | |
+// // | |
+// } | |
+// | |
+typedef struct _EFI_SHELL_PROTOCOL { | |
+ EFI_SHELL_EXECUTE Execute; | |
+ EFI_SHELL_GET_ENV GetEnv; | |
+ EFI_SHELL_SET_ENV SetEnv; | |
+ EFI_SHELL_GET_ALIAS GetAlias; | |
+ EFI_SHELL_SET_ALIAS SetAlias; | |
+ EFI_SHELL_GET_HELP_TEXT GetHelpText; | |
+ EFI_SHELL_GET_DEVICE_PATH_FROM_MAP GetDevicePathFromMap; | |
+ EFI_SHELL_GET_MAP_FROM_DEVICE_PATH GetMapFromDevicePath; | |
+ EFI_SHELL_GET_DEVICE_PATH_FROM_FILE_PATH GetDevicePathFromFilePath; | |
+ EFI_SHELL_GET_FILE_PATH_FROM_DEVICE_PATH GetFilePathFromDevicePath; | |
+ EFI_SHELL_SET_MAP SetMap; | |
+ EFI_SHELL_GET_CUR_DIR GetCurDir; | |
+ EFI_SHELL_SET_CUR_DIR SetCurDir; | |
+ EFI_SHELL_OPEN_FILE_LIST OpenFileList; | |
+ EFI_SHELL_FREE_FILE_LIST FreeFileList; | |
+ EFI_SHELL_REMOVE_DUP_IN_FILE_LIST RemoveDupInFileList; | |
+ EFI_SHELL_BATCH_IS_ACTIVE BatchIsActive; | |
+ EFI_SHELL_IS_ROOT_SHELL IsRootShell; | |
+ EFI_SHELL_ENABLE_PAGE_BREAK EnablePageBreak; | |
+ EFI_SHELL_DISABLE_PAGE_BREAK DisablePageBreak; | |
+ EFI_SHELL_GET_PAGE_BREAK GetPageBreak; | |
+ EFI_SHELL_GET_DEVICE_NAME GetDeviceName; | |
+ EFI_SHELL_GET_FILE_INFO GetFileInfo; | |
+ EFI_SHELL_SET_FILE_INFO SetFileInfo; | |
+ EFI_SHELL_OPEN_FILE_BY_NAME OpenFileByName; | |
+ EFI_SHELL_CLOSE_FILE CloseFile; | |
+ EFI_SHELL_CREATE_FILE CreateFile; | |
+ EFI_SHELL_READ_FILE ReadFile; | |
+ EFI_SHELL_WRITE_FILE WriteFile; | |
+ EFI_SHELL_DELETE_FILE DeleteFile; | |
+ EFI_SHELL_DELETE_FILE_BY_NAME DeleteFileByName; | |
+ EFI_SHELL_GET_FILE_POSITION GetFilePosition; | |
+ EFI_SHELL_SET_FILE_POSITION SetFilePosition; | |
+ EFI_SHELL_FLUSH_FILE FlushFile; | |
+ EFI_SHELL_FIND_FILES FindFiles; | |
+ EFI_SHELL_FIND_FILES_IN_DIR FindFilesInDir; | |
+ EFI_SHELL_GET_FILE_SIZE GetFileSize; | |
+ EFI_SHELL_OPEN_ROOT OpenRoot; | |
+ EFI_SHELL_OPEN_ROOT_BY_HANDLE OpenRootByHandle; | |
+ EFI_EVENT ExecutionBreak; | |
+ UINT32 MajorVersion; | |
+ UINT32 MinorVersion; | |
+ // Added for Shell 2.1 | |
+ EFI_SHELL_REGISTER_GUID_NAME RegisterGuidName; | |
+ EFI_SHELL_GET_GUID_NAME GetGuidName; | |
+ EFI_SHELL_GET_GUID_FROM_NAME GetGuidFromName; | |
+ EFI_SHELL_GET_ENV_EX GetEnvEx; | |
+} EFI_SHELL_PROTOCOL; | |
+ | |
+extern EFI_GUID gEfiShellProtocolGuid; | |
+ | |
+enum ShellVersion { | |
+ SHELL_MAJOR_VERSION = 2, | |
+ SHELL_MINOR_VERSION = 2 | |
+}; | |
#endif | |
diff --git a/MdeModulePkg/Bus/Pci/UhciDxe/UsbHcMem.c b/MdeModulePkg/Bus/Pci/UhciDxe/UsbHcMem.c | |
index 301a2eca215d..9ee0cb89264f 100644 | |
--- a/MdeModulePkg/Bus/Pci/UhciDxe/UsbHcMem.c | |
+++ b/MdeModulePkg/Bus/Pci/UhciDxe/UsbHcMem.c | |
@@ -182,7 +182,7 @@ UsbHcAllocMemFromBlock ( | |
// available, otherwise we need to restart our searching. | |
// Available counts the consective number of zero bit. | |
// | |
- if (!USB_HC_BIT_IS_SET (Block->Bits[Byte], Bit)) { | |
+ if (!USB_HC_BIT_IS_SET (Block->Bits[Byte], (UINTN)Bit)) { | |
Available++; | |
if (Available >= Units) { | |
@@ -474,7 +474,7 @@ UsbHcAllocateMem ( | |
NewBlock = UsbHcAllocMemBlock (Pool, Pages); | |
if (NewBlock == NULL) { | |
- DEBUG ((EFI_D_INFO, "UsbHcAllocateMem: failed to allocate block\n")); | |
+ // DEBUG ((EFI_D_INFO, "UsbHcAllocateMem: failed to allocate block\n")); | |
return NULL; | |
} | |
diff --git a/MdeModulePkg/Library/UefiBootManagerLib/BmDriverHealth.c b/MdeModulePkg/Library/UefiBootManagerLib/BmDriverHealth.c | |
index db2f859ae73d..e926924c258c 100644 | |
--- a/MdeModulePkg/Library/UefiBootManagerLib/BmDriverHealth.c | |
+++ b/MdeModulePkg/Library/UefiBootManagerLib/BmDriverHealth.c | |
@@ -82,6 +82,7 @@ BmGetControllerName ( | |
BestLanguage = GetBestLanguage( | |
ComponentName->SupportedLanguages, | |
Iso639Language, | |
+ "", | |
(LanguageVariable != NULL) ? LanguageVariable : "", | |
Iso639Language ? "eng" : "en-US", | |
NULL | |
diff --git a/MdeModulePkg/Library/UefiHiiLib/HiiString.c b/MdeModulePkg/Library/UefiHiiLib/HiiString.c | |
index c6a241e6577b..8ccf1083c4b1 100644 | |
--- a/MdeModulePkg/Library/UefiHiiLib/HiiString.c | |
+++ b/MdeModulePkg/Library/UefiHiiLib/HiiString.c | |
@@ -273,6 +273,7 @@ HiiGetString ( | |
BestLanguage = GetBestLanguage ( | |
SupportedLanguages, | |
FALSE, // RFC 4646 mode | |
+ "", // skipped by GetBestLanguage() | |
Language, // Highest priority | |
PlatformLanguage != NULL ? PlatformLanguage : "", // Next highest priority | |
SupportedLanguages, // Lowest priority | |
diff --git a/MdeModulePkg/Library/UefiHiiServicesLib/UefiHiiServicesLib.c b/MdeModulePkg/Library/UefiHiiServicesLib/UefiHiiServicesLib.c | |
index bd3a12560349..38826e779be0 100644 | |
--- a/MdeModulePkg/Library/UefiHiiServicesLib/UefiHiiServicesLib.c | |
+++ b/MdeModulePkg/Library/UefiHiiServicesLib/UefiHiiServicesLib.c | |
@@ -79,25 +79,25 @@ UefiHiiServicesLibConstructor ( | |
IN EFI_SYSTEM_TABLE *SystemTable | |
) | |
{ | |
- EFI_STATUS Status; | |
+ // EFI_STATUS Status; | |
// | |
// Retrieve the pointer to the UEFI HII String Protocol | |
// | |
- Status = gBS->LocateProtocol (&gEfiHiiStringProtocolGuid, NULL, (VOID **) &gHiiString); | |
- ASSERT_EFI_ERROR (Status); | |
+ /* Status = */gBS->LocateProtocol (&gEfiHiiStringProtocolGuid, NULL, (VOID **) &gHiiString); | |
+ // ASSERT_EFI_ERROR (Status); | |
// | |
// Retrieve the pointer to the UEFI HII Database Protocol | |
// | |
- Status = gBS->LocateProtocol (&gEfiHiiDatabaseProtocolGuid, NULL, (VOID **) &gHiiDatabase); | |
- ASSERT_EFI_ERROR (Status); | |
+ /* Status = */gBS->LocateProtocol (&gEfiHiiDatabaseProtocolGuid, NULL, (VOID **) &gHiiDatabase); | |
+ // ASSERT_EFI_ERROR (Status); | |
// | |
// Retrieve the pointer to the UEFI HII Config Routing Protocol | |
// | |
- Status = gBS->LocateProtocol (&gEfiHiiConfigRoutingProtocolGuid, NULL, (VOID **) &gHiiConfigRouting); | |
- ASSERT_EFI_ERROR (Status); | |
+ /* Status = */gBS->LocateProtocol (&gEfiHiiConfigRoutingProtocolGuid, NULL, (VOID **) &gHiiConfigRouting); | |
+ // ASSERT_EFI_ERROR (Status); | |
// | |
// Retrieve the pointer to the optional UEFI HII Font Protocol | |
diff --git a/MdeModulePkg/Universal/HiiDatabaseDxe/ConfigKeywordHandler.c b/MdeModulePkg/Universal/HiiDatabaseDxe/ConfigKeywordHandler.c | |
index 5d5f17fb1779..8598900137c1 100644 | |
--- a/MdeModulePkg/Universal/HiiDatabaseDxe/ConfigKeywordHandler.c | |
+++ b/MdeModulePkg/Universal/HiiDatabaseDxe/ConfigKeywordHandler.c | |
@@ -1934,6 +1934,7 @@ GetNameFromId ( | |
BestLanguage = GetBestLanguage ( | |
SupportedLanguages, | |
FALSE, // RFC 4646 mode | |
+ "", // skipped by GetBestLanguage() | |
PlatformLanguage != NULL ? PlatformLanguage : "", // Highest priority | |
SupportedLanguages, // Lowest priority | |
NULL | |
diff --git a/MdeModulePkg/Universal/HiiDatabaseDxe/ConfigRouting.c b/MdeModulePkg/Universal/HiiDatabaseDxe/ConfigRouting.c | |
index 646864f4dfc1..280f70ed14cc 100644 | |
--- a/MdeModulePkg/Universal/HiiDatabaseDxe/ConfigRouting.c | |
+++ b/MdeModulePkg/Universal/HiiDatabaseDxe/ConfigRouting.c | |
@@ -1396,6 +1396,7 @@ InternalGetString ( | |
BestLanguage = GetBestLanguage ( | |
SupportedLanguages, | |
FALSE, // RFC 4646 mode | |
+ "", // skipped by GetBestLanguage() | |
Language, // Highest priority | |
PlatformLanguage != NULL ? PlatformLanguage : "", // Next highest priority | |
SupportedLanguages, // Lowest priority | |
diff --git a/MdeModulePkg/Universal/HiiDatabaseDxe/Font.c b/MdeModulePkg/Universal/HiiDatabaseDxe/Font.c | |
index b85cf88f54e5..30eb45f10aa3 100644 | |
--- a/MdeModulePkg/Universal/HiiDatabaseDxe/Font.c | |
+++ b/MdeModulePkg/Universal/HiiDatabaseDxe/Font.c | |
@@ -2400,6 +2400,7 @@ HiiStringIdToImage ( | |
BestLanguage = GetBestLanguage ( | |
SupportedLanguages, | |
FALSE, | |
+ "", | |
Language, | |
(CurrentLanguage == NULL) ? CurrentLanguage : "", | |
(CHAR8 *) PcdGetPtr (PcdUefiVariableDefaultPlatformLang), | |
diff --git a/MdeModulePkg/Universal/PlatformDriOverrideDxe/PlatDriOverrideDxe.c b/MdeModulePkg/Universal/PlatformDriOverrideDxe/PlatDriOverrideDxe.c | |
index 76c240b73d0c..cd782de9e0b6 100644 | |
--- a/MdeModulePkg/Universal/PlatformDriOverrideDxe/PlatDriOverrideDxe.c | |
+++ b/MdeModulePkg/Universal/PlatformDriOverrideDxe/PlatDriOverrideDxe.c | |
@@ -174,6 +174,7 @@ GetComponentNameWorker ( | |
BestLanguage = GetBestLanguage ( | |
ComponentName->SupportedLanguages, | |
(BOOLEAN) (ProtocolGuid == &gEfiComponentNameProtocolGuid), | |
+ "", | |
Language, | |
NULL | |
); | |
diff --git a/MdeModulePkg/Universal/SecurityStubDxe/Defer3rdPartyImageLoad.c b/MdeModulePkg/Universal/SecurityStubDxe/Defer3rdPartyImageLoad.c | |
index 7135a9d87cc0..02c885b34501 100644 | |
--- a/MdeModulePkg/Universal/SecurityStubDxe/Defer3rdPartyImageLoad.c | |
+++ b/MdeModulePkg/Universal/SecurityStubDxe/Defer3rdPartyImageLoad.c | |
@@ -55,6 +55,8 @@ FileFromFv ( | |
IN CONST EFI_DEVICE_PATH_PROTOCOL *File | |
) | |
{ | |
+ return TRUE; | |
+ /* | |
EFI_STATUS Status; | |
EFI_HANDLE DeviceHandle; | |
EFI_DEVICE_PATH_PROTOCOL *TempDevicePath; | |
@@ -84,6 +86,7 @@ FileFromFv ( | |
} | |
return FALSE; | |
+ */ | |
} | |
/** | |
diff --git a/MdeModulePkg/Universal/Variable/EmuRuntimeDxe/EmuVariable.c b/MdeModulePkg/Universal/Variable/EmuRuntimeDxe/EmuVariable.c | |
index 6dee2b6add4b..d9f537e30984 100644 | |
--- a/MdeModulePkg/Universal/Variable/EmuRuntimeDxe/EmuVariable.c | |
+++ b/MdeModulePkg/Universal/Variable/EmuRuntimeDxe/EmuVariable.c | |
@@ -156,7 +156,7 @@ GetVariableDataPtr ( | |
// | |
// Be careful about pad size for alignment | |
// | |
- return (UINT8 *) ((UINTN) GET_VARIABLE_NAME_PTR (Variable) + Variable->NameSize + GET_PAD_SIZE (Variable->NameSize)); | |
+ return (UINT8 *) ((UINTN) (GET_VARIABLE_NAME_PTR (Variable)) + Variable->NameSize + GET_PAD_SIZE (Variable->NameSize)); | |
} | |
/** | |
@@ -576,6 +576,7 @@ EFIAPI | |
VariableGetBestLanguage ( | |
IN CONST CHAR8 *SupportedLanguages, | |
IN BOOLEAN Iso639Language, | |
+ IN CONST CHAR8 *Lang, | |
... | |
) | |
{ | |
@@ -588,7 +589,7 @@ VariableGetBestLanguage ( | |
ASSERT (SupportedLanguages != NULL); | |
- VA_START (Args, Iso639Language); | |
+ VA_START (Args, Lang); | |
while ((Language = VA_ARG (Args, CHAR8 *)) != NULL) { | |
// | |
// Default to ISO 639-2 mode | |
@@ -799,7 +800,7 @@ AutoUpdateLangVariable( | |
// | |
// When setting PlatformLang, firstly get most matched language string from supported language codes. | |
// | |
- BestPlatformLang = VariableGetBestLanguage (mVariableModuleGlobal->PlatformLangCodes, FALSE, Data, NULL); | |
+ BestPlatformLang = VariableGetBestLanguage (mVariableModuleGlobal->PlatformLangCodes, FALSE, "", Data, NULL); | |
if (BestPlatformLang != NULL) { | |
// | |
// Get the corresponding index in language codes. | |
@@ -832,7 +833,7 @@ AutoUpdateLangVariable( | |
// | |
// When setting Lang, firstly get most matched language string from supported language codes. | |
// | |
- BestLang = VariableGetBestLanguage (mVariableModuleGlobal->LangCodes, TRUE, Data, NULL); | |
+ BestLang = VariableGetBestLanguage (mVariableModuleGlobal->LangCodes, TRUE, "", Data, NULL); | |
if (BestLang != NULL) { | |
// | |
// Get the corresponding index in language codes. | |
@@ -1472,7 +1473,7 @@ EmuSetVariable ( | |
// Check whether the input variable is already existed | |
// | |
- Status = FindVariable (VariableName, VendorGuid, &Variable, Global); | |
+ FindVariable (VariableName, VendorGuid, &Variable, Global); | |
// | |
// Hook the operation of setting PlatformLangCodes/PlatformLang and LangCodes/Lang | |
@@ -1651,7 +1652,7 @@ InitializeVariableStore ( | |
IN BOOLEAN VolatileStore | |
) | |
{ | |
- EFI_STATUS Status; | |
+ EFI_STATUS Status = EFI_SUCCESS; | |
VARIABLE_STORE_HEADER *VariableStore; | |
BOOLEAN FullyInitializeStore; | |
EFI_PHYSICAL_ADDRESS *VariableBase; | |
@@ -1677,7 +1678,10 @@ InitializeVariableStore ( | |
// ensure that the value of PcdHwErrStorageSize is less than or equal to the value of | |
// PcdVariableStoreSize. | |
// | |
- ASSERT (PcdGet32 (PcdHwErrStorageSize) <= PcdGet32 (PcdVariableStoreSize)); | |
+ // ASSERT (PcdGet32 (PcdHwErrStorageSize) <= PcdGet32 (PcdVariableStoreSize)); | |
+ if (PcdGet32 (PcdHwErrStorageSize) > PcdGet32 (PcdVariableStoreSize)) { | |
+ return EFI_OUT_OF_RESOURCES; | |
+ } | |
// | |
// Allocate memory for variable store. | |
@@ -1747,8 +1751,12 @@ InitializeVariableStore ( | |
; (Variable < GetEndPointer (VariableStoreHeader) && (Variable != NULL)) | |
; Variable = GetNextVariablePtr (Variable) | |
) { | |
- ASSERT (Variable->State == VAR_ADDED); | |
- ASSERT ((Variable->Attributes & EFI_VARIABLE_NON_VOLATILE) != 0); | |
+ // ASSERT (Variable->State == VAR_ADDED); | |
+ // ASSERT ((Variable->Attributes & EFI_VARIABLE_NON_VOLATILE) != 0); | |
+ if ((Variable->State != VAR_ADDED) || | |
+ ((Variable->Attributes & EFI_VARIABLE_NON_VOLATILE) == 0)) { | |
+ return EFI_OUT_OF_RESOURCES; | |
+ } | |
VariableData = GetVariableDataPtr (Variable); | |
Status = EmuSetVariable ( | |
GET_VARIABLE_NAME_PTR (Variable), | |
@@ -1760,13 +1768,13 @@ InitializeVariableStore ( | |
&mVariableModuleGlobal->VolatileLastVariableOffset, | |
&mVariableModuleGlobal->NonVolatileLastVariableOffset | |
); | |
- ASSERT_EFI_ERROR (Status); | |
+ // ASSERT_EFI_ERROR (Status); | |
} | |
} | |
} | |
} | |
- return EFI_SUCCESS; | |
+ return Status; //EFI_SUCCESS; | |
} | |
/** | |
diff --git a/MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.c b/MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.c | |
index 6caf603b3d30..05c5a4cc47db 100644 | |
--- a/MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.c | |
+++ b/MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.c | |
@@ -1561,6 +1561,7 @@ EFIAPI | |
VariableGetBestLanguage ( | |
IN CONST CHAR8 *SupportedLanguages, | |
IN BOOLEAN Iso639Language, | |
+ IN CONST CHAR8 *Lang, | |
... | |
) | |
{ | |
@@ -1575,7 +1576,7 @@ VariableGetBestLanguage ( | |
return NULL; | |
} | |
- VA_START (Args, Iso639Language); | |
+ VA_START (Args, Lang); | |
while ((Language = VA_ARG (Args, CHAR8 *)) != NULL) { | |
// | |
// Default to ISO 639-2 mode | |
@@ -1961,7 +1962,7 @@ AutoUpdateLangVariable ( | |
// | |
// When setting PlatformLang, firstly get most matched language string from supported language codes. | |
// | |
- BestPlatformLang = VariableGetBestLanguage (mVariableModuleGlobal->PlatformLangCodes, FALSE, Data, NULL); | |
+ BestPlatformLang = VariableGetBestLanguage (mVariableModuleGlobal->PlatformLangCodes, FALSE, "", Data, NULL); | |
if (BestPlatformLang != NULL) { | |
// | |
// Get the corresponding index in language codes. | |
@@ -2010,7 +2011,7 @@ AutoUpdateLangVariable ( | |
// | |
// When setting Lang, firstly get most matched language string from supported language codes. | |
// | |
- BestLang = VariableGetBestLanguage (mVariableModuleGlobal->LangCodes, TRUE, Data, NULL); | |
+ BestLang = VariableGetBestLanguage (mVariableModuleGlobal->LangCodes, TRUE, "", Data, NULL); | |
if (BestLang != NULL) { | |
// | |
// Get the corresponding index in language codes. | |
diff --git a/MdePkg/Library/BaseLib/SafeString.c b/MdePkg/Library/BaseLib/SafeString.c | |
index 29310889cabb..8595462b758f 100644 | |
--- a/MdePkg/Library/BaseLib/SafeString.c | |
+++ b/MdePkg/Library/BaseLib/SafeString.c | |
@@ -13,10 +13,12 @@ | |
**/ | |
#include "BaseLibInternals.h" | |
+// this is 1.000.000 | |
+#define RSIZE_MAX 100000000ull | |
+// (PcdGet32 (PcdMaximumUnicodeStringLength)) | |
-#define RSIZE_MAX (PcdGet32 (PcdMaximumUnicodeStringLength)) | |
- | |
-#define ASCII_RSIZE_MAX (PcdGet32 (PcdMaximumAsciiStringLength)) | |
+#define ASCII_RSIZE_MAX 100000000ull | |
+// (PcdGet32 (PcdMaximumAsciiStringLength)) | |
#define SAFE_STRING_CONSTRAINT_CHECK(Expression, Status) \ | |
do { \ | |
@@ -110,11 +112,16 @@ InternalSafeStringNoAsciiStrOverlap ( | |
@param String A pointer to a Null-terminated Unicode string. | |
@param MaxSize The maximum number of Destination Unicode | |
char, including terminating null char. | |
+ Slice: NOT including | |
@retval 0 If String is NULL. | |
@retval MaxSize If there is no null character in the first MaxSize characters of String. | |
@return The number of characters that percede the terminating null character. | |
- | |
+ Slice: | |
+ for example string = L"012345" | |
+ StrnLenS(string, 4) = 4; | |
+ StrnLenS(string, 6) = 6; | |
+ StrnLenS(string, 9) = 6; | |
**/ | |
UINTN | |
EFIAPI | |
@@ -130,7 +137,7 @@ StrnLenS ( | |
// | |
// If String is a null pointer or MaxSize is 0, then the StrnLenS function returns zero. | |
// | |
- if ((String == NULL) || (MaxSize == 0)) { | |
+ if (String == NULL) { | |
return 0; | |
} | |
@@ -257,18 +264,20 @@ StrCpyS ( | |
// 4. DestMax shall be greater than StrnLenS(Source, DestMax). | |
// | |
SourceLen = StrnLenS (Source, DestMax); | |
- SAFE_STRING_CONSTRAINT_CHECK ((DestMax > SourceLen), RETURN_BUFFER_TOO_SMALL); | |
+ // SAFE_STRING_CONSTRAINT_CHECK ((DestMax > SourceLen), RETURN_BUFFER_TOO_SMALL); | |
+ // Slice: nonsense because of StrnLenS result always <= DestMax | |
// | |
// 5. Copying shall not take place between objects that overlap. | |
// | |
- SAFE_STRING_CONSTRAINT_CHECK (InternalSafeStringNoStrOverlap (Destination, DestMax, (CHAR16 *)Source, SourceLen + 1), RETURN_ACCESS_DENIED); | |
+ // SAFE_STRING_CONSTRAINT_CHECK (InternalSafeStringNoStrOverlap (Destination, DestMax, (CHAR16 *)Source, SourceLen + 1), RETURN_ACCESS_DENIED); | |
+ // Slice: relax | |
// | |
// The StrCpyS function copies the string pointed to by Source (including the terminating | |
// null character) into the array pointed to by Destination. | |
// | |
- while (*Source != 0) { | |
+ while ((*Source != 0) && (--DestMax > 0)) { | |
*(Destination++) = *(Source++); | |
} | |
*Destination = 0; | |
@@ -329,10 +338,10 @@ StrnCpyS ( | |
// | |
// 2. Neither DestMax nor Length shall be greater than RSIZE_MAX | |
// | |
- if (RSIZE_MAX != 0) { | |
- SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= RSIZE_MAX), RETURN_INVALID_PARAMETER); | |
- SAFE_STRING_CONSTRAINT_CHECK ((Length <= RSIZE_MAX), RETURN_INVALID_PARAMETER); | |
- } | |
+ // if (RSIZE_MAX != 0) { | |
+ // SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= RSIZE_MAX), RETURN_INVALID_PARAMETER); | |
+ // SAFE_STRING_CONSTRAINT_CHECK ((Length <= RSIZE_MAX), RETURN_INVALID_PARAMETER); | |
+ // } | |
// | |
// 3. DestMax shall not equal zero. | |
@@ -342,10 +351,10 @@ StrnCpyS ( | |
// | |
// 4. If Length is not less than DestMax, then DestMax shall be greater than StrnLenS(Source, DestMax). | |
// | |
- SourceLen = StrnLenS (Source, MIN (DestMax, Length)); | |
- if (Length >= DestMax) { | |
- SAFE_STRING_CONSTRAINT_CHECK ((DestMax > SourceLen), RETURN_BUFFER_TOO_SMALL); | |
- } | |
+ SourceLen = StrnLenS (Source, MIN (DestMax, Length)); //Slice: SourceLen <= DestMax | |
+ // if (Length >= DestMax) { | |
+ // SAFE_STRING_CONSTRAINT_CHECK ((DestMax > SourceLen), RETURN_BUFFER_TOO_SMALL); | |
+ // } | |
// | |
// 5. Copying shall not take place between objects that overlap. | |
@@ -353,7 +362,7 @@ StrnCpyS ( | |
if (SourceLen > Length) { | |
SourceLen = Length; | |
} | |
- SAFE_STRING_CONSTRAINT_CHECK (InternalSafeStringNoStrOverlap (Destination, DestMax, (CHAR16 *)Source, SourceLen + 1), RETURN_ACCESS_DENIED); | |
+ // SAFE_STRING_CONSTRAINT_CHECK (InternalSafeStringNoStrOverlap (Destination, DestMax, (CHAR16 *)Source, SourceLen + 1), RETURN_ACCESS_DENIED); | |
// | |
// The StrnCpyS function copies not more than Length successive characters (characters that | |
@@ -361,7 +370,7 @@ StrnCpyS ( | |
// pointed to by Destination. If no null character was copied from Source, then Destination[Length] is set to a null | |
// character. | |
// | |
- while ((SourceLen > 0) && (*Source != 0)) { | |
+ while ((SourceLen > 0) && (*Source != 0) && (--DestMax > 0)) { | |
*(Destination++) = *(Source++); | |
SourceLen--; | |
} | |
@@ -430,9 +439,9 @@ StrCatS ( | |
// | |
// 2. DestMax shall not be greater than RSIZE_MAX. | |
// | |
- if (RSIZE_MAX != 0) { | |
- SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= RSIZE_MAX), RETURN_INVALID_PARAMETER); | |
- } | |
+ // if (RSIZE_MAX != 0) { | |
+ // SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= RSIZE_MAX), RETURN_INVALID_PARAMETER); | |
+ // } | |
// | |
// 3. DestMax shall not equal zero. | |
@@ -448,12 +457,12 @@ StrCatS ( | |
// 5. CopyLen shall be greater than StrnLenS(Source, CopyLen). | |
// | |
SourceLen = StrnLenS (Source, CopyLen); | |
- SAFE_STRING_CONSTRAINT_CHECK ((CopyLen > SourceLen), RETURN_BUFFER_TOO_SMALL); | |
+ // SAFE_STRING_CONSTRAINT_CHECK ((CopyLen > SourceLen), RETURN_BUFFER_TOO_SMALL); | |
// | |
// 6. Copying shall not take place between objects that overlap. | |
// | |
- SAFE_STRING_CONSTRAINT_CHECK (InternalSafeStringNoStrOverlap (Destination, DestMax, (CHAR16 *)Source, SourceLen + 1), RETURN_ACCESS_DENIED); | |
+ // SAFE_STRING_CONSTRAINT_CHECK (InternalSafeStringNoStrOverlap (Destination, DestMax, (CHAR16 *)Source, SourceLen + 1), RETURN_ACCESS_DENIED); | |
// | |
// The StrCatS function appends a copy of the string pointed to by Source (including the | |
@@ -461,7 +470,7 @@ StrCatS ( | |
// from Source overwrites the null character at the end of Destination. | |
// | |
Destination = Destination + DestLen; | |
- while (*Source != 0) { | |
+ while ((*Source != 0) && (--CopyLen > 0)) { | |
*(Destination++) = *(Source++); | |
} | |
*Destination = 0; | |
@@ -533,10 +542,10 @@ StrnCatS ( | |
// | |
// 2. Neither DestMax nor Length shall be greater than RSIZE_MAX. | |
// | |
- if (RSIZE_MAX != 0) { | |
- SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= RSIZE_MAX), RETURN_INVALID_PARAMETER); | |
- SAFE_STRING_CONSTRAINT_CHECK ((Length <= RSIZE_MAX), RETURN_INVALID_PARAMETER); | |
- } | |
+ // if (RSIZE_MAX != 0) { | |
+ // SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= RSIZE_MAX), RETURN_INVALID_PARAMETER); | |
+ // SAFE_STRING_CONSTRAINT_CHECK ((Length <= RSIZE_MAX), RETURN_INVALID_PARAMETER); | |
+ // } | |
// | |
// 3. DestMax shall not equal zero. | |
@@ -552,9 +561,9 @@ StrnCatS ( | |
// 5. If Length is not less than CopyLen, then CopyLen shall be greater than StrnLenS(Source, CopyLen). | |
// | |
SourceLen = StrnLenS (Source, MIN (CopyLen, Length)); | |
- if (Length >= CopyLen) { | |
- SAFE_STRING_CONSTRAINT_CHECK ((CopyLen > SourceLen), RETURN_BUFFER_TOO_SMALL); | |
- } | |
+ // if (Length >= CopyLen) { | |
+ // SAFE_STRING_CONSTRAINT_CHECK ((CopyLen > SourceLen), RETURN_BUFFER_TOO_SMALL); | |
+ // } | |
// | |
// 6. Copying shall not take place between objects that overlap. | |
@@ -562,7 +571,7 @@ StrnCatS ( | |
if (SourceLen > Length) { | |
SourceLen = Length; | |
} | |
- SAFE_STRING_CONSTRAINT_CHECK (InternalSafeStringNoStrOverlap (Destination, DestMax, (CHAR16 *)Source, SourceLen + 1), RETURN_ACCESS_DENIED); | |
+ // SAFE_STRING_CONSTRAINT_CHECK (InternalSafeStringNoStrOverlap (Destination, DestMax, (CHAR16 *)Source, SourceLen + 1), RETURN_ACCESS_DENIED); | |
// | |
// The StrnCatS function appends not more than Length successive characters (characters | |
@@ -572,7 +581,7 @@ StrnCatS ( | |
// a null character. | |
// | |
Destination = Destination + DestLen; | |
- while ((SourceLen > 0) && (*Source != 0)) { | |
+ while ((SourceLen > 0) && (*Source != 0) && (--CopyLen > 0)) { | |
*(Destination++) = *(Source++); | |
SourceLen--; | |
} | |
@@ -648,9 +657,9 @@ StrDecimalToUintnS ( | |
// | |
// 2. The length of String shall not be greater than RSIZE_MAX. | |
// | |
- if (RSIZE_MAX != 0) { | |
- SAFE_STRING_CONSTRAINT_CHECK ((StrnLenS (String, RSIZE_MAX + 1) <= RSIZE_MAX), RETURN_INVALID_PARAMETER); | |
- } | |
+ // if (RSIZE_MAX != 0) { | |
+ // SAFE_STRING_CONSTRAINT_CHECK ((StrnLenS (String, RSIZE_MAX + 1) <= RSIZE_MAX), RETURN_INVALID_PARAMETER); | |
+ // } | |
if (EndPointer != NULL) { | |
*EndPointer = (CHAR16 *) String; | |
@@ -678,13 +687,13 @@ StrDecimalToUintnS ( | |
// defined by UINTN, then MAX_UINTN is stored in *Data and | |
// RETURN_UNSUPPORTED is returned. | |
// | |
- if (*Data > ((MAX_UINTN - (*String - L'0')) / 10)) { | |
- *Data = MAX_UINTN; | |
- if (EndPointer != NULL) { | |
- *EndPointer = (CHAR16 *) String; | |
- } | |
- return RETURN_UNSUPPORTED; | |
- } | |
+ // if (*Data > ((MAX_UINTN - (*String - L'0')) / 10)) { | |
+ // *Data = MAX_UINTN; | |
+ // if (EndPointer != NULL) { | |
+ // *EndPointer = (CHAR16 *) String; | |
+ // } | |
+ // return RETURN_UNSUPPORTED; | |
+ // } | |
*Data = *Data * 10 + (*String - L'0'); | |
String++; | |
@@ -763,9 +772,9 @@ StrDecimalToUint64S ( | |
// | |
// 2. The length of String shall not be greater than RSIZE_MAX. | |
// | |
- if (RSIZE_MAX != 0) { | |
- SAFE_STRING_CONSTRAINT_CHECK ((StrnLenS (String, RSIZE_MAX + 1) <= RSIZE_MAX), RETURN_INVALID_PARAMETER); | |
- } | |
+ // if (RSIZE_MAX != 0) { | |
+ // SAFE_STRING_CONSTRAINT_CHECK ((StrnLenS (String, RSIZE_MAX + 1) <= RSIZE_MAX), RETURN_INVALID_PARAMETER); | |
+ // } | |
if (EndPointer != NULL) { | |
*EndPointer = (CHAR16 *) String; | |
@@ -793,13 +802,13 @@ StrDecimalToUint64S ( | |
// defined by UINT64, then MAX_UINT64 is stored in *Data and | |
// RETURN_UNSUPPORTED is returned. | |
// | |
- if (*Data > DivU64x32 (MAX_UINT64 - (*String - L'0'), 10)) { | |
- *Data = MAX_UINT64; | |
- if (EndPointer != NULL) { | |
- *EndPointer = (CHAR16 *) String; | |
- } | |
- return RETURN_UNSUPPORTED; | |
- } | |
+ // if (*Data > DivU64x32 (MAX_UINT64 - (*String - L'0'), 10)) { | |
+ // *Data = MAX_UINT64; | |
+ // if (EndPointer != NULL) { | |
+ // *EndPointer = (CHAR16 *) String; | |
+ // } | |
+ // return RETURN_UNSUPPORTED; | |
+ // } | |
*Data = MultU64x32 (*Data, 10) + (*String - L'0'); | |
String++; | |
@@ -883,9 +892,9 @@ StrHexToUintnS ( | |
// | |
// 2. The length of String shall not be greater than RSIZE_MAX. | |
// | |
- if (RSIZE_MAX != 0) { | |
- SAFE_STRING_CONSTRAINT_CHECK ((StrnLenS (String, RSIZE_MAX + 1) <= RSIZE_MAX), RETURN_INVALID_PARAMETER); | |
- } | |
+ // if (RSIZE_MAX != 0) { | |
+ // SAFE_STRING_CONSTRAINT_CHECK ((StrnLenS (String, RSIZE_MAX + 1) <= RSIZE_MAX), RETURN_INVALID_PARAMETER); | |
+ // } | |
if (EndPointer != NULL) { | |
*EndPointer = (CHAR16 *) String; | |
@@ -924,13 +933,13 @@ StrHexToUintnS ( | |
// defined by UINTN, then MAX_UINTN is stored in *Data and | |
// RETURN_UNSUPPORTED is returned. | |
// | |
- if (*Data > ((MAX_UINTN - InternalHexCharToUintn (*String)) >> 4)) { | |
- *Data = MAX_UINTN; | |
- if (EndPointer != NULL) { | |
- *EndPointer = (CHAR16 *) String; | |
- } | |
- return RETURN_UNSUPPORTED; | |
- } | |
+ // if (*Data > ((MAX_UINTN - InternalHexCharToUintn (*String)) >> 4)) { | |
+ // *Data = MAX_UINTN; | |
+ // if (EndPointer != NULL) { | |
+ // *EndPointer = (CHAR16 *) String; | |
+ // } | |
+ // return RETURN_UNSUPPORTED; | |
+ // } | |
*Data = (*Data << 4) + InternalHexCharToUintn (*String); | |
String++; | |
@@ -1014,9 +1023,9 @@ StrHexToUint64S ( | |
// | |
// 2. The length of String shall not be greater than RSIZE_MAX. | |
// | |
- if (RSIZE_MAX != 0) { | |
- SAFE_STRING_CONSTRAINT_CHECK ((StrnLenS (String, RSIZE_MAX + 1) <= RSIZE_MAX), RETURN_INVALID_PARAMETER); | |
- } | |
+ // if (RSIZE_MAX != 0) { | |
+ // SAFE_STRING_CONSTRAINT_CHECK ((StrnLenS (String, RSIZE_MAX + 1) <= RSIZE_MAX), RETURN_INVALID_PARAMETER); | |
+ // } | |
if (EndPointer != NULL) { | |
*EndPointer = (CHAR16 *) String; | |
@@ -1055,13 +1064,13 @@ StrHexToUint64S ( | |
// defined by UINT64, then MAX_UINT64 is stored in *Data and | |
// RETURN_UNSUPPORTED is returned. | |
// | |
- if (*Data > RShiftU64 (MAX_UINT64 - InternalHexCharToUintn (*String), 4)) { | |
- *Data = MAX_UINT64; | |
- if (EndPointer != NULL) { | |
- *EndPointer = (CHAR16 *) String; | |
- } | |
- return RETURN_UNSUPPORTED; | |
- } | |
+ // if (*Data > RShiftU64 (MAX_UINT64 - InternalHexCharToUintn (*String), 4)) { | |
+ // *Data = MAX_UINT64; | |
+ // if (EndPointer != NULL) { | |
+ // *EndPointer = (CHAR16 *) String; | |
+ // } | |
+ // return RETURN_UNSUPPORTED; | |
+ // } | |
*Data = LShiftU64 (*Data, 4) + InternalHexCharToUintn (*String); | |
String++; | |
@@ -1234,7 +1243,7 @@ StrToIpv6Address ( | |
// | |
// Uintn won't exceed MAX_UINT16 if number of hexadecimal digit characters is no more than 4. | |
// | |
- ASSERT (AddressIndex + 1 < ARRAY_SIZE (Address->Addr)); | |
+ // ASSERT (AddressIndex + 1 < ARRAY_SIZE (Address->Addr)); | |
LocalAddress.Addr[AddressIndex] = (UINT8) ((UINT16) Uintn >> 8); | |
LocalAddress.Addr[AddressIndex + 1] = (UINT8) Uintn; | |
AddressIndex += 2; | |
@@ -1713,9 +1722,9 @@ AsciiStrnLenS ( | |
UINTN Length; | |
// | |
- // If String is a null pointer or MaxSize is 0, then the AsciiStrnLenS function returns zero. | |
+ // If String is a null pointer, then the AsciiStrnLenS function returns zero. | |
// | |
- if ((String == NULL) || (MaxSize == 0)) { | |
+ if (String == NULL) { | |
return 0; | |
} | |
@@ -1776,7 +1785,7 @@ AsciiStrnSizeS ( | |
// then AsciiStrnSizeS returns (sizeof (CHAR8) * (MaxSize + 1)) to keep a | |
// consistent map with the AsciiStrnLenS function. | |
// | |
- return (AsciiStrnLenS (String, MaxSize) + 1) * sizeof (*String); | |
+ return (AsciiStrnLenS (String, MaxSize) + 1); | |
} | |
/** | |
@@ -1823,9 +1832,9 @@ AsciiStrCpyS ( | |
// | |
// 2. DestMax shall not be greater than ASCII_RSIZE_MAX. | |
// | |
- if (ASCII_RSIZE_MAX != 0) { | |
- SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER); | |
- } | |
+ // if (ASCII_RSIZE_MAX != 0) { | |
+ // SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER); | |
+ // } | |
// | |
// 3. DestMax shall not equal zero. | |
@@ -1836,18 +1845,18 @@ AsciiStrCpyS ( | |
// 4. DestMax shall be greater than AsciiStrnLenS(Source, DestMax). | |
// | |
SourceLen = AsciiStrnLenS (Source, DestMax); | |
- SAFE_STRING_CONSTRAINT_CHECK ((DestMax > SourceLen), RETURN_BUFFER_TOO_SMALL); | |
+ // SAFE_STRING_CONSTRAINT_CHECK ((DestMax > SourceLen), RETURN_BUFFER_TOO_SMALL); | |
// | |
// 5. Copying shall not take place between objects that overlap. | |
// | |
- SAFE_STRING_CONSTRAINT_CHECK (InternalSafeStringNoAsciiStrOverlap (Destination, DestMax, (CHAR8 *)Source, SourceLen + 1), RETURN_ACCESS_DENIED); | |
+ // SAFE_STRING_CONSTRAINT_CHECK (InternalSafeStringNoAsciiStrOverlap (Destination, DestMax, (CHAR8 *)Source, SourceLen + 1), RETURN_ACCESS_DENIED); | |
// | |
// The AsciiStrCpyS function copies the string pointed to by Source (including the terminating | |
// null character) into the array pointed to by Destination. | |
// | |
- while (*Source != 0) { | |
+ while ((*Source != 0) && (--DestMax > 0)) { | |
*(Destination++) = *(Source++); | |
} | |
*Destination = 0; | |
@@ -1903,10 +1912,10 @@ AsciiStrnCpyS ( | |
// | |
// 2. Neither DestMax nor Length shall be greater than ASCII_RSIZE_MAX | |
// | |
- if (ASCII_RSIZE_MAX != 0) { | |
- SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER); | |
- SAFE_STRING_CONSTRAINT_CHECK ((Length <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER); | |
- } | |
+ // if (ASCII_RSIZE_MAX != 0) { | |
+ // SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER); | |
+ // SAFE_STRING_CONSTRAINT_CHECK ((Length <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER); | |
+ // } | |
// | |
// 3. DestMax shall not equal zero. | |
@@ -1917,9 +1926,9 @@ AsciiStrnCpyS ( | |
// 4. If Length is not less than DestMax, then DestMax shall be greater than AsciiStrnLenS(Source, DestMax). | |
// | |
SourceLen = AsciiStrnLenS (Source, MIN (DestMax, Length)); | |
- if (Length >= DestMax) { | |
- SAFE_STRING_CONSTRAINT_CHECK ((DestMax > SourceLen), RETURN_BUFFER_TOO_SMALL); | |
- } | |
+ // if (Length >= DestMax) { | |
+ // SAFE_STRING_CONSTRAINT_CHECK ((DestMax > SourceLen), RETURN_BUFFER_TOO_SMALL); | |
+ // } | |
// | |
// 5. Copying shall not take place between objects that overlap. | |
@@ -1927,7 +1936,7 @@ AsciiStrnCpyS ( | |
if (SourceLen > Length) { | |
SourceLen = Length; | |
} | |
- SAFE_STRING_CONSTRAINT_CHECK (InternalSafeStringNoAsciiStrOverlap (Destination, DestMax, (CHAR8 *)Source, SourceLen + 1), RETURN_ACCESS_DENIED); | |
+ // SAFE_STRING_CONSTRAINT_CHECK (InternalSafeStringNoAsciiStrOverlap (Destination, DestMax, (CHAR8 *)Source, SourceLen + 1), RETURN_ACCESS_DENIED); | |
// | |
// The AsciiStrnCpyS function copies not more than Length successive characters (characters that | |
@@ -1935,7 +1944,7 @@ AsciiStrnCpyS ( | |
// pointed to by Destination. If no null character was copied from Source, then Destination[Length] is set to a null | |
// character. | |
// | |
- while ((SourceLen > 0) && (*Source != 0)) { | |
+ while ((SourceLen > 0) && (*Source != 0) && (--DestMax > 0)) { | |
*(Destination++) = *(Source++); | |
SourceLen--; | |
} | |
@@ -1999,9 +2008,9 @@ AsciiStrCatS ( | |
// | |
// 2. DestMax shall not be greater than ASCII_RSIZE_MAX. | |
// | |
- if (ASCII_RSIZE_MAX != 0) { | |
- SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER); | |
- } | |
+ // if (ASCII_RSIZE_MAX != 0) { | |
+ // SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER); | |
+ // } | |
// | |
// 3. DestMax shall not equal zero. | |
@@ -2017,12 +2026,12 @@ AsciiStrCatS ( | |
// 5. CopyLen shall be greater than AsciiStrnLenS(Source, CopyLen). | |
// | |
SourceLen = AsciiStrnLenS (Source, CopyLen); | |
- SAFE_STRING_CONSTRAINT_CHECK ((CopyLen > SourceLen), RETURN_BUFFER_TOO_SMALL); | |
+ // SAFE_STRING_CONSTRAINT_CHECK ((CopyLen > SourceLen), RETURN_BUFFER_TOO_SMALL); | |
// | |
// 6. Copying shall not take place between objects that overlap. | |
// | |
- SAFE_STRING_CONSTRAINT_CHECK (InternalSafeStringNoAsciiStrOverlap (Destination, DestMax, (CHAR8 *)Source, SourceLen + 1), RETURN_ACCESS_DENIED); | |
+ // SAFE_STRING_CONSTRAINT_CHECK (InternalSafeStringNoAsciiStrOverlap (Destination, DestMax, (CHAR8 *)Source, SourceLen + 1), RETURN_ACCESS_DENIED); | |
// | |
// The AsciiStrCatS function appends a copy of the string pointed to by Source (including the | |
@@ -2030,7 +2039,7 @@ AsciiStrCatS ( | |
// from Source overwrites the null character at the end of Destination. | |
// | |
Destination = Destination + DestLen; | |
- while (*Source != 0) { | |
+ while ((*Source != 0) && (--CopyLen > 0)) { | |
*(Destination++) = *(Source++); | |
} | |
*Destination = 0; | |
@@ -2097,10 +2106,10 @@ AsciiStrnCatS ( | |
// | |
// 2. Neither DestMax nor Length shall be greater than ASCII_RSIZE_MAX. | |
// | |
- if (ASCII_RSIZE_MAX != 0) { | |
- SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER); | |
- SAFE_STRING_CONSTRAINT_CHECK ((Length <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER); | |
- } | |
+ // if (ASCII_RSIZE_MAX != 0) { | |
+ // SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER); | |
+ // SAFE_STRING_CONSTRAINT_CHECK ((Length <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER); | |
+ // } | |
// | |
// 3. DestMax shall not equal zero. | |
@@ -2116,9 +2125,9 @@ AsciiStrnCatS ( | |
// 5. If Length is not less than CopyLen, then CopyLen shall be greater than AsciiStrnLenS(Source, CopyLen). | |
// | |
SourceLen = AsciiStrnLenS (Source, MIN (CopyLen, Length)); | |
- if (Length >= CopyLen) { | |
- SAFE_STRING_CONSTRAINT_CHECK ((CopyLen > SourceLen), RETURN_BUFFER_TOO_SMALL); | |
- } | |
+ // if (Length >= CopyLen) { | |
+ // SAFE_STRING_CONSTRAINT_CHECK ((CopyLen > SourceLen), RETURN_BUFFER_TOO_SMALL); | |
+ // } | |
// | |
// 6. Copying shall not take place between objects that overlap. | |
@@ -2126,7 +2135,7 @@ AsciiStrnCatS ( | |
if (SourceLen > Length) { | |
SourceLen = Length; | |
} | |
- SAFE_STRING_CONSTRAINT_CHECK (InternalSafeStringNoAsciiStrOverlap (Destination, DestMax, (CHAR8 *)Source, SourceLen + 1), RETURN_ACCESS_DENIED); | |
+ // SAFE_STRING_CONSTRAINT_CHECK (InternalSafeStringNoAsciiStrOverlap (Destination, DestMax, (CHAR8 *)Source, SourceLen + 1), RETURN_ACCESS_DENIED); | |
// | |
// The AsciiStrnCatS function appends not more than Length successive characters (characters | |
@@ -2136,7 +2145,7 @@ AsciiStrnCatS ( | |
// a null character. | |
// | |
Destination = Destination + DestLen; | |
- while ((SourceLen > 0) && (*Source != 0)) { | |
+ while ((SourceLen > 0) && (*Source != 0) && (--CopyLen > 0)) { | |
*(Destination++) = *(Source++); | |
SourceLen--; | |
} | |
@@ -2209,9 +2218,9 @@ AsciiStrDecimalToUintnS ( | |
// | |
// 2. The length of String shall not be greater than ASCII_RSIZE_MAX. | |
// | |
- if (ASCII_RSIZE_MAX != 0) { | |
- SAFE_STRING_CONSTRAINT_CHECK ((AsciiStrnLenS (String, ASCII_RSIZE_MAX + 1) <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER); | |
- } | |
+ // if (ASCII_RSIZE_MAX != 0) { | |
+ // SAFE_STRING_CONSTRAINT_CHECK ((AsciiStrnLenS (String, ASCII_RSIZE_MAX + 1) <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER); | |
+ // } | |
if (EndPointer != NULL) { | |
*EndPointer = (CHAR8 *) String; | |
@@ -2239,13 +2248,13 @@ AsciiStrDecimalToUintnS ( | |
// defined by UINTN, then MAX_UINTN is stored in *Data and | |
// RETURN_UNSUPPORTED is returned. | |
// | |
- if (*Data > ((MAX_UINTN - (*String - '0')) / 10)) { | |
- *Data = MAX_UINTN; | |
- if (EndPointer != NULL) { | |
- *EndPointer = (CHAR8 *) String; | |
- } | |
- return RETURN_UNSUPPORTED; | |
- } | |
+ // if (*Data > ((MAX_UINTN - (*String - '0')) / 10)) { | |
+ // *Data = MAX_UINTN; | |
+ // if (EndPointer != NULL) { | |
+ // *EndPointer = (CHAR8 *) String; | |
+ // } | |
+ // return RETURN_UNSUPPORTED; | |
+ // } | |
*Data = *Data * 10 + (*String - '0'); | |
String++; | |
@@ -2321,9 +2330,9 @@ AsciiStrDecimalToUint64S ( | |
// | |
// 2. The length of String shall not be greater than ASCII_RSIZE_MAX. | |
// | |
- if (ASCII_RSIZE_MAX != 0) { | |
- SAFE_STRING_CONSTRAINT_CHECK ((AsciiStrnLenS (String, ASCII_RSIZE_MAX + 1) <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER); | |
- } | |
+ // if (ASCII_RSIZE_MAX != 0) { | |
+ // SAFE_STRING_CONSTRAINT_CHECK ((AsciiStrnLenS (String, ASCII_RSIZE_MAX + 1) <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER); | |
+ // } | |
if (EndPointer != NULL) { | |
*EndPointer = (CHAR8 *) String; | |
@@ -2351,13 +2360,13 @@ AsciiStrDecimalToUint64S ( | |
// defined by UINT64, then MAX_UINT64 is stored in *Data and | |
// RETURN_UNSUPPORTED is returned. | |
// | |
- if (*Data > DivU64x32 (MAX_UINT64 - (*String - '0'), 10)) { | |
- *Data = MAX_UINT64; | |
- if (EndPointer != NULL) { | |
- *EndPointer = (CHAR8 *) String; | |
- } | |
- return RETURN_UNSUPPORTED; | |
- } | |
+ // if (*Data > DivU64x32 (MAX_UINT64 - (*String - '0'), 10)) { | |
+ // *Data = MAX_UINT64; | |
+ // if (EndPointer != NULL) { | |
+ // *EndPointer = (CHAR8 *) String; | |
+ // } | |
+ // return RETURN_UNSUPPORTED; | |
+ // } | |
*Data = MultU64x32 (*Data, 10) + (*String - '0'); | |
String++; | |
@@ -2437,9 +2446,9 @@ AsciiStrHexToUintnS ( | |
// | |
// 2. The length of String shall not be greater than ASCII_RSIZE_MAX. | |
// | |
- if (ASCII_RSIZE_MAX != 0) { | |
- SAFE_STRING_CONSTRAINT_CHECK ((AsciiStrnLenS (String, ASCII_RSIZE_MAX + 1) <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER); | |
- } | |
+ // if (ASCII_RSIZE_MAX != 0) { | |
+ // SAFE_STRING_CONSTRAINT_CHECK ((AsciiStrnLenS (String, ASCII_RSIZE_MAX + 1) <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER); | |
+ // } | |
if (EndPointer != NULL) { | |
*EndPointer = (CHAR8 *) String; | |
@@ -2478,13 +2487,13 @@ AsciiStrHexToUintnS ( | |
// defined by UINTN, then MAX_UINTN is stored in *Data and | |
// RETURN_UNSUPPORTED is returned. | |
// | |
- if (*Data > ((MAX_UINTN - InternalAsciiHexCharToUintn (*String)) >> 4)) { | |
- *Data = MAX_UINTN; | |
- if (EndPointer != NULL) { | |
- *EndPointer = (CHAR8 *) String; | |
- } | |
- return RETURN_UNSUPPORTED; | |
- } | |
+ // if (*Data > ((MAX_UINTN - InternalAsciiHexCharToUintn (*String)) >> 4)) { | |
+ // *Data = MAX_UINTN; | |
+ // if (EndPointer != NULL) { | |
+ // *EndPointer = (CHAR8 *) String; | |
+ // } | |
+ // return RETURN_UNSUPPORTED; | |
+ // } | |
*Data = (*Data << 4) + InternalAsciiHexCharToUintn (*String); | |
String++; | |
@@ -2564,9 +2573,9 @@ AsciiStrHexToUint64S ( | |
// | |
// 2. The length of String shall not be greater than ASCII_RSIZE_MAX. | |
// | |
- if (ASCII_RSIZE_MAX != 0) { | |
- SAFE_STRING_CONSTRAINT_CHECK ((AsciiStrnLenS (String, ASCII_RSIZE_MAX + 1) <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER); | |
- } | |
+ // if (ASCII_RSIZE_MAX != 0) { | |
+ // SAFE_STRING_CONSTRAINT_CHECK ((AsciiStrnLenS (String, ASCII_RSIZE_MAX + 1) <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER); | |
+ // } | |
if (EndPointer != NULL) { | |
*EndPointer = (CHAR8 *) String; | |
@@ -2605,13 +2614,13 @@ AsciiStrHexToUint64S ( | |
// defined by UINT64, then MAX_UINT64 is stored in *Data and | |
// RETURN_UNSUPPORTED is returned. | |
// | |
- if (*Data > RShiftU64 (MAX_UINT64 - InternalAsciiHexCharToUintn (*String), 4)) { | |
- *Data = MAX_UINT64; | |
- if (EndPointer != NULL) { | |
- *EndPointer = (CHAR8 *) String; | |
- } | |
- return RETURN_UNSUPPORTED; | |
- } | |
+ // if (*Data > RShiftU64 (MAX_UINT64 - InternalAsciiHexCharToUintn (*String), 4)) { | |
+ // *Data = MAX_UINT64; | |
+ // if (EndPointer != NULL) { | |
+ // *EndPointer = (CHAR8 *) String; | |
+ // } | |
+ // return RETURN_UNSUPPORTED; | |
+ // } | |
*Data = LShiftU64 (*Data, 4) + InternalAsciiHexCharToUintn (*String); | |
String++; | |
@@ -2685,12 +2694,12 @@ UnicodeStrToAsciiStrS ( | |
// | |
// 2. DestMax shall not be greater than ASCII_RSIZE_MAX or RSIZE_MAX. | |
// | |
- if (ASCII_RSIZE_MAX != 0) { | |
- SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER); | |
- } | |
- if (RSIZE_MAX != 0) { | |
- SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= RSIZE_MAX), RETURN_INVALID_PARAMETER); | |
- } | |
+ // if (ASCII_RSIZE_MAX != 0) { | |
+ // SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER); | |
+ // } | |
+ // if (RSIZE_MAX != 0) { | |
+ // SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= RSIZE_MAX), RETURN_INVALID_PARAMETER); | |
+ // } | |
// | |
// 3. DestMax shall not equal zero. | |
@@ -2701,23 +2710,23 @@ UnicodeStrToAsciiStrS ( | |
// 4. DestMax shall be greater than StrnLenS (Source, DestMax). | |
// | |
SourceLen = StrnLenS (Source, DestMax); | |
- SAFE_STRING_CONSTRAINT_CHECK ((DestMax > SourceLen), RETURN_BUFFER_TOO_SMALL); | |
+ // SAFE_STRING_CONSTRAINT_CHECK ((DestMax > SourceLen), RETURN_BUFFER_TOO_SMALL); | |
// | |
// 5. Copying shall not take place between objects that overlap. | |
// | |
- SAFE_STRING_CONSTRAINT_CHECK (!InternalSafeStringIsOverlap (Destination, DestMax, (VOID *)Source, (SourceLen + 1) * sizeof(CHAR16)), RETURN_ACCESS_DENIED); | |
+ // SAFE_STRING_CONSTRAINT_CHECK (!InternalSafeStringIsOverlap (Destination, DestMax, (VOID *)Source, (SourceLen + 1) * sizeof(CHAR16)), RETURN_ACCESS_DENIED); | |
// | |
// convert string | |
// | |
- while (*Source != '\0') { | |
+ while ((*Source != '\0') && (--DestMax > 0)) { | |
// | |
// If any Unicode characters in Source contain | |
// non-zero value in the upper 8 bits, then ASSERT(). | |
// | |
- ASSERT (*Source < 0x100); | |
- *(Destination++) = (CHAR8) *(Source++); | |
+ // ASSERT (*Source < 0x100); | |
+ *(Destination++) = (CHAR8) (*(Source++) & 0xFF); | |
} | |
*Destination = '\0'; | |
@@ -2796,7 +2805,7 @@ UnicodeStrnToAsciiStrS ( | |
// 2. Neither Length nor DestMax shall be greater than ASCII_RSIZE_MAX or | |
// RSIZE_MAX. | |
// | |
- if (ASCII_RSIZE_MAX != 0) { | |
+/* if (ASCII_RSIZE_MAX != 0) { | |
SAFE_STRING_CONSTRAINT_CHECK ((Length <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER); | |
SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER); | |
} | |
@@ -2804,7 +2813,7 @@ UnicodeStrnToAsciiStrS ( | |
SAFE_STRING_CONSTRAINT_CHECK ((Length <= RSIZE_MAX), RETURN_INVALID_PARAMETER); | |
SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= RSIZE_MAX), RETURN_INVALID_PARAMETER); | |
} | |
- | |
+*/ | |
// | |
// 3. DestMax shall not equal zero. | |
// | |
@@ -2832,13 +2841,13 @@ UnicodeStrnToAsciiStrS ( | |
// | |
// Convert string | |
// | |
- while ((*Source != 0) && (SourceLen > 0)) { | |
+ while ((*Source != 0) && (SourceLen > 0) && (--DestMax > 0)) { | |
// | |
// If any Unicode characters in Source contain non-zero value in the upper | |
// 8 bits, then ASSERT(). | |
// | |
- ASSERT (*Source < 0x100); | |
- *(Destination++) = (CHAR8) *(Source++); | |
+ // ASSERT (*Source < 0x100); | |
+ *(Destination++) = (CHAR8) (*(Source++) & 0xFF); | |
SourceLen--; | |
(*DestinationLength)++; | |
} | |
@@ -2905,13 +2914,13 @@ AsciiStrToUnicodeStrS ( | |
// | |
// 2. DestMax shall not be greater than RSIZE_MAX or ASCII_RSIZE_MAX. | |
// | |
- if (RSIZE_MAX != 0) { | |
+/* if (RSIZE_MAX != 0) { | |
SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= RSIZE_MAX), RETURN_INVALID_PARAMETER); | |
} | |
if (ASCII_RSIZE_MAX != 0) { | |
SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER); | |
} | |
- | |
+*/ | |
// | |
// 3. DestMax shall not equal zero. | |
// | |
@@ -2921,20 +2930,20 @@ AsciiStrToUnicodeStrS ( | |
// 4. DestMax shall be greater than AsciiStrnLenS(Source, DestMax). | |
// | |
SourceLen = AsciiStrnLenS (Source, DestMax); | |
- SAFE_STRING_CONSTRAINT_CHECK ((DestMax > SourceLen), RETURN_BUFFER_TOO_SMALL); | |
+ // SAFE_STRING_CONSTRAINT_CHECK ((DestMax > SourceLen), RETURN_BUFFER_TOO_SMALL); | |
// | |
// 5. Copying shall not take place between objects that overlap. | |
// | |
- SAFE_STRING_CONSTRAINT_CHECK (!InternalSafeStringIsOverlap (Destination, DestMax * sizeof(CHAR16), (VOID *)Source, SourceLen + 1), RETURN_ACCESS_DENIED); | |
+ // SAFE_STRING_CONSTRAINT_CHECK (!InternalSafeStringIsOverlap (Destination, DestMax * sizeof(CHAR16), (VOID *)Source, SourceLen + 1), RETURN_ACCESS_DENIED); | |
// | |
// Convert string | |
// | |
- while (*Source != '\0') { | |
+ while ((*Source != '\0') && (--DestMax > 0)) { | |
*(Destination++) = (CHAR16)*(Source++); | |
} | |
- *Destination = '\0'; | |
+ *Destination = L'\0'; | |
return RETURN_SUCCESS; | |
} | |
@@ -3008,7 +3017,7 @@ AsciiStrnToUnicodeStrS ( | |
// 2. Neither Length nor DestMax shall be greater than ASCII_RSIZE_MAX or | |
// RSIZE_MAX. | |
// | |
- if (RSIZE_MAX != 0) { | |
+/* if (RSIZE_MAX != 0) { | |
SAFE_STRING_CONSTRAINT_CHECK ((Length <= RSIZE_MAX), RETURN_INVALID_PARAMETER); | |
SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= RSIZE_MAX), RETURN_INVALID_PARAMETER); | |
} | |
@@ -3016,7 +3025,7 @@ AsciiStrnToUnicodeStrS ( | |
SAFE_STRING_CONSTRAINT_CHECK ((Length <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER); | |
SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER); | |
} | |
- | |
+*/ | |
// | |
// 3. DestMax shall not equal zero. | |
// | |
@@ -3027,9 +3036,9 @@ AsciiStrnToUnicodeStrS ( | |
// AsciiStrnLenS(Source, DestMax). | |
// | |
SourceLen = AsciiStrnLenS (Source, DestMax); | |
- if (Length >= DestMax) { | |
- SAFE_STRING_CONSTRAINT_CHECK ((DestMax > SourceLen), RETURN_BUFFER_TOO_SMALL); | |
- } | |
+ // if (Length >= DestMax) { | |
+ // SAFE_STRING_CONSTRAINT_CHECK ((DestMax > SourceLen), RETURN_BUFFER_TOO_SMALL); | |
+ // } | |
// | |
// 5. Copying shall not take place between objects that overlap. | |
@@ -3037,14 +3046,14 @@ AsciiStrnToUnicodeStrS ( | |
if (SourceLen > Length) { | |
SourceLen = Length; | |
} | |
- SAFE_STRING_CONSTRAINT_CHECK (!InternalSafeStringIsOverlap (Destination, DestMax * sizeof(CHAR16), (VOID *)Source, SourceLen + 1), RETURN_ACCESS_DENIED); | |
+ // SAFE_STRING_CONSTRAINT_CHECK (!InternalSafeStringIsOverlap (Destination, DestMax * sizeof(CHAR16), (VOID *)Source, SourceLen + 1), RETURN_ACCESS_DENIED); | |
*DestinationLength = 0; | |
// | |
// Convert string | |
// | |
- while ((*Source != 0) && (SourceLen > 0)) { | |
+ while ((*Source != 0) && (SourceLen > 0) && (--DestMax > 0)) { | |
*(Destination++) = (CHAR16)*(Source++); | |
SourceLen--; | |
(*DestinationLength)++; | |
@@ -3207,7 +3216,7 @@ AsciiStrToIpv6Address ( | |
// | |
// Uintn won't exceed MAX_UINT16 if number of hexadecimal digit characters is no more than 4. | |
// | |
- ASSERT (AddressIndex + 1 < ARRAY_SIZE (Address->Addr)); | |
+ // ASSERT (AddressIndex + 1 < ARRAY_SIZE (Address->Addr)); | |
LocalAddress.Addr[AddressIndex] = (UINT8) ((UINT16) Uintn >> 8); | |
LocalAddress.Addr[AddressIndex + 1] = (UINT8) Uintn; | |
AddressIndex += 2; | |
diff --git a/MdePkg/Library/BaseLib/String.c b/MdePkg/Library/BaseLib/String.c | |
index 4151e0e7ac58..1ff0c33d33b1 100644 | |
--- a/MdePkg/Library/BaseLib/String.c | |
+++ b/MdePkg/Library/BaseLib/String.c | |
@@ -49,6 +49,7 @@ StrCpy ( | |
) | |
{ | |
CHAR16 *ReturnValue; | |
+ INTN DestMax; | |
// | |
// Destination cannot be NULL | |
@@ -62,6 +63,7 @@ StrCpy ( | |
ASSERT ((UINTN)(Destination - Source) > StrLen (Source)); | |
ASSERT ((UINTN)(Source - Destination) > StrLen (Source)); | |
+ DestMax = StrLen (Destination); | |
ReturnValue = Destination; | |
while (*Source != 0) { | |
*(Destination++) = *(Source++); | |
@@ -128,8 +130,11 @@ StrnCpy ( | |
ASSERT ((UINTN)(Destination - Source) > StrLen (Source)); | |
ASSERT ((UINTN)(Source - Destination) >= Length); | |
- if (PcdGet32 (PcdMaximumUnicodeStringLength) != 0) { | |
- ASSERT (Length <= PcdGet32 (PcdMaximumUnicodeStringLength)); | |
+ // if (PcdGet32 (PcdMaximumUnicodeStringLength) != 0) { | |
+ // ASSERT (Length <= PcdGet32 (PcdMaximumUnicodeStringLength)); | |
+ // } | |
+ if (Length > 1000000) { | |
+ return Destination; | |
} | |
ReturnValue = Destination; | |
@@ -169,17 +174,23 @@ StrLen ( | |
{ | |
UINTN Length; | |
- ASSERT (String != NULL); | |
+ // ASSERT (String != NULL); | |
ASSERT (((UINTN) String & BIT0) == 0); | |
+ if (!String) { | |
+ return 0; | |
+ } | |
for (Length = 0; *String != L'\0'; String++, Length++) { | |
// | |
// If PcdMaximumUnicodeStringLength is not zero, | |
// length should not more than PcdMaximumUnicodeStringLength | |
// | |
- if (PcdGet32 (PcdMaximumUnicodeStringLength) != 0) { | |
- ASSERT (Length < PcdGet32 (PcdMaximumUnicodeStringLength)); | |
+ // if (PcdGet32 (PcdMaximumUnicodeStringLength) != 0) { | |
+ // ASSERT (Length < PcdGet32 (PcdMaximumUnicodeStringLength)); | |
+ if (Length >= 100000000ull) { | |
+ break; | |
} | |
+ // } | |
} | |
return Length; | |
} | |
@@ -208,6 +219,9 @@ StrSize ( | |
IN CONST CHAR16 *String | |
) | |
{ | |
+ if (!String) { | |
+ return 0; | |
+ } | |
return (StrLen (String) + 1) * sizeof (*String); | |
} | |
@@ -249,8 +263,18 @@ StrCmp ( | |
// | |
// ASSERT both strings are less long than PcdMaximumUnicodeStringLength | |
// | |
- ASSERT (StrSize (FirstString) != 0); | |
- ASSERT (StrSize (SecondString) != 0); | |
+ // ASSERT (StrSize (FirstString) != 0); | |
+ // ASSERT (StrSize (SecondString) != 0); | |
+ if ((StrSize (FirstString) == 0) && (StrSize (SecondString) == 0)) { | |
+ return 0; | |
+ } | |
+ | |
+ if (StrSize (FirstString) == 0) { | |
+ return -1; | |
+ } | |
+ if (StrSize (SecondString) == 0) { | |
+ return 1; | |
+ } | |
while ((*FirstString != L'\0') && (*FirstString == *SecondString)) { | |
FirstString++; | |
@@ -310,9 +334,12 @@ StrnCmp ( | |
ASSERT (StrSize (FirstString) != 0); | |
ASSERT (StrSize (SecondString) != 0); | |
- if (PcdGet32 (PcdMaximumUnicodeStringLength) != 0) { | |
- ASSERT (Length <= PcdGet32 (PcdMaximumUnicodeStringLength)); | |
+ // if (PcdGet32 (PcdMaximumUnicodeStringLength) != 0) { | |
+ // ASSERT (Length <= PcdGet32 (PcdMaximumUnicodeStringLength)); | |
+ if (Length > 100000000ull) { | |
+ Length = 100000000ull; | |
} | |
+ // } | |
while ((*FirstString != L'\0') && | |
(*SecondString != L'\0') && | |
@@ -482,8 +509,11 @@ StrStr ( | |
// ASSERT both strings are less long than PcdMaximumUnicodeStringLength. | |
// Length tests are performed inside StrLen(). | |
// | |
- ASSERT (StrSize (String) != 0); | |
- ASSERT (StrSize (SearchString) != 0); | |
+ // ASSERT (StrSize (String) != 0); | |
+ // ASSERT (StrSize (SearchString) != 0); | |
+ if (!StrSize (String) || !StrSize (SearchString)) { | |
+ return NULL; | |
+ } | |
if (*SearchString == L'\0') { | |
return (CHAR16 *) String; | |
@@ -532,7 +562,7 @@ InternalIsDecimalDigitCharacter ( | |
IN CHAR16 Char | |
) | |
{ | |
- return (BOOLEAN) (Char >= L'0' && Char <= L'9'); | |
+ return (BOOLEAN) ((Char >= L'0') && (Char <= L'9')); | |
} | |
/** | |
@@ -556,7 +586,7 @@ InternalCharToUpper ( | |
IN CHAR16 Char | |
) | |
{ | |
- if (Char >= L'a' && Char <= L'z') { | |
+ if ((Char >= L'a') && (Char <= L'z')) { | |
return (CHAR16) (Char - (L'a' - L'A')); | |
} | |
@@ -611,8 +641,8 @@ InternalIsHexaDecimalDigitCharacter ( | |
{ | |
return (BOOLEAN) (InternalIsDecimalDigitCharacter (Char) || | |
- (Char >= L'A' && Char <= L'F') || | |
- (Char >= L'a' && Char <= L'f')); | |
+ ((Char >= L'A') && (Char <= L'F')) || | |
+ ((Char >= L'a') && (Char <= L'f'))); | |
} | |
/** | |
@@ -655,9 +685,13 @@ StrDecimalToUintn ( | |
IN CONST CHAR16 *String | |
) | |
{ | |
- UINTN Result; | |
+ UINTN Result = 0; | |
+ RETURN_STATUS Status; | |
- StrDecimalToUintnS (String, (CHAR16 **) NULL, &Result); | |
+ Status = StrDecimalToUintnS (String, (CHAR16 **) NULL, &Result); | |
+ if (Status != RETURN_SUCCESS) { | |
+ return 0; | |
+ } | |
return Result; | |
} | |
@@ -702,9 +736,13 @@ StrDecimalToUint64 ( | |
IN CONST CHAR16 *String | |
) | |
{ | |
- UINT64 Result; | |
+ UINT64 Result = 0; | |
+ RETURN_STATUS Status; | |
- StrDecimalToUint64S (String, (CHAR16 **) NULL, &Result); | |
+ Status = StrDecimalToUint64S (String, (CHAR16 **) NULL, &Result); | |
+ if (Status != RETURN_SUCCESS) { | |
+ return 0; | |
+ } | |
return Result; | |
} | |
@@ -749,9 +787,13 @@ StrHexToUintn ( | |
IN CONST CHAR16 *String | |
) | |
{ | |
- UINTN Result; | |
+ UINTN Result = 0; | |
+ RETURN_STATUS Status; | |
- StrHexToUintnS (String, (CHAR16 **) NULL, &Result); | |
+ Status = StrHexToUintnS (String, (CHAR16 **) NULL, &Result); | |
+ if (Status != RETURN_SUCCESS) { | |
+ return 0; | |
+ } | |
return Result; | |
} | |
@@ -791,6 +833,23 @@ StrHexToUintn ( | |
@retval Value translated from String. | |
**/ | |
+#if 1 | |
+UINT64 | |
+EFIAPI | |
+StrHexToUint64 ( | |
+ IN CONST CHAR16 *String | |
+ ) | |
+{ | |
+ UINT64 Result = 0; | |
+ RETURN_STATUS Status; | |
+ | |
+ Status = StrHexToUint64S (String, (CHAR16 **) NULL, &Result); | |
+ if (Status != RETURN_SUCCESS) { | |
+ return 0; | |
+ } | |
+ return Result; | |
+} | |
+#else | |
UINT64 | |
EFIAPI | |
StrHexToUint64 ( | |
@@ -799,9 +858,57 @@ StrHexToUint64 ( | |
{ | |
UINT64 Result; | |
- StrHexToUint64S (String, (CHAR16 **) NULL, &Result); | |
+ // | |
+ // ASSERT String is less long than PcdMaximumUnicodeStringLength. | |
+ // Length tests are performed inside StrLen(). | |
+ // | |
+ // ASSERT (StrSize (String) != 0); | |
+ if (!String) { | |
+ return 0; | |
+ } | |
+ | |
+ // | |
+ // Ignore the pad spaces (space or tab) | |
+ // | |
+ while ((*String == L' ') || (*String == L'\t')) { | |
+ String++; | |
+ } | |
+ | |
+ // | |
+ // Ignore leading Zeros after the spaces | |
+ // | |
+ while (*String == L'0') { | |
+ String++; | |
+ } | |
+ | |
+ if (InternalCharToUpper (*String) == L'X') { | |
+ // ASSERT (*(String - 1) == L'0'); | |
+ if (*(String - 1) != L'0') { | |
+ return 0; | |
+ } | |
+ // | |
+ // Skip the 'X' | |
+ // | |
+ String++; | |
+ } | |
+ | |
+ Result = 0; | |
+ | |
+ while (InternalIsHexaDecimalDigitCharacter (*String)) { | |
+ // | |
+ // If the Hex Number represented by String overflows according | |
+ // to the range defined by UINTN, then ASSERT(). | |
+ // | |
+ // ASSERT (Result <= RShiftU64 (((UINT64) ~0) - InternalHexCharToUintn (*String) , 4)); | |
+ | |
+ Result = LShiftU64 (Result, 4); | |
+ Result = Result + InternalHexCharToUintn (*String); | |
+ String++; | |
+ } | |
+ | |
return Result; | |
} | |
+#endif | |
/** | |
Check if a ASCII character is a decimal character. | |
@@ -822,7 +929,7 @@ InternalAsciiIsDecimalDigitCharacter ( | |
IN CHAR8 Char | |
) | |
{ | |
- return (BOOLEAN) (Char >= '0' && Char <= '9'); | |
+ return (BOOLEAN) ((Char >= '0') && (Char <= '9')); | |
} | |
/** | |
@@ -847,8 +954,8 @@ InternalAsciiIsHexaDecimalDigitCharacter ( | |
{ | |
return (BOOLEAN) (InternalAsciiIsDecimalDigitCharacter (Char) || | |
- (Char >= 'A' && Char <= 'F') || | |
- (Char >= 'a' && Char <= 'f')); | |
+ ((Char >= 'A') && (Char <= 'F')) || | |
+ ((Char >= 'a') && (Char <= 'f'))); | |
} | |
#ifndef DISABLE_NEW_DEPRECATED_INTERFACES | |
@@ -903,7 +1010,10 @@ UnicodeStrToAsciiStr ( | |
// ASSERT if Source is long than PcdMaximumUnicodeStringLength. | |
// Length tests are performed inside StrLen(). | |
// | |
- ASSERT (StrSize (Source) != 0); | |
+ // ASSERT (StrSize (Source) != 0); | |
+ if (!StrSize (Source)) { | |
+ return NULL; | |
+ } | |
// | |
// Source and Destination should not overlap | |
@@ -918,8 +1028,8 @@ UnicodeStrToAsciiStr ( | |
// If any Unicode characters in Source contain | |
// non-zero value in the upper 8 bits, then ASSERT(). | |
// | |
- ASSERT (*Source < 0x100); | |
- *(Destination++) = (CHAR8) *(Source++); | |
+ // ASSERT (*Source < 0x100); | |
+ *(Destination++) = (CHAR8) (*(Source++) & 0xFF); | |
} | |
*Destination = '\0'; | |
@@ -968,7 +1078,10 @@ AsciiStrCpy ( | |
// | |
// Destination cannot be NULL | |
// | |
- ASSERT (Destination != NULL); | |
+ // ASSERT (Destination != NULL); | |
+ if (!Destination || !Source) { | |
+ return NULL; | |
+ } | |
// | |
// Destination and source cannot overlap | |
@@ -1030,7 +1143,10 @@ AsciiStrnCpy ( | |
// | |
// Destination cannot be NULL | |
// | |
- ASSERT (Destination != NULL); | |
+ // ASSERT (Destination != NULL); | |
+ if (!Destination || !Source) { | |
+ return NULL; | |
+ } | |
// | |
// Destination and source cannot overlap | |
@@ -1038,9 +1154,12 @@ AsciiStrnCpy ( | |
ASSERT ((UINTN)(Destination - Source) > AsciiStrLen (Source)); | |
ASSERT ((UINTN)(Source - Destination) >= Length); | |
- if (PcdGet32 (PcdMaximumAsciiStringLength) != 0) { | |
- ASSERT (Length <= PcdGet32 (PcdMaximumAsciiStringLength)); | |
+ // if (PcdGet32 (PcdMaximumAsciiStringLength) != 0) { | |
+ // ASSERT (Length <= PcdGet32 (PcdMaximumAsciiStringLength)); | |
+ if (Length <= 100000000ull) { | |
+ Length = 100000000ull; | |
} | |
+ // } | |
ReturnValue = Destination; | |
@@ -1079,16 +1198,22 @@ AsciiStrLen ( | |
{ | |
UINTN Length; | |
- ASSERT (String != NULL); | |
+ // ASSERT (String != NULL); | |
+ if (!String) { | |
+ return 0; | |
+ } | |
for (Length = 0; *String != '\0'; String++, Length++) { | |
// | |
// If PcdMaximumUnicodeStringLength is not zero, | |
// length should not more than PcdMaximumUnicodeStringLength | |
// | |
- if (PcdGet32 (PcdMaximumAsciiStringLength) != 0) { | |
- ASSERT (Length < PcdGet32 (PcdMaximumAsciiStringLength)); | |
+ // if (PcdGet32 (PcdMaximumAsciiStringLength) != 0) { | |
+ // ASSERT (Length < PcdGet32 (PcdMaximumAsciiStringLength)); | |
+ if (Length == 100000000ull) { | |
+ break; | |
} | |
+ // } | |
} | |
return Length; | |
} | |
@@ -1116,6 +1241,9 @@ AsciiStrSize ( | |
IN CONST CHAR8 *String | |
) | |
{ | |
+ if (!String) { | |
+ return 0; | |
+ } | |
return (AsciiStrLen (String) + 1) * sizeof (*String); | |
} | |
@@ -1155,8 +1283,17 @@ AsciiStrCmp ( | |
// | |
// ASSERT both strings are less long than PcdMaximumAsciiStringLength | |
// | |
- ASSERT (AsciiStrSize (FirstString)); | |
- ASSERT (AsciiStrSize (SecondString)); | |
+ // ASSERT (AsciiStrSize (FirstString)); | |
+ // ASSERT (AsciiStrSize (SecondString)); | |
+ if (!AsciiStrSize (FirstString) && !AsciiStrSize (SecondString)) { | |
+ return 0; | |
+ } | |
+ if (!AsciiStrSize (FirstString)) { | |
+ return -1; | |
+ } | |
+ if (!AsciiStrSize (SecondString)) { | |
+ return 1; | |
+ } | |
while ((*FirstString != '\0') && (*FirstString == *SecondString)) { | |
FirstString++; | |
@@ -1185,7 +1322,7 @@ InternalBaseLibAsciiToUpper ( | |
IN CHAR8 Chr | |
) | |
{ | |
- return (UINT8) ((Chr >= 'a' && Chr <= 'z') ? Chr - ('a' - 'A') : Chr); | |
+ return (UINT8) (((Chr >= 'a') && (Chr <= 'z')) ? Chr - ('a' - 'A') : Chr); | |
} | |
/** | |
@@ -1257,8 +1394,17 @@ AsciiStriCmp ( | |
// | |
// ASSERT both strings are less long than PcdMaximumAsciiStringLength | |
// | |
- ASSERT (AsciiStrSize (FirstString)); | |
- ASSERT (AsciiStrSize (SecondString)); | |
+ // ASSERT (AsciiStrSize (FirstString)); | |
+ // ASSERT (AsciiStrSize (SecondString)); | |
+ if (!AsciiStrSize (FirstString) && !AsciiStrSize (SecondString)) { | |
+ return 0; | |
+ } | |
+ if (!AsciiStrSize (FirstString)) { | |
+ return -1; | |
+ } | |
+ if (!AsciiStrSize (SecondString)) { | |
+ return 1; | |
+ } | |
UpperFirstString = InternalBaseLibAsciiToUpper (*FirstString); | |
UpperSecondString = InternalBaseLibAsciiToUpper (*SecondString); | |
@@ -1317,12 +1463,24 @@ AsciiStrnCmp ( | |
// | |
// ASSERT both strings are less long than PcdMaximumAsciiStringLength | |
// | |
- ASSERT (AsciiStrSize (FirstString)); | |
- ASSERT (AsciiStrSize (SecondString)); | |
+ // ASSERT (AsciiStrSize (FirstString)); | |
+ // ASSERT (AsciiStrSize (SecondString)); | |
+ if (!AsciiStrSize (FirstString) && !AsciiStrSize (SecondString)) { | |
+ return 0; | |
+ } | |
+ if (!AsciiStrSize (FirstString)) { | |
+ return -1; | |
+ } | |
+ if (!AsciiStrSize (SecondString)) { | |
+ return 1; | |
+ } | |
- if (PcdGet32 (PcdMaximumAsciiStringLength) != 0) { | |
- ASSERT (Length <= PcdGet32 (PcdMaximumAsciiStringLength)); | |
+ // if (PcdGet32 (PcdMaximumAsciiStringLength) != 0) { | |
+ // ASSERT (Length <= PcdGet32 (PcdMaximumAsciiStringLength)); | |
+ if (Length > 100000000ull) { | |
+ Length = 100000000ull; | |
} | |
+ // } | |
while ((*FirstString != '\0') && | |
(*SecondString != '\0') && | |
@@ -1481,8 +1639,11 @@ AsciiStrStr ( | |
// | |
// ASSERT both strings are less long than PcdMaximumAsciiStringLength | |
// | |
- ASSERT (AsciiStrSize (String) != 0); | |
- ASSERT (AsciiStrSize (SearchString) != 0); | |
+ // ASSERT (AsciiStrSize (String) != 0); | |
+ // ASSERT (AsciiStrSize (SearchString) != 0); | |
+ if (!String || !SearchString) { | |
+ return NULL; | |
+ } | |
if (*SearchString == '\0') { | |
return (CHAR8 *) String; | |
@@ -1548,9 +1709,13 @@ AsciiStrDecimalToUintn ( | |
IN CONST CHAR8 *String | |
) | |
{ | |
- UINTN Result; | |
+ UINTN Result = 0; | |
+ RETURN_STATUS Status; | |
- AsciiStrDecimalToUintnS (String, (CHAR8 **) NULL, &Result); | |
+ Status = AsciiStrDecimalToUintnS (String, (CHAR8 **) NULL, &Result); | |
+ if (Status != RETURN_SUCCESS) { | |
+ return 0; | |
+ } | |
return Result; | |
} | |
@@ -1591,9 +1756,13 @@ AsciiStrDecimalToUint64 ( | |
IN CONST CHAR8 *String | |
) | |
{ | |
- UINT64 Result; | |
+ UINT64 Result = 0; | |
+ RETURN_STATUS Status; | |
- AsciiStrDecimalToUint64S (String, (CHAR8 **) NULL, &Result); | |
+ Status = AsciiStrDecimalToUint64S (String, (CHAR8 **) NULL, &Result); | |
+ if (Status != RETURN_SUCCESS) { | |
+ return 0; | |
+ } | |
return Result; | |
} | |
@@ -1637,9 +1806,13 @@ AsciiStrHexToUintn ( | |
IN CONST CHAR8 *String | |
) | |
{ | |
- UINTN Result; | |
+ UINTN Result = 0; | |
+ RETURN_STATUS Status; | |
- AsciiStrHexToUintnS (String, (CHAR8 **) NULL, &Result); | |
+ Status = AsciiStrHexToUintnS (String, (CHAR8 **) NULL, &Result); | |
+ if (Status != RETURN_SUCCESS) { | |
+ return 0; | |
+ } | |
return Result; | |
} | |
@@ -1684,9 +1857,13 @@ AsciiStrHexToUint64 ( | |
IN CONST CHAR8 *String | |
) | |
{ | |
- UINT64 Result; | |
+ UINT64 Result = 0; | |
+ RETURN_STATUS Status; | |
- AsciiStrHexToUint64S (String, (CHAR8 **) NULL, &Result); | |
+ Status = AsciiStrHexToUint64S (String, (CHAR8 **) NULL, &Result); | |
+ if (Status != RETURN_SUCCESS) { | |
+ return 0; | |
+ } | |
return Result; | |
} | |
@@ -1730,12 +1907,18 @@ AsciiStrToUnicodeStr ( | |
{ | |
CHAR16 *ReturnValue; | |
- ASSERT (Destination != NULL); | |
+ // ASSERT (Destination != NULL); | |
+ if (!Destination) { | |
+ return NULL; | |
+ } | |
// | |
// ASSERT Source is less long than PcdMaximumAsciiStringLength | |
// | |
- ASSERT (AsciiStrSize (Source) != 0); | |
+ // ASSERT (AsciiStrSize (Source) != 0); | |
+ if (!AsciiStrSize (Source)) { | |
+ return NULL; | |
+ } | |
// | |
// Source and Destination should not overlap | |
diff --git a/MdePkg/Library/UefiLib/UefiLib.c b/MdePkg/Library/UefiLib/UefiLib.c | |
index f1a3f1c7af05..a9a7889fd35a 100644 | |
--- a/MdePkg/Library/UefiLib/UefiLib.c | |
+++ b/MdePkg/Library/UefiLib/UefiLib.c | |
@@ -1515,6 +1515,7 @@ EFIAPI | |
GetBestLanguage ( | |
IN CONST CHAR8 *SupportedLanguages, | |
IN BOOLEAN Iso639Language, | |
+ IN CONST CHAR8 *Lang, | |
... | |
) | |
{ | |
@@ -1527,7 +1528,7 @@ GetBestLanguage ( | |
ASSERT (SupportedLanguages != NULL); | |
- VA_START (Args, Iso639Language); | |
+ VA_START (Args, Lang); | |
while ((Language = VA_ARG (Args, CHAR8 *)) != NULL) { | |
// | |
// Default to ISO 639-2 mode | |
diff --git a/MdePkg/Library/UefiMemoryAllocationLib/MemoryAllocationLib.c b/MdePkg/Library/UefiMemoryAllocationLib/MemoryAllocationLib.c | |
index 3bd3aefa216d..2fb2579ff157 100644 | |
--- a/MdePkg/Library/UefiMemoryAllocationLib/MemoryAllocationLib.c | |
+++ b/MdePkg/Library/UefiMemoryAllocationLib/MemoryAllocationLib.c | |
@@ -147,9 +147,15 @@ FreePages ( | |
{ | |
EFI_STATUS Status; | |
- ASSERT (Pages != 0); | |
+ // ASSERT (Pages != 0); | |
+ if (!Pages) { | |
+ return; | |
+ } | |
Status = gBS->FreePages ((EFI_PHYSICAL_ADDRESS) (UINTN) Buffer, Pages); | |
- ASSERT_EFI_ERROR (Status); | |
+ // ASSERT_EFI_ERROR (Status); | |
+ if (EFI_ERROR (Status)) { | |
+ return; | |
+ } | |
} | |
/** | |
@@ -187,7 +193,10 @@ InternalAllocateAlignedPages ( | |
// | |
// Alignment must be a power of two or zero. | |
// | |
- ASSERT ((Alignment & (Alignment - 1)) == 0); | |
+ // ASSERT ((Alignment & (Alignment - 1)) == 0); | |
+ if ((Alignment & (Alignment - 1)) != 0) { | |
+ return NULL; | |
+ } | |
if (Pages == 0) { | |
return NULL; | |
@@ -201,7 +210,10 @@ InternalAllocateAlignedPages ( | |
// | |
// Make sure that Pages plus EFI_SIZE_TO_PAGES (Alignment) does not overflow. | |
// | |
- ASSERT (RealPages > Pages); | |
+ // ASSERT (RealPages > Pages); | |
+ if (RealPages < Pages) { | |
+ return NULL; | |
+ } | |
Status = gBS->AllocatePages (AllocateAnyPages, MemoryType, RealPages, &Memory); | |
if (EFI_ERROR (Status)) { | |
@@ -214,7 +226,10 @@ InternalAllocateAlignedPages ( | |
// Free first unaligned page(s). | |
// | |
Status = gBS->FreePages (Memory, UnalignedPages); | |
- ASSERT_EFI_ERROR (Status); | |
+ // ASSERT_EFI_ERROR (Status); | |
+ if (EFI_ERROR (Status)) { | |
+ return NULL; | |
+ } | |
} | |
Memory = AlignedMemory + EFI_PAGES_TO_SIZE (Pages); | |
UnalignedPages = RealPages - Pages - UnalignedPages; | |
@@ -223,7 +238,10 @@ InternalAllocateAlignedPages ( | |
// Free last unaligned page(s). | |
// | |
Status = gBS->FreePages (Memory, UnalignedPages); | |
- ASSERT_EFI_ERROR (Status); | |
+ // ASSERT_EFI_ERROR (Status); | |
+ if (EFI_ERROR (Status)) { | |
+ return NULL; | |
+ } | |
} | |
} else { | |
// | |
@@ -346,11 +364,14 @@ FreeAlignedPages ( | |
IN UINTN Pages | |
) | |
{ | |
- EFI_STATUS Status; | |
+ // EFI_STATUS Status; | |
- ASSERT (Pages != 0); | |
- Status = gBS->FreePages ((EFI_PHYSICAL_ADDRESS) (UINTN) Buffer, Pages); | |
- ASSERT_EFI_ERROR (Status); | |
+ // ASSERT (Pages != 0); | |
+ if (!Pages || !Buffer) { | |
+ return; | |
+ } | |
+ /* Status = */gBS->FreePages ((EFI_PHYSICAL_ADDRESS) (UINTN) Buffer, Pages); | |
+ // ASSERT_EFI_ERROR (Status); | |
} | |
/** | |
@@ -566,8 +587,14 @@ InternalAllocateCopyPool ( | |
{ | |
VOID *Memory; | |
- ASSERT (Buffer != NULL); | |
- ASSERT (AllocationSize <= (MAX_ADDRESS - (UINTN) Buffer + 1)); | |
+ // ASSERT (Buffer != NULL); | |
+ if (!Buffer) { | |
+ return NULL; | |
+ } | |
+ // ASSERT (AllocationSize <= (MAX_ADDRESS - (UINTN) Buffer + 1)); | |
+ if (AllocationSize > (MAX_ADDRESS - (UINTN) Buffer + 1)) { | |
+ return NULL; | |
+ } | |
Memory = InternalAllocatePool (PoolType, AllocationSize); | |
if (Memory != NULL) { | |
@@ -813,9 +840,11 @@ FreePool ( | |
IN VOID *Buffer | |
) | |
{ | |
- EFI_STATUS Status; | |
+ // EFI_STATUS Status; | |
+ if (Buffer) { | |
- Status = gBS->FreePool (Buffer); | |
- ASSERT_EFI_ERROR (Status); | |
+ /* Status = */gBS->FreePool (Buffer); | |
+ // ASSERT_EFI_ERROR (Status); | |
+ } | |
} | |
diff --git a/OvmfPkg/CsmOld/LegacyBiosDxe/Ipf/IpfBootSupport.c b/OvmfPkg/CsmOld/LegacyBiosDxe/Ipf/IpfBootSupport.c | |
new file mode 100644 | |
index 000000000000..eae45ac30107 | |
--- /dev/null | |
+++ b/OvmfPkg/CsmOld/LegacyBiosDxe/Ipf/IpfBootSupport.c | |
@@ -0,0 +1,277 @@ | |
+/** @file | |
+ | |
+Copyright (c) 2006 - 2014, 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. | |
+ | |
+**/ | |
+ | |
+#include "LegacyBiosInterface.h" | |
+ | |
+/** | |
+ Assign drive number to legacy HDD drives prior to booting an EFI | |
+ aware OS so the OS can access drives without an EFI driver. | |
+ Note: BBS compliant drives ARE NOT available until this call by | |
+ either shell or EFI. | |
+ | |
+ @param This Protocol instance pointer. | |
+ @param BbsCount Number of BBS_TABLE structures | |
+ @param BbsTable List BBS entries | |
+ | |
+ @retval EFI_SUCCESS Drive numbers assigned | |
+ | |
+**/ | |
+EFI_STATUS | |
+EFIAPI | |
+LegacyBiosPrepareToBootEfi ( | |
+ IN EFI_LEGACY_BIOS_PROTOCOL *This, | |
+ OUT UINT16 *BbsCount, | |
+ OUT BBS_TABLE **BbsTable | |
+ ) | |
+{ | |
+ // | |
+ // Shadow All Opion ROM | |
+ // | |
+ LegacyBiosShadowAllLegacyOproms (This); | |
+ return EFI_SUCCESS; | |
+} | |
+ | |
+ | |
+/** | |
+ To boot from an unconventional device like parties and/or execute | |
+ HDD diagnostics. | |
+ | |
+ @param This Protocol instance pointer. | |
+ @param Attributes How to interpret the other input parameters | |
+ @param BbsEntry The 0-based index into the BbsTable for the | |
+ parent device. | |
+ @param BeerData Pointer to the 128 bytes of ram BEER data. | |
+ @param ServiceAreaData Pointer to the 64 bytes of raw Service Area data. | |
+ The caller must provide a pointer to the specific | |
+ Service Area and not the start all Service Areas. | |
+ EFI_INVALID_PARAMETER if error. Does NOT return if no error. | |
+ | |
+**/ | |
+EFI_STATUS | |
+EFIAPI | |
+LegacyBiosBootUnconventionalDevice ( | |
+ IN EFI_LEGACY_BIOS_PROTOCOL *This, | |
+ IN UDC_ATTRIBUTES Attributes, | |
+ IN UINTN BbsEntry, | |
+ IN VOID *BeerData, | |
+ IN VOID *ServiceAreaData | |
+ ) | |
+{ | |
+ return EFI_INVALID_PARAMETER; | |
+} | |
+ | |
+ | |
+/** | |
+ Attempt to legacy boot the BootOption. If the EFI contexted has been | |
+ compromised this function will not return. | |
+ | |
+ @param This Protocol instance pointer. | |
+ @param BbsDevicePath EFI Device Path from BootXXXX variable. | |
+ @param LoadOptionsSize Size of LoadOption in size. | |
+ @param LoadOptions LoadOption from BootXXXX variable | |
+ | |
+ @retval EFI_SUCCESS Removable media not present | |
+ | |
+**/ | |
+EFI_STATUS | |
+EFIAPI | |
+LegacyBiosLegacyBoot ( | |
+ IN EFI_LEGACY_BIOS_PROTOCOL *This, | |
+ IN BBS_BBS_DEVICE_PATH *BbsDevicePath, | |
+ IN UINT32 LoadOptionsSize, | |
+ IN VOID *LoadOptions | |
+ ) | |
+{ | |
+ return EFI_UNSUPPORTED; | |
+} | |
+ | |
+/** | |
+ Build the E820 table. | |
+ | |
+ @param Private Legacy BIOS Instance data | |
+ @param Size Size of E820 Table | |
+ | |
+ @retval EFI_SUCCESS It should always work. | |
+ | |
+**/ | |
+EFI_STATUS | |
+LegacyBiosBuildE820 ( | |
+ IN LEGACY_BIOS_INSTANCE *Private, | |
+ OUT UINTN *Size | |
+ ) | |
+{ | |
+ *Size = 0; | |
+ return EFI_SUCCESS; | |
+} | |
+ | |
+/** | |
+ Get all BBS info | |
+ | |
+ @param This Protocol instance pointer. | |
+ @param HddCount Number of HDD_INFO structures | |
+ @param HddInfo Onboard IDE controller information | |
+ @param BbsCount Number of BBS_TABLE structures | |
+ @param BbsTable List BBS entries | |
+ | |
+ @retval EFI_SUCCESS Tables returned | |
+ @retval EFI_NOT_FOUND resource not found | |
+ @retval EFI_DEVICE_ERROR can not get BBS table | |
+ | |
+**/ | |
+EFI_STATUS | |
+EFIAPI | |
+LegacyBiosGetBbsInfo ( | |
+ IN EFI_LEGACY_BIOS_PROTOCOL *This, | |
+ OUT UINT16 *HddCount, | |
+ OUT HDD_INFO **HddInfo, | |
+ OUT UINT16 *BbsCount, | |
+ OUT BBS_TABLE **BbsTable | |
+ ) | |
+{ | |
+ return EFI_UNSUPPORTED; | |
+} | |
+ | |
+/** | |
+ Fill in the standard BDA for Keyboard LEDs | |
+ | |
+ @param This Protocol instance pointer. | |
+ @param Leds Current LED status | |
+ | |
+ @retval EFI_SUCCESS It should always work. | |
+ | |
+**/ | |
+EFI_STATUS | |
+EFIAPI | |
+LegacyBiosUpdateKeyboardLedStatus ( | |
+ IN EFI_LEGACY_BIOS_PROTOCOL *This, | |
+ IN UINT8 Leds | |
+ ) | |
+{ | |
+ return EFI_UNSUPPORTED; | |
+} | |
+ | |
+/** | |
+ Relocate this image under 4G memory for IPF. | |
+ | |
+ @param ImageHandle Handle of driver image. | |
+ @param SystemTable Pointer to system table. | |
+ | |
+ @retval EFI_SUCCESS Image successfully relocated. | |
+ @retval EFI_ABORTED Failed to relocate image. | |
+ | |
+**/ | |
+EFI_STATUS | |
+RelocateImageUnder4GIfNeeded ( | |
+ IN EFI_HANDLE ImageHandle, | |
+ IN EFI_SYSTEM_TABLE *SystemTable | |
+ ) | |
+{ | |
+ EFI_STATUS Status; | |
+ EFI_LOADED_IMAGE_PROTOCOL *LoadedImage; | |
+ UINTN NumberOfPages; | |
+ EFI_PHYSICAL_ADDRESS LoadedImageBase; | |
+ PE_COFF_LOADER_IMAGE_CONTEXT ImageContext; | |
+ EFI_PHYSICAL_ADDRESS MemoryAddress; | |
+ EFI_HANDLE NewImageHandle; | |
+ | |
+ Status = gBS->HandleProtocol ( | |
+ ImageHandle, | |
+ &gEfiLoadedImageProtocolGuid, | |
+ (VOID *) &LoadedImage | |
+ ); | |
+ | |
+ if (!EFI_ERROR (Status)) { | |
+ LoadedImageBase = (EFI_PHYSICAL_ADDRESS) (UINTN) LoadedImage->ImageBase; | |
+ if (LoadedImageBase > 0xffffffff) { | |
+ NumberOfPages = (UINTN) (DivU64x32(LoadedImage->ImageSize, EFI_PAGE_SIZE) + 1); | |
+ | |
+ // | |
+ // Allocate buffer below 4GB here | |
+ // | |
+ Status = AllocateLegacyMemory ( | |
+ AllocateMaxAddress, | |
+ 0x7FFFFFFF, | |
+ NumberOfPages, // do we have to convert this to pages?? | |
+ &MemoryAddress | |
+ ); | |
+ if (EFI_ERROR (Status)) { | |
+ return Status; | |
+ } | |
+ | |
+ ZeroMem (&ImageContext, sizeof (PE_COFF_LOADER_IMAGE_CONTEXT)); | |
+ ImageContext.Handle = (VOID *)(UINTN)LoadedImageBase; | |
+ ImageContext.ImageRead = PeCoffLoaderImageReadFromMemory; | |
+ | |
+ // | |
+ // Get information about the image being loaded | |
+ // | |
+ Status = PeCoffLoaderGetImageInfo (&ImageContext); | |
+ if (EFI_ERROR (Status)) { | |
+ return Status; | |
+ } | |
+ ImageContext.ImageAddress = (PHYSICAL_ADDRESS)MemoryAddress; | |
+ // | |
+ // Align buffer on section boundry | |
+ // | |
+ ImageContext.ImageAddress += ImageContext.SectionAlignment - 1; | |
+ ImageContext.ImageAddress &= ~((PHYSICAL_ADDRESS)ImageContext.SectionAlignment - 1); | |
+ | |
+ // | |
+ // Load the image to our new buffer | |
+ // | |
+ Status = PeCoffLoaderLoadImage (&ImageContext); | |
+ if (EFI_ERROR (Status)) { | |
+ gBS->FreePages (MemoryAddress, NumberOfPages); | |
+ return Status; | |
+ } | |
+ | |
+ // | |
+ // Relocate the image in our new buffer | |
+ // | |
+ Status = PeCoffLoaderRelocateImage (&ImageContext); | |
+ if (EFI_ERROR (Status)) { | |
+ gBS->FreePages (MemoryAddress, NumberOfPages); | |
+ return Status; | |
+ } | |
+ | |
+ // | |
+ // Create a new handle with gEfiCallerIdGuid to be used as the ImageHandle fore the reloaded image | |
+ // | |
+ NewImageHandle = NULL; | |
+ Status = gBS->InstallProtocolInterface ( | |
+ &NewImageHandle, | |
+ &gEfiCallerIdGuid, | |
+ EFI_NATIVE_INTERFACE, | |
+ NULL | |
+ ); | |
+ | |
+ // | |
+ // Flush the instruction cache so the image data is written before we execute it | |
+ // | |
+ InvalidateInstructionCacheRange ((VOID *)(UINTN)ImageContext.ImageAddress, (UINTN)ImageContext.ImageSize); | |
+ | |
+ Status = ((EFI_IMAGE_ENTRY_POINT)(UINTN)(ImageContext.EntryPoint)) (NewImageHandle, SystemTable); | |
+ if (EFI_ERROR (Status)) { | |
+ gBS->FreePages (MemoryAddress, NumberOfPages); | |
+ return Status; | |
+ } | |
+ // | |
+ // return error directly the BS will unload this image | |
+ // | |
+ return EFI_ABORTED; | |
+ } | |
+ } | |
+ return EFI_SUCCESS; | |
+} | |
diff --git a/OvmfPkg/CsmOld/LegacyBiosDxe/Ipf/Thunk.c b/OvmfPkg/CsmOld/LegacyBiosDxe/Ipf/Thunk.c | |
new file mode 100644 | |
index 000000000000..e601bbd63bf2 | |
--- /dev/null | |
+++ b/OvmfPkg/CsmOld/LegacyBiosDxe/Ipf/Thunk.c | |
@@ -0,0 +1,550 @@ | |
+/** @file | |
+ Call into 16-bit BIOS code | |
+ | |
+ BugBug: Thunker does A20 gate. Can we get rid of this code or | |
+ put it into Legacy16 code. | |
+ | |
+Copyright (c) 1999 - 2014, 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. | |
+ | |
+**/ | |
+ | |
+#include "LegacyBiosInterface.h" | |
+#include "IpfThunk.h" | |
+ | |
+/** | |
+ Gets the current flat GDT and IDT descriptors and store them in | |
+ Private->IntThunk. These values are used by the Thunk code. | |
+ This method must be called before every thunk in order to assure | |
+ that the correct GDT and IDT are restored after the thunk. | |
+ | |
+ @param Private Private context for Legacy BIOS | |
+ | |
+ @retval EFI_SUCCESS Should only pass. | |
+ | |
+**/ | |
+EFI_STATUS | |
+LegacyBiosGetFlatDescs ( | |
+ IN LEGACY_BIOS_INSTANCE *Private | |
+ ) | |
+{ | |
+ return EFI_SUCCESS; | |
+} | |
+ | |
+ | |
+/** | |
+ BIOS interrupt call function. | |
+ | |
+ @param BiosInt Int number of BIOS call | |
+ @param Segment Segment number | |
+ @param Offset Offset in segment | |
+ @param Regs IA32 Register set. | |
+ @param Stack Base address of stack | |
+ @param StackSize Size of stack | |
+ | |
+ @retval EFI_SUCCESS BIOS interrupt call succeeds. | |
+ | |
+**/ | |
+EFI_STATUS | |
+BiosIntCall ( | |
+ IN UINT16 BiosInt, | |
+ IN UINT16 Segment, | |
+ IN UINT16 Offset, | |
+ IN EFI_IA32_REGISTER_SET *Regs, | |
+ IN VOID *Stack, | |
+ IN UINTN StackSize | |
+ ) | |
+{ | |
+ IPF_DWORD_REGS DwordRegs; | |
+ UINT64 IntTypeVariable; | |
+ | |
+ IntTypeVariable = 0x8000000000000000; | |
+ IntTypeVariable |= (UINT64)BiosInt; | |
+ | |
+ DwordRegs.Cs = Segment; | |
+ DwordRegs.Eip = Offset; | |
+ | |
+ DwordRegs.Ds = Regs->X.DS; | |
+ DwordRegs.Es = Regs->X.ES; | |
+ DwordRegs.Fs = Regs->X.ES; | |
+ DwordRegs.Gs = Regs->X.ES; | |
+ DwordRegs.Ss = 0xFFFF; | |
+ | |
+ DwordRegs.Eax = Regs->X.AX; | |
+ DwordRegs.Ebx = Regs->X.BX; | |
+ // | |
+ // Sometimes, ECX is used to pass in 32 bit data. For example, INT 1Ah, AX = B10Dh is | |
+ // "PCI BIOS v2.0c + Write Configuration DWORD" and ECX has the dword to write. | |
+ // | |
+ DwordRegs.Ecx = Regs->E.ECX; | |
+ DwordRegs.Edx = Regs->X.DX; | |
+ | |
+ DwordRegs.Ebp = Regs->X.BP; | |
+ DwordRegs.Eflag = *((UINT16 *) &Regs->X.Flags); | |
+ | |
+ DwordRegs.Edi = Regs->X.DI; | |
+ DwordRegs.Esi = Regs->X.SI; | |
+ DwordRegs.Esp = 0xFFFFFFFF; | |
+ | |
+ EfiIaEntryPoint (IntTypeVariable, &DwordRegs, ((UINTN) Stack + StackSize), StackSize); | |
+ | |
+ Regs->X.CS = DwordRegs.Cs; | |
+ | |
+ Regs->X.DS = (UINT16) DwordRegs.Ds; | |
+ Regs->X.SS = (UINT16) DwordRegs.Ss; | |
+ | |
+ Regs->E.EAX = DwordRegs.Eax; | |
+ Regs->E.EBX = DwordRegs.Ebx; | |
+ Regs->E.ECX = DwordRegs.Ecx; | |
+ Regs->E.EDX = DwordRegs.Edx; | |
+ | |
+ Regs->E.EBP = DwordRegs.Ebp; | |
+ CopyMem (&Regs->X.Flags, &DwordRegs.Eflag, sizeof (EFI_FLAGS_REG)); | |
+ | |
+ Regs->E.EDI = DwordRegs.Edi; | |
+ Regs->E.ESI = DwordRegs.Esi; | |
+ | |
+ return EFI_SUCCESS; | |
+} | |
+ | |
+ | |
+/** | |
+ Template of real mode code. | |
+ | |
+ @param CodeStart Start address of code. | |
+ @param CodeEnd End address of code | |
+ @param ReverseThunkStart Start of reverse thunk. | |
+ @param IntThunk Low memory thunk. | |
+ | |
+**/ | |
+VOID | |
+RealModeTemplate ( | |
+ OUT UINTN *CodeStart, | |
+ OUT UINTN *CodeEnd, | |
+ OUT UINTN *ReverseThunkStart, | |
+ LOW_MEMORY_THUNK *IntThunk | |
+ ) | |
+{ | |
+ SAL_RETURN_REGS SalStatus; | |
+ | |
+ SalStatus = EsalGetReverseThunkAddress (); | |
+ | |
+ *CodeStart = SalStatus.r9; | |
+ *CodeEnd = SalStatus.r10; | |
+ *ReverseThunkStart = SalStatus.r11; | |
+ | |
+} | |
+ | |
+ | |
+/** | |
+ Allocate memory < 1 MB and copy the thunker code into low memory. Se up | |
+ all the descriptors. | |
+ | |
+ @param Private Private context for Legacy BIOS | |
+ | |
+ @retval EFI_SUCCESS Should only pass. | |
+ | |
+**/ | |
+EFI_STATUS | |
+LegacyBiosInitializeThunk ( | |
+ IN LEGACY_BIOS_INSTANCE *Private | |
+ ) | |
+{ | |
+ GDT32 *CodeGdt; | |
+ GDT32 *DataGdt; | |
+ UINTN CodeStart; | |
+ UINTN CodeEnd; | |
+ UINTN ReverseThunkStart; | |
+ UINT32 Base; | |
+ LOW_MEMORY_THUNK *IntThunk; | |
+ UINTN TempData; | |
+ | |
+ ASSERT (Private); | |
+ | |
+ IntThunk = Private->IntThunk; | |
+ | |
+ // | |
+ // Clear the reserved descriptor | |
+ // | |
+ ZeroMem (&(IntThunk->RealModeGdt[0]), sizeof (GDT32)); | |
+ | |
+ // | |
+ // Setup a descriptor for real-mode code | |
+ // | |
+ CodeGdt = &(IntThunk->RealModeGdt[1]); | |
+ | |
+ // | |
+ // Fill in the descriptor with our real-mode segment value | |
+ // | |
+ CodeGdt->Type = 0xA; | |
+ // | |
+ // code/read | |
+ // | |
+ CodeGdt->System = 1; | |
+ CodeGdt->Dpl = 0; | |
+ CodeGdt->Present = 1; | |
+ CodeGdt->Software = 0; | |
+ CodeGdt->Reserved = 0; | |
+ CodeGdt->DefaultSize = 0; | |
+ // | |
+ // 16 bit operands | |
+ // | |
+ CodeGdt->Granularity = 0; | |
+ | |
+ CodeGdt->LimitHi = 0; | |
+ CodeGdt->LimitLo = 0xffff; | |
+ | |
+ Base = (*((UINT32 *) &IntThunk->Code)); | |
+ CodeGdt->BaseHi = (Base >> 24) & 0xFF; | |
+ CodeGdt->BaseMid = (Base >> 16) & 0xFF; | |
+ CodeGdt->BaseLo = Base & 0xFFFF; | |
+ | |
+ // | |
+ // Setup a descriptor for read-mode data | |
+ // | |
+ DataGdt = &(IntThunk->RealModeGdt[2]); | |
+ CopyMem (DataGdt, CodeGdt, sizeof (GDT32)); | |
+ | |
+ DataGdt->Type = 0x2; | |
+ // | |
+ // read/write data | |
+ // | |
+ DataGdt->BaseHi = 0x0; | |
+ // | |
+ // Base = 0 | |
+ // | |
+ DataGdt->BaseMid = 0x0; | |
+ // | |
+ DataGdt->BaseLo = 0x0; | |
+ // | |
+ DataGdt->LimitHi = 0x0F; | |
+ // | |
+ // Limit = 4Gb | |
+ // | |
+ DataGdt->LimitLo = 0xFFFF; | |
+ // | |
+ DataGdt->Granularity = 0x1; | |
+ // | |
+ // | |
+ // Compute selector value | |
+ // | |
+ IntThunk->RealModeGdtDesc.Limit = (UINT16) (sizeof (IntThunk->RealModeGdt) - 1); | |
+ CopyMem (&IntThunk->RealModeGdtDesc.Base, (UINT32 *) &IntThunk->RealModeGdt, sizeof (UINT32)); | |
+ // | |
+ // IntThunk->RealModeGdtDesc.Base = *((UINT32*) &IntThunk->RealModeGdt); | |
+ // | |
+ IntThunk->RealModeIdtDesc.Limit = 0xFFFF; | |
+ IntThunk->RealModeIdtDesc.Base = 0; | |
+ IntThunk->LowCodeSelector = (UINT32) ((UINTN) CodeGdt - IntThunk->RealModeGdtDesc.Base); | |
+ IntThunk->LowDataSelector = (UINT32) ((UINTN) DataGdt - IntThunk->RealModeGdtDesc.Base); | |
+ | |
+ // | |
+ // Initialize low real-mode code thunk | |
+ // | |
+ RealModeTemplate (&CodeStart, &CodeEnd, &ReverseThunkStart, IntThunk); | |
+ | |
+ TempData = (UINTN) &(IntThunk->Code); | |
+ IntThunk->LowReverseThunkStart = ((UINT32) TempData + (UINT32) (ReverseThunkStart - CodeStart)); | |
+ | |
+ EsalSetSalDataArea (TempData, (UINTN) IntThunk); | |
+ CopyMem (IntThunk->Code, (VOID *) CodeStart, CodeEnd - CodeStart); | |
+ | |
+ IntThunk->EfiToLegacy16InitTable.ReverseThunkCallSegment = EFI_SEGMENT (*((UINT32 *) &IntThunk->LowReverseThunkStart)); | |
+ IntThunk->EfiToLegacy16InitTable.ReverseThunkCallOffset = EFI_OFFSET (*((UINT32 *) &IntThunk->LowReverseThunkStart)); | |
+ | |
+ return EFI_SUCCESS; | |
+} | |
+ | |
+ | |
+/** | |
+ Thunk to 16-bit real mode and execute a software interrupt with a vector | |
+ of BiosInt. Regs will contain the 16-bit register context on entry and | |
+ exit. | |
+ | |
+ @param This Protocol instance pointer. | |
+ @param BiosInt Processor interrupt vector to invoke | |
+ @param Regs Register contexted passed into (and returned) from | |
+ thunk to 16-bit mode | |
+ | |
+ @retval FALSE Thunk completed, and there were no BIOS errors in the | |
+ target code. See Regs for status. | |
+ @retval TRUE There was a BIOS erro in the target code. | |
+ | |
+**/ | |
+BOOLEAN | |
+EFIAPI | |
+LegacyBiosInt86 ( | |
+ IN EFI_LEGACY_BIOS_PROTOCOL *This, | |
+ IN UINT8 BiosInt, | |
+ IN EFI_IA32_REGISTER_SET *Regs | |
+ ) | |
+{ | |
+ EFI_STATUS Status; | |
+ LEGACY_BIOS_INSTANCE *Private; | |
+ LOW_MEMORY_THUNK *IntThunk; | |
+ UINT16 *Stack16; | |
+ EFI_TPL OriginalTpl; | |
+ UINTN IaSegment; | |
+ UINTN IaOffset; | |
+ UINTN *Address; | |
+ UINTN TempData; | |
+ | |
+ Private = LEGACY_BIOS_INSTANCE_FROM_THIS (This); | |
+ IntThunk = Private->IntThunk; | |
+ | |
+ // | |
+ // Get the current flat GDT, IDT, and SS and store them in Private->IntThunk. | |
+ // | |
+ Status = LegacyBiosGetFlatDescs (Private); | |
+ ASSERT_EFI_ERROR (Status); | |
+ | |
+ Regs->X.Flags.Reserved1 = 1; | |
+ Regs->X.Flags.Reserved2 = 0; | |
+ Regs->X.Flags.Reserved3 = 0; | |
+ Regs->X.Flags.Reserved4 = 0; | |
+ Regs->X.Flags.IOPL = 3; | |
+ Regs->X.Flags.NT = 0; | |
+ Regs->X.Flags.IF = 1; | |
+ Regs->X.Flags.TF = 0; | |
+ Regs->X.Flags.CF = 0; | |
+ // | |
+ // Clear the error flag; thunk code may set it. | |
+ // | |
+ Stack16 = (UINT16 *) (IntThunk->Stack + LOW_STACK_SIZE); | |
+ | |
+ // | |
+ // Copy regs to low memory stack | |
+ // | |
+ Stack16 -= sizeof (EFI_IA32_REGISTER_SET) / sizeof (UINT16); | |
+ CopyMem (Stack16, Regs, sizeof (EFI_IA32_REGISTER_SET)); | |
+ | |
+ // | |
+ // Provide low stack esp | |
+ // | |
+ TempData = ((UINTN) Stack16) - ((UINTN) IntThunk); | |
+ IntThunk->LowStack = *((UINT32 *) &TempData); | |
+ | |
+ // | |
+ // Stack for reverse thunk flat mode. | |
+ // It must point to top of stack (end of stack space). | |
+ // | |
+ TempData = ((UINTN) IntThunk->RevThunkStack) + LOW_STACK_SIZE; | |
+ IntThunk->RevFlatStack = *((UINT32 *) &TempData); | |
+ | |
+ // | |
+ // The call to Legacy16 is a critical section to EFI | |
+ // | |
+ OriginalTpl = gBS->RaiseTPL (TPL_HIGH_LEVEL); | |
+ | |
+ // | |
+ // Set Legacy16 state. 0x08, 0x70 is legacy 8259 vector bases. | |
+ // | |
+ Status = Private->Legacy8259->SetMode (Private->Legacy8259, Efi8259LegacyMode, NULL, NULL); | |
+ ASSERT_EFI_ERROR (Status); | |
+ | |
+ // | |
+ // Call the real mode thunk code | |
+ // | |
+ TempData = BiosInt * 4; | |
+ Address = (UINTN *) TempData; | |
+ IaOffset = 0xFFFF & (*Address); | |
+ IaSegment = 0xFFFF & ((*Address) >> 16); | |
+ | |
+ Status = BiosIntCall ( | |
+ BiosInt, | |
+ (UINT16) IaSegment, | |
+ (UINT16) IaOffset, | |
+ (EFI_IA32_REGISTER_SET *) Stack16, | |
+ IntThunk, | |
+ IntThunk->LowStack | |
+ ); | |
+ | |
+ // | |
+ // Check for errors with the thunk | |
+ // | |
+ switch (Status) { | |
+ case THUNK_OK: | |
+ break; | |
+ | |
+ case THUNK_ERR_A20_UNSUP: | |
+ case THUNK_ERR_A20_FAILED: | |
+ default: | |
+ // | |
+ // For all errors, set EFLAGS.CF (used by legacy BIOS to indicate error). | |
+ // | |
+ Regs->X.Flags.CF = 1; | |
+ break; | |
+ } | |
+ | |
+ Status = Private->Legacy8259->SetMode (Private->Legacy8259, Efi8259ProtectedMode, NULL, NULL); | |
+ ASSERT_EFI_ERROR (Status); | |
+ | |
+ // | |
+ // End critical section | |
+ // | |
+ gBS->RestoreTPL (OriginalTpl); | |
+ | |
+ // | |
+ // Return the resulting registers | |
+ // | |
+ CopyMem (Regs, Stack16, sizeof (EFI_IA32_REGISTER_SET)); | |
+ | |
+ return (BOOLEAN) (Regs->X.Flags.CF != 0); | |
+} | |
+ | |
+ | |
+/** | |
+ Thunk to 16-bit real mode and call Segment:Offset. Regs will contain the | |
+ 16-bit register context on entry and exit. Arguments can be passed on | |
+ the Stack argument | |
+ | |
+ @param This Protocol instance pointer. | |
+ @param Segment Segemnt of 16-bit mode call | |
+ @param Offset Offset of 16-bit mdoe call | |
+ @param Regs Register contexted passed into (and returned) from | |
+ thunk to 16-bit mode | |
+ @param Stack Caller allocated stack used to pass arguments | |
+ @param StackSize Size of Stack in bytes | |
+ | |
+ @retval FALSE Thunk completed, and there were no BIOS errors in the | |
+ target code. See Regs for status. | |
+ @retval TRUE There was a BIOS erro in the target code. | |
+ | |
+**/ | |
+BOOLEAN | |
+EFIAPI | |
+LegacyBiosFarCall86 ( | |
+ IN EFI_LEGACY_BIOS_PROTOCOL *This, | |
+ IN UINT16 Segment, | |
+ IN UINT16 Offset, | |
+ IN EFI_IA32_REGISTER_SET *Regs, | |
+ IN VOID *Stack, | |
+ IN UINTN StackSize | |
+ ) | |
+{ | |
+ EFI_STATUS Status; | |
+ LEGACY_BIOS_INSTANCE *Private; | |
+ LOW_MEMORY_THUNK *IntThunk; | |
+ UINT16 *Stack16; | |
+ EFI_TPL OriginalTpl; | |
+ UINTN IaSegment; | |
+ UINTN IaOffset; | |
+ UINTN TempData; | |
+ | |
+ Private = LEGACY_BIOS_INSTANCE_FROM_THIS (This); | |
+ IntThunk = Private->IntThunk; | |
+ IaSegment = Segment; | |
+ IaOffset = Offset; | |
+ | |
+ // | |
+ // Get the current flat GDT and IDT and store them in Private->IntThunk. | |
+ // | |
+ Status = LegacyBiosGetFlatDescs (Private); | |
+ ASSERT_EFI_ERROR (Status); | |
+ | |
+ Regs->X.Flags.Reserved1 = 1; | |
+ Regs->X.Flags.Reserved2 = 0; | |
+ Regs->X.Flags.Reserved3 = 0; | |
+ Regs->X.Flags.Reserved4 = 0; | |
+ Regs->X.Flags.IOPL = 3; | |
+ Regs->X.Flags.NT = 0; | |
+ Regs->X.Flags.IF = 1; | |
+ Regs->X.Flags.TF = 0; | |
+ Regs->X.Flags.CF = 0; | |
+ // | |
+ // Clear the error flag; thunk code may set it. | |
+ // | |
+ Stack16 = (UINT16 *) (IntThunk->Stack + LOW_STACK_SIZE); | |
+ if (Stack != NULL && StackSize != 0) { | |
+ // | |
+ // Copy Stack to low memory stack | |
+ // | |
+ Stack16 -= StackSize / sizeof (UINT16); | |
+ CopyMem (Stack16, Stack, StackSize); | |
+ } | |
+ // | |
+ // Copy regs to low memory stack | |
+ // | |
+ Stack16 -= sizeof (EFI_IA32_REGISTER_SET) / sizeof (UINT16); | |
+ CopyMem (Stack16, Regs, sizeof (EFI_IA32_REGISTER_SET)); | |
+ | |
+ // | |
+ // Provide low stack esp | |
+ // | |
+ TempData = ((UINTN) Stack16) - ((UINTN) IntThunk); | |
+ IntThunk->LowStack = *((UINT32 *) &TempData); | |
+ | |
+ // | |
+ // The call to Legacy16 is a critical section to EFI | |
+ // | |
+ OriginalTpl = gBS->RaiseTPL (TPL_HIGH_LEVEL); | |
+ | |
+ // | |
+ // Set Legacy16 state. 0x08, 0x70 is legacy 8259 vector bases. | |
+ // | |
+ Status = Private->Legacy8259->SetMode (Private->Legacy8259, Efi8259LegacyMode, NULL, NULL); | |
+ ASSERT_EFI_ERROR (Status); | |
+ | |
+ // | |
+ // Call the real mode thunk code | |
+ // | |
+ Status = BiosIntCall ( | |
+ 0x100, | |
+ (UINT16) IaSegment, | |
+ (UINT16) IaOffset, | |
+ (EFI_IA32_REGISTER_SET *) Stack16, | |
+ IntThunk, | |
+ IntThunk->LowStack | |
+ ); | |
+ | |
+ // | |
+ // Check for errors with the thunk | |
+ // | |
+ switch (Status) { | |
+ case THUNK_OK: | |
+ break; | |
+ | |
+ case THUNK_ERR_A20_UNSUP: | |
+ case THUNK_ERR_A20_FAILED: | |
+ default: | |
+ // | |
+ // For all errors, set EFLAGS.CF (used by legacy BIOS to indicate error). | |
+ // | |
+ Regs->X.Flags.CF = 1; | |
+ break; | |
+ } | |
+ // | |
+ // Restore protected mode interrupt state | |
+ // | |
+ Status = Private->Legacy8259->SetMode (Private->Legacy8259, Efi8259ProtectedMode, NULL, NULL); | |
+ ASSERT_EFI_ERROR (Status); | |
+ | |
+ // | |
+ // End critical section | |
+ // | |
+ gBS->RestoreTPL (OriginalTpl); | |
+ | |
+ // | |
+ // Return the resulting registers | |
+ // | |
+ CopyMem (Regs, Stack16, sizeof (EFI_IA32_REGISTER_SET)); | |
+ Stack16 += sizeof (EFI_IA32_REGISTER_SET) / sizeof (UINT16); | |
+ | |
+ if (Stack != NULL && StackSize != 0) { | |
+ // | |
+ // Copy low memory stack to Stack | |
+ // | |
+ CopyMem (Stack, Stack16, StackSize); | |
+ Stack16 += StackSize / sizeof (UINT16); | |
+ } | |
+ | |
+ return (BOOLEAN) (Regs->X.Flags.CF != 0); | |
+} | |
diff --git a/OvmfPkg/CsmOld/LegacyBiosDxe/LegacyBbs.c b/OvmfPkg/CsmOld/LegacyBiosDxe/LegacyBbs.c | |
new file mode 100644 | |
index 000000000000..41f380a89278 | |
--- /dev/null | |
+++ b/OvmfPkg/CsmOld/LegacyBiosDxe/LegacyBbs.c | |
@@ -0,0 +1,516 @@ | |
+/** @file | |
+ | |
+Copyright (c) 2006 - 2012, 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. | |
+ | |
+**/ | |
+ | |
+#include "LegacyBiosInterface.h" | |
+#include <IndustryStandard/Pci.h> | |
+ | |
+// Give floppy 3 states | |
+// FLOPPY_PRESENT_WITH_MEDIA = Floppy controller present and media is inserted | |
+// FLOPPY_NOT_PRESENT = No floppy controller present | |
+// FLOPPY_PRESENT_NO_MEDIA = Floppy controller present but no media inserted | |
+// | |
+#define FLOPPY_NOT_PRESENT 0 | |
+#define FLOPPY_PRESENT_WITH_MEDIA 1 | |
+#define FLOPPY_PRESENT_NO_MEDIA 2 | |
+ | |
+BBS_TABLE *mBbsTable; | |
+BOOLEAN mBbsTableDoneFlag = FALSE; | |
+BOOLEAN IsHaveMediaInFloppy = TRUE; | |
+ | |
+/** | |
+ Checks the state of the floppy and if media is inserted. | |
+ | |
+ This routine checks the state of the floppy and if media is inserted. | |
+ There are 3 cases: | |
+ No floppy present - Set BBS entry to ignore | |
+ Floppy present & no media - Set BBS entry to lowest priority. We cannot | |
+ set it to ignore since 16-bit CSM will | |
+ indicate no floppy and thus drive A: is | |
+ unusable. CSM-16 will not try floppy since | |
+ lowest priority and thus not incur boot | |
+ time penality. | |
+ Floppy present & media - Set BBS entry to some priority. | |
+ | |
+ @return State of floppy media | |
+ | |
+**/ | |
+UINT8 | |
+HasMediaInFloppy ( | |
+ VOID | |
+ ) | |
+{ | |
+ EFI_STATUS Status; | |
+ UINTN HandleCount; | |
+ EFI_HANDLE *HandleBuffer; | |
+ UINTN Index; | |
+ EFI_ISA_IO_PROTOCOL *IsaIo; | |
+ EFI_BLOCK_IO_PROTOCOL *BlkIo; | |
+ | |
+ HandleBuffer = NULL; | |
+ HandleCount = 0; | |
+ | |
+ gBS->LocateHandleBuffer ( | |
+ ByProtocol, | |
+ &gEfiIsaIoProtocolGuid, | |
+ NULL, | |
+ &HandleCount, | |
+ &HandleBuffer | |
+ ); | |
+ | |
+ // | |
+ // If don't find any ISA/IO protocol assume no floppy. Need for floppy | |
+ // free system | |
+ // | |
+ if (HandleCount == 0) { | |
+ return FLOPPY_NOT_PRESENT; | |
+ } | |
+ | |
+ ASSERT (HandleBuffer != NULL); | |
+ | |
+ for (Index = 0; Index < HandleCount; Index++) { | |
+ Status = gBS->HandleProtocol ( | |
+ HandleBuffer[Index], | |
+ &gEfiIsaIoProtocolGuid, | |
+ (VOID **) &IsaIo | |
+ ); | |
+ if (EFI_ERROR (Status)) { | |
+ continue; | |
+ } | |
+ | |
+ if (IsaIo->ResourceList->Device.HID != EISA_PNP_ID (0x604)) { | |
+ continue; | |
+ } | |
+ // | |
+ // Update blockio in case the floppy is inserted in during BdsTimeout | |
+ // | |
+ Status = gBS->DisconnectController (HandleBuffer[Index], NULL, NULL); | |
+ | |
+ if (EFI_ERROR (Status)) { | |
+ continue; | |
+ } | |
+ | |
+ Status = gBS->ConnectController (HandleBuffer[Index], NULL, NULL, TRUE); | |
+ | |
+ if (EFI_ERROR (Status)) { | |
+ continue; | |
+ } | |
+ | |
+ Status = gBS->HandleProtocol ( | |
+ HandleBuffer[Index], | |
+ &gEfiBlockIoProtocolGuid, | |
+ (VOID **) &BlkIo | |
+ ); | |
+ if (EFI_ERROR (Status)) { | |
+ continue; | |
+ } | |
+ | |
+ if (BlkIo->Media->MediaPresent) { | |
+ FreePool (HandleBuffer); | |
+ return FLOPPY_PRESENT_WITH_MEDIA; | |
+ } else { | |
+ FreePool (HandleBuffer); | |
+ return FLOPPY_PRESENT_NO_MEDIA; | |
+ } | |
+ } | |
+ | |
+ FreePool (HandleBuffer); | |
+ | |
+ return FLOPPY_NOT_PRESENT; | |
+ | |
+} | |
+ | |
+ | |
+/** | |
+ Complete build of BBS TABLE. | |
+ | |
+ @param Private Legacy BIOS Instance data | |
+ @param BbsTable BBS Table passed to 16-bit code | |
+ | |
+ @retval EFI_SUCCESS Removable media not present | |
+ | |
+**/ | |
+EFI_STATUS | |
+LegacyBiosBuildBbs ( | |
+ IN LEGACY_BIOS_INSTANCE *Private, | |
+ IN BBS_TABLE *BbsTable | |
+ ) | |
+{ | |
+ UINTN BbsIndex; | |
+ HDD_INFO *HddInfo; | |
+ UINTN HddIndex; | |
+ UINTN Index; | |
+ | |
+ // | |
+ // First entry is floppy. | |
+ // Next 2*MAX_IDE_CONTROLLER entries are for onboard IDE. | |
+ // Next n entries are filled in after each ROM is dispatched. | |
+ // Entry filled in if follow BBS spec. See LegacyPci.c | |
+ // Next entries are for non-BBS compliant ROMS. They are filled in by | |
+ // 16-bit code during Legacy16UpdateBbs invocation. Final BootPriority | |
+ // occurs after that invocation. | |
+ // | |
+ // Floppy | |
+ // Set default state. | |
+ // | |
+ IsHaveMediaInFloppy = HasMediaInFloppy (); | |
+ if (IsHaveMediaInFloppy == FLOPPY_PRESENT_WITH_MEDIA) { | |
+ BbsTable[0].BootPriority = BBS_UNPRIORITIZED_ENTRY; | |
+ } else { | |
+ if (IsHaveMediaInFloppy == FLOPPY_PRESENT_NO_MEDIA) { | |
+ BbsTable[0].BootPriority = BBS_LOWEST_PRIORITY; | |
+ } else { | |
+ BbsTable[0].BootPriority = BBS_IGNORE_ENTRY; | |
+ } | |
+ } | |
+ | |
+ BbsTable[0].Bus = 0xff; | |
+ BbsTable[0].Device = 0xff; | |
+ BbsTable[0].Function = 0xff; | |
+ BbsTable[0].DeviceType = BBS_FLOPPY; | |
+ BbsTable[0].Class = 01; | |
+ BbsTable[0].SubClass = 02; | |
+ BbsTable[0].StatusFlags.OldPosition = 0; | |
+ BbsTable[0].StatusFlags.Reserved1 = 0; | |
+ BbsTable[0].StatusFlags.Enabled = 0; | |
+ BbsTable[0].StatusFlags.Failed = 0; | |
+ BbsTable[0].StatusFlags.MediaPresent = 0; | |
+ BbsTable[0].StatusFlags.Reserved2 = 0; | |
+ | |
+ // | |
+ // Onboard HDD - Note Each HDD controller controls 2 drives | |
+ // Master & Slave | |
+ // | |
+ HddInfo = &Private->IntThunk->EfiToLegacy16BootTable.HddInfo[0]; | |
+ // | |
+ // Get IDE Drive Info | |
+ // | |
+ LegacyBiosBuildIdeData (Private, &HddInfo, 0); | |
+ | |
+ for (HddIndex = 0; HddIndex < MAX_IDE_CONTROLLER; HddIndex++) { | |
+ | |
+ BbsIndex = HddIndex * 2 + 1; | |
+ for (Index = 0; Index < 2; ++Index) { | |
+ | |
+ BbsTable[BbsIndex + Index].Bus = HddInfo[HddIndex].Bus; | |
+ BbsTable[BbsIndex + Index].Device = HddInfo[HddIndex].Device; | |
+ BbsTable[BbsIndex + Index].Function = HddInfo[HddIndex].Function; | |
+ BbsTable[BbsIndex + Index].Class = 01; | |
+ BbsTable[BbsIndex + Index].SubClass = 01; | |
+ BbsTable[BbsIndex + Index].StatusFlags.OldPosition = 0; | |
+ BbsTable[BbsIndex + Index].StatusFlags.Reserved1 = 0; | |
+ BbsTable[BbsIndex + Index].StatusFlags.Enabled = 0; | |
+ BbsTable[BbsIndex + Index].StatusFlags.Failed = 0; | |
+ BbsTable[BbsIndex + Index].StatusFlags.MediaPresent = 0; | |
+ BbsTable[BbsIndex + Index].StatusFlags.Reserved2 = 0; | |
+ | |
+ // | |
+ // If no controller found or no device found set to ignore | |
+ // else set to unprioritized and set device type | |
+ // | |
+ if (HddInfo[HddIndex].CommandBaseAddress == 0) { | |
+ BbsTable[BbsIndex + Index].BootPriority = BBS_IGNORE_ENTRY; | |
+ } else { | |
+ if (Index == 0) { | |
+ if ((HddInfo[HddIndex].Status & (HDD_MASTER_IDE | HDD_MASTER_ATAPI_CDROM | HDD_MASTER_ATAPI_ZIPDISK)) != 0) { | |
+ BbsTable[BbsIndex + Index].BootPriority = BBS_UNPRIORITIZED_ENTRY; | |
+ if ((HddInfo[HddIndex].Status & HDD_MASTER_IDE) != 0) { | |
+ BbsTable[BbsIndex + Index].DeviceType = BBS_HARDDISK; | |
+ } else if ((HddInfo[HddIndex].Status & HDD_MASTER_ATAPI_CDROM) != 0) { | |
+ BbsTable[BbsIndex + Index].DeviceType = BBS_CDROM; | |
+ } else { | |
+ // | |
+ // for ZIPDISK | |
+ // | |
+ BbsTable[BbsIndex + Index].DeviceType = BBS_HARDDISK; | |
+ } | |
+ } else { | |
+ BbsTable[BbsIndex + Index].BootPriority = BBS_IGNORE_ENTRY; | |
+ } | |
+ } else { | |
+ if ((HddInfo[HddIndex].Status & (HDD_SLAVE_IDE | HDD_SLAVE_ATAPI_CDROM | HDD_SLAVE_ATAPI_ZIPDISK)) != 0) { | |
+ BbsTable[BbsIndex + Index].BootPriority = BBS_UNPRIORITIZED_ENTRY; | |
+ if ((HddInfo[HddIndex].Status & HDD_SLAVE_IDE) != 0) { | |
+ BbsTable[BbsIndex + Index].DeviceType = BBS_HARDDISK; | |
+ } else if ((HddInfo[HddIndex].Status & HDD_SLAVE_ATAPI_CDROM) != 0) { | |
+ BbsTable[BbsIndex + Index].DeviceType = BBS_CDROM; | |
+ } else { | |
+ // | |
+ // for ZIPDISK | |
+ // | |
+ BbsTable[BbsIndex + Index].DeviceType = BBS_HARDDISK; | |
+ } | |
+ } else { | |
+ BbsTable[BbsIndex + Index].BootPriority = BBS_IGNORE_ENTRY; | |
+ } | |
+ } | |
+ } | |
+ } | |
+ } | |
+ | |
+ // | |
+ // add virtio-blk devices | |
+ // | |
+ { | |
+ EFI_STATUS Status; | |
+ UINTN NumPciIoHandles; | |
+ EFI_HANDLE *PciIoHandles; | |
+ | |
+ BbsIndex = HddIndex * 2 + 1; | |
+ | |
+ // | |
+ // scan all handles supporting the PCI IO protocol | |
+ // | |
+ Status = gBS->LocateHandleBuffer ( | |
+ ByProtocol, | |
+ &gEfiPciIoProtocolGuid, | |
+ NULL, | |
+ &NumPciIoHandles, | |
+ &PciIoHandles | |
+ ); | |
+ | |
+ if (Status == EFI_SUCCESS) { | |
+ UINTN CurPciIo; | |
+ | |
+ for (CurPciIo = 0; CurPciIo < NumPciIoHandles; ++CurPciIo) { | |
+ EFI_OPEN_PROTOCOL_INFORMATION_ENTRY *References; | |
+ UINTN NumReferences; | |
+ UINTN CurRef; | |
+ | |
+ // | |
+ // on each handle supporting the PCI IO protocol, see which drivers | |
+ // (agents) have a PCI IO protocol interface actually opened | |
+ // | |
+ Status = gBS->OpenProtocolInformation ( | |
+ PciIoHandles[CurPciIo], | |
+ &gEfiPciIoProtocolGuid, | |
+ &References, | |
+ &NumReferences | |
+ ); | |
+ if (EFI_ERROR (Status)) { | |
+ continue; | |
+ } | |
+ | |
+ for (CurRef = 0; CurRef < NumReferences; ++CurRef) { | |
+ if (References[CurRef].Attributes & EFI_OPEN_PROTOCOL_BY_DRIVER) { | |
+ EFI_COMPONENT_NAME2_PROTOCOL *ComponentName; | |
+ CHAR16 *DriverName; | |
+ | |
+ // | |
+ // OpenProtocol() enforced non-NULL AgentHandle for this case | |
+ // | |
+ ASSERT (References[CurRef].AgentHandle != NULL); | |
+ | |
+ // | |
+ // Check if the agent owning the open protocol interface can | |
+ // provide its name, and if so, whether it's VirtioBlkDxe. For this | |
+ // check we don't want a persistent reference to the agent's | |
+ // EFI_COMPONENT_NAME2_PROTOCOL instance, therefore we use | |
+ // HandleProtocol() instead of OpenProtocol(). | |
+ // | |
+ Status = gBS->HandleProtocol ( | |
+ References[CurRef].AgentHandle, | |
+ &gEfiComponentName2ProtocolGuid, | |
+ (VOID **) &ComponentName | |
+ ); | |
+ if (EFI_ERROR (Status)) { | |
+ continue; | |
+ } | |
+ | |
+ Status = ComponentName->GetDriverName ( | |
+ ComponentName, | |
+ "en", | |
+ &DriverName | |
+ ); | |
+ | |
+ if (Status == EFI_SUCCESS && | |
+ StrCmp (DriverName, L"Virtio Block Driver") == 0) { | |
+ break; | |
+ } | |
+ } | |
+ } | |
+ | |
+ if (CurRef < NumReferences) { | |
+ EFI_PCI_IO_PROTOCOL *PciIo; | |
+ UINTN Segment; | |
+ UINTN Bus; | |
+ UINTN Device; | |
+ UINTN Function; | |
+ | |
+ // | |
+ // reference by VirtioBlkDxe found, produce boot entry for device | |
+ // | |
+ Status = gBS->HandleProtocol ( | |
+ PciIoHandles[CurPciIo], | |
+ &gEfiPciIoProtocolGuid, | |
+ (VOID **) &PciIo | |
+ ); | |
+ ASSERT (Status == EFI_SUCCESS); | |
+ | |
+ Status = PciIo->GetLocation ( | |
+ PciIo, | |
+ &Segment, | |
+ &Bus, | |
+ &Device, | |
+ &Function | |
+ ); | |
+ ASSERT (Status == EFI_SUCCESS); | |
+ | |
+ if (Segment == 0) { | |
+ BbsTable[BbsIndex].Bus = (UINT32) Bus; | |
+ BbsTable[BbsIndex].Device = (UINT32) Device; | |
+ BbsTable[BbsIndex].Function = (UINT32) Function; | |
+ BbsTable[BbsIndex].Class = 1; | |
+ BbsTable[BbsIndex].SubClass = 0x80; | |
+ BbsTable[BbsIndex].StatusFlags.OldPosition = 0; | |
+ BbsTable[BbsIndex].StatusFlags.Reserved1 = 0; | |
+ BbsTable[BbsIndex].StatusFlags.Enabled = 0; | |
+ BbsTable[BbsIndex].StatusFlags.Failed = 0; | |
+ BbsTable[BbsIndex].StatusFlags.MediaPresent = 0; | |
+ BbsTable[BbsIndex].StatusFlags.Reserved2 = 0; | |
+ BbsTable[BbsIndex].DeviceType = BBS_HARDDISK; | |
+ BbsTable[BbsIndex].BootPriority = BBS_UNPRIORITIZED_ENTRY; | |
+ ++BbsIndex; | |
+ } | |
+ } | |
+ | |
+ FreePool (References); | |
+ } | |
+ | |
+ FreePool (PciIoHandles); | |
+ } | |
+ } | |
+ | |
+ return EFI_SUCCESS; | |
+} | |
+ | |
+ | |
+/** | |
+ Get all BBS info | |
+ | |
+ @param This Protocol instance pointer. | |
+ @param HddCount Number of HDD_INFO structures | |
+ @param HddInfo Onboard IDE controller information | |
+ @param BbsCount Number of BBS_TABLE structures | |
+ @param BbsTable List BBS entries | |
+ | |
+ @retval EFI_SUCCESS Tables returned | |
+ @retval EFI_NOT_FOUND resource not found | |
+ @retval EFI_DEVICE_ERROR can not get BBS table | |
+ | |
+**/ | |
+EFI_STATUS | |
+EFIAPI | |
+LegacyBiosGetBbsInfo ( | |
+ IN EFI_LEGACY_BIOS_PROTOCOL *This, | |
+ OUT UINT16 *HddCount, | |
+ OUT HDD_INFO **HddInfo, | |
+ OUT UINT16 *BbsCount, | |
+ OUT BBS_TABLE **BbsTable | |
+ ) | |
+{ | |
+ LEGACY_BIOS_INSTANCE *Private; | |
+ EFI_IA32_REGISTER_SET Regs; | |
+ EFI_TO_COMPATIBILITY16_BOOT_TABLE *EfiToLegacy16BootTable; | |
+// HDD_INFO *LocalHddInfo; | |
+// IN BBS_TABLE *LocalBbsTable; | |
+ UINTN NumHandles; | |
+ EFI_HANDLE *HandleBuffer; | |
+ UINTN Index; | |
+ UINTN TempData; | |
+ UINT32 Granularity; | |
+ | |
+ HandleBuffer = NULL; | |
+ | |
+ Private = LEGACY_BIOS_INSTANCE_FROM_THIS (This); | |
+ EfiToLegacy16BootTable = &Private->IntThunk->EfiToLegacy16BootTable; | |
+// LocalHddInfo = EfiToLegacy16BootTable->HddInfo; | |
+// LocalBbsTable = (BBS_TABLE*)(UINTN)EfiToLegacy16BootTable->BbsTable; | |
+ | |
+ if (!mBbsTableDoneFlag) { | |
+ mBbsTable = Private->BbsTablePtr; | |
+ | |
+ // | |
+ // Always enable disk controllers so 16-bit CSM code has valid information for all | |
+ // drives. | |
+ // | |
+ // | |
+ // Get PciRootBridgeIO protocol | |
+ // | |
+ gBS->LocateHandleBuffer ( | |
+ ByProtocol, | |
+ &gEfiPciRootBridgeIoProtocolGuid, | |
+ NULL, | |
+ &NumHandles, | |
+ &HandleBuffer | |
+ ); | |
+ | |
+ if (NumHandles == 0) { | |
+ return EFI_NOT_FOUND; | |
+ } | |
+ | |
+ mBbsTableDoneFlag = TRUE; | |
+ for (Index = 0; Index < NumHandles; Index++) { | |
+ // | |
+ // Connect PciRootBridgeIO protocol handle with FALSE parameter to let | |
+ // PCI bus driver enumerate all subsequent handles | |
+ // | |
+ gBS->ConnectController (HandleBuffer[Index], NULL, NULL, FALSE); | |
+ | |
+ } | |
+ | |
+ LegacyBiosBuildBbs (Private, mBbsTable); | |
+ | |
+ Private->LegacyRegion->UnLock (Private->LegacyRegion, 0xe0000, 0x20000, &Granularity); | |
+ | |
+ // | |
+ // Call into Legacy16 code to add to BBS table for non BBS compliant OPROMs. | |
+ // | |
+ ZeroMem (&Regs, sizeof (EFI_IA32_REGISTER_SET)); | |
+ Regs.X.AX = Legacy16UpdateBbs; | |
+ | |
+ // | |
+ // Pass in handoff data | |
+ // | |
+ TempData = (UINTN) EfiToLegacy16BootTable; | |
+ Regs.X.ES = NORMALIZE_EFI_SEGMENT ((UINT32) TempData); | |
+ Regs.X.BX = NORMALIZE_EFI_OFFSET ((UINT32) TempData); | |
+ | |
+ Private->LegacyBios.FarCall86 ( | |
+ This, | |
+ Private->Legacy16CallSegment, | |
+ Private->Legacy16CallOffset, | |
+ &Regs, | |
+ NULL, | |
+ 0 | |
+ ); | |
+ | |
+ Private->Cpu->FlushDataCache (Private->Cpu, 0xE0000, 0x20000, EfiCpuFlushTypeWriteBackInvalidate); | |
+ Private->LegacyRegion->Lock (Private->LegacyRegion, 0xe0000, 0x20000, &Granularity); | |
+ | |
+ if (Regs.X.AX != 0) { | |
+ return EFI_DEVICE_ERROR; | |
+ } | |
+ } | |
+ | |
+ if (HandleBuffer != NULL) { | |
+ FreePool (HandleBuffer); | |
+ } | |
+ | |
+ *HddCount = MAX_IDE_CONTROLLER; | |
+ *HddInfo = EfiToLegacy16BootTable->HddInfo; | |
+ *BbsTable = (BBS_TABLE*)(UINTN)EfiToLegacy16BootTable->BbsTable; | |
+ *BbsCount = (UINT16) (sizeof (Private->IntThunk->BbsTable) / sizeof (BBS_TABLE)); | |
+ return EFI_SUCCESS; | |
+} | |
diff --git a/OvmfPkg/CsmOld/LegacyBiosDxe/LegacyBda.c b/OvmfPkg/CsmOld/LegacyBiosDxe/LegacyBda.c | |
new file mode 100644 | |
index 000000000000..c45d5d4c3e14 | |
--- /dev/null | |
+++ b/OvmfPkg/CsmOld/LegacyBiosDxe/LegacyBda.c | |
@@ -0,0 +1,66 @@ | |
+/** @file | |
+ This code fills in BDA (0x400) and EBDA (pointed to by 0x4xx) | |
+ information. There is support for doing initializeation before | |
+ Legacy16 is loaded and before a legacy boot is attempted. | |
+ | |
+Copyright (c) 2006 - 2010, 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. | |
+ | |
+**/ | |
+ | |
+#include "LegacyBiosInterface.h" | |
+ | |
+/** | |
+ Fill in the standard BDA and EBDA stuff before Legacy16 load | |
+ | |
+ @param Private Legacy BIOS Instance data | |
+ | |
+ @retval EFI_SUCCESS It should always work. | |
+ | |
+**/ | |
+EFI_STATUS | |
+LegacyBiosInitBda ( | |
+ IN LEGACY_BIOS_INSTANCE *Private | |
+ ) | |
+{ | |
+ BDA_STRUC *Bda; | |
+ UINT8 *Ebda; | |
+ | |
+ Bda = (BDA_STRUC *) ((UINTN) 0x400); | |
+ Ebda = (UINT8 *) ((UINTN) 0x9fc00); | |
+ | |
+ ZeroMem (Bda, 0x100); | |
+ ZeroMem (Ebda, 0x400); | |
+ // | |
+ // 640k-1k for EBDA | |
+ // | |
+ Bda->MemSize = 0x27f; | |
+ Bda->KeyHead = 0x1e; | |
+ Bda->KeyTail = 0x1e; | |
+ Bda->FloppyData = 0x00; | |
+ Bda->FloppyTimeout = 0xff; | |
+ | |
+ Bda->KeyStart = 0x001E; | |
+ Bda->KeyEnd = 0x003E; | |
+ Bda->KeyboardStatus = 0x10; | |
+ Bda->Ebda = 0x9fc0; | |
+ | |
+ // | |
+ // Move LPT time out here and zero out LPT4 since some SCSI OPROMS | |
+ // use this as scratch pad (LPT4 is Reserved) | |
+ // | |
+ Bda->Lpt1_2Timeout = 0x1414; | |
+ Bda->Lpt3_4Timeout = 0x1400; | |
+ | |
+ *Ebda = 0x01; | |
+ | |
+ return EFI_SUCCESS; | |
+} | |
diff --git a/OvmfPkg/CsmOld/LegacyBiosDxe/LegacyBios.c b/OvmfPkg/CsmOld/LegacyBiosDxe/LegacyBios.c | |
new file mode 100644 | |
index 000000000000..8c1426ce5af1 | |
--- /dev/null | |
+++ b/OvmfPkg/CsmOld/LegacyBiosDxe/LegacyBios.c | |
@@ -0,0 +1,1154 @@ | |
+/** @file | |
+ | |
+Copyright (c) 2006 - 2013, 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. | |
+ | |
+**/ | |
+ | |
+#include "LegacyBiosInterface.h" | |
+ | |
+#define PHYSICAL_ADDRESS_TO_POINTER(Address) ((VOID *) ((UINTN) Address)) | |
+ | |
+// | |
+// define maximum number of HDD system supports | |
+// | |
+#define MAX_HDD_ENTRIES 0x30 | |
+ | |
+// | |
+// Module Global: | |
+// Since this driver will only ever produce one instance of the Private Data | |
+// protocol you are not required to dynamically allocate the PrivateData. | |
+// | |
+LEGACY_BIOS_INSTANCE mPrivateData; | |
+ | |
+// | |
+// The SMBIOS table in EfiRuntimeServicesData memory | |
+// | |
+VOID *mRuntimeSmbiosEntryPoint = NULL; | |
+ | |
+// | |
+// The SMBIOS table in EfiReservedMemoryType memory | |
+// | |
+EFI_PHYSICAL_ADDRESS mReserveSmbiosEntryPoint = 0; | |
+EFI_PHYSICAL_ADDRESS mStructureTableAddress = 0; | |
+UINTN mStructureTablePages = 0; | |
+ | |
+/** | |
+ Do an AllocatePages () of type AllocateMaxAddress for EfiBootServicesCode | |
+ memory. | |
+ | |
+ @param AllocateType Allocated Legacy Memory Type | |
+ @param StartPageAddress Start address of range | |
+ @param Pages Number of pages to allocate | |
+ @param Result Result of allocation | |
+ | |
+ @retval EFI_SUCCESS Legacy16 code loaded | |
+ @retval Other No protocol installed, unload driver. | |
+ | |
+**/ | |
+EFI_STATUS | |
+AllocateLegacyMemory ( | |
+ IN EFI_ALLOCATE_TYPE AllocateType, | |
+ IN EFI_PHYSICAL_ADDRESS StartPageAddress, | |
+ IN UINTN Pages, | |
+ OUT EFI_PHYSICAL_ADDRESS *Result | |
+ ) | |
+{ | |
+ EFI_STATUS Status; | |
+ EFI_PHYSICAL_ADDRESS MemPage; | |
+ | |
+ // | |
+ // Allocate Pages of memory less <= StartPageAddress | |
+ // | |
+ MemPage = (EFI_PHYSICAL_ADDRESS) (UINTN) StartPageAddress; | |
+ Status = gBS->AllocatePages ( | |
+ AllocateType, | |
+ EfiBootServicesCode, | |
+ Pages, | |
+ &MemPage | |
+ ); | |
+ // | |
+ // Do not ASSERT on Status error but let caller decide since some cases | |
+ // memory is already taken but that is ok. | |
+ // | |
+ if (!EFI_ERROR (Status)) { | |
+ *Result = (EFI_PHYSICAL_ADDRESS) (UINTN) MemPage; | |
+ } | |
+ // | |
+ // If reach here the status = EFI_SUCCESS | |
+ // | |
+ return Status; | |
+} | |
+ | |
+ | |
+/** | |
+ This function is called when EFI needs to reserve an area in the 0xE0000 or 0xF0000 | |
+ 64 KB blocks. | |
+ | |
+ Note: inconsistency with the Framework CSM spec. Per the spec, this function may be | |
+ invoked only once. This limitation is relaxed to allow multiple calls in this implemenation. | |
+ | |
+ @param This Protocol instance pointer. | |
+ @param LegacyMemorySize Size of required region | |
+ @param Region Region to use. 00 = Either 0xE0000 or 0xF0000 | |
+ block Bit0 = 1 0xF0000 block Bit1 = 1 0xE0000 | |
+ block | |
+ @param Alignment Address alignment. Bit mapped. First non-zero | |
+ bit from right is alignment. | |
+ @param LegacyMemoryAddress Region Assigned | |
+ | |
+ @retval EFI_SUCCESS Region assigned | |
+ @retval EFI_ACCESS_DENIED Procedure previously invoked | |
+ @retval Other Region not assigned | |
+ | |
+**/ | |
+EFI_STATUS | |
+EFIAPI | |
+LegacyBiosGetLegacyRegion ( | |
+ IN EFI_LEGACY_BIOS_PROTOCOL *This, | |
+ IN UINTN LegacyMemorySize, | |
+ IN UINTN Region, | |
+ IN UINTN Alignment, | |
+ OUT VOID **LegacyMemoryAddress | |
+ ) | |
+{ | |
+ | |
+ LEGACY_BIOS_INSTANCE *Private; | |
+ EFI_IA32_REGISTER_SET Regs; | |
+ EFI_STATUS Status; | |
+ UINT32 Granularity; | |
+ | |
+ Private = LEGACY_BIOS_INSTANCE_FROM_THIS (This); | |
+ Private->LegacyRegion->UnLock (Private->LegacyRegion, 0xE0000, 0x20000, &Granularity); | |
+ | |
+ ZeroMem (&Regs, sizeof (EFI_IA32_REGISTER_SET)); | |
+ Regs.X.AX = Legacy16GetTableAddress; | |
+ Regs.X.BX = (UINT16) Region; | |
+ Regs.X.CX = (UINT16) LegacyMemorySize; | |
+ Regs.X.DX = (UINT16) Alignment; | |
+ Private->LegacyBios.FarCall86 ( | |
+ &Private->LegacyBios, | |
+ Private->Legacy16CallSegment, | |
+ Private->Legacy16CallOffset, | |
+ &Regs, | |
+ NULL, | |
+ 0 | |
+ ); | |
+ | |
+ if (Regs.X.AX == 0) { | |
+ *LegacyMemoryAddress = (VOID *) (UINTN) ((Regs.X.DS << 4) + Regs.X.BX); | |
+ Status = EFI_SUCCESS; | |
+ } else { | |
+ Status = EFI_OUT_OF_RESOURCES; | |
+ } | |
+ | |
+ Private->Cpu->FlushDataCache (Private->Cpu, 0xE0000, 0x20000, EfiCpuFlushTypeWriteBackInvalidate); | |
+ Private->LegacyRegion->Lock (Private->LegacyRegion, 0xE0000, 0x20000, &Granularity); | |
+ | |
+ return Status; | |
+} | |
+ | |
+ | |
+/** | |
+ This function is called when copying data to the region assigned by | |
+ EFI_LEGACY_BIOS_PROTOCOL.GetLegacyRegion(). | |
+ | |
+ @param This Protocol instance pointer. | |
+ @param LegacyMemorySize Size of data to copy | |
+ @param LegacyMemoryAddress Legacy Region destination address Note: must | |
+ be in region assigned by | |
+ LegacyBiosGetLegacyRegion | |
+ @param LegacyMemorySourceAddress Source of data | |
+ | |
+ @retval EFI_SUCCESS The data was copied successfully. | |
+ @retval EFI_ACCESS_DENIED Either the starting or ending address is out of bounds. | |
+**/ | |
+EFI_STATUS | |
+EFIAPI | |
+LegacyBiosCopyLegacyRegion ( | |
+ IN EFI_LEGACY_BIOS_PROTOCOL *This, | |
+ IN UINTN LegacyMemorySize, | |
+ IN VOID *LegacyMemoryAddress, | |
+ IN VOID *LegacyMemorySourceAddress | |
+ ) | |
+{ | |
+ | |
+ LEGACY_BIOS_INSTANCE *Private; | |
+ UINT32 Granularity; | |
+ | |
+ if ((LegacyMemoryAddress < (VOID *)(UINTN)0xE0000 ) || | |
+ ((UINTN) LegacyMemoryAddress + LegacyMemorySize > (UINTN) 0x100000) | |
+ ) { | |
+ return EFI_ACCESS_DENIED; | |
+ } | |
+ // | |
+ // There is no protection from writes over lapping if this function is | |
+ // called multiple times. | |
+ // | |
+ Private = LEGACY_BIOS_INSTANCE_FROM_THIS (This); | |
+ Private->LegacyRegion->UnLock (Private->LegacyRegion, 0xE0000, 0x20000, &Granularity); | |
+ CopyMem (LegacyMemoryAddress, LegacyMemorySourceAddress, LegacyMemorySize); | |
+ | |
+ Private->Cpu->FlushDataCache (Private->Cpu, 0xE0000, 0x20000, EfiCpuFlushTypeWriteBackInvalidate); | |
+ Private->LegacyRegion->Lock (Private->LegacyRegion, 0xE0000, 0x20000, &Granularity); | |
+ | |
+ return EFI_SUCCESS; | |
+} | |
+ | |
+ | |
+/** | |
+ Find Legacy16 BIOS image in the FLASH device and shadow it into memory. Find | |
+ the $EFI table in the shadow area. Thunk into the Legacy16 code after it had | |
+ been shadowed. | |
+ | |
+ @param Private Legacy BIOS context data | |
+ | |
+ @retval EFI_SUCCESS Legacy16 code loaded | |
+ @retval Other No protocol installed, unload driver. | |
+ | |
+**/ | |
+EFI_STATUS | |
+ShadowAndStartLegacy16 ( | |
+ IN LEGACY_BIOS_INSTANCE *Private | |
+ ) | |
+{ | |
+ EFI_STATUS Status; | |
+ UINT8 *Ptr; | |
+ UINT8 *PtrEnd; | |
+ BOOLEAN Done; | |
+ EFI_COMPATIBILITY16_TABLE *Table; | |
+ UINT8 CheckSum; | |
+ EFI_IA32_REGISTER_SET Regs; | |
+ EFI_TO_COMPATIBILITY16_INIT_TABLE *EfiToLegacy16InitTable; | |
+ EFI_TO_COMPATIBILITY16_BOOT_TABLE *EfiToLegacy16BootTable; | |
+ VOID *LegacyBiosImage; | |
+ UINTN LegacyBiosImageSize; | |
+ UINTN E820Size; | |
+ UINT32 *ClearPtr; | |
+ BBS_TABLE *BbsTable; | |
+ LEGACY_EFI_HDD_TABLE *LegacyEfiHddTable; | |
+ UINTN Index; | |
+ UINT32 TpmPointer; | |
+ VOID *TpmBinaryImage; | |
+ UINTN TpmBinaryImageSize; | |
+ UINTN Location; | |
+ UINTN Alignment; | |
+ UINTN TempData; | |
+ EFI_PHYSICAL_ADDRESS Address; | |
+ UINT16 OldMask; | |
+ UINT16 NewMask; | |
+ UINT32 Granularity; | |
+ EFI_GCD_MEMORY_SPACE_DESCRIPTOR Descriptor; | |
+ | |
+ Location = 0; | |
+ Alignment = 0; | |
+ | |
+ // | |
+ // we allocate the C/D/E/F segment as RT code so no one will use it any more. | |
+ // | |
+ Address = 0xC0000; | |
+ gDS->GetMemorySpaceDescriptor (Address, &Descriptor); | |
+ if (Descriptor.GcdMemoryType == EfiGcdMemoryTypeSystemMemory) { | |
+ // | |
+ // If it is already reserved, we should be safe, or else we allocate it. | |
+ // | |
+ Status = gBS->AllocatePages ( | |
+ AllocateAddress, | |
+ EfiRuntimeServicesCode, | |
+ 0x40000/EFI_PAGE_SIZE, | |
+ &Address | |
+ ); | |
+ if (EFI_ERROR (Status)) { | |
+ // | |
+ // Bugbug: need to figure out whether C/D/E/F segment should be marked as reserved memory. | |
+ // | |
+ DEBUG ((DEBUG_ERROR, "Failed to allocate the C/D/E/F segment Status = %r", Status)); | |
+ } | |
+ } | |
+ | |
+ // | |
+ // start testtest | |
+ // GetTimerValue (&Ticker); | |
+ // | |
+ // gRT->SetVariable (L"StartLegacy", | |
+ // &gEfiGlobalVariableGuid, | |
+ // EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS, | |
+ // sizeof (UINT64), | |
+ // (VOID *)&Ticker | |
+ // ); | |
+ // end testtest | |
+ // | |
+ EfiToLegacy16BootTable = &Private->IntThunk->EfiToLegacy16BootTable; | |
+ Status = Private->LegacyBiosPlatform->GetPlatformInfo ( | |
+ Private->LegacyBiosPlatform, | |
+ EfiGetPlatformBinarySystemRom, | |
+ &LegacyBiosImage, | |
+ &LegacyBiosImageSize, | |
+ &Location, | |
+ &Alignment, | |
+ 0, | |
+ 0 | |
+ ); | |
+ if (EFI_ERROR (Status)) { | |
+ return Status; | |
+ } | |
+ | |
+ Private->BiosStart = (UINT32) (0x100000 - LegacyBiosImageSize); | |
+ Private->OptionRom = 0xc0000; | |
+ Private->LegacyBiosImageSize = (UINT32) LegacyBiosImageSize; | |
+ | |
+ // | |
+ // Can only shadow into memory allocated for legacy useage. | |
+ // | |
+ ASSERT (Private->BiosStart > Private->OptionRom); | |
+ | |
+ // | |
+ // Shadow Legacy BIOS. Turn on memory and copy image | |
+ // | |
+ Private->LegacyRegion->UnLock (Private->LegacyRegion, 0xc0000, 0x40000, &Granularity); | |
+ | |
+ ClearPtr = (VOID *) ((UINTN) 0xc0000); | |
+ | |
+ // | |
+ // Initialize region from 0xc0000 to start of BIOS to all ffs. This allows unused | |
+ // regions to be used by EMM386 etc. | |
+ // | |
+ SetMem ((VOID *) ClearPtr, (UINTN) (0x40000 - LegacyBiosImageSize), 0xff); | |
+ | |
+ TempData = Private->BiosStart; | |
+ | |
+ CopyMem ( | |
+ (VOID *) TempData, | |
+ LegacyBiosImage, | |
+ (UINTN) LegacyBiosImageSize | |
+ ); | |
+ | |
+ Private->Cpu->FlushDataCache (Private->Cpu, 0xc0000, 0x40000, EfiCpuFlushTypeWriteBackInvalidate); | |
+ | |
+ // | |
+ // Search for Legacy16 table in Shadowed ROM | |
+ // | |
+ Done = FALSE; | |
+ Table = NULL; | |
+ for (Ptr = (UINT8 *) TempData; Ptr < (UINT8 *) ((UINTN) 0x100000) && !Done; Ptr += 0x10) { | |
+ if (*(UINT32 *) Ptr == SIGNATURE_32 ('I', 'F', 'E', '$')) { | |
+ Table = (EFI_COMPATIBILITY16_TABLE *) Ptr; | |
+ PtrEnd = Ptr + Table->TableLength; | |
+ for (CheckSum = 0; Ptr < PtrEnd; Ptr++) { | |
+ CheckSum = (UINT8) (CheckSum +*Ptr); | |
+ } | |
+ | |
+ Done = TRUE; | |
+ } | |
+ } | |
+ | |
+ if (Table == NULL) { | |
+ DEBUG ((EFI_D_ERROR, "No Legacy16 table found\n")); | |
+ return EFI_NOT_FOUND; | |
+ } | |
+ | |
+ if (!Done) { | |
+ // | |
+ // Legacy16 table header checksum error. | |
+ // | |
+ DEBUG ((EFI_D_ERROR, "Legacy16 table found with bad talbe header checksum\n")); | |
+ } | |
+ | |
+ // | |
+ // Remember location of the Legacy16 table | |
+ // | |
+ Private->Legacy16Table = Table; | |
+ Private->Legacy16CallSegment = Table->Compatibility16CallSegment; | |
+ Private->Legacy16CallOffset = Table->Compatibility16CallOffset; | |
+ EfiToLegacy16InitTable = &Private->IntThunk->EfiToLegacy16InitTable; | |
+ Private->Legacy16InitPtr = EfiToLegacy16InitTable; | |
+ Private->Legacy16BootPtr = &Private->IntThunk->EfiToLegacy16BootTable; | |
+ Private->InternalIrqRoutingTable = NULL; | |
+ Private->NumberIrqRoutingEntries = 0; | |
+ Private->BbsTablePtr = NULL; | |
+ Private->LegacyEfiHddTable = NULL; | |
+ Private->DiskEnd = 0; | |
+ Private->Disk4075 = 0; | |
+ Private->HddTablePtr = &Private->IntThunk->EfiToLegacy16BootTable.HddInfo; | |
+ Private->NumberHddControllers = MAX_IDE_CONTROLLER; | |
+ Private->Dump[0] = 'D'; | |
+ Private->Dump[1] = 'U'; | |
+ Private->Dump[2] = 'M'; | |
+ Private->Dump[3] = 'P'; | |
+ | |
+ ZeroMem ( | |
+ Private->Legacy16BootPtr, | |
+ sizeof (EFI_TO_COMPATIBILITY16_BOOT_TABLE) | |
+ ); | |
+ | |
+ // | |
+ // Store away a copy of the EFI System Table | |
+ // | |
+ Table->EfiSystemTable = (UINT32) (UINTN) gST; | |
+ | |
+ // | |
+ // IPF CSM integration -Bug | |
+ // | |
+ // Construct the Legacy16 boot memory map. This sets up number of | |
+ // E820 entries. | |
+ // | |
+ LegacyBiosBuildE820 (Private, &E820Size); | |
+ // | |
+ // Initialize BDA and EBDA standard values needed to load Legacy16 code | |
+ // | |
+ LegacyBiosInitBda (Private); | |
+ LegacyBiosInitCmos (Private); | |
+ | |
+ // | |
+ // All legacy interrupt should be masked when do initialization work from legacy 16 code. | |
+ // | |
+ Private->Legacy8259->GetMask(Private->Legacy8259, &OldMask, NULL, NULL, NULL); | |
+ NewMask = 0xFFFF; | |
+ Private->Legacy8259->SetMask(Private->Legacy8259, &NewMask, NULL, NULL, NULL); | |
+ | |
+ // | |
+ // Call into Legacy16 code to do an INIT | |
+ // | |
+ ZeroMem (&Regs, sizeof (EFI_IA32_REGISTER_SET)); | |
+ Regs.X.AX = Legacy16InitializeYourself; | |
+ Regs.X.ES = EFI_SEGMENT (*((UINT32 *) &EfiToLegacy16InitTable)); | |
+ Regs.X.BX = EFI_OFFSET (*((UINT32 *) &EfiToLegacy16InitTable)); | |
+ | |
+ Private->LegacyBios.FarCall86 ( | |
+ &Private->LegacyBios, | |
+ Table->Compatibility16CallSegment, | |
+ Table->Compatibility16CallOffset, | |
+ &Regs, | |
+ NULL, | |
+ 0 | |
+ ); | |
+ | |
+ // | |
+ // Restore original legacy interrupt mask value | |
+ // | |
+ Private->Legacy8259->SetMask(Private->Legacy8259, &OldMask, NULL, NULL, NULL); | |
+ | |
+ if (Regs.X.AX != 0) { | |
+ return EFI_DEVICE_ERROR; | |
+ } | |
+ | |
+ // | |
+ // start testtest | |
+ // GetTimerValue (&Ticker); | |
+ // | |
+ // gRT->SetVariable (L"BackFromInitYourself", | |
+ // &gEfiGlobalVariableGuid, | |
+ // EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS, | |
+ // sizeof (UINT64), | |
+ // (VOID *)&Ticker | |
+ // ); | |
+ // end testtest | |
+ // | |
+ // Copy E820 table after InitializeYourself is completed | |
+ // | |
+ ZeroMem (&Regs, sizeof (EFI_IA32_REGISTER_SET)); | |
+ Regs.X.AX = Legacy16GetTableAddress; | |
+ Regs.X.CX = (UINT16) E820Size; | |
+ Regs.X.DX = 1; | |
+ Private->LegacyBios.FarCall86 ( | |
+ &Private->LegacyBios, | |
+ Table->Compatibility16CallSegment, | |
+ Table->Compatibility16CallOffset, | |
+ &Regs, | |
+ NULL, | |
+ 0 | |
+ ); | |
+ | |
+ Table->E820Pointer = (UINT32) (Regs.X.DS * 16 + Regs.X.BX); | |
+ Table->E820Length = (UINT32) E820Size; | |
+ if (Regs.X.AX != 0) { | |
+ DEBUG ((EFI_D_ERROR, "Legacy16 E820 length insufficient\n")); | |
+ } else { | |
+ TempData = Table->E820Pointer; | |
+ CopyMem ((VOID *) TempData, Private->E820Table, E820Size); | |
+ } | |
+ // | |
+ // Get PnPInstallationCheck Info. | |
+ // | |
+ Private->PnPInstallationCheckSegment = Table->PnPInstallationCheckSegment; | |
+ Private->PnPInstallationCheckOffset = Table->PnPInstallationCheckOffset; | |
+ | |
+ // | |
+ // Check if PCI Express is supported. If yes, Save base address. | |
+ // | |
+ Status = Private->LegacyBiosPlatform->GetPlatformInfo ( | |
+ Private->LegacyBiosPlatform, | |
+ EfiGetPlatformPciExpressBase, | |
+ NULL, | |
+ NULL, | |
+ &Location, | |
+ &Alignment, | |
+ 0, | |
+ 0 | |
+ ); | |
+ if (!EFI_ERROR (Status)) { | |
+ Private->Legacy16Table->PciExpressBase = (UINT32)Location; | |
+ Location = 0; | |
+ } | |
+ // | |
+ // Check if TPM is supported. If yes get a region in E0000,F0000 to copy it | |
+ // into, copy it and update pointer to binary image. This needs to be | |
+ // done prior to any OPROM for security purposes. | |
+ // | |
+ Status = Private->LegacyBiosPlatform->GetPlatformInfo ( | |
+ Private->LegacyBiosPlatform, | |
+ EfiGetPlatformBinaryTpmBinary, | |
+ &TpmBinaryImage, | |
+ &TpmBinaryImageSize, | |
+ &Location, | |
+ &Alignment, | |
+ 0, | |
+ 0 | |
+ ); | |
+ if (!EFI_ERROR (Status)) { | |
+ | |
+ ZeroMem (&Regs, sizeof (EFI_IA32_REGISTER_SET)); | |
+ Regs.X.AX = Legacy16GetTableAddress; | |
+ Regs.X.CX = (UINT16) TpmBinaryImageSize; | |
+ Regs.X.DX = 1; | |
+ Private->LegacyBios.FarCall86 ( | |
+ &Private->LegacyBios, | |
+ Table->Compatibility16CallSegment, | |
+ Table->Compatibility16CallOffset, | |
+ &Regs, | |
+ NULL, | |
+ 0 | |
+ ); | |
+ | |
+ TpmPointer = (UINT32) (Regs.X.DS * 16 + Regs.X.BX); | |
+ if (Regs.X.AX != 0) { | |
+ DEBUG ((EFI_D_ERROR, "TPM cannot be loaded\n")); | |
+ } else { | |
+ CopyMem ((VOID *) (UINTN)TpmPointer, TpmBinaryImage, TpmBinaryImageSize); | |
+ Table->TpmSegment = Regs.X.DS; | |
+ Table->TpmOffset = Regs.X.BX; | |
+ | |
+ } | |
+ } | |
+ // | |
+ // Lock the Legacy BIOS region | |
+ // | |
+ Private->Cpu->FlushDataCache (Private->Cpu, Private->BiosStart, (UINT32) LegacyBiosImageSize, EfiCpuFlushTypeWriteBackInvalidate); | |
+ Private->LegacyRegion->Lock (Private->LegacyRegion, Private->BiosStart, (UINT32) LegacyBiosImageSize, &Granularity); | |
+ | |
+ // | |
+ // Get the BbsTable from LOW_MEMORY_THUNK | |
+ // | |
+ BbsTable = (BBS_TABLE *)(UINTN)Private->IntThunk->BbsTable; | |
+ ZeroMem ((VOID *)BbsTable, sizeof (Private->IntThunk->BbsTable)); | |
+ | |
+ EfiToLegacy16BootTable->BbsTable = (UINT32)(UINTN)BbsTable; | |
+ Private->BbsTablePtr = (VOID *) BbsTable; | |
+ // | |
+ // Skip Floppy and possible onboard IDE drives | |
+ // | |
+ EfiToLegacy16BootTable->NumberBbsEntries = sizeof(Private->IntThunk->BbsTable) / sizeof(BBS_TABLE); | |
+ | |
+ for (Index = 0; Index < (sizeof (Private->IntThunk->BbsTable) / sizeof (BBS_TABLE)); Index++) { | |
+ BbsTable[Index].BootPriority = BBS_IGNORE_ENTRY; | |
+ } | |
+ // | |
+ // Allocate space for Legacy HDD table | |
+ // | |
+ LegacyEfiHddTable = (LEGACY_EFI_HDD_TABLE *) AllocateZeroPool ((UINTN) MAX_HDD_ENTRIES * sizeof (LEGACY_EFI_HDD_TABLE)); | |
+ ASSERT (LegacyEfiHddTable); | |
+ | |
+ Private->LegacyEfiHddTable = LegacyEfiHddTable; | |
+ Private->LegacyEfiHddTableIndex = 0x00; | |
+ | |
+ // | |
+ // start testtest | |
+ // GetTimerValue (&Ticker); | |
+ // | |
+ // gRT->SetVariable (L"EndOfLoadFv", | |
+ // &gEfiGlobalVariableGuid, | |
+ // EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS, | |
+ // sizeof (UINT64), | |
+ // (VOID *)&Ticker | |
+ // ); | |
+ // end testtest | |
+ // | |
+ return EFI_SUCCESS; | |
+} | |
+ | |
+/** | |
+ Shadow all legacy16 OPROMs that haven't been shadowed. | |
+ Warning: Use this with caution. This routine disconnects all EFI | |
+ drivers. If used externally then caller must re-connect EFI | |
+ drivers. | |
+ | |
+ @param This Protocol instance pointer. | |
+ | |
+ @retval EFI_SUCCESS OPROMs shadowed | |
+ | |
+**/ | |
+EFI_STATUS | |
+EFIAPI | |
+LegacyBiosShadowAllLegacyOproms ( | |
+ IN EFI_LEGACY_BIOS_PROTOCOL *This | |
+ ) | |
+{ | |
+ LEGACY_BIOS_INSTANCE *Private; | |
+ | |
+ // | |
+ // EFI_LEGACY_BIOS_PLATFORM_PROTOCOL *LegacyBiosPlatform; | |
+ // EFI_LEGACY16_TABLE *Legacy16Table; | |
+ // | |
+ Private = LEGACY_BIOS_INSTANCE_FROM_THIS (This); | |
+ | |
+ // | |
+ // LegacyBiosPlatform = Private->LegacyBiosPlatform; | |
+ // Legacy16Table = Private->Legacy16Table; | |
+ // | |
+ // Shadow PCI ROMs. We must do this near the end since this will kick | |
+ // of Native EFI drivers that may be needed to collect info for Legacy16 | |
+ // | |
+ // WARNING: PciIo is gone after this call. | |
+ // | |
+ PciProgramAllInterruptLineRegisters (Private); | |
+ | |
+ PciShadowRoms (Private); | |
+ | |
+ // | |
+ // Shadow PXE base code, BIS etc. | |
+ // | |
+ // LegacyBiosPlatform->ShadowServiceRoms (LegacyBiosPlatform, | |
+ // &Private->OptionRom, | |
+ // Legacy16Table); | |
+ // | |
+ return EFI_SUCCESS; | |
+} | |
+ | |
+/** | |
+ Get the PCI BIOS interface version. | |
+ | |
+ @param Private Driver private data. | |
+ | |
+ @return The PCI interface version number in Binary Coded Decimal (BCD) format. | |
+ E.g.: 0x0210 indicates 2.10, 0x0300 indicates 3.00 | |
+ | |
+**/ | |
+UINT16 | |
+GetPciInterfaceVersion ( | |
+ IN LEGACY_BIOS_INSTANCE *Private | |
+ ) | |
+{ | |
+ EFI_IA32_REGISTER_SET Reg; | |
+ BOOLEAN ThunkFailed; | |
+ UINT16 PciInterfaceVersion; | |
+ | |
+ PciInterfaceVersion = 0; | |
+ | |
+ Reg.X.AX = 0xB101; | |
+ Reg.E.EDI = 0; | |
+ | |
+ ThunkFailed = Private->LegacyBios.Int86 (&Private->LegacyBios, 0x1A, &Reg); | |
+ if (!ThunkFailed) { | |
+ // | |
+ // From PCI Firmware 3.0 Specification: | |
+ // If the CARRY FLAG [CF] is cleared and AH is set to 00h, it is still necessary to examine the | |
+ // contents of [EDX] for the presence of the string "PCI" + (trailing space) to fully validate the | |
+ // presence of the PCI function set. [BX] will further indicate the version level, with enough | |
+ // granularity to allow for incremental changes in the code that don't affect the function interface. | |
+ // Version numbers are stored as Binary Coded Decimal (BCD) values. For example, Version 2.10 | |
+ // would be returned as a 02h in the [BH] registers and 10h in the [BL] registers. | |
+ // | |
+ if ((Reg.X.Flags.CF == 0) && (Reg.H.AH == 0) && (Reg.E.EDX == SIGNATURE_32 ('P', 'C', 'I', ' '))) { | |
+ PciInterfaceVersion = Reg.X.BX; | |
+ } | |
+ } | |
+ return PciInterfaceVersion; | |
+} | |
+ | |
+/** | |
+ Callback function to calculate SMBIOS table size, and allocate memory for SMBIOS table. | |
+ SMBIOS table will be copied into EfiReservedMemoryType memory in legacy boot path. | |
+ | |
+ @param Event Event whose notification function is being invoked. | |
+ @param Context The pointer to the notification function's context, | |
+ which is implementation-dependent. | |
+ | |
+**/ | |
+VOID | |
+EFIAPI | |
+InstallSmbiosEventCallback ( | |
+ IN EFI_EVENT Event, | |
+ IN VOID *Context | |
+ ) | |
+{ | |
+ EFI_STATUS Status; | |
+ SMBIOS_TABLE_ENTRY_POINT *EntryPointStructure; | |
+ | |
+ // | |
+ // Get SMBIOS table from EFI configuration table | |
+ // | |
+ Status = EfiGetSystemConfigurationTable ( | |
+ &gEfiSmbiosTableGuid, | |
+ &mRuntimeSmbiosEntryPoint | |
+ ); | |
+ if ((EFI_ERROR (Status)) || (mRuntimeSmbiosEntryPoint == NULL)) { | |
+ return; | |
+ } | |
+ | |
+ EntryPointStructure = (SMBIOS_TABLE_ENTRY_POINT *) mRuntimeSmbiosEntryPoint; | |
+ | |
+ // | |
+ // Allocate memory for SMBIOS Entry Point Structure. | |
+ // CSM framework spec requires SMBIOS table below 4GB in EFI_TO_COMPATIBILITY16_BOOT_TABLE. | |
+ // | |
+ if (mReserveSmbiosEntryPoint == 0) { | |
+ // | |
+ // Entrypoint structure with fixed size is allocated only once. | |
+ // | |
+ mReserveSmbiosEntryPoint = SIZE_4GB - 1; | |
+ Status = gBS->AllocatePages ( | |
+ AllocateMaxAddress, | |
+ EfiReservedMemoryType, | |
+ EFI_SIZE_TO_PAGES ((UINTN) (EntryPointStructure->EntryPointLength)), | |
+ &mReserveSmbiosEntryPoint | |
+ ); | |
+ if (EFI_ERROR (Status)) { | |
+ mReserveSmbiosEntryPoint = 0; | |
+ return; | |
+ } | |
+ DEBUG ((EFI_D_INFO, "Allocate memory for Smbios Entry Point Structure\n")); | |
+ } | |
+ | |
+ if ((mStructureTableAddress != 0) && | |
+ (mStructureTablePages < (UINTN) EFI_SIZE_TO_PAGES (EntryPointStructure->TableLength))) { | |
+ // | |
+ // If original buffer is not enough for the new SMBIOS table, free original buffer and re-allocate | |
+ // | |
+ gBS->FreePages (mStructureTableAddress, mStructureTablePages); | |
+ mStructureTableAddress = 0; | |
+ mStructureTablePages = 0; | |
+ DEBUG ((EFI_D_INFO, "Original size is not enough. Re-allocate the memory.\n")); | |
+ } | |
+ | |
+ if (mStructureTableAddress == 0) { | |
+ // | |
+ // Allocate reserved memory below 4GB. | |
+ // Smbios spec requires the structure table is below 4GB. | |
+ // | |
+ mStructureTableAddress = SIZE_4GB - 1; | |
+ mStructureTablePages = EFI_SIZE_TO_PAGES (EntryPointStructure->TableLength); | |
+ Status = gBS->AllocatePages ( | |
+ AllocateMaxAddress, | |
+ EfiReservedMemoryType, | |
+ mStructureTablePages, | |
+ &mStructureTableAddress | |
+ ); | |
+ if (EFI_ERROR (Status)) { | |
+ gBS->FreePages ( | |
+ mReserveSmbiosEntryPoint, | |
+ EFI_SIZE_TO_PAGES ((UINTN) (EntryPointStructure->EntryPointLength)) | |
+ ); | |
+ mReserveSmbiosEntryPoint = 0; | |
+ mStructureTableAddress = 0; | |
+ mStructureTablePages = 0; | |
+ return; | |
+ } | |
+ DEBUG ((EFI_D_INFO, "Allocate memory for Smbios Structure Table\n")); | |
+ } | |
+} | |
+ | |
+/** | |
+ Install Driver to produce Legacy BIOS protocol. | |
+ | |
+ @param ImageHandle Handle of driver image. | |
+ @param SystemTable Pointer to system table. | |
+ | |
+ @retval EFI_SUCCESS Legacy BIOS protocol installed | |
+ @retval No protocol installed, unload driver. | |
+ | |
+**/ | |
+EFI_STATUS | |
+EFIAPI | |
+LegacyBiosInstall ( | |
+ IN EFI_HANDLE ImageHandle, | |
+ IN EFI_SYSTEM_TABLE *SystemTable | |
+ ) | |
+{ | |
+ EFI_STATUS Status; | |
+ LEGACY_BIOS_INSTANCE *Private; | |
+ EFI_TO_COMPATIBILITY16_INIT_TABLE *EfiToLegacy16InitTable; | |
+ EFI_PHYSICAL_ADDRESS MemoryAddress; | |
+ EFI_PHYSICAL_ADDRESS EbdaReservedBaseAddress; | |
+ VOID *MemoryPtr; | |
+ EFI_PHYSICAL_ADDRESS MemoryAddressUnder1MB; | |
+ UINTN Index; | |
+ UINT32 *BaseVectorMaster; | |
+ EFI_PHYSICAL_ADDRESS StartAddress; | |
+ UINT32 *ClearPtr; | |
+ EFI_PHYSICAL_ADDRESS MemStart; | |
+ UINT32 IntRedirCode; | |
+ UINT32 Granularity; | |
+ BOOLEAN DecodeOn; | |
+ UINT32 MemorySize; | |
+ EFI_GCD_MEMORY_SPACE_DESCRIPTOR Descriptor; | |
+ UINT64 Length; | |
+ UINT8 *SecureBoot; | |
+ EFI_EVENT InstallSmbiosEvent; | |
+ | |
+ // | |
+ // Load this driver's image to memory | |
+ // | |
+ Status = RelocateImageUnder4GIfNeeded (ImageHandle, SystemTable); | |
+ if (EFI_ERROR (Status)) { | |
+ return Status; | |
+ } | |
+ | |
+ // | |
+ // When UEFI Secure Boot is enabled, CSM module will not start any more. | |
+ // | |
+ SecureBoot = NULL; | |
+ GetEfiGlobalVariable2 (EFI_SECURE_BOOT_MODE_NAME, (VOID**)&SecureBoot, NULL); | |
+ if ((SecureBoot != NULL) && (*SecureBoot == SECURE_BOOT_MODE_ENABLE)) { | |
+ FreePool (SecureBoot); | |
+ return EFI_SECURITY_VIOLATION; | |
+ } | |
+ | |
+ if (SecureBoot != NULL) { | |
+ FreePool (SecureBoot); | |
+ } | |
+ | |
+ Private = &mPrivateData; | |
+ ZeroMem (Private, sizeof (LEGACY_BIOS_INSTANCE)); | |
+ | |
+ // | |
+ // Grab a copy of all the protocols we depend on. Any error would | |
+ // be a dispatcher bug!. | |
+ // | |
+ Status = gBS->LocateProtocol (&gEfiCpuArchProtocolGuid, NULL, (VOID **) &Private->Cpu); | |
+ ASSERT_EFI_ERROR (Status); | |
+ | |
+ Status = gBS->LocateProtocol (&gEfiTimerArchProtocolGuid, NULL, (VOID **) &Private->Timer); | |
+ ASSERT_EFI_ERROR (Status); | |
+ | |
+ Status = gBS->LocateProtocol (&gEfiLegacyRegion2ProtocolGuid, NULL, (VOID **) &Private->LegacyRegion); | |
+ ASSERT_EFI_ERROR (Status); | |
+ | |
+ Status = gBS->LocateProtocol (&gEfiLegacyBiosPlatformProtocolGuid, NULL, (VOID **) &Private->LegacyBiosPlatform); | |
+ ASSERT_EFI_ERROR (Status); | |
+ | |
+ Status = gBS->LocateProtocol (&gEfiLegacy8259ProtocolGuid, NULL, (VOID **) &Private->Legacy8259); | |
+ ASSERT_EFI_ERROR (Status); | |
+ | |
+ Status = gBS->LocateProtocol (&gEfiLegacyInterruptProtocolGuid, NULL, (VOID **) &Private->LegacyInterrupt); | |
+ ASSERT_EFI_ERROR (Status); | |
+ | |
+ // | |
+ // Locate Memory Test Protocol if exists | |
+ // | |
+ Status = gBS->LocateProtocol ( | |
+ &gEfiGenericMemTestProtocolGuid, | |
+ NULL, | |
+ (VOID **) &Private->GenericMemoryTest | |
+ ); | |
+ ASSERT_EFI_ERROR (Status); | |
+ | |
+ // | |
+ // Make sure all memory from 0-640K is tested | |
+ // | |
+ for (StartAddress = 0; StartAddress < 0xa0000; ) { | |
+ gDS->GetMemorySpaceDescriptor (StartAddress, &Descriptor); | |
+ if (Descriptor.GcdMemoryType != EfiGcdMemoryTypeReserved) { | |
+ StartAddress = Descriptor.BaseAddress + Descriptor.Length; | |
+ continue; | |
+ } | |
+ Length = MIN (Descriptor.Length, 0xa0000 - StartAddress); | |
+ Private->GenericMemoryTest->CompatibleRangeTest ( | |
+ Private->GenericMemoryTest, | |
+ StartAddress, | |
+ Length | |
+ ); | |
+ StartAddress = StartAddress + Length; | |
+ } | |
+ // | |
+ // Make sure all memory from 1MB to 16MB is tested and added to memory map | |
+ // | |
+ for (StartAddress = BASE_1MB; StartAddress < BASE_16MB; ) { | |
+ gDS->GetMemorySpaceDescriptor (StartAddress, &Descriptor); | |
+ if (Descriptor.GcdMemoryType != EfiGcdMemoryTypeReserved) { | |
+ StartAddress = Descriptor.BaseAddress + Descriptor.Length; | |
+ continue; | |
+ } | |
+ Length = MIN (Descriptor.Length, BASE_16MB - StartAddress); | |
+ Private->GenericMemoryTest->CompatibleRangeTest ( | |
+ Private->GenericMemoryTest, | |
+ StartAddress, | |
+ Length | |
+ ); | |
+ StartAddress = StartAddress + Length; | |
+ } | |
+ | |
+ Private->Signature = LEGACY_BIOS_INSTANCE_SIGNATURE; | |
+ | |
+ Private->LegacyBios.Int86 = LegacyBiosInt86; | |
+ Private->LegacyBios.FarCall86 = LegacyBiosFarCall86; | |
+ Private->LegacyBios.CheckPciRom = LegacyBiosCheckPciRom; | |
+ Private->LegacyBios.InstallPciRom = LegacyBiosInstallPciRom; | |
+ Private->LegacyBios.LegacyBoot = LegacyBiosLegacyBoot; | |
+ Private->LegacyBios.UpdateKeyboardLedStatus = LegacyBiosUpdateKeyboardLedStatus; | |
+ Private->LegacyBios.GetBbsInfo = LegacyBiosGetBbsInfo; | |
+ Private->LegacyBios.ShadowAllLegacyOproms = LegacyBiosShadowAllLegacyOproms; | |
+ Private->LegacyBios.PrepareToBootEfi = LegacyBiosPrepareToBootEfi; | |
+ Private->LegacyBios.GetLegacyRegion = LegacyBiosGetLegacyRegion; | |
+ Private->LegacyBios.CopyLegacyRegion = LegacyBiosCopyLegacyRegion; | |
+ Private->LegacyBios.BootUnconventionalDevice = LegacyBiosBootUnconventionalDevice; | |
+ | |
+ Private->ImageHandle = ImageHandle; | |
+ | |
+ // | |
+ // Enable read attribute of legacy region. | |
+ // | |
+ DecodeOn = TRUE; | |
+ Private->LegacyRegion->Decode ( | |
+ Private->LegacyRegion, | |
+ 0xc0000, | |
+ 0x40000, | |
+ &Granularity, | |
+ &DecodeOn | |
+ ); | |
+ // | |
+ // Set Cachebility for legacy region | |
+ // BUGBUG: Comments about this legacy region cacheability setting | |
+ // This setting will make D865GCHProduction CSM Unhappy | |
+ // | |
+ if (PcdGetBool (PcdLegacyBiosCacheLegacyRegion)) { | |
+ gDS->SetMemorySpaceAttributes ( | |
+ 0x0, | |
+ 0xA0000, | |
+ EFI_MEMORY_WB | |
+ ); | |
+ gDS->SetMemorySpaceAttributes ( | |
+ 0xc0000, | |
+ 0x40000, | |
+ EFI_MEMORY_WB | |
+ ); | |
+ } | |
+ | |
+ gDS->SetMemorySpaceAttributes ( | |
+ 0xA0000, | |
+ 0x20000, | |
+ EFI_MEMORY_UC | |
+ ); | |
+ | |
+ // | |
+ // Allocate 0 - 4K for real mode interupt vectors and BDA. | |
+ // | |
+ AllocateLegacyMemory ( | |
+ AllocateAddress, | |
+ 0, | |
+ 1, | |
+ &MemoryAddress | |
+ ); | |
+ ASSERT (MemoryAddress == 0x000000000); | |
+ | |
+ ClearPtr = (VOID *) ((UINTN) 0x0000); | |
+ | |
+ // | |
+ // Initialize region from 0x0000 to 4k. This initializes interrupt vector | |
+ // range. | |
+ // | |
+ gBS->SetMem ((VOID *) ClearPtr, 0x400, INITIAL_VALUE_BELOW_1K); | |
+ ZeroMem ((VOID *) ((UINTN)ClearPtr + 0x400), 0xC00); | |
+ | |
+ // | |
+ // Allocate pages for OPROM usage | |
+ // | |
+ MemorySize = PcdGet32 (PcdEbdaReservedMemorySize); | |
+ ASSERT ((MemorySize & 0xFFF) == 0); | |
+ | |
+ Status = AllocateLegacyMemory ( | |
+ AllocateAddress, | |
+ CONVENTIONAL_MEMORY_TOP - MemorySize, | |
+ EFI_SIZE_TO_PAGES (MemorySize), | |
+ &MemoryAddress | |
+ ); | |
+ ASSERT_EFI_ERROR (Status); | |
+ | |
+ ZeroMem ((VOID *) ((UINTN) MemoryAddress), MemorySize); | |
+ | |
+ // | |
+ // Allocate all 32k chunks from 0x60000 ~ 0x88000 for Legacy OPROMs that | |
+ // don't use PMM but look for zeroed memory. Note that various non-BBS | |
+ // OpROMs expect different areas to be free | |
+ // | |
+ EbdaReservedBaseAddress = MemoryAddress; | |
+ MemoryAddress = PcdGet32 (PcdOpromReservedMemoryBase); | |
+ MemorySize = PcdGet32 (PcdOpromReservedMemorySize); | |
+ // | |
+ // Check if base address and size for reserved memory are 4KB aligned. | |
+ // | |
+ ASSERT ((MemoryAddress & 0xFFF) == 0); | |
+ ASSERT ((MemorySize & 0xFFF) == 0); | |
+ // | |
+ // Check if the reserved memory is below EBDA reserved range. | |
+ // | |
+ ASSERT ((MemoryAddress < EbdaReservedBaseAddress) && ((MemoryAddress + MemorySize - 1) < EbdaReservedBaseAddress)); | |
+ for (MemStart = MemoryAddress; MemStart < MemoryAddress + MemorySize; MemStart += 0x1000) { | |
+ Status = AllocateLegacyMemory ( | |
+ AllocateAddress, | |
+ MemStart, | |
+ 1, | |
+ &StartAddress | |
+ ); | |
+ if (!EFI_ERROR (Status)) { | |
+ MemoryPtr = (VOID *) ((UINTN) StartAddress); | |
+ ZeroMem (MemoryPtr, 0x1000); | |
+ } else { | |
+ DEBUG ((EFI_D_ERROR, "WARNING: Allocate legacy memory fail for SCSI card - %x\n", MemStart)); | |
+ } | |
+ } | |
+ | |
+ // | |
+ // Allocate low PMM memory and zero it out | |
+ // | |
+ MemorySize = PcdGet32 (PcdLowPmmMemorySize); | |
+ ASSERT ((MemorySize & 0xFFF) == 0); | |
+ Status = AllocateLegacyMemory ( | |
+ AllocateMaxAddress, | |
+ CONVENTIONAL_MEMORY_TOP, | |
+ EFI_SIZE_TO_PAGES (MemorySize), | |
+ &MemoryAddressUnder1MB | |
+ ); | |
+ ASSERT_EFI_ERROR (Status); | |
+ | |
+ ZeroMem ((VOID *) ((UINTN) MemoryAddressUnder1MB), MemorySize); | |
+ | |
+ // | |
+ // Allocate space for thunker and Init Thunker | |
+ // | |
+ Status = AllocateLegacyMemory ( | |
+ AllocateMaxAddress, | |
+ CONVENTIONAL_MEMORY_TOP, | |
+ (sizeof (LOW_MEMORY_THUNK) / EFI_PAGE_SIZE) + 2, | |
+ &MemoryAddress | |
+ ); | |
+ ASSERT_EFI_ERROR (Status); | |
+ Private->IntThunk = (LOW_MEMORY_THUNK *) (UINTN) MemoryAddress; | |
+ EfiToLegacy16InitTable = &Private->IntThunk->EfiToLegacy16InitTable; | |
+ EfiToLegacy16InitTable->ThunkStart = (UINT32) (EFI_PHYSICAL_ADDRESS) (UINTN) MemoryAddress; | |
+ EfiToLegacy16InitTable->ThunkSizeInBytes = (UINT32) (sizeof (LOW_MEMORY_THUNK)); | |
+ | |
+ Status = LegacyBiosInitializeThunk (Private); | |
+ ASSERT_EFI_ERROR (Status); | |
+ | |
+ // | |
+ // Init the legacy memory map in memory < 1 MB. | |
+ // | |
+ EfiToLegacy16InitTable->BiosLessThan1MB = (UINT32) MemoryAddressUnder1MB; | |
+ EfiToLegacy16InitTable->LowPmmMemory = (UINT32) MemoryAddressUnder1MB; | |
+ EfiToLegacy16InitTable->LowPmmMemorySizeInBytes = MemorySize; | |
+ | |
+ MemorySize = PcdGet32 (PcdHighPmmMemorySize); | |
+ ASSERT ((MemorySize & 0xFFF) == 0); | |
+ // | |
+ // Allocate high PMM Memory under 16 MB | |
+ // | |
+ Status = AllocateLegacyMemory ( | |
+ AllocateMaxAddress, | |
+ 0x1000000, | |
+ EFI_SIZE_TO_PAGES (MemorySize), | |
+ &MemoryAddress | |
+ ); | |
+ if (EFI_ERROR (Status)) { | |
+ // | |
+ // If it fails, allocate high PMM Memory under 4GB | |
+ // | |
+ Status = AllocateLegacyMemory ( | |
+ AllocateMaxAddress, | |
+ 0xFFFFFFFF, | |
+ EFI_SIZE_TO_PAGES (MemorySize), | |
+ &MemoryAddress | |
+ ); | |
+ } | |
+ if (!EFI_ERROR (Status)) { | |
+ EfiToLegacy16InitTable->HiPmmMemory = (UINT32) (EFI_PHYSICAL_ADDRESS) (UINTN) MemoryAddress; | |
+ EfiToLegacy16InitTable->HiPmmMemorySizeInBytes = MemorySize; | |
+ } | |
+ | |
+ // | |
+ // ShutdownAPs(); | |
+ // | |
+ // Start the Legacy BIOS; | |
+ // | |
+ Status = ShadowAndStartLegacy16 (Private); | |
+ if (EFI_ERROR (Status)) { | |
+ return Status; | |
+ } | |
+ // | |
+ // Initialize interrupt redirection code and entries; | |
+ // IDT Vectors 0x68-0x6f must be redirected to IDT Vectors 0x08-0x0f. | |
+ // | |
+ CopyMem ( | |
+ Private->IntThunk->InterruptRedirectionCode, | |
+ (VOID *) (UINTN) InterruptRedirectionTemplate, | |
+ sizeof (Private->IntThunk->InterruptRedirectionCode) | |
+ ); | |
+ | |
+ // | |
+ // Save Unexpected interrupt vector so can restore it just prior to boot | |
+ // | |
+ BaseVectorMaster = (UINT32 *) (sizeof (UINT32) * PROTECTED_MODE_BASE_VECTOR_MASTER); | |
+ Private->BiosUnexpectedInt = BaseVectorMaster[0]; | |
+ IntRedirCode = (UINT32) (UINTN) Private->IntThunk->InterruptRedirectionCode; | |
+ for (Index = 0; Index < 8; Index++) { | |
+ BaseVectorMaster[Index] = (EFI_SEGMENT (IntRedirCode + Index * 4) << 16) | EFI_OFFSET (IntRedirCode + Index * 4); | |
+ } | |
+ // | |
+ // Save EFI value | |
+ // | |
+ Private->ThunkSeg = (UINT16) (EFI_SEGMENT (IntRedirCode)); | |
+ | |
+ // | |
+ // Allocate reserved memory for SMBIOS table used in legacy boot if SMBIOS table exists | |
+ // | |
+ InstallSmbiosEventCallback (NULL, NULL); | |
+ | |
+ // | |
+ // Create callback function to update the size of reserved memory after LegacyBiosDxe starts | |
+ // | |
+ Status = gBS->CreateEventEx ( | |
+ EVT_NOTIFY_SIGNAL, | |
+ TPL_NOTIFY, | |
+ InstallSmbiosEventCallback, | |
+ NULL, | |
+ &gEfiSmbiosTableGuid, | |
+ &InstallSmbiosEvent | |
+ ); | |
+ ASSERT_EFI_ERROR (Status); | |
+ | |
+ // | |
+ // Make a new handle and install the protocol | |
+ // | |
+ Private->Handle = NULL; | |
+ Status = gBS->InstallProtocolInterface ( | |
+ &Private->Handle, | |
+ &gEfiLegacyBiosProtocolGuid, | |
+ EFI_NATIVE_INTERFACE, | |
+ &Private->LegacyBios | |
+ ); | |
+ Private->Csm16PciInterfaceVersion = GetPciInterfaceVersion (Private); | |
+ | |
+ DEBUG ((EFI_D_INFO, "CSM16 PCI BIOS Interface Version: %02x.%02x\n", | |
+ (UINT8) (Private->Csm16PciInterfaceVersion >> 8), | |
+ (UINT8) Private->Csm16PciInterfaceVersion | |
+ )); | |
+ ASSERT (Private->Csm16PciInterfaceVersion != 0); | |
+ return Status; | |
+} | |
diff --git a/OvmfPkg/CsmOld/LegacyBiosDxe/LegacyBootSupport.c b/OvmfPkg/CsmOld/LegacyBiosDxe/LegacyBootSupport.c | |
new file mode 100644 | |
index 000000000000..9790fa5f4b02 | |
--- /dev/null | |
+++ b/OvmfPkg/CsmOld/LegacyBiosDxe/LegacyBootSupport.c | |
@@ -0,0 +1,2154 @@ | |
+/** @file | |
+ | |
+Copyright (c) 2006 - 2014, 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. | |
+ | |
+**/ | |
+ | |
+#include "LegacyBiosInterface.h" | |
+#include <IndustryStandard/Pci.h> | |
+ | |
+#define BOOT_LEGACY_OS 0 | |
+#define BOOT_EFI_OS 1 | |
+#define BOOT_UNCONVENTIONAL_DEVICE 2 | |
+ | |
+UINT32 mLoadOptionsSize = 0; | |
+UINTN mBootMode = BOOT_LEGACY_OS; | |
+VOID *mLoadOptions = NULL; | |
+BBS_BBS_DEVICE_PATH *mBbsDevicePathPtr = NULL; | |
+BBS_BBS_DEVICE_PATH mBbsDevicePathNode; | |
+UDC_ATTRIBUTES mAttributes = { 0, 0, 0, 0 }; | |
+UINTN mBbsEntry = 0; | |
+VOID *mBeerData = NULL; | |
+VOID *mServiceAreaData = NULL; | |
+UINT64 mLowWater = 0xffffffffffffffffULL; | |
+ | |
+extern BBS_TABLE *mBbsTable; | |
+ | |
+extern VOID *mRuntimeSmbiosEntryPoint; | |
+extern EFI_PHYSICAL_ADDRESS mReserveSmbiosEntryPoint; | |
+extern EFI_PHYSICAL_ADDRESS mStructureTableAddress; | |
+ | |
+/** | |
+ Print the BBS Table. | |
+ | |
+ @param BbsTable The BBS table. | |
+ | |
+ | |
+**/ | |
+VOID | |
+PrintBbsTable ( | |
+ IN BBS_TABLE *BbsTable | |
+ ) | |
+{ | |
+ UINT16 Index; | |
+ UINT16 SubIndex; | |
+ CHAR8 *String; | |
+ | |
+ DEBUG ((EFI_D_INFO, "\n")); | |
+ DEBUG ((EFI_D_INFO, " NO Prio bb/dd/ff cl/sc Type Stat segm:offs mfgs:mfgo dess:deso\n")); | |
+ DEBUG ((EFI_D_INFO, "=================================================================\n")); | |
+ for (Index = 0; Index < MAX_BBS_ENTRIES; Index++) { | |
+ // | |
+ // Filter | |
+ // | |
+ if (BbsTable[Index].BootPriority == BBS_IGNORE_ENTRY) { | |
+ continue; | |
+ } | |
+ | |
+ DEBUG (( | |
+ EFI_D_INFO, | |
+ " %02x: %04x %02x/%02x/%02x %02x/%02x %04x %04x", | |
+ (UINTN) Index, | |
+ (UINTN) BbsTable[Index].BootPriority, | |
+ (UINTN) BbsTable[Index].Bus, | |
+ (UINTN) BbsTable[Index].Device, | |
+ (UINTN) BbsTable[Index].Function, | |
+ (UINTN) BbsTable[Index].Class, | |
+ (UINTN) BbsTable[Index].SubClass, | |
+ (UINTN) BbsTable[Index].DeviceType, | |
+ (UINTN) * (UINT16 *) &BbsTable[Index].StatusFlags | |
+ )); | |
+ DEBUG (( | |
+ EFI_D_INFO, | |
+ " %04x:%04x %04x:%04x %04x:%04x", | |
+ (UINTN) BbsTable[Index].BootHandlerSegment, | |
+ (UINTN) BbsTable[Index].BootHandlerOffset, | |
+ (UINTN) BbsTable[Index].MfgStringSegment, | |
+ (UINTN) BbsTable[Index].MfgStringOffset, | |
+ (UINTN) BbsTable[Index].DescStringSegment, | |
+ (UINTN) BbsTable[Index].DescStringOffset | |
+ )); | |
+ | |
+ // | |
+ // Print DescString | |
+ // | |
+ String = (CHAR8 *)(UINTN)((BbsTable[Index].DescStringSegment << 4) + BbsTable[Index].DescStringOffset); | |
+ if (String != NULL) { | |
+ DEBUG ((EFI_D_INFO," (")); | |
+ for (SubIndex = 0; String[SubIndex] != 0; SubIndex++) { | |
+ DEBUG ((EFI_D_INFO, "%c", String[SubIndex])); | |
+ } | |
+ DEBUG ((EFI_D_INFO,")")); | |
+ } | |
+ DEBUG ((EFI_D_INFO,"\n")); | |
+ } | |
+ | |
+ DEBUG ((EFI_D_INFO, "\n")); | |
+ | |
+ return ; | |
+} | |
+ | |
+/** | |
+ Print the BBS Table. | |
+ | |
+ @param HddInfo The HddInfo table. | |
+ | |
+ | |
+**/ | |
+VOID | |
+PrintHddInfo ( | |
+ IN HDD_INFO *HddInfo | |
+ ) | |
+{ | |
+ UINTN Index; | |
+ | |
+ DEBUG ((EFI_D_INFO, "\n")); | |
+ for (Index = 0; Index < MAX_IDE_CONTROLLER; Index++) { | |
+ DEBUG ((EFI_D_INFO, "Index - %04x\n", Index)); | |
+ DEBUG ((EFI_D_INFO, " Status - %04x\n", (UINTN)HddInfo[Index].Status)); | |
+ DEBUG ((EFI_D_INFO, " B/D/F - %02x/%02x/%02x\n", (UINTN)HddInfo[Index].Bus, (UINTN)HddInfo[Index].Device, (UINTN)HddInfo[Index].Function)); | |
+ DEBUG ((EFI_D_INFO, " Command - %04x\n", HddInfo[Index].CommandBaseAddress)); | |
+ DEBUG ((EFI_D_INFO, " Control - %04x\n", HddInfo[Index].ControlBaseAddress)); | |
+ DEBUG ((EFI_D_INFO, " BusMaster - %04x\n", HddInfo[Index].BusMasterAddress)); | |
+ DEBUG ((EFI_D_INFO, " HddIrq - %02x\n", HddInfo[Index].HddIrq)); | |
+ DEBUG ((EFI_D_INFO, " IdentifyDrive[0].Raw[0] - %x\n", HddInfo[Index].IdentifyDrive[0].Raw[0])); | |
+ DEBUG ((EFI_D_INFO, " IdentifyDrive[1].Raw[0] - %x\n", HddInfo[Index].IdentifyDrive[1].Raw[0])); | |
+ } | |
+ | |
+ DEBUG ((EFI_D_INFO, "\n")); | |
+ | |
+ return ; | |
+} | |
+ | |
+/** | |
+ Print the PCI Interrupt Line and Interrupt Pin registers. | |
+**/ | |
+VOID | |
+PrintPciInterruptRegister ( | |
+ VOID | |
+ ) | |
+{ | |
+ EFI_STATUS Status; | |
+ UINTN Index; | |
+ EFI_HANDLE *Handles; | |
+ UINTN HandleNum; | |
+ EFI_PCI_IO_PROTOCOL *PciIo; | |
+ UINT8 Interrupt[2]; | |
+ UINTN Segment; | |
+ UINTN Bus; | |
+ UINTN Device; | |
+ UINTN Function; | |
+ | |
+ gBS->LocateHandleBuffer ( | |
+ ByProtocol, | |
+ &gEfiPciIoProtocolGuid, | |
+ NULL, | |
+ &HandleNum, | |
+ &Handles | |
+ ); | |
+ | |
+ Bus = 0; | |
+ Device = 0; | |
+ Function = 0; | |
+ | |
+ DEBUG ((EFI_D_INFO, "\n")); | |
+ DEBUG ((EFI_D_INFO, " bb/dd/ff interrupt line interrupt pin\n")); | |
+ DEBUG ((EFI_D_INFO, "======================================\n")); | |
+ for (Index = 0; Index < HandleNum; Index++) { | |
+ Status = gBS->HandleProtocol (Handles[Index], &gEfiPciIoProtocolGuid, (VOID **) &PciIo); | |
+ if (!EFI_ERROR (Status)) { | |
+ Status = PciIo->Pci.Read ( | |
+ PciIo, | |
+ EfiPciIoWidthUint8, | |
+ PCI_INT_LINE_OFFSET, | |
+ 2, | |
+ Interrupt | |
+ ); | |
+ } | |
+ if (!EFI_ERROR (Status)) { | |
+ Status = PciIo->GetLocation ( | |
+ PciIo, | |
+ &Segment, | |
+ &Bus, | |
+ &Device, | |
+ &Function | |
+ ); | |
+ } | |
+ if (!EFI_ERROR (Status)) { | |
+ DEBUG ((EFI_D_INFO, " %02x/%02x/%02x 0x%02x 0x%02x\n", | |
+ Bus, Device, Function, Interrupt[0], Interrupt[1])); | |
+ } | |
+ } | |
+ DEBUG ((EFI_D_INFO, "\n")); | |
+ | |
+ if (Handles != NULL) { | |
+ FreePool (Handles); | |
+ } | |
+} | |
+ | |
+/** | |
+ Identify drive data must be updated to actual parameters before boot. | |
+ | |
+ @param IdentifyDriveData ATA Identify Data | |
+ | |
+**/ | |
+VOID | |
+UpdateIdentifyDriveData ( | |
+ IN UINT8 *IdentifyDriveData | |
+ ); | |
+ | |
+/** | |
+ Update SIO data. | |
+ | |
+ @param Private Legacy BIOS Instance data | |
+ | |
+ @retval EFI_SUCCESS Removable media not present | |
+ | |
+**/ | |
+EFI_STATUS | |
+UpdateSioData ( | |
+ IN LEGACY_BIOS_INSTANCE *Private | |
+ ) | |
+{ | |
+ EFI_STATUS Status; | |
+ UINTN Index; | |
+ UINTN Index1; | |
+ UINT8 LegacyInterrupts[16]; | |
+ EFI_LEGACY_IRQ_ROUTING_ENTRY *RoutingTable; | |
+ UINTN RoutingTableEntries; | |
+ EFI_LEGACY_IRQ_PRIORITY_TABLE_ENTRY *IrqPriorityTable; | |
+ UINTN NumberPriorityEntries; | |
+ EFI_TO_COMPATIBILITY16_BOOT_TABLE *EfiToLegacy16BootTable; | |
+ UINT8 HddIrq; | |
+ UINT16 LegacyInt; | |
+ UINT16 LegMask; | |
+ UINT32 Register; | |
+ UINTN HandleCount; | |
+ EFI_HANDLE *HandleBuffer; | |
+ EFI_ISA_IO_PROTOCOL *IsaIo; | |
+ | |
+ LegacyInt = 0; | |
+ HandleBuffer = NULL; | |
+ | |
+ EfiToLegacy16BootTable = &Private->IntThunk->EfiToLegacy16BootTable; | |
+ LegacyBiosBuildSioData (Private); | |
+ SetMem (LegacyInterrupts, sizeof (LegacyInterrupts), 0); | |
+ | |
+ // | |
+ // Create list of legacy interrupts. | |
+ // | |
+ for (Index = 0; Index < 4; Index++) { | |
+ LegacyInterrupts[Index] = EfiToLegacy16BootTable->SioData.Serial[Index].Irq; | |
+ } | |
+ | |
+ for (Index = 4; Index < 7; Index++) { | |
+ LegacyInterrupts[Index] = EfiToLegacy16BootTable->SioData.Parallel[Index - 4].Irq; | |
+ } | |
+ | |
+ LegacyInterrupts[7] = EfiToLegacy16BootTable->SioData.Floppy.Irq; | |
+ | |
+ // | |
+ // Get Legacy Hdd IRQs. If native mode treat as PCI | |
+ // | |
+ for (Index = 0; Index < 2; Index++) { | |
+ HddIrq = EfiToLegacy16BootTable->HddInfo[Index].HddIrq; | |
+ if ((HddIrq != 0) && ((HddIrq == 15) || (HddIrq == 14))) { | |
+ LegacyInterrupts[Index + 8] = HddIrq; | |
+ } | |
+ } | |
+ | |
+ Private->LegacyBiosPlatform->GetRoutingTable ( | |
+ Private->LegacyBiosPlatform, | |
+ (VOID *) &RoutingTable, | |
+ &RoutingTableEntries, | |
+ NULL, | |
+ NULL, | |
+ (VOID **) &IrqPriorityTable, | |
+ &NumberPriorityEntries | |
+ ); | |
+ // | |
+ // Remove legacy interrupts from the list of PCI interrupts available. | |
+ // | |
+ for (Index = 0; Index <= 0x0b; Index++) { | |
+ for (Index1 = 0; Index1 <= NumberPriorityEntries; Index1++) { | |
+ if (LegacyInterrupts[Index] != 0) { | |
+ LegacyInt = (UINT16) (LegacyInt | (1 << LegacyInterrupts[Index])); | |
+ if (LegacyInterrupts[Index] == IrqPriorityTable[Index1].Irq) { | |
+ IrqPriorityTable[Index1].Used = LEGACY_USED; | |
+ } | |
+ } | |
+ } | |
+ } | |
+ | |
+ Private->Legacy8259->GetMask ( | |
+ Private->Legacy8259, | |
+ &LegMask, | |
+ NULL, | |
+ NULL, | |
+ NULL | |
+ ); | |
+ | |
+ // | |
+ // Set SIO interrupts and disable mouse. Let mouse driver | |
+ // re-enable it. | |
+ // | |
+ LegMask = (UINT16) ((LegMask &~LegacyInt) | 0x1000); | |
+ Private->Legacy8259->SetMask ( | |
+ Private->Legacy8259, | |
+ &LegMask, | |
+ NULL, | |
+ NULL, | |
+ NULL | |
+ ); | |
+ | |
+ // | |
+ // Disable mouse in keyboard controller | |
+ // | |
+ Register = 0xA7; | |
+ Status = gBS->LocateHandleBuffer ( | |
+ ByProtocol, | |
+ &gEfiIsaIoProtocolGuid, | |
+ NULL, | |
+ &HandleCount, | |
+ &HandleBuffer | |
+ ); | |
+ if (EFI_ERROR (Status)) { | |
+ return Status; | |
+ } | |
+ | |
+ for (Index = 0; Index < HandleCount; Index++) { | |
+ Status = gBS->HandleProtocol ( | |
+ HandleBuffer[Index], | |
+ &gEfiIsaIoProtocolGuid, | |
+ (VOID **) &IsaIo | |
+ ); | |
+ ASSERT_EFI_ERROR (Status); | |
+ IsaIo->Io.Write (IsaIo, EfiIsaIoWidthUint8, 0x64, 1, &Register); | |
+ | |
+ } | |
+ | |
+ if (HandleBuffer != NULL) { | |
+ FreePool (HandleBuffer); | |
+ } | |
+ | |
+ return EFI_SUCCESS; | |
+ | |
+} | |
+ | |
+/** | |
+ Identify drive data must be updated to actual parameters before boot. | |
+ This requires updating the checksum, if it exists. | |
+ | |
+ @param IdentifyDriveData ATA Identify Data | |
+ @param Checksum checksum of the ATA Identify Data | |
+ | |
+ @retval EFI_SUCCESS checksum calculated | |
+ @retval EFI_SECURITY_VIOLATION IdentifyData invalid | |
+ | |
+**/ | |
+EFI_STATUS | |
+CalculateIdentifyDriveChecksum ( | |
+ IN UINT8 *IdentifyDriveData, | |
+ OUT UINT8 *Checksum | |
+ ) | |
+{ | |
+ UINTN Index; | |
+ UINT8 LocalChecksum; | |
+ LocalChecksum = 0; | |
+ *Checksum = 0; | |
+ if (IdentifyDriveData[510] != 0xA5) { | |
+ return EFI_SECURITY_VIOLATION; | |
+ } | |
+ | |
+ for (Index = 0; Index < 512; Index++) { | |
+ LocalChecksum = (UINT8) (LocalChecksum + IdentifyDriveData[Index]); | |
+ } | |
+ | |
+ *Checksum = LocalChecksum; | |
+ return EFI_SUCCESS; | |
+} | |
+ | |
+ | |
+/** | |
+ Identify drive data must be updated to actual parameters before boot. | |
+ | |
+ @param IdentifyDriveData ATA Identify Data | |
+ | |
+ | |
+**/ | |
+VOID | |
+UpdateIdentifyDriveData ( | |
+ IN UINT8 *IdentifyDriveData | |
+ ) | |
+{ | |
+ UINT16 NumberCylinders; | |
+ UINT16 NumberHeads; | |
+ UINT16 NumberSectorsTrack; | |
+ UINT32 CapacityInSectors; | |
+ UINT8 OriginalChecksum; | |
+ UINT8 FinalChecksum; | |
+ EFI_STATUS Status; | |
+ ATAPI_IDENTIFY *ReadInfo; | |
+ | |
+ // | |
+ // Status indicates if Integrity byte is correct. Checksum should be | |
+ // 0 if valid. | |
+ // | |
+ ReadInfo = (ATAPI_IDENTIFY *) IdentifyDriveData; | |
+ Status = CalculateIdentifyDriveChecksum (IdentifyDriveData, &OriginalChecksum); | |
+ if (OriginalChecksum != 0) { | |
+ Status = EFI_SECURITY_VIOLATION; | |
+ } | |
+ // | |
+ // If NumberCylinders = 0 then do data(Controller present but don drive attached). | |
+ // | |
+ NumberCylinders = ReadInfo->Raw[1]; | |
+ if (NumberCylinders != 0) { | |
+ ReadInfo->Raw[54] = NumberCylinders; | |
+ | |
+ NumberHeads = ReadInfo->Raw[3]; | |
+ ReadInfo->Raw[55] = NumberHeads; | |
+ | |
+ NumberSectorsTrack = ReadInfo->Raw[6]; | |
+ ReadInfo->Raw[56] = NumberSectorsTrack; | |
+ | |
+ // | |
+ // Copy Multisector info and set valid bit. | |
+ // | |
+ ReadInfo->Raw[59] = (UINT16) (ReadInfo->Raw[47] + 0x100); | |
+ CapacityInSectors = (UINT32) ((UINT32) (NumberCylinders) * (UINT32) (NumberHeads) * (UINT32) (NumberSectorsTrack)); | |
+ ReadInfo->Raw[57] = (UINT16) (CapacityInSectors >> 16); | |
+ ReadInfo->Raw[58] = (UINT16) (CapacityInSectors & 0xffff); | |
+ if (Status == EFI_SUCCESS) { | |
+ // | |
+ // Forece checksum byte to 0 and get new checksum. | |
+ // | |
+ ReadInfo->Raw[255] &= 0xff; | |
+ CalculateIdentifyDriveChecksum (IdentifyDriveData, &FinalChecksum); | |
+ | |
+ // | |
+ // Force new checksum such that sum is 0. | |
+ // | |
+ FinalChecksum = (UINT8) ((UINT8)0 - FinalChecksum); | |
+ ReadInfo->Raw[255] = (UINT16) (ReadInfo->Raw[255] | (FinalChecksum << 8)); | |
+ } | |
+ } | |
+} | |
+ | |
+/** | |
+ Identify drive data must be updated to actual parameters before boot. | |
+ Do for all drives. | |
+ | |
+ @param Private Legacy BIOS Instance data | |
+ | |
+ | |
+**/ | |
+VOID | |
+UpdateAllIdentifyDriveData ( | |
+ IN LEGACY_BIOS_INSTANCE *Private | |
+ ) | |
+{ | |
+ UINTN Index; | |
+ HDD_INFO *HddInfo; | |
+ | |
+ HddInfo = &Private->IntThunk->EfiToLegacy16BootTable.HddInfo[0]; | |
+ | |
+ for (Index = 0; Index < MAX_IDE_CONTROLLER; Index++) { | |
+ // | |
+ // Each controller can have 2 devices. Update for each device | |
+ // | |
+ if ((HddInfo[Index].Status & HDD_MASTER_IDE) != 0) { | |
+ UpdateIdentifyDriveData ((UINT8 *) (&HddInfo[Index].IdentifyDrive[0].Raw[0])); | |
+ } | |
+ | |
+ if ((HddInfo[Index].Status & HDD_SLAVE_IDE) != 0) { | |
+ UpdateIdentifyDriveData ((UINT8 *) (&HddInfo[Index].IdentifyDrive[1].Raw[0])); | |
+ } | |
+ } | |
+} | |
+ | |
+/** | |
+ Enable ide controller. This gets disabled when LegacyBoot.c is about | |
+ to run the Option ROMs. | |
+ | |
+ @param Private Legacy BIOS Instance data | |
+ | |
+ | |
+**/ | |
+VOID | |
+EnableIdeController ( | |
+ IN LEGACY_BIOS_INSTANCE *Private | |
+ ) | |
+{ | |
+ EFI_PCI_IO_PROTOCOL *PciIo; | |
+ EFI_STATUS Status; | |
+ EFI_HANDLE IdeController; | |
+ UINT8 ByteBuffer; | |
+ UINTN HandleCount; | |
+ EFI_HANDLE *HandleBuffer; | |
+ | |
+ Status = Private->LegacyBiosPlatform->GetPlatformHandle ( | |
+ Private->LegacyBiosPlatform, | |
+ EfiGetPlatformIdeHandle, | |
+ 0, | |
+ &HandleBuffer, | |
+ &HandleCount, | |
+ NULL | |
+ ); | |
+ if (!EFI_ERROR (Status)) { | |
+ IdeController = HandleBuffer[0]; | |
+ Status = gBS->HandleProtocol ( | |
+ IdeController, | |
+ &gEfiPciIoProtocolGuid, | |
+ (VOID **) &PciIo | |
+ ); | |
+ ByteBuffer = 0x1f; | |
+ if (!EFI_ERROR (Status)) { | |
+ PciIo->Pci.Write (PciIo, EfiPciIoWidthUint8, 0x04, 1, &ByteBuffer); | |
+ } | |
+ } | |
+} | |
+ | |
+ | |
+/** | |
+ Enable ide controller. This gets disabled when LegacyBoot.c is about | |
+ to run the Option ROMs. | |
+ | |
+ @param Private Legacy BIOS Instance data | |
+ | |
+ | |
+**/ | |
+VOID | |
+EnableAllControllers ( | |
+ IN LEGACY_BIOS_INSTANCE *Private | |
+ ) | |
+{ | |
+ UINTN HandleCount; | |
+ EFI_HANDLE *HandleBuffer; | |
+ UINTN Index; | |
+ EFI_PCI_IO_PROTOCOL *PciIo; | |
+ PCI_TYPE01 PciConfigHeader; | |
+ EFI_STATUS Status; | |
+ | |
+ // | |
+ // | |
+ // | |
+ EnableIdeController (Private); | |
+ | |
+ // | |
+ // Assumption is table is built from low bus to high bus numbers. | |
+ // | |
+ Status = gBS->LocateHandleBuffer ( | |
+ ByProtocol, | |
+ &gEfiPciIoProtocolGuid, | |
+ NULL, | |
+ &HandleCount, | |
+ &HandleBuffer | |
+ ); | |
+ ASSERT_EFI_ERROR (Status); | |
+ | |
+ for (Index = 0; Index < HandleCount; Index++) { | |
+ Status = gBS->HandleProtocol ( | |
+ HandleBuffer[Index], | |
+ &gEfiPciIoProtocolGuid, | |
+ (VOID **) &PciIo | |
+ ); | |
+ ASSERT_EFI_ERROR (Status); | |
+ | |
+ PciIo->Pci.Read ( | |
+ PciIo, | |
+ EfiPciIoWidthUint32, | |
+ 0, | |
+ sizeof (PciConfigHeader) / sizeof (UINT32), | |
+ &PciConfigHeader | |
+ ); | |
+ | |
+ // | |
+ // We do not enable PPB here. This is for HotPlug Consideration. | |
+ // The Platform HotPlug Driver is responsible for Padding enough hot plug | |
+ // resources. It is also responsible for enable this bridge. If it | |
+ // does not pad it. It will cause some early Windows fail to installation. | |
+ // If the platform driver does not pad resource for PPB, PPB should be in | |
+ // un-enabled state to let Windows know that this PPB is not configured by | |
+ // BIOS. So Windows will allocate default resource for PPB. | |
+ // | |
+ // The reason for why we enable the command register is: | |
+ // The CSM will use the IO bar to detect some IRQ status, if the command | |
+ // is disabled, the IO resource will be out of scope. | |
+ // For example: | |
+ // We installed a legacy IRQ handle for a PCI IDE controller. When IRQ | |
+ // comes up, the handle will check the IO space to identify is the | |
+ // controller generated the IRQ source. | |
+ // If the IO command is not enabled, the IRQ handler will has wrong | |
+ // information. It will cause IRQ storm when the correctly IRQ handler fails | |
+ // to run. | |
+ // | |
+ if (!(IS_PCI_VGA (&PciConfigHeader) || | |
+ IS_PCI_OLD_VGA (&PciConfigHeader) || | |
+ IS_PCI_IDE (&PciConfigHeader) || | |
+ IS_PCI_P2P (&PciConfigHeader) || | |
+ IS_PCI_P2P_SUB (&PciConfigHeader) || | |
+ IS_PCI_LPC (&PciConfigHeader) )) { | |
+ | |
+ PciConfigHeader.Hdr.Command |= 0x1f; | |
+ | |
+ PciIo->Pci.Write (PciIo, EfiPciIoWidthUint32, 4, 1, &PciConfigHeader.Hdr.Command); | |
+ } | |
+ } | |
+} | |
+ | |
+/** | |
+ The following routines are identical in operation, so combine | |
+ for code compaction: | |
+ EfiGetPlatformBinaryGetMpTable | |
+ EfiGetPlatformBinaryGetOemIntData | |
+ EfiGetPlatformBinaryGetOem32Data | |
+ EfiGetPlatformBinaryGetOem16Data | |
+ | |
+ @param This Protocol instance pointer. | |
+ @param Id Table/Data identifier | |
+ | |
+ @retval EFI_SUCCESS Success | |
+ @retval EFI_INVALID_PARAMETER Invalid ID | |
+ @retval EFI_OUT_OF_RESOURCES no resource to get data or table | |
+ | |
+**/ | |
+EFI_STATUS | |
+LegacyGetDataOrTable ( | |
+ IN EFI_LEGACY_BIOS_PROTOCOL *This, | |
+ IN EFI_GET_PLATFORM_INFO_MODE Id | |
+ ) | |
+{ | |
+ VOID *Table; | |
+ UINT32 TablePtr; | |
+ UINTN TableSize; | |
+ UINTN Alignment; | |
+ UINTN Location; | |
+ EFI_STATUS Status; | |
+ EFI_LEGACY_BIOS_PLATFORM_PROTOCOL *LegacyBiosPlatform; | |
+ EFI_COMPATIBILITY16_TABLE *Legacy16Table; | |
+ EFI_IA32_REGISTER_SET Regs; | |
+ LEGACY_BIOS_INSTANCE *Private; | |
+ | |
+ Private = LEGACY_BIOS_INSTANCE_FROM_THIS (This); | |
+ | |
+ LegacyBiosPlatform = Private->LegacyBiosPlatform; | |
+ Legacy16Table = Private->Legacy16Table; | |
+ | |
+ // | |
+ // Phase 1 - get an address allocated in 16-bit code | |
+ // | |
+ while (TRUE) { | |
+ switch (Id) { | |
+ case EfiGetPlatformBinaryMpTable: | |
+ case EfiGetPlatformBinaryOemIntData: | |
+ case EfiGetPlatformBinaryOem32Data: | |
+ case EfiGetPlatformBinaryOem16Data: | |
+ { | |
+ Status = LegacyBiosPlatform->GetPlatformInfo ( | |
+ LegacyBiosPlatform, | |
+ Id, | |
+ (VOID *) &Table, | |
+ &TableSize, | |
+ &Location, | |
+ &Alignment, | |
+ 0, | |
+ 0 | |
+ ); | |
+ DEBUG ((EFI_D_INFO, "LegacyGetDataOrTable - ID: %x, %r\n", (UINTN)Id, Status)); | |
+ DEBUG ((EFI_D_INFO, " Table - %x, Size - %x, Location - %x, Alignment - %x\n", (UINTN)Table, (UINTN)TableSize, (UINTN)Location, (UINTN)Alignment)); | |
+ break; | |
+ } | |
+ | |
+ default: | |
+ { | |
+ return EFI_INVALID_PARAMETER; | |
+ } | |
+ } | |
+ | |
+ if (EFI_ERROR (Status)) { | |
+ return Status; | |
+ } | |
+ | |
+ ZeroMem (&Regs, sizeof (EFI_IA32_REGISTER_SET)); | |
+ Regs.X.AX = Legacy16GetTableAddress; | |
+ Regs.X.CX = (UINT16) TableSize; | |
+ Regs.X.BX = (UINT16) Location; | |
+ Regs.X.DX = (UINT16) Alignment; | |
+ Private->LegacyBios.FarCall86 ( | |
+ This, | |
+ Private->Legacy16CallSegment, | |
+ Private->Legacy16CallOffset, | |
+ &Regs, | |
+ NULL, | |
+ 0 | |
+ ); | |
+ | |
+ if (Regs.X.AX != 0) { | |
+ DEBUG ((EFI_D_ERROR, "Table ID %x length insufficient\n", Id)); | |
+ return EFI_OUT_OF_RESOURCES; | |
+ } else { | |
+ break; | |
+ } | |
+ } | |
+ // | |
+ // Phase 2 Call routine second time with address to allow address adjustment | |
+ // | |
+ Status = LegacyBiosPlatform->GetPlatformInfo ( | |
+ LegacyBiosPlatform, | |
+ Id, | |
+ (VOID *) &Table, | |
+ &TableSize, | |
+ &Location, | |
+ &Alignment, | |
+ Regs.X.DS, | |
+ Regs.X.BX | |
+ ); | |
+ switch (Id) { | |
+ case EfiGetPlatformBinaryMpTable: | |
+ { | |
+ Legacy16Table->MpTablePtr = (UINT32) (Regs.X.DS * 16 + Regs.X.BX); | |
+ Legacy16Table->MpTableLength = (UINT32)TableSize; | |
+ DEBUG ((EFI_D_INFO, "MP table in legacy region - %x\n", (UINTN)Legacy16Table->MpTablePtr)); | |
+ break; | |
+ } | |
+ | |
+ case EfiGetPlatformBinaryOemIntData: | |
+ { | |
+ | |
+ Legacy16Table->OemIntSegment = Regs.X.DS; | |
+ Legacy16Table->OemIntOffset = Regs.X.BX; | |
+ DEBUG ((EFI_D_INFO, "OemInt table in legacy region - %04x:%04x\n", (UINTN)Legacy16Table->OemIntSegment, (UINTN)Legacy16Table->OemIntOffset)); | |
+ break; | |
+ } | |
+ | |
+ case EfiGetPlatformBinaryOem32Data: | |
+ { | |
+ Legacy16Table->Oem32Segment = Regs.X.DS; | |
+ Legacy16Table->Oem32Offset = Regs.X.BX; | |
+ DEBUG ((EFI_D_INFO, "Oem32 table in legacy region - %04x:%04x\n", (UINTN)Legacy16Table->Oem32Segment, (UINTN)Legacy16Table->Oem32Offset)); | |
+ break; | |
+ } | |
+ | |
+ case EfiGetPlatformBinaryOem16Data: | |
+ { | |
+ // | |
+ // Legacy16Table->Oem16Segment = Regs.X.DS; | |
+ // Legacy16Table->Oem16Offset = Regs.X.BX; | |
+ DEBUG ((EFI_D_INFO, "Oem16 table in legacy region - %04x:%04x\n", (UINTN)Legacy16Table->Oem16Segment, (UINTN)Legacy16Table->Oem16Offset)); | |
+ break; | |
+ } | |
+ | |
+ default: | |
+ { | |
+ return EFI_INVALID_PARAMETER; | |
+ } | |
+ } | |
+ | |
+ if (EFI_ERROR (Status)) { | |
+ return Status; | |
+ } | |
+ // | |
+ // Phase 3 Copy table to final location | |
+ // | |
+ TablePtr = (UINT32) (Regs.X.DS * 16 + Regs.X.BX); | |
+ | |
+ CopyMem ( | |
+ (VOID *) (UINTN)TablePtr, | |
+ Table, | |
+ TableSize | |
+ ); | |
+ | |
+ return EFI_SUCCESS; | |
+} | |
+ | |
+/** | |
+ Copy SMBIOS table to EfiReservedMemoryType of memory for legacy boot. | |
+ | |
+**/ | |
+VOID | |
+CreateSmbiosTableInReservedMemory ( | |
+ VOID | |
+ ) | |
+{ | |
+ SMBIOS_TABLE_ENTRY_POINT *EntryPointStructure; | |
+ | |
+ if ((mRuntimeSmbiosEntryPoint == NULL) || | |
+ (mReserveSmbiosEntryPoint == 0) || | |
+ (mStructureTableAddress == 0)) { | |
+ return; | |
+ } | |
+ | |
+ EntryPointStructure = (SMBIOS_TABLE_ENTRY_POINT *) mRuntimeSmbiosEntryPoint; | |
+ | |
+ // | |
+ // Copy SMBIOS Entry Point Structure | |
+ // | |
+ CopyMem ( | |
+ (VOID *)(UINTN) mReserveSmbiosEntryPoint, | |
+ EntryPointStructure, | |
+ EntryPointStructure->EntryPointLength | |
+ ); | |
+ | |
+ // | |
+ // Copy SMBIOS Structure Table into EfiReservedMemoryType memory | |
+ // | |
+ CopyMem ( | |
+ (VOID *)(UINTN) mStructureTableAddress, | |
+ (VOID *)(UINTN) EntryPointStructure->TableAddress, | |
+ EntryPointStructure->TableLength | |
+ ); | |
+ | |
+ // | |
+ // Update TableAddress in Entry Point Structure | |
+ // | |
+ EntryPointStructure = (SMBIOS_TABLE_ENTRY_POINT *)(UINTN) mReserveSmbiosEntryPoint; | |
+ EntryPointStructure->TableAddress = (UINT32)(UINTN) mStructureTableAddress; | |
+ | |
+ // | |
+ // Fixup checksums in the Entry Point Structure | |
+ // | |
+ EntryPointStructure->IntermediateChecksum = 0; | |
+ EntryPointStructure->EntryPointStructureChecksum = 0; | |
+ | |
+ EntryPointStructure->IntermediateChecksum = | |
+ CalculateCheckSum8 ( | |
+ (UINT8 *) EntryPointStructure + OFFSET_OF (SMBIOS_TABLE_ENTRY_POINT, IntermediateAnchorString), | |
+ EntryPointStructure->EntryPointLength - OFFSET_OF (SMBIOS_TABLE_ENTRY_POINT, IntermediateAnchorString) | |
+ ); | |
+ EntryPointStructure->EntryPointStructureChecksum = | |
+ CalculateCheckSum8 ((UINT8 *) EntryPointStructure, EntryPointStructure->EntryPointLength); | |
+} | |
+ | |
+/** | |
+ Assign drive number to legacy HDD drives prior to booting an EFI | |
+ aware OS so the OS can access drives without an EFI driver. | |
+ Note: BBS compliant drives ARE NOT available until this call by | |
+ either shell or EFI. | |
+ | |
+ @param This Protocol instance pointer. | |
+ | |
+ @retval EFI_SUCCESS Drive numbers assigned | |
+ | |
+**/ | |
+EFI_STATUS | |
+GenericLegacyBoot ( | |
+ IN EFI_LEGACY_BIOS_PROTOCOL *This | |
+ ) | |
+{ | |
+ EFI_STATUS Status; | |
+ LEGACY_BIOS_INSTANCE *Private; | |
+ EFI_IA32_REGISTER_SET Regs; | |
+ EFI_TO_COMPATIBILITY16_BOOT_TABLE *EfiToLegacy16BootTable; | |
+ EFI_LEGACY_BIOS_PLATFORM_PROTOCOL *LegacyBiosPlatform; | |
+ UINTN CopySize; | |
+ VOID *AcpiPtr; | |
+ HDD_INFO *HddInfo; | |
+ HDD_INFO *LocalHddInfo; | |
+ UINTN Index; | |
+ EFI_COMPATIBILITY16_TABLE *Legacy16Table; | |
+ UINT32 *BdaPtr; | |
+ UINT16 HddCount; | |
+ UINT16 BbsCount; | |
+ BBS_TABLE *LocalBbsTable; | |
+ UINT32 *BaseVectorMaster; | |
+ EFI_TIME BootTime; | |
+ UINT32 LocalTime; | |
+ EFI_HANDLE IdeController; | |
+ UINTN HandleCount; | |
+ EFI_HANDLE *HandleBuffer; | |
+ VOID *AcpiTable; | |
+ UINTN ShadowAddress; | |
+ UINT32 Granularity; | |
+ | |
+ LocalHddInfo = NULL; | |
+ HddCount = 0; | |
+ BbsCount = 0; | |
+ LocalBbsTable = NULL; | |
+ | |
+ Private = LEGACY_BIOS_INSTANCE_FROM_THIS (This); | |
+ DEBUG_CODE ( | |
+ DEBUG ((EFI_D_ERROR, "Start of legacy boot\n")); | |
+ ); | |
+ | |
+ Legacy16Table = Private->Legacy16Table; | |
+ EfiToLegacy16BootTable = &Private->IntThunk->EfiToLegacy16BootTable; | |
+ HddInfo = &EfiToLegacy16BootTable->HddInfo[0]; | |
+ | |
+ LegacyBiosPlatform = Private->LegacyBiosPlatform; | |
+ | |
+ EfiToLegacy16BootTable->MajorVersion = EFI_TO_LEGACY_MAJOR_VERSION; | |
+ EfiToLegacy16BootTable->MinorVersion = EFI_TO_LEGACY_MINOR_VERSION; | |
+ | |
+ // | |
+ // If booting to a legacy OS then force HDD drives to the appropriate | |
+ // boot mode by calling GetIdeHandle. | |
+ // A reconnect -r can force all HDDs back to native mode. | |
+ // | |
+ IdeController = NULL; | |
+ if ((mBootMode == BOOT_LEGACY_OS) || (mBootMode == BOOT_UNCONVENTIONAL_DEVICE)) { | |
+ Status = LegacyBiosPlatform->GetPlatformHandle ( | |
+ Private->LegacyBiosPlatform, | |
+ EfiGetPlatformIdeHandle, | |
+ 0, | |
+ &HandleBuffer, | |
+ &HandleCount, | |
+ NULL | |
+ ); | |
+ if (!EFI_ERROR (Status)) { | |
+ IdeController = HandleBuffer[0]; | |
+ } | |
+ } | |
+ // | |
+ // Unlock the Legacy BIOS region | |
+ // | |
+ Private->LegacyRegion->UnLock ( | |
+ Private->LegacyRegion, | |
+ 0xE0000, | |
+ 0x20000, | |
+ &Granularity | |
+ ); | |
+ | |
+ // | |
+ // Reconstruct the Legacy16 boot memory map | |
+ // | |
+ LegacyBiosBuildE820 (Private, &CopySize); | |
+ if (CopySize > Private->Legacy16Table->E820Length) { | |
+ ZeroMem (&Regs, sizeof (EFI_IA32_REGISTER_SET)); | |
+ Regs.X.AX = Legacy16GetTableAddress; | |
+ Regs.X.CX = (UINT16) CopySize; | |
+ Private->LegacyBios.FarCall86 ( | |
+ &Private->LegacyBios, | |
+ Private->Legacy16Table->Compatibility16CallSegment, | |
+ Private->Legacy16Table->Compatibility16CallOffset, | |
+ &Regs, | |
+ NULL, | |
+ 0 | |
+ ); | |
+ | |
+ Private->Legacy16Table->E820Pointer = (UINT32) (Regs.X.DS * 16 + Regs.X.BX); | |
+ Private->Legacy16Table->E820Length = (UINT32) CopySize; | |
+ if (Regs.X.AX != 0) { | |
+ DEBUG ((EFI_D_ERROR, "Legacy16 E820 length insufficient\n")); | |
+ } else { | |
+ CopyMem ( | |
+ (VOID *)(UINTN) Private->Legacy16Table->E820Pointer, | |
+ Private->E820Table, | |
+ CopySize | |
+ ); | |
+ } | |
+ } else { | |
+ CopyMem ( | |
+ (VOID *)(UINTN) Private->Legacy16Table->E820Pointer, | |
+ Private->E820Table, | |
+ CopySize | |
+ ); | |
+ Private->Legacy16Table->E820Length = (UINT32) CopySize; | |
+ } | |
+ | |
+ // | |
+ // We do not ASSERT if SmbiosTable not found. It is possbile that a platform does not produce SmbiosTable. | |
+ // | |
+ if (mReserveSmbiosEntryPoint == 0) { | |
+ DEBUG ((EFI_D_INFO, "Smbios table is not found!\n")); | |
+ } | |
+ CreateSmbiosTableInReservedMemory (); | |
+ EfiToLegacy16BootTable->SmbiosTable = (UINT32)(UINTN)mReserveSmbiosEntryPoint; | |
+ | |
+ AcpiTable = NULL; | |
+ Status = EfiGetSystemConfigurationTable ( | |
+ &gEfiAcpi20TableGuid, | |
+ &AcpiTable | |
+ ); | |
+ if (EFI_ERROR (Status)) { | |
+ /*Status = */EfiGetSystemConfigurationTable ( | |
+ &gEfiAcpi10TableGuid, | |
+ &AcpiTable | |
+ ); | |
+ } | |
+ // | |
+ // We do not ASSERT if AcpiTable not found. It is possbile that a platform does not produce AcpiTable. | |
+ // | |
+ if (AcpiTable == NULL) { | |
+ DEBUG ((EFI_D_INFO, "ACPI table is not found!\n")); | |
+ } | |
+ EfiToLegacy16BootTable->AcpiTable = (UINT32)(UINTN)AcpiTable; | |
+ | |
+ // | |
+ // Get RSD Ptr table rev at offset 15 decimal | |
+ // Rev = 0 Length is 20 decimal | |
+ // Rev != 0 Length is UINT32 at offset 20 decimal | |
+ // | |
+ if (AcpiTable != NULL) { | |
+ | |
+ AcpiPtr = AcpiTable; | |
+ if (*((UINT8 *) AcpiPtr + 15) == 0) { | |
+ CopySize = 20; | |
+ } else { | |
+ AcpiPtr = ((UINT8 *) AcpiPtr + 20); | |
+ CopySize = (*(UINT32 *) AcpiPtr); | |
+ } | |
+ | |
+ CopyMem ( | |
+ (VOID *)(UINTN) Private->Legacy16Table->AcpiRsdPtrPointer, | |
+ AcpiTable, | |
+ CopySize | |
+ ); | |
+ } | |
+ // | |
+ // Make sure all PCI Interrupt Line register are programmed to match 8259 | |
+ // | |
+ PciProgramAllInterruptLineRegisters (Private); | |
+ | |
+ // | |
+ // Unlock the Legacy BIOS region as PciProgramAllInterruptLineRegisters | |
+ // can lock it. | |
+ // | |
+ Private->LegacyRegion->UnLock ( | |
+ Private->LegacyRegion, | |
+ Private->BiosStart, | |
+ Private->LegacyBiosImageSize, | |
+ &Granularity | |
+ ); | |
+ | |
+ // | |
+ // Configure Legacy Device Magic | |
+ // | |
+ // Only do this code if booting legacy OS | |
+ // | |
+ if ((mBootMode == BOOT_LEGACY_OS) || (mBootMode == BOOT_UNCONVENTIONAL_DEVICE)) { | |
+ UpdateSioData (Private); | |
+ } | |
+ // | |
+ // Setup BDA and EBDA standard areas before Legacy Boot | |
+ // | |
+ LegacyBiosCompleteBdaBeforeBoot (Private); | |
+ LegacyBiosCompleteStandardCmosBeforeBoot (Private); | |
+ | |
+ // | |
+ // We must build IDE data, if it hasn't been done, before PciShadowRoms | |
+ // to insure EFI drivers are connected. | |
+ // | |
+ LegacyBiosBuildIdeData (Private, &HddInfo, 1); | |
+ UpdateAllIdentifyDriveData (Private); | |
+ | |
+ // | |
+ // Clear IO BAR, if IDE controller in legacy mode. | |
+ // | |
+ InitLegacyIdeController (IdeController); | |
+ | |
+ // | |
+ // Generate number of ticks since midnight for BDA. DOS requires this | |
+ // for its time. We have to make assumptions as to how long following | |
+ // code takes since after PciShadowRoms PciIo is gone. Place result in | |
+ // 40:6C-6F | |
+ // | |
+ // Adjust value by 1 second. | |
+ // | |
+ gRT->GetTime (&BootTime, NULL); | |
+ LocalTime = BootTime.Hour * 3600 + BootTime.Minute * 60 + BootTime.Second; | |
+ LocalTime += 1; | |
+ | |
+ // | |
+ // Multiply result by 18.2 for number of ticks since midnight. | |
+ // Use 182/10 to avoid floating point math. | |
+ // | |
+ LocalTime = (LocalTime * 182) / 10; | |
+ BdaPtr = (UINT32 *) (UINTN)0x46C; | |
+ *BdaPtr = LocalTime; | |
+ | |
+ // | |
+ // Shadow PCI ROMs. We must do this near the end since this will kick | |
+ // of Native EFI drivers that may be needed to collect info for Legacy16 | |
+ // | |
+ // WARNING: PciIo is gone after this call. | |
+ // | |
+ PciShadowRoms (Private); | |
+ | |
+ // | |
+ // Shadow PXE base code, BIS etc. | |
+ // | |
+ Private->LegacyRegion->UnLock (Private->LegacyRegion, 0xc0000, 0x40000, &Granularity); | |
+ ShadowAddress = Private->OptionRom; | |
+ Private->LegacyBiosPlatform->PlatformHooks ( | |
+ Private->LegacyBiosPlatform, | |
+ EfiPlatformHookShadowServiceRoms, | |
+ 0, | |
+ 0, | |
+ &ShadowAddress, | |
+ Legacy16Table, | |
+ NULL | |
+ ); | |
+ Private->OptionRom = (UINT32)ShadowAddress; | |
+ // | |
+ // Register Legacy SMI Handler | |
+ // | |
+ LegacyBiosPlatform->SmmInit ( | |
+ LegacyBiosPlatform, | |
+ EfiToLegacy16BootTable | |
+ ); | |
+ | |
+ // | |
+ // Let platform code know the boot options | |
+ // | |
+ LegacyBiosGetBbsInfo ( | |
+ This, | |
+ &HddCount, | |
+ &LocalHddInfo, | |
+ &BbsCount, | |
+ &LocalBbsTable | |
+ ); | |
+ | |
+ DEBUG_CODE ( | |
+ PrintPciInterruptRegister (); | |
+ PrintBbsTable (LocalBbsTable); | |
+ PrintHddInfo (LocalHddInfo); | |
+ ); | |
+ // | |
+ // If drive wasn't spun up then BuildIdeData may have found new drives. | |
+ // Need to update BBS boot priority. | |
+ // | |
+ for (Index = 0; Index < MAX_IDE_CONTROLLER; Index++) { | |
+ if ((LocalHddInfo[Index].IdentifyDrive[0].Raw[0] != 0) && | |
+ (LocalBbsTable[2 * Index + 1].BootPriority == BBS_IGNORE_ENTRY) | |
+ ) { | |
+ LocalBbsTable[2 * Index + 1].BootPriority = BBS_UNPRIORITIZED_ENTRY; | |
+ } | |
+ | |
+ if ((LocalHddInfo[Index].IdentifyDrive[1].Raw[0] != 0) && | |
+ (LocalBbsTable[2 * Index + 2].BootPriority == BBS_IGNORE_ENTRY) | |
+ ) { | |
+ LocalBbsTable[2 * Index + 2].BootPriority = BBS_UNPRIORITIZED_ENTRY; | |
+ } | |
+ } | |
+ | |
+ Private->LegacyRegion->UnLock ( | |
+ Private->LegacyRegion, | |
+ 0xc0000, | |
+ 0x40000, | |
+ &Granularity | |
+ ); | |
+ | |
+ LegacyBiosPlatform->PrepareToBoot ( | |
+ LegacyBiosPlatform, | |
+ mBbsDevicePathPtr, | |
+ mBbsTable, | |
+ mLoadOptionsSize, | |
+ mLoadOptions, | |
+ (VOID *) &Private->IntThunk->EfiToLegacy16BootTable | |
+ ); | |
+ | |
+ // | |
+ // If no boot device return to BDS | |
+ // | |
+ if ((mBootMode == BOOT_LEGACY_OS) || (mBootMode == BOOT_UNCONVENTIONAL_DEVICE)) { | |
+ for (Index = 0; Index < BbsCount; Index++){ | |
+ if ((LocalBbsTable[Index].BootPriority != BBS_DO_NOT_BOOT_FROM) && | |
+ (LocalBbsTable[Index].BootPriority != BBS_UNPRIORITIZED_ENTRY) && | |
+ (LocalBbsTable[Index].BootPriority != BBS_IGNORE_ENTRY)) { | |
+ break; | |
+ } | |
+ } | |
+ if (Index == BbsCount) { | |
+ return EFI_DEVICE_ERROR; | |
+ } | |
+ } | |
+ // | |
+ // Let the Legacy16 code know the device path type for legacy boot | |
+ // | |
+ EfiToLegacy16BootTable->DevicePathType = mBbsDevicePathPtr->DeviceType; | |
+ | |
+ // | |
+ // Copy MP table, if it exists. | |
+ // | |
+ LegacyGetDataOrTable (This, EfiGetPlatformBinaryMpTable); | |
+ | |
+ if (!Private->LegacyBootEntered) { | |
+ // | |
+ // Copy OEM INT Data, if it exists. Note: This code treats any data | |
+ // as a bag of bits and knows nothing of the contents nor cares. | |
+ // Contents are IBV specific. | |
+ // | |
+ LegacyGetDataOrTable (This, EfiGetPlatformBinaryOemIntData); | |
+ | |
+ // | |
+ // Copy OEM16 Data, if it exists.Note: This code treats any data | |
+ // as a bag of bits and knows nothing of the contents nor cares. | |
+ // Contents are IBV specific. | |
+ // | |
+ LegacyGetDataOrTable (This, EfiGetPlatformBinaryOem16Data); | |
+ | |
+ // | |
+ // Copy OEM32 Data, if it exists.Note: This code treats any data | |
+ // as a bag of bits and knows nothing of the contents nor cares. | |
+ // Contents are IBV specific. | |
+ // | |
+ LegacyGetDataOrTable (This, EfiGetPlatformBinaryOem32Data); | |
+ } | |
+ | |
+ // | |
+ // Call into Legacy16 code to prepare for INT 19h | |
+ // | |
+ ZeroMem (&Regs, sizeof (EFI_IA32_REGISTER_SET)); | |
+ Regs.X.AX = Legacy16PrepareToBoot; | |
+ | |
+ // | |
+ // Pass in handoff data | |
+ // | |
+ Regs.X.ES = NORMALIZE_EFI_SEGMENT ((UINTN)EfiToLegacy16BootTable); | |
+ Regs.X.BX = NORMALIZE_EFI_OFFSET ((UINTN)EfiToLegacy16BootTable); | |
+ | |
+ Private->LegacyBios.FarCall86 ( | |
+ This, | |
+ Private->Legacy16CallSegment, | |
+ Private->Legacy16CallOffset, | |
+ &Regs, | |
+ NULL, | |
+ 0 | |
+ ); | |
+ | |
+ if (Regs.X.AX != 0) { | |
+ return EFI_DEVICE_ERROR; | |
+ } | |
+ // | |
+ // Lock the Legacy BIOS region | |
+ // | |
+ Private->LegacyRegion->Lock ( | |
+ Private->LegacyRegion, | |
+ 0xc0000, | |
+ 0x40000, | |
+ &Granularity | |
+ ); | |
+ if (Private->Legacy16Table->TableLength >= OFFSET_OF(EFI_COMPATIBILITY16_TABLE, | |
+ HiPermanentMemoryAddress) && | |
+ Private->Legacy16Table->UmaAddress != 0 && Private->Legacy16Table->UmaSize != 0) { | |
+ | |
+ // Here we could reduce UmaAddress down as far as Private->OptionRom, taking into | |
+ // account the granularity of the access control. | |
+ | |
+ DEBUG((EFI_D_INFO, "Unlocking UMB RAM region %x-%x\n", | |
+ Private->Legacy16Table->UmaAddress, | |
+ Private->Legacy16Table->UmaAddress + Private->Legacy16Table->UmaSize)); | |
+ | |
+ Private->LegacyRegion->UnLock ( | |
+ Private->LegacyRegion, | |
+ Private->Legacy16Table->UmaAddress, | |
+ Private->Legacy16Table->UmaSize, | |
+ &Granularity | |
+ ); | |
+ } | |
+ // | |
+ // Lock attributes of the Legacy Region if chipset supports | |
+ // | |
+ Private->LegacyRegion->BootLock ( | |
+ Private->LegacyRegion, | |
+ 0xc0000, | |
+ 0x40000, | |
+ &Granularity | |
+ ); | |
+ | |
+ // | |
+ // Call into Legacy16 code to do the INT 19h | |
+ // | |
+ EnableAllControllers (Private); | |
+ if ((mBootMode == BOOT_LEGACY_OS) || (mBootMode == BOOT_UNCONVENTIONAL_DEVICE)) { | |
+ // | |
+ // Report Status Code to indicate legacy boot event will be signalled | |
+ // | |
+ REPORT_STATUS_CODE ( | |
+ EFI_PROGRESS_CODE, | |
+ (EFI_SOFTWARE_DXE_BS_DRIVER | EFI_SW_DXE_BS_PC_LEGACY_BOOT_EVENT) | |
+ ); | |
+ | |
+ // | |
+ // Signal all the events that are waiting on EVT_SIGNAL_LEGACY_BOOT | |
+ // | |
+ EfiSignalEventLegacyBoot (); | |
+ DEBUG ((EFI_D_INFO, "Legacy INT19 Boot...\n")); | |
+ | |
+ // | |
+ // Disable DXE Timer while executing in real mode | |
+ // | |
+ Private->Timer->SetTimerPeriod (Private->Timer, 0); | |
+ | |
+ // | |
+ // Save and disable interrupt of debug timer | |
+ // | |
+ SaveAndSetDebugTimerInterrupt (FALSE); | |
+ | |
+ | |
+ // | |
+ // Put the 8259 into its legacy mode by reprogramming the vector bases | |
+ // | |
+ Private->Legacy8259->SetVectorBase (Private->Legacy8259, LEGACY_MODE_BASE_VECTOR_MASTER, LEGACY_MODE_BASE_VECTOR_SLAVE); | |
+ // | |
+ // PC History | |
+ // The original PC used INT8-F for master PIC. Since these mapped over | |
+ // processor exceptions TIANO moved the master PIC to INT68-6F. | |
+ // We need to set these back to the Legacy16 unexpected interrupt(saved | |
+ // in LegacyBios.c) since some OS see that these have values different from | |
+ // what is expected and invoke them. Since the legacy OS corrupts EFI | |
+ // memory, there is no handler for these interrupts and OS blows up. | |
+ // | |
+ // We need to save the TIANO values for the rare case that the Legacy16 | |
+ // code cannot boot but knows memory hasn't been destroyed. | |
+ // | |
+ // To compound the problem, video takes over one of these INTS and must be | |
+ // be left. | |
+ // @bug - determine if video hooks INT(in which case we must find new | |
+ // set of TIANO vectors) or takes it over. | |
+ // | |
+ // | |
+ BaseVectorMaster = (UINT32 *) (sizeof (UINT32) * PROTECTED_MODE_BASE_VECTOR_MASTER); | |
+ for (Index = 0; Index < 8; Index++) { | |
+ Private->ThunkSavedInt[Index] = BaseVectorMaster[Index]; | |
+ if (Private->ThunkSeg == (UINT16) (BaseVectorMaster[Index] >> 16)) { | |
+ BaseVectorMaster[Index] = (UINT32) (Private->BiosUnexpectedInt); | |
+ } | |
+ } | |
+ | |
+ ZeroMem (&Regs, sizeof (EFI_IA32_REGISTER_SET)); | |
+ Regs.X.AX = Legacy16Boot; | |
+ | |
+ Private->LegacyBios.FarCall86 ( | |
+ This, | |
+ Private->Legacy16CallSegment, | |
+ Private->Legacy16CallOffset, | |
+ &Regs, | |
+ NULL, | |
+ 0 | |
+ ); | |
+ | |
+ BaseVectorMaster = (UINT32 *) (sizeof (UINT32) * PROTECTED_MODE_BASE_VECTOR_MASTER); | |
+ for (Index = 0; Index < 8; Index++) { | |
+ BaseVectorMaster[Index] = Private->ThunkSavedInt[Index]; | |
+ } | |
+ } | |
+ Private->LegacyBootEntered = TRUE; | |
+ if ((mBootMode == BOOT_LEGACY_OS) || (mBootMode == BOOT_UNCONVENTIONAL_DEVICE)) { | |
+ // | |
+ // Should never return unless never passed control to 0:7c00(first stage | |
+ // OS loader) and only then if no bootable device found. | |
+ // | |
+ return EFI_DEVICE_ERROR; | |
+ } else { | |
+ // | |
+ // If boot to EFI then expect to return to caller | |
+ // | |
+ return EFI_SUCCESS; | |
+ } | |
+} | |
+ | |
+ | |
+/** | |
+ Assign drive number to legacy HDD drives prior to booting an EFI | |
+ aware OS so the OS can access drives without an EFI driver. | |
+ Note: BBS compliant drives ARE NOT available until this call by | |
+ either shell or EFI. | |
+ | |
+ @param This Protocol instance pointer. | |
+ @param BbsCount Number of BBS_TABLE structures | |
+ @param BbsTable List BBS entries | |
+ | |
+ @retval EFI_SUCCESS Drive numbers assigned | |
+ | |
+**/ | |
+EFI_STATUS | |
+EFIAPI | |
+LegacyBiosPrepareToBootEfi ( | |
+ IN EFI_LEGACY_BIOS_PROTOCOL *This, | |
+ OUT UINT16 *BbsCount, | |
+ OUT BBS_TABLE **BbsTable | |
+ ) | |
+{ | |
+ EFI_STATUS Status; | |
+ EFI_TO_COMPATIBILITY16_BOOT_TABLE *EfiToLegacy16BootTable; | |
+ LEGACY_BIOS_INSTANCE *Private; | |
+ | |
+ Private = LEGACY_BIOS_INSTANCE_FROM_THIS (This); | |
+ EfiToLegacy16BootTable = &Private->IntThunk->EfiToLegacy16BootTable; | |
+ mBootMode = BOOT_EFI_OS; | |
+ mBbsDevicePathPtr = NULL; | |
+ Status = GenericLegacyBoot (This); | |
+ *BbsTable = (BBS_TABLE*)(UINTN)EfiToLegacy16BootTable->BbsTable; | |
+ *BbsCount = (UINT16) (sizeof (Private->IntThunk->BbsTable) / sizeof (BBS_TABLE)); | |
+ return Status; | |
+} | |
+ | |
+/** | |
+ To boot from an unconventional device like parties and/or execute HDD diagnostics. | |
+ | |
+ @param This Protocol instance pointer. | |
+ @param Attributes How to interpret the other input parameters | |
+ @param BbsEntry The 0-based index into the BbsTable for the parent | |
+ device. | |
+ @param BeerData Pointer to the 128 bytes of ram BEER data. | |
+ @param ServiceAreaData Pointer to the 64 bytes of raw Service Area data. The | |
+ caller must provide a pointer to the specific Service | |
+ Area and not the start all Service Areas. | |
+ | |
+ @retval EFI_INVALID_PARAMETER if error. Does NOT return if no error. | |
+ | |
+***/ | |
+EFI_STATUS | |
+EFIAPI | |
+LegacyBiosBootUnconventionalDevice ( | |
+ IN EFI_LEGACY_BIOS_PROTOCOL *This, | |
+ IN UDC_ATTRIBUTES Attributes, | |
+ IN UINTN BbsEntry, | |
+ IN VOID *BeerData, | |
+ IN VOID *ServiceAreaData | |
+ ) | |
+{ | |
+ EFI_STATUS Status; | |
+ EFI_TO_COMPATIBILITY16_BOOT_TABLE *EfiToLegacy16BootTable; | |
+ LEGACY_BIOS_INSTANCE *Private; | |
+ UD_TABLE *UcdTable; | |
+ UINTN Index; | |
+ UINT16 BootPriority; | |
+ BBS_TABLE *BbsTable; | |
+ | |
+ BootPriority = 0; | |
+ Private = LEGACY_BIOS_INSTANCE_FROM_THIS (This); | |
+ mBootMode = BOOT_UNCONVENTIONAL_DEVICE; | |
+ mBbsDevicePathPtr = &mBbsDevicePathNode; | |
+ mAttributes = Attributes; | |
+ mBbsEntry = BbsEntry; | |
+ mBeerData = BeerData, mServiceAreaData = ServiceAreaData; | |
+ | |
+ EfiToLegacy16BootTable = &Private->IntThunk->EfiToLegacy16BootTable; | |
+ | |
+ // | |
+ // Do input parameter checking | |
+ // | |
+ if ((Attributes.DirectoryServiceValidity == 0) && | |
+ (Attributes.RabcaUsedFlag == 0) && | |
+ (Attributes.ExecuteHddDiagnosticsFlag == 0) | |
+ ) { | |
+ return EFI_INVALID_PARAMETER; | |
+ } | |
+ | |
+ if (((Attributes.DirectoryServiceValidity != 0) && (ServiceAreaData == NULL)) || | |
+ (((Attributes.DirectoryServiceValidity | Attributes.RabcaUsedFlag) != 0) && (BeerData == NULL)) | |
+ ) { | |
+ return EFI_INVALID_PARAMETER; | |
+ } | |
+ | |
+ UcdTable = (UD_TABLE *) AllocatePool ( | |
+ sizeof (UD_TABLE) | |
+ ); | |
+ if (NULL == UcdTable) { | |
+ return EFI_OUT_OF_RESOURCES; | |
+ } | |
+ | |
+ EfiToLegacy16BootTable->UnconventionalDeviceTable = (UINT32)(UINTN)UcdTable; | |
+ UcdTable->Attributes = Attributes; | |
+ UcdTable->BbsTableEntryNumberForParentDevice = (UINT8) BbsEntry; | |
+ // | |
+ // Force all existing BBS entries to DoNotBoot. This allows 16-bit CSM | |
+ // to assign drive numbers but bot boot from. Only newly created entries | |
+ // will be valid. | |
+ // | |
+ BbsTable = (BBS_TABLE*)(UINTN)EfiToLegacy16BootTable->BbsTable; | |
+ for (Index = 0; Index < EfiToLegacy16BootTable->NumberBbsEntries; Index++) { | |
+ BbsTable[Index].BootPriority = BBS_DO_NOT_BOOT_FROM; | |
+ } | |
+ // | |
+ // If parent is onboard IDE then assign controller & device number | |
+ // else they are 0. | |
+ // | |
+ if (BbsEntry < MAX_IDE_CONTROLLER * 2) { | |
+ UcdTable->DeviceNumber = (UINT8) ((BbsEntry - 1) % 2); | |
+ } | |
+ | |
+ if (BeerData != NULL) { | |
+ CopyMem ( | |
+ (VOID *) UcdTable->BeerData, | |
+ BeerData, | |
+ (UINTN) 128 | |
+ ); | |
+ } | |
+ | |
+ if (ServiceAreaData != NULL) { | |
+ CopyMem ( | |
+ (VOID *) UcdTable->ServiceAreaData, | |
+ ServiceAreaData, | |
+ (UINTN) 64 | |
+ ); | |
+ } | |
+ // | |
+ // For each new entry do the following: | |
+ // 1. Increment current number of BBS entries | |
+ // 2. Copy parent entry to new entry. | |
+ // 3. Zero out BootHandler Offset & segment | |
+ // 4. Set appropriate device type. BEV(0x80) for HDD diagnostics | |
+ // and Floppy(0x01) for PARTIES boot. | |
+ // 5. Assign new priority. | |
+ // | |
+ if ((Attributes.ExecuteHddDiagnosticsFlag) != 0) { | |
+ EfiToLegacy16BootTable->NumberBbsEntries += 1; | |
+ | |
+ CopyMem ( | |
+ (VOID *) &BbsTable[EfiToLegacy16BootTable->NumberBbsEntries].BootPriority, | |
+ (VOID *) &BbsTable[BbsEntry].BootPriority, | |
+ sizeof (BBS_TABLE) | |
+ ); | |
+ | |
+ BbsTable[EfiToLegacy16BootTable->NumberBbsEntries].BootHandlerOffset = 0; | |
+ BbsTable[EfiToLegacy16BootTable->NumberBbsEntries].BootHandlerSegment = 0; | |
+ BbsTable[EfiToLegacy16BootTable->NumberBbsEntries].DeviceType = 0x80; | |
+ | |
+ UcdTable->BbsTableEntryNumberForHddDiag = (UINT8) (EfiToLegacy16BootTable->NumberBbsEntries - 1); | |
+ | |
+ BbsTable[EfiToLegacy16BootTable->NumberBbsEntries].BootPriority = BootPriority; | |
+ BootPriority += 1; | |
+ | |
+ // | |
+ // Set device type as BBS_TYPE_DEV for PARTIES diagnostic | |
+ // | |
+ mBbsDevicePathNode.DeviceType = BBS_TYPE_BEV; | |
+ } | |
+ | |
+ if (((Attributes.DirectoryServiceValidity | Attributes.RabcaUsedFlag)) != 0) { | |
+ EfiToLegacy16BootTable->NumberBbsEntries += 1; | |
+ CopyMem ( | |
+ (VOID *) &BbsTable[EfiToLegacy16BootTable->NumberBbsEntries].BootPriority, | |
+ (VOID *) &BbsTable[BbsEntry].BootPriority, | |
+ sizeof (BBS_TABLE) | |
+ ); | |
+ | |
+ BbsTable[EfiToLegacy16BootTable->NumberBbsEntries].BootHandlerOffset = 0; | |
+ BbsTable[EfiToLegacy16BootTable->NumberBbsEntries].BootHandlerSegment = 0; | |
+ BbsTable[EfiToLegacy16BootTable->NumberBbsEntries].DeviceType = 0x01; | |
+ UcdTable->BbsTableEntryNumberForBoot = (UINT8) (EfiToLegacy16BootTable->NumberBbsEntries - 1); | |
+ BbsTable[EfiToLegacy16BootTable->NumberBbsEntries].BootPriority = BootPriority; | |
+ | |
+ // | |
+ // Set device type as BBS_TYPE_FLOPPY for PARTIES boot as floppy | |
+ // | |
+ mBbsDevicePathNode.DeviceType = BBS_TYPE_FLOPPY; | |
+ } | |
+ // | |
+ // Build the BBS Device Path for this boot selection | |
+ // | |
+ mBbsDevicePathNode.Header.Type = BBS_DEVICE_PATH; | |
+ mBbsDevicePathNode.Header.SubType = BBS_BBS_DP; | |
+ SetDevicePathNodeLength (&mBbsDevicePathNode.Header, sizeof (BBS_BBS_DEVICE_PATH)); | |
+ mBbsDevicePathNode.StatusFlag = 0; | |
+ mBbsDevicePathNode.String[0] = 0; | |
+ | |
+ Status = GenericLegacyBoot (This); | |
+ return Status; | |
+} | |
+ | |
+/** | |
+ Attempt to legacy boot the BootOption. If the EFI contexted has been | |
+ compromised this function will not return. | |
+ | |
+ @param This Protocol instance pointer. | |
+ @param BbsDevicePath EFI Device Path from BootXXXX variable. | |
+ @param LoadOptionsSize Size of LoadOption in size. | |
+ @param LoadOptions LoadOption from BootXXXX variable | |
+ | |
+ @retval EFI_SUCCESS Removable media not present | |
+ | |
+**/ | |
+EFI_STATUS | |
+EFIAPI | |
+LegacyBiosLegacyBoot ( | |
+ IN EFI_LEGACY_BIOS_PROTOCOL *This, | |
+ IN BBS_BBS_DEVICE_PATH *BbsDevicePath, | |
+ IN UINT32 LoadOptionsSize, | |
+ IN VOID *LoadOptions | |
+ ) | |
+{ | |
+ EFI_STATUS Status; | |
+ | |
+ mBbsDevicePathPtr = BbsDevicePath; | |
+ mLoadOptionsSize = LoadOptionsSize; | |
+ mLoadOptions = LoadOptions; | |
+ mBootMode = BOOT_LEGACY_OS; | |
+ Status = GenericLegacyBoot (This); | |
+ | |
+ return Status; | |
+} | |
+ | |
+/** | |
+ Convert EFI Memory Type to E820 Memory Type. | |
+ | |
+ @param Type EFI Memory Type | |
+ | |
+ @return ACPI Memory Type for EFI Memory Type | |
+ | |
+**/ | |
+EFI_ACPI_MEMORY_TYPE | |
+EfiMemoryTypeToE820Type ( | |
+ IN UINT32 Type | |
+ ) | |
+{ | |
+ switch (Type) { | |
+ case EfiLoaderCode: | |
+ case EfiLoaderData: | |
+ case EfiBootServicesCode: | |
+ case EfiBootServicesData: | |
+ case EfiConventionalMemory: | |
+ case EfiRuntimeServicesCode: | |
+ case EfiRuntimeServicesData: | |
+ return EfiAcpiAddressRangeMemory; | |
+ | |
+ case EfiACPIReclaimMemory: | |
+ return EfiAcpiAddressRangeACPI; | |
+ | |
+ case EfiACPIMemoryNVS: | |
+ return EfiAcpiAddressRangeNVS; | |
+ | |
+ // | |
+ // All other types map to reserved. | |
+ // Adding the code just waists FLASH space. | |
+ // | |
+ // case EfiReservedMemoryType: | |
+ // case EfiUnusableMemory: | |
+ // case EfiMemoryMappedIO: | |
+ // case EfiMemoryMappedIOPortSpace: | |
+ // case EfiPalCode: | |
+ // | |
+ default: | |
+ return EfiAcpiAddressRangeReserved; | |
+ } | |
+} | |
+ | |
+/** | |
+ Build the E820 table. | |
+ | |
+ @param Private Legacy BIOS Instance data | |
+ @param Size Size of E820 Table | |
+ | |
+ @retval EFI_SUCCESS It should always work. | |
+ | |
+**/ | |
+EFI_STATUS | |
+LegacyBiosBuildE820 ( | |
+ IN LEGACY_BIOS_INSTANCE *Private, | |
+ OUT UINTN *Size | |
+ ) | |
+{ | |
+ EFI_STATUS Status; | |
+ EFI_E820_ENTRY64 *E820Table; | |
+ EFI_MEMORY_DESCRIPTOR *EfiMemoryMap; | |
+ EFI_MEMORY_DESCRIPTOR *EfiMemoryMapEnd; | |
+ EFI_MEMORY_DESCRIPTOR *EfiEntry; | |
+ EFI_MEMORY_DESCRIPTOR *NextEfiEntry; | |
+ EFI_MEMORY_DESCRIPTOR TempEfiEntry; | |
+ UINTN EfiMemoryMapSize; | |
+ UINTN EfiMapKey; | |
+ UINTN EfiDescriptorSize; | |
+ UINT32 EfiDescriptorVersion; | |
+ UINTN Index; | |
+ EFI_PEI_HOB_POINTERS Hob; | |
+ EFI_HOB_RESOURCE_DESCRIPTOR *ResourceHob; | |
+ UINTN TempIndex; | |
+ UINTN IndexSort; | |
+ UINTN TempNextIndex; | |
+ EFI_E820_ENTRY64 TempE820; | |
+ EFI_ACPI_MEMORY_TYPE TempType; | |
+ BOOLEAN ChangedFlag; | |
+ UINTN Above1MIndex; | |
+ UINT64 MemoryBlockLength; | |
+ | |
+ E820Table = (EFI_E820_ENTRY64 *) Private->E820Table; | |
+ | |
+ // | |
+ // Get the EFI memory map. | |
+ // | |
+ EfiMemoryMapSize = 0; | |
+ EfiMemoryMap = NULL; | |
+ Status = gBS->GetMemoryMap ( | |
+ &EfiMemoryMapSize, | |
+ EfiMemoryMap, | |
+ &EfiMapKey, | |
+ &EfiDescriptorSize, | |
+ &EfiDescriptorVersion | |
+ ); | |
+ ASSERT (Status == EFI_BUFFER_TOO_SMALL); | |
+ | |
+ do { | |
+ // | |
+ // Use size returned back plus 1 descriptor for the AllocatePool. | |
+ // We don't just multiply by 2 since the "for" loop below terminates on | |
+ // EfiMemoryMapEnd which is dependent upon EfiMemoryMapSize. Otherwize | |
+ // we process bogus entries and create bogus E820 entries. | |
+ // | |
+ EfiMemoryMap = (EFI_MEMORY_DESCRIPTOR *) AllocatePool (EfiMemoryMapSize); | |
+ ASSERT (EfiMemoryMap != NULL); | |
+ Status = gBS->GetMemoryMap ( | |
+ &EfiMemoryMapSize, | |
+ EfiMemoryMap, | |
+ &EfiMapKey, | |
+ &EfiDescriptorSize, | |
+ &EfiDescriptorVersion | |
+ ); | |
+ if (EFI_ERROR (Status)) { | |
+ FreePool (EfiMemoryMap); | |
+ } | |
+ } while (Status == EFI_BUFFER_TOO_SMALL); | |
+ | |
+ ASSERT_EFI_ERROR (Status); | |
+ | |
+ // | |
+ // Punch in the E820 table for memory less than 1 MB. | |
+ // Assume ZeroMem () has been done on data structure. | |
+ // | |
+ // | |
+ // First entry is 0 to (640k - EBDA) | |
+ // | |
+ E820Table[0].BaseAddr = 0; | |
+ E820Table[0].Length = (UINT64) ((*(UINT16 *) (UINTN)0x40E) << 4); | |
+ E820Table[0].Type = EfiAcpiAddressRangeMemory; | |
+ | |
+ // | |
+ // Second entry is (640k - EBDA) to 640k | |
+ // | |
+ E820Table[1].BaseAddr = E820Table[0].Length; | |
+ E820Table[1].Length = (UINT64) ((640 * 1024) - E820Table[0].Length); | |
+ E820Table[1].Type = EfiAcpiAddressRangeReserved; | |
+ | |
+ // | |
+ // Third Entry is legacy BIOS | |
+ // DO NOT CLAIM region from 0xA0000-0xDFFFF. OS can use free areas | |
+ // to page in memory under 1MB. | |
+ // Omit region from 0xE0000 to start of BIOS, if any. This can be | |
+ // used for a multiple reasons including OPROMS. | |
+ // | |
+ | |
+ // | |
+ // The CSM binary image size is not the actually size that CSM binary used, | |
+ // to avoid memory corrupt, we declare the 0E0000 - 0FFFFF is used by CSM binary. | |
+ // | |
+ E820Table[2].BaseAddr = 0xE0000; | |
+ E820Table[2].Length = 0x20000; | |
+ E820Table[2].Type = EfiAcpiAddressRangeReserved; | |
+ | |
+ Above1MIndex = 2; | |
+ | |
+ // | |
+ // Process the EFI map to produce E820 map; | |
+ // | |
+ | |
+ // | |
+ // Sort memory map from low to high | |
+ // | |
+ EfiEntry = EfiMemoryMap; | |
+ NextEfiEntry = NEXT_MEMORY_DESCRIPTOR (EfiEntry, EfiDescriptorSize); | |
+ EfiMemoryMapEnd = (EFI_MEMORY_DESCRIPTOR *) ((UINT8 *) EfiMemoryMap + EfiMemoryMapSize); | |
+ while (EfiEntry < EfiMemoryMapEnd) { | |
+ while (NextEfiEntry < EfiMemoryMapEnd) { | |
+ if (EfiEntry->PhysicalStart > NextEfiEntry->PhysicalStart) { | |
+ CopyMem (&TempEfiEntry, EfiEntry, sizeof (EFI_MEMORY_DESCRIPTOR)); | |
+ CopyMem (EfiEntry, NextEfiEntry, sizeof (EFI_MEMORY_DESCRIPTOR)); | |
+ CopyMem (NextEfiEntry, &TempEfiEntry, sizeof (EFI_MEMORY_DESCRIPTOR)); | |
+ } | |
+ | |
+ NextEfiEntry = NEXT_MEMORY_DESCRIPTOR (NextEfiEntry, EfiDescriptorSize); | |
+ } | |
+ | |
+ EfiEntry = NEXT_MEMORY_DESCRIPTOR (EfiEntry, EfiDescriptorSize); | |
+ NextEfiEntry = NEXT_MEMORY_DESCRIPTOR (EfiEntry, EfiDescriptorSize); | |
+ } | |
+ | |
+ EfiEntry = EfiMemoryMap; | |
+ EfiMemoryMapEnd = (EFI_MEMORY_DESCRIPTOR *) ((UINT8 *) EfiMemoryMap + EfiMemoryMapSize); | |
+ for (Index = Above1MIndex; (EfiEntry < EfiMemoryMapEnd) && (Index < EFI_MAX_E820_ENTRY - 1); ) { | |
+ MemoryBlockLength = (UINT64) (LShiftU64 (EfiEntry->NumberOfPages, 12)); | |
+ if ((EfiEntry->PhysicalStart + MemoryBlockLength) < 0x100000) { | |
+ // | |
+ // Skip the memory block is under 1MB | |
+ // | |
+ } else { | |
+ if (EfiEntry->PhysicalStart < 0x100000) { | |
+ // | |
+ // When the memory block spans below 1MB, ensure the memory block start address is at least 1MB | |
+ // | |
+ MemoryBlockLength -= 0x100000 - EfiEntry->PhysicalStart; | |
+ EfiEntry->PhysicalStart = 0x100000; | |
+ } | |
+ | |
+ // | |
+ // Convert memory type to E820 type | |
+ // | |
+ TempType = EfiMemoryTypeToE820Type (EfiEntry->Type); | |
+ | |
+ if ((E820Table[Index].Type == TempType) && (EfiEntry->PhysicalStart == (E820Table[Index].BaseAddr + E820Table[Index].Length))) { | |
+ // | |
+ // Grow an existing entry | |
+ // | |
+ E820Table[Index].Length += MemoryBlockLength; | |
+ } else { | |
+ // | |
+ // Make a new entry | |
+ // | |
+ ++Index; | |
+ E820Table[Index].BaseAddr = EfiEntry->PhysicalStart; | |
+ E820Table[Index].Length = MemoryBlockLength; | |
+ E820Table[Index].Type = TempType; | |
+ } | |
+ } | |
+ EfiEntry = NEXT_MEMORY_DESCRIPTOR (EfiEntry, EfiDescriptorSize); | |
+ } | |
+ | |
+ FreePool (EfiMemoryMap); | |
+ | |
+ // | |
+ // Process the reserved memory map to produce E820 map ; | |
+ // | |
+ for (Hob.Raw = GetHobList (); !END_OF_HOB_LIST (Hob); Hob.Raw = GET_NEXT_HOB (Hob)) { | |
+ if (Hob.Raw != NULL && GET_HOB_TYPE (Hob) == EFI_HOB_TYPE_RESOURCE_DESCRIPTOR) { | |
+ ResourceHob = Hob.ResourceDescriptor; | |
+ if (((ResourceHob->ResourceType == EFI_RESOURCE_MEMORY_MAPPED_IO) || | |
+ (ResourceHob->ResourceType == EFI_RESOURCE_FIRMWARE_DEVICE) || | |
+ (ResourceHob->ResourceType == EFI_RESOURCE_MEMORY_RESERVED) ) && | |
+ (ResourceHob->PhysicalStart > 0x100000) && | |
+ (Index < EFI_MAX_E820_ENTRY - 1)) { | |
+ ++Index; | |
+ E820Table[Index].BaseAddr = ResourceHob->PhysicalStart; | |
+ E820Table[Index].Length = ResourceHob->ResourceLength; | |
+ E820Table[Index].Type = EfiAcpiAddressRangeReserved; | |
+ } | |
+ } | |
+ } | |
+ | |
+ Index ++; | |
+ Private->IntThunk->EfiToLegacy16InitTable.NumberE820Entries = (UINT32)Index; | |
+ Private->IntThunk->EfiToLegacy16BootTable.NumberE820Entries = (UINT32)Index; | |
+ Private->NumberE820Entries = (UINT32)Index; | |
+ *Size = (UINTN) (Index * sizeof (EFI_E820_ENTRY64)); | |
+ | |
+ // | |
+ // Sort E820Table from low to high | |
+ // | |
+ for (TempIndex = 0; TempIndex < Index; TempIndex++) { | |
+ ChangedFlag = FALSE; | |
+ for (TempNextIndex = 1; TempNextIndex < Index - TempIndex; TempNextIndex++) { | |
+ if (E820Table[TempNextIndex - 1].BaseAddr > E820Table[TempNextIndex].BaseAddr) { | |
+ ChangedFlag = TRUE; | |
+ TempE820.BaseAddr = E820Table[TempNextIndex - 1].BaseAddr; | |
+ TempE820.Length = E820Table[TempNextIndex - 1].Length; | |
+ TempE820.Type = E820Table[TempNextIndex - 1].Type; | |
+ | |
+ E820Table[TempNextIndex - 1].BaseAddr = E820Table[TempNextIndex].BaseAddr; | |
+ E820Table[TempNextIndex - 1].Length = E820Table[TempNextIndex].Length; | |
+ E820Table[TempNextIndex - 1].Type = E820Table[TempNextIndex].Type; | |
+ | |
+ E820Table[TempNextIndex].BaseAddr = TempE820.BaseAddr; | |
+ E820Table[TempNextIndex].Length = TempE820.Length; | |
+ E820Table[TempNextIndex].Type = TempE820.Type; | |
+ } | |
+ } | |
+ | |
+ if (!ChangedFlag) { | |
+ break; | |
+ } | |
+ } | |
+ | |
+ // | |
+ // Remove the overlap range | |
+ // | |
+ for (TempIndex = 1; TempIndex < Index; TempIndex++) { | |
+ if (E820Table[TempIndex - 1].BaseAddr <= E820Table[TempIndex].BaseAddr && | |
+ ((E820Table[TempIndex - 1].BaseAddr + E820Table[TempIndex - 1].Length) >= | |
+ (E820Table[TempIndex].BaseAddr +E820Table[TempIndex].Length))) { | |
+ // | |
+ //Overlap range is found | |
+ // | |
+ ASSERT (E820Table[TempIndex - 1].Type == E820Table[TempIndex].Type); | |
+ | |
+ if (TempIndex == Index - 1) { | |
+ E820Table[TempIndex].BaseAddr = 0; | |
+ E820Table[TempIndex].Length = 0; | |
+ E820Table[TempIndex].Type = (EFI_ACPI_MEMORY_TYPE) 0; | |
+ Index--; | |
+ break; | |
+ } else { | |
+ for (IndexSort = TempIndex; IndexSort < Index - 1; IndexSort ++) { | |
+ E820Table[IndexSort].BaseAddr = E820Table[IndexSort + 1].BaseAddr; | |
+ E820Table[IndexSort].Length = E820Table[IndexSort + 1].Length; | |
+ E820Table[IndexSort].Type = E820Table[IndexSort + 1].Type; | |
+ } | |
+ Index--; | |
+ } | |
+ } | |
+ } | |
+ | |
+ | |
+ | |
+ Private->IntThunk->EfiToLegacy16InitTable.NumberE820Entries = (UINT32)Index; | |
+ Private->IntThunk->EfiToLegacy16BootTable.NumberE820Entries = (UINT32)Index; | |
+ Private->NumberE820Entries = (UINT32)Index; | |
+ *Size = (UINTN) (Index * sizeof (EFI_E820_ENTRY64)); | |
+ | |
+ // | |
+ // Determine OS usable memory above 1Mb | |
+ // | |
+ Private->IntThunk->EfiToLegacy16BootTable.OsMemoryAbove1Mb = 0x0000; | |
+ for (TempIndex = Above1MIndex; TempIndex < Index; TempIndex++) { | |
+ if (E820Table[TempIndex].BaseAddr >= 0x100000 && E820Table[TempIndex].BaseAddr < 0x100000000ULL) { // not include above 4G memory | |
+ // | |
+ // ACPIReclaimMemory is also usable memory for ACPI OS, after OS dumps all ACPI tables. | |
+ // | |
+ if ((E820Table[TempIndex].Type == EfiAcpiAddressRangeMemory) || (E820Table[TempIndex].Type == EfiAcpiAddressRangeACPI)) { | |
+ Private->IntThunk->EfiToLegacy16BootTable.OsMemoryAbove1Mb += (UINT32) (E820Table[TempIndex].Length); | |
+ } else { | |
+ break; // break at first not normal memory, because SMM may use reserved memory. | |
+ } | |
+ } | |
+ } | |
+ | |
+ Private->IntThunk->EfiToLegacy16InitTable.OsMemoryAbove1Mb = Private->IntThunk->EfiToLegacy16BootTable.OsMemoryAbove1Mb; | |
+ | |
+ // | |
+ // Print DEBUG information | |
+ // | |
+ for (TempIndex = 0; TempIndex < Index; TempIndex++) { | |
+ DEBUG((EFI_D_INFO, "E820[%2d]: 0x%16lx ---- 0x%16lx, Type = 0x%x \n", | |
+ TempIndex, | |
+ E820Table[TempIndex].BaseAddr, | |
+ (E820Table[TempIndex].BaseAddr + E820Table[TempIndex].Length), | |
+ E820Table[TempIndex].Type | |
+ )); | |
+ } | |
+ | |
+ return EFI_SUCCESS; | |
+} | |
+ | |
+ | |
+/** | |
+ Fill in the standard BDA and EBDA stuff prior to legacy Boot | |
+ | |
+ @param Private Legacy BIOS Instance data | |
+ | |
+ @retval EFI_SUCCESS It should always work. | |
+ | |
+**/ | |
+EFI_STATUS | |
+LegacyBiosCompleteBdaBeforeBoot ( | |
+ IN LEGACY_BIOS_INSTANCE *Private | |
+ ) | |
+{ | |
+ BDA_STRUC *Bda; | |
+ UINT16 MachineConfig; | |
+ DEVICE_PRODUCER_DATA_HEADER *SioPtr; | |
+ | |
+ Bda = (BDA_STRUC *) ((UINTN) 0x400); | |
+ MachineConfig = 0; | |
+ | |
+ SioPtr = &(Private->IntThunk->EfiToLegacy16BootTable.SioData); | |
+ Bda->Com1 = SioPtr->Serial[0].Address; | |
+ Bda->Com2 = SioPtr->Serial[1].Address; | |
+ Bda->Com3 = SioPtr->Serial[2].Address; | |
+ Bda->Com4 = SioPtr->Serial[3].Address; | |
+ | |
+ if (SioPtr->Serial[0].Address != 0x00) { | |
+ MachineConfig += 0x200; | |
+ } | |
+ | |
+ if (SioPtr->Serial[1].Address != 0x00) { | |
+ MachineConfig += 0x200; | |
+ } | |
+ | |
+ if (SioPtr->Serial[2].Address != 0x00) { | |
+ MachineConfig += 0x200; | |
+ } | |
+ | |
+ if (SioPtr->Serial[3].Address != 0x00) { | |
+ MachineConfig += 0x200; | |
+ } | |
+ | |
+ Bda->Lpt1 = SioPtr->Parallel[0].Address; | |
+ Bda->Lpt2 = SioPtr->Parallel[1].Address; | |
+ Bda->Lpt3 = SioPtr->Parallel[2].Address; | |
+ | |
+ if (SioPtr->Parallel[0].Address != 0x00) { | |
+ MachineConfig += 0x4000; | |
+ } | |
+ | |
+ if (SioPtr->Parallel[1].Address != 0x00) { | |
+ MachineConfig += 0x4000; | |
+ } | |
+ | |
+ if (SioPtr->Parallel[2].Address != 0x00) { | |
+ MachineConfig += 0x4000; | |
+ } | |
+ | |
+ Bda->NumberOfDrives = (UINT8) (Bda->NumberOfDrives + Private->IdeDriveCount); | |
+ if (SioPtr->Floppy.NumberOfFloppy != 0x00) { | |
+ MachineConfig = (UINT16) (MachineConfig + 0x01 + (SioPtr->Floppy.NumberOfFloppy - 1) * 0x40); | |
+ Bda->FloppyXRate = 0x07; | |
+ } | |
+ | |
+ Bda->Lpt1_2Timeout = 0x1414; | |
+ Bda->Lpt3_4Timeout = 0x1414; | |
+ Bda->Com1_2Timeout = 0x0101; | |
+ Bda->Com3_4Timeout = 0x0101; | |
+ | |
+ // | |
+ // Force VGA and Coprocessor, indicate 101/102 keyboard | |
+ // | |
+ MachineConfig = (UINT16) (MachineConfig + 0x00 + 0x02 + (SioPtr->MousePresent * 0x04)); | |
+ Bda->MachineConfig = MachineConfig; | |
+ | |
+ return EFI_SUCCESS; | |
+} | |
+ | |
+/** | |
+ Fill in the standard BDA for Keyboard LEDs | |
+ | |
+ @param This Protocol instance pointer. | |
+ @param Leds Current LED status | |
+ | |
+ @retval EFI_SUCCESS It should always work. | |
+ | |
+**/ | |
+EFI_STATUS | |
+EFIAPI | |
+LegacyBiosUpdateKeyboardLedStatus ( | |
+ IN EFI_LEGACY_BIOS_PROTOCOL *This, | |
+ IN UINT8 Leds | |
+ ) | |
+{ | |
+ LEGACY_BIOS_INSTANCE *Private; | |
+ BDA_STRUC *Bda; | |
+ UINT8 LocalLeds; | |
+ EFI_IA32_REGISTER_SET Regs; | |
+ | |
+ Bda = (BDA_STRUC *) ((UINTN) 0x400); | |
+ | |
+ Private = LEGACY_BIOS_INSTANCE_FROM_THIS (This); | |
+ LocalLeds = Leds; | |
+ Bda->LedStatus = (UINT8) ((Bda->LedStatus &~0x07) | LocalLeds); | |
+ LocalLeds = (UINT8) (LocalLeds << 4); | |
+ Bda->ShiftStatus = (UINT8) ((Bda->ShiftStatus &~0x70) | LocalLeds); | |
+ LocalLeds = (UINT8) (Leds & 0x20); | |
+ Bda->KeyboardStatus = (UINT8) ((Bda->KeyboardStatus &~0x20) | LocalLeds); | |
+ // | |
+ // Call into Legacy16 code to allow it to do any processing | |
+ // | |
+ ZeroMem (&Regs, sizeof (EFI_IA32_REGISTER_SET)); | |
+ Regs.X.AX = Legacy16SetKeyboardLeds; | |
+ Regs.H.CL = Leds; | |
+ | |
+ Private->LegacyBios.FarCall86 ( | |
+ &Private->LegacyBios, | |
+ Private->Legacy16Table->Compatibility16CallSegment, | |
+ Private->Legacy16Table->Compatibility16CallOffset, | |
+ &Regs, | |
+ NULL, | |
+ 0 | |
+ ); | |
+ | |
+ return EFI_SUCCESS; | |
+} | |
+ | |
+ | |
+/** | |
+ Fill in the standard CMOS stuff prior to legacy Boot | |
+ | |
+ @param Private Legacy BIOS Instance data | |
+ | |
+ @retval EFI_SUCCESS It should always work. | |
+ | |
+**/ | |
+EFI_STATUS | |
+LegacyBiosCompleteStandardCmosBeforeBoot ( | |
+ IN LEGACY_BIOS_INSTANCE *Private | |
+ ) | |
+{ | |
+ UINT8 Bda; | |
+ UINT8 Floppy; | |
+ UINT32 Size; | |
+ | |
+ // | |
+ // Update CMOS locations | |
+ // 10 floppy | |
+ // 12,19,1A - ignore as OS don't use them and there is no standard due | |
+ // to large capacity drives | |
+ // CMOS 14 = BDA 40:10 plus bit 3(display enabled) | |
+ // | |
+ Bda = (UINT8)(*((UINT8 *)((UINTN)0x410)) | BIT3); | |
+ | |
+ // | |
+ // Force display enabled | |
+ // | |
+ Floppy = 0x00; | |
+ if ((Bda & BIT0) != 0) { | |
+ Floppy = BIT6; | |
+ } | |
+ | |
+ // | |
+ // Check if 2.88MB floppy set | |
+ // | |
+ if ((Bda & (BIT7 | BIT6)) != 0) { | |
+ Floppy = (UINT8)(Floppy | BIT1); | |
+ } | |
+ | |
+ LegacyWriteStandardCmos (CMOS_10, Floppy); | |
+ LegacyWriteStandardCmos (CMOS_14, Bda); | |
+ | |
+ // | |
+ // Force Status Register A to set rate selection bits and divider | |
+ // | |
+ LegacyWriteStandardCmos (CMOS_0A, 0x26); | |
+ | |
+ // | |
+ // redo memory size since it can change | |
+ // | |
+ Size = (15 * SIZE_1MB) >> 10; | |
+ if (Private->IntThunk->EfiToLegacy16InitTable.OsMemoryAbove1Mb < (15 * SIZE_1MB)) { | |
+ Size = Private->IntThunk->EfiToLegacy16InitTable.OsMemoryAbove1Mb >> 10; | |
+ } | |
+ | |
+ LegacyWriteStandardCmos (CMOS_17, (UINT8)(Size & 0xFF)); | |
+ LegacyWriteStandardCmos (CMOS_30, (UINT8)(Size & 0xFF)); | |
+ LegacyWriteStandardCmos (CMOS_18, (UINT8)(Size >> 8)); | |
+ LegacyWriteStandardCmos (CMOS_31, (UINT8)(Size >> 8)); | |
+ | |
+ LegacyCalculateWriteStandardCmosChecksum (); | |
+ | |
+ return EFI_SUCCESS; | |
+} | |
+ | |
+/** | |
+ Relocate this image under 4G memory for IPF. | |
+ | |
+ @param ImageHandle Handle of driver image. | |
+ @param SystemTable Pointer to system table. | |
+ | |
+ @retval EFI_SUCCESS Image successfully relocated. | |
+ @retval EFI_ABORTED Failed to relocate image. | |
+ | |
+**/ | |
+EFI_STATUS | |
+RelocateImageUnder4GIfNeeded ( | |
+ IN EFI_HANDLE ImageHandle, | |
+ IN EFI_SYSTEM_TABLE *SystemTable | |
+ ) | |
+{ | |
+ return EFI_SUCCESS; | |
+} | |
diff --git a/OvmfPkg/CsmOld/LegacyBiosDxe/LegacyCmos.c b/OvmfPkg/CsmOld/LegacyBiosDxe/LegacyCmos.c | |
new file mode 100644 | |
index 000000000000..0fbf90281336 | |
--- /dev/null | |
+++ b/OvmfPkg/CsmOld/LegacyBiosDxe/LegacyCmos.c | |
@@ -0,0 +1,124 @@ | |
+/** @file | |
+ This code fills in standard CMOS values and updates the standard CMOS | |
+ checksum. The Legacy16 code or LegacyBiosPlatform.c is responsible for | |
+ non-standard CMOS locations and non-standard checksums. | |
+ | |
+Copyright (c) 2006 - 2010, 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. | |
+ | |
+**/ | |
+ | |
+#include "LegacyBiosInterface.h" | |
+ | |
+/** | |
+ Read CMOS register through index/data port. | |
+ | |
+ @param[in] Index The index of the CMOS register to read. | |
+ | |
+ @return The data value from the CMOS register specified by Index. | |
+ | |
+**/ | |
+UINT8 | |
+LegacyReadStandardCmos ( | |
+ IN UINT8 Index | |
+ ) | |
+{ | |
+ IoWrite8 (PORT_70, Index); | |
+ return IoRead8 (PORT_71); | |
+} | |
+ | |
+/** | |
+ Write CMOS register through index/data port. | |
+ | |
+ @param[in] Index The index of the CMOS register to write. | |
+ @param[in] Value The value of CMOS register to write. | |
+ | |
+ @return The value written to the CMOS register specified by Index. | |
+ | |
+**/ | |
+UINT8 | |
+LegacyWriteStandardCmos ( | |
+ IN UINT8 Index, | |
+ IN UINT8 Value | |
+ ) | |
+{ | |
+ IoWrite8 (PORT_70, Index); | |
+ return IoWrite8 (PORT_71, Value); | |
+} | |
+ | |
+/** | |
+ Calculate the new standard CMOS checksum and write it. | |
+ | |
+ @param Private Legacy BIOS Instance data | |
+ | |
+ @retval EFI_SUCCESS Calculate 16-bit checksum successfully | |
+ | |
+**/ | |
+EFI_STATUS | |
+LegacyCalculateWriteStandardCmosChecksum ( | |
+ VOID | |
+ ) | |
+{ | |
+ UINT8 Register; | |
+ UINT16 Checksum; | |
+ | |
+ for (Checksum = 0, Register = 0x10; Register < 0x2e; Register++) { | |
+ Checksum = (UINT16)(Checksum + LegacyReadStandardCmos (Register)); | |
+ } | |
+ LegacyWriteStandardCmos (CMOS_2E, (UINT8)(Checksum >> 8)); | |
+ LegacyWriteStandardCmos (CMOS_2F, (UINT8)(Checksum & 0xff)); | |
+ return EFI_SUCCESS; | |
+} | |
+ | |
+ | |
+/** | |
+ Fill in the standard CMOS stuff before Legacy16 load | |
+ | |
+ @param Private Legacy BIOS Instance data | |
+ | |
+ @retval EFI_SUCCESS It should always work. | |
+ | |
+**/ | |
+EFI_STATUS | |
+LegacyBiosInitCmos ( | |
+ IN LEGACY_BIOS_INSTANCE *Private | |
+ ) | |
+{ | |
+ UINT32 Size; | |
+ | |
+ // | |
+ // Clear all errors except RTC lost power | |
+ // | |
+ LegacyWriteStandardCmos (CMOS_0E, (UINT8)(LegacyReadStandardCmos (CMOS_0E) & BIT7)); | |
+ | |
+ // | |
+ // Update CMOS locations 15,16,17,18,30,31 and 32 | |
+ // CMOS 16,15 = 640Kb = 0x280 | |
+ // CMOS 18,17 = 31,30 = 15Mb max in 1Kb increments =0x3C00 max | |
+ // CMOS 32 = 0x20 | |
+ // | |
+ LegacyWriteStandardCmos (CMOS_15, 0x80); | |
+ LegacyWriteStandardCmos (CMOS_16, 0x02); | |
+ | |
+ Size = 15 * SIZE_1MB; | |
+ if (Private->IntThunk->EfiToLegacy16InitTable.OsMemoryAbove1Mb < (15 * SIZE_1MB)) { | |
+ Size = Private->IntThunk->EfiToLegacy16InitTable.OsMemoryAbove1Mb >> 10; | |
+ } | |
+ | |
+ LegacyWriteStandardCmos (CMOS_17, (UINT8)(Size & 0xFF)); | |
+ LegacyWriteStandardCmos (CMOS_30, (UINT8)(Size & 0xFF)); | |
+ LegacyWriteStandardCmos (CMOS_18, (UINT8)(Size >> 8)); | |
+ LegacyWriteStandardCmos (CMOS_31, (UINT8)(Size >> 8)); | |
+ | |
+ LegacyCalculateWriteStandardCmosChecksum (); | |
+ | |
+ return EFI_SUCCESS; | |
+} | |
diff --git a/OvmfPkg/CsmOld/LegacyBiosDxe/LegacyIde.c b/OvmfPkg/CsmOld/LegacyBiosDxe/LegacyIde.c | |
new file mode 100644 | |
index 000000000000..3570b8e0b62a | |
--- /dev/null | |
+++ b/OvmfPkg/CsmOld/LegacyBiosDxe/LegacyIde.c | |
@@ -0,0 +1,334 @@ | |
+/** @file | |
+ Collect IDE information from Native EFI Driver | |
+ | |
+Copyright (c) 2006 - 2010, 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. | |
+ | |
+**/ | |
+ | |
+#include "LegacyBiosInterface.h" | |
+ | |
+BOOLEAN mIdeDataBuiltFlag = FALSE; | |
+ | |
+/** | |
+ Collect IDE Inquiry data from the IDE disks | |
+ | |
+ @param Private Legacy BIOS Instance data | |
+ @param HddInfo Hdd Information | |
+ @param Flag Reconnect IdeController or not | |
+ | |
+ @retval EFI_SUCCESS It should always work. | |
+ | |
+**/ | |
+EFI_STATUS | |
+LegacyBiosBuildIdeData ( | |
+ IN LEGACY_BIOS_INSTANCE *Private, | |
+ IN HDD_INFO **HddInfo, | |
+ IN UINT16 Flag | |
+ ) | |
+{ | |
+ EFI_STATUS Status; | |
+ EFI_HANDLE IdeController; | |
+ UINTN HandleCount; | |
+ EFI_HANDLE *HandleBuffer; | |
+ UINTN Index; | |
+ EFI_DISK_INFO_PROTOCOL *DiskInfo; | |
+ UINT32 IdeChannel; | |
+ UINT32 IdeDevice; | |
+ UINT32 Size; | |
+ UINT8 *InquiryData; | |
+ UINT32 InquiryDataSize; | |
+ HDD_INFO *LocalHddInfo; | |
+ UINT32 PciIndex; | |
+ EFI_DEVICE_PATH_PROTOCOL *DevicePath; | |
+ EFI_DEVICE_PATH_PROTOCOL *DevicePathNode; | |
+ EFI_DEVICE_PATH_PROTOCOL *TempDevicePathNode; | |
+ PCI_DEVICE_PATH *PciDevicePath; | |
+ BOOLEAN PciDPFound = FALSE; | |
+ UINTN PciDPDevice = 0; | |
+ UINTN PciDPFunction = 0; | |
+ | |
+ // | |
+ // Only build data once | |
+ // We have a problem with GetBbsInfo in that it can be invoked two | |
+ // places. Once in BDS, when all EFI drivers are connected and once in | |
+ // LegacyBoot after all EFI drivers are disconnected causing this routine | |
+ // to hang. In LegacyBoot this function is also called before EFI drivers | |
+ // are disconnected. | |
+ // Cases covered | |
+ // GetBbsInfo invoked in BDS. Both invocations in LegacyBoot ignored. | |
+ // GetBbsInfo not invoked in BDS. First invocation of this function | |
+ // proceeds normally and second via GetBbsInfo ignored. | |
+ // | |
+ PciDevicePath = NULL; | |
+ LocalHddInfo = *HddInfo; | |
+ Status = Private->LegacyBiosPlatform->GetPlatformHandle ( | |
+ Private->LegacyBiosPlatform, | |
+ EfiGetPlatformIdeHandle, | |
+ 0, | |
+ &HandleBuffer, | |
+ &HandleCount, | |
+ (VOID *) &LocalHddInfo | |
+ ); | |
+ if (!EFI_ERROR (Status)) { | |
+ IdeController = HandleBuffer[0]; | |
+ // | |
+ // Force IDE drive spin up! | |
+ // | |
+ if (Flag != 0) { | |
+ gBS->DisconnectController ( | |
+ IdeController, | |
+ NULL, | |
+ NULL | |
+ ); | |
+ } | |
+ | |
+ gBS->ConnectController (IdeController, NULL, NULL, FALSE); | |
+ | |
+ // | |
+ // Do GetIdeHandle twice since disconnect/reconnect will switch to native mode | |
+ // And GetIdeHandle will switch to Legacy mode, if required. | |
+ // | |
+ Private->LegacyBiosPlatform->GetPlatformHandle ( | |
+ Private->LegacyBiosPlatform, | |
+ EfiGetPlatformIdeHandle, | |
+ 0, | |
+ &HandleBuffer, | |
+ &HandleCount, | |
+ (VOID *) &LocalHddInfo | |
+ ); | |
+ } | |
+ | |
+ mIdeDataBuiltFlag = TRUE; | |
+ | |
+ // | |
+ // Get Identity command from all drives | |
+ // | |
+ gBS->LocateHandleBuffer ( | |
+ ByProtocol, | |
+ &gEfiDiskInfoProtocolGuid, | |
+ NULL, | |
+ &HandleCount, | |
+ &HandleBuffer | |
+ ); | |
+ | |
+ Private->IdeDriveCount = (UINT8) HandleCount; | |
+ for (Index = 0; Index < HandleCount; Index++) { | |
+ Status = gBS->HandleProtocol ( | |
+ HandleBuffer[Index], | |
+ &gEfiDiskInfoProtocolGuid, | |
+ (VOID **) &DiskInfo | |
+ ); | |
+ ASSERT_EFI_ERROR (Status); | |
+ | |
+ if (CompareGuid (&DiskInfo->Interface, &gEfiDiskInfoIdeInterfaceGuid) || CompareGuid (&DiskInfo->Interface, &gEfiDiskInfoAhciInterfaceGuid)) { | |
+ // | |
+ // Locate which PCI device | |
+ // | |
+ Status = gBS->HandleProtocol ( | |
+ HandleBuffer[Index], | |
+ &gEfiDevicePathProtocolGuid, | |
+ (VOID *) &DevicePath | |
+ ); | |
+ ASSERT_EFI_ERROR (Status); | |
+ | |
+ DevicePathNode = DevicePath; | |
+ while (!IsDevicePathEnd (DevicePathNode)) { | |
+ TempDevicePathNode = NextDevicePathNode (DevicePathNode); | |
+ if ((DevicePathType (DevicePathNode) == HARDWARE_DEVICE_PATH) && | |
+ ( DevicePathSubType (DevicePathNode) == HW_PCI_DP) && | |
+ ( DevicePathType(TempDevicePathNode) == MESSAGING_DEVICE_PATH) && | |
+ ( DevicePathSubType(TempDevicePathNode) == MSG_ATAPI_DP || DevicePathSubType (TempDevicePathNode) == MSG_SATA_DP) ) { | |
+ PciDevicePath = (PCI_DEVICE_PATH *) DevicePathNode; | |
+ break; | |
+ } | |
+ DevicePathNode = NextDevicePathNode (DevicePathNode); | |
+ } | |
+ | |
+ if (PciDevicePath == NULL) { | |
+ continue; | |
+ } | |
+ | |
+ // | |
+ // Find start of PCI device in HddInfo. The assumption of the data | |
+ // structure is 2 controllers(channels) per PCI device and each | |
+ // controller can have 2 drives(devices). | |
+ // HddInfo[PciIndex+0].[0] = Channel[0].Device[0] Primary Master | |
+ // HddInfo[PciIndex+0].[1] = Channel[0].Device[1] Primary Slave | |
+ // HddInfo[PciIndex+1].[0] = Channel[1].Device[0] Secondary Master | |
+ // HddInfo[PciIndex+1].[1] = Channel[1].Device[1] Secondary Slave | |
+ // @bug eventually need to pass in max number of entries | |
+ // for end of for loop | |
+ // | |
+ /*for (PciIndex = 0; PciIndex < 8; PciIndex++) { | |
+ if ((PciDevicePath->Device == LocalHddInfo[PciIndex].Device) && | |
+ (PciDevicePath->Function == LocalHddInfo[PciIndex].Function) | |
+ ) { | |
+ break; | |
+ } | |
+ } | |
+ | |
+ if (PciIndex == 8) { | |
+ continue; | |
+ }*/ | |
+ | |
+ // Support single IDE or AHCI controller (each can contain multiple devices/channels). | |
+ if (PciDPFound && (PciDevicePath->Device =! PciDPDevice || PciDevicePath->Function != PciDPFunction)) { | |
+ continue; | |
+ } | |
+ PciIndex = 0; | |
+ | |
+ Status = DiskInfo->WhichIde (DiskInfo, &IdeChannel, &IdeDevice); | |
+ if (!EFI_ERROR (Status)) { | |
+ // There are 8 slots in HddInfo | |
+ if (PciIndex + IdeChannel >= 8) { | |
+ continue; | |
+ } | |
+ PciDPFound = TRUE; | |
+ PciDPDevice = PciDevicePath->Device; | |
+ PciDPFunction = PciDevicePath->Function; | |
+ | |
+ Size = sizeof (ATAPI_IDENTIFY); | |
+ DiskInfo->Identify ( | |
+ DiskInfo, | |
+ &LocalHddInfo[PciIndex + IdeChannel].IdentifyDrive[IdeDevice], | |
+ &Size | |
+ ); | |
+ if (IdeChannel == 0) { | |
+ LocalHddInfo[PciIndex + IdeChannel].Status |= HDD_PRIMARY; | |
+ } else if (IdeChannel == 1) { | |
+ LocalHddInfo[PciIndex + IdeChannel].Status |= HDD_SECONDARY; | |
+ } | |
+ | |
+ InquiryData = NULL; | |
+ InquiryDataSize = 0; | |
+ Status = DiskInfo->Inquiry ( | |
+ DiskInfo, | |
+ NULL, | |
+ &InquiryDataSize | |
+ ); | |
+ if (Status == EFI_BUFFER_TOO_SMALL) { | |
+ InquiryData = (UINT8 *) AllocatePool ( | |
+ InquiryDataSize | |
+ ); | |
+ if (InquiryData != NULL) { | |
+ Status = DiskInfo->Inquiry ( | |
+ DiskInfo, | |
+ InquiryData, | |
+ &InquiryDataSize | |
+ ); | |
+ } | |
+ } else { | |
+ Status = EFI_DEVICE_ERROR; | |
+ } | |
+ | |
+ // | |
+ // If ATAPI device then Inquiry will pass and ATA fail. | |
+ // | |
+ if (!EFI_ERROR (Status)) { | |
+ ASSERT (InquiryData != NULL); | |
+ // | |
+ // If IdeDevice = 0 then set master bit, else slave bit | |
+ // | |
+ if (IdeDevice == 0) { | |
+ if ((InquiryData[0] & 0x1f) == 0x05) { | |
+ LocalHddInfo[PciIndex + IdeChannel].Status |= HDD_MASTER_ATAPI_CDROM; | |
+ } else if ((InquiryData[0] & 0x1f) == 0x00) { | |
+ LocalHddInfo[PciIndex + IdeChannel].Status |= HDD_MASTER_ATAPI_ZIPDISK; | |
+ } | |
+ } else { | |
+ if ((InquiryData[0] & 0x1f) == 0x05) { | |
+ LocalHddInfo[PciIndex + IdeChannel].Status |= HDD_SLAVE_ATAPI_CDROM; | |
+ } else if ((InquiryData[0] & 0x1f) == 0x00) { | |
+ LocalHddInfo[PciIndex + IdeChannel].Status |= HDD_SLAVE_ATAPI_ZIPDISK; | |
+ } | |
+ } | |
+ FreePool (InquiryData); | |
+ } else { | |
+ if (IdeDevice == 0) { | |
+ LocalHddInfo[PciIndex + IdeChannel].Status |= HDD_MASTER_IDE; | |
+ } else { | |
+ LocalHddInfo[PciIndex + IdeChannel].Status |= HDD_SLAVE_IDE; | |
+ } | |
+ } | |
+ } | |
+ } | |
+ } | |
+ | |
+ if (HandleBuffer != NULL) { | |
+ FreePool (HandleBuffer); | |
+ } | |
+ | |
+ return EFI_SUCCESS; | |
+} | |
+ | |
+ | |
+/** | |
+ If the IDE channel is in compatibility (legacy) mode, remove all | |
+ PCI I/O BAR addresses from the controller. | |
+ | |
+ @param IdeController The handle of target IDE controller | |
+ | |
+ | |
+**/ | |
+VOID | |
+InitLegacyIdeController ( | |
+ IN EFI_HANDLE IdeController | |
+ ) | |
+{ | |
+ EFI_PCI_IO_PROTOCOL *PciIo; | |
+ UINT32 IOBarClear; | |
+ EFI_STATUS Status; | |
+ PCI_TYPE00 PciData; | |
+ | |
+ // | |
+ // If the IDE channel is in compatibility (legacy) mode, remove all | |
+ // PCI I/O BAR addresses from the controller. Some software gets | |
+ // confused if an IDE controller is in compatibility (legacy) mode | |
+ // and has PCI I/O resources allocated | |
+ // | |
+ Status = gBS->HandleProtocol ( | |
+ IdeController, | |
+ &gEfiPciIoProtocolGuid, | |
+ (VOID **)&PciIo | |
+ ); | |
+ if (EFI_ERROR (Status)) { | |
+ return ; | |
+ } | |
+ | |
+ Status = PciIo->Pci.Read (PciIo, EfiPciIoWidthUint8, 0, sizeof (PciData), &PciData); | |
+ if (EFI_ERROR (Status)) { | |
+ return ; | |
+ } | |
+ | |
+ // | |
+ // Check whether this is IDE | |
+ // | |
+ if ((PciData.Hdr.ClassCode[2] != PCI_CLASS_MASS_STORAGE) || | |
+ (PciData.Hdr.ClassCode[1] != PCI_CLASS_MASS_STORAGE_IDE)) { | |
+ return ; | |
+ } | |
+ | |
+ // | |
+ // Clear bar for legacy IDE | |
+ // | |
+ IOBarClear = 0x00; | |
+ if ((PciData.Hdr.ClassCode[0] & IDE_PI_REGISTER_PNE) == 0) { | |
+ PciIo->Pci.Write (PciIo, EfiPciIoWidthUint32, 0x10, 1, &IOBarClear); | |
+ PciIo->Pci.Write (PciIo, EfiPciIoWidthUint32, 0x14, 1, &IOBarClear); | |
+ } | |
+ if ((PciData.Hdr.ClassCode[0] & IDE_PI_REGISTER_SNE) == 0) { | |
+ PciIo->Pci.Write (PciIo, EfiPciIoWidthUint32, 0x18, 1, &IOBarClear); | |
+ PciIo->Pci.Write (PciIo, EfiPciIoWidthUint32, 0x1C, 1, &IOBarClear); | |
+ } | |
+ | |
+ return ; | |
+} | |
diff --git a/OvmfPkg/CsmOld/LegacyBiosDxe/LegacyPci.c b/OvmfPkg/CsmOld/LegacyBiosDxe/LegacyPci.c | |
new file mode 100644 | |
index 000000000000..ef238f7a02ed | |
--- /dev/null | |
+++ b/OvmfPkg/CsmOld/LegacyBiosDxe/LegacyPci.c | |
@@ -0,0 +1,3005 @@ | |
+/** @file | |
+ | |
+Copyright (c) 2006 - 2014, 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. | |
+ | |
+**/ | |
+ | |
+#include "LegacyBiosInterface.h" | |
+#include <IndustryStandard/Pci30.h> | |
+ | |
+#define PCI_START_ADDRESS(x) (((x) + 0x7ff) & ~0x7ff) | |
+ | |
+#define MAX_BRIDGE_INDEX 0x20 | |
+typedef struct { | |
+ UINTN PciSegment; | |
+ UINTN PciBus; | |
+ UINTN PciDevice; | |
+ UINTN PciFunction; | |
+ UINT8 PrimaryBus; | |
+ UINT8 SecondaryBus; | |
+ UINT8 SubordinateBus; | |
+} BRIDGE_TABLE; | |
+ | |
+#define ROM_MAX_ENTRIES 24 | |
+BRIDGE_TABLE Bridges[MAX_BRIDGE_INDEX]; | |
+UINTN SortedBridgeIndex[MAX_BRIDGE_INDEX]; | |
+UINTN NumberOfBridges; | |
+LEGACY_PNP_EXPANSION_HEADER *mBasePnpPtr; | |
+UINT16 mBbsRomSegment; | |
+UINTN mHandleCount; | |
+EFI_HANDLE mVgaHandle; | |
+BOOLEAN mIgnoreBbsUpdateFlag; | |
+BOOLEAN mVgaInstallationInProgress = FALSE; | |
+UINT32 mRomCount = 0x00; | |
+ROM_INSTANCE_ENTRY mRomEntry[ROM_MAX_ENTRIES]; | |
+ | |
+ | |
+/** | |
+ Query shadowed legacy ROM parameters registered by RomShadow() previously. | |
+ | |
+ @param PciHandle PCI device whos ROM has been shadowed | |
+ @param DiskStart DiskStart value from EFI_LEGACY_BIOS_PROTOCOL.InstallPciRom | |
+ @param DiskEnd DiskEnd value from EFI_LEGACY_BIOS_PROTOCOL.InstallPciRom | |
+ @param RomShadowAddress Address where ROM was shadowed | |
+ @param ShadowedSize Runtime size of ROM | |
+ | |
+ @retval EFI_SUCCESS Query Logging successful. | |
+ @retval EFI_NOT_FOUND No logged data found about PciHandle. | |
+ | |
+**/ | |
+EFI_STATUS | |
+GetShadowedRomParameters ( | |
+ IN EFI_HANDLE PciHandle, | |
+ OUT UINT8 *DiskStart, OPTIONAL | |
+ OUT UINT8 *DiskEnd, OPTIONAL | |
+ OUT VOID **RomShadowAddress, OPTIONAL | |
+ OUT UINTN *ShadowedSize OPTIONAL | |
+ ) | |
+{ | |
+ EFI_STATUS Status; | |
+ EFI_PCI_IO_PROTOCOL *PciIo; | |
+ UINTN Index; | |
+ UINTN PciSegment; | |
+ UINTN PciBus; | |
+ UINTN PciDevice; | |
+ UINTN PciFunction; | |
+ | |
+ // | |
+ // Get the PCI I/O Protocol on PciHandle | |
+ // | |
+ Status = gBS->HandleProtocol ( | |
+ PciHandle, | |
+ &gEfiPciIoProtocolGuid, | |
+ (VOID **) &PciIo | |
+ ); | |
+ if (EFI_ERROR (Status)) { | |
+ return Status; | |
+ } | |
+ | |
+ // | |
+ // Get the location of the PCI device | |
+ // | |
+ PciIo->GetLocation ( | |
+ PciIo, | |
+ &PciSegment, | |
+ &PciBus, | |
+ &PciDevice, | |
+ &PciFunction | |
+ ); | |
+ | |
+ for(Index = 0; Index < mRomCount; Index++) { | |
+ if ((mRomEntry[Index].PciSegment == PciSegment) && | |
+ (mRomEntry[Index].PciBus == PciBus) && | |
+ (mRomEntry[Index].PciDevice == PciDevice) && | |
+ (mRomEntry[Index].PciFunction == PciFunction)) { | |
+ break; | |
+ } | |
+ } | |
+ | |
+ if (Index == mRomCount) { | |
+ return EFI_NOT_FOUND; | |
+ } | |
+ | |
+ if (DiskStart != NULL) { | |
+ *DiskStart = mRomEntry[Index].DiskStart; | |
+ } | |
+ | |
+ if (DiskEnd != NULL) { | |
+ *DiskEnd = mRomEntry[Index].DiskEnd; | |
+ } | |
+ | |
+ if (RomShadowAddress != NULL) { | |
+ *RomShadowAddress = (VOID *)(UINTN)mRomEntry[Index].ShadowAddress; | |
+ } | |
+ | |
+ if (ShadowedSize != NULL) { | |
+ *ShadowedSize = mRomEntry[Index].ShadowedSize; | |
+ } | |
+ | |
+ return EFI_SUCCESS; | |
+} | |
+ | |
+/** | |
+ Every legacy ROM that is shadowed by the Legacy BIOS driver will be | |
+ registered into this API so that the policy code can know what has | |
+ happend | |
+ | |
+ @param PciHandle PCI device whos ROM is being shadowed | |
+ @param ShadowAddress Address that ROM was shadowed | |
+ @param ShadowedSize Runtime size of ROM | |
+ @param DiskStart DiskStart value from | |
+ EFI_LEGACY_BIOS_PROTOCOL.InstallPciRom | |
+ @param DiskEnd DiskEnd value from | |
+ EFI_LEGACY_BIOS_PROTOCOL.InstallPciRom | |
+ | |
+ @retval EFI_SUCCESS Logging successful. | |
+ @retval EFI_OUT_OF_RESOURCES No remaining room for registering another option | |
+ ROM. | |
+ | |
+**/ | |
+EFI_STATUS | |
+RomShadow ( | |
+ IN EFI_HANDLE PciHandle, | |
+ IN UINT32 ShadowAddress, | |
+ IN UINT32 ShadowedSize, | |
+ IN UINT8 DiskStart, | |
+ IN UINT8 DiskEnd | |
+ ) | |
+{ | |
+ EFI_STATUS Status; | |
+ EFI_PCI_IO_PROTOCOL *PciIo; | |
+ | |
+ // | |
+ // See if there is room to register another option ROM | |
+ // | |
+ if (mRomCount >= ROM_MAX_ENTRIES) { | |
+ return EFI_OUT_OF_RESOURCES; | |
+ } | |
+ // | |
+ // Get the PCI I/O Protocol on PciHandle | |
+ // | |
+ Status = gBS->HandleProtocol ( | |
+ PciHandle, | |
+ &gEfiPciIoProtocolGuid, | |
+ (VOID **) &PciIo | |
+ ); | |
+ if (EFI_ERROR (Status)) { | |
+ return Status; | |
+ } | |
+ // | |
+ // Get the location of the PCI device | |
+ // | |
+ PciIo->GetLocation ( | |
+ PciIo, | |
+ &mRomEntry[mRomCount].PciSegment, | |
+ &mRomEntry[mRomCount].PciBus, | |
+ &mRomEntry[mRomCount].PciDevice, | |
+ &mRomEntry[mRomCount].PciFunction | |
+ ); | |
+ mRomEntry[mRomCount].ShadowAddress = ShadowAddress; | |
+ mRomEntry[mRomCount].ShadowedSize = ShadowedSize; | |
+ mRomEntry[mRomCount].DiskStart = DiskStart; | |
+ mRomEntry[mRomCount].DiskEnd = DiskEnd; | |
+ | |
+ mRomCount++; | |
+ | |
+ return EFI_SUCCESS; | |
+} | |
+ | |
+ | |
+/** | |
+ Return EFI_SUCCESS if PciHandle has had a legacy BIOS ROM shadowed. This | |
+ information represents every call to RomShadow () | |
+ | |
+ @param PciHandle PCI device to get status for | |
+ | |
+ @retval EFI_SUCCESS Legacy ROM loaded for this device | |
+ @retval EFI_NOT_FOUND No Legacy ROM loaded for this device | |
+ | |
+**/ | |
+EFI_STATUS | |
+IsLegacyRom ( | |
+ IN EFI_HANDLE PciHandle | |
+ ) | |
+{ | |
+ EFI_STATUS Status; | |
+ EFI_PCI_IO_PROTOCOL *PciIo; | |
+ UINTN Index; | |
+ UINTN Segment; | |
+ UINTN Bus; | |
+ UINTN Device; | |
+ UINTN Function; | |
+ | |
+ // | |
+ // Get the PCI I/O Protocol on PciHandle | |
+ // | |
+ Status = gBS->HandleProtocol ( | |
+ PciHandle, | |
+ &gEfiPciIoProtocolGuid, | |
+ (VOID **) &PciIo | |
+ ); | |
+ if (EFI_ERROR (Status)) { | |
+ return Status; | |
+ } | |
+ // | |
+ // Get the location of the PCI device | |
+ // | |
+ PciIo->GetLocation ( | |
+ PciIo, | |
+ &Segment, | |
+ &Bus, | |
+ &Device, | |
+ &Function | |
+ ); | |
+ | |
+ // | |
+ // See if the option ROM from PciHandle has been previously posted | |
+ // | |
+ for (Index = 0; Index < mRomCount; Index++) { | |
+ if (mRomEntry[Index].PciSegment == Segment && | |
+ mRomEntry[Index].PciBus == Bus && | |
+ mRomEntry[Index].PciDevice == Device && | |
+ mRomEntry[Index].PciFunction == Function | |
+ ) { | |
+ return EFI_SUCCESS; | |
+ } | |
+ } | |
+ | |
+ return EFI_NOT_FOUND; | |
+} | |
+ | |
+/** | |
+ Find the PC-AT ROM Image in the raw PCI Option ROM. Also return the | |
+ related information from the header. | |
+ | |
+ @param Csm16Revision The PCI interface version of underlying CSM16 | |
+ @param VendorId Vendor ID of the PCI device | |
+ @param DeviceId Device ID of the PCI device | |
+ @param Rom On input pointing to beginning of the raw PCI OpROM | |
+ On output pointing to the first legacy PCI OpROM | |
+ @param ImageSize On input is the size of Raw PCI Rom | |
+ On output is the size of the first legacy PCI ROM | |
+ @param MaxRuntimeImageLength The max runtime image length only valid if OpRomRevision >= 3 | |
+ @param OpRomRevision Revision of the PCI Rom | |
+ @param ConfigUtilityCodeHeader Pointer to Configuration Utility Code Header | |
+ | |
+ @retval EFI_SUCCESS Successfully find the legacy PCI ROM | |
+ @retval EFI_NOT_FOUND Failed to find the legacy PCI ROM | |
+ | |
+**/ | |
+EFI_STATUS | |
+GetPciLegacyRom ( | |
+ IN UINT16 Csm16Revision, | |
+ IN UINT16 VendorId, | |
+ IN UINT16 DeviceId, | |
+ IN OUT VOID **Rom, | |
+ IN OUT UINTN *ImageSize, | |
+ OUT UINTN *MaxRuntimeImageLength, OPTIONAL | |
+ OUT UINT8 *OpRomRevision, OPTIONAL | |
+ OUT VOID **ConfigUtilityCodeHeader OPTIONAL | |
+ ) | |
+{ | |
+ BOOLEAN Match; | |
+ UINT16 *DeviceIdList; | |
+ EFI_PCI_ROM_HEADER RomHeader; | |
+ PCI_3_0_DATA_STRUCTURE *Pcir; | |
+ VOID *BackupImage; | |
+ VOID *BestImage; | |
+ | |
+ | |
+ if (*ImageSize < sizeof (EFI_PCI_ROM_HEADER)) { | |
+ return EFI_NOT_FOUND; | |
+ } | |
+ | |
+ BestImage = NULL; | |
+ BackupImage = NULL; | |
+ RomHeader.Raw = *Rom; | |
+ while (RomHeader.Generic->Signature == PCI_EXPANSION_ROM_HEADER_SIGNATURE) { | |
+ if (RomHeader.Generic->PcirOffset == 0 || | |
+ (RomHeader.Generic->PcirOffset & 3) !=0 || | |
+ *ImageSize < RomHeader.Raw - (UINT8 *) *Rom + RomHeader.Generic->PcirOffset + sizeof (PCI_DATA_STRUCTURE)) { | |
+ break; | |
+ } | |
+ | |
+ Pcir = (PCI_3_0_DATA_STRUCTURE *) (RomHeader.Raw + RomHeader.Generic->PcirOffset); | |
+ // | |
+ // Check signature in the PCI Data Structure. | |
+ // | |
+ if (Pcir->Signature != PCI_DATA_STRUCTURE_SIGNATURE) { | |
+ break; | |
+ } | |
+ | |
+ if ((UINTN)(RomHeader.Raw - (UINT8 *) *Rom) + Pcir->ImageLength * 512 > *ImageSize) { | |
+ break; | |
+ } | |
+ | |
+ if (Pcir->CodeType == PCI_CODE_TYPE_PCAT_IMAGE) { | |
+ Match = FALSE; | |
+ if (Pcir->VendorId == VendorId) { | |
+ if (Pcir->DeviceId == DeviceId) { | |
+ Match = TRUE; | |
+ } else if ((Pcir->Revision >= 3) && (Pcir->DeviceListOffset != 0)) { | |
+ DeviceIdList = (UINT16 *)(((UINT8 *) Pcir) + Pcir->DeviceListOffset); | |
+ // | |
+ // Checking the device list | |
+ // | |
+ while (*DeviceIdList != 0) { | |
+ if (*DeviceIdList == DeviceId) { | |
+ Match = TRUE; | |
+ break; | |
+ } | |
+ DeviceIdList ++; | |
+ } | |
+ } | |
+ } | |
+ | |
+ if (Match) { | |
+ if (Csm16Revision >= 0x0300) { | |
+ // | |
+ // Case 1: CSM16 3.0 | |
+ // | |
+ if (Pcir->Revision >= 3) { | |
+ // | |
+ // case 1.1: meets OpRom 3.0 | |
+ // Perfect!!! | |
+ // | |
+ BestImage = RomHeader.Raw; | |
+ break; | |
+ } else { | |
+ // | |
+ // case 1.2: meets OpRom 2.x | |
+ // Store it and try to find the OpRom 3.0 | |
+ // | |
+ BackupImage = RomHeader.Raw; | |
+ } | |
+ } else { | |
+ // | |
+ // Case 2: CSM16 2.x | |
+ // | |
+ if (Pcir->Revision >= 3) { | |
+ // | |
+ // case 2.1: meets OpRom 3.0 | |
+ // Store it and try to find the OpRom 2.x | |
+ // | |
+ BackupImage = RomHeader.Raw; | |
+ } else { | |
+ // | |
+ // case 2.2: meets OpRom 2.x | |
+ // Perfect!!! | |
+ // | |
+ BestImage = RomHeader.Raw; | |
+ break; | |
+ } | |
+ } | |
+ } else { | |
+ DEBUG ((EFI_D_ERROR, "GetPciLegacyRom - OpRom not match (%04x-%04x)\n", (UINTN)VendorId, (UINTN)DeviceId)); | |
+ } | |
+ } | |
+ | |
+ if ((Pcir->Indicator & 0x80) == 0x80) { | |
+ break; | |
+ } else { | |
+ RomHeader.Raw += 512 * Pcir->ImageLength; | |
+ } | |
+ } | |
+ | |
+ if (BestImage == NULL) { | |
+ if (BackupImage == NULL) { | |
+ return EFI_NOT_FOUND; | |
+ } | |
+ // | |
+ // The versions of CSM16 and OpRom don't match exactly | |
+ // | |
+ BestImage = BackupImage; | |
+ } | |
+ RomHeader.Raw = BestImage; | |
+ Pcir = (PCI_3_0_DATA_STRUCTURE *) (RomHeader.Raw + RomHeader.Generic->PcirOffset); | |
+ *Rom = BestImage; | |
+ *ImageSize = Pcir->ImageLength * 512; | |
+ | |
+ if (MaxRuntimeImageLength != NULL) { | |
+ if (Pcir->Revision < 3) { | |
+ *MaxRuntimeImageLength = 0; | |
+ } else { | |
+ *MaxRuntimeImageLength = Pcir->MaxRuntimeImageLength * 512; | |
+ } | |
+ } | |
+ | |
+ if (OpRomRevision != NULL) { | |
+ // | |
+ // Optional return PCI Data Structure revision | |
+ // | |
+ if (Pcir->Length >= 0x1C) { | |
+ *OpRomRevision = Pcir->Revision; | |
+ } else { | |
+ *OpRomRevision = 0; | |
+ } | |
+ } | |
+ | |
+ if (ConfigUtilityCodeHeader != NULL) { | |
+ // | |
+ // Optional return ConfigUtilityCodeHeaderOffset supported by the PC-AT ROM | |
+ // | |
+ if ((Pcir->Revision < 3) || (Pcir->ConfigUtilityCodeHeaderOffset == 0)) { | |
+ *ConfigUtilityCodeHeader = NULL; | |
+ } else { | |
+ *ConfigUtilityCodeHeader = RomHeader.Raw + Pcir->ConfigUtilityCodeHeaderOffset; | |
+ } | |
+ } | |
+ | |
+ return EFI_SUCCESS; | |
+} | |
+ | |
+/** | |
+ Build a table of bridge info for PIRQ translation. | |
+ | |
+ @param RoutingTable RoutingTable obtained from Platform. | |
+ @param RoutingTableEntries Number of RoutingTable entries. | |
+ | |
+ @retval EFI_SUCCESS New Subordinate bus. | |
+ @retval EFI_NOT_FOUND No more Subordinate busses. | |
+ | |
+**/ | |
+EFI_STATUS | |
+CreateBridgeTable ( | |
+ IN EFI_LEGACY_IRQ_ROUTING_ENTRY *RoutingTable, | |
+ IN UINTN RoutingTableEntries | |
+ ) | |
+{ | |
+ EFI_STATUS Status; | |
+ UINTN HandleCount; | |
+ EFI_HANDLE *HandleBuffer; | |
+ UINTN BridgeIndex; | |
+ UINTN Index; | |
+ UINTN Index1; | |
+ EFI_PCI_IO_PROTOCOL *PciIo; | |
+ PCI_TYPE01 PciConfigHeader; | |
+ BRIDGE_TABLE SlotBridges[MAX_BRIDGE_INDEX]; | |
+ UINTN SlotBridgeIndex; | |
+ | |
+ BridgeIndex = 0x00; | |
+ SlotBridgeIndex = 0x00; | |
+ | |
+ // | |
+ // Assumption is table is built from low bus to high bus numbers. | |
+ // | |
+ Status = gBS->LocateHandleBuffer ( | |
+ ByProtocol, | |
+ &gEfiPciIoProtocolGuid, | |
+ NULL, | |
+ &HandleCount, | |
+ &HandleBuffer | |
+ ); | |
+ if (EFI_ERROR (Status)) { | |
+ return EFI_NOT_FOUND; | |
+ } | |
+ for (Index = 0; Index < HandleCount; Index++) { | |
+ Status = gBS->HandleProtocol ( | |
+ HandleBuffer[Index], | |
+ &gEfiPciIoProtocolGuid, | |
+ (VOID **) &PciIo | |
+ ); | |
+ if (EFI_ERROR (Status)) { | |
+ continue; | |
+ } | |
+ | |
+ PciIo->Pci.Read ( | |
+ PciIo, | |
+ EfiPciIoWidthUint32, | |
+ 0, | |
+ sizeof (PciConfigHeader) / sizeof (UINT32), | |
+ &PciConfigHeader | |
+ ); | |
+ | |
+ if (IS_PCI_P2P (&PciConfigHeader) && (BridgeIndex < MAX_BRIDGE_INDEX)) { | |
+ PciIo->GetLocation ( | |
+ PciIo, | |
+ &Bridges[BridgeIndex].PciSegment, | |
+ &Bridges[BridgeIndex].PciBus, | |
+ &Bridges[BridgeIndex].PciDevice, | |
+ &Bridges[BridgeIndex].PciFunction | |
+ ); | |
+ | |
+ Bridges[BridgeIndex].PrimaryBus = PciConfigHeader.Bridge.PrimaryBus; | |
+ | |
+ Bridges[BridgeIndex].SecondaryBus = PciConfigHeader.Bridge.SecondaryBus; | |
+ | |
+ Bridges[BridgeIndex].SubordinateBus = PciConfigHeader.Bridge.SubordinateBus; | |
+ | |
+ for (Index1 = 0; Index1 < RoutingTableEntries; Index1++){ | |
+ // | |
+ // Test whether we have found the Bridge in the slot, must be the one that directly interfaced to the board | |
+ // Once we find one, store it in the SlotBridges[] | |
+ // | |
+ if ((RoutingTable[Index1].Slot != 0) && (Bridges[BridgeIndex].PrimaryBus == RoutingTable[Index1].Bus) | |
+ && ((Bridges[BridgeIndex].PciDevice << 3) == RoutingTable[Index1].Device)) { | |
+ CopyMem (&SlotBridges[SlotBridgeIndex], &Bridges[BridgeIndex], sizeof (BRIDGE_TABLE)); | |
+ SlotBridgeIndex++; | |
+ | |
+ break; | |
+ } | |
+ } | |
+ | |
+ ++BridgeIndex; | |
+ } | |
+ } | |
+ | |
+ // | |
+ // Pack up Bridges by removing those useless ones | |
+ // | |
+ for (Index = 0; Index < BridgeIndex;){ | |
+ for (Index1 = 0; Index1 < SlotBridgeIndex; Index1++) { | |
+ if (((Bridges[Index].PciBus == SlotBridges[Index1].PrimaryBus) && (Bridges[Index].PciDevice == SlotBridges[Index1].PciDevice)) || | |
+ ((Bridges[Index].PciBus >= SlotBridges[Index1].SecondaryBus) && (Bridges[Index].PciBus <= SlotBridges[Index1].SubordinateBus))) { | |
+ // | |
+ // We have found one that meets our criteria | |
+ // | |
+ Index++; | |
+ break; | |
+ } | |
+ } | |
+ | |
+ // | |
+ // This one doesn't meet criteria, pack it | |
+ // | |
+ if (Index1 >= SlotBridgeIndex) { | |
+ for (Index1 = Index; BridgeIndex > 1 && Index1 < BridgeIndex - 1 ; Index1++) { | |
+ CopyMem (&Bridges[Index1], &Bridges[Index1 + 1], sizeof (BRIDGE_TABLE)); | |
+ } | |
+ | |
+ BridgeIndex--; | |
+ } | |
+ } | |
+ | |
+ NumberOfBridges = BridgeIndex; | |
+ | |
+ // | |
+ // Sort bridges low to high by Secondary bus followed by subordinate bus | |
+ // | |
+ if (NumberOfBridges > 1) { | |
+ Index = 0; | |
+ do { | |
+ SortedBridgeIndex[Index] = Index; | |
+ ++Index; | |
+ } while (Index < NumberOfBridges); | |
+ | |
+ for (Index = 0; Index < NumberOfBridges - 1; Index++) { | |
+ for (Index1 = Index + 1; Index1 < NumberOfBridges; Index1++) { | |
+ if (Bridges[Index].SecondaryBus > Bridges[Index1].SecondaryBus) { | |
+ SortedBridgeIndex[Index] = Index1; | |
+ SortedBridgeIndex[Index1] = Index; | |
+ } | |
+ | |
+ if ((Bridges[Index].SecondaryBus == Bridges[Index1].SecondaryBus) && | |
+ (Bridges[Index].SubordinateBus > Bridges[Index1].SubordinateBus) | |
+ ) { | |
+ SortedBridgeIndex[Index] = Index1; | |
+ SortedBridgeIndex[Index1] = Index; | |
+ } | |
+ } | |
+ } | |
+ } | |
+ FreePool (HandleBuffer); | |
+ return EFI_SUCCESS; | |
+} | |
+ | |
+ | |
+/** | |
+ Find base Bridge for device. | |
+ | |
+ @param Private Legacy BIOS Instance data | |
+ @param PciBus Input = Bus of device. | |
+ @param PciDevice Input = Device. | |
+ @param RoutingTable The platform specific routing table | |
+ @param RoutingTableEntries Number of entries in table | |
+ | |
+ @retval EFI_SUCCESS At base bus. | |
+ @retval EFI_NOT_FOUND Behind a bridge. | |
+ | |
+**/ | |
+EFI_STATUS | |
+GetBaseBus ( | |
+ IN LEGACY_BIOS_INSTANCE *Private, | |
+ IN UINTN PciBus, | |
+ IN UINTN PciDevice, | |
+ IN EFI_LEGACY_IRQ_ROUTING_ENTRY *RoutingTable, | |
+ IN UINTN RoutingTableEntries | |
+ ) | |
+{ | |
+ UINTN Index; | |
+ for (Index = 0; Index < RoutingTableEntries; Index++) { | |
+ if ((RoutingTable[Index].Bus == PciBus) && (RoutingTable[Index].Device == (PciDevice << 3))) { | |
+ return EFI_SUCCESS; | |
+ } | |
+ } | |
+ | |
+ return EFI_NOT_FOUND; | |
+} | |
+ | |
+/** | |
+ Translate PIRQ through busses | |
+ | |
+ @param Private Legacy BIOS Instance data | |
+ @param PciBus Input = Bus of device. Output = Translated Bus | |
+ @param PciDevice Input = Device. Output = Translated Device | |
+ @param PciFunction Input = Function. Output = Translated Function | |
+ @param PirqIndex Input = Original PIRQ index. If single function | |
+ device then 0, otherwise 0-3. | |
+ Output = Translated Index | |
+ | |
+ @retval EFI_SUCCESS Pirq successfully translated. | |
+ @retval EFI_NOT_FOUND The device is not behind any known bridge. | |
+ | |
+**/ | |
+EFI_STATUS | |
+TranslateBusPirq ( | |
+ IN LEGACY_BIOS_INSTANCE *Private, | |
+ IN OUT UINTN *PciBus, | |
+ IN OUT UINTN *PciDevice, | |
+ IN OUT UINTN *PciFunction, | |
+ IN OUT UINT8 *PirqIndex | |
+ ) | |
+{ | |
+ /* | |
+ This routine traverses the PCI busses from base slot | |
+ and translates the PIRQ register to the appropriate one. | |
+ | |
+ Example: | |
+ | |
+ Bus 0, Device 1 is PCI-PCI bridge that all PCI slots reside on. | |
+ Primary bus# = 0 | |
+ Secondary bus # = 1 | |
+ Subordinate bus # is highest bus # behind this bus | |
+ Bus 1, Device 0 is Slot 0 and is not a bridge. | |
+ Bus 1, Device 1 is Slot 1 and is a bridge. | |
+ Slot PIRQ routing is A,B,C,D. | |
+ Primary bus # = 1 | |
+ Secondary bus # = 2 | |
+ Subordinate bus # = 5 | |
+ Bus 2, Device 6 is a bridge. It has no bridges behind it. | |
+ Primary bus # = 2 | |
+ Secondary bus # = 3 | |
+ Subordinate bus # = 3 | |
+ Bridge PIRQ routing is C,D,A,B | |
+ Bus 2, Device 7 is a bridge. It has 1 bridge behind it. | |
+ Primary bus # = 2 | |
+ Secondary bus = 4 Device 6 takes bus 2. | |
+ Subordinate bus = 5. | |
+ Bridge PIRQ routing is D,A,B,C | |
+ Bus 4, Device 2 is a bridge. It has no bridges behind it. | |
+ Primary bus # = 4 | |
+ Secondary bus # = 5 | |
+ Subordinate bus = 5 | |
+ Bridge PIRQ routing is B,C,D,A | |
+ Bus 5, Device 1 is to be programmed. | |
+ Device PIRQ routing is C,D,A,B | |
+ | |
+ | |
+Search busses starting from slot bus for final bus >= Secondary bus and | |
+final bus <= Suborninate bus. Assumption is bus entries increase in bus | |
+number. | |
+Starting PIRQ is A,B,C,D. | |
+Bus 2, Device 7 satisfies search criteria. Rotate (A,B,C,D) left by device | |
+ 7 modulo 4 giving (D,A,B,C). | |
+Bus 4, Device 2 satisfies search criteria. Rotate (D,A,B,C) left by 2 giving | |
+ (B,C,D,A). | |
+No other busses match criteria. Device to be programmed is Bus 5, Device 1. | |
+Rotate (B,C,D,A) by 1 giving C,D,A,B. Translated PIRQ is C. | |
+ | |
+*/ | |
+ UINTN LocalBus; | |
+ UINTN LocalDevice; | |
+ UINTN BaseBus; | |
+ UINTN BaseDevice; | |
+ UINTN BaseFunction; | |
+ UINT8 LocalPirqIndex; | |
+ BOOLEAN BaseIndexFlag; | |
+ UINTN BridgeIndex; | |
+ UINTN SBridgeIndex; | |
+ BaseIndexFlag = FALSE; | |
+ BridgeIndex = 0x00; | |
+ | |
+ LocalPirqIndex = *PirqIndex; | |
+ LocalBus = *PciBus; | |
+ LocalDevice = *PciDevice; | |
+ BaseBus = *PciBus; | |
+ BaseDevice = *PciDevice; | |
+ BaseFunction = *PciFunction; | |
+ | |
+ // | |
+ // LocalPirqIndex list PIRQs in rotated fashion | |
+ // = 0 A,B,C,D | |
+ // = 1 B,C,D,A | |
+ // = 2 C,D,A,B | |
+ // = 3 D,A,B,C | |
+ // | |
+ | |
+ for (BridgeIndex = 0; BridgeIndex < NumberOfBridges; BridgeIndex++) { | |
+ SBridgeIndex = SortedBridgeIndex[BridgeIndex]; | |
+ // | |
+ // Check if device behind this bridge | |
+ // | |
+ if ((LocalBus >= Bridges[SBridgeIndex].SecondaryBus) && (LocalBus <= Bridges[SBridgeIndex].SubordinateBus)) { | |
+ // | |
+ // If BaseIndexFlag = FALSE then have found base bridge, i.e | |
+ // bridge in slot. Save info for use by IRQ routing table. | |
+ // | |
+ if (!BaseIndexFlag) { | |
+ BaseBus = Bridges[SBridgeIndex].PciBus; | |
+ BaseDevice = Bridges[SBridgeIndex].PciDevice; | |
+ BaseFunction = Bridges[SBridgeIndex].PciFunction; | |
+ BaseIndexFlag = TRUE; | |
+ } else { | |
+ LocalPirqIndex = (UINT8) ((LocalPirqIndex + (UINT8)Bridges[SBridgeIndex].PciDevice)%4); | |
+ } | |
+ | |
+ // | |
+ // Check if at device. If not get new PCI location & PIRQ | |
+ // | |
+ if (Bridges[SBridgeIndex].SecondaryBus == (UINT8) LocalBus) { | |
+ // | |
+ // Translate PIRQ | |
+ // | |
+ LocalPirqIndex = (UINT8) ((LocalPirqIndex + (UINT8) (LocalDevice)) % 4); | |
+ break; | |
+ } | |
+ } | |
+ } | |
+ | |
+ // | |
+ // In case we fail to find the Bridge just above us, this is some potential error and we want to warn the user | |
+ // | |
+ if(BridgeIndex >= NumberOfBridges){ | |
+ DEBUG ((EFI_D_ERROR, "Cannot Find IRQ Routing for Bus %d, Device %d, Function %d\n", *PciBus, *PciDevice, *PciFunction)); | |
+ } | |
+ | |
+ *PirqIndex = LocalPirqIndex; | |
+ *PciBus = BaseBus; | |
+ *PciDevice = BaseDevice; | |
+ *PciFunction = BaseFunction; | |
+ | |
+ return EFI_SUCCESS; | |
+} | |
+ | |
+ | |
+/** | |
+ Copy the $PIR table as required. | |
+ | |
+ @param Private Legacy BIOS Instance data | |
+ @param RoutingTable Pointer to IRQ routing table | |
+ @param RoutingTableEntries IRQ routing table entries | |
+ @param PirqTable Pointer to $PIR table | |
+ @param PirqTableSize Length of table | |
+ | |
+**/ | |
+VOID | |
+CopyPirqTable ( | |
+ IN LEGACY_BIOS_INSTANCE *Private, | |
+ IN EFI_LEGACY_IRQ_ROUTING_ENTRY *RoutingTable, | |
+ IN UINTN RoutingTableEntries, | |
+ IN EFI_LEGACY_PIRQ_TABLE_HEADER *PirqTable, | |
+ IN UINTN PirqTableSize | |
+ ) | |
+{ | |
+ EFI_IA32_REGISTER_SET Regs; | |
+ UINT32 Granularity; | |
+ | |
+ // | |
+ // Copy $PIR table, if it exists. | |
+ // | |
+ if (PirqTable != NULL) { | |
+ Private->LegacyRegion->UnLock ( | |
+ Private->LegacyRegion, | |
+ 0xE0000, | |
+ 0x20000, | |
+ &Granularity | |
+ ); | |
+ | |
+ Private->InternalIrqRoutingTable = RoutingTable; | |
+ Private->NumberIrqRoutingEntries = (UINT16) (RoutingTableEntries); | |
+ ZeroMem (&Regs, sizeof (EFI_IA32_REGISTER_SET)); | |
+ | |
+ Regs.X.AX = Legacy16GetTableAddress; | |
+ Regs.X.CX = (UINT16) PirqTableSize; | |
+ // | |
+ // Allocate at F segment according to PCI IRQ Routing Table Specification | |
+ // | |
+ Regs.X.BX = (UINT16) 0x1; | |
+ // | |
+ // 16-byte boundary alignment requirement according to | |
+ // PCI IRQ Routing Table Specification | |
+ // | |
+ Regs.X.DX = 0x10; | |
+ Private->LegacyBios.FarCall86 ( | |
+ &Private->LegacyBios, | |
+ Private->Legacy16CallSegment, | |
+ Private->Legacy16CallOffset, | |
+ &Regs, | |
+ NULL, | |
+ 0 | |
+ ); | |
+ | |
+ Private->Legacy16Table->IrqRoutingTablePointer = (UINT32) (Regs.X.DS * 16 + Regs.X.BX); | |
+ if (Regs.X.AX != 0) { | |
+ DEBUG ((EFI_D_ERROR, "PIRQ table length insufficient - %x\n", PirqTableSize)); | |
+ } else { | |
+ DEBUG ((EFI_D_INFO, "PIRQ table in legacy region - %x\n", Private->Legacy16Table->IrqRoutingTablePointer)); | |
+ Private->Legacy16Table->IrqRoutingTableLength = (UINT32)PirqTableSize; | |
+ CopyMem ( | |
+ (VOID *) (UINTN)Private->Legacy16Table->IrqRoutingTablePointer, | |
+ PirqTable, | |
+ PirqTableSize | |
+ ); | |
+ } | |
+ | |
+ Private->Cpu->FlushDataCache (Private->Cpu, 0xE0000, 0x20000, EfiCpuFlushTypeWriteBackInvalidate); | |
+ Private->LegacyRegion->Lock ( | |
+ Private->LegacyRegion, | |
+ 0xE0000, | |
+ 0x20000, | |
+ &Granularity | |
+ ); | |
+ } | |
+ | |
+ Private->PciInterruptLine = TRUE; | |
+ mHandleCount = 0; | |
+} | |
+ | |
+/** | |
+ Dump EFI_LEGACY_INSTALL_PCI_HANDLER structure information. | |
+ | |
+ @param PciHandle The pointer to EFI_LEGACY_INSTALL_PCI_HANDLER structure | |
+ | |
+**/ | |
+VOID | |
+DumpPciHandle ( | |
+ IN EFI_LEGACY_INSTALL_PCI_HANDLER *PciHandle | |
+ ) | |
+{ | |
+ DEBUG ((EFI_D_INFO, "PciBus - %02x\n", (UINTN)PciHandle->PciBus)); | |
+ DEBUG ((EFI_D_INFO, "PciDeviceFun - %02x\n", (UINTN)PciHandle->PciDeviceFun)); | |
+ DEBUG ((EFI_D_INFO, "PciSegment - %02x\n", (UINTN)PciHandle->PciSegment)); | |
+ DEBUG ((EFI_D_INFO, "PciClass - %02x\n", (UINTN)PciHandle->PciClass)); | |
+ DEBUG ((EFI_D_INFO, "PciSubclass - %02x\n", (UINTN)PciHandle->PciSubclass)); | |
+ DEBUG ((EFI_D_INFO, "PciInterface - %02x\n", (UINTN)PciHandle->PciInterface)); | |
+ | |
+ DEBUG ((EFI_D_INFO, "PrimaryIrq - %02x\n", (UINTN)PciHandle->PrimaryIrq)); | |
+ DEBUG ((EFI_D_INFO, "PrimaryReserved - %02x\n", (UINTN)PciHandle->PrimaryReserved)); | |
+ DEBUG ((EFI_D_INFO, "PrimaryControl - %04x\n", (UINTN)PciHandle->PrimaryControl)); | |
+ DEBUG ((EFI_D_INFO, "PrimaryBase - %04x\n", (UINTN)PciHandle->PrimaryBase)); | |
+ DEBUG ((EFI_D_INFO, "PrimaryBusMaster - %04x\n", (UINTN)PciHandle->PrimaryBusMaster)); | |
+ | |
+ DEBUG ((EFI_D_INFO, "SecondaryIrq - %02x\n", (UINTN)PciHandle->SecondaryIrq)); | |
+ DEBUG ((EFI_D_INFO, "SecondaryReserved - %02x\n", (UINTN)PciHandle->SecondaryReserved)); | |
+ DEBUG ((EFI_D_INFO, "SecondaryControl - %04x\n", (UINTN)PciHandle->SecondaryControl)); | |
+ DEBUG ((EFI_D_INFO, "SecondaryBase - %04x\n", (UINTN)PciHandle->SecondaryBase)); | |
+ DEBUG ((EFI_D_INFO, "SecondaryBusMaster - %04x\n", (UINTN)PciHandle->SecondaryBusMaster)); | |
+ return; | |
+} | |
+ | |
+/** | |
+ Copy the $PIR table as required. | |
+ | |
+ @param Private Legacy BIOS Instance data | |
+ @param PciIo Pointer to PCI_IO protocol | |
+ @param PciIrq Pci IRQ number | |
+ @param PciConfigHeader Type00 Pci configuration header | |
+ | |
+**/ | |
+VOID | |
+InstallLegacyIrqHandler ( | |
+ IN LEGACY_BIOS_INSTANCE *Private, | |
+ IN EFI_PCI_IO_PROTOCOL *PciIo, | |
+ IN UINT8 PciIrq, | |
+ IN PCI_TYPE00 *PciConfigHeader | |
+ ) | |
+{ | |
+ EFI_IA32_REGISTER_SET Regs; | |
+ UINT16 LegMask; | |
+ UINTN PciSegment; | |
+ UINTN PciBus; | |
+ UINTN PciDevice; | |
+ UINTN PciFunction; | |
+ EFI_LEGACY_8259_PROTOCOL *Legacy8259; | |
+ UINT16 PrimaryMaster; | |
+ UINT16 SecondaryMaster; | |
+ UINTN TempData; | |
+ UINTN RegisterAddress; | |
+ UINT32 Granularity; | |
+ | |
+ PrimaryMaster = 0; | |
+ SecondaryMaster = 0; | |
+ Legacy8259 = Private->Legacy8259; | |
+ // | |
+ // Disable interrupt in PIC, in case shared, to prevent an | |
+ // interrupt from occuring. | |
+ // | |
+ Legacy8259->GetMask ( | |
+ Legacy8259, | |
+ &LegMask, | |
+ NULL, | |
+ NULL, | |
+ NULL | |
+ ); | |
+ | |
+ LegMask = (UINT16) (LegMask | (UINT16) (1 << PciIrq)); | |
+ | |
+ Legacy8259->SetMask ( | |
+ Legacy8259, | |
+ &LegMask, | |
+ NULL, | |
+ NULL, | |
+ NULL | |
+ ); | |
+ | |
+ PciIo->GetLocation ( | |
+ PciIo, | |
+ &PciSegment, | |
+ &PciBus, | |
+ &PciDevice, | |
+ &PciFunction | |
+ ); | |
+ Private->IntThunk->PciHandler.PciBus = (UINT8) PciBus; | |
+ Private->IntThunk->PciHandler.PciDeviceFun = (UINT8) ((PciDevice << 3) + PciFunction); | |
+ Private->IntThunk->PciHandler.PciSegment = (UINT8) PciSegment; | |
+ Private->IntThunk->PciHandler.PciClass = PciConfigHeader->Hdr.ClassCode[2]; | |
+ Private->IntThunk->PciHandler.PciSubclass = PciConfigHeader->Hdr.ClassCode[1]; | |
+ Private->IntThunk->PciHandler.PciInterface = PciConfigHeader->Hdr.ClassCode[0]; | |
+ | |
+ // | |
+ // Use native mode base address registers in two cases: | |
+ // 1. Programming Interface (PI) register indicates Primary Controller is | |
+ // in native mode OR | |
+ // 2. PCI device Sub Class Code is not IDE | |
+ // | |
+ Private->IntThunk->PciHandler.PrimaryBusMaster = (UINT16)(PciConfigHeader->Device.Bar[4] & 0xfffc); | |
+ if (((PciConfigHeader->Hdr.ClassCode[0] & 0x01) != 0) || (PciConfigHeader->Hdr.ClassCode[1] != PCI_CLASS_MASS_STORAGE_IDE)) { | |
+ Private->IntThunk->PciHandler.PrimaryIrq = PciIrq; | |
+ Private->IntThunk->PciHandler.PrimaryBase = (UINT16) (PciConfigHeader->Device.Bar[0] & 0xfffc); | |
+ Private->IntThunk->PciHandler.PrimaryControl = (UINT16) ((PciConfigHeader->Device.Bar[1] & 0xfffc) + 2); | |
+ } else { | |
+ Private->IntThunk->PciHandler.PrimaryIrq = 14; | |
+ Private->IntThunk->PciHandler.PrimaryBase = 0x1f0; | |
+ Private->IntThunk->PciHandler.PrimaryControl = 0x3f6; | |
+ } | |
+ // | |
+ // Secondary controller data | |
+ // | |
+ if (Private->IntThunk->PciHandler.PrimaryBusMaster != 0) { | |
+ Private->IntThunk->PciHandler.SecondaryBusMaster = (UINT16) ((PciConfigHeader->Device.Bar[4] & 0xfffc) + 8); | |
+ PrimaryMaster = (UINT16) (Private->IntThunk->PciHandler.PrimaryBusMaster + 2); | |
+ SecondaryMaster = (UINT16) (Private->IntThunk->PciHandler.SecondaryBusMaster + 2); | |
+ | |
+ // | |
+ // Clear pending interrupts in Bus Master registers | |
+ // | |
+ IoWrite16 (PrimaryMaster, 0x04); | |
+ IoWrite16 (SecondaryMaster, 0x04); | |
+ | |
+ } | |
+ | |
+ // | |
+ // Use native mode base address registers in two cases: | |
+ // 1. Programming Interface (PI) register indicates Secondary Controller is | |
+ // in native mode OR | |
+ // 2. PCI device Sub Class Code is not IDE | |
+ // | |
+ if (((PciConfigHeader->Hdr.ClassCode[0] & 0x04) != 0) || (PciConfigHeader->Hdr.ClassCode[1] != PCI_CLASS_MASS_STORAGE_IDE)) { | |
+ Private->IntThunk->PciHandler.SecondaryIrq = PciIrq; | |
+ Private->IntThunk->PciHandler.SecondaryBase = (UINT16) (PciConfigHeader->Device.Bar[2] & 0xfffc); | |
+ Private->IntThunk->PciHandler.SecondaryControl = (UINT16) ((PciConfigHeader->Device.Bar[3] & 0xfffc) + 2); | |
+ } else { | |
+ | |
+ Private->IntThunk->PciHandler.SecondaryIrq = 15; | |
+ Private->IntThunk->PciHandler.SecondaryBase = 0x170; | |
+ Private->IntThunk->PciHandler.SecondaryControl = 0x376; | |
+ } | |
+ | |
+ // | |
+ // Clear pending interrupts in IDE Command Block Status reg before we | |
+ // Thunk to CSM16 below. Don't want a pending Interrupt before we | |
+ // install the handlers as wierd corruption would occur and hang system. | |
+ // | |
+ // | |
+ // Read IDE CMD blk status reg to clear out any pending interrupts. | |
+ // Do here for Primary and Secondary IDE channels | |
+ // | |
+ RegisterAddress = (UINT16)Private->IntThunk->PciHandler.PrimaryBase + 0x07; | |
+ IoRead8 (RegisterAddress); | |
+ RegisterAddress = (UINT16)Private->IntThunk->PciHandler.SecondaryBase + 0x07; | |
+ IoRead8 (RegisterAddress); | |
+ | |
+ Private->IntThunk->PciHandler.PrimaryReserved = 0; | |
+ Private->IntThunk->PciHandler.SecondaryReserved = 0; | |
+ Private->LegacyRegion->UnLock ( | |
+ Private->LegacyRegion, | |
+ 0xE0000, | |
+ 0x20000, | |
+ &Granularity | |
+ ); | |
+ | |
+ Regs.X.AX = Legacy16InstallPciHandler; | |
+ TempData = (UINTN) &Private->IntThunk->PciHandler; | |
+ Regs.X.ES = EFI_SEGMENT ((UINT32) TempData); | |
+ Regs.X.BX = EFI_OFFSET ((UINT32) TempData); | |
+ | |
+ DumpPciHandle (&Private->IntThunk->PciHandler); | |
+ | |
+ Private->LegacyBios.FarCall86 ( | |
+ &Private->LegacyBios, | |
+ Private->Legacy16CallSegment, | |
+ Private->Legacy16CallOffset, | |
+ &Regs, | |
+ NULL, | |
+ 0 | |
+ ); | |
+ | |
+ Private->Cpu->FlushDataCache (Private->Cpu, 0xE0000, 0x20000, EfiCpuFlushTypeWriteBackInvalidate); | |
+ Private->LegacyRegion->Lock ( | |
+ Private->LegacyRegion, | |
+ 0xE0000, | |
+ 0x20000, | |
+ &Granularity | |
+ ); | |
+ | |
+} | |
+ | |
+ | |
+/** | |
+ Program the interrupt routing register in all the PCI devices. On a PC AT system | |
+ this register contains the 8259 IRQ vector that matches it's PCI interrupt. | |
+ | |
+ @param Private Legacy BIOS Instance data | |
+ | |
+ @retval EFI_SUCCESS Succeed. | |
+ @retval EFI_ALREADY_STARTED All PCI devices have been processed. | |
+ | |
+**/ | |
+EFI_STATUS | |
+PciProgramAllInterruptLineRegisters ( | |
+ IN LEGACY_BIOS_INSTANCE *Private | |
+ ) | |
+{ | |
+ EFI_STATUS Status; | |
+ EFI_PCI_IO_PROTOCOL *PciIo; | |
+ EFI_LEGACY_8259_PROTOCOL *Legacy8259; | |
+ EFI_LEGACY_INTERRUPT_PROTOCOL *LegacyInterrupt; | |
+ EFI_LEGACY_BIOS_PLATFORM_PROTOCOL *LegacyBiosPlatform; | |
+ UINT8 InterruptPin; | |
+ UINTN Index; | |
+ UINTN HandleCount; | |
+ EFI_HANDLE *HandleBuffer; | |
+ UINTN MassStorageHandleCount; | |
+ EFI_HANDLE *MassStorageHandleBuffer; | |
+ UINTN MassStorageHandleIndex; | |
+ UINT8 PciIrq; | |
+ UINT16 Command; | |
+ UINTN PciSegment; | |
+ UINTN PciBus; | |
+ UINTN PciDevice; | |
+ UINTN PciFunction; | |
+ EFI_LEGACY_IRQ_ROUTING_ENTRY *RoutingTable; | |
+ UINTN RoutingTableEntries; | |
+ UINT16 LegMask; | |
+ UINT16 LegEdgeLevel; | |
+ PCI_TYPE00 PciConfigHeader; | |
+ EFI_LEGACY_PIRQ_TABLE_HEADER *PirqTable; | |
+ UINTN PirqTableSize; | |
+ UINTN Flags; | |
+ HDD_INFO *HddInfo; | |
+ UINT64 Supports; | |
+ | |
+ // | |
+ // Note - This routine use to return immediately if Private->PciInterruptLine | |
+ // was true. Routine changed since resets etc can cause not all | |
+ // PciIo protocols to be registered the first time through. | |
+ // New algorithm is to do the copy $PIR table on first pass and save | |
+ // HandleCount on first pass. If subsequent passes LocateHandleBuffer gives | |
+ // a larger handle count then proceed with body of function else return | |
+ // EFI_ALREADY_STARTED. In addition check if PCI device InterruptLine != 0. | |
+ // If zero then function unprogrammed else skip function. | |
+ // | |
+ Legacy8259 = Private->Legacy8259; | |
+ LegacyInterrupt = Private->LegacyInterrupt; | |
+ LegacyBiosPlatform = Private->LegacyBiosPlatform; | |
+ | |
+ LegacyBiosPlatform->GetRoutingTable ( | |
+ Private->LegacyBiosPlatform, | |
+ (VOID *) &RoutingTable, | |
+ &RoutingTableEntries, | |
+ (VOID *) &PirqTable, | |
+ &PirqTableSize, | |
+ NULL, | |
+ NULL | |
+ ); | |
+ CreateBridgeTable (RoutingTable, RoutingTableEntries); | |
+ | |
+ if (!Private->PciInterruptLine) { | |
+ CopyPirqTable ( | |
+ Private, | |
+ RoutingTable, | |
+ RoutingTableEntries, | |
+ PirqTable, | |
+ PirqTableSize | |
+ ); | |
+ } | |
+ | |
+ Status = gBS->LocateHandleBuffer ( | |
+ ByProtocol, | |
+ &gEfiPciIoProtocolGuid, | |
+ NULL, | |
+ &HandleCount, | |
+ &HandleBuffer | |
+ ); | |
+ if (EFI_ERROR (Status)) { | |
+ return EFI_NOT_FOUND; | |
+ } | |
+ if (HandleCount == mHandleCount) { | |
+ FreePool (HandleBuffer); | |
+ return EFI_ALREADY_STARTED; | |
+ } | |
+ | |
+ if (mHandleCount == 0x00) { | |
+ mHandleCount = HandleCount; | |
+ } | |
+ | |
+ for (Index = 0; Index < HandleCount; Index++) { | |
+ // | |
+ // If VGA then only do VGA to allow drives fore time to spin up | |
+ // otherwise assign PCI IRQs to all potential devices. | |
+ // | |
+ if ((mVgaInstallationInProgress) && (HandleBuffer[Index] != mVgaHandle)) { | |
+ continue; | |
+ } else { | |
+ // | |
+ // Force code to go through all handles next time called if video. | |
+ // This will catch case where HandleCount doesn't change but want | |
+ // to get drive info etc. | |
+ // | |
+ mHandleCount = 0x00; | |
+ } | |
+ | |
+ Status = gBS->HandleProtocol ( | |
+ HandleBuffer[Index], | |
+ &gEfiPciIoProtocolGuid, | |
+ (VOID **) &PciIo | |
+ ); | |
+ ASSERT_EFI_ERROR (Status); | |
+ | |
+ // | |
+ // Test whether the device can be enabled or not. | |
+ // If it can't be enabled, then just skip it to avoid further operation. | |
+ // | |
+ PciIo->Pci.Read ( | |
+ PciIo, | |
+ EfiPciIoWidthUint32, | |
+ 0, | |
+ sizeof (PciConfigHeader) / sizeof (UINT32), | |
+ &PciConfigHeader | |
+ ); | |
+ Command = PciConfigHeader.Hdr.Command; | |
+ | |
+ // | |
+ // Note PciIo->Attributes does not program the PCI command register | |
+ // | |
+ Status = PciIo->Attributes ( | |
+ PciIo, | |
+ EfiPciIoAttributeOperationSupported, | |
+ 0, | |
+ &Supports | |
+ ); | |
+ if (!EFI_ERROR (Status)) { | |
+ Supports &= (UINT64)EFI_PCI_DEVICE_ENABLE; | |
+ Status = PciIo->Attributes ( | |
+ PciIo, | |
+ EfiPciIoAttributeOperationEnable, | |
+ Supports, | |
+ NULL | |
+ ); | |
+ } | |
+ PciIo->Pci.Write (PciIo, EfiPciIoWidthUint16, 0x04, 1, &Command); | |
+ | |
+ if (EFI_ERROR (Status)) { | |
+ continue; | |
+ } | |
+ | |
+ InterruptPin = PciConfigHeader.Device.InterruptPin; | |
+ | |
+ if ((InterruptPin != 0) && (PciConfigHeader.Device.InterruptLine == PCI_INT_LINE_UNKNOWN)) { | |
+ PciIo->GetLocation ( | |
+ PciIo, | |
+ &PciSegment, | |
+ &PciBus, | |
+ &PciDevice, | |
+ &PciFunction | |
+ ); | |
+ // | |
+ // Translate PIRQ index back thru busses to slot bus with InterruptPin | |
+ // zero based | |
+ // | |
+ InterruptPin -= 1; | |
+ | |
+ Status = GetBaseBus ( | |
+ Private, | |
+ PciBus, | |
+ PciDevice, | |
+ RoutingTable, | |
+ RoutingTableEntries | |
+ ); | |
+ | |
+ if (Status == EFI_NOT_FOUND) { | |
+ TranslateBusPirq ( | |
+ Private, | |
+ &PciBus, | |
+ &PciDevice, | |
+ &PciFunction, | |
+ &InterruptPin | |
+ ); | |
+ } | |
+ // | |
+ // Translate InterruptPin(0-3) into PIRQ | |
+ // | |
+ Status = LegacyBiosPlatform->TranslatePirq ( | |
+ LegacyBiosPlatform, | |
+ PciBus, | |
+ (PciDevice << 3), | |
+ PciFunction, | |
+ &InterruptPin, | |
+ &PciIrq | |
+ ); | |
+ // | |
+ // TranslatePirq() should never fail or we are in trouble | |
+ // If it does return failure status, check your PIRQ routing table to see if some item is missing or incorrect | |
+ // | |
+ if (EFI_ERROR (Status)) { | |
+ DEBUG ((EFI_D_ERROR, "Translate Pirq Failed - Status = %r\n ", Status)); | |
+ continue; | |
+ } | |
+ | |
+ LegacyInterrupt->WritePirq ( | |
+ LegacyInterrupt, | |
+ InterruptPin, | |
+ PciIrq | |
+ ); | |
+ | |
+ // | |
+ // Check if device has an OPROM associated with it. | |
+ // If not invoke special 16-bit function, to allow 16-bit | |
+ // code to install an interrupt handler. | |
+ // | |
+ Status = LegacyBiosCheckPciRom ( | |
+ &Private->LegacyBios, | |
+ HandleBuffer[Index], | |
+ NULL, | |
+ NULL, | |
+ &Flags | |
+ ); | |
+ if ((EFI_ERROR (Status)) && (PciConfigHeader.Hdr.ClassCode[2] == PCI_CLASS_MASS_STORAGE)) { | |
+ // | |
+ // Device has no OPROM associated with it and is a mass storage | |
+ // device. It needs to have an PCI IRQ handler installed. To | |
+ // correctly install the handler we need to insure device is | |
+ // connected. The device may just have register itself but not | |
+ // been connected. Re-read PCI config space after as it can | |
+ // change | |
+ // | |
+ // | |
+ // Get IDE Handle. If matches handle then skip ConnectController | |
+ // since ConnectController may force native mode and we don't | |
+ // want that for primary IDE controller | |
+ // | |
+ MassStorageHandleCount = 0; | |
+ MassStorageHandleBuffer = NULL; | |
+ LegacyBiosPlatform->GetPlatformHandle ( | |
+ Private->LegacyBiosPlatform, | |
+ EfiGetPlatformIdeHandle, | |
+ 0, | |
+ &MassStorageHandleBuffer, | |
+ &MassStorageHandleCount, | |
+ NULL | |
+ ); | |
+ | |
+ HddInfo = &Private->IntThunk->EfiToLegacy16BootTable.HddInfo[0]; | |
+ | |
+ LegacyBiosBuildIdeData (Private, &HddInfo, 0); | |
+ PciIo->Pci.Read ( | |
+ PciIo, | |
+ EfiPciIoWidthUint32, | |
+ 0, | |
+ sizeof (PciConfigHeader) / sizeof (UINT32), | |
+ &PciConfigHeader | |
+ ); | |
+ | |
+ for (MassStorageHandleIndex = 0; MassStorageHandleIndex < MassStorageHandleCount; MassStorageHandleIndex++) { | |
+ if (MassStorageHandleBuffer[MassStorageHandleIndex] == HandleBuffer[Index]) { | |
+ // | |
+ // InstallLegacyIrqHandler according to Platform requirement | |
+ // | |
+ InstallLegacyIrqHandler ( | |
+ Private, | |
+ PciIo, | |
+ PciIrq, | |
+ &PciConfigHeader | |
+ ); | |
+ break; | |
+ } | |
+ } | |
+ } | |
+ // | |
+ // Write InterruptPin and enable 8259. | |
+ // | |
+ PciIo->Pci.Write ( | |
+ PciIo, | |
+ EfiPciIoWidthUint8, | |
+ 0x3c, | |
+ 1, | |
+ &PciIrq | |
+ ); | |
+ Private->IntThunk->EfiToLegacy16BootTable.PciIrqMask = (UINT16) (Private->IntThunk->EfiToLegacy16BootTable.PciIrqMask | (UINT16) (1 << PciIrq)); | |
+ | |
+ Legacy8259->GetMask ( | |
+ Legacy8259, | |
+ &LegMask, | |
+ &LegEdgeLevel, | |
+ NULL, | |
+ NULL | |
+ ); | |
+ | |
+ LegMask = (UINT16) (LegMask & (UINT16)~(1 << PciIrq)); | |
+ LegEdgeLevel = (UINT16) (LegEdgeLevel | (UINT16) (1 << PciIrq)); | |
+ Legacy8259->SetMask ( | |
+ Legacy8259, | |
+ &LegMask, | |
+ &LegEdgeLevel, | |
+ NULL, | |
+ NULL | |
+ ); | |
+ } | |
+ } | |
+ FreePool (HandleBuffer); | |
+ return EFI_SUCCESS; | |
+} | |
+ | |
+ | |
+/** | |
+ Find & verify PnP Expansion header in ROM image | |
+ | |
+ @param Private Protocol instance pointer. | |
+ @param FirstHeader 1 = Find first header, 0 = Find successive headers | |
+ @param PnpPtr Input Rom start if FirstHeader =1, Current Header | |
+ otherwise Output Next header, if it exists | |
+ | |
+ @retval EFI_SUCCESS Next Header found at BasePnpPtr | |
+ @retval EFI_NOT_FOUND No more headers | |
+ | |
+**/ | |
+EFI_STATUS | |
+FindNextPnpExpansionHeader ( | |
+ IN LEGACY_BIOS_INSTANCE *Private, | |
+ IN BOOLEAN FirstHeader, | |
+ IN OUT LEGACY_PNP_EXPANSION_HEADER **PnpPtr | |
+ | |
+ ) | |
+{ | |
+ UINTN TempData; | |
+ LEGACY_PNP_EXPANSION_HEADER *LocalPnpPtr; | |
+ LocalPnpPtr = *PnpPtr; | |
+ if (FirstHeader == FIRST_INSTANCE) { | |
+ mBasePnpPtr = LocalPnpPtr; | |
+ mBbsRomSegment = (UINT16) ((UINTN) mBasePnpPtr >> 4); | |
+ // | |
+ // Offset 0x1a gives offset to PnP expansion header for the first | |
+ // instance, there after the structure gives the offset to the next | |
+ // structure | |
+ // | |
+ LocalPnpPtr = (LEGACY_PNP_EXPANSION_HEADER *) ((UINT8 *) LocalPnpPtr + 0x1a); | |
+ TempData = (*((UINT16 *) LocalPnpPtr)); | |
+ } else { | |
+ TempData = (UINT16) LocalPnpPtr->NextHeader; | |
+ } | |
+ | |
+ LocalPnpPtr = (LEGACY_PNP_EXPANSION_HEADER *) (((UINT8 *) mBasePnpPtr + TempData)); | |
+ | |
+ // | |
+ // Search for PnP table in Shadowed ROM | |
+ // | |
+ *PnpPtr = LocalPnpPtr; | |
+ if (*(UINT32 *) LocalPnpPtr == SIGNATURE_32 ('$', 'P', 'n', 'P')) { | |
+ return EFI_SUCCESS; | |
+ } else { | |
+ return EFI_NOT_FOUND; | |
+ } | |
+} | |
+ | |
+ | |
+/** | |
+ Update list of Bev or BCV table entries. | |
+ | |
+ @param Private Protocol instance pointer. | |
+ @param RomStart Table of ROM start address in RAM/ROM. PciIo _ | |
+ Handle to PCI IO for this device | |
+ @param PciIo Instance of PCI I/O Protocol | |
+ | |
+ @retval EFI_SUCCESS Always should succeed. | |
+ | |
+**/ | |
+EFI_STATUS | |
+UpdateBevBcvTable ( | |
+ IN LEGACY_BIOS_INSTANCE *Private, | |
+ IN EFI_LEGACY_EXPANSION_ROM_HEADER *RomStart, | |
+ IN EFI_PCI_IO_PROTOCOL *PciIo | |
+ ) | |
+{ | |
+ VOID *RomEnd; | |
+ BBS_TABLE *BbsTable; | |
+ UINTN BbsIndex; | |
+ EFI_LEGACY_EXPANSION_ROM_HEADER *PciPtr; | |
+ LEGACY_PNP_EXPANSION_HEADER *PnpPtr; | |
+ BOOLEAN Instance; | |
+ EFI_STATUS Status; | |
+ UINTN Segment; | |
+ UINTN Bus; | |
+ UINTN Device; | |
+ UINTN Function; | |
+ UINT8 Class; | |
+ UINT16 DeviceType; | |
+ Segment = 0; | |
+ Bus = 0; | |
+ Device = 0; | |
+ Function = 0; | |
+ Class = 0; | |
+ DeviceType = BBS_UNKNOWN; | |
+ | |
+ // | |
+ // Skip floppy and 2*onboard IDE controller entries(Master/Slave per | |
+ // controller). | |
+ // | |
+ BbsIndex = Private->IntThunk->EfiToLegacy16BootTable.NumberBbsEntries; | |
+ | |
+ BbsTable = (BBS_TABLE*)(UINTN) Private->IntThunk->EfiToLegacy16BootTable.BbsTable; | |
+ PnpPtr = (LEGACY_PNP_EXPANSION_HEADER *) RomStart; | |
+ PciPtr = (EFI_LEGACY_EXPANSION_ROM_HEADER *) RomStart; | |
+ | |
+ RomEnd = (VOID *) (PciPtr->Size512 * 512 + (UINTN) PciPtr); | |
+ Instance = FIRST_INSTANCE; | |
+ // | |
+ // OPROMs like PXE may not be tied to a piece of hardware and thus | |
+ // don't have a PciIo associated with them | |
+ // | |
+ if (PciIo != NULL) { | |
+ PciIo->GetLocation ( | |
+ PciIo, | |
+ &Segment, | |
+ &Bus, | |
+ &Device, | |
+ &Function | |
+ ); | |
+ PciIo->Pci.Read ( | |
+ PciIo, | |
+ EfiPciIoWidthUint8, | |
+ 0x0b, | |
+ 1, | |
+ &Class | |
+ ); | |
+ | |
+ if (Class == PCI_CLASS_MASS_STORAGE) { | |
+ DeviceType = BBS_HARDDISK; | |
+ } else { | |
+ if (Class == PCI_CLASS_NETWORK) { | |
+ DeviceType = BBS_EMBED_NETWORK; | |
+ } | |
+ } | |
+ } | |
+ | |
+ while (TRUE) { | |
+ Status = FindNextPnpExpansionHeader (Private, Instance, &PnpPtr); | |
+ Instance = NOT_FIRST_INSTANCE; | |
+ if (EFI_ERROR (Status)) { | |
+ break; | |
+ } | |
+ // | |
+ // There can be additional $PnP headers within the OPROM. | |
+ // Example: SCSI can have one per drive. | |
+ // | |
+ BbsTable[BbsIndex].BootPriority = BBS_UNPRIORITIZED_ENTRY; | |
+ BbsTable[BbsIndex].DeviceType = DeviceType; | |
+ BbsTable[BbsIndex].Bus = (UINT32) Bus; | |
+ BbsTable[BbsIndex].Device = (UINT32) Device; | |
+ BbsTable[BbsIndex].Function = (UINT32) Function; | |
+ BbsTable[BbsIndex].StatusFlags.OldPosition = 0; | |
+ BbsTable[BbsIndex].StatusFlags.Reserved1 = 0; | |
+ BbsTable[BbsIndex].StatusFlags.Enabled = 0; | |
+ BbsTable[BbsIndex].StatusFlags.Failed = 0; | |
+ BbsTable[BbsIndex].StatusFlags.MediaPresent = 0; | |
+ BbsTable[BbsIndex].StatusFlags.Reserved2 = 0; | |
+ BbsTable[BbsIndex].Class = PnpPtr->Class; | |
+ BbsTable[BbsIndex].SubClass = PnpPtr->SubClass; | |
+ BbsTable[BbsIndex].DescStringOffset = PnpPtr->ProductNamePointer; | |
+ BbsTable[BbsIndex].DescStringSegment = mBbsRomSegment; | |
+ BbsTable[BbsIndex].MfgStringOffset = PnpPtr->MfgPointer; | |
+ BbsTable[BbsIndex].MfgStringSegment = mBbsRomSegment; | |
+ BbsTable[BbsIndex].BootHandlerSegment = mBbsRomSegment; | |
+ | |
+ // | |
+ // Have seen case where PXE base code have PnP expansion ROM | |
+ // header but no Bcv or Bev vectors. | |
+ // | |
+ if (PnpPtr->Bcv != 0) { | |
+ BbsTable[BbsIndex].BootHandlerOffset = PnpPtr->Bcv; | |
+ ++BbsIndex; | |
+ } | |
+ | |
+ if (PnpPtr->Bev != 0) { | |
+ BbsTable[BbsIndex].BootHandlerOffset = PnpPtr->Bev; | |
+ BbsTable[BbsIndex].DeviceType = BBS_BEV_DEVICE; | |
+ ++BbsIndex; | |
+ } | |
+ | |
+ if ((PnpPtr == (LEGACY_PNP_EXPANSION_HEADER *) PciPtr) || (PnpPtr > (LEGACY_PNP_EXPANSION_HEADER *) RomEnd)) { | |
+ break; | |
+ } | |
+ } | |
+ | |
+ BbsTable[BbsIndex].BootPriority = BBS_IGNORE_ENTRY; | |
+ Private->IntThunk->EfiToLegacy16BootTable.NumberBbsEntries = (UINT32) BbsIndex; | |
+ return EFI_SUCCESS; | |
+} | |
+ | |
+ | |
+/** | |
+ Shadow all the PCI legacy ROMs. Use data from the Legacy BIOS Protocol | |
+ to chose the order. Skip any devices that have already have legacy | |
+ BIOS run. | |
+ | |
+ @param Private Protocol instance pointer. | |
+ | |
+ @retval EFI_SUCCESS Succeed. | |
+ @retval EFI_UNSUPPORTED Cannot get VGA device handle. | |
+ | |
+**/ | |
+EFI_STATUS | |
+PciShadowRoms ( | |
+ IN LEGACY_BIOS_INSTANCE *Private | |
+ ) | |
+{ | |
+ EFI_STATUS Status; | |
+ EFI_PCI_IO_PROTOCOL *PciIo; | |
+ PCI_TYPE00 Pci; | |
+ UINTN Index; | |
+ UINTN HandleCount; | |
+ EFI_HANDLE *HandleBuffer; | |
+ EFI_HANDLE VgaHandle; | |
+ EFI_HANDLE FirstHandle; | |
+ VOID **RomStart; | |
+ UINTN Flags; | |
+ PCI_TYPE00 PciConfigHeader; | |
+ UINT16 *Command; | |
+ UINT64 Supports; | |
+ | |
+ // | |
+ // Make the VGA device first | |
+ // | |
+ Status = Private->LegacyBiosPlatform->GetPlatformHandle ( | |
+ Private->LegacyBiosPlatform, | |
+ EfiGetPlatformVgaHandle, | |
+ 0, | |
+ &HandleBuffer, | |
+ &HandleCount, | |
+ NULL | |
+ ); | |
+ if (EFI_ERROR (Status)) { | |
+ return EFI_UNSUPPORTED; | |
+ } | |
+ | |
+ VgaHandle = HandleBuffer[0]; | |
+ | |
+ Status = gBS->LocateHandleBuffer ( | |
+ ByProtocol, | |
+ &gEfiPciIoProtocolGuid, | |
+ NULL, | |
+ &HandleCount, | |
+ &HandleBuffer | |
+ ); | |
+ | |
+ if (EFI_ERROR (Status)) { | |
+ return Status; | |
+ } | |
+ // | |
+ // Place the VGA handle as first. | |
+ // | |
+ for (Index = 0; Index < HandleCount; Index++) { | |
+ if (HandleBuffer[Index] == VgaHandle) { | |
+ FirstHandle = HandleBuffer[0]; | |
+ HandleBuffer[0] = HandleBuffer[Index]; | |
+ HandleBuffer[Index] = FirstHandle; | |
+ break; | |
+ } | |
+ } | |
+ // | |
+ // Allocate memory to save Command WORD from each device. We do this | |
+ // to restore devices to same state as EFI after switching to legacy. | |
+ // | |
+ Command = (UINT16 *) AllocatePool ( | |
+ sizeof (UINT16) * (HandleCount + 1) | |
+ ); | |
+ if (NULL == Command) { | |
+ FreePool (HandleBuffer); | |
+ return EFI_OUT_OF_RESOURCES; | |
+ } | |
+ // | |
+ // Disconnect all EFI devices first. This covers cases where alegacy BIOS | |
+ // may control multiple PCI devices. | |
+ // | |
+ for (Index = 0; Index < HandleCount; Index++) { | |
+ | |
+ Status = gBS->HandleProtocol ( | |
+ HandleBuffer[Index], | |
+ &gEfiPciIoProtocolGuid, | |
+ (VOID **) &PciIo | |
+ ); | |
+ ASSERT_EFI_ERROR (Status); | |
+ | |
+ // | |
+ // Save command register for "connect" loop | |
+ // | |
+ PciIo->Pci.Read ( | |
+ PciIo, | |
+ EfiPciIoWidthUint32, | |
+ 0, | |
+ sizeof (PciConfigHeader) / sizeof (UINT32), | |
+ &PciConfigHeader | |
+ ); | |
+ Command[Index] = PciConfigHeader.Hdr.Command; | |
+ // | |
+ // Skip any device that already has a legacy ROM run | |
+ // | |
+ Status = IsLegacyRom (HandleBuffer[Index]); | |
+ if (!EFI_ERROR (Status)) { | |
+ continue; | |
+ } | |
+ // | |
+ // Stop EFI Drivers with oprom. | |
+ // | |
+ gBS->DisconnectController ( | |
+ HandleBuffer[Index], | |
+ NULL, | |
+ NULL | |
+ ); | |
+ } | |
+ // | |
+ // For every device that has not had a legacy ROM started. Start a legacy ROM. | |
+ // | |
+ for (Index = 0; Index < HandleCount; Index++) { | |
+ | |
+ Status = gBS->HandleProtocol ( | |
+ HandleBuffer[Index], | |
+ &gEfiPciIoProtocolGuid, | |
+ (VOID **) &PciIo | |
+ ); | |
+ | |
+ ASSERT_EFI_ERROR (Status); | |
+ | |
+ // | |
+ // Here make sure if one VGA have been shadowed, | |
+ // then wil not shadowed another one. | |
+ // | |
+ PciIo->Pci.Read ( | |
+ PciIo, | |
+ EfiPciIoWidthUint32, | |
+ 0, | |
+ sizeof (Pci) / sizeof (UINT32), | |
+ &Pci | |
+ ); | |
+ | |
+ // | |
+ // Only one Video OPROM can be given control in BIOS phase. If there are multiple Video devices, | |
+ // one will work in legacy mode (OPROM will be given control) and | |
+ // other Video devices will work in native mode (OS driver will handle these devices). | |
+ // | |
+ if (IS_PCI_DISPLAY (&Pci) && Index != 0) { | |
+ continue; | |
+ } | |
+ // | |
+ // Skip any device that already has a legacy ROM run | |
+ // | |
+ Status = IsLegacyRom (HandleBuffer[Index]); | |
+ if (!EFI_ERROR (Status)) { | |
+ continue; | |
+ } | |
+ | |
+ // | |
+ // If legacy VBIOS Oprom has not been dispatched before, install legacy VBIOS here. | |
+ // | |
+ if (IS_PCI_DISPLAY (&Pci) && Index == 0) { | |
+ Status = LegacyBiosInstallVgaRom (Private); | |
+ // | |
+ // A return status of EFI_NOT_FOUND is considered valid (No EFI | |
+ // driver is controlling video). | |
+ // | |
+ ASSERT ((Status == EFI_SUCCESS) || (Status == EFI_NOT_FOUND)); | |
+ continue; | |
+ } | |
+ | |
+ // | |
+ // Install legacy ROM | |
+ // | |
+ Status = LegacyBiosInstallPciRom ( | |
+ &Private->LegacyBios, | |
+ HandleBuffer[Index], | |
+ NULL, | |
+ &Flags, | |
+ NULL, | |
+ NULL, | |
+ (VOID **) &RomStart, | |
+ NULL | |
+ ); | |
+ if (EFI_ERROR (Status)) { | |
+ if (!((Status == EFI_UNSUPPORTED) && (Flags == NO_ROM))) { | |
+ continue; | |
+ } | |
+ } | |
+ // | |
+ // Restore Command register so legacy has same devices enabled or disabled | |
+ // as EFI. | |
+ // If Flags = NO_ROM use command register as is. This covers the | |
+ // following cases: | |
+ // Device has no ROMs associated with it. | |
+ // Device has ROM associated with it but was already | |
+ // installed. | |
+ // = ROM_FOUND but not VALID_LEGACY_ROM, disable it. | |
+ // = ROM_FOUND and VALID_LEGACY_ROM, enable it. | |
+ // | |
+ if ((Flags & ROM_FOUND) == ROM_FOUND) { | |
+ if ((Flags & VALID_LEGACY_ROM) == 0) { | |
+ Command[Index] = 0; | |
+ } else { | |
+ // | |
+ // For several VGAs, only one of them can be enabled. | |
+ // | |
+ Status = PciIo->Attributes ( | |
+ PciIo, | |
+ EfiPciIoAttributeOperationSupported, | |
+ 0, | |
+ &Supports | |
+ ); | |
+ if (!EFI_ERROR (Status)) { | |
+ Supports &= (UINT64)EFI_PCI_DEVICE_ENABLE; | |
+ Status = PciIo->Attributes ( | |
+ PciIo, | |
+ EfiPciIoAttributeOperationEnable, | |
+ Supports, | |
+ NULL | |
+ ); | |
+ } | |
+ if (!EFI_ERROR (Status)) { | |
+ Command[Index] = 0x1f; | |
+ } | |
+ } | |
+ } | |
+ | |
+ PciIo->Pci.Write ( | |
+ PciIo, | |
+ EfiPciIoWidthUint16, | |
+ 0x04, | |
+ 1, | |
+ &Command[Index] | |
+ ); | |
+ } | |
+ | |
+ FreePool (Command); | |
+ FreePool (HandleBuffer); | |
+ return EFI_SUCCESS; | |
+} | |
+ | |
+ | |
+/** | |
+ Test to see if a legacy PCI ROM exists for this device. Optionally return | |
+ the Legacy ROM instance for this PCI device. | |
+ | |
+ @param This Protocol instance pointer. | |
+ @param PciHandle The PCI PC-AT OPROM from this devices ROM BAR will | |
+ be loaded | |
+ @param RomImage Return the legacy PCI ROM for this device | |
+ @param RomSize Size of ROM Image | |
+ @param Flags Indicates if ROM found and if PC-AT. | |
+ | |
+ @retval EFI_SUCCESS Legacy Option ROM availible for this device | |
+ @retval EFI_UNSUPPORTED Legacy Option ROM not supported. | |
+ | |
+**/ | |
+EFI_STATUS | |
+EFIAPI | |
+LegacyBiosCheckPciRom ( | |
+ IN EFI_LEGACY_BIOS_PROTOCOL *This, | |
+ IN EFI_HANDLE PciHandle, | |
+ OUT VOID **RomImage, OPTIONAL | |
+ OUT UINTN *RomSize, OPTIONAL | |
+ OUT UINTN *Flags | |
+ ) | |
+{ | |
+ return LegacyBiosCheckPciRomEx ( | |
+ This, | |
+ PciHandle, | |
+ RomImage, | |
+ RomSize, | |
+ NULL, | |
+ Flags, | |
+ NULL, | |
+ NULL | |
+ ); | |
+ | |
+} | |
+ | |
+/** | |
+ | |
+ Routine Description: | |
+ Test to see if a legacy PCI ROM exists for this device. Optionally return | |
+ the Legacy ROM instance for this PCI device. | |
+ | |
+ @param[in] This Protocol instance pointer. | |
+ @param[in] PciHandle The PCI PC-AT OPROM from this devices ROM BAR will be loaded | |
+ @param[out] RomImage Return the legacy PCI ROM for this device | |
+ @param[out] RomSize Size of ROM Image | |
+ @param[out] RuntimeImageLength Runtime size of ROM Image | |
+ @param[out] Flags Indicates if ROM found and if PC-AT. | |
+ @param[out] OpromRevision Revision of the PCI Rom | |
+ @param[out] ConfigUtilityCodeHeaderPointer of Configuration Utility Code Header | |
+ | |
+ @return EFI_SUCCESS Legacy Option ROM availible for this device | |
+ @return EFI_ALREADY_STARTED This device is already managed by its Oprom | |
+ @return EFI_UNSUPPORTED Legacy Option ROM not supported. | |
+ | |
+**/ | |
+EFI_STATUS | |
+LegacyBiosCheckPciRomEx ( | |
+ IN EFI_LEGACY_BIOS_PROTOCOL *This, | |
+ IN EFI_HANDLE PciHandle, | |
+ OUT VOID **RomImage, OPTIONAL | |
+ OUT UINTN *RomSize, OPTIONAL | |
+ OUT UINTN *RuntimeImageLength, OPTIONAL | |
+ OUT UINTN *Flags, OPTIONAL | |
+ OUT UINT8 *OpromRevision, OPTIONAL | |
+ OUT VOID **ConfigUtilityCodeHeader OPTIONAL | |
+ ) | |
+{ | |
+ EFI_STATUS Status; | |
+ LEGACY_BIOS_INSTANCE *Private; | |
+ EFI_PCI_IO_PROTOCOL *PciIo; | |
+ UINTN LocalRomSize; | |
+ VOID *LocalRomImage; | |
+ PCI_TYPE00 PciConfigHeader; | |
+ VOID *LocalConfigUtilityCodeHeader; | |
+ | |
+ LocalConfigUtilityCodeHeader = NULL; | |
+ *Flags = NO_ROM; | |
+ Status = gBS->HandleProtocol ( | |
+ PciHandle, | |
+ &gEfiPciIoProtocolGuid, | |
+ (VOID **) &PciIo | |
+ ); | |
+ if (EFI_ERROR (Status)) { | |
+ return EFI_UNSUPPORTED; | |
+ } | |
+ | |
+ // | |
+ // See if the option ROM for PciHandle has already been executed | |
+ // | |
+ Status = IsLegacyRom (PciHandle); | |
+ if (!EFI_ERROR (Status)) { | |
+ *Flags |= (UINTN)(ROM_FOUND | VALID_LEGACY_ROM); | |
+ return EFI_SUCCESS; | |
+ } | |
+ // | |
+ // Check for PCI ROM Bar | |
+ // | |
+ LocalRomSize = (UINTN) PciIo->RomSize; | |
+ LocalRomImage = PciIo->RomImage; | |
+ if (LocalRomSize != 0) { | |
+ *Flags |= ROM_FOUND; | |
+ } | |
+ | |
+ // | |
+ // PCI specification states you should check VendorId and Device Id. | |
+ // | |
+ PciIo->Pci.Read ( | |
+ PciIo, | |
+ EfiPciIoWidthUint32, | |
+ 0, | |
+ sizeof (PciConfigHeader) / sizeof (UINT32), | |
+ &PciConfigHeader | |
+ ); | |
+ | |
+ Private = LEGACY_BIOS_INSTANCE_FROM_THIS (This); | |
+ Status = GetPciLegacyRom ( | |
+ Private->Csm16PciInterfaceVersion, | |
+ PciConfigHeader.Hdr.VendorId, | |
+ PciConfigHeader.Hdr.DeviceId, | |
+ &LocalRomImage, | |
+ &LocalRomSize, | |
+ RuntimeImageLength, | |
+ OpromRevision, | |
+ &LocalConfigUtilityCodeHeader | |
+ ); | |
+ if (EFI_ERROR (Status)) { | |
+ return EFI_UNSUPPORTED; | |
+ } | |
+ | |
+ *Flags |= VALID_LEGACY_ROM; | |
+ | |
+ // | |
+ // See if Configuration Utility Code Header valid | |
+ // | |
+ if (LocalConfigUtilityCodeHeader != NULL) { | |
+ *Flags |= ROM_WITH_CONFIG; | |
+ } | |
+ | |
+ if (ConfigUtilityCodeHeader != NULL) { | |
+ *ConfigUtilityCodeHeader = LocalConfigUtilityCodeHeader; | |
+ } | |
+ | |
+ if (RomImage != NULL) { | |
+ *RomImage = LocalRomImage; | |
+ } | |
+ | |
+ if (RomSize != NULL) { | |
+ *RomSize = LocalRomSize; | |
+ } | |
+ | |
+ return EFI_SUCCESS; | |
+} | |
+ | |
+/** | |
+ Load a legacy PC-AT OPROM on the PciHandle device. Return information | |
+ about how many disks were added by the OPROM and the shadow address and | |
+ size. DiskStart & DiskEnd are INT 13h drive letters. Thus 0x80 is C: | |
+ | |
+ @retval EFI_SUCCESS Legacy ROM loaded for this device | |
+ @retval EFI_NOT_FOUND No PS2 Keyboard found | |
+ | |
+**/ | |
+EFI_STATUS | |
+EnablePs2Keyboard ( | |
+ VOID | |
+ ) | |
+{ | |
+ EFI_STATUS Status; | |
+ EFI_HANDLE *HandleBuffer; | |
+ UINTN HandleCount; | |
+ EFI_ISA_IO_PROTOCOL *IsaIo; | |
+ UINTN Index; | |
+ | |
+ // | |
+ // Get SimpleTextIn and find PS2 controller | |
+ // | |
+ Status = gBS->LocateHandleBuffer ( | |
+ ByProtocol, | |
+ &gEfiSimpleTextInProtocolGuid, | |
+ NULL, | |
+ &HandleCount, | |
+ &HandleBuffer | |
+ ); | |
+ if (EFI_ERROR (Status)) { | |
+ return EFI_NOT_FOUND; | |
+ } | |
+ for (Index = 0; Index < HandleCount; Index++) { | |
+ // | |
+ // Open the IO Abstraction(s) needed to perform the supported test | |
+ // | |
+ Status = gBS->OpenProtocol ( | |
+ HandleBuffer[Index], | |
+ &gEfiIsaIoProtocolGuid, | |
+ (VOID **) &IsaIo, | |
+ NULL, | |
+ HandleBuffer[Index], | |
+ EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL | |
+ ); | |
+ | |
+ if (!EFI_ERROR (Status)) { | |
+ // | |
+ // Use the ISA I/O Protocol to see if Controller is the Keyboard | |
+ // controller | |
+ // | |
+ if (IsaIo->ResourceList->Device.HID != EISA_PNP_ID (0x303) || IsaIo->ResourceList->Device.UID != 0) { | |
+ Status = EFI_UNSUPPORTED; | |
+ } | |
+ | |
+ gBS->CloseProtocol ( | |
+ HandleBuffer[Index], | |
+ &gEfiIsaIoProtocolGuid, | |
+ NULL, | |
+ HandleBuffer[Index] | |
+ ); | |
+ } | |
+ | |
+ if (!EFI_ERROR (Status)) { | |
+ gBS->ConnectController (HandleBuffer[Index], NULL, NULL, FALSE); | |
+ } | |
+ } | |
+ FreePool (HandleBuffer); | |
+ return EFI_SUCCESS; | |
+} | |
+ | |
+ | |
+/** | |
+ Load a legacy PC-AT OpROM for VGA controller. | |
+ | |
+ @param Private Driver private data. | |
+ | |
+ @retval EFI_SUCCESS Legacy ROM successfully installed for this device. | |
+ @retval EFI_DEVICE_ERROR No VGA device handle found, or native EFI video | |
+ driver cannot be successfully disconnected, or VGA | |
+ thunk driver cannot be successfully connected. | |
+ | |
+**/ | |
+EFI_STATUS | |
+LegacyBiosInstallVgaRom ( | |
+ IN LEGACY_BIOS_INSTANCE *Private | |
+ ) | |
+{ | |
+ EFI_STATUS Status; | |
+ EFI_HANDLE VgaHandle; | |
+ UINTN HandleCount; | |
+ EFI_HANDLE *HandleBuffer; | |
+ EFI_HANDLE *ConnectHandleBuffer; | |
+ EFI_PCI_IO_PROTOCOL *PciIo; | |
+ PCI_TYPE00 PciConfigHeader; | |
+ UINT64 Supports; | |
+ EFI_OPEN_PROTOCOL_INFORMATION_ENTRY *OpenInfoBuffer; | |
+ UINTN EntryCount; | |
+ UINTN Index; | |
+ VOID *Interface; | |
+ | |
+ // | |
+ // EfiLegacyBiosGuild attached to a device implies that there is a legacy | |
+ // BIOS associated with that device. | |
+ // | |
+ // There are 3 cases to consider. | |
+ // Case 1: No EFI driver is controlling the video. | |
+ // Action: Return EFI_SUCCESS from DisconnectController, search | |
+ // video thunk driver, and connect it. | |
+ // Case 2: EFI driver is controlling the video and EfiLegacyBiosGuid is | |
+ // not on the image handle. | |
+ // Action: Disconnect EFI driver. | |
+ // ConnectController for video thunk | |
+ // Case 3: EFI driver is controlling the video and EfiLegacyBiosGuid is | |
+ // on the image handle. | |
+ // Action: Do nothing and set Private->VgaInstalled = TRUE. | |
+ // Then this routine is not called any more. | |
+ // | |
+ // | |
+ // Get the VGA device. | |
+ // | |
+ Status = Private->LegacyBiosPlatform->GetPlatformHandle ( | |
+ Private->LegacyBiosPlatform, | |
+ EfiGetPlatformVgaHandle, | |
+ 0, | |
+ &HandleBuffer, | |
+ &HandleCount, | |
+ NULL | |
+ ); | |
+ if (EFI_ERROR (Status)) { | |
+ return EFI_DEVICE_ERROR; | |
+ } | |
+ | |
+ VgaHandle = HandleBuffer[0]; | |
+ | |
+ // | |
+ // Check whether video thunk driver already starts. | |
+ // | |
+ Status = gBS->OpenProtocolInformation ( | |
+ VgaHandle, | |
+ &gEfiPciIoProtocolGuid, | |
+ &OpenInfoBuffer, | |
+ &EntryCount | |
+ ); | |
+ if (EFI_ERROR (Status)) { | |
+ return Status; | |
+ } | |
+ | |
+ for (Index = 0; Index < EntryCount; Index++) { | |
+ if ((OpenInfoBuffer[Index].Attributes & EFI_OPEN_PROTOCOL_BY_DRIVER) != 0) { | |
+ Status = gBS->HandleProtocol ( | |
+ OpenInfoBuffer[Index].AgentHandle, | |
+ &gEfiLegacyBiosGuid, | |
+ (VOID **) &Interface | |
+ ); | |
+ if (!EFI_ERROR (Status)) { | |
+ // | |
+ // This should be video thunk driver which is managing video device | |
+ // So it need not start again | |
+ // | |
+ DEBUG ((EFI_D_INFO, "Video thunk driver already start! Return!\n")); | |
+ Private->VgaInstalled = TRUE; | |
+ return EFI_SUCCESS; | |
+ } | |
+ } | |
+ } | |
+ | |
+ // | |
+ // Kick off the native EFI driver | |
+ // | |
+ Status = gBS->DisconnectController ( | |
+ VgaHandle, | |
+ NULL, | |
+ NULL | |
+ ); | |
+ if (EFI_ERROR (Status)) { | |
+ if (Status != EFI_NOT_FOUND) { | |
+ return EFI_DEVICE_ERROR; | |
+ } else { | |
+ return Status; | |
+ } | |
+ } | |
+ // | |
+ // Find all the Thunk Driver | |
+ // | |
+ HandleBuffer = NULL; | |
+ Status = gBS->LocateHandleBuffer ( | |
+ ByProtocol, | |
+ &gEfiLegacyBiosGuid, | |
+ NULL, | |
+ &HandleCount, | |
+ &HandleBuffer | |
+ ); | |
+ ASSERT_EFI_ERROR (Status); | |
+ ConnectHandleBuffer = (EFI_HANDLE *) AllocatePool (sizeof (EFI_HANDLE) * (HandleCount + 1)); | |
+ ASSERT (ConnectHandleBuffer != NULL); | |
+ | |
+ CopyMem ( | |
+ ConnectHandleBuffer, | |
+ HandleBuffer, | |
+ sizeof (EFI_HANDLE) * HandleCount | |
+ ); | |
+ ConnectHandleBuffer[HandleCount] = NULL; | |
+ | |
+ FreePool (HandleBuffer); | |
+ | |
+ // | |
+ // Enable the device and make sure VGA cycles are being forwarded to this VGA device | |
+ // | |
+ Status = gBS->HandleProtocol ( | |
+ VgaHandle, | |
+ &gEfiPciIoProtocolGuid, | |
+ (VOID **) &PciIo | |
+ ); | |
+ ASSERT_EFI_ERROR (Status); | |
+ PciIo->Pci.Read ( | |
+ PciIo, | |
+ EfiPciIoWidthUint32, | |
+ 0, | |
+ sizeof (PciConfigHeader) / sizeof (UINT32), | |
+ &PciConfigHeader | |
+ ); | |
+ | |
+ Status = PciIo->Attributes ( | |
+ PciIo, | |
+ EfiPciIoAttributeOperationSupported, | |
+ 0, | |
+ &Supports | |
+ ); | |
+ if (!EFI_ERROR (Status)) { | |
+ Supports &= (UINT64)(EFI_PCI_DEVICE_ENABLE | EFI_PCI_IO_ATTRIBUTE_VGA_MEMORY | \ | |
+ EFI_PCI_IO_ATTRIBUTE_VGA_IO | EFI_PCI_IO_ATTRIBUTE_VGA_IO_16); | |
+ Status = PciIo->Attributes ( | |
+ PciIo, | |
+ EfiPciIoAttributeOperationEnable, | |
+ Supports, | |
+ NULL | |
+ ); | |
+ } | |
+ | |
+ if (Status == EFI_SUCCESS) { | |
+ Private->VgaInstalled = TRUE; | |
+ | |
+ // | |
+ // Attach the VGA thunk driver. | |
+ // Assume the video is installed. This prevents potential of infinite recursion. | |
+ // | |
+ Status = gBS->ConnectController ( | |
+ VgaHandle, | |
+ ConnectHandleBuffer, | |
+ NULL, | |
+ TRUE | |
+ ); | |
+ } | |
+ | |
+ FreePool (ConnectHandleBuffer); | |
+ | |
+ if (EFI_ERROR (Status)) { | |
+ | |
+ Private->VgaInstalled = FALSE; | |
+ | |
+ // | |
+ // Reconnect the EFI VGA driver. | |
+ // | |
+ gBS->ConnectController (VgaHandle, NULL, NULL, TRUE); | |
+ return EFI_DEVICE_ERROR; | |
+ } | |
+ | |
+ return EFI_SUCCESS; | |
+} | |
+ | |
+ | |
+/** | |
+ Load a legacy PC-AT OpROM. | |
+ | |
+ @param This Protocol instance pointer. | |
+ @param Private Driver's private data. | |
+ @param PciHandle The EFI handle for the PCI device. It could be | |
+ NULL if the OpROM image is not associated with | |
+ any device. | |
+ @param OpromRevision The revision of PCI PC-AT ROM image. | |
+ @param RomImage Pointer to PCI PC-AT ROM image header. It must not | |
+ be NULL. | |
+ @param ImageSize Size of the PCI PC-AT ROM image. | |
+ @param RuntimeImageLength On input is the max runtime image length indicated by the PCIR structure | |
+ On output is the actual runtime image length | |
+ @param DiskStart Disk number of first device hooked by the ROM. If | |
+ DiskStart is the same as DiskEnd no disked were | |
+ hooked. | |
+ @param DiskEnd Disk number of the last device hooked by the ROM. | |
+ @param RomShadowAddress Shadow address of PC-AT ROM | |
+ | |
+ @retval EFI_SUCCESS Legacy ROM loaded for this device | |
+ @retval EFI_OUT_OF_RESOURCES No more space for this ROM | |
+ | |
+**/ | |
+EFI_STATUS | |
+EFIAPI | |
+LegacyBiosInstallRom ( | |
+ IN EFI_LEGACY_BIOS_PROTOCOL *This, | |
+ IN LEGACY_BIOS_INSTANCE *Private, | |
+ IN EFI_HANDLE PciHandle, | |
+ IN UINT8 OpromRevision, | |
+ IN VOID *RomImage, | |
+ IN UINTN ImageSize, | |
+ IN OUT UINTN *RuntimeImageLength, | |
+ OUT UINT8 *DiskStart, OPTIONAL | |
+ OUT UINT8 *DiskEnd, OPTIONAL | |
+ OUT VOID **RomShadowAddress OPTIONAL | |
+ ) | |
+{ | |
+ EFI_STATUS Status; | |
+ EFI_STATUS PciEnableStatus; | |
+ EFI_PCI_IO_PROTOCOL *PciIo; | |
+ UINT8 LocalDiskStart; | |
+ UINT8 LocalDiskEnd; | |
+ UINTN Segment; | |
+ UINTN Bus; | |
+ UINTN Device; | |
+ UINTN Function; | |
+ EFI_IA32_REGISTER_SET Regs; | |
+ UINT8 VideoMode; | |
+ EFI_TIME BootTime; | |
+ UINT32 *BdaPtr; | |
+ UINT32 LocalTime; | |
+ UINT32 StartBbsIndex; | |
+ UINT32 EndBbsIndex; | |
+ UINT32 MaxRomAddr; | |
+ UINTN TempData; | |
+ UINTN InitAddress; | |
+ UINTN RuntimeAddress; | |
+ EFI_PHYSICAL_ADDRESS PhysicalAddress; | |
+ UINT32 Granularity; | |
+ | |
+ PciIo = NULL; | |
+ LocalDiskStart = 0; | |
+ LocalDiskEnd = 0; | |
+ Segment = 0; | |
+ Bus = 0; | |
+ Device = 0; | |
+ Function = 0; | |
+ VideoMode = 0; | |
+ PhysicalAddress = 0; | |
+ MaxRomAddr = PcdGet32 (PcdEndOpromShadowAddress); | |
+ | |
+ if (Private->Legacy16Table->TableLength >= OFFSET_OF(EFI_COMPATIBILITY16_TABLE, | |
+ HiPermanentMemoryAddress) && | |
+ Private->Legacy16Table->UmaAddress != 0 && Private->Legacy16Table->UmaSize != 0 && | |
+ MaxRomAddr > (Private->Legacy16Table->UmaAddress)) { | |
+ MaxRomAddr = Private->Legacy16Table->UmaAddress; | |
+ } | |
+ PciProgramAllInterruptLineRegisters (Private); | |
+ | |
+ if ((OpromRevision >= 3) && (Private->Csm16PciInterfaceVersion >= 0x0300)) { | |
+ // | |
+ // CSM16 3.0 meets PCI 3.0 OpROM | |
+ // first test if there is enough space for its INIT code | |
+ // | |
+ PhysicalAddress = CONVENTIONAL_MEMORY_TOP; | |
+ Status = gBS->AllocatePages ( | |
+ AllocateMaxAddress, | |
+ EfiBootServicesCode, | |
+ EFI_SIZE_TO_PAGES (ImageSize), | |
+ &PhysicalAddress | |
+ ); | |
+ | |
+ if (EFI_ERROR (Status)) { | |
+ DEBUG ((EFI_D_ERROR, "return LegacyBiosInstallRom(%d): EFI_OUT_OF_RESOURCES (no more space for OpROM)\n", __LINE__)); | |
+ // | |
+ // Report Status Code to indicate that there is no enough space for OpROM | |
+ // | |
+ REPORT_STATUS_CODE ( | |
+ EFI_ERROR_CODE | EFI_ERROR_MINOR, | |
+ (EFI_SOFTWARE_DXE_BS_DRIVER | EFI_SW_DXE_BS_EC_LEGACY_OPROM_NO_SPACE) | |
+ ); | |
+ return EFI_OUT_OF_RESOURCES; | |
+ } | |
+ InitAddress = (UINTN) PhysicalAddress; | |
+ // | |
+ // then test if there is enough space for its RT code | |
+ // | |
+ RuntimeAddress = Private->OptionRom; | |
+ if (RuntimeAddress + *RuntimeImageLength > MaxRomAddr) { | |
+ DEBUG ((EFI_D_ERROR, "return LegacyBiosInstallRom(%d): EFI_OUT_OF_RESOURCES (no more space for OpROM)\n", __LINE__)); | |
+ gBS->FreePages (PhysicalAddress, EFI_SIZE_TO_PAGES (ImageSize)); | |
+ // | |
+ // Report Status Code to indicate that there is no enough space for OpROM | |
+ // | |
+ REPORT_STATUS_CODE ( | |
+ EFI_ERROR_CODE | EFI_ERROR_MINOR, | |
+ (EFI_SOFTWARE_DXE_BS_DRIVER | EFI_SW_DXE_BS_EC_LEGACY_OPROM_NO_SPACE) | |
+ ); | |
+ return EFI_OUT_OF_RESOURCES; | |
+ } | |
+ } else { | |
+ // CSM16 3.0 meets PCI 2.x OpROM | |
+ // CSM16 2.x meets PCI 2.x/3.0 OpROM | |
+ // test if there is enough space for its INIT code | |
+ // | |
+ InitAddress = PCI_START_ADDRESS (Private->OptionRom); | |
+ if (InitAddress + ImageSize > MaxRomAddr) { | |
+ DEBUG ((EFI_D_ERROR, "return LegacyBiosInstallRom(%d): EFI_OUT_OF_RESOURCES (no more space for OpROM)\n", __LINE__)); | |
+ // | |
+ // Report Status Code to indicate that there is no enough space for OpROM | |
+ // | |
+ REPORT_STATUS_CODE ( | |
+ EFI_ERROR_CODE | EFI_ERROR_MINOR, | |
+ (EFI_SOFTWARE_DXE_BS_DRIVER | EFI_SW_DXE_BS_EC_LEGACY_OPROM_NO_SPACE) | |
+ ); | |
+ return EFI_OUT_OF_RESOURCES; | |
+ } | |
+ | |
+ RuntimeAddress = InitAddress; | |
+ } | |
+ | |
+ Private->LegacyRegion->UnLock ( | |
+ Private->LegacyRegion, | |
+ 0xE0000, | |
+ 0x20000, | |
+ &Granularity | |
+ ); | |
+ | |
+ Private->LegacyRegion->UnLock ( | |
+ Private->LegacyRegion, | |
+ (UINT32) RuntimeAddress, | |
+ (UINT32) ImageSize, | |
+ &Granularity | |
+ ); | |
+ | |
+ DEBUG ((EFI_D_INFO, " Shadowing OpROM init/runtime/isize = %x/%x/%x\n", InitAddress, RuntimeAddress, ImageSize)); | |
+ | |
+ CopyMem ((VOID *) InitAddress, RomImage, ImageSize); | |
+ | |
+ // | |
+ // Read the highest disk number "installed: and assume a new disk will | |
+ // show up on the first drive past the current value. | |
+ // There are several considerations here: | |
+ // 1. Non-BBS compliant drives will change 40:75 but 16-bit CSM will undo | |
+ // the change until boot selection time frame. | |
+ // 2. BBS compliants drives will not change 40:75 until boot time. | |
+ // 3. Onboard IDE controllers will change 40:75 | |
+ // | |
+ LocalDiskStart = (UINT8) ((*(UINT8 *) ((UINTN) 0x475)) + 0x80); | |
+ if ((Private->Disk4075 + 0x80) < LocalDiskStart) { | |
+ // | |
+ // Update table since onboard IDE drives found | |
+ // | |
+ Private->LegacyEfiHddTable[Private->LegacyEfiHddTableIndex].PciSegment = 0xff; | |
+ Private->LegacyEfiHddTable[Private->LegacyEfiHddTableIndex].PciBus = 0xff; | |
+ Private->LegacyEfiHddTable[Private->LegacyEfiHddTableIndex].PciDevice = 0xff; | |
+ Private->LegacyEfiHddTable[Private->LegacyEfiHddTableIndex].PciFunction = 0xff; | |
+ Private->LegacyEfiHddTable[Private->LegacyEfiHddTableIndex].StartDriveNumber = (UINT8) (Private->Disk4075 + 0x80); | |
+ Private->LegacyEfiHddTable[Private->LegacyEfiHddTableIndex].EndDriveNumber = LocalDiskStart; | |
+ Private->LegacyEfiHddTableIndex ++; | |
+ Private->Disk4075 = (UINT8) (LocalDiskStart & 0x7f); | |
+ Private->DiskEnd = LocalDiskStart; | |
+ } | |
+ | |
+ if (PciHandle != mVgaHandle) { | |
+ | |
+ EnablePs2Keyboard (); | |
+ | |
+ // | |
+ // Store current mode settings since PrepareToScanRom may change mode. | |
+ // | |
+ VideoMode = *(UINT8 *) ((UINTN) (0x400 + BDA_VIDEO_MODE)); | |
+ } | |
+ // | |
+ // Notify the platform that we are about to scan the ROM | |
+ // | |
+ Status = Private->LegacyBiosPlatform->PlatformHooks ( | |
+ Private->LegacyBiosPlatform, | |
+ EfiPlatformHookPrepareToScanRom, | |
+ 0, | |
+ PciHandle, | |
+ &InitAddress, | |
+ NULL, | |
+ NULL | |
+ ); | |
+ | |
+ // | |
+ // If Status returned is EFI_UNSUPPORTED then abort due to platform | |
+ // policy. | |
+ // | |
+ if (Status == EFI_UNSUPPORTED) { | |
+ goto Done; | |
+ } | |
+ | |
+ // | |
+ // Report corresponding status code | |
+ // | |
+ REPORT_STATUS_CODE ( | |
+ EFI_PROGRESS_CODE, | |
+ (EFI_SOFTWARE_DXE_BS_DRIVER | EFI_SW_CSM_LEGACY_ROM_INIT) | |
+ ); | |
+ | |
+ // | |
+ // Generate number of ticks since midnight for BDA. Some OPROMs require | |
+ // this. Place result in 40:6C-6F | |
+ // | |
+ gRT->GetTime (&BootTime, NULL); | |
+ LocalTime = BootTime.Hour * 3600 + BootTime.Minute * 60 + BootTime.Second; | |
+ | |
+ // | |
+ // Multiply result by 18.2 for number of ticks since midnight. | |
+ // Use 182/10 to avoid floating point math. | |
+ // | |
+ LocalTime = (LocalTime * 182) / 10; | |
+ BdaPtr = (UINT32 *) ((UINTN) 0x46C); | |
+ *BdaPtr = LocalTime; | |
+ | |
+ // | |
+ // Pass in handoff data | |
+ // | |
+ PciEnableStatus = EFI_UNSUPPORTED; | |
+ ZeroMem (&Regs, sizeof (Regs)); | |
+ if (PciHandle != NULL) { | |
+ | |
+ Status = gBS->HandleProtocol ( | |
+ PciHandle, | |
+ &gEfiPciIoProtocolGuid, | |
+ (VOID **) &PciIo | |
+ ); | |
+ ASSERT_EFI_ERROR (Status); | |
+ | |
+ // | |
+ // Enable command register. | |
+ // | |
+ PciEnableStatus = PciIo->Attributes ( | |
+ PciIo, | |
+ EfiPciIoAttributeOperationEnable, | |
+ EFI_PCI_DEVICE_ENABLE, | |
+ NULL | |
+ ); | |
+ | |
+ PciIo->GetLocation ( | |
+ PciIo, | |
+ &Segment, | |
+ &Bus, | |
+ &Device, | |
+ &Function | |
+ ); | |
+ DEBUG ((EFI_D_INFO, "Shadowing OpROM on the PCI device %x/%x/%x\n", Bus, Device, Function)); | |
+ } | |
+ | |
+ mIgnoreBbsUpdateFlag = FALSE; | |
+ Regs.X.AX = Legacy16DispatchOprom; | |
+ | |
+ // | |
+ // Generate DispatchOpRomTable data | |
+ // | |
+ Private->IntThunk->DispatchOpromTable.PnPInstallationCheckSegment = Private->Legacy16Table->PnPInstallationCheckSegment; | |
+ Private->IntThunk->DispatchOpromTable.PnPInstallationCheckOffset = Private->Legacy16Table->PnPInstallationCheckOffset; | |
+ Private->IntThunk->DispatchOpromTable.OpromSegment = (UINT16) (InitAddress >> 4); | |
+ Private->IntThunk->DispatchOpromTable.PciBus = (UINT8) Bus; | |
+ Private->IntThunk->DispatchOpromTable.PciDeviceFunction = (UINT8) ((Device << 3) | Function); | |
+ Private->IntThunk->DispatchOpromTable.NumberBbsEntries = (UINT8) Private->IntThunk->EfiToLegacy16BootTable.NumberBbsEntries; | |
+ Private->IntThunk->DispatchOpromTable.BbsTablePointer = (UINT32) (UINTN) Private->BbsTablePtr; | |
+ Private->IntThunk->DispatchOpromTable.RuntimeSegment = (UINT16)((OpromRevision < 3) ? 0xffff : (RuntimeAddress >> 4)); | |
+ TempData = (UINTN) &Private->IntThunk->DispatchOpromTable; | |
+ Regs.X.ES = EFI_SEGMENT ((UINT32) TempData); | |
+ Regs.X.BX = EFI_OFFSET ((UINT32) TempData); | |
+ // | |
+ // Skip dispatching ROM for those PCI devices that can not be enabled by PciIo->Attributes | |
+ // Otherwise, it may cause the system to hang in some cases | |
+ // | |
+ if (!EFI_ERROR (PciEnableStatus)) { | |
+ DEBUG ((EFI_D_INFO, " Legacy16DispatchOprom - %02x/%02x/%02x\n", Bus, Device, Function)); | |
+ Private->LegacyBios.FarCall86 ( | |
+ &Private->LegacyBios, | |
+ Private->Legacy16CallSegment, | |
+ Private->Legacy16CallOffset, | |
+ &Regs, | |
+ NULL, | |
+ 0 | |
+ ); | |
+ } else { | |
+ Regs.X.BX = 0; | |
+ } | |
+ | |
+ if (Private->IntThunk->DispatchOpromTable.NumberBbsEntries != (UINT8) Private->IntThunk->EfiToLegacy16BootTable.NumberBbsEntries) { | |
+ Private->IntThunk->EfiToLegacy16BootTable.NumberBbsEntries = (UINT8) Private->IntThunk->DispatchOpromTable.NumberBbsEntries; | |
+ mIgnoreBbsUpdateFlag = TRUE; | |
+ } | |
+ // | |
+ // Check if non-BBS compliant drives found | |
+ // | |
+ if (Regs.X.BX != 0) { | |
+ LocalDiskEnd = (UINT8) (LocalDiskStart + Regs.H.BL); | |
+ Private->LegacyEfiHddTable[Private->LegacyEfiHddTableIndex].PciSegment = (UINT8) Segment; | |
+ Private->LegacyEfiHddTable[Private->LegacyEfiHddTableIndex].PciBus = (UINT8) Bus; | |
+ Private->LegacyEfiHddTable[Private->LegacyEfiHddTableIndex].PciDevice = (UINT8) Device; | |
+ Private->LegacyEfiHddTable[Private->LegacyEfiHddTableIndex].PciFunction = (UINT8) Function; | |
+ Private->LegacyEfiHddTable[Private->LegacyEfiHddTableIndex].StartDriveNumber = Private->DiskEnd; | |
+ Private->DiskEnd = LocalDiskEnd; | |
+ Private->LegacyEfiHddTable[Private->LegacyEfiHddTableIndex].EndDriveNumber = Private->DiskEnd; | |
+ Private->LegacyEfiHddTableIndex += 1; | |
+ } | |
+ // | |
+ // Skip video mode set, if installing VGA | |
+ // | |
+ if (PciHandle != mVgaHandle) { | |
+ // | |
+ // Set mode settings since PrepareToScanRom may change mode | |
+ // | |
+ if (VideoMode != *(UINT8 *) ((UINTN) (0x400 + BDA_VIDEO_MODE))) { | |
+ // | |
+ // The active video mode is changed, restore it to original mode. | |
+ // | |
+ Regs.H.AH = 0x00; | |
+ Regs.H.AL = VideoMode; | |
+ Private->LegacyBios.Int86 (&Private->LegacyBios, 0x10, &Regs); | |
+ } | |
+ } | |
+ // | |
+ // Regs.X.AX from the adapter initializion is ignored since some adapters | |
+ // do not follow the standard of setting AX = 0 on success. | |
+ // | |
+ // | |
+ // The ROM could have updated it's size so we need to read again. | |
+ // | |
+ if (((EFI_LEGACY_EXPANSION_ROM_HEADER *) RuntimeAddress)->Signature != PCI_EXPANSION_ROM_HEADER_SIGNATURE) { | |
+ // | |
+ // Now we check the signature (0xaa55) to judge whether the run-time code is truly generated by INIT function. | |
+ // If signature is not valid, that means the INIT function didn't copy the run-time code to RuntimeAddress. | |
+ // | |
+ *RuntimeImageLength = 0; | |
+ } else { | |
+ *RuntimeImageLength = ((EFI_LEGACY_EXPANSION_ROM_HEADER *) RuntimeAddress)->Size512 * 512; | |
+ } | |
+ | |
+ DEBUG ((EFI_D_INFO, " fsize = %x\n", *RuntimeImageLength)); | |
+ | |
+ // | |
+ // If OpROM runs in 2.0 mode | |
+ // | |
+ if (PhysicalAddress == 0) { | |
+ if (*RuntimeImageLength < ImageSize) { | |
+ // | |
+ // Make area from end of shadowed rom to end of original rom all ffs | |
+ // | |
+ gBS->SetMem ((VOID *) (InitAddress + *RuntimeImageLength), ImageSize - *RuntimeImageLength, 0xff); | |
+ } | |
+ } | |
+ | |
+ LocalDiskEnd = (UINT8) ((*(UINT8 *) ((UINTN) 0x475)) + 0x80); | |
+ | |
+ // | |
+ // Allow platform to perform any required actions after the | |
+ // OPROM has been initialized. | |
+ // | |
+ Status = Private->LegacyBiosPlatform->PlatformHooks ( | |
+ Private->LegacyBiosPlatform, | |
+ EfiPlatformHookAfterRomInit, | |
+ 0, | |
+ PciHandle, | |
+ &RuntimeAddress, | |
+ NULL, | |
+ NULL | |
+ ); | |
+ if (PciHandle != NULL) { | |
+ // | |
+ // If no PCI Handle then no header or Bevs. | |
+ // | |
+ if ((*RuntimeImageLength != 0) && (!mIgnoreBbsUpdateFlag)) { | |
+ StartBbsIndex = Private->IntThunk->EfiToLegacy16BootTable.NumberBbsEntries; | |
+ TempData = RuntimeAddress; | |
+ UpdateBevBcvTable ( | |
+ Private, | |
+ (EFI_LEGACY_EXPANSION_ROM_HEADER *) TempData, | |
+ PciIo | |
+ ); | |
+ EndBbsIndex = Private->IntThunk->EfiToLegacy16BootTable.NumberBbsEntries; | |
+ LocalDiskEnd = (UINT8) (LocalDiskStart + (UINT8) (EndBbsIndex - StartBbsIndex)); | |
+ if (LocalDiskEnd != LocalDiskStart) { | |
+ Private->LegacyEfiHddTable[Private->LegacyEfiHddTableIndex].PciSegment = (UINT8) Segment; | |
+ Private->LegacyEfiHddTable[Private->LegacyEfiHddTableIndex].PciBus = (UINT8) Bus; | |
+ Private->LegacyEfiHddTable[Private->LegacyEfiHddTableIndex].PciDevice = (UINT8) Device; | |
+ Private->LegacyEfiHddTable[Private->LegacyEfiHddTableIndex].PciFunction = (UINT8) Function; | |
+ Private->LegacyEfiHddTable[Private->LegacyEfiHddTableIndex].StartDriveNumber = Private->DiskEnd; | |
+ Private->DiskEnd = LocalDiskEnd; | |
+ Private->LegacyEfiHddTable[Private->LegacyEfiHddTableIndex].EndDriveNumber = Private->DiskEnd; | |
+ Private->LegacyEfiHddTableIndex += 1; | |
+ } | |
+ } | |
+ // | |
+ // Mark PCI device as having a legacy BIOS ROM loaded. | |
+ // | |
+ RomShadow ( | |
+ PciHandle, | |
+ (UINT32) RuntimeAddress, | |
+ (UINT32) *RuntimeImageLength, | |
+ LocalDiskStart, | |
+ LocalDiskEnd | |
+ ); | |
+ } | |
+ | |
+ // | |
+ // Stuff caller's OPTIONAL return parameters. | |
+ // | |
+ if (RomShadowAddress != NULL) { | |
+ *RomShadowAddress = (VOID *) RuntimeAddress; | |
+ } | |
+ | |
+ if (DiskStart != NULL) { | |
+ *DiskStart = LocalDiskStart; | |
+ } | |
+ | |
+ if (DiskEnd != NULL) { | |
+ *DiskEnd = LocalDiskEnd; | |
+ } | |
+ | |
+ Private->OptionRom = (UINT32) (RuntimeAddress + *RuntimeImageLength); | |
+ | |
+ Status = EFI_SUCCESS; | |
+ | |
+Done: | |
+ if (PhysicalAddress != 0) { | |
+ // | |
+ // Free pages when OpROM is 3.0 | |
+ // | |
+ gBS->FreePages (PhysicalAddress, EFI_SIZE_TO_PAGES (ImageSize)); | |
+ } | |
+ | |
+ // | |
+ // Insure all shadowed areas are locked | |
+ // | |
+ Private->LegacyRegion->Lock ( | |
+ Private->LegacyRegion, | |
+ 0xC0000, | |
+ 0x40000, | |
+ &Granularity | |
+ ); | |
+ | |
+ return Status; | |
+} | |
+ | |
+/** | |
+ Load a legacy PC-AT OPROM on the PciHandle device. Return information | |
+ about how many disks were added by the OPROM and the shadow address and | |
+ size. DiskStart & DiskEnd are INT 13h drive letters. Thus 0x80 is C: | |
+ | |
+ @param This Protocol instance pointer. | |
+ @param PciHandle The PCI PC-AT OPROM from this devices ROM BAR will | |
+ be loaded. This value is NULL if RomImage is | |
+ non-NULL. This is the normal case. | |
+ @param RomImage A PCI PC-AT ROM image. This argument is non-NULL | |
+ if there is no hardware associated with the ROM | |
+ and thus no PciHandle, otherwise is must be NULL. | |
+ Example is PXE base code. | |
+ @param Flags Indicates if ROM found and if PC-AT. | |
+ @param DiskStart Disk number of first device hooked by the ROM. If | |
+ DiskStart is the same as DiskEnd no disked were | |
+ hooked. | |
+ @param DiskEnd Disk number of the last device hooked by the ROM. | |
+ @param RomShadowAddress Shadow address of PC-AT ROM | |
+ @param RomShadowedSize Size of RomShadowAddress in bytes | |
+ | |
+ @retval EFI_SUCCESS Legacy ROM loaded for this device | |
+ @retval EFI_INVALID_PARAMETER PciHandle not found | |
+ @retval EFI_UNSUPPORTED There is no PCI ROM in the ROM BAR or no onboard | |
+ ROM | |
+ | |
+**/ | |
+EFI_STATUS | |
+EFIAPI | |
+LegacyBiosInstallPciRom ( | |
+ IN EFI_LEGACY_BIOS_PROTOCOL * This, | |
+ IN EFI_HANDLE PciHandle, | |
+ IN VOID **RomImage, | |
+ OUT UINTN *Flags, | |
+ OUT UINT8 *DiskStart, OPTIONAL | |
+ OUT UINT8 *DiskEnd, OPTIONAL | |
+ OUT VOID **RomShadowAddress, OPTIONAL | |
+ OUT UINT32 *RomShadowedSize OPTIONAL | |
+ ) | |
+{ | |
+ EFI_STATUS Status; | |
+ LEGACY_BIOS_INSTANCE *Private; | |
+ VOID *LocalRomImage; | |
+ UINTN ImageSize; | |
+ UINTN RuntimeImageLength; | |
+ EFI_PCI_IO_PROTOCOL *PciIo; | |
+ PCI_TYPE01 PciConfigHeader; | |
+ UINTN HandleCount; | |
+ EFI_HANDLE *HandleBuffer; | |
+ UINTN PciSegment; | |
+ UINTN PciBus; | |
+ UINTN PciDevice; | |
+ UINTN PciFunction; | |
+ UINTN LastBus; | |
+ UINTN Index; | |
+ UINT8 OpromRevision; | |
+ UINT32 Granularity; | |
+ PCI_3_0_DATA_STRUCTURE *Pcir; | |
+ | |
+ OpromRevision = 0; | |
+ | |
+ Private = LEGACY_BIOS_INSTANCE_FROM_THIS (This); | |
+ if (Private->Legacy16Table->LastPciBus == 0) { | |
+ // | |
+ // Get last bus number if not already found | |
+ // | |
+ Status = gBS->LocateHandleBuffer ( | |
+ ByProtocol, | |
+ &gEfiPciIoProtocolGuid, | |
+ NULL, | |
+ &HandleCount, | |
+ &HandleBuffer | |
+ ); | |
+ | |
+ LastBus = 0; | |
+ for (Index = 0; Index < HandleCount; Index++) { | |
+ Status = gBS->HandleProtocol ( | |
+ HandleBuffer[Index], | |
+ &gEfiPciIoProtocolGuid, | |
+ (VOID **) &PciIo | |
+ ); | |
+ if (EFI_ERROR (Status)) { | |
+ continue; | |
+ } | |
+ | |
+ Status = PciIo->GetLocation ( | |
+ PciIo, | |
+ &PciSegment, | |
+ &PciBus, | |
+ &PciDevice, | |
+ &PciFunction | |
+ ); | |
+ if (PciBus > LastBus) { | |
+ LastBus = PciBus; | |
+ } | |
+ } | |
+ | |
+ Private->LegacyRegion->UnLock ( | |
+ Private->LegacyRegion, | |
+ 0xE0000, | |
+ 0x20000, | |
+ &Granularity | |
+ ); | |
+ Private->Legacy16Table->LastPciBus = (UINT8) LastBus; | |
+ Private->LegacyRegion->Lock ( | |
+ Private->LegacyRegion, | |
+ 0xE0000, | |
+ 0x20000, | |
+ &Granularity | |
+ ); | |
+ } | |
+ | |
+ *Flags = 0; | |
+ if ((PciHandle != NULL) && (RomImage == NULL)) { | |
+ // | |
+ // If PciHandle has OpRom to Execute | |
+ // and OpRom are all associated with Hardware | |
+ // | |
+ Status = gBS->HandleProtocol ( | |
+ PciHandle, | |
+ &gEfiPciIoProtocolGuid, | |
+ (VOID **) &PciIo | |
+ ); | |
+ | |
+ if (!EFI_ERROR (Status)) { | |
+ PciIo->Pci.Read ( | |
+ PciIo, | |
+ EfiPciIoWidthUint32, | |
+ 0, | |
+ sizeof (PciConfigHeader) / sizeof (UINT32), | |
+ &PciConfigHeader | |
+ ); | |
+ | |
+ // | |
+ // if video installed & OPROM is video return | |
+ // | |
+ if ( | |
+ ( | |
+ ((PciConfigHeader.Hdr.ClassCode[2] == PCI_CLASS_OLD) && | |
+ (PciConfigHeader.Hdr.ClassCode[1] == PCI_CLASS_OLD_VGA)) | |
+ || | |
+ ((PciConfigHeader.Hdr.ClassCode[2] == PCI_CLASS_DISPLAY) && | |
+ (PciConfigHeader.Hdr.ClassCode[1] == PCI_CLASS_DISPLAY_VGA)) | |
+ ) | |
+ && | |
+ (!Private->VgaInstalled) | |
+ ) { | |
+ mVgaInstallationInProgress = TRUE; | |
+ | |
+ // | |
+ // return EFI_UNSUPPORTED; | |
+ // | |
+ } | |
+ } | |
+ // | |
+ // To run any legacy image, the VGA needs to be installed first. | |
+ // if installing the video, then don't need the thunk as already installed. | |
+ // | |
+ Status = Private->LegacyBiosPlatform->GetPlatformHandle ( | |
+ Private->LegacyBiosPlatform, | |
+ EfiGetPlatformVgaHandle, | |
+ 0, | |
+ &HandleBuffer, | |
+ &HandleCount, | |
+ NULL | |
+ ); | |
+ | |
+ if (!EFI_ERROR (Status)) { | |
+ mVgaHandle = HandleBuffer[0]; | |
+ if ((!Private->VgaInstalled) && (PciHandle != mVgaHandle)) { | |
+ // | |
+ // A return status of EFI_NOT_FOUND is considered valid (No EFI | |
+ // driver is controlling video. | |
+ // | |
+ mVgaInstallationInProgress = TRUE; | |
+ Status = LegacyBiosInstallVgaRom (Private); | |
+ if (EFI_ERROR (Status)) { | |
+ if (Status != EFI_NOT_FOUND) { | |
+ mVgaInstallationInProgress = FALSE; | |
+ return Status; | |
+ } | |
+ } else { | |
+ mVgaInstallationInProgress = FALSE; | |
+ } | |
+ } | |
+ } | |
+ // | |
+ // See if the option ROM for PciHandle has already been executed | |
+ // | |
+ Status = IsLegacyRom (PciHandle); | |
+ | |
+ if (!EFI_ERROR (Status)) { | |
+ mVgaInstallationInProgress = FALSE; | |
+ GetShadowedRomParameters ( | |
+ PciHandle, | |
+ DiskStart, | |
+ DiskEnd, | |
+ RomShadowAddress, | |
+ (UINTN *) RomShadowedSize | |
+ ); | |
+ return EFI_SUCCESS; | |
+ } | |
+ | |
+ Status = LegacyBiosCheckPciRomEx ( | |
+ &Private->LegacyBios, | |
+ PciHandle, | |
+ &LocalRomImage, | |
+ &ImageSize, | |
+ &RuntimeImageLength, | |
+ Flags, | |
+ &OpromRevision, | |
+ NULL | |
+ ); | |
+ if (EFI_ERROR (Status)) { | |
+ // | |
+ // There is no PCI ROM in the ROM BAR or no onboard ROM | |
+ // | |
+ mVgaInstallationInProgress = FALSE; | |
+ return EFI_UNSUPPORTED; | |
+ } | |
+ } else { | |
+ if ((RomImage == NULL) || (*RomImage == NULL)) { | |
+ // | |
+ // If PciHandle is NULL, and no OpRom is to be associated | |
+ // | |
+ mVgaInstallationInProgress = FALSE; | |
+ return EFI_UNSUPPORTED; | |
+ } | |
+ | |
+ Status = Private->LegacyBiosPlatform->GetPlatformHandle ( | |
+ Private->LegacyBiosPlatform, | |
+ EfiGetPlatformVgaHandle, | |
+ 0, | |
+ &HandleBuffer, | |
+ &HandleCount, | |
+ NULL | |
+ ); | |
+ if ((!EFI_ERROR (Status)) && (!Private->VgaInstalled)) { | |
+ // | |
+ // A return status of EFI_NOT_FOUND is considered valid (No EFI | |
+ // driver is controlling video. | |
+ // | |
+ mVgaInstallationInProgress = TRUE; | |
+ Status = LegacyBiosInstallVgaRom (Private); | |
+ if (EFI_ERROR (Status)) { | |
+ if (Status != EFI_NOT_FOUND) { | |
+ mVgaInstallationInProgress = FALSE; | |
+ return Status; | |
+ } | |
+ } else { | |
+ mVgaInstallationInProgress = FALSE; | |
+ } | |
+ } | |
+ | |
+ LocalRomImage = *RomImage; | |
+ if (((PCI_EXPANSION_ROM_HEADER *) LocalRomImage)->Signature != PCI_EXPANSION_ROM_HEADER_SIGNATURE || | |
+ ((PCI_EXPANSION_ROM_HEADER *) LocalRomImage)->PcirOffset == 0 || | |
+ (((PCI_EXPANSION_ROM_HEADER *) LocalRomImage)->PcirOffset & 3 ) != 0) { | |
+ mVgaInstallationInProgress = FALSE; | |
+ return EFI_UNSUPPORTED; | |
+ } | |
+ | |
+ Pcir = (PCI_3_0_DATA_STRUCTURE *) | |
+ ((UINT8 *) LocalRomImage + ((PCI_EXPANSION_ROM_HEADER *) LocalRomImage)->PcirOffset); | |
+ | |
+ if ((Pcir->Signature != PCI_DATA_STRUCTURE_SIGNATURE) || (Pcir->CodeType != PCI_CODE_TYPE_PCAT_IMAGE)) { | |
+ mVgaInstallationInProgress = FALSE; | |
+ return EFI_UNSUPPORTED; | |
+ } | |
+ | |
+ ImageSize = Pcir->ImageLength * 512; | |
+ if (Pcir->Length >= 0x1C) { | |
+ OpromRevision = Pcir->Revision; | |
+ } else { | |
+ OpromRevision = 0; | |
+ } | |
+ if (Pcir->Revision < 3) { | |
+ RuntimeImageLength = 0; | |
+ } else { | |
+ RuntimeImageLength = Pcir->MaxRuntimeImageLength * 512; | |
+ } | |
+ } | |
+ // | |
+ // Shadow and initialize the OpROM. | |
+ // | |
+ ASSERT (Private->TraceIndex < 0x200); | |
+ Private->Trace[Private->TraceIndex] = LEGACY_PCI_TRACE_000; | |
+ Private->TraceIndex ++; | |
+ Private->TraceIndex = (UINT16) (Private->TraceIndex % 0x200); | |
+ Status = LegacyBiosInstallRom ( | |
+ This, | |
+ Private, | |
+ PciHandle, | |
+ OpromRevision, | |
+ LocalRomImage, | |
+ ImageSize, | |
+ &RuntimeImageLength, | |
+ DiskStart, | |
+ DiskEnd, | |
+ RomShadowAddress | |
+ ); | |
+ if (RomShadowedSize != NULL) { | |
+ *RomShadowedSize = (UINT32) RuntimeImageLength; | |
+ } | |
+ | |
+ mVgaInstallationInProgress = FALSE; | |
+ return Status; | |
+} | |
+ | |
diff --git a/OvmfPkg/CsmOld/LegacyBiosDxe/LegacySio.c b/OvmfPkg/CsmOld/LegacyBiosDxe/LegacySio.c | |
new file mode 100644 | |
index 000000000000..f82121c607b0 | |
--- /dev/null | |
+++ b/OvmfPkg/CsmOld/LegacyBiosDxe/LegacySio.c | |
@@ -0,0 +1,234 @@ | |
+/** @file | |
+ Collect Sio information from Native EFI Drivers. | |
+ Sio is floppy, parallel, serial, ... hardware | |
+ | |
+Copyright (c) 2006 - 2010, 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. | |
+ | |
+**/ | |
+ | |
+#include "LegacyBiosInterface.h" | |
+ | |
+ | |
+/** | |
+ Collect EFI Info about legacy devices. | |
+ | |
+ @param Private Legacy BIOS Instance data | |
+ | |
+ @retval EFI_SUCCESS It should always work. | |
+ | |
+**/ | |
+EFI_STATUS | |
+LegacyBiosBuildSioData ( | |
+ IN LEGACY_BIOS_INSTANCE *Private | |
+ ) | |
+{ | |
+ EFI_STATUS Status; | |
+ DEVICE_PRODUCER_DATA_HEADER *SioPtr; | |
+ DEVICE_PRODUCER_SERIAL *Sio1Ptr; | |
+ DEVICE_PRODUCER_PARALLEL *Sio2Ptr; | |
+ DEVICE_PRODUCER_FLOPPY *Sio3Ptr; | |
+ EFI_HANDLE IsaBusController; | |
+ UINTN HandleCount; | |
+ EFI_HANDLE *HandleBuffer; | |
+ UINTN Index; | |
+ UINTN ResourceIndex; | |
+ UINTN ChildIndex; | |
+ EFI_ISA_IO_PROTOCOL *IsaIo; | |
+ EFI_ISA_ACPI_RESOURCE_LIST *ResourceList; | |
+ EFI_ISA_ACPI_RESOURCE *IoResource; | |
+ EFI_ISA_ACPI_RESOURCE *DmaResource; | |
+ EFI_ISA_ACPI_RESOURCE *InterruptResource; | |
+ UINTN EntryCount; | |
+ EFI_OPEN_PROTOCOL_INFORMATION_ENTRY *OpenInfoBuffer; | |
+ EFI_BLOCK_IO_PROTOCOL *BlockIo; | |
+ | |
+ // | |
+ // Get the pointer to the SIO data structure | |
+ // | |
+ SioPtr = &Private->IntThunk->EfiToLegacy16BootTable.SioData; | |
+ | |
+ // | |
+ // Zero the data in the SIO data structure | |
+ // | |
+ gBS->SetMem (SioPtr, sizeof (DEVICE_PRODUCER_DATA_HEADER), 0); | |
+ | |
+ // | |
+ // Find the ISA Bus Controller used for legacy | |
+ // | |
+ Status = Private->LegacyBiosPlatform->GetPlatformHandle ( | |
+ Private->LegacyBiosPlatform, | |
+ EfiGetPlatformIsaBusHandle, | |
+ 0, | |
+ &HandleBuffer, | |
+ &HandleCount, | |
+ NULL | |
+ ); | |
+ IsaBusController = HandleBuffer[0]; | |
+ if (!EFI_ERROR (Status)) { | |
+ // | |
+ // Force ISA Bus Controller to produce all ISA devices | |
+ // | |
+ gBS->ConnectController (IsaBusController, NULL, NULL, TRUE); | |
+ } | |
+ // | |
+ // Get the list of ISA controllers in the system | |
+ // | |
+ Status = gBS->LocateHandleBuffer ( | |
+ ByProtocol, | |
+ &gEfiIsaIoProtocolGuid, | |
+ NULL, | |
+ &HandleCount, | |
+ &HandleBuffer | |
+ ); | |
+ if (EFI_ERROR (Status)) { | |
+ return EFI_SUCCESS; | |
+ } | |
+ // | |
+ // Collect legacy information from each of the ISA controllers in the system | |
+ // | |
+ for (Index = 0; Index < HandleCount; Index++) { | |
+ | |
+ Status = gBS->HandleProtocol (HandleBuffer[Index], &gEfiIsaIoProtocolGuid, (VOID **) &IsaIo); | |
+ if (EFI_ERROR (Status)) { | |
+ continue; | |
+ } | |
+ | |
+ ResourceList = IsaIo->ResourceList; | |
+ | |
+ if (ResourceList == NULL) { | |
+ continue; | |
+ } | |
+ // | |
+ // Collect the resource types neededto fill in the SIO data structure | |
+ // | |
+ IoResource = NULL; | |
+ DmaResource = NULL; | |
+ InterruptResource = NULL; | |
+ for (ResourceIndex = 0; | |
+ ResourceList->ResourceItem[ResourceIndex].Type != EfiIsaAcpiResourceEndOfList; | |
+ ResourceIndex++ | |
+ ) { | |
+ switch (ResourceList->ResourceItem[ResourceIndex].Type) { | |
+ case EfiIsaAcpiResourceIo: | |
+ IoResource = &ResourceList->ResourceItem[ResourceIndex]; | |
+ break; | |
+ | |
+ case EfiIsaAcpiResourceMemory: | |
+ break; | |
+ | |
+ case EfiIsaAcpiResourceDma: | |
+ DmaResource = &ResourceList->ResourceItem[ResourceIndex]; | |
+ break; | |
+ | |
+ case EfiIsaAcpiResourceInterrupt: | |
+ InterruptResource = &ResourceList->ResourceItem[ResourceIndex]; | |
+ break; | |
+ | |
+ default: | |
+ break; | |
+ } | |
+ } | |
+ // | |
+ // See if this is an ISA serial port | |
+ // | |
+ // Ignore DMA resource since it is always returned NULL | |
+ // | |
+ if (ResourceList->Device.HID == EISA_PNP_ID (0x500) || ResourceList->Device.HID == EISA_PNP_ID (0x501)) { | |
+ | |
+ if (ResourceList->Device.UID <= 3 && | |
+ IoResource != NULL && | |
+ InterruptResource != NULL | |
+ ) { | |
+ // | |
+ // Get the handle of the child device that has opened the ISA I/O Protocol | |
+ // | |
+ Status = gBS->OpenProtocolInformation ( | |
+ HandleBuffer[Index], | |
+ &gEfiIsaIoProtocolGuid, | |
+ &OpenInfoBuffer, | |
+ &EntryCount | |
+ ); | |
+ if (EFI_ERROR (Status)) { | |
+ continue; | |
+ } | |
+ // | |
+ // We want resource for legacy even if no 32-bit driver installed | |
+ // | |
+ for (ChildIndex = 0; ChildIndex < EntryCount; ChildIndex++) { | |
+ Sio1Ptr = &SioPtr->Serial[ResourceList->Device.UID]; | |
+ Sio1Ptr->Address = (UINT16) IoResource->StartRange; | |
+ Sio1Ptr->Irq = (UINT8) InterruptResource->StartRange; | |
+ Sio1Ptr->Mode = DEVICE_SERIAL_MODE_NORMAL | DEVICE_SERIAL_MODE_DUPLEX_HALF; | |
+ } | |
+ | |
+ FreePool (OpenInfoBuffer); | |
+ } | |
+ } | |
+ // | |
+ // See if this is an ISA parallel port | |
+ // | |
+ // Ignore DMA resource since it is always returned NULL, port | |
+ // only used in output mode. | |
+ // | |
+ if (ResourceList->Device.HID == EISA_PNP_ID (0x400) || ResourceList->Device.HID == EISA_PNP_ID (0x401)) { | |
+ if (ResourceList->Device.UID <= 2 && | |
+ IoResource != NULL && | |
+ InterruptResource != NULL && | |
+ DmaResource != NULL | |
+ ) { | |
+ Sio2Ptr = &SioPtr->Parallel[ResourceList->Device.UID]; | |
+ Sio2Ptr->Address = (UINT16) IoResource->StartRange; | |
+ Sio2Ptr->Irq = (UINT8) InterruptResource->StartRange; | |
+ Sio2Ptr->Dma = (UINT8) DmaResource->StartRange; | |
+ Sio2Ptr->Mode = DEVICE_PARALLEL_MODE_MODE_OUTPUT_ONLY; | |
+ } | |
+ } | |
+ // | |
+ // See if this is an ISA floppy controller | |
+ // | |
+ if (ResourceList->Device.HID == EISA_PNP_ID (0x604)) { | |
+ if (IoResource != NULL && InterruptResource != NULL && DmaResource != NULL) { | |
+ Status = gBS->HandleProtocol (HandleBuffer[Index], &gEfiBlockIoProtocolGuid, (VOID **) &BlockIo); | |
+ if (!EFI_ERROR (Status)) { | |
+ Sio3Ptr = &SioPtr->Floppy; | |
+ Sio3Ptr->Address = (UINT16) IoResource->StartRange; | |
+ Sio3Ptr->Irq = (UINT8) InterruptResource->StartRange; | |
+ Sio3Ptr->Dma = (UINT8) DmaResource->StartRange; | |
+ Sio3Ptr->NumberOfFloppy++; | |
+ } | |
+ } | |
+ } | |
+ // | |
+ // See if this is a mouse | |
+ // Always set mouse found so USB hot plug will work | |
+ // | |
+ // Ignore lower byte of HID. Pnp0fxx is any type of mouse. | |
+ // | |
+ // Hid = ResourceList->Device.HID & 0xff00ffff; | |
+ // PnpId = EISA_PNP_ID(0x0f00); | |
+ // if (Hid == PnpId) { | |
+ // if (ResourceList->Device.UID == 1) { | |
+ // Status = gBS->HandleProtocol (HandleBuffer[Index], &gEfiSimplePointerProtocolGuid, &SimplePointer); | |
+ // if (!EFI_ERROR (Status)) { | |
+ // | |
+ SioPtr->MousePresent = 0x01; | |
+ // | |
+ // } | |
+ // } | |
+ // } | |
+ // | |
+ } | |
+ | |
+ FreePool (HandleBuffer); | |
+ | |
+ return EFI_SUCCESS; | |
+} | |
diff --git a/OvmfPkg/CsmOld/LegacyBiosDxe/Thunk.c b/OvmfPkg/CsmOld/LegacyBiosDxe/Thunk.c | |
new file mode 100644 | |
index 000000000000..33528f5e186c | |
--- /dev/null | |
+++ b/OvmfPkg/CsmOld/LegacyBiosDxe/Thunk.c | |
@@ -0,0 +1,419 @@ | |
+/** @file | |
+ Call into 16-bit BIOS code, Use AsmThunk16 function of BaseLib. | |
+ | |
+Copyright (c) 2006 - 2011, 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. | |
+ | |
+**/ | |
+ | |
+#include "LegacyBiosInterface.h" | |
+ | |
+THUNK_CONTEXT mThunkContext; | |
+ | |
+/** | |
+ Sets the counter value for Timer #0 in a legacy 8254 timer. | |
+ | |
+ @param Count - The 16-bit counter value to program into Timer #0 of the legacy 8254 timer. | |
+ | |
+**/ | |
+VOID | |
+SetPitCount ( | |
+ IN UINT16 Count | |
+ ) | |
+{ | |
+ IoWrite8 (TIMER_CONTROL_PORT, TIMER0_CONTROL_WORD); | |
+ IoWrite8 (TIMER0_COUNT_PORT, (UINT8) (Count & 0xFF)); | |
+ IoWrite8 (TIMER0_COUNT_PORT, (UINT8) ((Count>>8) & 0xFF)); | |
+} | |
+ | |
+/** | |
+ Thunk to 16-bit real mode and execute a software interrupt with a vector | |
+ of BiosInt. Regs will contain the 16-bit register context on entry and | |
+ exit. | |
+ | |
+ @param This Protocol instance pointer. | |
+ @param BiosInt Processor interrupt vector to invoke | |
+ @param Regs Register contexted passed into (and returned) from thunk to | |
+ 16-bit mode | |
+ | |
+ @retval FALSE Thunk completed, and there were no BIOS errors in the target code. | |
+ See Regs for status. | |
+ @retval TRUE There was a BIOS erro in the target code. | |
+ | |
+**/ | |
+BOOLEAN | |
+EFIAPI | |
+LegacyBiosInt86 ( | |
+ IN EFI_LEGACY_BIOS_PROTOCOL *This, | |
+ IN UINT8 BiosInt, | |
+ IN EFI_IA32_REGISTER_SET *Regs | |
+ ) | |
+{ | |
+ UINT32 *VectorBase; | |
+ | |
+ Regs->X.Flags.Reserved1 = 1; | |
+ Regs->X.Flags.Reserved2 = 0; | |
+ Regs->X.Flags.Reserved3 = 0; | |
+ Regs->X.Flags.Reserved4 = 0; | |
+ Regs->X.Flags.IOPL = 3; | |
+ Regs->X.Flags.NT = 0; | |
+ Regs->X.Flags.IF = 0; | |
+ Regs->X.Flags.TF = 0; | |
+ Regs->X.Flags.CF = 0; | |
+ // | |
+ // The base address of legacy interrupt vector table is 0. | |
+ // We use this base address to get the legacy interrupt handler. | |
+ // | |
+ VectorBase = 0; | |
+ | |
+ return InternalLegacyBiosFarCall ( | |
+ This, | |
+ (UINT16) ((VectorBase)[BiosInt] >> 16), | |
+ (UINT16) (VectorBase)[BiosInt], | |
+ Regs, | |
+ &Regs->X.Flags, | |
+ sizeof (Regs->X.Flags) | |
+ ); | |
+} | |
+ | |
+/** | |
+ Thunk to 16-bit real mode and call Segment:Offset. Regs will contain the | |
+ 16-bit register context on entry and exit. Arguments can be passed on | |
+ the Stack argument | |
+ | |
+ @param This Protocol instance pointer. | |
+ @param Segment Segemnt of 16-bit mode call | |
+ @param Offset Offset of 16-bit mdoe call | |
+ @param Regs Register contexted passed into (and returned) from | |
+ thunk to 16-bit mode | |
+ @param Stack Caller allocated stack used to pass arguments | |
+ @param StackSize Size of Stack in bytes | |
+ | |
+ @retval FALSE Thunk completed, and there were no BIOS errors in | |
+ the target code. See Regs for status. | |
+ @retval TRUE There was a BIOS erro in the target code. | |
+ | |
+**/ | |
+BOOLEAN | |
+EFIAPI | |
+LegacyBiosFarCall86 ( | |
+ IN EFI_LEGACY_BIOS_PROTOCOL *This, | |
+ IN UINT16 Segment, | |
+ IN UINT16 Offset, | |
+ IN EFI_IA32_REGISTER_SET *Regs, | |
+ IN VOID *Stack, | |
+ IN UINTN StackSize | |
+ ) | |
+{ | |
+ Regs->X.Flags.Reserved1 = 1; | |
+ Regs->X.Flags.Reserved2 = 0; | |
+ Regs->X.Flags.Reserved3 = 0; | |
+ Regs->X.Flags.Reserved4 = 0; | |
+ Regs->X.Flags.IOPL = 3; | |
+ Regs->X.Flags.NT = 0; | |
+ Regs->X.Flags.IF = 1; | |
+ Regs->X.Flags.TF = 0; | |
+ Regs->X.Flags.CF = 0; | |
+ | |
+ return InternalLegacyBiosFarCall (This, Segment, Offset, Regs, Stack, StackSize); | |
+} | |
+ | |
+/** | |
+ Provide NULL interrupt handler which is used to check | |
+ if there is more than one HW interrupt registers with the CPU AP. | |
+ | |
+ @param InterruptType - The type of interrupt that occured | |
+ @param SystemContext - A pointer to the system context when the interrupt occured | |
+ | |
+**/ | |
+VOID | |
+EFIAPI | |
+LegacyBiosNullInterruptHandler ( | |
+ IN EFI_EXCEPTION_TYPE InterruptType, | |
+ IN EFI_SYSTEM_CONTEXT SystemContext | |
+ ) | |
+{ | |
+} | |
+ | |
+/** | |
+ Thunk to 16-bit real mode and call Segment:Offset. Regs will contain the | |
+ 16-bit register context on entry and exit. Arguments can be passed on | |
+ the Stack argument | |
+ | |
+ @param This Protocol instance pointer. | |
+ @param Segment Segemnt of 16-bit mode call | |
+ @param Offset Offset of 16-bit mdoe call | |
+ @param Regs Register contexted passed into (and returned) from thunk to | |
+ 16-bit mode | |
+ @param Stack Caller allocated stack used to pass arguments | |
+ @param StackSize Size of Stack in bytes | |
+ | |
+ @retval FALSE Thunk completed, and there were no BIOS errors in the target code. | |
+ See Regs for status. | |
+ @retval TRUE There was a BIOS erro in the target code. | |
+ | |
+**/ | |
+BOOLEAN | |
+EFIAPI | |
+InternalLegacyBiosFarCall ( | |
+ IN EFI_LEGACY_BIOS_PROTOCOL *This, | |
+ IN UINT16 Segment, | |
+ IN UINT16 Offset, | |
+ IN EFI_IA32_REGISTER_SET *Regs, | |
+ IN VOID *Stack, | |
+ IN UINTN StackSize | |
+ ) | |
+{ | |
+ UINTN Status; | |
+ LEGACY_BIOS_INSTANCE *Private; | |
+ UINT16 *Stack16; | |
+ EFI_TPL OriginalTpl; | |
+ IA32_REGISTER_SET ThunkRegSet; | |
+ BOOLEAN InterruptState; | |
+ UINT64 TimerPeriod; | |
+ | |
+ Private = LEGACY_BIOS_INSTANCE_FROM_THIS (This); | |
+ | |
+ ZeroMem (&ThunkRegSet, sizeof (ThunkRegSet)); | |
+ ThunkRegSet.X.DI = Regs->X.DI; | |
+ ThunkRegSet.X.SI = Regs->X.SI; | |
+ ThunkRegSet.X.BP = Regs->X.BP; | |
+ ThunkRegSet.X.BX = Regs->X.BX; | |
+ ThunkRegSet.X.DX = Regs->X.DX; | |
+ // | |
+ // Sometimes, ECX is used to pass in 32 bit data. For example, INT 1Ah, AX = B10Dh is | |
+ // "PCI BIOS v2.0c + Write Configuration DWORD" and ECX has the dword to write. | |
+ // | |
+ ThunkRegSet.E.ECX = Regs->E.ECX; | |
+ ThunkRegSet.X.AX = Regs->X.AX; | |
+ ThunkRegSet.E.DS = Regs->X.DS; | |
+ ThunkRegSet.E.ES = Regs->X.ES; | |
+ | |
+ CopyMem (&(ThunkRegSet.E.EFLAGS.UintN), &(Regs->X.Flags), sizeof (Regs->X.Flags)); | |
+ | |
+ // | |
+ // Clear the error flag; thunk code may set it. Stack16 should be the high address | |
+ // Make Statk16 address the low 16 bit must be not zero. | |
+ // | |
+ Stack16 = (UINT16 *)((UINT8 *) mThunkContext.RealModeBuffer + mThunkContext.RealModeBufferSize - sizeof (UINT16)); | |
+ | |
+ // | |
+ // Save current rate of DXE Timer | |
+ // | |
+ Private->Timer->GetTimerPeriod (Private->Timer, &TimerPeriod); | |
+ | |
+ // | |
+ // Disable DXE Timer while executing in real mode | |
+ // | |
+ Private->Timer->SetTimerPeriod (Private->Timer, 0); | |
+ | |
+ // | |
+ // Save and disable interrupt of debug timer | |
+ // | |
+ InterruptState = SaveAndSetDebugTimerInterrupt (FALSE); | |
+ | |
+ // | |
+ // The call to Legacy16 is a critical section to EFI | |
+ // | |
+ OriginalTpl = gBS->RaiseTPL (TPL_HIGH_LEVEL); | |
+ | |
+ // | |
+ // Check to see if there is more than one HW interrupt registers with the CPU AP. | |
+ // If there is, then ASSERT() since that is not compatible with the CSM because | |
+ // interupts other than the Timer interrupt that was disabled above can not be | |
+ // handled properly from real mode. | |
+ // | |
+ DEBUG_CODE ( | |
+ UINTN Vector; | |
+ UINTN Count; | |
+ | |
+ for (Vector = 0x20, Count = 0; Vector < 0x100; Vector++) { | |
+ Status = Private->Cpu->RegisterInterruptHandler (Private->Cpu, Vector, LegacyBiosNullInterruptHandler); | |
+ if (Status == EFI_ALREADY_STARTED) { | |
+ Count++; | |
+ } | |
+ if (Status == EFI_SUCCESS) { | |
+ Private->Cpu->RegisterInterruptHandler (Private->Cpu, Vector, NULL); | |
+ } | |
+ } | |
+ if (Count >= 2) { | |
+ DEBUG ((EFI_D_ERROR, "ERROR: More than one HW interrupt active with CSM enabled\n")); | |
+ } | |
+ ASSERT (Count < 2); | |
+ ); | |
+ | |
+ // | |
+ // If the Timer AP has enabled the 8254 timer IRQ and the current 8254 timer | |
+ // period is less than the CSM required rate of 54.9254, then force the 8254 | |
+ // PIT counter to 0, which is the CSM required rate of 54.9254 ms | |
+ // | |
+ if (Private->TimerUses8254 && TimerPeriod < 549254) { | |
+ SetPitCount (0); | |
+ } | |
+ | |
+ if (Stack != NULL && StackSize != 0) { | |
+ // | |
+ // Copy Stack to low memory stack | |
+ // | |
+ Stack16 -= StackSize / sizeof (UINT16); | |
+ CopyMem (Stack16, Stack, StackSize); | |
+ } | |
+ | |
+ ThunkRegSet.E.SS = (UINT16) (((UINTN) Stack16 >> 16) << 12); | |
+ ThunkRegSet.E.ESP = (UINT16) (UINTN) Stack16; | |
+ ThunkRegSet.E.CS = Segment; | |
+ ThunkRegSet.E.Eip = Offset; | |
+ | |
+ mThunkContext.RealModeState = &ThunkRegSet; | |
+ | |
+ // | |
+ // Set Legacy16 state. 0x08, 0x70 is legacy 8259 vector bases. | |
+ // | |
+ Status = Private->Legacy8259->SetMode (Private->Legacy8259, Efi8259LegacyMode, NULL, NULL); | |
+ ASSERT_EFI_ERROR (Status); | |
+ | |
+ AsmThunk16 (&mThunkContext); | |
+ | |
+ // | |
+ // OPROM may allocate EBDA range by itself and change EBDA base and EBDA size. | |
+ // Get the current EBDA base address, and compared with pre-allocate minimum | |
+ // EBDA base address, if the current EBDA base address is smaller, it indicates | |
+ // PcdEbdaReservedMemorySize should be adjusted to larger for more OPROMs. | |
+ // | |
+ DEBUG_CODE ( | |
+ { | |
+ UINTN EbdaBaseAddress; | |
+ UINTN ReservedEbdaBaseAddress; | |
+ | |
+ EbdaBaseAddress = (*(UINT16 *) (UINTN) 0x40E) << 4; | |
+ ReservedEbdaBaseAddress = CONVENTIONAL_MEMORY_TOP - PcdGet32 (PcdEbdaReservedMemorySize); | |
+ ASSERT (ReservedEbdaBaseAddress <= EbdaBaseAddress); | |
+ } | |
+ ); | |
+ | |
+ if (Stack != NULL && StackSize != 0) { | |
+ // | |
+ // Copy low memory stack to Stack | |
+ // | |
+ CopyMem (Stack, Stack16, StackSize); | |
+ } | |
+ | |
+ // | |
+ // Restore protected mode interrupt state | |
+ // | |
+ Status = Private->Legacy8259->SetMode (Private->Legacy8259, Efi8259ProtectedMode, NULL, NULL); | |
+ ASSERT_EFI_ERROR (Status); | |
+ | |
+ mThunkContext.RealModeState = NULL; | |
+ | |
+ // | |
+ // Enable and restore rate of DXE Timer | |
+ // | |
+ Private->Timer->SetTimerPeriod (Private->Timer, TimerPeriod); | |
+ | |
+ // | |
+ // End critical section | |
+ // | |
+ gBS->RestoreTPL (OriginalTpl); | |
+ | |
+ // | |
+ // Restore interrupt of debug timer | |
+ // | |
+ SaveAndSetDebugTimerInterrupt (InterruptState); | |
+ | |
+ Regs->E.EDI = ThunkRegSet.E.EDI; | |
+ Regs->E.ESI = ThunkRegSet.E.ESI; | |
+ Regs->E.EBP = ThunkRegSet.E.EBP; | |
+ Regs->E.EBX = ThunkRegSet.E.EBX; | |
+ Regs->E.EDX = ThunkRegSet.E.EDX; | |
+ Regs->E.ECX = ThunkRegSet.E.ECX; | |
+ Regs->E.EAX = ThunkRegSet.E.EAX; | |
+ Regs->X.SS = ThunkRegSet.E.SS; | |
+ Regs->X.CS = ThunkRegSet.E.CS; | |
+ Regs->X.DS = ThunkRegSet.E.DS; | |
+ Regs->X.ES = ThunkRegSet.E.ES; | |
+ | |
+ CopyMem (&(Regs->X.Flags), &(ThunkRegSet.E.EFLAGS.UintN), sizeof (Regs->X.Flags)); | |
+ | |
+ return (BOOLEAN) (Regs->X.Flags.CF == 1); | |
+} | |
+ | |
+/** | |
+ Allocate memory < 1 MB and copy the thunker code into low memory. Se up | |
+ all the descriptors. | |
+ | |
+ @param Private Private context for Legacy BIOS | |
+ | |
+ @retval EFI_SUCCESS Should only pass. | |
+ | |
+**/ | |
+EFI_STATUS | |
+LegacyBiosInitializeThunk ( | |
+ IN LEGACY_BIOS_INSTANCE *Private | |
+ ) | |
+{ | |
+ EFI_STATUS Status; | |
+ EFI_PHYSICAL_ADDRESS MemoryAddress; | |
+ UINT8 TimerVector; | |
+ | |
+ MemoryAddress = (EFI_PHYSICAL_ADDRESS) (UINTN) Private->IntThunk; | |
+ | |
+ mThunkContext.RealModeBuffer = (VOID *) (UINTN) (MemoryAddress + ((sizeof (LOW_MEMORY_THUNK) / EFI_PAGE_SIZE) + 1) * EFI_PAGE_SIZE); | |
+ mThunkContext.RealModeBufferSize = EFI_PAGE_SIZE; | |
+ mThunkContext.ThunkAttributes = THUNK_ATTRIBUTE_BIG_REAL_MODE | THUNK_ATTRIBUTE_DISABLE_A20_MASK_INT_15; | |
+ | |
+ AsmPrepareThunk16 (&mThunkContext); | |
+ | |
+ // | |
+ // Get the interrupt vector number corresponding to IRQ0 from the 8259 driver | |
+ // | |
+ TimerVector = 0; | |
+ Status = Private->Legacy8259->GetVector (Private->Legacy8259, Efi8259Irq0, &TimerVector); | |
+ ASSERT_EFI_ERROR (Status); | |
+ | |
+ // | |
+ // Check to see if the Timer AP has hooked the IRQ0 from the 8254 PIT | |
+ // | |
+ Status = Private->Cpu->RegisterInterruptHandler ( | |
+ Private->Cpu, | |
+ TimerVector, | |
+ LegacyBiosNullInterruptHandler | |
+ ); | |
+ if (Status == EFI_SUCCESS) { | |
+ // | |
+ // If the Timer AP has not enabled the 8254 timer IRQ, then force the 8254 PIT | |
+ // counter to 0, which is the CSM required rate of 54.9254 ms | |
+ // | |
+ Private->Cpu->RegisterInterruptHandler ( | |
+ Private->Cpu, | |
+ TimerVector, | |
+ NULL | |
+ ); | |
+ SetPitCount (0); | |
+ | |
+ // | |
+ // Save status that the Timer AP is not using the 8254 PIT | |
+ // | |
+ Private->TimerUses8254 = FALSE; | |
+ } else if (Status == EFI_ALREADY_STARTED) { | |
+ // | |
+ // Save status that the Timer AP is using the 8254 PIT | |
+ // | |
+ Private->TimerUses8254 = TRUE; | |
+ } else { | |
+ // | |
+ // Unexpected status from CPU AP RegisterInterruptHandler() | |
+ // | |
+ ASSERT (FALSE); | |
+ } | |
+ | |
+ return EFI_SUCCESS; | |
+} | |
diff --git a/OvmfPkg/CsmOld/VideoDxe/BiosVideo.c b/OvmfPkg/CsmOld/VideoDxe/BiosVideo.c | |
new file mode 100644 | |
index 000000000000..1bcbd7a806f9 | |
--- /dev/null | |
+++ b/OvmfPkg/CsmOld/VideoDxe/BiosVideo.c | |
@@ -0,0 +1,3336 @@ | |
+/** @file | |
+ ConsoleOut Routines that speak VGA. | |
+ | |
+Copyright (c) 2007 - 2013, 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. | |
+ | |
+**/ | |
+ | |
+#include "BiosVideo.h" | |
+ | |
+// | |
+// EFI Driver Binding Protocol Instance | |
+// | |
+EFI_DRIVER_BINDING_PROTOCOL gBiosVideoDriverBinding = { | |
+ BiosVideoDriverBindingSupported, | |
+ BiosVideoDriverBindingStart, | |
+ BiosVideoDriverBindingStop, | |
+ 0x3, | |
+ NULL, | |
+ NULL | |
+}; | |
+ | |
+// | |
+// Global lookup tables for VGA graphics modes | |
+// | |
+UINT8 mVgaLeftMaskTable[] = { 0xff, 0x7f, 0x3f, 0x1f, 0x0f, 0x07, 0x03, 0x01 }; | |
+ | |
+UINT8 mVgaRightMaskTable[] = { 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe, 0xff }; | |
+ | |
+UINT8 mVgaBitMaskTable[] = { 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01 }; | |
+ | |
+// | |
+// Save controller attributes during first start | |
+// | |
+UINT64 mOriginalPciAttributes; | |
+BOOLEAN mPciAttributesSaved = FALSE; | |
+ | |
+EFI_GRAPHICS_OUTPUT_BLT_PIXEL mVgaColorToGraphicsOutputColor[] = { | |
+ { 0x00, 0x00, 0x00, 0x00 }, | |
+ { 0x98, 0x00, 0x00, 0x00 }, | |
+ { 0x00, 0x98, 0x00, 0x00 }, | |
+ { 0x98, 0x98, 0x00, 0x00 }, | |
+ { 0x00, 0x00, 0x98, 0x00 }, | |
+ { 0x98, 0x00, 0x98, 0x00 }, | |
+ { 0x00, 0x98, 0x98, 0x00 }, | |
+ { 0x98, 0x98, 0x98, 0x00 }, | |
+ { 0x10, 0x10, 0x10, 0x00 }, | |
+ { 0xff, 0x10, 0x10, 0x00 }, | |
+ { 0x10, 0xff, 0x10, 0x00 }, | |
+ { 0xff, 0xff, 0x10, 0x00 }, | |
+ { 0x10, 0x10, 0xff, 0x00 }, | |
+ { 0xf0, 0x10, 0xff, 0x00 }, | |
+ { 0x10, 0xff, 0xff, 0x00 }, | |
+ { 0xff, 0xff, 0xff, 0x00 } | |
+}; | |
+ | |
+// | |
+// Standard timing defined by VESA EDID | |
+// | |
+VESA_BIOS_EXTENSIONS_EDID_TIMING mEstablishedEdidTiming[] = { | |
+ // | |
+ // Established Timing I | |
+ // | |
+ {800, 600, 60}, | |
+ {800, 600, 56}, | |
+ {640, 480, 75}, | |
+ {640, 480, 72}, | |
+ {640, 480, 67}, | |
+ {640, 480, 60}, | |
+ {720, 400, 88}, | |
+ {720, 400, 70}, | |
+ // | |
+ // Established Timing II | |
+ // | |
+ {1280, 1024, 75}, | |
+ {1024, 768, 75}, | |
+ {1024, 768, 70}, | |
+ {1024, 768, 60}, | |
+ {1024, 768, 87}, | |
+ {832, 624, 75}, | |
+ {800, 600, 75}, | |
+ {800, 600, 72}, | |
+ // | |
+ // Established Timing III | |
+ // | |
+ {1152, 870, 75} | |
+}; | |
+ | |
+/** | |
+ Supported. | |
+ | |
+ @param This Pointer to driver binding protocol | |
+ @param Controller Controller handle to connect | |
+ @param RemainingDevicePath A pointer to the remaining portion of a device | |
+ path | |
+ | |
+ @retval EFI_STATUS EFI_SUCCESS:This controller can be managed by this | |
+ driver, Otherwise, this controller cannot be | |
+ managed by this driver | |
+ | |
+**/ | |
+EFI_STATUS | |
+EFIAPI | |
+BiosVideoDriverBindingSupported ( | |
+ IN EFI_DRIVER_BINDING_PROTOCOL *This, | |
+ IN EFI_HANDLE Controller, | |
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath | |
+ ) | |
+{ | |
+ EFI_STATUS Status; | |
+ EFI_LEGACY_BIOS_PROTOCOL *LegacyBios; | |
+ EFI_PCI_IO_PROTOCOL *PciIo; | |
+ PCI_TYPE00 Pci; | |
+ EFI_DEV_PATH *Node; | |
+ | |
+ // | |
+ // See if the Legacy BIOS Protocol is available | |
+ // | |
+ Status = gBS->LocateProtocol (&gEfiLegacyBiosProtocolGuid, NULL, (VOID **) &LegacyBios); | |
+ if (EFI_ERROR (Status)) { | |
+ return Status; | |
+ } | |
+ | |
+ // | |
+ // Open the IO Abstraction(s) needed to perform the supported test | |
+ // | |
+ Status = gBS->OpenProtocol ( | |
+ Controller, | |
+ &gEfiPciIoProtocolGuid, | |
+ (VOID **) &PciIo, | |
+ This->DriverBindingHandle, | |
+ Controller, | |
+ EFI_OPEN_PROTOCOL_BY_DRIVER | |
+ ); | |
+ if (EFI_ERROR (Status) && (Status != EFI_ALREADY_STARTED)) { | |
+ return Status; | |
+ } | |
+ | |
+ if (Status == EFI_ALREADY_STARTED) { | |
+ // | |
+ // If VgaMiniPort protocol is installed, EFI_ALREADY_STARTED indicates failure, | |
+ // because VgaMiniPort protocol is installed on controller handle directly. | |
+ // | |
+ Status = gBS->OpenProtocol ( | |
+ Controller, | |
+ &gEfiVgaMiniPortProtocolGuid, | |
+ NULL, | |
+ NULL, | |
+ NULL, | |
+ EFI_OPEN_PROTOCOL_TEST_PROTOCOL | |
+ ); | |
+ if (!EFI_ERROR (Status)) { | |
+ return EFI_ALREADY_STARTED; | |
+ } | |
+ } | |
+ // | |
+ // See if this is a PCI Graphics Controller by looking at the Command register and | |
+ // Class Code Register | |
+ // | |
+ Status = PciIo->Pci.Read ( | |
+ PciIo, | |
+ EfiPciIoWidthUint32, | |
+ 0, | |
+ sizeof (Pci) / sizeof (UINT32), | |
+ &Pci | |
+ ); | |
+ if (EFI_ERROR (Status)) { | |
+ Status = EFI_UNSUPPORTED; | |
+ goto Done; | |
+ } | |
+ | |
+ Status = EFI_UNSUPPORTED; | |
+ if (Pci.Hdr.ClassCode[2] == 0x03 || (Pci.Hdr.ClassCode[2] == 0x00 && Pci.Hdr.ClassCode[1] == 0x01)) { | |
+ | |
+ Status = EFI_SUCCESS; | |
+ // | |
+ // If this is a graphics controller, | |
+ // go further check RemainingDevicePath validation | |
+ // | |
+ if (RemainingDevicePath != NULL) { | |
+ Node = (EFI_DEV_PATH *) RemainingDevicePath; | |
+ // | |
+ // Check if RemainingDevicePath is the End of Device Path Node, | |
+ // if yes, return EFI_SUCCESS | |
+ // | |
+ if (!IsDevicePathEnd (Node)) { | |
+ // | |
+ // If RemainingDevicePath isn't the End of Device Path Node, | |
+ // check its validation | |
+ // | |
+ if (Node->DevPath.Type != ACPI_DEVICE_PATH || | |
+ Node->DevPath.SubType != ACPI_ADR_DP || | |
+ DevicePathNodeLength(&Node->DevPath) < sizeof(ACPI_ADR_DEVICE_PATH)) { | |
+ Status = EFI_UNSUPPORTED; | |
+ } | |
+ } | |
+ } | |
+ } | |
+ | |
+Done: | |
+ gBS->CloseProtocol ( | |
+ Controller, | |
+ &gEfiPciIoProtocolGuid, | |
+ This->DriverBindingHandle, | |
+ Controller | |
+ ); | |
+ | |
+ return Status; | |
+} | |
+ | |
+ | |
+/** | |
+ Install Graphics Output Protocol onto VGA device handles. | |
+ | |
+ @param This Pointer to driver binding protocol | |
+ @param Controller Controller handle to connect | |
+ @param RemainingDevicePath A pointer to the remaining portion of a device | |
+ path | |
+ | |
+ @return EFI_STATUS | |
+ | |
+**/ | |
+EFI_STATUS | |
+EFIAPI | |
+BiosVideoDriverBindingStart ( | |
+ IN EFI_DRIVER_BINDING_PROTOCOL *This, | |
+ IN EFI_HANDLE Controller, | |
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath | |
+ ) | |
+{ | |
+ EFI_STATUS Status; | |
+ EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath; | |
+ EFI_PCI_IO_PROTOCOL *PciIo; | |
+ EFI_LEGACY_BIOS_PROTOCOL *LegacyBios; | |
+ UINTN Flags; | |
+ UINT64 Supports; | |
+ | |
+ // | |
+ // Initialize local variables | |
+ // | |
+ PciIo = NULL; | |
+ ParentDevicePath = NULL; | |
+ | |
+ // | |
+ // | |
+ // See if the Legacy BIOS Protocol is available | |
+ // | |
+ Status = gBS->LocateProtocol (&gEfiLegacyBiosProtocolGuid, NULL, (VOID **) &LegacyBios); | |
+ if (EFI_ERROR (Status)) { | |
+ return Status; | |
+ } | |
+ | |
+ // | |
+ // Prepare for status code | |
+ // | |
+ Status = gBS->HandleProtocol ( | |
+ Controller, | |
+ &gEfiDevicePathProtocolGuid, | |
+ (VOID **) &ParentDevicePath | |
+ ); | |
+ if (EFI_ERROR (Status)) { | |
+ return Status; | |
+ } | |
+ | |
+ // | |
+ // Open the IO Abstraction(s) needed | |
+ // | |
+ Status = gBS->OpenProtocol ( | |
+ Controller, | |
+ &gEfiPciIoProtocolGuid, | |
+ (VOID **) &PciIo, | |
+ This->DriverBindingHandle, | |
+ Controller, | |
+ EFI_OPEN_PROTOCOL_BY_DRIVER | |
+ ); | |
+ if (EFI_ERROR (Status) && (Status != EFI_ALREADY_STARTED)) { | |
+ return Status; | |
+ } | |
+ | |
+ // | |
+ // Save original PCI attributes | |
+ // | |
+ if (!mPciAttributesSaved) { | |
+ Status = PciIo->Attributes ( | |
+ PciIo, | |
+ EfiPciIoAttributeOperationGet, | |
+ 0, | |
+ &mOriginalPciAttributes | |
+ ); | |
+ | |
+ if (EFI_ERROR (Status)) { | |
+ goto Done; | |
+ } | |
+ mPciAttributesSaved = TRUE; | |
+ } | |
+ | |
+ // | |
+ // Get supported PCI attributes | |
+ // | |
+ Status = PciIo->Attributes ( | |
+ PciIo, | |
+ EfiPciIoAttributeOperationSupported, | |
+ 0, | |
+ &Supports | |
+ ); | |
+ if (EFI_ERROR (Status)) { | |
+ goto Done; | |
+ } | |
+ | |
+ Supports &= (EFI_PCI_IO_ATTRIBUTE_VGA_IO | EFI_PCI_IO_ATTRIBUTE_VGA_IO_16); | |
+ if (Supports == 0 || Supports == (EFI_PCI_IO_ATTRIBUTE_VGA_IO | EFI_PCI_IO_ATTRIBUTE_VGA_IO_16)) { | |
+ Status = EFI_UNSUPPORTED; | |
+ goto Done; | |
+ } | |
+ | |
+ REPORT_STATUS_CODE_WITH_DEVICE_PATH ( | |
+ EFI_PROGRESS_CODE, | |
+ EFI_PERIPHERAL_LOCAL_CONSOLE | EFI_P_PC_ENABLE, | |
+ ParentDevicePath | |
+ ); | |
+ // | |
+ // Enable the device and make sure VGA cycles are being forwarded to this VGA device | |
+ // | |
+ Status = PciIo->Attributes ( | |
+ PciIo, | |
+ EfiPciIoAttributeOperationEnable, | |
+ EFI_PCI_DEVICE_ENABLE | EFI_PCI_IO_ATTRIBUTE_VGA_MEMORY | Supports, | |
+ NULL | |
+ ); | |
+ if (EFI_ERROR (Status)) { | |
+ REPORT_STATUS_CODE_WITH_DEVICE_PATH ( | |
+ EFI_ERROR_CODE | EFI_ERROR_MINOR, | |
+ EFI_PERIPHERAL_LOCAL_CONSOLE | EFI_P_EC_RESOURCE_CONFLICT, | |
+ ParentDevicePath | |
+ ); | |
+ goto Done; | |
+ } | |
+ // | |
+ // Check to see if there is a legacy option ROM image associated with this PCI device | |
+ // | |
+ Status = LegacyBios->CheckPciRom ( | |
+ LegacyBios, | |
+ Controller, | |
+ NULL, | |
+ NULL, | |
+ &Flags | |
+ ); | |
+ if (EFI_ERROR (Status)) { | |
+ goto Done; | |
+ } | |
+ // | |
+ // Post the legacy option ROM if it is available. | |
+ // | |
+ REPORT_STATUS_CODE_WITH_DEVICE_PATH ( | |
+ EFI_PROGRESS_CODE, | |
+ EFI_P_PC_RESET, | |
+ ParentDevicePath | |
+ ); | |
+ Status = LegacyBios->InstallPciRom ( | |
+ LegacyBios, | |
+ Controller, | |
+ NULL, | |
+ &Flags, | |
+ NULL, | |
+ NULL, | |
+ NULL, | |
+ NULL | |
+ ); | |
+ if (EFI_ERROR (Status)) { | |
+ REPORT_STATUS_CODE_WITH_DEVICE_PATH ( | |
+ EFI_ERROR_CODE | EFI_ERROR_MINOR, | |
+ EFI_PERIPHERAL_LOCAL_CONSOLE | EFI_P_EC_CONTROLLER_ERROR, | |
+ ParentDevicePath | |
+ ); | |
+ goto Done; | |
+ } | |
+ | |
+ if (RemainingDevicePath != NULL) { | |
+ if (IsDevicePathEnd (RemainingDevicePath) && | |
+ (FeaturePcdGet (PcdBiosVideoCheckVbeEnable) || FeaturePcdGet (PcdBiosVideoCheckVgaEnable))) { | |
+ // | |
+ // If RemainingDevicePath is the End of Device Path Node, | |
+ // don't create any child device and return EFI_SUCESS | |
+ Status = EFI_SUCCESS; | |
+ goto Done; | |
+ } | |
+ } | |
+ | |
+ // | |
+ // Create child handle and install GraphicsOutputProtocol on it | |
+ // | |
+ Status = BiosVideoChildHandleInstall ( | |
+ This, | |
+ Controller, | |
+ PciIo, | |
+ LegacyBios, | |
+ ParentDevicePath, | |
+ RemainingDevicePath | |
+ ); | |
+ | |
+Done: | |
+ if ((EFI_ERROR (Status)) && (Status != EFI_ALREADY_STARTED)) { | |
+ REPORT_STATUS_CODE_WITH_DEVICE_PATH ( | |
+ EFI_PROGRESS_CODE, | |
+ EFI_PERIPHERAL_LOCAL_CONSOLE | EFI_P_PC_DISABLE, | |
+ ParentDevicePath | |
+ ); | |
+ | |
+ REPORT_STATUS_CODE_WITH_DEVICE_PATH ( | |
+ EFI_PROGRESS_CODE, | |
+ EFI_PERIPHERAL_LOCAL_CONSOLE | EFI_P_EC_NOT_DETECTED, | |
+ ParentDevicePath | |
+ ); | |
+ if (!HasChildHandle (Controller)) { | |
+ if (mPciAttributesSaved) { | |
+ // | |
+ // Restore original PCI attributes | |
+ // | |
+ PciIo->Attributes ( | |
+ PciIo, | |
+ EfiPciIoAttributeOperationSet, | |
+ mOriginalPciAttributes, | |
+ NULL | |
+ ); | |
+ } | |
+ } | |
+ // | |
+ // Release PCI I/O Protocols on the controller handle. | |
+ // | |
+ gBS->CloseProtocol ( | |
+ Controller, | |
+ &gEfiPciIoProtocolGuid, | |
+ This->DriverBindingHandle, | |
+ Controller | |
+ ); | |
+ } | |
+ | |
+ return Status; | |
+} | |
+ | |
+ | |
+/** | |
+ Stop. | |
+ | |
+ @param This Pointer to driver binding protocol | |
+ @param Controller Controller handle to connect | |
+ @param NumberOfChildren Number of children handle created by this driver | |
+ @param ChildHandleBuffer Buffer containing child handle created | |
+ | |
+ @retval EFI_SUCCESS Driver disconnected successfully from controller | |
+ @retval EFI_UNSUPPORTED Cannot find BIOS_VIDEO_DEV structure | |
+ | |
+**/ | |
+EFI_STATUS | |
+EFIAPI | |
+BiosVideoDriverBindingStop ( | |
+ IN EFI_DRIVER_BINDING_PROTOCOL *This, | |
+ IN EFI_HANDLE Controller, | |
+ IN UINTN NumberOfChildren, | |
+ IN EFI_HANDLE *ChildHandleBuffer | |
+ ) | |
+{ | |
+ EFI_STATUS Status; | |
+ BOOLEAN AllChildrenStopped; | |
+ UINTN Index; | |
+ EFI_PCI_IO_PROTOCOL *PciIo; | |
+ | |
+ AllChildrenStopped = TRUE; | |
+ | |
+ if (NumberOfChildren == 0) { | |
+ // | |
+ // Close PCI I/O protocol on the controller handle | |
+ // | |
+ gBS->CloseProtocol ( | |
+ Controller, | |
+ &gEfiPciIoProtocolGuid, | |
+ This->DriverBindingHandle, | |
+ Controller | |
+ ); | |
+ | |
+ return EFI_SUCCESS; | |
+ } | |
+ | |
+ for (Index = 0; Index < NumberOfChildren; Index++) { | |
+ Status = BiosVideoChildHandleUninstall (This, Controller, ChildHandleBuffer[Index]); | |
+ | |
+ if (EFI_ERROR (Status)) { | |
+ AllChildrenStopped = FALSE; | |
+ } | |
+ } | |
+ | |
+ if (!AllChildrenStopped) { | |
+ return EFI_DEVICE_ERROR; | |
+ } | |
+ | |
+ if (!HasChildHandle (Controller)) { | |
+ if (mPciAttributesSaved) { | |
+ Status = gBS->HandleProtocol ( | |
+ Controller, | |
+ &gEfiPciIoProtocolGuid, | |
+ (VOID **) &PciIo | |
+ ); | |
+ ASSERT_EFI_ERROR (Status); | |
+ | |
+ // | |
+ // Restore original PCI attributes | |
+ // | |
+ Status = PciIo->Attributes ( | |
+ PciIo, | |
+ EfiPciIoAttributeOperationSet, | |
+ mOriginalPciAttributes, | |
+ NULL | |
+ ); | |
+ ASSERT_EFI_ERROR (Status); | |
+ } | |
+ } | |
+ | |
+ | |
+ return EFI_SUCCESS; | |
+} | |
+ | |
+ | |
+/** | |
+ Install child handles if the Handle supports MBR format. | |
+ | |
+ @param This Calling context. | |
+ @param ParentHandle Parent Handle | |
+ @param ParentPciIo Parent PciIo interface | |
+ @param ParentLegacyBios Parent LegacyBios interface | |
+ @param ParentDevicePath Parent Device Path | |
+ @param RemainingDevicePath Remaining Device Path | |
+ | |
+ @retval EFI_SUCCESS If a child handle was added | |
+ @retval other A child handle was not added | |
+ | |
+**/ | |
+EFI_STATUS | |
+BiosVideoChildHandleInstall ( | |
+ IN EFI_DRIVER_BINDING_PROTOCOL *This, | |
+ IN EFI_HANDLE ParentHandle, | |
+ IN EFI_PCI_IO_PROTOCOL *ParentPciIo, | |
+ IN EFI_LEGACY_BIOS_PROTOCOL *ParentLegacyBios, | |
+ IN EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath, | |
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath | |
+ ) | |
+{ | |
+ EFI_STATUS Status; | |
+ BIOS_VIDEO_DEV *BiosVideoPrivate; | |
+ PCI_TYPE00 Pci; | |
+ ACPI_ADR_DEVICE_PATH AcpiDeviceNode; | |
+ BOOLEAN ProtocolInstalled; | |
+ | |
+ // | |
+ // Allocate the private device structure for video device | |
+ // | |
+ BiosVideoPrivate = (BIOS_VIDEO_DEV *) AllocateZeroPool ( | |
+ sizeof (BIOS_VIDEO_DEV) | |
+ ); | |
+ if (NULL == BiosVideoPrivate) { | |
+ Status = EFI_OUT_OF_RESOURCES; | |
+ goto Done; | |
+ } | |
+ | |
+ // | |
+ // See if this is a VGA compatible controller or not | |
+ // | |
+ Status = ParentPciIo->Pci.Read ( | |
+ ParentPciIo, | |
+ EfiPciIoWidthUint32, | |
+ 0, | |
+ sizeof (Pci) / sizeof (UINT32), | |
+ &Pci | |
+ ); | |
+ if (EFI_ERROR (Status)) { | |
+ REPORT_STATUS_CODE_WITH_DEVICE_PATH ( | |
+ EFI_ERROR_CODE | EFI_ERROR_MINOR, | |
+ EFI_PERIPHERAL_LOCAL_CONSOLE | EFI_P_EC_CONTROLLER_ERROR, | |
+ ParentDevicePath | |
+ ); | |
+ goto Done; | |
+ } | |
+ BiosVideoPrivate->VgaCompatible = FALSE; | |
+ if (Pci.Hdr.ClassCode[2] == 0x00 && Pci.Hdr.ClassCode[1] == 0x01) { | |
+ BiosVideoPrivate->VgaCompatible = TRUE; | |
+ } | |
+ | |
+ if (Pci.Hdr.ClassCode[2] == 0x03 && Pci.Hdr.ClassCode[1] == 0x00 && Pci.Hdr.ClassCode[0] == 0x00) { | |
+ BiosVideoPrivate->VgaCompatible = TRUE; | |
+ } | |
+ | |
+ if (PcdGetBool (PcdBiosVideoSetTextVgaModeEnable)) { | |
+ // | |
+ // Create EXIT_BOOT_SERIVES Event | |
+ // | |
+ Status = gBS->CreateEventEx ( | |
+ EVT_NOTIFY_SIGNAL, | |
+ TPL_NOTIFY, | |
+ BiosVideoNotifyExitBootServices, | |
+ BiosVideoPrivate, | |
+ &gEfiEventExitBootServicesGuid, | |
+ &BiosVideoPrivate->ExitBootServicesEvent | |
+ ); | |
+ if (EFI_ERROR (Status)) { | |
+ goto Done; | |
+ } | |
+ } | |
+ | |
+ // | |
+ // Initialize the child private structure | |
+ // | |
+ BiosVideoPrivate->Signature = BIOS_VIDEO_DEV_SIGNATURE; | |
+ | |
+ // | |
+ // Fill in Graphics Output specific mode structures | |
+ // | |
+ BiosVideoPrivate->HardwareNeedsStarting = TRUE; | |
+ BiosVideoPrivate->ModeData = NULL; | |
+ BiosVideoPrivate->LineBuffer = NULL; | |
+ BiosVideoPrivate->VgaFrameBuffer = NULL; | |
+ BiosVideoPrivate->VbeFrameBuffer = NULL; | |
+ | |
+ // | |
+ // Fill in the Graphics Output Protocol | |
+ // | |
+ BiosVideoPrivate->GraphicsOutput.QueryMode = BiosVideoGraphicsOutputQueryMode; | |
+ BiosVideoPrivate->GraphicsOutput.SetMode = BiosVideoGraphicsOutputSetMode; | |
+ | |
+ | |
+ // | |
+ // Allocate buffer for Graphics Output Protocol mode information | |
+ // | |
+ BiosVideoPrivate->GraphicsOutput.Mode = (EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE *) AllocatePool ( | |
+ sizeof (EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE) | |
+ ); | |
+ if (NULL == BiosVideoPrivate->GraphicsOutput.Mode) { | |
+ Status = EFI_OUT_OF_RESOURCES; | |
+ goto Done; | |
+ } | |
+ | |
+ BiosVideoPrivate->GraphicsOutput.Mode->Info = (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *) AllocatePool ( | |
+ sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION) | |
+ ); | |
+ if (NULL == BiosVideoPrivate->GraphicsOutput.Mode->Info) { | |
+ Status = EFI_OUT_OF_RESOURCES; | |
+ goto Done; | |
+ } | |
+ | |
+ // | |
+ // Assume that Graphics Output Protocol will be produced until proven otherwise | |
+ // | |
+ BiosVideoPrivate->ProduceGraphicsOutput = TRUE; | |
+ | |
+ // | |
+ // Set Gop Device Path, here RemainingDevicePath will not be one End of Device Path Node. | |
+ // | |
+ if ((RemainingDevicePath == NULL) || (!IsDevicePathEnd (RemainingDevicePath))) { | |
+ if (RemainingDevicePath == NULL) { | |
+ ZeroMem (&AcpiDeviceNode, sizeof (ACPI_ADR_DEVICE_PATH)); | |
+ AcpiDeviceNode.Header.Type = ACPI_DEVICE_PATH; | |
+ AcpiDeviceNode.Header.SubType = ACPI_ADR_DP; | |
+ AcpiDeviceNode.ADR = ACPI_DISPLAY_ADR (1, 0, 0, 1, 0, ACPI_ADR_DISPLAY_TYPE_VGA, 0, 0); | |
+ SetDevicePathNodeLength (&AcpiDeviceNode.Header, sizeof (ACPI_ADR_DEVICE_PATH)); | |
+ | |
+ BiosVideoPrivate->GopDevicePath = AppendDevicePathNode ( | |
+ ParentDevicePath, | |
+ (EFI_DEVICE_PATH_PROTOCOL *) &AcpiDeviceNode | |
+ ); | |
+ } else { | |
+ BiosVideoPrivate->GopDevicePath = AppendDevicePathNode (ParentDevicePath, RemainingDevicePath); | |
+ } | |
+ | |
+ // | |
+ // Creat child handle and device path protocol firstly | |
+ // | |
+ BiosVideoPrivate->Handle = NULL; | |
+ Status = gBS->InstallMultipleProtocolInterfaces ( | |
+ &BiosVideoPrivate->Handle, | |
+ &gEfiDevicePathProtocolGuid, | |
+ BiosVideoPrivate->GopDevicePath, | |
+ NULL | |
+ ); | |
+ if (EFI_ERROR (Status)) { | |
+ goto Done; | |
+ } | |
+ } | |
+ | |
+ // | |
+ // Fill in the VGA Mini Port Protocol fields | |
+ // | |
+ BiosVideoPrivate->VgaMiniPort.SetMode = BiosVideoVgaMiniPortSetMode; | |
+ BiosVideoPrivate->VgaMiniPort.VgaMemoryOffset = 0xb8000; | |
+ BiosVideoPrivate->VgaMiniPort.CrtcAddressRegisterOffset = 0x3d4; | |
+ BiosVideoPrivate->VgaMiniPort.CrtcDataRegisterOffset = 0x3d5; | |
+ BiosVideoPrivate->VgaMiniPort.VgaMemoryBar = EFI_PCI_IO_PASS_THROUGH_BAR; | |
+ BiosVideoPrivate->VgaMiniPort.CrtcAddressRegisterBar = EFI_PCI_IO_PASS_THROUGH_BAR; | |
+ BiosVideoPrivate->VgaMiniPort.CrtcDataRegisterBar = EFI_PCI_IO_PASS_THROUGH_BAR; | |
+ | |
+ // | |
+ // Child handle need to consume the Legacy Bios protocol | |
+ // | |
+ BiosVideoPrivate->LegacyBios = ParentLegacyBios; | |
+ | |
+ // | |
+ // When check for VBE, PCI I/O protocol is needed, so use parent's protocol interface temporally | |
+ // | |
+ BiosVideoPrivate->PciIo = ParentPciIo; | |
+ | |
+ // | |
+ // Check for VESA BIOS Extensions for modes that are compatible with Graphics Output | |
+ // | |
+ if (FeaturePcdGet (PcdBiosVideoCheckVbeEnable)) { | |
+ Status = BiosVideoCheckForVbe (BiosVideoPrivate); | |
+ DEBUG ((EFI_D_INFO, "BiosVideoCheckForVbe - %r\n", Status)); | |
+ } else { | |
+ Status = EFI_UNSUPPORTED; | |
+ } | |
+ if (EFI_ERROR (Status)) { | |
+ // | |
+ // The VESA BIOS Extensions are not compatible with Graphics Output, so check for support | |
+ // for the standard 640x480 16 color VGA mode | |
+ // | |
+ DEBUG ((EFI_D_INFO, "VgaCompatible - %x\n", BiosVideoPrivate->VgaCompatible)); | |
+ if (BiosVideoPrivate->VgaCompatible) { | |
+ if (FeaturePcdGet (PcdBiosVideoCheckVgaEnable)) { | |
+ Status = BiosVideoCheckForVga (BiosVideoPrivate); | |
+ DEBUG ((EFI_D_INFO, "BiosVideoCheckForVga - %r\n", Status)); | |
+ } else { | |
+ Status = EFI_UNSUPPORTED; | |
+ } | |
+ } | |
+ | |
+ if (EFI_ERROR (Status)) { | |
+ // | |
+ // Free GOP mode structure if it is not freed before | |
+ // VgaMiniPort does not need this structure any more | |
+ // | |
+ if (BiosVideoPrivate->GraphicsOutput.Mode != NULL) { | |
+ if (BiosVideoPrivate->GraphicsOutput.Mode->Info != NULL) { | |
+ FreePool (BiosVideoPrivate->GraphicsOutput.Mode->Info); | |
+ BiosVideoPrivate->GraphicsOutput.Mode->Info = NULL; | |
+ } | |
+ FreePool (BiosVideoPrivate->GraphicsOutput.Mode); | |
+ BiosVideoPrivate->GraphicsOutput.Mode = NULL; | |
+ } | |
+ | |
+ // | |
+ // Neither VBE nor the standard 640x480 16 color VGA mode are supported, so do | |
+ // not produce the Graphics Output protocol. Instead, produce the VGA MiniPort Protocol. | |
+ // | |
+ BiosVideoPrivate->ProduceGraphicsOutput = FALSE; | |
+ | |
+ // | |
+ // INT services are available, so on the 80x25 and 80x50 text mode are supported | |
+ // | |
+ BiosVideoPrivate->VgaMiniPort.MaxMode = 2; | |
+ } | |
+ } | |
+ | |
+ ProtocolInstalled = FALSE; | |
+ | |
+ if (BiosVideoPrivate->ProduceGraphicsOutput) { | |
+ // | |
+ // Creat child handle and install Graphics Output Protocol,EDID Discovered/Active Protocol | |
+ // | |
+ Status = gBS->InstallMultipleProtocolInterfaces ( | |
+ &BiosVideoPrivate->Handle, | |
+ &gEfiGraphicsOutputProtocolGuid, | |
+ &BiosVideoPrivate->GraphicsOutput, | |
+ &gEfiEdidDiscoveredProtocolGuid, | |
+ &BiosVideoPrivate->EdidDiscovered, | |
+ &gEfiEdidActiveProtocolGuid, | |
+ &BiosVideoPrivate->EdidActive, | |
+ NULL | |
+ ); | |
+ | |
+ if (!EFI_ERROR (Status)) { | |
+ // | |
+ // Open the Parent Handle for the child | |
+ // | |
+ Status = gBS->OpenProtocol ( | |
+ ParentHandle, | |
+ &gEfiPciIoProtocolGuid, | |
+ (VOID **) &BiosVideoPrivate->PciIo, | |
+ This->DriverBindingHandle, | |
+ BiosVideoPrivate->Handle, | |
+ EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER | |
+ ); | |
+ if (EFI_ERROR (Status)) { | |
+ goto Done; | |
+ } | |
+ ProtocolInstalled = TRUE; | |
+ } | |
+ } | |
+ | |
+ if (!ProtocolInstalled) { | |
+ // | |
+ // Install VGA Mini Port Protocol | |
+ // | |
+ Status = gBS->InstallMultipleProtocolInterfaces ( | |
+ &ParentHandle, | |
+ &gEfiVgaMiniPortProtocolGuid, | |
+ &BiosVideoPrivate->VgaMiniPort, | |
+ NULL | |
+ ); | |
+ } | |
+ | |
+Done: | |
+ if (EFI_ERROR (Status)) { | |
+ if ((BiosVideoPrivate != NULL) && (BiosVideoPrivate->ExitBootServicesEvent != NULL)) { | |
+ gBS->CloseEvent (BiosVideoPrivate->ExitBootServicesEvent); | |
+ } | |
+ // | |
+ // Free private data structure | |
+ // | |
+ BiosVideoDeviceReleaseResource (BiosVideoPrivate); | |
+ } | |
+ | |
+ return Status; | |
+} | |
+ | |
+ | |
+/** | |
+ Deregister an video child handle and free resources. | |
+ | |
+ @param This Protocol instance pointer. | |
+ @param Controller Video controller handle | |
+ @param Handle Video child handle | |
+ | |
+ @return EFI_STATUS | |
+ | |
+**/ | |
+EFI_STATUS | |
+BiosVideoChildHandleUninstall ( | |
+ EFI_DRIVER_BINDING_PROTOCOL *This, | |
+ EFI_HANDLE Controller, | |
+ EFI_HANDLE Handle | |
+ ) | |
+{ | |
+ EFI_STATUS Status; | |
+ EFI_IA32_REGISTER_SET Regs; | |
+ EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput; | |
+ EFI_VGA_MINI_PORT_PROTOCOL *VgaMiniPort; | |
+ BIOS_VIDEO_DEV *BiosVideoPrivate; | |
+ EFI_PCI_IO_PROTOCOL *PciIo; | |
+ | |
+ BiosVideoPrivate = NULL; | |
+ GraphicsOutput = NULL; | |
+ PciIo = NULL; | |
+// Status = EFI_UNSUPPORTED; | |
+ | |
+ Status = gBS->OpenProtocol ( | |
+ Handle, | |
+ &gEfiGraphicsOutputProtocolGuid, | |
+ (VOID **) &GraphicsOutput, | |
+ This->DriverBindingHandle, | |
+ Handle, | |
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL | |
+ ); | |
+ if (!EFI_ERROR (Status)) { | |
+ BiosVideoPrivate = BIOS_VIDEO_DEV_FROM_GRAPHICS_OUTPUT_THIS (GraphicsOutput); | |
+ } | |
+ | |
+ if (EFI_ERROR (Status)) { | |
+ Status = gBS->OpenProtocol ( | |
+ Handle, | |
+ &gEfiVgaMiniPortProtocolGuid, | |
+ (VOID **) &VgaMiniPort, | |
+ This->DriverBindingHandle, | |
+ Handle, | |
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL | |
+ ); | |
+ if (!EFI_ERROR (Status)) { | |
+ BiosVideoPrivate = BIOS_VIDEO_DEV_FROM_VGA_MINI_PORT_THIS (VgaMiniPort); | |
+ } | |
+ } | |
+ | |
+ if (BiosVideoPrivate == NULL) { | |
+ return EFI_UNSUPPORTED; | |
+ } | |
+ | |
+ // | |
+ // Set the 80x25 Text VGA Mode | |
+ // | |
+ Regs.H.AH = 0x00; | |
+ Regs.H.AL = 0x03; | |
+ BiosVideoPrivate->LegacyBios->Int86 (BiosVideoPrivate->LegacyBios, 0x10, &Regs); | |
+ | |
+ Regs.H.AH = 0x11; | |
+ Regs.H.AL = 0x14; | |
+ Regs.H.BL = 0; | |
+ BiosVideoPrivate->LegacyBios->Int86 (BiosVideoPrivate->LegacyBios, 0x10, &Regs); | |
+ | |
+ // | |
+ // Close PCI I/O protocol that opened by child handle | |
+ // | |
+ Status = gBS->CloseProtocol ( | |
+ Controller, | |
+ &gEfiPciIoProtocolGuid, | |
+ This->DriverBindingHandle, | |
+ Handle | |
+ ); | |
+ | |
+ // | |
+ // Uninstall protocols on child handle | |
+ // | |
+ if (BiosVideoPrivate->ProduceGraphicsOutput) { | |
+ Status = gBS->UninstallMultipleProtocolInterfaces ( | |
+ BiosVideoPrivate->Handle, | |
+ &gEfiDevicePathProtocolGuid, | |
+ BiosVideoPrivate->GopDevicePath, | |
+ &gEfiGraphicsOutputProtocolGuid, | |
+ &BiosVideoPrivate->GraphicsOutput, | |
+ &gEfiEdidDiscoveredProtocolGuid, | |
+ &BiosVideoPrivate->EdidDiscovered, | |
+ &gEfiEdidActiveProtocolGuid, | |
+ &BiosVideoPrivate->EdidActive, | |
+ NULL | |
+ ); | |
+ } | |
+ if (!BiosVideoPrivate->ProduceGraphicsOutput) { | |
+ Status = gBS->UninstallMultipleProtocolInterfaces ( | |
+ Controller, | |
+ &gEfiVgaMiniPortProtocolGuid, | |
+ &BiosVideoPrivate->VgaMiniPort, | |
+ NULL | |
+ ); | |
+ } | |
+ | |
+ if (EFI_ERROR (Status)) { | |
+ gBS->OpenProtocol ( | |
+ Controller, | |
+ &gEfiPciIoProtocolGuid, | |
+ (VOID **) &PciIo, | |
+ This->DriverBindingHandle, | |
+ Handle, | |
+ EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER | |
+ ); | |
+ return Status; | |
+ } | |
+ | |
+ if (PcdGetBool (PcdBiosVideoSetTextVgaModeEnable)) { | |
+ // | |
+ // Close EXIT_BOOT_SERIVES Event | |
+ // | |
+ gBS->CloseEvent (BiosVideoPrivate->ExitBootServicesEvent); | |
+ } | |
+ | |
+ // | |
+ // Release all allocated resources | |
+ // | |
+ BiosVideoDeviceReleaseResource (BiosVideoPrivate); | |
+ | |
+ return EFI_SUCCESS; | |
+} | |
+ | |
+ | |
+/** | |
+ Release resource for biso video instance. | |
+ | |
+ @param BiosVideoPrivate Video child device private data structure | |
+ | |
+**/ | |
+VOID | |
+BiosVideoDeviceReleaseResource ( | |
+ BIOS_VIDEO_DEV *BiosVideoPrivate | |
+ ) | |
+{ | |
+ if (BiosVideoPrivate == NULL) { | |
+ return ; | |
+ } | |
+ | |
+ // | |
+ // Release all the resourses occupied by the BIOS_VIDEO_DEV | |
+ // | |
+ | |
+ // | |
+ // Free VGA Frame Buffer | |
+ // | |
+ if (BiosVideoPrivate->VgaFrameBuffer != NULL) { | |
+ FreePool (BiosVideoPrivate->VgaFrameBuffer); | |
+ } | |
+ // | |
+ // Free VBE Frame Buffer | |
+ // | |
+ if (BiosVideoPrivate->VbeFrameBuffer != NULL) { | |
+ FreePool (BiosVideoPrivate->VbeFrameBuffer); | |
+ } | |
+ // | |
+ // Free line buffer | |
+ // | |
+ if (BiosVideoPrivate->LineBuffer != NULL) { | |
+ FreePool (BiosVideoPrivate->LineBuffer); | |
+ } | |
+ // | |
+ // Free mode data | |
+ // | |
+ if (BiosVideoPrivate->ModeData != NULL) { | |
+ FreePool (BiosVideoPrivate->ModeData); | |
+ } | |
+ // | |
+ // Free memory allocated below 1MB | |
+ // | |
+ if (BiosVideoPrivate->PagesBelow1MB != 0) { | |
+ gBS->FreePages (BiosVideoPrivate->PagesBelow1MB, BiosVideoPrivate->NumberOfPagesBelow1MB); | |
+ } | |
+ | |
+ if (BiosVideoPrivate->VbeSaveRestorePages != 0) { | |
+ gBS->FreePages (BiosVideoPrivate->VbeSaveRestoreBuffer, BiosVideoPrivate->VbeSaveRestorePages); | |
+ } | |
+ | |
+ // | |
+ // Free graphics output protocol occupied resource | |
+ // | |
+ if (BiosVideoPrivate->GraphicsOutput.Mode != NULL) { | |
+ if (BiosVideoPrivate->GraphicsOutput.Mode->Info != NULL) { | |
+ FreePool (BiosVideoPrivate->GraphicsOutput.Mode->Info); | |
+ BiosVideoPrivate->GraphicsOutput.Mode->Info = NULL; | |
+ } | |
+ FreePool (BiosVideoPrivate->GraphicsOutput.Mode); | |
+ BiosVideoPrivate->GraphicsOutput.Mode = NULL; | |
+ } | |
+ // | |
+ // Free EDID discovered protocol occupied resource | |
+ // | |
+ if (BiosVideoPrivate->EdidDiscovered.Edid != NULL) { | |
+ FreePool (BiosVideoPrivate->EdidDiscovered.Edid); | |
+ } | |
+ // | |
+ // Free EDID active protocol occupied resource | |
+ // | |
+ if (BiosVideoPrivate->EdidActive.Edid != NULL) { | |
+ FreePool (BiosVideoPrivate->EdidActive.Edid); | |
+ } | |
+ | |
+ if (BiosVideoPrivate->GopDevicePath!= NULL) { | |
+ FreePool (BiosVideoPrivate->GopDevicePath); | |
+ } | |
+ | |
+ FreePool (BiosVideoPrivate); | |
+ | |
+ return ; | |
+} | |
+ | |
+ | |
+/** | |
+ Generate a search key for a specified timing data. | |
+ | |
+ @param EdidTiming Pointer to EDID timing | |
+ | |
+ @return The 32 bit unique key for search. | |
+ | |
+**/ | |
+UINT32 | |
+CalculateEdidKey ( | |
+ VESA_BIOS_EXTENSIONS_EDID_TIMING *EdidTiming | |
+ ) | |
+{ | |
+ UINT32 Key; | |
+ | |
+ // | |
+ // Be sure no conflicts for all standard timing defined by VESA. | |
+ // | |
+ Key = (EdidTiming->HorizontalResolution * 2) + EdidTiming->VerticalResolution; | |
+ return Key; | |
+} | |
+ | |
+ | |
+/** | |
+ Parse the Established Timing and Standard Timing in EDID data block. | |
+ | |
+ @param EdidBuffer Pointer to EDID data block | |
+ @param ValidEdidTiming Valid EDID timing information | |
+ | |
+ @retval TRUE The EDID data is valid. | |
+ @retval FALSE The EDID data is invalid. | |
+ | |
+**/ | |
+BOOLEAN | |
+ParseEdidData ( | |
+ UINT8 *EdidBuffer, | |
+ VESA_BIOS_EXTENSIONS_VALID_EDID_TIMING *ValidEdidTiming | |
+ ) | |
+{ | |
+ UINT8 CheckSum; | |
+ UINT32 Index; | |
+ UINT32 ValidNumber; | |
+ UINT32 TimingBits; | |
+ UINT8 *BufferIndex; | |
+ UINT16 HorizontalResolution; | |
+ UINT16 VerticalResolution; | |
+ UINT8 AspectRatio; | |
+ UINT8 RefreshRate; | |
+ VESA_BIOS_EXTENSIONS_EDID_TIMING TempTiming; | |
+ VESA_BIOS_EXTENSIONS_EDID_DATA_BLOCK *EdidDataBlock; | |
+ | |
+ EdidDataBlock = (VESA_BIOS_EXTENSIONS_EDID_DATA_BLOCK *) EdidBuffer; | |
+ | |
+ // | |
+ // Check the checksum of EDID data | |
+ // | |
+ CheckSum = 0; | |
+ for (Index = 0; Index < VESA_BIOS_EXTENSIONS_EDID_BLOCK_SIZE; Index ++) { | |
+ CheckSum = (UINT8) (CheckSum + EdidBuffer[Index]); | |
+ } | |
+ if (CheckSum != 0) { | |
+ return FALSE; | |
+ } | |
+ | |
+ ValidNumber = 0; | |
+ gBS->SetMem (ValidEdidTiming, sizeof (VESA_BIOS_EXTENSIONS_VALID_EDID_TIMING), 0); | |
+ | |
+ if ((EdidDataBlock->EstablishedTimings[0] != 0) || | |
+ (EdidDataBlock->EstablishedTimings[1] != 0) || | |
+ (EdidDataBlock->EstablishedTimings[2] != 0) | |
+ ) { | |
+ // | |
+ // Established timing data | |
+ // | |
+ TimingBits = EdidDataBlock->EstablishedTimings[0] | | |
+ (EdidDataBlock->EstablishedTimings[1] << 8) | | |
+ ((EdidDataBlock->EstablishedTimings[2] & 0x80) << 9) ; | |
+ for (Index = 0; Index < VESA_BIOS_EXTENSIONS_EDID_ESTABLISHED_TIMING_MAX_NUMBER; Index ++) { | |
+ if ((TimingBits & 0x1) != 0) { | |
+ DEBUG ((EFI_D_INFO, "Established Timing: %d x %d\n", | |
+ mEstablishedEdidTiming[Index].HorizontalResolution, mEstablishedEdidTiming[Index].VerticalResolution)); | |
+ ValidEdidTiming->Key[ValidNumber] = CalculateEdidKey (&mEstablishedEdidTiming[Index]); | |
+ ValidNumber ++; | |
+ } | |
+ TimingBits = TimingBits >> 1; | |
+ } | |
+ } | |
+ | |
+ // | |
+ // Parse the standard timing data | |
+ // | |
+ BufferIndex = &EdidDataBlock->StandardTimingIdentification[0]; | |
+ for (Index = 0; Index < 8; Index ++) { | |
+ // | |
+ // Check if this is a valid Standard Timing entry | |
+ // VESA documents unused fields should be set to 01h | |
+ // | |
+ if ((BufferIndex[0] != 0x1) && (BufferIndex[1] != 0x1)){ | |
+ // | |
+ // A valid Standard Timing | |
+ // | |
+ HorizontalResolution = (UINT16) (BufferIndex[0] * 8 + 248); | |
+ AspectRatio = (UINT8) (BufferIndex[1] >> 6); | |
+ switch (AspectRatio) { | |
+ case 0: | |
+ VerticalResolution = (UINT16) (HorizontalResolution / 16 * 10); | |
+ break; | |
+ case 1: | |
+ VerticalResolution = (UINT16) (HorizontalResolution / 4 * 3); | |
+ break; | |
+ case 2: | |
+ VerticalResolution = (UINT16) (HorizontalResolution / 5 * 4); | |
+ break; | |
+ case 3: | |
+ VerticalResolution = (UINT16) (HorizontalResolution / 16 * 9); | |
+ break; | |
+ default: | |
+ VerticalResolution = (UINT16) (HorizontalResolution / 4 * 3); | |
+ break; | |
+ } | |
+ RefreshRate = (UINT8) ((BufferIndex[1] & 0x1f) + 60); | |
+ DEBUG ((EFI_D_INFO, "Standard Timing: %d x %d\n", HorizontalResolution, VerticalResolution)); | |
+ TempTiming.HorizontalResolution = HorizontalResolution; | |
+ TempTiming.VerticalResolution = VerticalResolution; | |
+ TempTiming.RefreshRate = RefreshRate; | |
+ ValidEdidTiming->Key[ValidNumber] = CalculateEdidKey (&TempTiming); | |
+ ValidNumber ++; | |
+ } | |
+ BufferIndex += 2; | |
+ } | |
+ | |
+ // | |
+ // Parse the Detailed Timing data | |
+ // | |
+ BufferIndex = &EdidDataBlock->DetailedTimingDescriptions[0]; | |
+ for (Index = 0; Index < 4; Index ++, BufferIndex += VESA_BIOS_EXTENSIONS_DETAILED_TIMING_EACH_DESCRIPTOR_SIZE) { | |
+ if ((BufferIndex[0] == 0x0) && (BufferIndex[1] == 0x0)) { | |
+ // | |
+ // Check if this is a valid Detailed Timing Descriptor | |
+ // If first 2 bytes are zero, it is monitor descriptor other than detailed timing descriptor | |
+ // | |
+ continue; | |
+ } | |
+ // | |
+ // Calculate Horizontal and Vertical resolution | |
+ // | |
+ TempTiming.HorizontalResolution = ((UINT16)(BufferIndex[4] & 0xF0) << 4) | (BufferIndex[2]); | |
+ TempTiming.VerticalResolution = ((UINT16)(BufferIndex[7] & 0xF0) << 4) | (BufferIndex[5]); | |
+ DEBUG ((EFI_D_INFO, "Detailed Timing %d: %d x %d\n", | |
+ Index, TempTiming.HorizontalResolution, TempTiming.VerticalResolution)); | |
+ ValidEdidTiming->Key[ValidNumber] = CalculateEdidKey (&TempTiming); | |
+ ValidNumber ++; | |
+ } | |
+ | |
+ ValidEdidTiming->ValidNumber = ValidNumber; | |
+ return TRUE; | |
+} | |
+ | |
+ | |
+/** | |
+ Search a specified Timing in all the valid EDID timings. | |
+ | |
+ @param ValidEdidTiming All valid EDID timing information. | |
+ @param EdidTiming The Timing to search for. | |
+ | |
+ @retval TRUE Found. | |
+ @retval FALSE Not found. | |
+ | |
+**/ | |
+BOOLEAN | |
+SearchEdidTiming ( | |
+ VESA_BIOS_EXTENSIONS_VALID_EDID_TIMING *ValidEdidTiming, | |
+ VESA_BIOS_EXTENSIONS_EDID_TIMING *EdidTiming | |
+ ) | |
+{ | |
+ UINT32 Index; | |
+ UINT32 Key; | |
+ | |
+ Key = CalculateEdidKey (EdidTiming); | |
+ | |
+ for (Index = 0; Index < ValidEdidTiming->ValidNumber; Index ++) { | |
+ if (Key == ValidEdidTiming->Key[Index]) { | |
+ return TRUE; | |
+ } | |
+ } | |
+ | |
+ return FALSE; | |
+} | |
+ | |
+/** | |
+ Check if all video child handles have been uninstalled. | |
+ | |
+ @param Controller Video controller handle | |
+ | |
+ @return TRUE Child handles exist. | |
+ @return FALSE All video child handles have been uninstalled. | |
+ | |
+**/ | |
+BOOLEAN | |
+HasChildHandle ( | |
+ IN EFI_HANDLE Controller | |
+ ) | |
+{ | |
+ UINTN Index; | |
+ EFI_OPEN_PROTOCOL_INFORMATION_ENTRY *OpenInfoBuffer; | |
+ UINTN EntryCount; | |
+ BOOLEAN HasChild; | |
+ EFI_STATUS Status; | |
+ | |
+ EntryCount = 0; | |
+ HasChild = FALSE; | |
+ Status = gBS->OpenProtocolInformation ( | |
+ Controller, | |
+ &gEfiPciIoProtocolGuid, | |
+ &OpenInfoBuffer, | |
+ &EntryCount | |
+ ); | |
+ if (!EFI_ERROR(Status) && (OpenInfoBuffer != NULL)) { | |
+ for (Index = 0; Index < EntryCount; Index++) { | |
+ if ((OpenInfoBuffer[Index].Attributes & EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) != 0) { | |
+ HasChild = TRUE; | |
+ } | |
+ } | |
+ } | |
+ return HasChild; | |
+} | |
+ | |
+/** | |
+ Check for VBE device. | |
+ | |
+ @param BiosVideoPrivate Pointer to BIOS_VIDEO_DEV structure | |
+ | |
+ @retval EFI_SUCCESS VBE device found | |
+ | |
+**/ | |
+EFI_STATUS | |
+BiosVideoCheckForVbe ( | |
+ IN OUT BIOS_VIDEO_DEV *BiosVideoPrivate | |
+ ) | |
+{ | |
+ EFI_STATUS Status; | |
+ EFI_IA32_REGISTER_SET Regs; | |
+ UINT16 *ModeNumberPtr; | |
+ UINT16 VbeModeNumber; | |
+ BOOLEAN ModeFound; | |
+ BOOLEAN EdidFound; | |
+ BIOS_VIDEO_MODE_DATA *ModeBuffer; | |
+ BIOS_VIDEO_MODE_DATA *CurrentModeData; | |
+ UINTN PreferMode; | |
+ UINTN ModeNumber; | |
+ VESA_BIOS_EXTENSIONS_EDID_TIMING Timing; | |
+ VESA_BIOS_EXTENSIONS_VALID_EDID_TIMING ValidEdidTiming; | |
+ EFI_EDID_OVERRIDE_PROTOCOL *EdidOverride; | |
+ UINT32 EdidAttributes; | |
+ BOOLEAN EdidOverrideFound; | |
+ UINTN EdidOverrideDataSize; | |
+ UINT8 *EdidOverrideDataBlock; | |
+ UINTN EdidActiveDataSize; | |
+ UINT8 *EdidActiveDataBlock; | |
+ UINT32 HighestHorizontalResolution; | |
+ UINT32 HighestVerticalResolution; | |
+ UINTN HighestResolutionMode; | |
+ UINT32 ScanBpp; | |
+ | |
+ EdidFound = TRUE; | |
+ EdidOverrideFound = FALSE; | |
+ EdidOverrideDataBlock = NULL; | |
+ EdidActiveDataSize = 0; | |
+ EdidActiveDataBlock = NULL; | |
+ HighestHorizontalResolution = 0; | |
+ HighestVerticalResolution = 0; | |
+ HighestResolutionMode = 0; | |
+ | |
+ // | |
+ // Allocate buffer under 1MB for VBE data structures | |
+ // | |
+ BiosVideoPrivate->NumberOfPagesBelow1MB = EFI_SIZE_TO_PAGES ( | |
+ sizeof (VESA_BIOS_EXTENSIONS_INFORMATION_BLOCK) + | |
+ sizeof (VESA_BIOS_EXTENSIONS_MODE_INFORMATION_BLOCK) + | |
+ sizeof (VESA_BIOS_EXTENSIONS_EDID_DATA_BLOCK) + | |
+ sizeof (VESA_BIOS_EXTENSIONS_CRTC_INFORMATION_BLOCK) | |
+ ); | |
+ | |
+ BiosVideoPrivate->PagesBelow1MB = 0x00100000 - 1; | |
+ | |
+ Status = gBS->AllocatePages ( | |
+ AllocateMaxAddress, | |
+ EfiBootServicesData, | |
+ BiosVideoPrivate->NumberOfPagesBelow1MB, | |
+ &BiosVideoPrivate->PagesBelow1MB | |
+ ); | |
+ if (EFI_ERROR (Status)) { | |
+ return Status; | |
+ } | |
+ | |
+ ZeroMem (&ValidEdidTiming, sizeof (VESA_BIOS_EXTENSIONS_VALID_EDID_TIMING)); | |
+ | |
+ // | |
+ // Fill in the VBE related data structures | |
+ // | |
+ BiosVideoPrivate->VbeInformationBlock = (VESA_BIOS_EXTENSIONS_INFORMATION_BLOCK *) (UINTN) (BiosVideoPrivate->PagesBelow1MB); | |
+ BiosVideoPrivate->VbeModeInformationBlock = (VESA_BIOS_EXTENSIONS_MODE_INFORMATION_BLOCK *) (BiosVideoPrivate->VbeInformationBlock + 1); | |
+ BiosVideoPrivate->VbeEdidDataBlock = (VESA_BIOS_EXTENSIONS_EDID_DATA_BLOCK *) (BiosVideoPrivate->VbeModeInformationBlock + 1); | |
+ BiosVideoPrivate->VbeCrtcInformationBlock = (VESA_BIOS_EXTENSIONS_CRTC_INFORMATION_BLOCK *) (BiosVideoPrivate->VbeEdidDataBlock + 1); | |
+ BiosVideoPrivate->VbeSaveRestorePages = 0; | |
+ BiosVideoPrivate->VbeSaveRestoreBuffer = 0; | |
+ | |
+ // | |
+ // Test to see if the Video Adapter is compliant with VBE 3.0 | |
+ // | |
+ gBS->SetMem (&Regs, sizeof (Regs), 0); | |
+ Regs.X.AX = VESA_BIOS_EXTENSIONS_RETURN_CONTROLLER_INFORMATION; | |
+ gBS->SetMem (BiosVideoPrivate->VbeInformationBlock, sizeof (VESA_BIOS_EXTENSIONS_INFORMATION_BLOCK), 0); | |
+ BiosVideoPrivate->VbeInformationBlock->VESASignature = VESA_BIOS_EXTENSIONS_VBE2_SIGNATURE; | |
+ Regs.X.ES = EFI_SEGMENT ((UINTN) BiosVideoPrivate->VbeInformationBlock); | |
+ Regs.X.DI = EFI_OFFSET ((UINTN) BiosVideoPrivate->VbeInformationBlock); | |
+ | |
+ BiosVideoPrivate->LegacyBios->Int86 (BiosVideoPrivate->LegacyBios, 0x10, &Regs); | |
+ | |
+ Status = EFI_DEVICE_ERROR; | |
+ | |
+ // | |
+ // See if the VESA call succeeded | |
+ // | |
+ if (Regs.X.AX != VESA_BIOS_EXTENSIONS_STATUS_SUCCESS) { | |
+ return Status; | |
+ } | |
+ // | |
+ // Check for 'VESA' signature | |
+ // | |
+ if (BiosVideoPrivate->VbeInformationBlock->VESASignature != VESA_BIOS_EXTENSIONS_VESA_SIGNATURE) { | |
+ return Status; | |
+ } | |
+ // | |
+ // Check to see if this is VBE 2.0 or higher | |
+ // | |
+ if (BiosVideoPrivate->VbeInformationBlock->VESAVersion < VESA_BIOS_EXTENSIONS_VERSION_2_0) { | |
+ return Status; | |
+ } | |
+ | |
+ EdidFound = FALSE; | |
+ EdidAttributes = 0xff; | |
+ EdidOverrideDataSize = 0; | |
+ | |
+ // | |
+ // Find EDID Override protocol firstly, this protocol is installed by platform if needed. | |
+ // | |
+ Status = gBS->LocateProtocol ( | |
+ &gEfiEdidOverrideProtocolGuid, | |
+ NULL, | |
+ (VOID **) &EdidOverride | |
+ ); | |
+ if (!EFI_ERROR (Status)) { | |
+ // | |
+ // Allocate double size of VESA_BIOS_EXTENSIONS_EDID_BLOCK_SIZE to avoid overflow | |
+ // | |
+ EdidOverrideDataBlock = AllocatePool (VESA_BIOS_EXTENSIONS_EDID_BLOCK_SIZE * 2); | |
+ if (NULL == EdidOverrideDataBlock) { | |
+ Status = EFI_OUT_OF_RESOURCES; | |
+ goto Done; | |
+ } | |
+ | |
+ Status = EdidOverride->GetEdid ( | |
+ EdidOverride, | |
+ BiosVideoPrivate->Handle, | |
+ &EdidAttributes, | |
+ &EdidOverrideDataSize, | |
+ (UINT8 **) &EdidOverrideDataBlock | |
+ ); | |
+ if (!EFI_ERROR (Status) && | |
+ EdidAttributes == 0 && | |
+ EdidOverrideDataSize != 0) { | |
+ // | |
+ // Succeeded to get EDID Override Data | |
+ // | |
+ EdidOverrideFound = TRUE; | |
+ } | |
+ } | |
+ | |
+ if (!EdidOverrideFound || EdidAttributes == EFI_EDID_OVERRIDE_DONT_OVERRIDE) { | |
+ // | |
+ // If EDID Override data doesn't exist or EFI_EDID_OVERRIDE_DONT_OVERRIDE returned, | |
+ // read EDID information through INT10 call | |
+ // | |
+ | |
+ gBS->SetMem (&Regs, sizeof (Regs), 0); | |
+ Regs.X.AX = VESA_BIOS_EXTENSIONS_EDID; | |
+ Regs.X.BX = 1; | |
+ Regs.X.CX = 0; | |
+ Regs.X.DX = 0; | |
+ Regs.X.ES = EFI_SEGMENT ((UINTN) BiosVideoPrivate->VbeEdidDataBlock); | |
+ Regs.X.DI = EFI_OFFSET ((UINTN) BiosVideoPrivate->VbeEdidDataBlock); | |
+ | |
+ BiosVideoPrivate->LegacyBios->Int86 (BiosVideoPrivate->LegacyBios, 0x10, &Regs); | |
+ // | |
+ // See if the VESA call succeeded | |
+ // | |
+ if (Regs.X.AX == VESA_BIOS_EXTENSIONS_STATUS_SUCCESS) { | |
+ // | |
+ // Set EDID Discovered Data | |
+ // | |
+ BiosVideoPrivate->EdidDiscovered.SizeOfEdid = VESA_BIOS_EXTENSIONS_EDID_BLOCK_SIZE; | |
+ BiosVideoPrivate->EdidDiscovered.Edid = (UINT8 *) AllocateCopyPool ( | |
+ VESA_BIOS_EXTENSIONS_EDID_BLOCK_SIZE, | |
+ BiosVideoPrivate->VbeEdidDataBlock | |
+ ); | |
+ | |
+ if (NULL == BiosVideoPrivate->EdidDiscovered.Edid) { | |
+ Status = EFI_OUT_OF_RESOURCES; | |
+ goto Done; | |
+ } | |
+ | |
+ EdidFound = TRUE; | |
+ } | |
+ } | |
+ | |
+ if (EdidFound) { | |
+ EdidActiveDataSize = VESA_BIOS_EXTENSIONS_EDID_BLOCK_SIZE; | |
+ EdidActiveDataBlock = BiosVideoPrivate->EdidDiscovered.Edid; | |
+ } else if (EdidOverrideFound) { | |
+ EdidActiveDataSize = EdidOverrideDataSize; | |
+ EdidActiveDataBlock = EdidOverrideDataBlock; | |
+ EdidFound = TRUE; | |
+ } | |
+ | |
+ if (EdidFound) { | |
+ // | |
+ // Parse EDID data structure to retrieve modes supported by monitor | |
+ // | |
+ if (ParseEdidData ((UINT8 *) EdidActiveDataBlock, &ValidEdidTiming)) { | |
+ // | |
+ // Copy EDID Override Data to EDID Active Data | |
+ // | |
+ BiosVideoPrivate->EdidActive.SizeOfEdid = (UINT32) EdidActiveDataSize; | |
+ BiosVideoPrivate->EdidActive.Edid = (UINT8 *) AllocateCopyPool ( | |
+ EdidActiveDataSize, | |
+ EdidActiveDataBlock | |
+ ); | |
+ if (NULL == BiosVideoPrivate->EdidActive.Edid) { | |
+ Status = EFI_OUT_OF_RESOURCES; | |
+ goto Done; | |
+ } | |
+ } | |
+ } else { | |
+ BiosVideoPrivate->EdidActive.SizeOfEdid = 0; | |
+ BiosVideoPrivate->EdidActive.Edid = NULL; | |
+ EdidFound = FALSE; | |
+ } | |
+ | |
+ PreferMode = 0; | |
+ ModeNumber = 0; | |
+ | |
+ // | |
+ // Scan for 32bpp modes first. Only if none found, accept 24bpp as well. | |
+ // | |
+ for (ScanBpp = 32; ModeNumber == 0 && ScanBpp >= 24; ScanBpp -= 8) { | |
+ // | |
+ // Walk through the mode list to see if there is at least one mode the is compatible with the EDID mode | |
+ // | |
+ ModeNumberPtr = (UINT16 *) | |
+ ( | |
+ (((UINTN) BiosVideoPrivate->VbeInformationBlock->VideoModePtr & 0xffff0000) >> 12) | | |
+ ((UINTN) BiosVideoPrivate->VbeInformationBlock->VideoModePtr & 0x0000ffff) | |
+ ); | |
+ | |
+ // | |
+ // ModeNumberPtr may be not 16-byte aligned, so ReadUnaligned16 is used to access the buffer pointed by ModeNumberPtr. | |
+ // | |
+ for (VbeModeNumber = ReadUnaligned16 (ModeNumberPtr); | |
+ VbeModeNumber != VESA_BIOS_EXTENSIONS_END_OF_MODE_LIST; | |
+ VbeModeNumber = ReadUnaligned16 (++ModeNumberPtr)) { | |
+ // | |
+ // Make sure this is a mode number defined by the VESA VBE specification. If it isn'tm then skip this mode number. | |
+ // | |
+ if ((VbeModeNumber & VESA_BIOS_EXTENSIONS_MODE_NUMBER_VESA) == 0) { | |
+ continue; | |
+ } | |
+ // | |
+ // Get the information about the mode | |
+ // | |
+ gBS->SetMem (&Regs, sizeof (Regs), 0); | |
+ Regs.X.AX = VESA_BIOS_EXTENSIONS_RETURN_MODE_INFORMATION; | |
+ Regs.X.CX = VbeModeNumber; | |
+ gBS->SetMem (BiosVideoPrivate->VbeModeInformationBlock, sizeof (VESA_BIOS_EXTENSIONS_MODE_INFORMATION_BLOCK), 0); | |
+ Regs.X.ES = EFI_SEGMENT ((UINTN) BiosVideoPrivate->VbeModeInformationBlock); | |
+ Regs.X.DI = EFI_OFFSET ((UINTN) BiosVideoPrivate->VbeModeInformationBlock); | |
+ | |
+ BiosVideoPrivate->LegacyBios->Int86 (BiosVideoPrivate->LegacyBios, 0x10, &Regs); | |
+ | |
+ // | |
+ // See if the call succeeded. If it didn't, then try the next mode. | |
+ // | |
+ if (Regs.X.AX != VESA_BIOS_EXTENSIONS_STATUS_SUCCESS) { | |
+ continue; | |
+ } | |
+ // | |
+ // See if the mode supports color. If it doesn't then try the next mode. | |
+ // | |
+ if ((BiosVideoPrivate->VbeModeInformationBlock->ModeAttributes & VESA_BIOS_EXTENSIONS_MODE_ATTRIBUTE_COLOR) == 0) { | |
+ continue; | |
+ } | |
+ // | |
+ // See if the mode supports graphics. If it doesn't then try the next mode. | |
+ // | |
+ if ((BiosVideoPrivate->VbeModeInformationBlock->ModeAttributes & VESA_BIOS_EXTENSIONS_MODE_ATTRIBUTE_GRAPHICS) == 0) { | |
+ continue; | |
+ } | |
+ // | |
+ // See if the mode supports a linear frame buffer. If it doesn't then try the next mode. | |
+ // | |
+ if ((BiosVideoPrivate->VbeModeInformationBlock->ModeAttributes & VESA_BIOS_EXTENSIONS_MODE_ATTRIBUTE_LINEAR_FRAME_BUFFER) == 0) { | |
+ continue; | |
+ } | |
+ // | |
+ // See if the mode supports 32 bit color. If it doesn't then try the next mode. | |
+ // 32 bit mode can be implemented by 24 Bits Per Pixels. Also make sure the | |
+ // number of bits per pixel is a multiple of 8 or more than 32 bits per pixel | |
+ // | |
+ if (BiosVideoPrivate->VbeModeInformationBlock->BitsPerPixel < ScanBpp) { | |
+ continue; | |
+ } | |
+ | |
+ if (BiosVideoPrivate->VbeModeInformationBlock->BitsPerPixel > 32) { | |
+ continue; | |
+ } | |
+ | |
+ if ((BiosVideoPrivate->VbeModeInformationBlock->BitsPerPixel % 8) != 0) { | |
+ continue; | |
+ } | |
+ // | |
+ // See if the physical base pointer for the linear mode is valid. If it isn't then try the next mode. | |
+ // | |
+ if (BiosVideoPrivate->VbeModeInformationBlock->PhysBasePtr == 0) { | |
+ continue; | |
+ } | |
+ | |
+ DEBUG ((EFI_D_INFO, "Video Controller Mode 0x%x: %d x %d\n", | |
+ VbeModeNumber, BiosVideoPrivate->VbeModeInformationBlock->XResolution, BiosVideoPrivate->VbeModeInformationBlock->YResolution)); | |
+ | |
+ if (EdidFound && (ValidEdidTiming.ValidNumber > 0)) { | |
+ // | |
+ // EDID exist, check whether this mode match with any mode in EDID | |
+ // | |
+ Timing.HorizontalResolution = BiosVideoPrivate->VbeModeInformationBlock->XResolution; | |
+ Timing.VerticalResolution = BiosVideoPrivate->VbeModeInformationBlock->YResolution; | |
+ if (!SearchEdidTiming (&ValidEdidTiming, &Timing)) { | |
+ // | |
+ // When EDID comes from INT10 call, EDID does not include 800x600, 640x480 and 1024x768, | |
+ // but INT10 can support these modes, we add them into GOP mode. | |
+ // | |
+ if ((BiosVideoPrivate->EdidDiscovered.SizeOfEdid != 0) && | |
+ !((Timing.HorizontalResolution) == 1024 && (Timing.VerticalResolution == 768)) && | |
+ !((Timing.HorizontalResolution) == 800 && (Timing.VerticalResolution == 600)) && | |
+ !((Timing.HorizontalResolution) == 640 && (Timing.VerticalResolution == 480))) { | |
+ continue; | |
+ } | |
+ } | |
+ } | |
+ | |
+ // | |
+ // Select a reasonable mode to be set for current display mode | |
+ // | |
+ ModeFound = FALSE; | |
+ | |
+ if (BiosVideoPrivate->VbeModeInformationBlock->XResolution == 1024 && | |
+ BiosVideoPrivate->VbeModeInformationBlock->YResolution == 768 | |
+ ) { | |
+ ModeFound = TRUE; | |
+ } | |
+ if (BiosVideoPrivate->VbeModeInformationBlock->XResolution == 800 && | |
+ BiosVideoPrivate->VbeModeInformationBlock->YResolution == 600 | |
+ ) { | |
+ ModeFound = TRUE; | |
+ PreferMode = ModeNumber; | |
+ } | |
+ if (BiosVideoPrivate->VbeModeInformationBlock->XResolution == 640 && | |
+ BiosVideoPrivate->VbeModeInformationBlock->YResolution == 480 | |
+ ) { | |
+ ModeFound = TRUE; | |
+ } | |
+ | |
+ if ((!EdidFound) && (!ModeFound)) { | |
+ // | |
+ // When no EDID exist, only select three possible resolutions, i.e. 1024x768, 800x600, 640x480 | |
+ // | |
+ continue; | |
+ } | |
+ | |
+ // | |
+ // Record the highest resolution mode to set later | |
+ // | |
+ if ((BiosVideoPrivate->VbeModeInformationBlock->XResolution > HighestHorizontalResolution) || | |
+ ((BiosVideoPrivate->VbeModeInformationBlock->XResolution == HighestHorizontalResolution) && | |
+ (BiosVideoPrivate->VbeModeInformationBlock->YResolution > HighestVerticalResolution))) { | |
+ HighestHorizontalResolution = BiosVideoPrivate->VbeModeInformationBlock->XResolution; | |
+ HighestVerticalResolution = BiosVideoPrivate->VbeModeInformationBlock->YResolution; | |
+ HighestResolutionMode = ModeNumber; | |
+ } | |
+ | |
+ // | |
+ // Add mode to the list of available modes | |
+ // | |
+ ModeNumber ++; | |
+ ModeBuffer = (BIOS_VIDEO_MODE_DATA *) AllocatePool ( | |
+ ModeNumber * sizeof (BIOS_VIDEO_MODE_DATA) | |
+ ); | |
+ if (NULL == ModeBuffer) { | |
+ Status = EFI_OUT_OF_RESOURCES; | |
+ goto Done; | |
+ } | |
+ | |
+ if (ModeNumber > 1) { | |
+ CopyMem ( | |
+ ModeBuffer, | |
+ BiosVideoPrivate->ModeData, | |
+ (ModeNumber - 1) * sizeof (BIOS_VIDEO_MODE_DATA) | |
+ ); | |
+ } | |
+ | |
+ if (BiosVideoPrivate->ModeData != NULL) { | |
+ FreePool (BiosVideoPrivate->ModeData); | |
+ } | |
+ | |
+ CurrentModeData = &ModeBuffer[ModeNumber - 1]; | |
+ CurrentModeData->VbeModeNumber = VbeModeNumber; | |
+ if (BiosVideoPrivate->VbeInformationBlock->VESAVersion >= VESA_BIOS_EXTENSIONS_VERSION_3_0) { | |
+ CurrentModeData->BytesPerScanLine = BiosVideoPrivate->VbeModeInformationBlock->LinBytesPerScanLine; | |
+ CurrentModeData->Red.Position = BiosVideoPrivate->VbeModeInformationBlock->LinRedFieldPosition; | |
+ CurrentModeData->Red.Mask = (UINT8) ((1 << BiosVideoPrivate->VbeModeInformationBlock->LinRedMaskSize) - 1); | |
+ CurrentModeData->Blue.Position = BiosVideoPrivate->VbeModeInformationBlock->LinBlueFieldPosition; | |
+ CurrentModeData->Blue.Mask = (UINT8) ((1 << BiosVideoPrivate->VbeModeInformationBlock->LinBlueMaskSize) - 1); | |
+ CurrentModeData->Green.Position = BiosVideoPrivate->VbeModeInformationBlock->LinGreenFieldPosition; | |
+ CurrentModeData->Green.Mask = (UINT8) ((1 << BiosVideoPrivate->VbeModeInformationBlock->LinGreenMaskSize) - 1); | |
+ CurrentModeData->Reserved.Position = BiosVideoPrivate->VbeModeInformationBlock->LinRsvdFieldPosition; | |
+ CurrentModeData->Reserved.Mask = (UINT8) ((1 << BiosVideoPrivate->VbeModeInformationBlock->LinRsvdMaskSize) - 1); | |
+ } else { | |
+ CurrentModeData->BytesPerScanLine = BiosVideoPrivate->VbeModeInformationBlock->BytesPerScanLine; | |
+ CurrentModeData->Red.Position = BiosVideoPrivate->VbeModeInformationBlock->RedFieldPosition; | |
+ CurrentModeData->Red.Mask = (UINT8) ((1 << BiosVideoPrivate->VbeModeInformationBlock->RedMaskSize) - 1); | |
+ CurrentModeData->Blue.Position = BiosVideoPrivate->VbeModeInformationBlock->BlueFieldPosition; | |
+ CurrentModeData->Blue.Mask = (UINT8) ((1 << BiosVideoPrivate->VbeModeInformationBlock->BlueMaskSize) - 1); | |
+ CurrentModeData->Green.Position = BiosVideoPrivate->VbeModeInformationBlock->GreenFieldPosition; | |
+ CurrentModeData->Green.Mask = (UINT8) ((1 << BiosVideoPrivate->VbeModeInformationBlock->GreenMaskSize) - 1); | |
+ CurrentModeData->Reserved.Position = BiosVideoPrivate->VbeModeInformationBlock->RsvdFieldPosition; | |
+ CurrentModeData->Reserved.Mask = (UINT8) ((1 << BiosVideoPrivate->VbeModeInformationBlock->RsvdMaskSize) - 1); | |
+ } | |
+ | |
+ CurrentModeData->PixelFormat = PixelBitMask; | |
+ if ((BiosVideoPrivate->VbeModeInformationBlock->BitsPerPixel == 32) && | |
+ (CurrentModeData->Red.Mask == 0xff) && (CurrentModeData->Green.Mask == 0xff) && (CurrentModeData->Blue.Mask == 0xff)) { | |
+ if ((CurrentModeData->Red.Position == 0) && (CurrentModeData->Green.Position == 8) && (CurrentModeData->Blue.Position == 16)) { | |
+ CurrentModeData->PixelFormat = PixelRedGreenBlueReserved8BitPerColor; | |
+ } else if ((CurrentModeData->Blue.Position == 0) && (CurrentModeData->Green.Position == 8) && (CurrentModeData->Red.Position == 16)) { | |
+ CurrentModeData->PixelFormat = PixelBlueGreenRedReserved8BitPerColor; | |
+ } | |
+ } | |
+ | |
+ CurrentModeData->PixelBitMask.RedMask = ((UINT32) CurrentModeData->Red.Mask) << CurrentModeData->Red.Position; | |
+ CurrentModeData->PixelBitMask.GreenMask = ((UINT32) CurrentModeData->Green.Mask) << CurrentModeData->Green.Position; | |
+ CurrentModeData->PixelBitMask.BlueMask = ((UINT32) CurrentModeData->Blue.Mask) << CurrentModeData->Blue.Position; | |
+ CurrentModeData->PixelBitMask.ReservedMask = ((UINT32) CurrentModeData->Reserved.Mask) << CurrentModeData->Reserved.Position; | |
+ | |
+ CurrentModeData->LinearFrameBuffer = (VOID *) (UINTN)BiosVideoPrivate->VbeModeInformationBlock->PhysBasePtr; | |
+ CurrentModeData->HorizontalResolution = BiosVideoPrivate->VbeModeInformationBlock->XResolution; | |
+ CurrentModeData->VerticalResolution = BiosVideoPrivate->VbeModeInformationBlock->YResolution; | |
+ | |
+ CurrentModeData->BitsPerPixel = BiosVideoPrivate->VbeModeInformationBlock->BitsPerPixel; | |
+ CurrentModeData->FrameBufferSize = CurrentModeData->BytesPerScanLine * CurrentModeData->VerticalResolution; | |
+ // | |
+ // Make sure the FrameBufferSize does not exceed the max available frame buffer size reported by VEB. | |
+ // | |
+ ASSERT (CurrentModeData->FrameBufferSize <= (UINTN)(BiosVideoPrivate->VbeInformationBlock->TotalMemory * 64 * 1024)); | |
+ | |
+ BiosVideoPrivate->ModeData = ModeBuffer; | |
+ } | |
+ } | |
+ // | |
+ // Check to see if we found any modes that are compatible with GRAPHICS OUTPUT | |
+ // | |
+ if (ModeNumber == 0) { | |
+ Status = EFI_DEVICE_ERROR; | |
+ goto Done; | |
+ } | |
+ | |
+ // | |
+ // Assign Gop's Blt function | |
+ // | |
+ BiosVideoPrivate->GraphicsOutput.Blt = BiosVideoGraphicsOutputVbeBlt; | |
+ | |
+ BiosVideoPrivate->GraphicsOutput.Mode->MaxMode = (UINT32) ModeNumber; | |
+ // | |
+ // Current mode is unknow till now, set it to an invalid mode. | |
+ // | |
+ BiosVideoPrivate->GraphicsOutput.Mode->Mode = GRAPHICS_OUTPUT_INVALIDE_MODE_NUMBER; | |
+ | |
+ // | |
+ // Find the best mode to initialize | |
+ // | |
+ if ((PcdGet32 (PcdVideoHorizontalResolution) == 0x0) || (PcdGet32 (PcdVideoVerticalResolution) == 0x0)) { | |
+ DEBUG_CODE ( | |
+ BIOS_VIDEO_MODE_DATA *ModeData; | |
+ ModeData = &BiosVideoPrivate->ModeData[HighestResolutionMode]; | |
+ DEBUG ((EFI_D_INFO, "BiosVideo set highest resolution %d x %d\n", | |
+ ModeData->HorizontalResolution, ModeData->VerticalResolution)); | |
+ ); | |
+ PreferMode = HighestResolutionMode; | |
+ } | |
+ Status = BiosVideoGraphicsOutputSetMode (&BiosVideoPrivate->GraphicsOutput, (UINT32) PreferMode); | |
+ if (EFI_ERROR (Status)) { | |
+ for (PreferMode = 0; PreferMode < ModeNumber; PreferMode ++) { | |
+ Status = BiosVideoGraphicsOutputSetMode ( | |
+ &BiosVideoPrivate->GraphicsOutput, | |
+ (UINT32) PreferMode | |
+ ); | |
+ if (!EFI_ERROR (Status)) { | |
+ break; | |
+ } | |
+ } | |
+ if (PreferMode == ModeNumber) { | |
+ // | |
+ // None mode is set successfully. | |
+ // | |
+ goto Done; | |
+ } | |
+ } | |
+ | |
+Done: | |
+ // | |
+ // If there was an error, then free the mode structure | |
+ // | |
+ if (EFI_ERROR (Status)) { | |
+ if (BiosVideoPrivate->ModeData != NULL) { | |
+ FreePool (BiosVideoPrivate->ModeData); | |
+ BiosVideoPrivate->ModeData = NULL; | |
+ BiosVideoPrivate->MaxMode = 0; | |
+ } | |
+ if (EdidOverrideDataBlock != NULL) { | |
+ FreePool (EdidOverrideDataBlock); | |
+ } | |
+ } | |
+ | |
+ return Status; | |
+} | |
+ | |
+ | |
+/** | |
+ Check for VGA device. | |
+ | |
+ @param BiosVideoPrivate Pointer to BIOS_VIDEO_DEV structure | |
+ | |
+ @retval EFI_SUCCESS Standard VGA device found | |
+ | |
+**/ | |
+EFI_STATUS | |
+BiosVideoCheckForVga ( | |
+ IN OUT BIOS_VIDEO_DEV *BiosVideoPrivate | |
+ ) | |
+{ | |
+ EFI_STATUS Status; | |
+ BIOS_VIDEO_MODE_DATA *ModeBuffer; | |
+ | |
+ Status = EFI_UNSUPPORTED; | |
+ | |
+ // | |
+ // Assign Gop's Blt function | |
+ // | |
+ BiosVideoPrivate->GraphicsOutput.Blt = BiosVideoGraphicsOutputVgaBlt; | |
+ | |
+ // | |
+ // Add mode to the list of available modes | |
+ // caller should guarantee that Mode has been allocated. | |
+ // | |
+ ASSERT (BiosVideoPrivate->GraphicsOutput.Mode != NULL); | |
+ BiosVideoPrivate->GraphicsOutput.Mode->MaxMode = 1; | |
+ | |
+ ModeBuffer = (BIOS_VIDEO_MODE_DATA *) AllocatePool ( | |
+ sizeof (BIOS_VIDEO_MODE_DATA) | |
+ ); | |
+ if (NULL == ModeBuffer) { | |
+ Status = EFI_OUT_OF_RESOURCES; | |
+ goto Done; | |
+ } | |
+ | |
+ ModeBuffer->VbeModeNumber = 0x0012; | |
+ ModeBuffer->BytesPerScanLine = 640; | |
+ ModeBuffer->LinearFrameBuffer = (VOID *) (UINTN) (0xa0000); | |
+ ModeBuffer->HorizontalResolution = 640; | |
+ ModeBuffer->VerticalResolution = 480; | |
+ ModeBuffer->PixelFormat = PixelBltOnly; | |
+ ModeBuffer->BitsPerPixel = 8; | |
+ ModeBuffer->ColorDepth = 32; | |
+ ModeBuffer->RefreshRate = 60; | |
+ | |
+ BiosVideoPrivate->ModeData = ModeBuffer; | |
+ | |
+ // | |
+ // Test to see if the Video Adapter support the 640x480 16 color mode | |
+ // | |
+ BiosVideoPrivate->GraphicsOutput.Mode->Mode = GRAPHICS_OUTPUT_INVALIDE_MODE_NUMBER; | |
+ Status = BiosVideoGraphicsOutputSetMode (&BiosVideoPrivate->GraphicsOutput, 0); | |
+ | |
+Done: | |
+ // | |
+ // If there was an error, then free the mode structure | |
+ // | |
+ if (EFI_ERROR (Status)) { | |
+ if (BiosVideoPrivate->ModeData != NULL) { | |
+ FreePool (BiosVideoPrivate->ModeData); | |
+ BiosVideoPrivate->ModeData = NULL; | |
+ } | |
+ if (BiosVideoPrivate->GraphicsOutput.Mode != NULL) { | |
+ if (BiosVideoPrivate->GraphicsOutput.Mode->Info != NULL) { | |
+ FreePool (BiosVideoPrivate->GraphicsOutput.Mode->Info); | |
+ BiosVideoPrivate->GraphicsOutput.Mode->Info = NULL; | |
+ } | |
+ FreePool (BiosVideoPrivate->GraphicsOutput.Mode); | |
+ BiosVideoPrivate->GraphicsOutput.Mode = NULL; | |
+ } | |
+ } | |
+ return Status; | |
+} | |
+ | |
+// | |
+// Graphics Output Protocol Member Functions for VESA BIOS Extensions | |
+// | |
+ | |
+/** | |
+ Graphics Output protocol interface to get video mode. | |
+ | |
+ @param This Protocol instance pointer. | |
+ @param ModeNumber The mode number to return information on. | |
+ @param SizeOfInfo A pointer to the size, in bytes, of the Info | |
+ buffer. | |
+ @param Info Caller allocated buffer that returns information | |
+ about ModeNumber. | |
+ | |
+ @retval EFI_SUCCESS Mode information returned. | |
+ @retval EFI_DEVICE_ERROR A hardware error occurred trying to retrieve the | |
+ video mode. | |
+ @retval EFI_NOT_STARTED Video display is not initialized. Call SetMode () | |
+ @retval EFI_INVALID_PARAMETER One of the input args was NULL. | |
+ | |
+**/ | |
+EFI_STATUS | |
+EFIAPI | |
+BiosVideoGraphicsOutputQueryMode ( | |
+ IN EFI_GRAPHICS_OUTPUT_PROTOCOL *This, | |
+ IN UINT32 ModeNumber, | |
+ OUT UINTN *SizeOfInfo, | |
+ OUT EFI_GRAPHICS_OUTPUT_MODE_INFORMATION **Info | |
+ ) | |
+{ | |
+ BIOS_VIDEO_DEV *BiosVideoPrivate; | |
+ BIOS_VIDEO_MODE_DATA *ModeData; | |
+ | |
+ BiosVideoPrivate = BIOS_VIDEO_DEV_FROM_GRAPHICS_OUTPUT_THIS (This); | |
+ | |
+ if (BiosVideoPrivate->HardwareNeedsStarting) { | |
+ REPORT_STATUS_CODE_WITH_DEVICE_PATH ( | |
+ EFI_ERROR_CODE | EFI_ERROR_MINOR, | |
+ EFI_PERIPHERAL_LOCAL_CONSOLE | EFI_P_EC_OUTPUT_ERROR, | |
+ BiosVideoPrivate->GopDevicePath | |
+ ); | |
+ return EFI_NOT_STARTED; | |
+ } | |
+ | |
+ if (This == NULL || Info == NULL || SizeOfInfo == NULL || ModeNumber >= This->Mode->MaxMode) { | |
+ return EFI_INVALID_PARAMETER; | |
+ } | |
+ | |
+ *Info = (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *) AllocatePool ( | |
+ sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION) | |
+ ); | |
+ if (NULL == *Info) { | |
+ return EFI_OUT_OF_RESOURCES; | |
+ } | |
+ | |
+ *SizeOfInfo = sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION); | |
+ | |
+ ModeData = &BiosVideoPrivate->ModeData[ModeNumber]; | |
+ (*Info)->Version = 0; | |
+ (*Info)->HorizontalResolution = ModeData->HorizontalResolution; | |
+ (*Info)->VerticalResolution = ModeData->VerticalResolution; | |
+ (*Info)->PixelFormat = ModeData->PixelFormat; | |
+ CopyMem (&((*Info)->PixelInformation), &(ModeData->PixelBitMask), sizeof(ModeData->PixelBitMask)); | |
+ | |
+ (*Info)->PixelsPerScanLine = (ModeData->BytesPerScanLine * 8) / ModeData->BitsPerPixel; | |
+ | |
+ return EFI_SUCCESS; | |
+} | |
+ | |
+/** | |
+ Worker function to set video mode. | |
+ | |
+ @param BiosVideoPrivate Instance of BIOS_VIDEO_DEV. | |
+ @param ModeData The mode data to be set. | |
+ @param DevicePath Pointer to Device Path Protocol. | |
+ | |
+ @retval EFI_SUCCESS Graphics mode was changed. | |
+ @retval EFI_DEVICE_ERROR The device had an error and could not complete the | |
+ request. | |
+ @retval EFI_UNSUPPORTED ModeNumber is not supported by this device. | |
+ | |
+**/ | |
+EFI_STATUS | |
+BiosVideoSetModeWorker ( | |
+ IN BIOS_VIDEO_DEV *BiosVideoPrivate, | |
+ IN BIOS_VIDEO_MODE_DATA *ModeData, | |
+ IN EFI_DEVICE_PATH_PROTOCOL *DevicePath | |
+ ) | |
+{ | |
+ EFI_STATUS Status; | |
+ EFI_IA32_REGISTER_SET Regs; | |
+ | |
+ if (BiosVideoPrivate->LineBuffer != NULL) { | |
+ FreePool (BiosVideoPrivate->LineBuffer); | |
+ } | |
+ | |
+ if (BiosVideoPrivate->VgaFrameBuffer != NULL) { | |
+ FreePool (BiosVideoPrivate->VgaFrameBuffer); | |
+ } | |
+ | |
+ if (BiosVideoPrivate->VbeFrameBuffer != NULL) { | |
+ FreePool (BiosVideoPrivate->VbeFrameBuffer); | |
+ } | |
+ | |
+ BiosVideoPrivate->LineBuffer = (UINT8 *) AllocatePool ( | |
+ ModeData->BytesPerScanLine | |
+ ); | |
+ if (NULL == BiosVideoPrivate->LineBuffer) { | |
+ return EFI_OUT_OF_RESOURCES; | |
+ } | |
+ // | |
+ // Clear all registers | |
+ // | |
+ ZeroMem (&Regs, sizeof (Regs)); | |
+ | |
+ if (ModeData->VbeModeNumber < 0x100) { | |
+ // | |
+ // Allocate a working buffer for BLT operations to the VGA frame buffer | |
+ // | |
+ BiosVideoPrivate->VgaFrameBuffer = (UINT8 *) AllocatePool (4 * 480 * 80); | |
+ if (NULL == BiosVideoPrivate->VgaFrameBuffer) { | |
+ return EFI_OUT_OF_RESOURCES; | |
+ } | |
+ // | |
+ // Set VGA Mode | |
+ // | |
+ Regs.X.AX = ModeData->VbeModeNumber; | |
+ BiosVideoPrivate->LegacyBios->Int86 (BiosVideoPrivate->LegacyBios, 0x10, &Regs); | |
+ | |
+ } else { | |
+ // | |
+ // Allocate a working buffer for BLT operations to the VBE frame buffer | |
+ // | |
+ BiosVideoPrivate->VbeFrameBuffer = | |
+ (EFI_GRAPHICS_OUTPUT_BLT_PIXEL *) AllocatePool ( | |
+ ModeData->BytesPerScanLine * ModeData->VerticalResolution | |
+ ); | |
+ if (NULL == BiosVideoPrivate->VbeFrameBuffer) { | |
+ return EFI_OUT_OF_RESOURCES; | |
+ } | |
+ // | |
+ // Set VBE mode | |
+ // | |
+ Regs.X.AX = VESA_BIOS_EXTENSIONS_SET_MODE; | |
+ Regs.X.BX = (UINT16) (ModeData->VbeModeNumber | VESA_BIOS_EXTENSIONS_MODE_NUMBER_LINEAR_FRAME_BUFFER); | |
+ ZeroMem (BiosVideoPrivate->VbeCrtcInformationBlock, sizeof (VESA_BIOS_EXTENSIONS_CRTC_INFORMATION_BLOCK)); | |
+ Regs.X.ES = EFI_SEGMENT ((UINTN) BiosVideoPrivate->VbeCrtcInformationBlock); | |
+ Regs.X.DI = EFI_OFFSET ((UINTN) BiosVideoPrivate->VbeCrtcInformationBlock); | |
+ BiosVideoPrivate->LegacyBios->Int86 (BiosVideoPrivate->LegacyBios, 0x10, &Regs); | |
+ | |
+ // | |
+ // Check to see if the call succeeded | |
+ // | |
+ if (Regs.X.AX != VESA_BIOS_EXTENSIONS_STATUS_SUCCESS) { | |
+ REPORT_STATUS_CODE_WITH_DEVICE_PATH ( | |
+ EFI_ERROR_CODE | EFI_ERROR_MINOR, | |
+ EFI_PERIPHERAL_LOCAL_CONSOLE | EFI_P_EC_OUTPUT_ERROR, | |
+ DevicePath | |
+ ); | |
+ return EFI_DEVICE_ERROR; | |
+ } | |
+ // | |
+ // Initialize the state of the VbeFrameBuffer | |
+ // | |
+ Status = BiosVideoPrivate->PciIo->Mem.Read ( | |
+ BiosVideoPrivate->PciIo, | |
+ EfiPciIoWidthUint32, | |
+ EFI_PCI_IO_PASS_THROUGH_BAR, | |
+ (UINT64) (UINTN) ModeData->LinearFrameBuffer, | |
+ (ModeData->BytesPerScanLine * ModeData->VerticalResolution) >> 2, | |
+ BiosVideoPrivate->VbeFrameBuffer | |
+ ); | |
+ if (EFI_ERROR (Status)) { | |
+ return Status; | |
+ } | |
+ } | |
+ | |
+ return EFI_SUCCESS; | |
+} | |
+ | |
+/** | |
+ Graphics Output protocol interface to set video mode. | |
+ | |
+ @param This Protocol instance pointer. | |
+ @param ModeNumber The mode number to be set. | |
+ | |
+ @retval EFI_SUCCESS Graphics mode was changed. | |
+ @retval EFI_DEVICE_ERROR The device had an error and could not complete the | |
+ request. | |
+ @retval EFI_UNSUPPORTED ModeNumber is not supported by this device. | |
+ | |
+**/ | |
+EFI_STATUS | |
+EFIAPI | |
+BiosVideoGraphicsOutputSetMode ( | |
+ IN EFI_GRAPHICS_OUTPUT_PROTOCOL * This, | |
+ IN UINT32 ModeNumber | |
+ ) | |
+{ | |
+ EFI_STATUS Status; | |
+ BIOS_VIDEO_DEV *BiosVideoPrivate; | |
+ BIOS_VIDEO_MODE_DATA *ModeData; | |
+ EFI_GRAPHICS_OUTPUT_BLT_PIXEL Background; | |
+ UINTN Index; | |
+ UINTN HandleCount; | |
+ EFI_HANDLE *HandleBuffer; | |
+ | |
+ if (This == NULL) { | |
+ return EFI_INVALID_PARAMETER; | |
+ } | |
+ | |
+ BiosVideoPrivate = BIOS_VIDEO_DEV_FROM_GRAPHICS_OUTPUT_THIS (This); | |
+ | |
+ ModeData = &BiosVideoPrivate->ModeData[ModeNumber]; | |
+ | |
+ if (ModeNumber >= This->Mode->MaxMode) { | |
+ return EFI_UNSUPPORTED; | |
+ } | |
+ | |
+ if (ModeNumber == This->Mode->Mode) { | |
+ // | |
+ // Clear screen to black | |
+ // | |
+ ZeroMem (&Background, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL)); | |
+ BiosVideoGraphicsOutputVbeBlt ( | |
+ This, | |
+ &Background, | |
+ EfiBltVideoFill, | |
+ 0, | |
+ 0, | |
+ 0, | |
+ 0, | |
+ ModeData->HorizontalResolution, | |
+ ModeData->VerticalResolution, | |
+ 0 | |
+ ); | |
+ return EFI_SUCCESS; | |
+ } | |
+ | |
+ Status = BiosVideoSetModeWorker (BiosVideoPrivate, ModeData, BiosVideoPrivate->GopDevicePath); | |
+ if (EFI_ERROR (Status)) { | |
+ return Status; | |
+ } | |
+ | |
+ This->Mode->Mode = ModeNumber; | |
+ This->Mode->Info->Version = 0; | |
+ This->Mode->Info->HorizontalResolution = ModeData->HorizontalResolution; | |
+ This->Mode->Info->VerticalResolution = ModeData->VerticalResolution; | |
+ This->Mode->Info->PixelFormat = ModeData->PixelFormat; | |
+ CopyMem (&(This->Mode->Info->PixelInformation), &(ModeData->PixelBitMask), sizeof (ModeData->PixelBitMask)); | |
+ This->Mode->Info->PixelsPerScanLine = (ModeData->BytesPerScanLine * 8) / ModeData->BitsPerPixel; | |
+ This->Mode->SizeOfInfo = sizeof(EFI_GRAPHICS_OUTPUT_MODE_INFORMATION); | |
+ This->Mode->FrameBufferSize = ModeData->FrameBufferSize; | |
+ This->Mode->FrameBufferBase = (EFI_PHYSICAL_ADDRESS) (UINTN) ModeData->LinearFrameBuffer; | |
+ | |
+ BiosVideoPrivate->HardwareNeedsStarting = FALSE; | |
+ | |
+ // | |
+ // Set PCDs to Inform GraphicsConsole of video resolution. | |
+ // | |
+ PcdSet32 (PcdVideoHorizontalResolution, ModeData->HorizontalResolution); | |
+ PcdSet32 (PcdVideoVerticalResolution, ModeData->VerticalResolution); | |
+ | |
+ // | |
+ // Video mode is changed, so restart graphics console driver and higher level driver. | |
+ // Reconnect graphics console driver and higher level driver. | |
+ // Locate all the handles with GOP protocol and reconnect it. | |
+ // | |
+ Status = gBS->LocateHandleBuffer ( | |
+ ByProtocol, | |
+ &gEfiSimpleTextOutProtocolGuid, | |
+ NULL, | |
+ &HandleCount, | |
+ &HandleBuffer | |
+ ); | |
+ if (!EFI_ERROR (Status)) { | |
+ for (Index = 0; Index < HandleCount; Index++) { | |
+ gBS->DisconnectController (HandleBuffer[Index], NULL, NULL); | |
+ } for (Index = 0; Index < HandleCount; Index++) { | |
+ gBS->ConnectController (HandleBuffer[Index], NULL, NULL, TRUE); | |
+ } | |
+ if (HandleBuffer != NULL) { | |
+ FreePool (HandleBuffer); | |
+ } | |
+ } | |
+ | |
+ return EFI_SUCCESS; | |
+} | |
+ | |
+/** | |
+ Update physical frame buffer, copy 4 bytes block, then copy remaining bytes. | |
+ | |
+ @param PciIo The pointer of EFI_PCI_IO_PROTOCOL | |
+ @param VbeBuffer The data to transfer to screen | |
+ @param MemAddress Physical frame buffer base address | |
+ @param DestinationX The X coordinate of the destination for BltOperation | |
+ @param DestinationY The Y coordinate of the destination for BltOperation | |
+ @param TotalBytes The total bytes of copy | |
+ @param VbePixelWidth Bytes per pixel | |
+ @param BytesPerScanLine Bytes per scan line | |
+ | |
+**/ | |
+VOID | |
+CopyVideoBuffer ( | |
+ IN EFI_PCI_IO_PROTOCOL *PciIo, | |
+ IN UINT8 *VbeBuffer, | |
+ IN VOID *MemAddress, | |
+ IN UINTN DestinationX, | |
+ IN UINTN DestinationY, | |
+ IN UINTN TotalBytes, | |
+ IN UINT32 VbePixelWidth, | |
+ IN UINTN BytesPerScanLine | |
+ ) | |
+{ | |
+ UINTN FrameBufferAddr; | |
+ UINTN CopyBlockNum; | |
+ UINTN RemainingBytes; | |
+ UINTN UnalignedBytes; | |
+ EFI_STATUS Status; | |
+ | |
+ FrameBufferAddr = (UINTN) MemAddress + (DestinationY * BytesPerScanLine) + DestinationX * VbePixelWidth; | |
+ | |
+ // | |
+ // If TotalBytes is less than 4 bytes, only start byte copy. | |
+ // | |
+ if (TotalBytes < 4) { | |
+ Status = PciIo->Mem.Write ( | |
+ PciIo, | |
+ EfiPciIoWidthUint8, | |
+ EFI_PCI_IO_PASS_THROUGH_BAR, | |
+ (UINT64) FrameBufferAddr, | |
+ TotalBytes, | |
+ VbeBuffer | |
+ ); | |
+ ASSERT_EFI_ERROR (Status); | |
+ return; | |
+ } | |
+ | |
+ // | |
+ // If VbeBuffer is not 4-byte aligned, start byte copy. | |
+ // | |
+ UnalignedBytes = (4 - ((UINTN) VbeBuffer & 0x3)) & 0x3; | |
+ | |
+ if (UnalignedBytes != 0) { | |
+ Status = PciIo->Mem.Write ( | |
+ PciIo, | |
+ EfiPciIoWidthUint8, | |
+ EFI_PCI_IO_PASS_THROUGH_BAR, | |
+ (UINT64) FrameBufferAddr, | |
+ UnalignedBytes, | |
+ VbeBuffer | |
+ ); | |
+ ASSERT_EFI_ERROR (Status); | |
+ FrameBufferAddr += UnalignedBytes; | |
+ VbeBuffer += UnalignedBytes; | |
+ } | |
+ | |
+ // | |
+ // Calculate 4-byte block count and remaining bytes. | |
+ // | |
+ CopyBlockNum = (TotalBytes - UnalignedBytes) >> 2; | |
+ RemainingBytes = (TotalBytes - UnalignedBytes) & 3; | |
+ | |
+ // | |
+ // Copy 4-byte block and remaining bytes to physical frame buffer. | |
+ // | |
+ if (CopyBlockNum != 0) { | |
+ Status = PciIo->Mem.Write ( | |
+ PciIo, | |
+ EfiPciIoWidthUint32, | |
+ EFI_PCI_IO_PASS_THROUGH_BAR, | |
+ (UINT64) FrameBufferAddr, | |
+ CopyBlockNum, | |
+ VbeBuffer | |
+ ); | |
+ ASSERT_EFI_ERROR (Status); | |
+ } | |
+ | |
+ if (RemainingBytes != 0) { | |
+ FrameBufferAddr += (CopyBlockNum << 2); | |
+ VbeBuffer += (CopyBlockNum << 2); | |
+ Status = PciIo->Mem.Write ( | |
+ PciIo, | |
+ EfiPciIoWidthUint8, | |
+ EFI_PCI_IO_PASS_THROUGH_BAR, | |
+ (UINT64) FrameBufferAddr, | |
+ RemainingBytes, | |
+ VbeBuffer | |
+ ); | |
+ ASSERT_EFI_ERROR (Status); | |
+ } | |
+} | |
+ | |
+/** | |
+ Worker function to block transfer for VBE device. | |
+ | |
+ @param BiosVideoPrivate Instance of BIOS_VIDEO_DEV | |
+ @param BltBuffer The data to transfer to screen | |
+ @param BltOperation The operation to perform | |
+ @param SourceX The X coordinate of the source for BltOperation | |
+ @param SourceY The Y coordinate of the source for BltOperation | |
+ @param DestinationX The X coordinate of the destination for | |
+ BltOperation | |
+ @param DestinationY The Y coordinate of the destination for | |
+ BltOperation | |
+ @param Width The width of a rectangle in the blt rectangle in | |
+ pixels | |
+ @param Height The height of a rectangle in the blt rectangle in | |
+ pixels | |
+ @param Delta Not used for EfiBltVideoFill and | |
+ EfiBltVideoToVideo operation. If a Delta of 0 is | |
+ used, the entire BltBuffer will be operated on. If | |
+ a subrectangle of the BltBuffer is used, then | |
+ Delta represents the number of bytes in a row of | |
+ the BltBuffer. | |
+ @param Mode Mode data. | |
+ | |
+ @retval EFI_INVALID_PARAMETER Invalid parameter passed in | |
+ @retval EFI_SUCCESS Blt operation success | |
+ | |
+**/ | |
+EFI_STATUS | |
+BiosVideoVbeBltWorker ( | |
+ IN BIOS_VIDEO_DEV *BiosVideoPrivate, | |
+ IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer, OPTIONAL | |
+ IN EFI_GRAPHICS_OUTPUT_BLT_OPERATION BltOperation, | |
+ IN UINTN SourceX, | |
+ IN UINTN SourceY, | |
+ IN UINTN DestinationX, | |
+ IN UINTN DestinationY, | |
+ IN UINTN Width, | |
+ IN UINTN Height, | |
+ IN UINTN Delta, | |
+ IN BIOS_VIDEO_MODE_DATA *Mode | |
+ ) | |
+{ | |
+ EFI_PCI_IO_PROTOCOL *PciIo; | |
+ EFI_TPL OriginalTPL; | |
+ UINTN DstY; | |
+ UINTN SrcY; | |
+ UINTN DstX; | |
+ EFI_GRAPHICS_OUTPUT_BLT_PIXEL *Blt; | |
+ VOID *MemAddress; | |
+ EFI_GRAPHICS_OUTPUT_BLT_PIXEL *VbeFrameBuffer; | |
+ UINTN BytesPerScanLine; | |
+ UINTN Index; | |
+ UINT8 *VbeBuffer; | |
+ UINT8 *VbeBuffer1; | |
+ UINT8 *BltUint8; | |
+ UINT32 VbePixelWidth; | |
+ UINT32 Pixel; | |
+ UINTN TotalBytes; | |
+ | |
+ PciIo = BiosVideoPrivate->PciIo; | |
+ | |
+ VbeFrameBuffer = BiosVideoPrivate->VbeFrameBuffer; | |
+ MemAddress = Mode->LinearFrameBuffer; | |
+ BytesPerScanLine = Mode->BytesPerScanLine; | |
+ VbePixelWidth = Mode->BitsPerPixel / 8; | |
+ BltUint8 = (UINT8 *) BltBuffer; | |
+ TotalBytes = Width * VbePixelWidth; | |
+ | |
+ if (((UINTN) BltOperation) >= EfiGraphicsOutputBltOperationMax) { | |
+ return EFI_INVALID_PARAMETER; | |
+ } | |
+ | |
+ if (Width == 0 || Height == 0) { | |
+ return EFI_INVALID_PARAMETER; | |
+ } | |
+ // | |
+ // We need to fill the Virtual Screen buffer with the blt data. | |
+ // The virtual screen is upside down, as the first row is the bootom row of | |
+ // the image. | |
+ // | |
+ if (BltOperation == EfiBltVideoToBltBuffer) { | |
+ // | |
+ // Video to BltBuffer: Source is Video, destination is BltBuffer | |
+ // | |
+ if (SourceY + Height > Mode->VerticalResolution) { | |
+ return EFI_INVALID_PARAMETER; | |
+ } | |
+ | |
+ if (SourceX + Width > Mode->HorizontalResolution) { | |
+ return EFI_INVALID_PARAMETER; | |
+ } | |
+ } else { | |
+ // | |
+ // BltBuffer to Video: Source is BltBuffer, destination is Video | |
+ // | |
+ if (DestinationY + Height > Mode->VerticalResolution) { | |
+ return EFI_INVALID_PARAMETER; | |
+ } | |
+ | |
+ if (DestinationX + Width > Mode->HorizontalResolution) { | |
+ return EFI_INVALID_PARAMETER; | |
+ } | |
+ } | |
+ // | |
+ // If Delta is zero, then the entire BltBuffer is being used, so Delta | |
+ // is the number of bytes in each row of BltBuffer. Since BltBuffer is Width pixels size, | |
+ // the number of bytes in each row can be computed. | |
+ // | |
+ if (Delta == 0) { | |
+ Delta = Width * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL); | |
+ } | |
+ // | |
+ // We have to raise to TPL Notify, so we make an atomic write the frame buffer. | |
+ // We would not want a timer based event (Cursor, ...) to come in while we are | |
+ // doing this operation. | |
+ // | |
+ OriginalTPL = gBS->RaiseTPL (TPL_NOTIFY); | |
+ | |
+ switch (BltOperation) { | |
+ case EfiBltVideoToBltBuffer: | |
+ for (SrcY = SourceY, DstY = DestinationY; DstY < (Height + DestinationY); SrcY++, DstY++) { | |
+ Blt = (EFI_GRAPHICS_OUTPUT_BLT_PIXEL *) (BltUint8 + DstY * Delta + DestinationX * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL)); | |
+ // | |
+ // Shuffle the packed bytes in the hardware buffer to match EFI_GRAPHICS_OUTPUT_BLT_PIXEL | |
+ // | |
+ VbeBuffer = ((UINT8 *) VbeFrameBuffer + (SrcY * BytesPerScanLine + SourceX * VbePixelWidth)); | |
+ for (DstX = DestinationX; DstX < (Width + DestinationX); DstX++) { | |
+ Pixel = VbeBuffer[0] | VbeBuffer[1] << 8 | VbeBuffer[2] << 16 | VbeBuffer[3] << 24; | |
+ Blt->Red = (UINT8) ((Pixel >> Mode->Red.Position) & Mode->Red.Mask); | |
+ Blt->Blue = (UINT8) ((Pixel >> Mode->Blue.Position) & Mode->Blue.Mask); | |
+ Blt->Green = (UINT8) ((Pixel >> Mode->Green.Position) & Mode->Green.Mask); | |
+ Blt->Reserved = 0; | |
+ Blt++; | |
+ VbeBuffer += VbePixelWidth; | |
+ } | |
+ | |
+ } | |
+ break; | |
+ | |
+ case EfiBltVideoToVideo: | |
+ for (Index = 0; Index < Height; Index++) { | |
+ if (DestinationY <= SourceY) { | |
+ SrcY = SourceY + Index; | |
+ DstY = DestinationY + Index; | |
+ } else { | |
+ SrcY = SourceY + Height - Index - 1; | |
+ DstY = DestinationY + Height - Index - 1; | |
+ } | |
+ | |
+ VbeBuffer = ((UINT8 *) VbeFrameBuffer + DstY * BytesPerScanLine + DestinationX * VbePixelWidth); | |
+ VbeBuffer1 = ((UINT8 *) VbeFrameBuffer + SrcY * BytesPerScanLine + SourceX * VbePixelWidth); | |
+ | |
+ gBS->CopyMem ( | |
+ VbeBuffer, | |
+ VbeBuffer1, | |
+ TotalBytes | |
+ ); | |
+ | |
+ // | |
+ // Update physical frame buffer. | |
+ // | |
+ CopyVideoBuffer ( | |
+ PciIo, | |
+ VbeBuffer, | |
+ MemAddress, | |
+ DestinationX, | |
+ DstY, | |
+ TotalBytes, | |
+ VbePixelWidth, | |
+ BytesPerScanLine | |
+ ); | |
+ } | |
+ break; | |
+ | |
+ case EfiBltVideoFill: | |
+ VbeBuffer = (UINT8 *) ((UINTN) VbeFrameBuffer + (DestinationY * BytesPerScanLine) + DestinationX * VbePixelWidth); | |
+ Blt = (EFI_GRAPHICS_OUTPUT_BLT_PIXEL *) BltUint8; | |
+ // | |
+ // Shuffle the RGB fields in EFI_GRAPHICS_OUTPUT_BLT_PIXEL to match the hardware buffer | |
+ // | |
+ Pixel = ((Blt->Red & Mode->Red.Mask) << Mode->Red.Position) | | |
+ ( | |
+ (Blt->Green & Mode->Green.Mask) << | |
+ Mode->Green.Position | |
+ ) | | |
+ ((Blt->Blue & Mode->Blue.Mask) << Mode->Blue.Position); | |
+ | |
+ for (Index = 0; Index < Width; Index++) { | |
+ gBS->CopyMem ( | |
+ VbeBuffer, | |
+ &Pixel, | |
+ VbePixelWidth | |
+ ); | |
+ VbeBuffer += VbePixelWidth; | |
+ } | |
+ | |
+ VbeBuffer = (UINT8 *) ((UINTN) VbeFrameBuffer + (DestinationY * BytesPerScanLine) + DestinationX * VbePixelWidth); | |
+ for (DstY = DestinationY + 1; DstY < (Height + DestinationY); DstY++) { | |
+ gBS->CopyMem ( | |
+ (VOID *) ((UINTN) VbeFrameBuffer + (DstY * BytesPerScanLine) + DestinationX * VbePixelWidth), | |
+ VbeBuffer, | |
+ TotalBytes | |
+ ); | |
+ } | |
+ | |
+ for (DstY = DestinationY; DstY < (Height + DestinationY); DstY++) { | |
+ // | |
+ // Update physical frame buffer. | |
+ // | |
+ CopyVideoBuffer ( | |
+ PciIo, | |
+ VbeBuffer, | |
+ MemAddress, | |
+ DestinationX, | |
+ DstY, | |
+ TotalBytes, | |
+ VbePixelWidth, | |
+ BytesPerScanLine | |
+ ); | |
+ } | |
+ break; | |
+ | |
+ case EfiBltBufferToVideo: | |
+ for (SrcY = SourceY, DstY = DestinationY; SrcY < (Height + SourceY); SrcY++, DstY++) { | |
+ Blt = (EFI_GRAPHICS_OUTPUT_BLT_PIXEL *) (BltUint8 + (SrcY * Delta) + (SourceX) * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL)); | |
+ VbeBuffer = ((UINT8 *) VbeFrameBuffer + (DstY * BytesPerScanLine + DestinationX * VbePixelWidth)); | |
+ for (DstX = DestinationX; DstX < (Width + DestinationX); DstX++) { | |
+ // | |
+ // Shuffle the RGB fields in EFI_GRAPHICS_OUTPUT_BLT_PIXEL to match the hardware buffer | |
+ // | |
+ Pixel = ((Blt->Red & Mode->Red.Mask) << Mode->Red.Position) | | |
+ ((Blt->Green & Mode->Green.Mask) << Mode->Green.Position) | | |
+ ((Blt->Blue & Mode->Blue.Mask) << Mode->Blue.Position); | |
+ gBS->CopyMem ( | |
+ VbeBuffer, | |
+ &Pixel, | |
+ VbePixelWidth | |
+ ); | |
+ Blt++; | |
+ VbeBuffer += VbePixelWidth; | |
+ } | |
+ | |
+ VbeBuffer = ((UINT8 *) VbeFrameBuffer + (DstY * BytesPerScanLine + DestinationX * VbePixelWidth)); | |
+ | |
+ // | |
+ // Update physical frame buffer. | |
+ // | |
+ CopyVideoBuffer ( | |
+ PciIo, | |
+ VbeBuffer, | |
+ MemAddress, | |
+ DestinationX, | |
+ DstY, | |
+ TotalBytes, | |
+ VbePixelWidth, | |
+ BytesPerScanLine | |
+ ); | |
+ } | |
+ break; | |
+ | |
+ default: ; | |
+ } | |
+ | |
+ gBS->RestoreTPL (OriginalTPL); | |
+ | |
+ return EFI_SUCCESS; | |
+} | |
+ | |
+/** | |
+ Graphics Output protocol instance to block transfer for VBE device. | |
+ | |
+ @param This Pointer to Graphics Output protocol instance | |
+ @param BltBuffer The data to transfer to screen | |
+ @param BltOperation The operation to perform | |
+ @param SourceX The X coordinate of the source for BltOperation | |
+ @param SourceY The Y coordinate of the source for BltOperation | |
+ @param DestinationX The X coordinate of the destination for | |
+ BltOperation | |
+ @param DestinationY The Y coordinate of the destination for | |
+ BltOperation | |
+ @param Width The width of a rectangle in the blt rectangle in | |
+ pixels | |
+ @param Height The height of a rectangle in the blt rectangle in | |
+ pixels | |
+ @param Delta Not used for EfiBltVideoFill and | |
+ EfiBltVideoToVideo operation. If a Delta of 0 is | |
+ used, the entire BltBuffer will be operated on. If | |
+ a subrectangle of the BltBuffer is used, then | |
+ Delta represents the number of bytes in a row of | |
+ the BltBuffer. | |
+ | |
+ @retval EFI_INVALID_PARAMETER Invalid parameter passed in | |
+ @retval EFI_SUCCESS Blt operation success | |
+ | |
+**/ | |
+EFI_STATUS | |
+EFIAPI | |
+BiosVideoGraphicsOutputVbeBlt ( | |
+ IN EFI_GRAPHICS_OUTPUT_PROTOCOL *This, | |
+ IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer, OPTIONAL | |
+ IN EFI_GRAPHICS_OUTPUT_BLT_OPERATION BltOperation, | |
+ IN UINTN SourceX, | |
+ IN UINTN SourceY, | |
+ IN UINTN DestinationX, | |
+ IN UINTN DestinationY, | |
+ IN UINTN Width, | |
+ IN UINTN Height, | |
+ IN UINTN Delta | |
+ ) | |
+{ | |
+ BIOS_VIDEO_DEV *BiosVideoPrivate; | |
+ BIOS_VIDEO_MODE_DATA *Mode; | |
+ | |
+ if (This == NULL) { | |
+ return EFI_INVALID_PARAMETER; | |
+ } | |
+ | |
+ BiosVideoPrivate = BIOS_VIDEO_DEV_FROM_GRAPHICS_OUTPUT_THIS (This); | |
+ Mode = &BiosVideoPrivate->ModeData[This->Mode->Mode]; | |
+ | |
+ return BiosVideoVbeBltWorker ( | |
+ BiosVideoPrivate, | |
+ BltBuffer, | |
+ BltOperation, | |
+ SourceX, | |
+ SourceY, | |
+ DestinationX, | |
+ DestinationY, | |
+ Width, | |
+ Height, | |
+ Delta, | |
+ Mode | |
+ ); | |
+} | |
+ | |
+/** | |
+ Write graphics controller registers. | |
+ | |
+ @param PciIo Pointer to PciIo protocol instance of the | |
+ controller | |
+ @param Address Register address | |
+ @param Data Data to be written to register | |
+ | |
+ @return None | |
+ | |
+**/ | |
+VOID | |
+WriteGraphicsController ( | |
+ IN EFI_PCI_IO_PROTOCOL *PciIo, | |
+ IN UINTN Address, | |
+ IN UINTN Data | |
+ ) | |
+{ | |
+ Address = Address | (Data << 8); | |
+ PciIo->Io.Write ( | |
+ PciIo, | |
+ EfiPciIoWidthUint16, | |
+ EFI_PCI_IO_PASS_THROUGH_BAR, | |
+ VGA_GRAPHICS_CONTROLLER_ADDRESS_REGISTER, | |
+ 1, | |
+ &Address | |
+ ); | |
+} | |
+ | |
+ | |
+/** | |
+ Read the four bit plane of VGA frame buffer. | |
+ | |
+ @param PciIo Pointer to PciIo protocol instance of the | |
+ controller | |
+ @param HardwareBuffer Hardware VGA frame buffer address | |
+ @param MemoryBuffer Memory buffer address | |
+ @param WidthInBytes Number of bytes in a line to read | |
+ @param Height Height of the area to read | |
+ | |
+ @return None | |
+ | |
+**/ | |
+VOID | |
+VgaReadBitPlanes ( | |
+ EFI_PCI_IO_PROTOCOL *PciIo, | |
+ UINT8 *HardwareBuffer, | |
+ UINT8 *MemoryBuffer, | |
+ UINTN WidthInBytes, | |
+ UINTN Height | |
+ ) | |
+{ | |
+ UINTN BitPlane; | |
+ UINTN Rows; | |
+ UINTN FrameBufferOffset; | |
+ UINT8 *Source; | |
+ UINT8 *Destination; | |
+ | |
+ // | |
+ // Program the Mode Register Write mode 0, Read mode 0 | |
+ // | |
+ WriteGraphicsController ( | |
+ PciIo, | |
+ VGA_GRAPHICS_CONTROLLER_MODE_REGISTER, | |
+ VGA_GRAPHICS_CONTROLLER_READ_MODE_0 | VGA_GRAPHICS_CONTROLLER_WRITE_MODE_0 | |
+ ); | |
+ | |
+ for (BitPlane = 0, FrameBufferOffset = 0; | |
+ BitPlane < VGA_NUMBER_OF_BIT_PLANES; | |
+ BitPlane++, FrameBufferOffset += VGA_BYTES_PER_BIT_PLANE | |
+ ) { | |
+ // | |
+ // Program the Read Map Select Register to select the correct bit plane | |
+ // | |
+ WriteGraphicsController ( | |
+ PciIo, | |
+ VGA_GRAPHICS_CONTROLLER_READ_MAP_SELECT_REGISTER, | |
+ BitPlane | |
+ ); | |
+ | |
+ Source = HardwareBuffer; | |
+ Destination = MemoryBuffer + FrameBufferOffset; | |
+ | |
+ for (Rows = 0; Rows < Height; Rows++, Source += VGA_BYTES_PER_SCAN_LINE, Destination += VGA_BYTES_PER_SCAN_LINE) { | |
+ PciIo->Mem.Read ( | |
+ PciIo, | |
+ EfiPciIoWidthUint8, | |
+ EFI_PCI_IO_PASS_THROUGH_BAR, | |
+ (UINT64) (UINTN) Source, | |
+ WidthInBytes, | |
+ (VOID *) Destination | |
+ ); | |
+ } | |
+ } | |
+} | |
+ | |
+ | |
+/** | |
+ Internal routine to convert VGA color to Grahpics Output color. | |
+ | |
+ @param MemoryBuffer Buffer containing VGA color | |
+ @param CoordinateX The X coordinate of pixel on screen | |
+ @param CoordinateY The Y coordinate of pixel on screen | |
+ @param BltBuffer Buffer to contain converted Grahpics Output color | |
+ | |
+ @return None | |
+ | |
+**/ | |
+VOID | |
+VgaConvertToGraphicsOutputColor ( | |
+ UINT8 *MemoryBuffer, | |
+ UINTN CoordinateX, | |
+ UINTN CoordinateY, | |
+ EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer | |
+ ) | |
+{ | |
+ UINTN Mask; | |
+ UINTN Bit; | |
+ UINTN Color; | |
+ | |
+ MemoryBuffer += ((CoordinateY << 6) + (CoordinateY << 4) + (CoordinateX >> 3)); | |
+ Mask = mVgaBitMaskTable[CoordinateX & 0x07]; | |
+ for (Bit = 0x01, Color = 0; Bit < 0x10; Bit <<= 1, MemoryBuffer += VGA_BYTES_PER_BIT_PLANE) { | |
+ if ((*MemoryBuffer & Mask) != 0) { | |
+ Color |= Bit; | |
+ } | |
+ } | |
+ | |
+ *BltBuffer = mVgaColorToGraphicsOutputColor[Color]; | |
+} | |
+ | |
+/** | |
+ Internal routine to convert Grahpics Output color to VGA color. | |
+ | |
+ @param BltBuffer buffer containing Grahpics Output color | |
+ | |
+ @return Converted VGA color | |
+ | |
+**/ | |
+UINT8 | |
+VgaConvertColor ( | |
+ IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer | |
+ ) | |
+{ | |
+ UINT8 Color; | |
+ | |
+ Color = (UINT8) ((BltBuffer->Blue >> 7) | ((BltBuffer->Green >> 6) & 0x02) | ((BltBuffer->Red >> 5) & 0x04)); | |
+ if ((BltBuffer->Red + BltBuffer->Green + BltBuffer->Blue) > 0x180) { | |
+ Color |= 0x08; | |
+ } | |
+ | |
+ return Color; | |
+} | |
+ | |
+ | |
+/** | |
+ Grahpics Output protocol instance to block transfer for VGA device. | |
+ | |
+ @param This Pointer to Grahpics Output protocol instance | |
+ @param BltBuffer The data to transfer to screen | |
+ @param BltOperation The operation to perform | |
+ @param SourceX The X coordinate of the source for BltOperation | |
+ @param SourceY The Y coordinate of the source for BltOperation | |
+ @param DestinationX The X coordinate of the destination for | |
+ BltOperation | |
+ @param DestinationY The Y coordinate of the destination for | |
+ BltOperation | |
+ @param Width The width of a rectangle in the blt rectangle in | |
+ pixels | |
+ @param Height The height of a rectangle in the blt rectangle in | |
+ pixels | |
+ @param Delta Not used for EfiBltVideoFill and | |
+ EfiBltVideoToVideo operation. If a Delta of 0 is | |
+ used, the entire BltBuffer will be operated on. If | |
+ a subrectangle of the BltBuffer is used, then | |
+ Delta represents the number of bytes in a row of | |
+ the BltBuffer. | |
+ | |
+ @retval EFI_INVALID_PARAMETER Invalid parameter passed in | |
+ @retval EFI_SUCCESS Blt operation success | |
+ | |
+**/ | |
+EFI_STATUS | |
+EFIAPI | |
+BiosVideoGraphicsOutputVgaBlt ( | |
+ IN EFI_GRAPHICS_OUTPUT_PROTOCOL *This, | |
+ IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer, OPTIONAL | |
+ IN EFI_GRAPHICS_OUTPUT_BLT_OPERATION BltOperation, | |
+ IN UINTN SourceX, | |
+ IN UINTN SourceY, | |
+ IN UINTN DestinationX, | |
+ IN UINTN DestinationY, | |
+ IN UINTN Width, | |
+ IN UINTN Height, | |
+ IN UINTN Delta | |
+ ) | |
+{ | |
+ BIOS_VIDEO_DEV *BiosVideoPrivate; | |
+ EFI_TPL OriginalTPL; | |
+ UINT8 *MemAddress; | |
+ UINTN BytesPerScanLine; | |
+ UINTN Bit; | |
+ UINTN Index; | |
+ UINTN Index1; | |
+ UINTN StartAddress; | |
+ UINTN Bytes; | |
+ UINTN Offset; | |
+ UINT8 LeftMask; | |
+ UINT8 RightMask; | |
+ UINTN Address; | |
+ UINTN AddressFix; | |
+ UINT8 *Address1; | |
+ UINT8 *SourceAddress; | |
+ UINT8 *DestinationAddress; | |
+ EFI_PCI_IO_PROTOCOL *PciIo; | |
+ UINT8 Data; | |
+ UINT8 PixelColor; | |
+ UINT8 *VgaFrameBuffer; | |
+ UINTN SourceOffset; | |
+ UINTN SourceWidth; | |
+ UINTN Rows; | |
+ UINTN Columns; | |
+ UINTN CoordinateX; | |
+ UINTN CoordinateY; | |
+ UINTN CurrentMode; | |
+ | |
+ if (This == NULL || ((UINTN) BltOperation) >= EfiGraphicsOutputBltOperationMax) { | |
+ return EFI_INVALID_PARAMETER; | |
+ } | |
+ | |
+ BiosVideoPrivate = BIOS_VIDEO_DEV_FROM_GRAPHICS_OUTPUT_THIS (This); | |
+ | |
+ CurrentMode = This->Mode->Mode; | |
+ PciIo = BiosVideoPrivate->PciIo; | |
+ MemAddress = BiosVideoPrivate->ModeData[CurrentMode].LinearFrameBuffer; | |
+ BytesPerScanLine = BiosVideoPrivate->ModeData[CurrentMode].BytesPerScanLine >> 3; | |
+ VgaFrameBuffer = BiosVideoPrivate->VgaFrameBuffer; | |
+ | |
+ | |
+ if (Width == 0 || Height == 0) { | |
+ return EFI_INVALID_PARAMETER; | |
+ } | |
+ // | |
+ // We need to fill the Virtual Screen buffer with the blt data. | |
+ // The virtual screen is upside down, as the first row is the bootom row of | |
+ // the image. | |
+ // | |
+ if (BltOperation == EfiBltVideoToBltBuffer) { | |
+ // | |
+ // Video to BltBuffer: Source is Video, destination is BltBuffer | |
+ // | |
+ if (SourceY + Height > BiosVideoPrivate->ModeData[CurrentMode].VerticalResolution) { | |
+ return EFI_INVALID_PARAMETER; | |
+ } | |
+ | |
+ if (SourceX + Width > BiosVideoPrivate->ModeData[CurrentMode].HorizontalResolution) { | |
+ return EFI_INVALID_PARAMETER; | |
+ } | |
+ } else { | |
+ // | |
+ // BltBuffer to Video: Source is BltBuffer, destination is Video | |
+ // | |
+ if (DestinationY + Height > BiosVideoPrivate->ModeData[CurrentMode].VerticalResolution) { | |
+ return EFI_INVALID_PARAMETER; | |
+ } | |
+ | |
+ if (DestinationX + Width > BiosVideoPrivate->ModeData[CurrentMode].HorizontalResolution) { | |
+ return EFI_INVALID_PARAMETER; | |
+ } | |
+ } | |
+ // | |
+ // If Delta is zero, then the entire BltBuffer is being used, so Delta | |
+ // is the number of bytes in each row of BltBuffer. Since BltBuffer is Width pixels size, | |
+ // the number of bytes in each row can be computed. | |
+ // | |
+ if (Delta == 0) { | |
+ Delta = Width * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL); | |
+ } | |
+ // | |
+ // We have to raise to TPL Notify, so we make an atomic write the frame buffer. | |
+ // We would not want a timer based event (Cursor, ...) to come in while we are | |
+ // doing this operation. | |
+ // | |
+ OriginalTPL = gBS->RaiseTPL (TPL_NOTIFY); | |
+ | |
+ // | |
+ // Compute some values we need for VGA | |
+ // | |
+ switch (BltOperation) { | |
+ case EfiBltVideoToBltBuffer: | |
+ | |
+ SourceOffset = (SourceY << 6) + (SourceY << 4) + (SourceX >> 3); | |
+ SourceWidth = ((SourceX + Width - 1) >> 3) - (SourceX >> 3) + 1; | |
+ | |
+ // | |
+ // Read all the pixels in the 4 bit planes into a memory buffer that looks like the VGA buffer | |
+ // | |
+ VgaReadBitPlanes ( | |
+ PciIo, | |
+ MemAddress + SourceOffset, | |
+ VgaFrameBuffer + SourceOffset, | |
+ SourceWidth, | |
+ Height | |
+ ); | |
+ | |
+ // | |
+ // Convert VGA Bit Planes to a Graphics Output 32-bit color value | |
+ // | |
+ BltBuffer += (DestinationY * (Delta >> 2) + DestinationX); | |
+ for (Rows = 0, CoordinateY = SourceY; Rows < Height; Rows++, CoordinateY++, BltBuffer += (Delta >> 2)) { | |
+ for (Columns = 0, CoordinateX = SourceX; Columns < Width; Columns++, CoordinateX++, BltBuffer++) { | |
+ VgaConvertToGraphicsOutputColor (VgaFrameBuffer, CoordinateX, CoordinateY, BltBuffer); | |
+ } | |
+ | |
+ BltBuffer -= Width; | |
+ } | |
+ | |
+ break; | |
+ | |
+ case EfiBltVideoToVideo: | |
+ // | |
+ // Check for an aligned Video to Video operation | |
+ // | |
+ if ((SourceX & 0x07) == 0x00 && (DestinationX & 0x07) == 0x00 && (Width & 0x07) == 0x00) { | |
+ // | |
+ // Program the Mode Register Write mode 1, Read mode 0 | |
+ // | |
+ WriteGraphicsController ( | |
+ PciIo, | |
+ VGA_GRAPHICS_CONTROLLER_MODE_REGISTER, | |
+ VGA_GRAPHICS_CONTROLLER_READ_MODE_0 | VGA_GRAPHICS_CONTROLLER_WRITE_MODE_1 | |
+ ); | |
+ | |
+ SourceAddress = (UINT8 *) (MemAddress + (SourceY << 6) + (SourceY << 4) + (SourceX >> 3)); | |
+ DestinationAddress = (UINT8 *) (MemAddress + (DestinationY << 6) + (DestinationY << 4) + (DestinationX >> 3)); | |
+ Bytes = Width >> 3; | |
+ for (Index = 0, Offset = 0; Index < Height; Index++, Offset += BytesPerScanLine) { | |
+ PciIo->CopyMem ( | |
+ PciIo, | |
+ EfiPciIoWidthUint8, | |
+ EFI_PCI_IO_PASS_THROUGH_BAR, | |
+ (UINT64) (UINTN) (DestinationAddress + Offset), | |
+ EFI_PCI_IO_PASS_THROUGH_BAR, | |
+ (UINT64) (UINTN) (SourceAddress + Offset), | |
+ Bytes | |
+ ); | |
+ } | |
+ } else { | |
+ SourceOffset = (SourceY << 6) + (SourceY << 4) + (SourceX >> 3); | |
+ SourceWidth = ((SourceX + Width - 1) >> 3) - (SourceX >> 3) + 1; | |
+ | |
+ // | |
+ // Read all the pixels in the 4 bit planes into a memory buffer that looks like the VGA buffer | |
+ // | |
+ VgaReadBitPlanes ( | |
+ PciIo, | |
+ MemAddress + SourceOffset, | |
+ VgaFrameBuffer + SourceOffset, | |
+ SourceWidth, | |
+ Height | |
+ ); | |
+ } | |
+ | |
+ break; | |
+ | |
+ case EfiBltVideoFill: | |
+ StartAddress = (UINTN) (MemAddress + (DestinationY << 6) + (DestinationY << 4) + (DestinationX >> 3)); | |
+ Bytes = ((DestinationX + Width - 1) >> 3) - (DestinationX >> 3); | |
+ LeftMask = mVgaLeftMaskTable[DestinationX & 0x07]; | |
+ RightMask = mVgaRightMaskTable[(DestinationX + Width - 1) & 0x07]; | |
+ if (Bytes == 0) { | |
+ LeftMask = (UINT8) (LeftMask & RightMask); | |
+ RightMask = 0; | |
+ } | |
+ | |
+ if (LeftMask == 0xff) { | |
+ StartAddress--; | |
+ Bytes++; | |
+ LeftMask = 0; | |
+ } | |
+ | |
+ if (RightMask == 0xff) { | |
+ Bytes++; | |
+ RightMask = 0; | |
+ } | |
+ | |
+ PixelColor = VgaConvertColor (BltBuffer); | |
+ | |
+ // | |
+ // Program the Mode Register Write mode 2, Read mode 0 | |
+ // | |
+ WriteGraphicsController ( | |
+ PciIo, | |
+ VGA_GRAPHICS_CONTROLLER_MODE_REGISTER, | |
+ VGA_GRAPHICS_CONTROLLER_READ_MODE_0 | VGA_GRAPHICS_CONTROLLER_WRITE_MODE_2 | |
+ ); | |
+ | |
+ // | |
+ // Program the Data Rotate/Function Select Register to replace | |
+ // | |
+ WriteGraphicsController ( | |
+ PciIo, | |
+ VGA_GRAPHICS_CONTROLLER_DATA_ROTATE_REGISTER, | |
+ VGA_GRAPHICS_CONTROLLER_FUNCTION_REPLACE | |
+ ); | |
+ | |
+ if (LeftMask != 0) { | |
+ // | |
+ // Program the BitMask register with the Left column mask | |
+ // | |
+ WriteGraphicsController ( | |
+ PciIo, | |
+ VGA_GRAPHICS_CONTROLLER_BIT_MASK_REGISTER, | |
+ LeftMask | |
+ ); | |
+ | |
+ for (Index = 0, Address = StartAddress; Index < Height; Index++, Address += BytesPerScanLine) { | |
+ // | |
+ // Read data from the bit planes into the latches | |
+ // | |
+ PciIo->Mem.Read ( | |
+ PciIo, | |
+ EfiPciIoWidthUint8, | |
+ EFI_PCI_IO_PASS_THROUGH_BAR, | |
+ (UINT64) (UINTN) Address, | |
+ 1, | |
+ &Data | |
+ ); | |
+ // | |
+ // Write the lower 4 bits of PixelColor to the bit planes in the pixels enabled by BitMask | |
+ // | |
+ PciIo->Mem.Write ( | |
+ PciIo, | |
+ EfiPciIoWidthUint8, | |
+ EFI_PCI_IO_PASS_THROUGH_BAR, | |
+ (UINT64) (UINTN) Address, | |
+ 1, | |
+ &PixelColor | |
+ ); | |
+ } | |
+ } | |
+ | |
+ if (Bytes > 1) { | |
+ // | |
+ // Program the BitMask register with the middle column mask of 0xff | |
+ // | |
+ WriteGraphicsController ( | |
+ PciIo, | |
+ VGA_GRAPHICS_CONTROLLER_BIT_MASK_REGISTER, | |
+ 0xff | |
+ ); | |
+ | |
+ for (Index = 0, Address = StartAddress + 1; Index < Height; Index++, Address += BytesPerScanLine) { | |
+ PciIo->Mem.Write ( | |
+ PciIo, | |
+ EfiPciIoWidthFillUint8, | |
+ EFI_PCI_IO_PASS_THROUGH_BAR, | |
+ (UINT64) (UINTN) Address, | |
+ Bytes - 1, | |
+ &PixelColor | |
+ ); | |
+ } | |
+ } | |
+ | |
+ if (RightMask != 0) { | |
+ // | |
+ // Program the BitMask register with the Right column mask | |
+ // | |
+ WriteGraphicsController ( | |
+ PciIo, | |
+ VGA_GRAPHICS_CONTROLLER_BIT_MASK_REGISTER, | |
+ RightMask | |
+ ); | |
+ | |
+ for (Index = 0, Address = StartAddress + Bytes; Index < Height; Index++, Address += BytesPerScanLine) { | |
+ // | |
+ // Read data from the bit planes into the latches | |
+ // | |
+ PciIo->Mem.Read ( | |
+ PciIo, | |
+ EfiPciIoWidthUint8, | |
+ EFI_PCI_IO_PASS_THROUGH_BAR, | |
+ (UINT64) (UINTN) Address, | |
+ 1, | |
+ &Data | |
+ ); | |
+ // | |
+ // Write the lower 4 bits of PixelColor to the bit planes in the pixels enabled by BitMask | |
+ // | |
+ PciIo->Mem.Write ( | |
+ PciIo, | |
+ EfiPciIoWidthUint8, | |
+ EFI_PCI_IO_PASS_THROUGH_BAR, | |
+ (UINT64) (UINTN) Address, | |
+ 1, | |
+ &PixelColor | |
+ ); | |
+ } | |
+ } | |
+ break; | |
+ | |
+ case EfiBltBufferToVideo: | |
+ StartAddress = (UINTN) (MemAddress + (DestinationY << 6) + (DestinationY << 4) + (DestinationX >> 3)); | |
+ LeftMask = mVgaBitMaskTable[DestinationX & 0x07]; | |
+ | |
+ // | |
+ // Program the Mode Register Write mode 2, Read mode 0 | |
+ // | |
+ WriteGraphicsController ( | |
+ PciIo, | |
+ VGA_GRAPHICS_CONTROLLER_MODE_REGISTER, | |
+ VGA_GRAPHICS_CONTROLLER_READ_MODE_0 | VGA_GRAPHICS_CONTROLLER_WRITE_MODE_2 | |
+ ); | |
+ | |
+ // | |
+ // Program the Data Rotate/Function Select Register to replace | |
+ // | |
+ WriteGraphicsController ( | |
+ PciIo, | |
+ VGA_GRAPHICS_CONTROLLER_DATA_ROTATE_REGISTER, | |
+ VGA_GRAPHICS_CONTROLLER_FUNCTION_REPLACE | |
+ ); | |
+ | |
+ for (Index = 0, Address = StartAddress; Index < Height; Index++, Address += BytesPerScanLine) { | |
+ for (Index1 = 0; Index1 < Width; Index1++) { | |
+ BiosVideoPrivate->LineBuffer[Index1] = VgaConvertColor (&BltBuffer[(SourceY + Index) * (Delta >> 2) + SourceX + Index1]); | |
+ } | |
+ AddressFix = Address; | |
+ | |
+ for (Bit = 0; Bit < 8; Bit++) { | |
+ // | |
+ // Program the BitMask register with the Left column mask | |
+ // | |
+ WriteGraphicsController ( | |
+ PciIo, | |
+ VGA_GRAPHICS_CONTROLLER_BIT_MASK_REGISTER, | |
+ LeftMask | |
+ ); | |
+ | |
+ for (Index1 = Bit, Address1 = (UINT8 *) AddressFix; Index1 < Width; Index1 += 8, Address1++) { | |
+ // | |
+ // Read data from the bit planes into the latches | |
+ // | |
+ PciIo->Mem.Read ( | |
+ PciIo, | |
+ EfiPciIoWidthUint8, | |
+ EFI_PCI_IO_PASS_THROUGH_BAR, | |
+ (UINT64) (UINTN) Address1, | |
+ 1, | |
+ &Data | |
+ ); | |
+ | |
+ PciIo->Mem.Write ( | |
+ PciIo, | |
+ EfiPciIoWidthUint8, | |
+ EFI_PCI_IO_PASS_THROUGH_BAR, | |
+ (UINT64) (UINTN) Address1, | |
+ 1, | |
+ &BiosVideoPrivate->LineBuffer[Index1] | |
+ ); | |
+ } | |
+ | |
+ LeftMask = (UINT8) (LeftMask >> 1); | |
+ if (LeftMask == 0) { | |
+ LeftMask = 0x80; | |
+ AddressFix++; | |
+ } | |
+ } | |
+ } | |
+ | |
+ break; | |
+ | |
+ default: ; | |
+ } | |
+ | |
+ gBS->RestoreTPL (OriginalTPL); | |
+ | |
+ return EFI_SUCCESS; | |
+} | |
+ | |
+// | |
+// VGA Mini Port Protocol Functions | |
+// | |
+ | |
+/** | |
+ VgaMiniPort protocol interface to set mode. | |
+ | |
+ @param This Pointer to VgaMiniPort protocol instance | |
+ @param ModeNumber The index of the mode | |
+ | |
+ @retval EFI_UNSUPPORTED The requested mode is not supported | |
+ @retval EFI_SUCCESS The requested mode is set successfully | |
+ | |
+**/ | |
+EFI_STATUS | |
+EFIAPI | |
+BiosVideoVgaMiniPortSetMode ( | |
+ IN EFI_VGA_MINI_PORT_PROTOCOL *This, | |
+ IN UINTN ModeNumber | |
+ ) | |
+{ | |
+ BIOS_VIDEO_DEV *BiosVideoPrivate; | |
+ EFI_IA32_REGISTER_SET Regs; | |
+ | |
+ if (This == NULL) { | |
+ return EFI_INVALID_PARAMETER; | |
+ } | |
+ | |
+ // | |
+ // Make sure the ModeNumber is a valid value | |
+ // | |
+ if (ModeNumber >= This->MaxMode) { | |
+ return EFI_UNSUPPORTED; | |
+ } | |
+ // | |
+ // Get the device structure for this device | |
+ // | |
+ BiosVideoPrivate = BIOS_VIDEO_DEV_FROM_VGA_MINI_PORT_THIS (This); | |
+ | |
+ switch (ModeNumber) { | |
+ case 0: | |
+ // | |
+ // Set the 80x25 Text VGA Mode | |
+ // | |
+ Regs.H.AH = 0x00; | |
+ Regs.H.AL = 0x83; | |
+ BiosVideoPrivate->LegacyBios->Int86 (BiosVideoPrivate->LegacyBios, 0x10, &Regs); | |
+ | |
+ Regs.H.AH = 0x11; | |
+ Regs.H.AL = 0x14; | |
+ Regs.H.BL = 0; | |
+ BiosVideoPrivate->LegacyBios->Int86 (BiosVideoPrivate->LegacyBios, 0x10, &Regs); | |
+ break; | |
+ | |
+ case 1: | |
+ // | |
+ // Set the 80x50 Text VGA Mode | |
+ // | |
+ Regs.H.AH = 0x00; | |
+ Regs.H.AL = 0x83; | |
+ BiosVideoPrivate->LegacyBios->Int86 (BiosVideoPrivate->LegacyBios, 0x10, &Regs); | |
+ Regs.H.AH = 0x11; | |
+ Regs.H.AL = 0x12; | |
+ Regs.H.BL = 0; | |
+ BiosVideoPrivate->LegacyBios->Int86 (BiosVideoPrivate->LegacyBios, 0x10, &Regs); | |
+ break; | |
+ | |
+ default: | |
+ return EFI_UNSUPPORTED; | |
+ } | |
+ | |
+ return EFI_SUCCESS; | |
+} | |
+ | |
+/** | |
+ Event handler for Exit Boot Service. | |
+ | |
+ @param Event The event that be siganlled when exiting boot service. | |
+ @param Context Pointer to instance of BIOS_VIDEO_DEV. | |
+ | |
+**/ | |
+VOID | |
+EFIAPI | |
+BiosVideoNotifyExitBootServices ( | |
+ IN EFI_EVENT Event, | |
+ IN VOID *Context | |
+ ) | |
+{ | |
+ BIOS_VIDEO_DEV *BiosVideoPrivate; | |
+ EFI_IA32_REGISTER_SET Regs; | |
+ | |
+ BiosVideoPrivate = (BIOS_VIDEO_DEV *)Context; | |
+ | |
+ // | |
+ // Set the 80x25 Text VGA Mode | |
+ // | |
+ Regs.H.AH = 0x00; | |
+ Regs.H.AL = 0x03; | |
+ BiosVideoPrivate->LegacyBios->Int86 (BiosVideoPrivate->LegacyBios, 0x10, &Regs); | |
+ | |
+ Regs.H.AH = 0x00; | |
+ Regs.H.AL = 0x83; | |
+ BiosVideoPrivate->LegacyBios->Int86 (BiosVideoPrivate->LegacyBios, 0x10, &Regs); | |
+ | |
+ Regs.H.AH = 0x11; | |
+ Regs.H.AL = 0x04; | |
+ Regs.H.BL = 0; | |
+ BiosVideoPrivate->LegacyBios->Int86 (BiosVideoPrivate->LegacyBios, 0x10, &Regs); | |
+} | |
+ | |
+/** | |
+ The user Entry Point for module UefiBiosVideo. 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. | |
+ | |
+**/ | |
+EFI_STATUS | |
+EFIAPI | |
+BiosVideoEntryPoint( | |
+ IN EFI_HANDLE ImageHandle, | |
+ IN EFI_SYSTEM_TABLE *SystemTable | |
+ ) | |
+{ | |
+ EFI_STATUS Status; | |
+ | |
+ // | |
+ // Install driver model protocol(s). | |
+ // | |
+ Status = EfiLibInstallDriverBindingComponentName2 ( | |
+ ImageHandle, | |
+ SystemTable, | |
+ &gBiosVideoDriverBinding, | |
+ ImageHandle, | |
+ &gBiosVideoComponentName, | |
+ &gBiosVideoComponentName2 | |
+ ); | |
+ ASSERT_EFI_ERROR (Status); | |
+ | |
+ // | |
+ // Install Legacy BIOS GUID to mark this driver as a BIOS Thunk Driver | |
+ // | |
+ return gBS->InstallMultipleProtocolInterfaces ( | |
+ &ImageHandle, | |
+ &gEfiLegacyBiosGuid, | |
+ NULL, | |
+ NULL | |
+ ); | |
+} | |
+ | |
diff --git a/OvmfPkg/CsmOld/VideoDxe/ComponentName.c b/OvmfPkg/CsmOld/VideoDxe/ComponentName.c | |
new file mode 100644 | |
index 000000000000..d9bd0a923855 | |
--- /dev/null | |
+++ b/OvmfPkg/CsmOld/VideoDxe/ComponentName.c | |
@@ -0,0 +1,313 @@ | |
+/** @file | |
+ | |
+Copyright (c) 2006 - 2011, 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. | |
+ | |
+**/ | |
+ | |
+#include "BiosVideo.h" | |
+ | |
+// | |
+// EFI Component Name Functions | |
+// | |
+/** | |
+ Retrieves a Unicode string that is the user readable name of the driver. | |
+ | |
+ This function retrieves the user readable name of a driver in the form of a | |
+ Unicode string. If the driver specified by This has a user readable name in | |
+ the language specified by Language, then a pointer to the driver name is | |
+ returned in DriverName, and EFI_SUCCESS is returned. If the driver specified | |
+ by This does not support the language specified by Language, | |
+ then EFI_UNSUPPORTED is returned. | |
+ | |
+ @param This[in] A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or | |
+ EFI_COMPONENT_NAME_PROTOCOL instance. | |
+ | |
+ @param Language[in] A pointer to a Null-terminated ASCII string | |
+ array indicating the language. This is the | |
+ language of the driver name that the caller is | |
+ requesting, and it must match one of the | |
+ languages specified in SupportedLanguages. The | |
+ number of languages supported by a driver is up | |
+ to the driver writer. Language is specified | |
+ in RFC 4646 or ISO 639-2 language code format. | |
+ | |
+ @param DriverName[out] A pointer to the Unicode string to return. | |
+ This Unicode string is the name of the | |
+ driver specified by This in the language | |
+ specified by Language. | |
+ | |
+ @retval EFI_SUCCESS The Unicode string for the Driver specified by | |
+ This and the language specified by Language was | |
+ returned in DriverName. | |
+ | |
+ @retval EFI_INVALID_PARAMETER Language is NULL. | |
+ | |
+ @retval EFI_INVALID_PARAMETER DriverName is NULL. | |
+ | |
+ @retval EFI_UNSUPPORTED The driver specified by This does not support | |
+ the language specified by Language. | |
+ | |
+**/ | |
+EFI_STATUS | |
+EFIAPI | |
+BiosVideoComponentNameGetDriverName ( | |
+ IN EFI_COMPONENT_NAME_PROTOCOL *This, | |
+ IN CHAR8 *Language, | |
+ OUT CHAR16 **DriverName | |
+ ); | |
+ | |
+ | |
+/** | |
+ Retrieves a Unicode string that is the user readable name of the controller | |
+ that is being managed by a driver. | |
+ | |
+ This function retrieves the user readable name of the controller specified by | |
+ ControllerHandle and ChildHandle in the form of a Unicode string. If the | |
+ driver specified by This has a user readable name in the language specified by | |
+ Language, then a pointer to the controller name is returned in ControllerName, | |
+ and EFI_SUCCESS is returned. If the driver specified by This is not currently | |
+ managing the controller specified by ControllerHandle and ChildHandle, | |
+ then EFI_UNSUPPORTED is returned. If the driver specified by This does not | |
+ support the language specified by Language, then EFI_UNSUPPORTED is returned. | |
+ | |
+ @param This[in] A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or | |
+ EFI_COMPONENT_NAME_PROTOCOL instance. | |
+ | |
+ @param ControllerHandle[in] The handle of a controller that the driver | |
+ specified by This is managing. This handle | |
+ specifies the controller whose name is to be | |
+ returned. | |
+ | |
+ @param ChildHandle[in] The handle of the child controller to retrieve | |
+ the name of. This is an optional parameter that | |
+ may be NULL. It will be NULL for device | |
+ drivers. It will also be NULL for a bus drivers | |
+ that wish to retrieve the name of the bus | |
+ controller. It will not be NULL for a bus | |
+ driver that wishes to retrieve the name of a | |
+ child controller. | |
+ | |
+ @param Language[in] A pointer to a Null-terminated ASCII string | |
+ array indicating the language. This is the | |
+ language of the driver name that the caller is | |
+ requesting, and it must match one of the | |
+ languages specified in SupportedLanguages. The | |
+ number of languages supported by a driver is up | |
+ to the driver writer. Language is specified in | |
+ RFC 4646 or ISO 639-2 language code format. | |
+ | |
+ @param ControllerName[out] A pointer to the Unicode string to return. | |
+ This Unicode string is the name of the | |
+ controller specified by ControllerHandle and | |
+ ChildHandle in the language specified by | |
+ Language from the point of view of the driver | |
+ specified by This. | |
+ | |
+ @retval EFI_SUCCESS The Unicode string for the user readable name in | |
+ the language specified by Language for the | |
+ driver specified by This was returned in | |
+ DriverName. | |
+ | |
+ @retval EFI_INVALID_PARAMETER ControllerHandle is NULL. | |
+ | |
+ @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid | |
+ EFI_HANDLE. | |
+ | |
+ @retval EFI_INVALID_PARAMETER Language is NULL. | |
+ | |
+ @retval EFI_INVALID_PARAMETER ControllerName is NULL. | |
+ | |
+ @retval EFI_UNSUPPORTED The driver specified by This is not currently | |
+ managing the controller specified by | |
+ ControllerHandle and ChildHandle. | |
+ | |
+ @retval EFI_UNSUPPORTED The driver specified by This does not support | |
+ the language specified by Language. | |
+ | |
+**/ | |
+EFI_STATUS | |
+EFIAPI | |
+BiosVideoComponentNameGetControllerName ( | |
+ IN EFI_COMPONENT_NAME_PROTOCOL *This, | |
+ IN EFI_HANDLE ControllerHandle, | |
+ IN EFI_HANDLE ChildHandle OPTIONAL, | |
+ IN CHAR8 *Language, | |
+ OUT CHAR16 **ControllerName | |
+ ); | |
+ | |
+ | |
+// | |
+// EFI Component Name Protocol | |
+// | |
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME_PROTOCOL gBiosVideoComponentName = { | |
+ BiosVideoComponentNameGetDriverName, | |
+ BiosVideoComponentNameGetControllerName, | |
+ "eng" | |
+}; | |
+ | |
+// | |
+// EFI Component Name 2 Protocol | |
+// | |
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME2_PROTOCOL gBiosVideoComponentName2 = { | |
+ (EFI_COMPONENT_NAME2_GET_DRIVER_NAME) BiosVideoComponentNameGetDriverName, | |
+ (EFI_COMPONENT_NAME2_GET_CONTROLLER_NAME) BiosVideoComponentNameGetControllerName, | |
+ "en" | |
+}; | |
+ | |
+ | |
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE mBiosVideoDriverNameTable[] = { | |
+ { | |
+ "eng;en", | |
+ L"BIOS[INT10] Video Driver" | |
+ }, | |
+ { | |
+ NULL, | |
+ NULL | |
+ } | |
+}; | |
+ | |
+/** | |
+ Retrieves a Unicode string that is the user readable name of the driver. | |
+ | |
+ This function retrieves the user readable name of a driver in the form of a | |
+ Unicode string. If the driver specified by This has a user readable name in | |
+ the language specified by Language, then a pointer to the driver name is | |
+ returned in DriverName, and EFI_SUCCESS is returned. If the driver specified | |
+ by This does not support the language specified by Language, | |
+ then EFI_UNSUPPORTED is returned. | |
+ | |
+ @param This[in] A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or | |
+ EFI_COMPONENT_NAME_PROTOCOL instance. | |
+ | |
+ @param Language[in] A pointer to a Null-terminated ASCII string | |
+ array indicating the language. This is the | |
+ language of the driver name that the caller is | |
+ requesting, and it must match one of the | |
+ languages specified in SupportedLanguages. The | |
+ number of languages supported by a driver is up | |
+ to the driver writer. Language is specified | |
+ in RFC 4646 or ISO 639-2 language code format. | |
+ | |
+ @param DriverName[out] A pointer to the Unicode string to return. | |
+ This Unicode string is the name of the | |
+ driver specified by This in the language | |
+ specified by Language. | |
+ | |
+ @retval EFI_SUCCESS The Unicode string for the Driver specified by | |
+ This and the language specified by Language was | |
+ returned in DriverName. | |
+ | |
+ @retval EFI_INVALID_PARAMETER Language is NULL. | |
+ | |
+ @retval EFI_INVALID_PARAMETER DriverName is NULL. | |
+ | |
+ @retval EFI_UNSUPPORTED The driver specified by This does not support | |
+ the language specified by Language. | |
+ | |
+**/ | |
+EFI_STATUS | |
+EFIAPI | |
+BiosVideoComponentNameGetDriverName ( | |
+ IN EFI_COMPONENT_NAME_PROTOCOL *This, | |
+ IN CHAR8 *Language, | |
+ OUT CHAR16 **DriverName | |
+ ) | |
+{ | |
+ return LookupUnicodeString2 ( | |
+ Language, | |
+ This->SupportedLanguages, | |
+ mBiosVideoDriverNameTable, | |
+ DriverName, | |
+ (BOOLEAN)(This == &gBiosVideoComponentName) | |
+ ); | |
+} | |
+ | |
+/** | |
+ Retrieves a Unicode string that is the user readable name of the controller | |
+ that is being managed by a driver. | |
+ | |
+ This function retrieves the user readable name of the controller specified by | |
+ ControllerHandle and ChildHandle in the form of a Unicode string. If the | |
+ driver specified by This has a user readable name in the language specified by | |
+ Language, then a pointer to the controller name is returned in ControllerName, | |
+ and EFI_SUCCESS is returned. If the driver specified by This is not currently | |
+ managing the controller specified by ControllerHandle and ChildHandle, | |
+ then EFI_UNSUPPORTED is returned. If the driver specified by This does not | |
+ support the language specified by Language, then EFI_UNSUPPORTED is returned. | |
+ | |
+ @param This[in] A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or | |
+ EFI_COMPONENT_NAME_PROTOCOL instance. | |
+ | |
+ @param ControllerHandle[in] The handle of a controller that the driver | |
+ specified by This is managing. This handle | |
+ specifies the controller whose name is to be | |
+ returned. | |
+ | |
+ @param ChildHandle[in] The handle of the child controller to retrieve | |
+ the name of. This is an optional parameter that | |
+ may be NULL. It will be NULL for device | |
+ drivers. It will also be NULL for a bus drivers | |
+ that wish to retrieve the name of the bus | |
+ controller. It will not be NULL for a bus | |
+ driver that wishes to retrieve the name of a | |
+ child controller. | |
+ | |
+ @param Language[in] A pointer to a Null-terminated ASCII string | |
+ array indicating the language. This is the | |
+ language of the driver name that the caller is | |
+ requesting, and it must match one of the | |
+ languages specified in SupportedLanguages. The | |
+ number of languages supported by a driver is up | |
+ to the driver writer. Language is specified in | |
+ RFC 4646 or ISO 639-2 language code format. | |
+ | |
+ @param ControllerName[out] A pointer to the Unicode string to return. | |
+ This Unicode string is the name of the | |
+ controller specified by ControllerHandle and | |
+ ChildHandle in the language specified by | |
+ Language from the point of view of the driver | |
+ specified by This. | |
+ | |
+ @retval EFI_SUCCESS The Unicode string for the user readable name in | |
+ the language specified by Language for the | |
+ driver specified by This was returned in | |
+ DriverName. | |
+ | |
+ @retval EFI_INVALID_PARAMETER ControllerHandle is NULL. | |
+ | |
+ @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid | |
+ EFI_HANDLE. | |
+ | |
+ @retval EFI_INVALID_PARAMETER Language is NULL. | |
+ | |
+ @retval EFI_INVALID_PARAMETER ControllerName is NULL. | |
+ | |
+ @retval EFI_UNSUPPORTED The driver specified by This is not currently | |
+ managing the controller specified by | |
+ ControllerHandle and ChildHandle. | |
+ | |
+ @retval EFI_UNSUPPORTED The driver specified by This does not support | |
+ the language specified by Language. | |
+ | |
+**/ | |
+EFI_STATUS | |
+EFIAPI | |
+BiosVideoComponentNameGetControllerName ( | |
+ IN EFI_COMPONENT_NAME_PROTOCOL *This, | |
+ IN EFI_HANDLE ControllerHandle, | |
+ IN EFI_HANDLE ChildHandle OPTIONAL, | |
+ IN CHAR8 *Language, | |
+ OUT CHAR16 **ControllerName | |
+ ) | |
+{ | |
+ return EFI_UNSUPPORTED; | |
+} | |
diff --git a/OvmfPkg/GccBugReproducer/GccBugReproducer.c b/OvmfPkg/GccBugReproducer/GccBugReproducer.c | |
new file mode 100644 | |
index 000000000000..c3ebb202d136 | |
--- /dev/null | |
+++ b/OvmfPkg/GccBugReproducer/GccBugReproducer.c | |
@@ -0,0 +1,93 @@ | |
+/** @file | |
+ An application reproducing local variable corruption in recursive calls with | |
+ gcc-4.8 on the X64 target. | |
+ | |
+ Copyright (C) 2014, Red Hat, Inc. | |
+ Copyright (c) 2010 - 2011, 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. | |
+ | |
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, WITHOUT | |
+ WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. | |
+**/ | |
+#include <Uefi.h> | |
+#include <Library/UefiLib.h> | |
+#include <Library/ShellCEntryLib.h> | |
+ | |
+VOID | |
+EFIAPI | |
+PrintSeveralQuadruplets ( | |
+ IN UINT64 Dummy1, | |
+ IN UINT64 Dummy2, | |
+ IN UINT64 Dummy3, | |
+ IN BOOLEAN Recursive, | |
+ ... | |
+ ); | |
+ | |
+VOID | |
+EFIAPI | |
+Print4 ( | |
+ IN UINT64 Dummy1, | |
+ IN UINT64 Dummy2, | |
+ IN UINT64 Dummy3, | |
+ IN BOOLEAN Recursive, | |
+ IN VA_LIST Marker | |
+ ) | |
+{ | |
+ UINT64 Value1, Value2, Value3, Value4; | |
+ | |
+ do { | |
+ Value1 = VA_ARG (Marker, UINT64); | |
+ Value2 = VA_ARG (Marker, UINT64); | |
+ Value3 = VA_ARG (Marker, UINT64); | |
+ Value4 = VA_ARG (Marker, UINT64); | |
+ | |
+ if (!Recursive) { | |
+ AsciiPrint ("0x%02Lx 0x%02Lx 0x%02Lx 0x%02Lx\n", | |
+ Value1, Value2, Value3, Value4); | |
+ return; | |
+ } | |
+ PrintSeveralQuadruplets (Dummy1, Dummy2, Dummy3, FALSE, | |
+ Value1, Value2, Value3, Value4); | |
+ } while (Value4 != 0); | |
+} | |
+ | |
+VOID | |
+EFIAPI | |
+PrintSeveralQuadruplets ( | |
+ IN UINT64 Dummy1, | |
+ IN UINT64 Dummy2, | |
+ IN UINT64 Dummy3, | |
+ IN BOOLEAN Recursive, | |
+ ... | |
+ ) | |
+{ | |
+ VA_LIST Marker; | |
+ | |
+ VA_START (Marker, Recursive); | |
+ Print4 (Dummy1 + 1, Dummy2 + 2, Dummy3 + 3, Recursive, Marker); | |
+ VA_END (Marker); | |
+} | |
+ | |
+INTN | |
+EFIAPI | |
+ShellAppMain ( | |
+ IN UINTN Argc, | |
+ IN CHAR16 **Argv | |
+ ) | |
+{ | |
+ PrintSeveralQuadruplets (0, 0, 0, TRUE, | |
+ 0LLU, 1LLU, 2LLU, 3LLU, | |
+ 4LLU, 5LLU, 6LLU, 7LLU, | |
+ 8LLU, 9LLU, 10LLU, 11LLU, | |
+ 12LLU, 13LLU, 14LLU, 15LLU, | |
+ 16LLU, 17LLU, 18LLU, 19LLU, | |
+ 20LLU, 21LLU, 22LLU, 23LLU, | |
+ 24LLU, 25LLU, 26LLU, 27LLU, | |
+ 28LLU, 29LLU, 30LLU, 0LLU | |
+ ); | |
+ return 0; | |
+} | |
diff --git a/OvmfPkg/Library/PlatformBdsLib/BdsPlatform.c b/OvmfPkg/Library/PlatformBdsLib/BdsPlatform.c | |
new file mode 100644 | |
index 000000000000..3a17058a3b34 | |
--- /dev/null | |
+++ b/OvmfPkg/Library/PlatformBdsLib/BdsPlatform.c | |
@@ -0,0 +1,1579 @@ | |
+/** @file | |
+ Platform BDS customizations. | |
+ | |
+ Copyright (c) 2004 - 2014, 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. | |
+ | |
+**/ | |
+ | |
+#include "BdsPlatform.h" | |
+#include <Guid/RootBridgesConnectedEventGroup.h> | |
+#include <Library/QemuBootOrderLib.h> | |
+ | |
+#ifdef Q35 | |
+#define IS_PLATFORM_Q35 1 | |
+#else | |
+#define IS_PLATFORM_Q35 0 | |
+#endif | |
+// | |
+// Global data | |
+// | |
+ | |
+VOID *mEfiDevPathNotifyReg; | |
+EFI_EVENT mEfiDevPathEvent; | |
+VOID *mEmuVariableEventReg; | |
+EFI_EVENT mEmuVariableEvent; | |
+BOOLEAN mDetectVgaOnly; | |
+UINT16 mHostBridgeDevId; | |
+ | |
+// | |
+// Table of host IRQs matching PCI IRQs A-D | |
+// (for configuring PCI Interrupt Line register) | |
+// | |
+CONST UINT8 PciHostIrqs[] = { | |
+ 0x0a, 0x0a, 0x0b, 0x0b | |
+}; | |
+ | |
+// | |
+// Array Size macro | |
+// | |
+#define ARRAY_SIZE(array) (sizeof (array) / sizeof (array[0])) | |
+ | |
+// | |
+// Type definitions | |
+// | |
+ | |
+typedef | |
+EFI_STATUS | |
+(EFIAPI *PROTOCOL_INSTANCE_CALLBACK)( | |
+ IN EFI_HANDLE Handle, | |
+ IN VOID *Instance, | |
+ IN VOID *Context | |
+ ); | |
+ | |
+/** | |
+ @param[in] Handle - Handle of PCI device instance | |
+ @param[in] PciIo - PCI IO protocol instance | |
+ @param[in] Pci - PCI Header register block | |
+**/ | |
+typedef | |
+EFI_STATUS | |
+(EFIAPI *VISIT_PCI_INSTANCE_CALLBACK)( | |
+ IN EFI_HANDLE Handle, | |
+ IN EFI_PCI_IO_PROTOCOL *PciIo, | |
+ IN PCI_TYPE00 *Pci | |
+ ); | |
+ | |
+ | |
+// | |
+// Function prototypes | |
+// | |
+ | |
+EFI_STATUS | |
+VisitAllInstancesOfProtocol ( | |
+ IN EFI_GUID *Id, | |
+ IN PROTOCOL_INSTANCE_CALLBACK CallBackFunction, | |
+ IN VOID *Context | |
+ ); | |
+ | |
+EFI_STATUS | |
+VisitAllPciInstancesOfProtocol ( | |
+ IN VISIT_PCI_INSTANCE_CALLBACK CallBackFunction | |
+ ); | |
+ | |
+VOID | |
+InstallDevicePathCallback ( | |
+ VOID | |
+ ); | |
+ | |
+// | |
+// BDS Platform Functions | |
+// | |
+VOID | |
+EFIAPI | |
+PlatformBdsInit ( | |
+ VOID | |
+ ) | |
+/*++ | |
+ | |
+Routine Description: | |
+ | |
+ Platform Bds init. Incude the platform firmware vendor, revision | |
+ and so crc check. | |
+ | |
+Arguments: | |
+ | |
+Returns: | |
+ | |
+ None. | |
+ | |
+--*/ | |
+{ | |
+ DEBUG ((EFI_D_INFO, "PlatformBdsInit\n")); | |
+ InstallDevicePathCallback (); | |
+} | |
+ | |
+ | |
+EFI_STATUS | |
+EFIAPI | |
+ConnectRootBridge ( | |
+ IN EFI_HANDLE RootBridgeHandle, | |
+ IN VOID *Instance, | |
+ IN VOID *Context | |
+ ) | |
+{ | |
+ EFI_STATUS Status; | |
+ | |
+ // | |
+ // Make the PCI bus driver connect the root bridge, non-recursively. This | |
+ // will produce a number of child handles with PciIo on them. | |
+ // | |
+ Status = gBS->ConnectController ( | |
+ RootBridgeHandle, // ControllerHandle | |
+ NULL, // DriverImageHandle | |
+ NULL, // RemainingDevicePath -- produce all | |
+ // children | |
+ FALSE // Recursive | |
+ ); | |
+ return Status; | |
+ } | |
+ | |
+ | |
+EFI_STATUS | |
+PrepareLpcBridgeDevicePath ( | |
+ IN EFI_HANDLE DeviceHandle | |
+ ) | |
+/*++ | |
+ | |
+Routine Description: | |
+ | |
+ Add IsaKeyboard to ConIn, | |
+ add IsaSerial to ConOut, ConIn, ErrOut. | |
+ LPC Bridge: 06 01 00 | |
+ | |
+Arguments: | |
+ | |
+ DeviceHandle - Handle of PCIIO protocol. | |
+ | |
+Returns: | |
+ | |
+ EFI_SUCCESS - LPC bridge is added to ConOut, ConIn, and ErrOut. | |
+ EFI_STATUS - No LPC bridge is added. | |
+ | |
+--*/ | |
+{ | |
+ EFI_STATUS Status; | |
+ EFI_DEVICE_PATH_PROTOCOL *DevicePath; | |
+ EFI_DEVICE_PATH_PROTOCOL *TempDevicePath; | |
+ CHAR16 *DevPathStr; | |
+ | |
+ DevicePath = NULL; | |
+ Status = gBS->HandleProtocol ( | |
+ DeviceHandle, | |
+ &gEfiDevicePathProtocolGuid, | |
+ (VOID*)&DevicePath | |
+ ); | |
+ if (EFI_ERROR (Status)) { | |
+ return Status; | |
+ } | |
+ TempDevicePath = DevicePath; | |
+ | |
+ // | |
+ // Register Keyboard | |
+ // | |
+ DevicePath = AppendDevicePathNode (DevicePath, (EFI_DEVICE_PATH_PROTOCOL *)&gPnpPs2KeyboardDeviceNode); | |
+ | |
+ BdsLibUpdateConsoleVariable (VarConsoleInp, DevicePath, NULL); | |
+ | |
+ // | |
+ // Register COM1 | |
+ // | |
+ DevicePath = TempDevicePath; | |
+ gPnp16550ComPortDeviceNode.UID = 0; | |
+ | |
+ DevicePath = AppendDevicePathNode (DevicePath, (EFI_DEVICE_PATH_PROTOCOL *)&gPnp16550ComPortDeviceNode); | |
+ DevicePath = AppendDevicePathNode (DevicePath, (EFI_DEVICE_PATH_PROTOCOL *)&gUartDeviceNode); | |
+ DevicePath = AppendDevicePathNode (DevicePath, (EFI_DEVICE_PATH_PROTOCOL *)&gTerminalTypeDeviceNode); | |
+ | |
+ // | |
+ // Print Device Path | |
+ // | |
+ DevPathStr = DevicePathToStr(DevicePath); | |
+ if (DevPathStr != NULL) { | |
+ DEBUG(( | |
+ EFI_D_INFO, | |
+ "BdsPlatform.c+%d: COM%d DevPath: %s\n", | |
+ __LINE__, | |
+ gPnp16550ComPortDeviceNode.UID + 1, | |
+ DevPathStr | |
+ )); | |
+ FreePool(DevPathStr); | |
+ } | |
+ | |
+ BdsLibUpdateConsoleVariable (VarConsoleOut, DevicePath, NULL); | |
+ BdsLibUpdateConsoleVariable (VarConsoleInp, DevicePath, NULL); | |
+ BdsLibUpdateConsoleVariable (VarErrorOut, DevicePath, NULL); | |
+ | |
+ // | |
+ // Register COM2 | |
+ // | |
+ DevicePath = TempDevicePath; | |
+ gPnp16550ComPortDeviceNode.UID = 1; | |
+ | |
+ DevicePath = AppendDevicePathNode (DevicePath, (EFI_DEVICE_PATH_PROTOCOL *)&gPnp16550ComPortDeviceNode); | |
+ DevicePath = AppendDevicePathNode (DevicePath, (EFI_DEVICE_PATH_PROTOCOL *)&gUartDeviceNode); | |
+ DevicePath = AppendDevicePathNode (DevicePath, (EFI_DEVICE_PATH_PROTOCOL *)&gTerminalTypeDeviceNode); | |
+ | |
+ // | |
+ // Print Device Path | |
+ // | |
+ DevPathStr = DevicePathToStr(DevicePath); | |
+ if (DevPathStr != NULL) { | |
+ DEBUG(( | |
+ EFI_D_INFO, | |
+ "BdsPlatform.c+%d: COM%d DevPath: %s\n", | |
+ __LINE__, | |
+ gPnp16550ComPortDeviceNode.UID + 1, | |
+ DevPathStr | |
+ )); | |
+ FreePool(DevPathStr); | |
+ } | |
+ | |
+ BdsLibUpdateConsoleVariable (VarConsoleOut, DevicePath, NULL); | |
+ BdsLibUpdateConsoleVariable (VarConsoleInp, DevicePath, NULL); | |
+ BdsLibUpdateConsoleVariable (VarErrorOut, DevicePath, NULL); | |
+ | |
+ return EFI_SUCCESS; | |
+} | |
+ | |
+EFI_STATUS | |
+GetGopDevicePath ( | |
+ IN EFI_DEVICE_PATH_PROTOCOL *PciDevicePath, | |
+ OUT EFI_DEVICE_PATH_PROTOCOL **GopDevicePath | |
+ ) | |
+{ | |
+ UINTN Index; | |
+ EFI_STATUS Status; | |
+ EFI_HANDLE PciDeviceHandle; | |
+ EFI_DEVICE_PATH_PROTOCOL *TempDevicePath; | |
+ EFI_DEVICE_PATH_PROTOCOL *TempPciDevicePath; | |
+ UINTN GopHandleCount; | |
+ EFI_HANDLE *GopHandleBuffer; | |
+ | |
+ if (PciDevicePath == NULL || GopDevicePath == NULL) { | |
+ return EFI_INVALID_PARAMETER; | |
+ } | |
+ | |
+ // | |
+ // Initialize the GopDevicePath to be PciDevicePath | |
+ // | |
+ *GopDevicePath = PciDevicePath; | |
+ TempPciDevicePath = PciDevicePath; | |
+ | |
+ Status = gBS->LocateDevicePath ( | |
+ &gEfiDevicePathProtocolGuid, | |
+ &TempPciDevicePath, | |
+ &PciDeviceHandle | |
+ ); | |
+ if (EFI_ERROR (Status)) { | |
+ return Status; | |
+ } | |
+ | |
+ // | |
+ // Try to connect this handle, so that GOP dirver could start on this | |
+ // device and create child handles with GraphicsOutput Protocol installed | |
+ // on them, then we get device paths of these child handles and select | |
+ // them as possible console device. | |
+ // | |
+ gBS->ConnectController (PciDeviceHandle, NULL, NULL, FALSE); | |
+ | |
+ Status = gBS->LocateHandleBuffer ( | |
+ ByProtocol, | |
+ &gEfiGraphicsOutputProtocolGuid, | |
+ NULL, | |
+ &GopHandleCount, | |
+ &GopHandleBuffer | |
+ ); | |
+ if (!EFI_ERROR (Status)) { | |
+ // | |
+ // Add all the child handles as possible Console Device | |
+ // | |
+ for (Index = 0; Index < GopHandleCount; Index++) { | |
+ Status = gBS->HandleProtocol (GopHandleBuffer[Index], &gEfiDevicePathProtocolGuid, (VOID*)&TempDevicePath); | |
+ if (EFI_ERROR (Status)) { | |
+ continue; | |
+ } | |
+ if (CompareMem ( | |
+ PciDevicePath, | |
+ TempDevicePath, | |
+ GetDevicePathSize (PciDevicePath) - END_DEVICE_PATH_LENGTH | |
+ ) == 0) { | |
+ // | |
+ // In current implementation, we only enable one of the child handles | |
+ // as console device, i.e. sotre one of the child handle's device | |
+ // path to variable "ConOut" | |
+ // In futhure, we could select all child handles to be console device | |
+ // | |
+ | |
+ *GopDevicePath = TempDevicePath; | |
+ | |
+ // | |
+ // Delete the PCI device's path that added by GetPlugInPciVgaDevicePath() | |
+ // Add the integrity GOP device path. | |
+ // | |
+ BdsLibUpdateConsoleVariable (VarConsoleOutDev, NULL, PciDevicePath); | |
+ BdsLibUpdateConsoleVariable (VarConsoleOutDev, TempDevicePath, NULL); | |
+ } | |
+ } | |
+ gBS->FreePool (GopHandleBuffer); | |
+ } | |
+ | |
+ return EFI_SUCCESS; | |
+} | |
+ | |
+EFI_STATUS | |
+PreparePciVgaDevicePath ( | |
+ IN EFI_HANDLE DeviceHandle | |
+ ) | |
+/*++ | |
+ | |
+Routine Description: | |
+ | |
+ Add PCI VGA to ConOut. | |
+ PCI VGA: 03 00 00 | |
+ | |
+Arguments: | |
+ | |
+ DeviceHandle - Handle of PCIIO protocol. | |
+ | |
+Returns: | |
+ | |
+ EFI_SUCCESS - PCI VGA is added to ConOut. | |
+ EFI_STATUS - No PCI VGA device is added. | |
+ | |
+--*/ | |
+{ | |
+ EFI_STATUS Status; | |
+ EFI_DEVICE_PATH_PROTOCOL *DevicePath; | |
+ EFI_DEVICE_PATH_PROTOCOL *GopDevicePath; | |
+ | |
+ DevicePath = NULL; | |
+ GopDevicePath = NULL; | |
+ Status = gBS->HandleProtocol ( | |
+ DeviceHandle, | |
+ &gEfiDevicePathProtocolGuid, | |
+ (VOID*)&DevicePath | |
+ ); | |
+ if (EFI_ERROR (Status)) { | |
+ return Status; | |
+ } | |
+ | |
+ GetGopDevicePath (DevicePath, &GopDevicePath); | |
+ DevicePath = GopDevicePath; | |
+ | |
+ BdsLibUpdateConsoleVariable (VarConsoleOut, DevicePath, NULL); | |
+ | |
+ return EFI_SUCCESS; | |
+} | |
+ | |
+EFI_STATUS | |
+PreparePciSerialDevicePath ( | |
+ IN EFI_HANDLE DeviceHandle | |
+ ) | |
+/*++ | |
+ | |
+Routine Description: | |
+ | |
+ Add PCI Serial to ConOut, ConIn, ErrOut. | |
+ PCI Serial: 07 00 02 | |
+ | |
+Arguments: | |
+ | |
+ DeviceHandle - Handle of PCIIO protocol. | |
+ | |
+Returns: | |
+ | |
+ EFI_SUCCESS - PCI Serial is added to ConOut, ConIn, and ErrOut. | |
+ EFI_STATUS - No PCI Serial device is added. | |
+ | |
+--*/ | |
+{ | |
+ EFI_STATUS Status; | |
+ EFI_DEVICE_PATH_PROTOCOL *DevicePath; | |
+ | |
+ DevicePath = NULL; | |
+ Status = gBS->HandleProtocol ( | |
+ DeviceHandle, | |
+ &gEfiDevicePathProtocolGuid, | |
+ (VOID*)&DevicePath | |
+ ); | |
+ if (EFI_ERROR (Status)) { | |
+ return Status; | |
+ } | |
+ | |
+ DevicePath = AppendDevicePathNode (DevicePath, (EFI_DEVICE_PATH_PROTOCOL *)&gUartDeviceNode); | |
+ DevicePath = AppendDevicePathNode (DevicePath, (EFI_DEVICE_PATH_PROTOCOL *)&gTerminalTypeDeviceNode); | |
+ | |
+ BdsLibUpdateConsoleVariable (VarConsoleOut, DevicePath, NULL); | |
+ BdsLibUpdateConsoleVariable (VarConsoleInp, DevicePath, NULL); | |
+ BdsLibUpdateConsoleVariable (VarErrorOut, DevicePath, NULL); | |
+ | |
+ return EFI_SUCCESS; | |
+} | |
+ | |
+EFI_STATUS | |
+VisitAllInstancesOfProtocol ( | |
+ IN EFI_GUID *Id, | |
+ IN PROTOCOL_INSTANCE_CALLBACK CallBackFunction, | |
+ IN VOID *Context | |
+ ) | |
+{ | |
+ EFI_STATUS Status; | |
+ UINTN HandleCount; | |
+ EFI_HANDLE *HandleBuffer; | |
+ UINTN Index; | |
+ VOID *Instance; | |
+ | |
+ // | |
+ // Start to check all the PciIo to find all possible device | |
+ // | |
+ HandleCount = 0; | |
+ HandleBuffer = NULL; | |
+ Status = gBS->LocateHandleBuffer ( | |
+ ByProtocol, | |
+ Id, | |
+ NULL, | |
+ &HandleCount, | |
+ &HandleBuffer | |
+ ); | |
+ if (EFI_ERROR (Status)) { | |
+ return Status; | |
+ } | |
+ | |
+ for (Index = 0; Index < HandleCount; Index++) { | |
+ Status = gBS->HandleProtocol (HandleBuffer[Index], Id, &Instance); | |
+ if (EFI_ERROR (Status)) { | |
+ continue; | |
+ } | |
+ | |
+ Status = (*CallBackFunction) ( | |
+ HandleBuffer[Index], | |
+ Instance, | |
+ Context | |
+ ); | |
+ } | |
+ | |
+ gBS->FreePool (HandleBuffer); | |
+ | |
+ return EFI_SUCCESS; | |
+} | |
+ | |
+ | |
+EFI_STATUS | |
+EFIAPI | |
+VisitingAPciInstance ( | |
+ IN EFI_HANDLE Handle, | |
+ IN VOID *Instance, | |
+ IN VOID *Context | |
+ ) | |
+{ | |
+ EFI_STATUS Status; | |
+ EFI_PCI_IO_PROTOCOL *PciIo; | |
+ PCI_TYPE00 Pci; | |
+ | |
+ PciIo = (EFI_PCI_IO_PROTOCOL*) Instance; | |
+ | |
+ // | |
+ // Check for all PCI device | |
+ // | |
+ Status = PciIo->Pci.Read ( | |
+ PciIo, | |
+ EfiPciIoWidthUint32, | |
+ 0, | |
+ sizeof (Pci) / sizeof (UINT32), | |
+ &Pci | |
+ ); | |
+ if (EFI_ERROR (Status)) { | |
+ return Status; | |
+ } | |
+ | |
+ return (*(VISIT_PCI_INSTANCE_CALLBACK)(UINTN) Context) ( | |
+ Handle, | |
+ PciIo, | |
+ &Pci | |
+ ); | |
+ | |
+} | |
+ | |
+ | |
+ | |
+EFI_STATUS | |
+VisitAllPciInstances ( | |
+ IN VISIT_PCI_INSTANCE_CALLBACK CallBackFunction | |
+ ) | |
+{ | |
+ return VisitAllInstancesOfProtocol ( | |
+ &gEfiPciIoProtocolGuid, | |
+ VisitingAPciInstance, | |
+ (VOID*)(UINTN) CallBackFunction | |
+ ); | |
+} | |
+ | |
+ | |
+/** | |
+ Do platform specific PCI Device check and add them to | |
+ ConOut, ConIn, ErrOut. | |
+ | |
+ @param[in] Handle - Handle of PCI device instance | |
+ @param[in] PciIo - PCI IO protocol instance | |
+ @param[in] Pci - PCI Header register block | |
+ | |
+ @retval EFI_SUCCESS - PCI Device check and Console variable update successfully. | |
+ @retval EFI_STATUS - PCI Device check or Console variable update fail. | |
+ | |
+**/ | |
+EFI_STATUS | |
+EFIAPI | |
+DetectAndPreparePlatformPciDevicePath ( | |
+ IN EFI_HANDLE Handle, | |
+ IN EFI_PCI_IO_PROTOCOL *PciIo, | |
+ IN PCI_TYPE00 *Pci | |
+ ) | |
+{ | |
+ EFI_STATUS Status; | |
+ | |
+ Status = PciIo->Attributes ( | |
+ PciIo, | |
+ EfiPciIoAttributeOperationEnable, | |
+ EFI_PCI_DEVICE_ENABLE, | |
+ NULL | |
+ ); | |
+ ASSERT_EFI_ERROR (Status); | |
+ | |
+ if (!mDetectVgaOnly) { | |
+ // | |
+ // Here we decide whether it is LPC Bridge | |
+ // | |
+ if ((IS_PCI_LPC (Pci)) || | |
+ ((IS_PCI_ISA_PDECODE (Pci)) && | |
+ (Pci->Hdr.VendorId == 0x8086) && | |
+ (Pci->Hdr.DeviceId == 0x7000) | |
+ ) | |
+ ) { | |
+ // | |
+ // Add IsaKeyboard to ConIn, | |
+ // add IsaSerial to ConOut, ConIn, ErrOut | |
+ // | |
+ DEBUG ((EFI_D_INFO, "Found LPC Bridge device\n")); | |
+ PrepareLpcBridgeDevicePath (Handle); | |
+ return EFI_SUCCESS; | |
+ } | |
+ // | |
+ // Here we decide which Serial device to enable in PCI bus | |
+ // | |
+ if (IS_PCI_16550SERIAL (Pci)) { | |
+ // | |
+ // Add them to ConOut, ConIn, ErrOut. | |
+ // | |
+ DEBUG ((EFI_D_INFO, "Found PCI 16550 SERIAL device\n")); | |
+ PreparePciSerialDevicePath (Handle); | |
+ return EFI_SUCCESS; | |
+ } | |
+ } | |
+ | |
+ // | |
+ // Here we decide which VGA device to enable in PCI bus | |
+ // | |
+ if (IS_PCI_VGA (Pci)) { | |
+ // | |
+ // Add them to ConOut. | |
+ // | |
+ DEBUG ((EFI_D_INFO, "Found PCI VGA device\n")); | |
+ PreparePciVgaDevicePath (Handle); | |
+ return EFI_SUCCESS; | |
+ } | |
+ | |
+ return Status; | |
+} | |
+ | |
+ | |
+/** | |
+ Do platform specific PCI Device check and add them to ConOut, ConIn, ErrOut | |
+ | |
+ @param[in] DetectVgaOnly - Only detect VGA device if it's TRUE. | |
+ | |
+ @retval EFI_SUCCESS - PCI Device check and Console variable update successfully. | |
+ @retval EFI_STATUS - PCI Device check or Console variable update fail. | |
+ | |
+**/ | |
+EFI_STATUS | |
+DetectAndPreparePlatformPciDevicePaths ( | |
+ BOOLEAN DetectVgaOnly | |
+ ) | |
+{ | |
+ mDetectVgaOnly = DetectVgaOnly; | |
+ return VisitAllPciInstances (DetectAndPreparePlatformPciDevicePath); | |
+} | |
+ | |
+ | |
+EFI_STATUS | |
+PlatformBdsConnectConsole ( | |
+ IN BDS_CONSOLE_CONNECT_ENTRY *PlatformConsole | |
+ ) | |
+/*++ | |
+ | |
+Routine Description: | |
+ | |
+ Connect the predefined platform default console device. Always try to find | |
+ and enable the vga device if have. | |
+ | |
+Arguments: | |
+ | |
+ PlatformConsole - Predfined platform default console device array. | |
+ | |
+Returns: | |
+ | |
+ EFI_SUCCESS - Success connect at least one ConIn and ConOut | |
+ device, there must have one ConOut device is | |
+ active vga device. | |
+ | |
+ EFI_STATUS - Return the status of | |
+ BdsLibConnectAllDefaultConsoles () | |
+ | |
+--*/ | |
+{ | |
+ EFI_STATUS Status; | |
+ UINTN Index; | |
+ EFI_DEVICE_PATH_PROTOCOL *VarConout; | |
+ EFI_DEVICE_PATH_PROTOCOL *VarConin; | |
+ UINTN DevicePathSize; | |
+ | |
+ // | |
+ // Connect RootBridge | |
+ // | |
+ VarConout = BdsLibGetVariableAndSize ( | |
+ VarConsoleOut, | |
+ &gEfiGlobalVariableGuid, | |
+ &DevicePathSize | |
+ ); | |
+ VarConin = BdsLibGetVariableAndSize ( | |
+ VarConsoleInp, | |
+ &gEfiGlobalVariableGuid, | |
+ &DevicePathSize | |
+ ); | |
+ | |
+ if (VarConout == NULL || VarConin == NULL) { | |
+ // | |
+ // Do platform specific PCI Device check and add them to ConOut, ConIn, ErrOut | |
+ // | |
+ DetectAndPreparePlatformPciDevicePaths (FALSE); | |
+ | |
+ // | |
+ // Have chance to connect the platform default console, | |
+ // the platform default console is the minimue device group | |
+ // the platform should support | |
+ // | |
+ for (Index = 0; PlatformConsole[Index].DevicePath != NULL; ++Index) { | |
+ // | |
+ // Update the console variable with the connect type | |
+ // | |
+ if ((PlatformConsole[Index].ConnectType & CONSOLE_IN) == CONSOLE_IN) { | |
+ BdsLibUpdateConsoleVariable (VarConsoleInp, PlatformConsole[Index].DevicePath, NULL); | |
+ } | |
+ if ((PlatformConsole[Index].ConnectType & CONSOLE_OUT) == CONSOLE_OUT) { | |
+ BdsLibUpdateConsoleVariable (VarConsoleOut, PlatformConsole[Index].DevicePath, NULL); | |
+ } | |
+ if ((PlatformConsole[Index].ConnectType & STD_ERROR) == STD_ERROR) { | |
+ BdsLibUpdateConsoleVariable (VarErrorOut, PlatformConsole[Index].DevicePath, NULL); | |
+ } | |
+ } | |
+ } else { | |
+ // | |
+ // Only detect VGA device and add them to ConOut | |
+ // | |
+ DetectAndPreparePlatformPciDevicePaths (TRUE); | |
+ } | |
+ | |
+ // | |
+ // Connect the all the default console with current cosole variable | |
+ // | |
+ Status = BdsLibConnectAllDefaultConsoles (); | |
+ if (EFI_ERROR (Status)) { | |
+ return Status; | |
+ } | |
+ | |
+ return EFI_SUCCESS; | |
+} | |
+ | |
+ | |
+/** | |
+ Configure PCI Interrupt Line register for applicable devices | |
+ Ported from SeaBIOS, src/fw/pciinit.c, *_pci_slot_get_irq() | |
+ | |
+ @param[in] Handle - Handle of PCI device instance | |
+ @param[in] PciIo - PCI IO protocol instance | |
+ @param[in] PciHdr - PCI Header register block | |
+ | |
+ @retval EFI_SUCCESS - PCI Interrupt Line register configured successfully. | |
+ | |
+**/ | |
+EFI_STATUS | |
+EFIAPI | |
+SetPciIntLine ( | |
+ IN EFI_HANDLE Handle, | |
+ IN EFI_PCI_IO_PROTOCOL *PciIo, | |
+ IN PCI_TYPE00 *PciHdr | |
+ ) | |
+{ | |
+ EFI_DEVICE_PATH_PROTOCOL *DevPathNode; | |
+ EFI_DEVICE_PATH_PROTOCOL *DevPath; | |
+ UINTN RootSlot; | |
+ UINTN Idx; | |
+ UINT8 IrqLine; | |
+ EFI_STATUS Status; | |
+ UINT32 RootBusNumber; | |
+ | |
+ Status = EFI_SUCCESS; | |
+ | |
+ if (PciHdr->Device.InterruptPin != 0) { | |
+ | |
+ DevPathNode = DevicePathFromHandle (Handle); | |
+ ASSERT (DevPathNode != NULL); | |
+ DevPath = DevPathNode; | |
+ | |
+ RootBusNumber = 0; | |
+ if (DevicePathType (DevPathNode) == ACPI_DEVICE_PATH && | |
+ DevicePathSubType (DevPathNode) == ACPI_DP && | |
+ ((ACPI_HID_DEVICE_PATH *)DevPathNode)->HID == EISA_PNP_ID(0x0A03)) { | |
+ RootBusNumber = ((ACPI_HID_DEVICE_PATH *)DevPathNode)->UID; | |
+ } | |
+ | |
+ // | |
+ // Compute index into PciHostIrqs[] table by walking | |
+ // the device path and adding up all device numbers | |
+ // | |
+ Status = EFI_NOT_FOUND; | |
+ RootSlot = 0; | |
+ Idx = PciHdr->Device.InterruptPin - 1; | |
+ while (!IsDevicePathEnd (DevPathNode)) { | |
+ if (DevicePathType (DevPathNode) == HARDWARE_DEVICE_PATH && | |
+ DevicePathSubType (DevPathNode) == HW_PCI_DP) { | |
+ | |
+ Idx += ((PCI_DEVICE_PATH *)DevPathNode)->Device; | |
+ | |
+ // | |
+ // Unlike SeaBIOS, which starts climbing from the leaf device | |
+ // up toward the root, we traverse the device path starting at | |
+ // the root moving toward the leaf node. | |
+ // The slot number of the top-level parent bridge is needed for | |
+ // Q35 cases with more than 24 slots on the root bus. | |
+ // | |
+ if (Status != EFI_SUCCESS) { | |
+ Status = EFI_SUCCESS; | |
+ RootSlot = ((PCI_DEVICE_PATH *)DevPathNode)->Device; | |
+ } | |
+ } | |
+ | |
+ DevPathNode = NextDevicePathNode (DevPathNode); | |
+ } | |
+ if (EFI_ERROR (Status)) { | |
+ return Status; | |
+ } | |
+ if (RootBusNumber == 0 && RootSlot == 0) { | |
+ DEBUG(( | |
+ EFI_D_ERROR, | |
+ "%a: PCI host bridge (00:00.0) should have no interrupts!\n", | |
+ __FUNCTION__ | |
+ )); | |
+ ASSERT (FALSE); | |
+ } | |
+ | |
+ // | |
+ // Final PciHostIrqs[] index calculation depends on the platform | |
+ // and should match SeaBIOS src/fw/pciinit.c *_pci_slot_get_irq() | |
+ // | |
+ switch (mHostBridgeDevId) { | |
+ case INTEL_82441_DEVICE_ID: | |
+ Idx -= 1; | |
+ break; | |
+ case INTEL_Q35_MCH_DEVICE_ID: | |
+ // | |
+ // SeaBIOS contains the following comment: | |
+ // "Slots 0-24 rotate slot:pin mapping similar to piix above, but | |
+ // with a different starting index - see q35-acpi-dsdt.dsl. | |
+ // | |
+ // Slots 25-31 all use LNKA mapping (or LNKE, but A:D = E:H)" | |
+ // | |
+ if (RootSlot > 24) { | |
+ // | |
+ // in this case, subtract back out RootSlot from Idx | |
+ // (SeaBIOS never adds it to begin with, but that would make our | |
+ // device path traversal loop above too awkward) | |
+ // | |
+ Idx -= RootSlot; | |
+ } | |
+ break; | |
+ default: | |
+ ASSERT (FALSE); // should never get here | |
+ } | |
+ Idx %= ARRAY_SIZE (PciHostIrqs); | |
+ IrqLine = PciHostIrqs[Idx]; | |
+ | |
+ DEBUG_CODE_BEGIN (); | |
+ { | |
+ CHAR16 *DevPathString; | |
+ STATIC CHAR16 Fallback[] = L"<failed to convert>"; | |
+ UINTN Segment, Bus, Device, Function; | |
+ | |
+ DevPathString = ConvertDevicePathToText (DevPath, FALSE, FALSE); | |
+ if (DevPathString == NULL) { | |
+ DevPathString = Fallback; | |
+ } | |
+ Status = PciIo->GetLocation (PciIo, &Segment, &Bus, &Device, &Function); | |
+ ASSERT_EFI_ERROR (Status); | |
+ | |
+ DEBUG ((EFI_D_VERBOSE, "%a: [%02x:%02x.%x] %s -> 0x%02x\n", __FUNCTION__, | |
+ (UINT32)Bus, (UINT32)Device, (UINT32)Function, DevPathString, | |
+ IrqLine)); | |
+ | |
+ if (DevPathString != Fallback) { | |
+ FreePool (DevPathString); | |
+ } | |
+ } | |
+ DEBUG_CODE_END (); | |
+ | |
+ // | |
+ // Set PCI Interrupt Line register for this device to PciHostIrqs[Idx] | |
+ // | |
+ Status = PciIo->Pci.Write ( | |
+ PciIo, | |
+ EfiPciIoWidthUint8, | |
+ PCI_INT_LINE_OFFSET, | |
+ 1, | |
+ &IrqLine | |
+ ); | |
+ } | |
+ | |
+ return Status; | |
+} | |
+ | |
+ | |
+VOID | |
+PciAcpiInitialization ( | |
+ ) | |
+{ | |
+ UINTN Pmba; | |
+ | |
+ // | |
+ // Query Host Bridge DID to determine platform type | |
+ // | |
+ mHostBridgeDevId = PcdGet16 (PcdOvmfHostBridgePciDevId); | |
+ switch (mHostBridgeDevId) { | |
+ case INTEL_82441_DEVICE_ID: | |
+ Pmba = POWER_MGMT_REGISTER_PIIX4 (PIIX4_PMBA); | |
+ // | |
+ // 00:01.0 ISA Bridge (PIIX4) LNK routing targets | |
+ // | |
+ PciWrite8 (PCI_LIB_ADDRESS (0, 1, 0, 0x60), 0x0b); // A | |
+ PciWrite8 (PCI_LIB_ADDRESS (0, 1, 0, 0x61), 0x0b); // B | |
+ PciWrite8 (PCI_LIB_ADDRESS (0, 1, 0, 0x62), 0x0a); // C | |
+ PciWrite8 (PCI_LIB_ADDRESS (0, 1, 0, 0x63), 0x0a); // D | |
+ break; | |
+ case INTEL_Q35_MCH_DEVICE_ID: | |
+ Pmba = POWER_MGMT_REGISTER_Q35 (ICH9_PMBASE); | |
+ // | |
+ // 00:1f.0 LPC Bridge (Q35) LNK routing targets | |
+ // | |
+ PciWrite8 (PCI_LIB_ADDRESS (0, 0x1f, 0, 0x60), 0x0a); // A | |
+ PciWrite8 (PCI_LIB_ADDRESS (0, 0x1f, 0, 0x61), 0x0a); // B | |
+ PciWrite8 (PCI_LIB_ADDRESS (0, 0x1f, 0, 0x62), 0x0b); // C | |
+ PciWrite8 (PCI_LIB_ADDRESS (0, 0x1f, 0, 0x63), 0x0b); // D | |
+ PciWrite8 (PCI_LIB_ADDRESS (0, 0x1f, 0, 0x68), 0x0a); // E | |
+ PciWrite8 (PCI_LIB_ADDRESS (0, 0x1f, 0, 0x69), 0x0a); // F | |
+ PciWrite8 (PCI_LIB_ADDRESS (0, 0x1f, 0, 0x6a), 0x0b); // G | |
+ PciWrite8 (PCI_LIB_ADDRESS (0, 0x1f, 0, 0x6b), 0x0b); // H | |
+ break; | |
+ default: | |
+ DEBUG ((EFI_D_ERROR, "%a: Unknown Host Bridge Device ID: 0x%04x\n", | |
+ __FUNCTION__, mHostBridgeDevId)); | |
+ ASSERT (FALSE); | |
+ return; | |
+ } | |
+ | |
+ // | |
+ // Initialize PCI_INTERRUPT_LINE for applicable present PCI devices | |
+ // | |
+ VisitAllPciInstances (SetPciIntLine); | |
+ | |
+ // | |
+ // Set ACPI SCI_EN bit in PMCNTRL | |
+ // | |
+ IoOr16 ((PciRead32 (Pmba) & ~BIT0) + 4, BIT0); | |
+} | |
+ | |
+ | |
+EFI_STATUS | |
+EFIAPI | |
+ConnectRecursivelyIfPciMassStorage ( | |
+ IN EFI_HANDLE Handle, | |
+ IN EFI_PCI_IO_PROTOCOL *Instance, | |
+ IN PCI_TYPE00 *PciHeader | |
+ ) | |
+{ | |
+ EFI_STATUS Status; | |
+ EFI_DEVICE_PATH_PROTOCOL *DevicePath; | |
+ CHAR16 *DevPathStr; | |
+ | |
+ if (IS_CLASS1 (PciHeader, PCI_CLASS_MASS_STORAGE)) { | |
+ DevicePath = NULL; | |
+ Status = gBS->HandleProtocol ( | |
+ Handle, | |
+ &gEfiDevicePathProtocolGuid, | |
+ (VOID*)&DevicePath | |
+ ); | |
+ if (EFI_ERROR (Status)) { | |
+ return Status; | |
+ } | |
+ | |
+ // | |
+ // Print Device Path | |
+ // | |
+ DevPathStr = DevicePathToStr (DevicePath); | |
+ if (DevPathStr != NULL) { | |
+ DEBUG(( | |
+ EFI_D_INFO, | |
+ "Found Mass Storage device: %s\n", | |
+ DevPathStr | |
+ )); | |
+ FreePool(DevPathStr); | |
+ } | |
+ | |
+ Status = gBS->ConnectController (Handle, NULL, NULL, TRUE); | |
+ if (EFI_ERROR (Status)) { | |
+ return Status; | |
+ } | |
+ | |
+ } | |
+ | |
+ return EFI_SUCCESS; | |
+} | |
+ | |
+ | |
+/** | |
+ This notification function is invoked when the | |
+ EMU Variable FVB has been changed. | |
+ | |
+ @param Event The event that occured | |
+ @param Context For EFI compatiblity. Not used. | |
+ | |
+**/ | |
+VOID | |
+EFIAPI | |
+EmuVariablesUpdatedCallback ( | |
+ IN EFI_EVENT Event, | |
+ IN VOID *Context | |
+ ) | |
+{ | |
+ DEBUG ((EFI_D_INFO, "EmuVariablesUpdatedCallback\n")); | |
+ UpdateNvVarsOnFileSystem (); | |
+} | |
+ | |
+ | |
+EFI_STATUS | |
+EFIAPI | |
+VisitingFileSystemInstance ( | |
+ IN EFI_HANDLE Handle, | |
+ IN VOID *Instance, | |
+ IN VOID *Context | |
+ ) | |
+{ | |
+ EFI_STATUS Status; | |
+ STATIC BOOLEAN ConnectedToFileSystem = FALSE; | |
+ | |
+ if (ConnectedToFileSystem) { | |
+ return EFI_ALREADY_STARTED; | |
+ } | |
+ | |
+ Status = ConnectNvVarsToFileSystem (Handle); | |
+ if (EFI_ERROR (Status)) { | |
+ return Status; | |
+ } | |
+ | |
+ ConnectedToFileSystem = TRUE; | |
+ mEmuVariableEvent = | |
+ EfiCreateProtocolNotifyEvent ( | |
+ &gEfiDevicePathProtocolGuid, | |
+ TPL_CALLBACK, | |
+ EmuVariablesUpdatedCallback, | |
+ NULL, | |
+ &mEmuVariableEventReg | |
+ ); | |
+ PcdSet64 (PcdEmuVariableEvent, (UINT64)(UINTN) mEmuVariableEvent); | |
+ | |
+ return EFI_SUCCESS; | |
+} | |
+ | |
+ | |
+VOID | |
+PlatformBdsRestoreNvVarsFromHardDisk ( | |
+ ) | |
+{ | |
+ VisitAllPciInstances (ConnectRecursivelyIfPciMassStorage); | |
+ VisitAllInstancesOfProtocol ( | |
+ &gEfiSimpleFileSystemProtocolGuid, | |
+ VisitingFileSystemInstance, | |
+ NULL | |
+ ); | |
+ | |
+} | |
+ | |
+ | |
+VOID | |
+PlatformBdsConnectSequence ( | |
+ VOID | |
+ ) | |
+/*++ | |
+ | |
+Routine Description: | |
+ | |
+ Connect with predeined platform connect sequence, | |
+ the OEM/IBV can customize with their own connect sequence. | |
+ | |
+Arguments: | |
+ | |
+ None. | |
+ | |
+Returns: | |
+ | |
+ None. | |
+ | |
+--*/ | |
+{ | |
+ UINTN Index; | |
+ | |
+ DEBUG ((EFI_D_INFO, "PlatformBdsConnectSequence\n")); | |
+ | |
+ Index = 0; | |
+ | |
+ // | |
+ // Here we can get the customized platform connect sequence | |
+ // Notes: we can connect with new variable which record the | |
+ // last time boots connect device path sequence | |
+ // | |
+ while (gPlatformConnectSequence[Index] != NULL) { | |
+ // | |
+ // Build the platform boot option | |
+ // | |
+ BdsLibConnectDevicePath (gPlatformConnectSequence[Index]); | |
+ Index++; | |
+ } | |
+ | |
+ // | |
+ // Just use the simple policy to connect all devices | |
+ // | |
+ BdsLibConnectAll (); | |
+ | |
+ PciAcpiInitialization (); | |
+ | |
+ // | |
+ // Clear the logo after all devices are connected. | |
+ // | |
+ gST->ConOut->ClearScreen (gST->ConOut); | |
+} | |
+ | |
+VOID | |
+PlatformBdsGetDriverOption ( | |
+ IN OUT LIST_ENTRY *BdsDriverLists | |
+ ) | |
+/*++ | |
+ | |
+Routine Description: | |
+ | |
+ Load the predefined driver option, OEM/IBV can customize this | |
+ to load their own drivers | |
+ | |
+Arguments: | |
+ | |
+ BdsDriverLists - The header of the driver option link list. | |
+ | |
+Returns: | |
+ | |
+ None. | |
+ | |
+--*/ | |
+{ | |
+ DEBUG ((EFI_D_INFO, "PlatformBdsGetDriverOption\n")); | |
+ return; | |
+} | |
+ | |
+VOID | |
+PlatformBdsDiagnostics ( | |
+ IN EXTENDMEM_COVERAGE_LEVEL MemoryTestLevel, | |
+ IN BOOLEAN QuietBoot, | |
+ IN BASEM_MEMORY_TEST BaseMemoryTest | |
+ ) | |
+/*++ | |
+ | |
+Routine Description: | |
+ | |
+ Perform the platform diagnostic, such like test memory. OEM/IBV also | |
+ can customize this fuction to support specific platform diagnostic. | |
+ | |
+Arguments: | |
+ | |
+ MemoryTestLevel - The memory test intensive level | |
+ | |
+ QuietBoot - Indicate if need to enable the quiet boot | |
+ | |
+ BaseMemoryTest - A pointer to BaseMemoryTest() | |
+ | |
+Returns: | |
+ | |
+ None. | |
+ | |
+--*/ | |
+{ | |
+ EFI_STATUS Status; | |
+ | |
+ DEBUG ((EFI_D_INFO, "PlatformBdsDiagnostics\n")); | |
+ | |
+ // | |
+ // Here we can decide if we need to show | |
+ // the diagnostics screen | |
+ // Notes: this quiet boot code should be remove | |
+ // from the graphic lib | |
+ // | |
+ if (QuietBoot) { | |
+ EnableQuietBoot (PcdGetPtr(PcdLogoFile)); | |
+ // | |
+ // Perform system diagnostic | |
+ // | |
+ Status = BaseMemoryTest (MemoryTestLevel); | |
+ if (EFI_ERROR (Status)) { | |
+ DisableQuietBoot (); | |
+ } | |
+ | |
+ return ; | |
+ } | |
+ // | |
+ // Perform system diagnostic | |
+ // | |
+ Status = BaseMemoryTest (MemoryTestLevel); | |
+} | |
+ | |
+ | |
+/** | |
+ Save the S3 boot script. | |
+ | |
+ Note that we trigger DxeSmmReadyToLock here -- otherwise the script wouldn't | |
+ be saved actually. Triggering this protocol installation event in turn locks | |
+ down SMM, so no further changes to LockBoxes or SMRAM are possible | |
+ afterwards. | |
+**/ | |
+STATIC | |
+VOID | |
+SaveS3BootScript ( | |
+ VOID | |
+ ) | |
+{ | |
+ EFI_STATUS Status; | |
+ EFI_S3_SAVE_STATE_PROTOCOL *BootScript; | |
+ EFI_HANDLE Handle; | |
+ STATIC CONST UINT8 Info[] = { 0xDE, 0xAD, 0xBE, 0xEF }; | |
+ | |
+ Status = gBS->LocateProtocol (&gEfiS3SaveStateProtocolGuid, NULL, | |
+ (VOID **) &BootScript); | |
+ ASSERT_EFI_ERROR (Status); | |
+ | |
+ // | |
+ // Despite the opcode documentation in the PI spec, the protocol | |
+ // implementation embeds a deep copy of the info in the boot script, rather | |
+ // than storing just a pointer to runtime or NVS storage. | |
+ // | |
+ Status = BootScript->Write(BootScript, EFI_BOOT_SCRIPT_INFORMATION_OPCODE, | |
+ (UINT32) sizeof Info, | |
+ (EFI_PHYSICAL_ADDRESS)(UINTN) &Info); | |
+ ASSERT_EFI_ERROR (Status); | |
+ | |
+ Handle = NULL; | |
+ Status = gBS->InstallProtocolInterface (&Handle, | |
+ &gEfiDxeSmmReadyToLockProtocolGuid, EFI_NATIVE_INTERFACE, | |
+ NULL); | |
+ ASSERT_EFI_ERROR (Status); | |
+} | |
+ | |
+ | |
+VOID | |
+EFIAPI | |
+PlatformBdsPolicyBehavior ( | |
+ IN OUT LIST_ENTRY *DriverOptionList, | |
+ IN OUT LIST_ENTRY *BootOptionList, | |
+ IN PROCESS_CAPSULES ProcessCapsules, | |
+ IN BASEM_MEMORY_TEST BaseMemoryTest | |
+ ) | |
+/*++ | |
+ | |
+Routine Description: | |
+ | |
+ The function will excute with as the platform policy, current policy | |
+ is driven by boot mode. IBV/OEM can customize this code for their specific | |
+ policy action. | |
+ | |
+Arguments: | |
+ | |
+ DriverOptionList - The header of the driver option link list | |
+ | |
+ BootOptionList - The header of the boot option link list | |
+ | |
+ ProcessCapsules - A pointer to ProcessCapsules() | |
+ | |
+ BaseMemoryTest - A pointer to BaseMemoryTest() | |
+ | |
+Returns: | |
+ | |
+ None. | |
+ | |
+--*/ | |
+{ | |
+ EFI_STATUS Status; | |
+ EFI_BOOT_MODE BootMode; | |
+ | |
+ DEBUG ((EFI_D_INFO, "PlatformBdsPolicyBehavior\n")); | |
+ | |
+ VisitAllInstancesOfProtocol (&gEfiPciRootBridgeIoProtocolGuid, | |
+ ConnectRootBridge, NULL); | |
+ | |
+ // | |
+ // Signal the ACPI platform driver that it can download QEMU ACPI tables. | |
+ // | |
+ EfiEventGroupSignal (&gRootBridgesConnectedEventGroupGuid); | |
+ | |
+ // | |
+ // We can't signal End-of-Dxe earlier than this. Namely, End-of-Dxe triggers | |
+ // the preparation of S3 system information. That logic has a hard dependency | |
+ // on the presence of the FACS ACPI table. Since our ACPI tables are only | |
+ // installed after PCI enumeration completes, we must not trigger the S3 save | |
+ // earlier, hence we can't signal End-of-Dxe earlier. | |
+ // | |
+ EfiEventGroupSignal (&gEfiEndOfDxeEventGroupGuid); | |
+ | |
+ if (QemuFwCfgS3Enabled ()) { | |
+ // | |
+ // Save the boot script too. Note that this requires/includes emitting the | |
+ // DxeSmmReadyToLock event, which in turn locks down SMM. | |
+ // | |
+ SaveS3BootScript (); | |
+ } | |
+ | |
+ if (PcdGetBool (PcdOvmfFlashVariablesEnable)) { | |
+ DEBUG ((EFI_D_INFO, "PlatformBdsPolicyBehavior: not restoring NvVars " | |
+ "from disk since flash variables appear to be supported.\n")); | |
+ } else { | |
+ // | |
+ // Try to restore variables from the hard disk early so | |
+ // they can be used for the other BDS connect operations. | |
+ // | |
+ PlatformBdsRestoreNvVarsFromHardDisk (); | |
+ } | |
+ | |
+ // | |
+ // Load the driver option as the driver option list | |
+ // | |
+ PlatformBdsGetDriverOption (DriverOptionList); | |
+ | |
+ // | |
+ // Get current Boot Mode | |
+ // | |
+ Status = BdsLibGetBootMode (&BootMode); | |
+ DEBUG ((EFI_D_ERROR, "Boot Mode:%x\n", BootMode)); | |
+ | |
+ // | |
+ // Go the different platform policy with different boot mode | |
+ // Notes: this part code can be change with the table policy | |
+ // | |
+ ASSERT (BootMode == BOOT_WITH_FULL_CONFIGURATION); | |
+ // | |
+ // Connect platform console | |
+ // | |
+ Status = PlatformBdsConnectConsole (gPlatformConsole); | |
+ if (EFI_ERROR (Status)) { | |
+ // | |
+ // Here OEM/IBV can customize with defined action | |
+ // | |
+ PlatformBdsNoConsoleAction (); | |
+ } | |
+ | |
+ // | |
+ // Memory test and Logo show | |
+ // | |
+ PlatformBdsDiagnostics (IGNORE, TRUE, BaseMemoryTest); | |
+ | |
+ // | |
+ // Perform some platform specific connect sequence | |
+ // | |
+ PlatformBdsConnectSequence (); | |
+ | |
+ // | |
+ // Process QEMU's -kernel command line option | |
+ // | |
+ TryRunningQemuKernel (); | |
+ | |
+ DEBUG ((EFI_D_INFO, "BdsLibConnectAll\n")); | |
+ BdsLibConnectAll (); | |
+ BdsLibEnumerateAllBootOption (BootOptionList); | |
+ | |
+ SetBootOrderFromQemu (BootOptionList); | |
+ // | |
+ // The BootOrder variable may have changed, reload the in-memory list with | |
+ // it. | |
+ // | |
+ BdsLibBuildOptionFromVar (BootOptionList, L"BootOrder"); | |
+ | |
+ PlatformBdsEnterFrontPage (GetFrontPageTimeoutFromQemu(), TRUE); | |
+} | |
+ | |
+VOID | |
+EFIAPI | |
+PlatformBdsBootSuccess ( | |
+ IN BDS_COMMON_OPTION *Option | |
+ ) | |
+/*++ | |
+ | |
+Routine Description: | |
+ | |
+ Hook point after a boot attempt succeeds. We don't expect a boot option to | |
+ return, so the EFI 1.0 specification defines that you will default to an | |
+ interactive mode and stop processing the BootOrder list in this case. This | |
+ is alos a platform implementation and can be customized by IBV/OEM. | |
+ | |
+Arguments: | |
+ | |
+ Option - Pointer to Boot Option that succeeded to boot. | |
+ | |
+Returns: | |
+ | |
+ None. | |
+ | |
+--*/ | |
+{ | |
+ CHAR16 *TmpStr; | |
+ | |
+ DEBUG ((EFI_D_INFO, "PlatformBdsBootSuccess\n")); | |
+ // | |
+ // If Boot returned with EFI_SUCCESS and there is not in the boot device | |
+ // select loop then we need to pop up a UI and wait for user input. | |
+ // | |
+ TmpStr = Option->StatusString; | |
+ if (TmpStr != NULL) { | |
+ BdsLibOutputStrings (gST->ConOut, TmpStr, Option->Description, L"\n\r", NULL); | |
+ FreePool (TmpStr); | |
+ } | |
+} | |
+ | |
+VOID | |
+EFIAPI | |
+PlatformBdsBootFail ( | |
+ IN BDS_COMMON_OPTION *Option, | |
+ IN EFI_STATUS Status, | |
+ IN CHAR16 *ExitData, | |
+ IN UINTN ExitDataSize | |
+ ) | |
+/*++ | |
+ | |
+Routine Description: | |
+ | |
+ Hook point after a boot attempt fails. | |
+ | |
+Arguments: | |
+ | |
+ Option - Pointer to Boot Option that failed to boot. | |
+ | |
+ Status - Status returned from failed boot. | |
+ | |
+ ExitData - Exit data returned from failed boot. | |
+ | |
+ ExitDataSize - Exit data size returned from failed boot. | |
+ | |
+Returns: | |
+ | |
+ None. | |
+ | |
+--*/ | |
+{ | |
+ CHAR16 *TmpStr; | |
+ | |
+ DEBUG ((EFI_D_INFO, "PlatformBdsBootFail\n")); | |
+ | |
+ // | |
+ // If Boot returned with failed status then we need to pop up a UI and wait | |
+ // for user input. | |
+ // | |
+ TmpStr = Option->StatusString; | |
+ if (TmpStr != NULL) { | |
+ BdsLibOutputStrings (gST->ConOut, TmpStr, Option->Description, L"\n\r", NULL); | |
+ FreePool (TmpStr); | |
+ } | |
+} | |
+ | |
+EFI_STATUS | |
+PlatformBdsNoConsoleAction ( | |
+ VOID | |
+ ) | |
+/*++ | |
+ | |
+Routine Description: | |
+ | |
+ This function is remained for IBV/OEM to do some platform action, | |
+ if there no console device can be connected. | |
+ | |
+Arguments: | |
+ | |
+ None. | |
+ | |
+Returns: | |
+ | |
+ EFI_SUCCESS - Direct return success now. | |
+ | |
+--*/ | |
+{ | |
+ DEBUG ((EFI_D_INFO, "PlatformBdsNoConsoleAction\n")); | |
+ return EFI_SUCCESS; | |
+} | |
+ | |
+VOID | |
+EFIAPI | |
+PlatformBdsLockNonUpdatableFlash ( | |
+ VOID | |
+ ) | |
+{ | |
+ DEBUG ((EFI_D_INFO, "PlatformBdsLockNonUpdatableFlash\n")); | |
+ return; | |
+} | |
+ | |
+ | |
+/** | |
+ This notification function is invoked when an instance of the | |
+ EFI_DEVICE_PATH_PROTOCOL is produced. | |
+ | |
+ @param Event The event that occured | |
+ @param Context For EFI compatiblity. Not used. | |
+ | |
+**/ | |
+VOID | |
+EFIAPI | |
+NotifyDevPath ( | |
+ IN EFI_EVENT Event, | |
+ IN VOID *Context | |
+ ) | |
+{ | |
+ EFI_HANDLE Handle; | |
+ EFI_STATUS Status; | |
+ UINTN BufferSize; | |
+ EFI_DEVICE_PATH_PROTOCOL *DevPathNode; | |
+ ATAPI_DEVICE_PATH *Atapi; | |
+ | |
+ // | |
+ // Examine all new handles | |
+ // | |
+ for (;;) { | |
+ // | |
+ // Get the next handle | |
+ // | |
+ BufferSize = sizeof (Handle); | |
+ Status = gBS->LocateHandle ( | |
+ ByRegisterNotify, | |
+ NULL, | |
+ mEfiDevPathNotifyReg, | |
+ &BufferSize, | |
+ &Handle | |
+ ); | |
+ | |
+ // | |
+ // If not found, we're done | |
+ // | |
+ if (EFI_NOT_FOUND == Status) { | |
+ break; | |
+ } | |
+ | |
+ if (EFI_ERROR (Status)) { | |
+ continue; | |
+ } | |
+ | |
+ // | |
+ // Get the DevicePath protocol on that handle | |
+ // | |
+ Status = gBS->HandleProtocol (Handle, &gEfiDevicePathProtocolGuid, (VOID **)&DevPathNode); | |
+ ASSERT_EFI_ERROR (Status); | |
+ | |
+ while (!IsDevicePathEnd (DevPathNode)) { | |
+ // | |
+ // Find the handler to dump this device path node | |
+ // | |
+ if ( | |
+ (DevicePathType(DevPathNode) == MESSAGING_DEVICE_PATH) && | |
+ (DevicePathSubType(DevPathNode) == MSG_ATAPI_DP) | |
+ ) { | |
+ Atapi = (ATAPI_DEVICE_PATH*) DevPathNode; | |
+ PciOr16 ( | |
+ PCI_LIB_ADDRESS ( | |
+ 0, | |
+ 1, | |
+ 1, | |
+ (Atapi->PrimarySecondary == 1) ? 0x42: 0x40 | |
+ ), | |
+ BIT15 | |
+ ); | |
+ } | |
+ | |
+ // | |
+ // Next device path node | |
+ // | |
+ DevPathNode = NextDevicePathNode (DevPathNode); | |
+ } | |
+ } | |
+ | |
+ return; | |
+} | |
+ | |
+ | |
+VOID | |
+InstallDevicePathCallback ( | |
+ VOID | |
+ ) | |
+{ | |
+ DEBUG ((EFI_D_INFO, "Registered NotifyDevPath Event\n")); | |
+ mEfiDevPathEvent = EfiCreateProtocolNotifyEvent ( | |
+ &gEfiDevicePathProtocolGuid, | |
+ TPL_CALLBACK, | |
+ NotifyDevPath, | |
+ NULL, | |
+ &mEfiDevPathNotifyReg | |
+ ); | |
+} | |
+ | |
+/** | |
+ Lock the ConsoleIn device in system table. All key | |
+ presses will be ignored until the Password is typed in. The only way to | |
+ disable the password is to type it in to a ConIn device. | |
+ | |
+ @param Password Password used to lock ConIn device. | |
+ | |
+ @retval EFI_SUCCESS lock the Console In Spliter virtual handle successfully. | |
+ @retval EFI_UNSUPPORTED Password not found | |
+ | |
+**/ | |
+EFI_STATUS | |
+EFIAPI | |
+LockKeyboards ( | |
+ IN CHAR16 *Password | |
+ ) | |
+{ | |
+ return EFI_UNSUPPORTED; | |
+} | |
+ | |
diff --git a/OvmfPkg/QemuSmbiosPlatformDxe/Qemu.c b/OvmfPkg/QemuSmbiosPlatformDxe/Qemu.c | |
new file mode 100644 | |
index 000000000000..867488181251 | |
--- /dev/null | |
+++ b/OvmfPkg/QemuSmbiosPlatformDxe/Qemu.c | |
@@ -0,0 +1,702 @@ | |
+/** @file | |
+ This file fetches and installs SMBIOS tables on the QEMU hypervisor. | |
+ | |
+ Copyright (C) 2013, Red Hat, Inc. | |
+ | |
+ 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. | |
+**/ | |
+ | |
+#include <Library/MemoryAllocationLib.h> | |
+ | |
+#include "Qemu.h" | |
+#include "QemuInternal.h" | |
+ | |
+ | |
+// | |
+// An SMBIOS entry exported by QEMU over fw_cfg can have one of the following | |
+// types. | |
+// | |
+typedef enum | |
+{ | |
+ ET_FIELD, // defines one field in some SMBIOS table | |
+ ET_TABLE // defines an SMBIOS table instance in entirety | |
+} FW_CFG_SMBIOS_ENTRY_TYPE; | |
+ | |
+// | |
+// Header type introducing each entry in the QemuFwCfgItemX86SmbiosTables | |
+// fw_cfg blob. | |
+// | |
+#pragma pack(1) | |
+typedef struct { | |
+ UINT16 Size; // including payload and this header | |
+ UINT8 Type; // value from FW_CFG_SMBIOS_ENTRY_TYPE | |
+} FW_CFG_SMBIOS_ENTRY_HDR; | |
+#pragma pack() | |
+ | |
+// | |
+// Fields included at the beginning of the the payload in QEMU SMBIOS entries | |
+// with ET_FIELD type. | |
+// | |
+#pragma pack(1) | |
+typedef struct { | |
+ UINT8 TableType; // SMBIOS table type to patch | |
+ UINT16 Offset; // offset of a field in the formatted area | |
+} FW_CFG_SMBIOS_FIELD; | |
+#pragma pack() | |
+ | |
+ | |
+/** | |
+ Initialize a context object tracking SMBIOS table installation and patches | |
+ for fields. | |
+ | |
+ @param[out] Context A BUILD_CONTEXT object allocated dynamically and | |
+ initialized. | |
+ | |
+ @retval EFI_OUT_OF_RESOURCES Memory allocation failed. | |
+ @retval EFI_SUCCESS Allocation and initialization successful. | |
+**/ | |
+STATIC | |
+EFI_STATUS | |
+EFIAPI | |
+InitSmbiosContext ( | |
+ OUT BUILD_CONTEXT **Context | |
+ ) | |
+{ | |
+ *Context = AllocateZeroPool (sizeof **Context); | |
+ if (*Context == NULL) { | |
+ DEBUG ((DEBUG_ERROR, "%a: out of memory\n", __FUNCTION__)); | |
+ return EFI_OUT_OF_RESOURCES; | |
+ } | |
+ return EFI_SUCCESS; | |
+} | |
+ | |
+ | |
+/** | |
+ Release a context object tracking SMBIOS table installation and patches for | |
+ fields. | |
+ | |
+ @param[in,out] Context The BUILD_CONTEXT object to tear down. | |
+**/ | |
+STATIC | |
+VOID | |
+EFIAPI | |
+UninitSmbiosContext ( | |
+ IN OUT BUILD_CONTEXT *Context | |
+ ) | |
+{ | |
+ INT32 Type; | |
+ INT32 Idx; | |
+ | |
+ // | |
+ // free all patches | |
+ // | |
+ for (Type = 0; Type < TABLE_TYPE_LIMIT; ++Type) { | |
+ for (Idx = 0; Idx < PATCH_SUBSCRIPT_LIMIT; ++Idx) { | |
+ PATCH *Patch; | |
+ | |
+ Patch = &Context->Table[Type].Patch[Idx]; | |
+ if (Patch->Base != NULL) { | |
+ FreePool (Patch->Base); | |
+ } | |
+ } | |
+ } | |
+ FreePool (Context); | |
+} | |
+ | |
+ | |
+/** | |
+ Save a patch targeting an SMBIOS field in dynamically allocated memory. | |
+ | |
+ @param[in,out] Context The initialized BUILD_CONTEXT object to save the | |
+ patch in. | |
+ @param[in] TableType The patch to be saved targets this table type. | |
+ Patches for table types equal to or greater than | |
+ TABLE_TYPE_LIMIT are ignored. | |
+ @param[in] FieldOffset The patch to be saved targets the field that | |
+ begins at offset FieldOffset in SMBIOS table type | |
+ TableType. FieldOffset is enforced not to point | |
+ into the SMBIOS table header. A FieldOffset value | |
+ equal to or greater than 255 is rejected, since | |
+ the formatted area of an SMBIOS table never | |
+ exceeds 255 bytes. FieldOffset is not validated | |
+ against actual field offsets here, it is only | |
+ saved for later lookup. | |
+ @param[in] PatchData Byte array constituting the patch body. | |
+ @param[in] PatchSize Number of bytes in PatchData. | |
+ | |
+ @retval EFI_SUCCESS Patch has been either ignored due to not | |
+ meeting the criterion on TableType, or it has | |
+ been saved successfully. | |
+ @retval EFI_INVALID_PARAMETER FieldOffset is invalid. | |
+ @retval EFI_OUT_OF_RESOURCES Couldn't allocate memory for the patch. | |
+**/ | |
+STATIC | |
+EFI_STATUS | |
+EFIAPI | |
+SaveSmbiosPatch ( | |
+ IN OUT BUILD_CONTEXT *Context, | |
+ IN UINT8 TableType, | |
+ IN UINT16 FieldOffset, | |
+ IN UINT8 *PatchData, | |
+ IN UINT16 PatchSize | |
+) | |
+{ | |
+ UINT8 *NewBase; | |
+ PATCH *Patch; | |
+ | |
+ if (TableType >= TABLE_TYPE_LIMIT) { | |
+ DEBUG ((DEBUG_VERBOSE, | |
+ "%a: ignoring patch for unsupported table type %d\n", | |
+ __FUNCTION__, TableType)); | |
+ return EFI_SUCCESS; | |
+ } | |
+ | |
+ if (FieldOffset < FIELD_OFFSET_MINIMUM | |
+ || FieldOffset - FIELD_OFFSET_MINIMUM >= PATCH_SUBSCRIPT_LIMIT) { | |
+ DEBUG ((DEBUG_ERROR, | |
+ "%a: invalid patch for table type %d field offset %d\n", | |
+ __FUNCTION__, TableType, FieldOffset)); | |
+ return EFI_INVALID_PARAMETER; | |
+ } | |
+ | |
+ NewBase = AllocateCopyPool (PatchSize, PatchData); | |
+ if (PatchSize > 0 && NewBase == NULL) { | |
+ DEBUG ((DEBUG_ERROR, "%a: table type %d field offset %d: out of memory\n", | |
+ __FUNCTION__, TableType, FieldOffset)); | |
+ return EFI_OUT_OF_RESOURCES; | |
+ } | |
+ | |
+ Patch = &Context->Table[TableType].Patch[FieldOffset - FIELD_OFFSET_MINIMUM]; | |
+ // | |
+ // replace previous patch if it exists | |
+ // | |
+ if (Patch->Base != NULL) { | |
+ DEBUG ((DEBUG_VERBOSE, | |
+ "%a: replacing prior patch for table type %d field offset %d\n", | |
+ __FUNCTION__, TableType, FieldOffset)); | |
+ FreePool (Patch->Base); | |
+ } | |
+ | |
+ Patch->Base = NewBase; | |
+ Patch->Size = PatchSize; | |
+ return EFI_SUCCESS; | |
+} | |
+ | |
+ | |
+/** | |
+ Apply a saved patch to a field located in the formatted are of a not yet | |
+ installed SMBIOS table. | |
+ | |
+ The patch is looked up based on (Context, TableType, FieldOffset). | |
+ | |
+ @param[in] Context The BUILD_CONTEXT object storing saved patches. | |
+ @param[in] TableType Selects the table type for which the patch has been | |
+ saved. It is assumed that the caller has validated | |
+ TableType against TABLE_TYPE_LIMIT (upper | |
+ exclusive). | |
+ @param[in] FieldOffset Selects the SMBIOS field for which the patch has | |
+ been saved. It is assumed that the caller has | |
+ validated FieldOffset against FIELD_OFFSET_MINIMUM | |
+ (lower inclusive) and 255 (upper exclusive). | |
+ @param[in] FieldSize The caller supplies the size of the field to patch | |
+ in FieldSize. The patch saved for | |
+ TableType:FieldOffset, if any, is only applied if | |
+ its size equals FieldSize. | |
+ @param[out] TableBase Base of the SMBIOS table of type TableType in which | |
+ the field starting at FieldOffset needs to be | |
+ patched. | |
+ | |
+ @retval EFI_NOT_FOUND No patch found for TableType:FieldOffset in | |
+ Context. This return value is considered | |
+ informative (ie. non-fatal). | |
+ @retval EFI_INVALID_PARAMETER Patch found for TableType:FieldOffset, but its | |
+ size doesn't match FieldSize. This result is | |
+ considered a fatal error of the patch origin. | |
+ @retval EFI_SUCCESS The SMBIOS table at TableBase has been patched | |
+ starting at FieldOffset for a length of | |
+ FieldSize. | |
+**/ | |
+EFI_STATUS | |
+EFIAPI | |
+PatchSmbiosFormatted ( | |
+ IN BUILD_CONTEXT *Context, | |
+ IN UINT8 TableType, | |
+ IN UINT16 FieldOffset, | |
+ IN UINT16 FieldSize, | |
+ OUT UINT8 *TableBase | |
+ ) | |
+{ | |
+ PATCH *Patch; | |
+ | |
+ ASSERT (TableType < TABLE_TYPE_LIMIT); | |
+ ASSERT (FieldOffset >= FIELD_OFFSET_MINIMUM); | |
+ ASSERT (FieldOffset - FIELD_OFFSET_MINIMUM < PATCH_SUBSCRIPT_LIMIT); | |
+ | |
+ Patch = &Context->Table[TableType].Patch[FieldOffset - FIELD_OFFSET_MINIMUM]; | |
+ if (Patch->Base == NULL) { | |
+ return EFI_NOT_FOUND; | |
+ } | |
+ | |
+ if (Patch->Size != FieldSize) { | |
+ DEBUG ((DEBUG_ERROR, "%a: table type %d, field offset %d: " | |
+ "patch size %d doesn't match field size %d\n", | |
+ __FUNCTION__, TableType, FieldOffset, Patch->Size, FieldSize)); | |
+ return EFI_INVALID_PARAMETER; | |
+ } | |
+ | |
+ CopyMem (TableBase + FieldOffset, Patch->Base, FieldSize); | |
+ return EFI_SUCCESS; | |
+} | |
+ | |
+ | |
+/** | |
+ Apply a saved patch to a text string located in the unformatted area of an | |
+ already installed SMBIOS table. | |
+ | |
+ The patch is looked up based on (Context, TableType, FieldOffset). | |
+ | |
+ @param[in] Smbios The EFI_SMBIOS_PROTOCOL instance used previously | |
+ for installing the SMBIOS table. | |
+ @param[in] SmbiosHandle The EFI_SMBIOS_HANDLE previously returned by | |
+ Smbios->Add(). | |
+ @param[in] Context The BUILD_CONTEXT object storing saved patches. | |
+ @param[in] TableType Selects the table type for which the patch has been | |
+ saved. It is assumed that the caller has validated | |
+ TableType against TABLE_TYPE_LIMIT (upper | |
+ exclusive). | |
+ @param[in] FieldOffset Selects the SMBIOS field for which the patch has | |
+ been saved. It is assumed that the caller has | |
+ validated FieldOffset against FIELD_OFFSET_MINIMUM | |
+ (lower inclusive) and 255 (upper exclusive). | |
+ It is also assumed that TableBase[FieldOffset] | |
+ accesses a field of type SMBIOS_TABLE_STRING, ie. a | |
+ field in the formatted area that identifies an | |
+ existent text string in the unformatted area. Text | |
+ string identifiers are one-based. | |
+ @param[out] TableBase Base of the SMBIOS table of type TableType in which | |
+ the SMBIOS_TABLE_STRING field at FieldOffset | |
+ identifies the existent text string to update. | |
+ | |
+ @retval EFI_NOT_FOUND No patch found for TableType:FieldOffset in | |
+ Context. This return value is considered | |
+ informative (ie. non-fatal). | |
+ @retval EFI_INVALID_PARAMETER Patch found for TableType:FieldOffset, but it | |
+ doesn't end with a NUL character. This result | |
+ is considered a fatal error of the patch | |
+ origin. | |
+ @retval EFI_SUCCESS The text string identified by | |
+ TableBase[FieldOffset] has been replaced in | |
+ the installed SMBIOS table under SmbiosHandle. | |
+ @return Error codes returned by | |
+ Smbios->UpdateString(). EFI_NOT_FOUND shall | |
+ not be returned. | |
+**/ | |
+EFI_STATUS | |
+EFIAPI | |
+PatchSmbiosUnformatted ( | |
+ IN EFI_SMBIOS_PROTOCOL *Smbios, | |
+ IN EFI_SMBIOS_HANDLE SmbiosHandle, | |
+ IN BUILD_CONTEXT *Context, | |
+ IN UINT8 TableType, | |
+ IN UINT16 FieldOffset, | |
+ IN UINT8 *TableBase | |
+ ) | |
+{ | |
+ PATCH *Patch; | |
+ UINTN StringNumber; | |
+ EFI_STATUS Status; | |
+ | |
+ ASSERT (TableType < TABLE_TYPE_LIMIT); | |
+ ASSERT (FieldOffset >= FIELD_OFFSET_MINIMUM); | |
+ ASSERT (FieldOffset - FIELD_OFFSET_MINIMUM < PATCH_SUBSCRIPT_LIMIT); | |
+ | |
+ Patch = &Context->Table[TableType].Patch[FieldOffset - FIELD_OFFSET_MINIMUM]; | |
+ if (Patch->Base == NULL) { | |
+ return EFI_NOT_FOUND; | |
+ } | |
+ | |
+ if (Patch->Size == 0 || Patch->Base[Patch->Size - 1] != '\0') { | |
+ DEBUG ((DEBUG_ERROR, "%a: table type %d, field offset %d: " | |
+ "missing terminator, or trailing garbage\n", | |
+ __FUNCTION__, TableType, FieldOffset)); | |
+ return EFI_INVALID_PARAMETER; | |
+ } | |
+ | |
+ StringNumber = TableBase[FieldOffset]; | |
+ ASSERT (StringNumber != 0); | |
+ | |
+ Status = Smbios->UpdateString (Smbios, &SmbiosHandle, &StringNumber, | |
+ (CHAR8 *)Patch->Base); | |
+ if (EFI_ERROR (Status)) { | |
+ ASSERT (Status != EFI_NOT_FOUND); | |
+ DEBUG ((DEBUG_ERROR, "%a: table type %d, field offset %d, " | |
+ "string number %d: Smbios->UpdateString(): %r\n", __FUNCTION__, | |
+ TableType, FieldOffset, TableBase[FieldOffset], Status)); | |
+ return Status; | |
+ } | |
+ return EFI_SUCCESS; | |
+} | |
+ | |
+ | |
+/** | |
+ Process an SMBIOS firmware configuration entry with ET_FIELD type, exported | |
+ by QEMU under QemuFwCfgItemX86SmbiosTables. | |
+ | |
+ Such entries describe patches to be saved with SaveSmbiosPatch(). | |
+ | |
+ @param[in,out] Context The BUILD_CONTEXT object tracking saved patches. | |
+ @param[in] Payload Points to the buffer to parse as | |
+ FW_CFG_SMBIOS_FIELD. | |
+ @param[in] PayloadSize Number of bytes in Payload. | |
+ | |
+ @retval EFI_INVALID_PARAMETER PayloadSize is less than the size of | |
+ FW_CFG_SMBIOS_FIELD -- fields describing | |
+ the patch are incomplete. | |
+ @retval EFI_SUCCESS Payload has been parsed and patch has been | |
+ saved successfully. | |
+ @return Error codes returned by SaveSmbiosPatch(). | |
+**/ | |
+STATIC | |
+EFI_STATUS | |
+EFIAPI | |
+VisitSmbiosField ( | |
+ IN OUT BUILD_CONTEXT *Context, | |
+ IN UINT8 *Payload, | |
+ IN UINT16 PayloadSize | |
+ ) | |
+{ | |
+ FW_CFG_SMBIOS_FIELD *Field; | |
+ | |
+ if (PayloadSize < (INT32) sizeof *Field) { | |
+ DEBUG ((DEBUG_ERROR, "%a: required minimum size %d, available %d\n", | |
+ __FUNCTION__, (INT32) sizeof *Field, PayloadSize)); | |
+ return EFI_INVALID_PARAMETER; | |
+ } | |
+ | |
+ Field = (FW_CFG_SMBIOS_FIELD *) Payload; | |
+ return SaveSmbiosPatch (Context, Field->TableType, Field->Offset, | |
+ Payload + sizeof *Field, (UINT16) (PayloadSize - sizeof *Field)); | |
+} | |
+ | |
+ | |
+/** | |
+ Process an SMBIOS firmware configuration entry with ET_TABLE type, exported | |
+ by QEMU under QemuFwCfgItemX86SmbiosTables. | |
+ | |
+ Such entries describe entire SMBIOS table instances to install verbatim. This | |
+ module never overrides tables installed in this manner with default tables. | |
+ | |
+ @param[in] Smbios The EFI_SMBIOS_PROTOCOL instance used for | |
+ installing SMBIOS tables. | |
+ @param[in] ProducerHandle Passed on to Smbios->Add(), ProducerHandle | |
+ tracks the origin of installed SMBIOS tables. | |
+ @param[in,out] Context The BUILD_CONTEXT object tracking installed | |
+ tables. | |
+ @param[in] Payload Points to the buffer to install as an SMBIOS | |
+ table. | |
+ @param[in] PayloadSize Number of bytes in Payload. | |
+ | |
+ @retval EFI_INVALID_PARAMETER The buffer at Payload, interpreted as an | |
+ SMBIOS table, failed basic sanity checks. | |
+ @retval EFI_SUCCESS Payload has been installed successfully as an | |
+ SMBIOS table. | |
+ @return Error codes returned by Smbios->Add(). | |
+**/ | |
+STATIC | |
+EFI_STATUS | |
+EFIAPI | |
+VisitSmbiosTable ( | |
+ IN EFI_SMBIOS_PROTOCOL *Smbios, | |
+ IN EFI_HANDLE ProducerHandle, | |
+ IN OUT BUILD_CONTEXT *Context, | |
+ IN UINT8 *Payload, | |
+ IN UINT16 PayloadSize | |
+ ) | |
+{ | |
+ SMBIOS_STRUCTURE *SmbiosHeader; | |
+ UINT16 MinimumSize; | |
+ EFI_SMBIOS_HANDLE SmbiosHandle; | |
+ EFI_STATUS Status; | |
+ | |
+ // | |
+ // Basic sanity checks only in order to help debugging and to catch blatantly | |
+ // invalid data passed with "-smbios file=binary_file" on the QEMU command | |
+ // line. Beyond these we don't enforce correct, type-specific SMBIOS table | |
+ // formatting. | |
+ // | |
+ if (PayloadSize < (INT32) sizeof *SmbiosHeader) { | |
+ DEBUG ((DEBUG_ERROR, "%a: required minimum size %d, available %d\n", | |
+ __FUNCTION__, (INT32) sizeof *SmbiosHeader, PayloadSize)); | |
+ return EFI_INVALID_PARAMETER; | |
+ } | |
+ | |
+ SmbiosHeader = (SMBIOS_STRUCTURE *) Payload; | |
+ | |
+ if (SmbiosHeader->Length < (INT32) sizeof *SmbiosHeader) { | |
+ DEBUG ((DEBUG_ERROR, "%a: required minimum size %d, stated %d\n", | |
+ __FUNCTION__, (INT32) sizeof *SmbiosHeader, SmbiosHeader->Length)); | |
+ return EFI_INVALID_PARAMETER; | |
+ } | |
+ | |
+ MinimumSize = (UINT16) (SmbiosHeader->Length + 2); | |
+ | |
+ if (PayloadSize < MinimumSize) { | |
+ DEBUG ((DEBUG_ERROR, | |
+ "%a: minimum for formatted area plus terminator is %d, available %d\n", | |
+ __FUNCTION__, MinimumSize, PayloadSize)); | |
+ return EFI_INVALID_PARAMETER; | |
+ } | |
+ | |
+ if (Payload[PayloadSize - 2] != '\0' || | |
+ Payload[PayloadSize - 1] != '\0') { | |
+ DEBUG ((DEBUG_ERROR, "%a: missing terminator, or trailing garbage\n", | |
+ __FUNCTION__)); | |
+ return EFI_INVALID_PARAMETER; | |
+ } | |
+ | |
+ // | |
+ // request unique handle | |
+ // | |
+ SmbiosHandle = SMBIOS_HANDLE_PI_RESERVED; | |
+ Status = Smbios->Add (Smbios, ProducerHandle, &SmbiosHandle, | |
+ (EFI_SMBIOS_TABLE_HEADER *) SmbiosHeader); | |
+ if (EFI_ERROR (Status)) { | |
+ DEBUG ((DEBUG_ERROR, "%a: Smbios->Add(): %r\n", __FUNCTION__, Status)); | |
+ return Status; | |
+ } | |
+ | |
+ // | |
+ // track known tables | |
+ // | |
+ if (SmbiosHeader->Type < TABLE_TYPE_LIMIT) { | |
+ Context->Table[SmbiosHeader->Type].Installed = TRUE; | |
+ } | |
+ return EFI_SUCCESS; | |
+} | |
+ | |
+ | |
+/** | |
+ Traverse the SMBIOS firmware configuration blob exported by QEMU under | |
+ QemuFwCfgItemX86SmbiosTables, processing each entry in turn. | |
+ | |
+ Entries with ET_FIELD type are parsed as patches for the SMBIOS tables this | |
+ module installs as fallbacks, while entries of type ET_TABLE are parsed and | |
+ installed as verbatim SMBIOS tables. | |
+ | |
+ Unknown entry types are silently skipped. Any error encountered during | |
+ traversal (for example, a recognized but malformed entry) aborts the | |
+ iteration, leaving the function with a possibly incomplete set of installed | |
+ tables. | |
+ | |
+ @param[in] Smbios The EFI_SMBIOS_PROTOCOL instance used for | |
+ installing SMBIOS tables. | |
+ @param[in] ProducerHandle Passed on to Smbios->Add(), ProducerHandle | |
+ tracks the origin of installed SMBIOS tables. | |
+ @param[in,out] Context The BUILD_CONTEXT object tracking installed | |
+ tables and saved patches. | |
+ | |
+ @retval EFI_SUCCESS The firmware configuration interface is | |
+ unavailable (no patches saved, no tables | |
+ installed). | |
+ @retval EFI_SUCCESS Traversal complete. Tables provided by QEMU | |
+ have been installed. Patches have been saved | |
+ for any default tables that will be necessary. | |
+ @retval EFI_INVALID_PARAMETER Encountered a corrupt entry in the SMBIOS | |
+ firmware configuration blob. | |
+ @retval EFI_OUT_OF_RESOURCES Memory allocation failed. | |
+ @return Error codes returned by VisitSmbiosField() and | |
+ VisitSmbiosTable(). | |
+**/ | |
+STATIC | |
+EFI_STATUS | |
+EFIAPI | |
+ScanQemuSmbios ( | |
+ IN EFI_SMBIOS_PROTOCOL *Smbios, | |
+ IN EFI_HANDLE ProducerHandle, | |
+ IN OUT BUILD_CONTEXT *Context | |
+ ) | |
+{ | |
+ EFI_STATUS Status; | |
+ UINT16 NumEntries; | |
+ UINT16 CurEntry; | |
+ | |
+ Status = EFI_SUCCESS; | |
+ | |
+ if (!QemuFwCfgIsAvailable ()) { | |
+ return Status; | |
+ } | |
+ | |
+ QemuFwCfgSelectItem (QemuFwCfgItemX86SmbiosTables); | |
+ | |
+ NumEntries = QemuFwCfgRead16 (); | |
+ for (CurEntry = 0; CurEntry < NumEntries && !EFI_ERROR (Status); | |
+ ++CurEntry) { | |
+ FW_CFG_SMBIOS_ENTRY_HDR Header; | |
+ UINT16 PayloadSize; | |
+ UINT8 *Payload; | |
+ | |
+ QemuFwCfgReadBytes (sizeof Header, &Header); | |
+ | |
+ if (Header.Size < (INT32) sizeof Header) { | |
+ DEBUG ((DEBUG_ERROR, "%a: invalid header size %d in entry %d\n", | |
+ __FUNCTION__, Header.Size, CurEntry)); | |
+ return EFI_INVALID_PARAMETER; | |
+ } | |
+ | |
+ PayloadSize = (UINT16) (Header.Size - sizeof Header); | |
+ Payload = AllocatePool (PayloadSize); | |
+ | |
+ if (PayloadSize > 0 && Payload == NULL) { | |
+ DEBUG ((DEBUG_ERROR, "%a: failed to allocate %d bytes for entry %d\n", | |
+ __FUNCTION__, PayloadSize, CurEntry)); | |
+ return EFI_OUT_OF_RESOURCES; | |
+ } | |
+ | |
+ QemuFwCfgReadBytes (PayloadSize, Payload); | |
+ | |
+ // | |
+ // dump the payload | |
+ // | |
+ DEBUG_CODE ( | |
+ UINT16 Idx; | |
+ | |
+ DEBUG ((DEBUG_VERBOSE, | |
+ "%a: entry %d, type %d, payload size %d, payload hex dump follows:", | |
+ __FUNCTION__, CurEntry, Header.Type, PayloadSize)); | |
+ for (Idx = 0; Idx < PayloadSize; ++Idx) { | |
+ switch (Idx % 16) { | |
+ case 0: | |
+ DEBUG ((DEBUG_VERBOSE, "\n%04X:", Idx)); | |
+ break; | |
+ case 8: | |
+ DEBUG ((DEBUG_VERBOSE, " ")); | |
+ break; | |
+ default: | |
+ ; | |
+ } | |
+ DEBUG ((DEBUG_VERBOSE, " %02X", Payload[Idx])); | |
+ } | |
+ DEBUG ((DEBUG_VERBOSE, "\n")); | |
+ ); | |
+ | |
+ switch (Header.Type) { | |
+ case ET_FIELD: | |
+ Status = VisitSmbiosField (Context, Payload, PayloadSize); | |
+ break; | |
+ case ET_TABLE: | |
+ Status = VisitSmbiosTable (Smbios, ProducerHandle, Context, Payload, | |
+ PayloadSize); | |
+ break; | |
+ default: | |
+ ; | |
+ } | |
+ | |
+ FreePool (Payload); | |
+ } | |
+ | |
+ return Status; | |
+} | |
+ | |
+ | |
+/** | |
+ Install some of the default SMBIOS tables for table types that QEMU hasn't | |
+ provided under QemuFwCfgItemX86SmbiosTables, but are required by the | |
+ SMBIOS-2.7.1 specification. | |
+ | |
+ @param[in] Smbios The EFI_SMBIOS_PROTOCOL instance used for | |
+ installing SMBIOS tables. | |
+ @param[in] ProducerHandle Passed on to Smbios->Add(), ProducerHandle | |
+ tracks the origin of installed SMBIOS tables. | |
+ @param[in,out] Context The BUILD_CONTEXT object tracking installed | |
+ tables and saved patches. | |
+ | |
+ @return Status codes returned by the InstallSmbiosTypeXX() functions, | |
+ including the final EFI_SUCCESS if all such calls succeed. | |
+**/ | |
+STATIC | |
+EFI_STATUS | |
+EFIAPI | |
+InstallDefaultTables ( | |
+ IN EFI_SMBIOS_PROTOCOL *Smbios, | |
+ IN EFI_HANDLE ProducerHandle, | |
+ IN OUT BUILD_CONTEXT *Context | |
+ ) | |
+{ | |
+ EFI_STATUS Status; | |
+ | |
+ Status = InstallSmbiosType0 (Smbios, ProducerHandle, Context); | |
+ if (EFI_ERROR (Status)) { | |
+ return Status; | |
+ } | |
+ | |
+ Status = InstallSmbiosType1 (Smbios, ProducerHandle, Context); | |
+ return Status; | |
+} | |
+ | |
+ | |
+/** | |
+ Fetch and install SMBIOS tables on the QEMU hypervisor. | |
+ | |
+ First, tables provided by QEMU in entirety are installed verbatim. | |
+ | |
+ Then the function prepares some of the remaining tables required by the | |
+ SMBIOS-2.7.1 specification. For each such table, | |
+ - if QEMU provides any fields for the table, they take effect verbatim, | |
+ - remaining fields are set by this function. | |
+ | |
+ @param[in] Smbios The EFI_SMBIOS_PROTOCOL instance used for installing | |
+ the SMBIOS tables. | |
+ @param[in] ImageHandle The image handle of the calling module, passed as | |
+ ProducerHandle to the Smbios->Add() call. | |
+ | |
+ @retval EFI_SUCCESS All tables have been installed. | |
+ @retval EFI_UNSUPPORTED The pair (Smbios->MajorVersion, | |
+ Smbios->MinorVersion) precedes (2, 3) | |
+ lexicographically. | |
+ @return Error codes returned by Smbios->Add() or | |
+ internal functions. Some tables may not have | |
+ been installed or fully patched. | |
+**/ | |
+EFI_STATUS | |
+EFIAPI | |
+InstallQemuSmbiosTables ( | |
+ IN EFI_SMBIOS_PROTOCOL *Smbios, | |
+ IN EFI_HANDLE ImageHandle | |
+ ) | |
+{ | |
+ EFI_STATUS Status; | |
+ BUILD_CONTEXT *Context; | |
+ | |
+ if (Smbios->MajorVersion < 2 || Smbios->MinorVersion < 3) { | |
+ DEBUG ((DEBUG_ERROR, "%a: unsupported Smbios version %d.%d\n", | |
+ __FUNCTION__, Smbios->MajorVersion, Smbios->MinorVersion)); | |
+ return EFI_UNSUPPORTED; | |
+ } | |
+ | |
+ Status = InitSmbiosContext (&Context); | |
+ if (EFI_ERROR (Status)) { | |
+ return Status; | |
+ } | |
+ | |
+ // | |
+ // <IndustryStandard/SmBios.h> and <Protocol/Smbios.h> must agree. | |
+ // | |
+ ASSERT (sizeof(SMBIOS_STRUCTURE) == sizeof(EFI_SMBIOS_TABLE_HEADER)); | |
+ | |
+ Status = ScanQemuSmbios (Smbios, ImageHandle, Context); | |
+ if (EFI_ERROR (Status)) { | |
+ goto Cleanup; | |
+ } | |
+ | |
+ Status = InstallDefaultTables (Smbios, ImageHandle, Context); | |
+ | |
+Cleanup: | |
+ UninitSmbiosContext (Context); | |
+ return Status; | |
+} | |
diff --git a/OvmfPkg/QemuSmbiosPlatformDxe/QemuType0.c b/OvmfPkg/QemuSmbiosPlatformDxe/QemuType0.c | |
new file mode 100644 | |
index 000000000000..24f3757f34f0 | |
--- /dev/null | |
+++ b/OvmfPkg/QemuSmbiosPlatformDxe/QemuType0.c | |
@@ -0,0 +1,180 @@ | |
+/** @file | |
+ Install the default Type 0 SMBIOS table if QEMU doesn't provide one through | |
+ the firmware configuration interface. | |
+ | |
+ Copyright (C) 2013, Red Hat, Inc. | |
+ | |
+ 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. | |
+**/ | |
+ | |
+#include "QemuInternal.h" | |
+ | |
+ | |
+// | |
+// Text strings (unformatted area) for the default Tpe 0 SMBIOS table. | |
+// | |
+// All possible strings must be provided because Smbios->UpdateString() can | |
+// only update existing strings, it can't introduce new ones. | |
+// | |
+#define OVMF_TYPE0_STRINGS \ | |
+ "EFI Development Kit II / OVMF\0" /* Vendor */ \ | |
+ "0.1\0" /* BiosVersion */ \ | |
+ "06/03/2013\0" /* BiosReleaseDate */ | |
+ | |
+ | |
+// | |
+// Type definition and contents of the default Type 0 SMBIOS table. | |
+// | |
+#pragma pack(1) | |
+OVMF_SMBIOS (0); | |
+#pragma pack() | |
+ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment