summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSteven Kinney <steven.kinney@linaro.org>2013-12-17 14:11:15 -0600
committerSteven Kinney <steven.kinney@linaro.org>2013-12-17 14:11:15 -0600
commit18110e987bb049e24ade0fb63b5577def8f99114 (patch)
tree9e8970d250ea95ffdc01cf81480a17c9b3f515cd
parentaec0833cc55918a9111af736171ba8ceb976824e (diff)
parent709b5d97be16420bc96161221903abb006c076a1 (diff)
Merging uefi-next/linaro-release into masterlinaro-uefi-2013.12
Signed-off-by: Steven Kinney <steven.kinney@linaro.org>
-rw-r--r--AppPkg/AppPkg.dsc23
-rw-r--r--AppPkg/Applications/Python/PythonReadMe.txt26
-rw-r--r--AppPkg/ReadMe.txt209
-rw-r--r--ArmPkg/ArmPkg.dec2
-rw-r--r--ArmPkg/ArmPkg.dsc8
-rw-r--r--ArmPkg/Drivers/ArmGic/ArmGic.c (renamed from ArmPkg/Drivers/PL390Gic/PL390Gic.c)0
-rw-r--r--ArmPkg/Drivers/ArmGic/ArmGicDxe.c (renamed from ArmPkg/Drivers/PL390Gic/PL390GicDxe.c)12
-rw-r--r--ArmPkg/Drivers/ArmGic/ArmGicDxe.inf (renamed from ArmPkg/Drivers/PL390Gic/PL390GicDxe.inf)6
-rw-r--r--ArmPkg/Drivers/ArmGic/ArmGicLib.inf (renamed from ArmPkg/Drivers/PL390Gic/PL390GicLib.inf)6
-rw-r--r--ArmPkg/Drivers/ArmGic/ArmGicNonSec.c (renamed from ArmPkg/Drivers/PL390Gic/PL390GicNonSec.c)0
-rw-r--r--ArmPkg/Drivers/ArmGic/ArmGicSec.c (renamed from ArmPkg/Drivers/PL390Gic/PL390GicSec.c)0
-rw-r--r--ArmPkg/Drivers/ArmGic/ArmGicSecLib.inf (renamed from ArmPkg/Drivers/PL390Gic/PL390GicSecLib.inf)6
-rw-r--r--ArmPkg/Drivers/CpuDxe/ArmV6/ExceptionSupport.S1
-rw-r--r--ArmPkg/Drivers/CpuDxe/ArmV6/ExceptionSupport.asm1
-rwxr-xr-xArmPkg/Drivers/CpuPei/CpuPei.inf5
-rw-r--r--ArmPkg/Include/Chipset/AArch64.h18
-rw-r--r--ArmPkg/Include/Chipset/ArmV7.h12
-rw-r--r--ArmPkg/Include/Library/ArmGicLib.h4
-rw-r--r--ArmPkg/Include/Library/ArmLib.h20
-rw-r--r--ArmPkg/Library/ArmArchTimerLib/ArmArchTimerLib.c4
-rw-r--r--ArmPkg/Library/BdsLib/BdsLinuxFdt.c2
-rwxr-xr-xArmPkg/Library/DebugPeCoffExtraActionLib/DebugPeCoffExtraActionLib.c6
-rw-r--r--ArmPlatformPkg/ArmPlatformPkg-2ndstage.dsc4
-rw-r--r--ArmPlatformPkg/ArmPlatformPkg.dsc6
-rw-r--r--ArmPlatformPkg/ArmRealViewEbPkg/ArmRealViewEb-RTSM-A8.dsc6
-rw-r--r--ArmPlatformPkg/ArmRealViewEbPkg/ArmRealViewEb-RTSM-A9x2.dsc6
-rw-r--r--ArmPlatformPkg/ArmRealViewEbPkg/ArmRealViewEb-RTSM-MPCore.fdf2
-rw-r--r--ArmPlatformPkg/ArmRealViewEbPkg/ArmRealViewEb-RTSM-UniCore.fdf2
-rw-r--r--ArmPlatformPkg/ArmRealViewEbPkg/ArmRealViewEb.dsc.inc4
-rw-r--r--ArmPlatformPkg/ArmRealViewEbPkg/Library/ArmRealViewEbSecLibRTSM/ArmRealViewEbSecLib.inf3
-rw-r--r--ArmPlatformPkg/ArmVExpressPkg/ArmVExpress-CTA15-A7.dsc19
-rw-r--r--ArmPlatformPkg/ArmVExpressPkg/ArmVExpress-CTA15-A7.fdf27
-rw-r--r--ArmPlatformPkg/ArmVExpressPkg/ArmVExpress-CTA15x2.dsc10
-rw-r--r--ArmPlatformPkg/ArmVExpressPkg/ArmVExpress-CTA15x2.fdf2
-rw-r--r--ArmPlatformPkg/ArmVExpressPkg/ArmVExpress-CTA5s.dsc10
-rw-r--r--ArmPlatformPkg/ArmVExpressPkg/ArmVExpress-CTA5s.fdf2
-rw-r--r--ArmPlatformPkg/ArmVExpressPkg/ArmVExpress-CTA9x4.dsc24
-rw-r--r--ArmPlatformPkg/ArmVExpressPkg/ArmVExpress-CTA9x4.fdf31
-rw-r--r--[-rwxr-xr-x]ArmPlatformPkg/ArmVExpressPkg/ArmVExpress-FVP-AArch64.dsc546
-rw-r--r--[-rwxr-xr-x]ArmPlatformPkg/ArmVExpressPkg/ArmVExpress-FVP-AArch64.fdf717
-rw-r--r--ArmPlatformPkg/ArmVExpressPkg/ArmVExpress-RTSM-A15.dsc23
-rw-r--r--ArmPlatformPkg/ArmVExpressPkg/ArmVExpress-RTSM-A15.fdf19
-rw-r--r--ArmPlatformPkg/ArmVExpressPkg/ArmVExpress-RTSM-A15_MPCore.dsc21
-rw-r--r--ArmPlatformPkg/ArmVExpressPkg/ArmVExpress-RTSM-A15_MPCore.fdf20
-rw-r--r--ArmPlatformPkg/ArmVExpressPkg/ArmVExpress-RTSM-A9x4.dsc8
-rw-r--r--ArmPlatformPkg/ArmVExpressPkg/ArmVExpress-RTSM-A9x4.fdf6
-rw-r--r--ArmPlatformPkg/ArmVExpressPkg/ArmVExpress-RTSM-AEMv8Ax4-foundation.dsc25
-rw-r--r--ArmPlatformPkg/ArmVExpressPkg/ArmVExpress-RTSM-AEMv8Ax4-foundation.fdf38
-rw-r--r--ArmPlatformPkg/ArmVExpressPkg/ArmVExpress-RTSM-AEMv8Ax4.dsc25
-rw-r--r--ArmPlatformPkg/ArmVExpressPkg/ArmVExpress-RTSM-AEMv8Ax4.fdf37
-rw-r--r--ArmPlatformPkg/ArmVExpressPkg/ArmVExpress.dsc.inc4
-rw-r--r--ArmPlatformPkg/ArmVExpressPkg/Library/ArmVExpressLibCTA15-A7/ArmVExpressLib.inf3
-rw-r--r--ArmPlatformPkg/ArmVExpressPkg/Library/ArmVExpressLibCTA9x4/ArmVExpressLib.inf5
-rw-r--r--ArmPlatformPkg/ArmVExpressPkg/Library/ArmVExpressLibCTA9x4/ArmVExpressLibSec.inf3
-rw-r--r--ArmPlatformPkg/ArmVExpressPkg/Library/ArmVExpressLibCTA9x4/CTA9x4.c20
-rw-r--r--ArmPlatformPkg/ArmVExpressPkg/Library/ArmVExpressLibRTSM/ArmVExpressLib.inf1
-rw-r--r--ArmPlatformPkg/ArmVExpressPkg/Library/ArmVExpressLibRTSM/ArmVExpressLibSec.inf1
-rw-r--r--ArmPlatformPkg/ArmVExpressPkg/Library/ArmVExpressSecLibCTA9x4/ArmVExpressSecLib.inf5
-rw-r--r--ArmPlatformPkg/ArmVExpressPkg/Library/ArmVExpressSecLibCTA9x4/CTA9x4Sec.c30
-rw-r--r--ArmPlatformPkg/ArmVExpressPkg/Library/ArmVExpressSecLibRTSM/AArch64/GicV3.S67
-rw-r--r--ArmPlatformPkg/ArmVExpressPkg/Library/ArmVExpressSecLibRTSM/Arm/GicV3.S24
-rw-r--r--ArmPlatformPkg/ArmVExpressPkg/Library/ArmVExpressSecLibRTSM/Arm/GicV3.asm27
-rw-r--r--ArmPlatformPkg/ArmVExpressPkg/Library/ArmVExpressSecLibRTSM/ArmVExpressSecLib.inf20
-rw-r--r--ArmPlatformPkg/ArmVExpressPkg/Library/ArmVExpressSecLibRTSM/RTSMSec.c33
-rwxr-xr-xArmPlatformPkg/Library/DebugSecExtraActionLib/DebugSecExtraActionLib.c2
-rw-r--r--ArmPlatformPkg/PrePi/AArch64/ModuleEntryPoint.S2
-rwxr-xr-xArmPlatformPkg/PrePi/PeiMPCore.inf1
-rwxr-xr-xArmPlatformPkg/PrePi/PeiUniCore.inf1
-rw-r--r--ArmPlatformPkg/Scripts/Ds5/system_table.py23
-rw-r--r--ArmPlatformPkg/Sec/Sec.inf3
-rw-r--r--BaseTools/Bin/Win32/BPDG.exebin1042267 -> 1042294 bytes
-rwxr-xr-xBaseTools/Bin/Win32/BootSectImage.exebin434176 -> 434176 bytes
-rwxr-xr-xBaseTools/Bin/Win32/EfiLdrImage.exebin421888 -> 421888 bytes
-rwxr-xr-xBaseTools/Bin/Win32/EfiRom.exebin446464 -> 446464 bytes
-rwxr-xr-xBaseTools/Bin/Win32/GenBootSector.exebin425984 -> 425984 bytes
-rwxr-xr-xBaseTools/Bin/Win32/GenCrc32.exebin425984 -> 425984 bytes
-rwxr-xr-xBaseTools/Bin/Win32/GenDepex.exebin1066587 -> 1081253 bytes
-rwxr-xr-xBaseTools/Bin/Win32/GenFds.exebin1385762 -> 1401050 bytes
-rwxr-xr-xBaseTools/Bin/Win32/GenFfs.exebin430080 -> 430080 bytes
-rwxr-xr-xBaseTools/Bin/Win32/GenFv.exebin479232 -> 479232 bytes
-rwxr-xr-xBaseTools/Bin/Win32/GenFw.exebin499712 -> 499712 bytes
-rwxr-xr-xBaseTools/Bin/Win32/GenPage.exebin425984 -> 425984 bytes
-rwxr-xr-xBaseTools/Bin/Win32/GenPatchPcdTable.exebin1064072 -> 1078875 bytes
-rwxr-xr-xBaseTools/Bin/Win32/GenSec.exebin446464 -> 446464 bytes
-rwxr-xr-xBaseTools/Bin/Win32/GenVtf.exebin446464 -> 446464 bytes
-rwxr-xr-xBaseTools/Bin/Win32/LzmaCompress.exebin397312 -> 397312 bytes
-rwxr-xr-xBaseTools/Bin/Win32/PatchPcdValue.exebin1036120 -> 1036120 bytes
-rwxr-xr-xBaseTools/Bin/Win32/Split.exebin425984 -> 425984 bytes
-rwxr-xr-xBaseTools/Bin/Win32/TargetTool.exebin1044355 -> 1044383 bytes
-rwxr-xr-xBaseTools/Bin/Win32/TianoCompress.exebin434176 -> 434176 bytes
-rwxr-xr-xBaseTools/Bin/Win32/Trim.exebin1103432 -> 1118098 bytes
-rw-r--r--BaseTools/Bin/Win32/UPT.exebin1680092 -> 1680092 bytes
-rwxr-xr-xBaseTools/Bin/Win32/VfrCompile.exebin1286144 -> 1286144 bytes
-rwxr-xr-xBaseTools/Bin/Win32/VolInfo.exebin471040 -> 471040 bytes
-rwxr-xr-xBaseTools/Bin/Win32/build.exebin1785910 -> 1803489 bytes
-rw-r--r--BaseTools/Source/C/Common/FvLib.c131
-rw-r--r--BaseTools/Source/C/Common/FvLib.h26
-rw-r--r--BaseTools/Source/C/GenFfs/GenFfs.c65
-rw-r--r--BaseTools/Source/C/GenFv/GenFv.c23
-rw-r--r--BaseTools/Source/C/GenFv/GenFvInternalLib.c236
-rw-r--r--BaseTools/Source/C/GenFv/GenFvInternalLib.h6
-rw-r--r--BaseTools/Source/C/GenFw/Elf32Convert.c20
-rw-r--r--BaseTools/Source/C/GenFw/Elf64Convert.c19
-rw-r--r--BaseTools/Source/C/GenSec/GenSec.c244
-rw-r--r--BaseTools/Source/C/Include/Common/BuildVersion.h2
-rw-r--r--BaseTools/Source/C/Include/Common/PiFirmwareFile.h78
-rw-r--r--BaseTools/Source/C/Include/Common/PiFirmwareVolume.h3
-rw-r--r--BaseTools/Source/C/Include/Guid/PiFirmwareFileSystem.h8
-rw-r--r--BaseTools/Source/C/VfrCompile/VfrSyntax.g34
-rw-r--r--BaseTools/Source/C/VfrCompile/VfrUtilityLib.cpp33
-rw-r--r--BaseTools/Source/C/VfrCompile/VfrUtilityLib.h2
-rw-r--r--BaseTools/Source/Python/AutoGen/AutoGen.py377
-rw-r--r--BaseTools/Source/Python/AutoGen/GenC.py907
-rw-r--r--BaseTools/Source/Python/AutoGen/GenPcdDb.py1566
-rw-r--r--BaseTools/Source/Python/BPDG/GenVpd.py14
-rw-r--r--BaseTools/Source/Python/Common/BuildVersion.py2
-rw-r--r--BaseTools/Source/Python/Common/DataType.py1
-rw-r--r--BaseTools/Source/Python/Common/GlobalData.py19
-rw-r--r--BaseTools/Source/Python/Common/Misc.py81
-rw-r--r--BaseTools/Source/Python/Common/VpdInfoFile.py25
-rw-r--r--BaseTools/Source/Python/CommonDataClass/DataClass.py1
-rw-r--r--BaseTools/Source/Python/CommonDataClass/FdfClass.py4
-rw-r--r--BaseTools/Source/Python/Ecc/MetaFileWorkspace/MetaFileParser.py1
-rw-r--r--BaseTools/Source/Python/GenFds/FdfParser.py160
-rw-r--r--BaseTools/Source/Python/GenFds/FfsInfStatement.py126
-rw-r--r--BaseTools/Source/Python/GenFds/Section.py2
-rw-r--r--BaseTools/Source/Python/GenPatchPcdTable/GenPatchPcdTable.py57
-rw-r--r--BaseTools/Source/Python/PatchPcdValue/PatchPcdValue.py14
-rw-r--r--BaseTools/Source/Python/UPT/BuildVersion.py2
-rw-r--r--BaseTools/Source/Python/Workspace/MetaFileCommentParser.py28
-rw-r--r--BaseTools/Source/Python/Workspace/MetaFileParser.py26
-rw-r--r--BaseTools/Source/Python/Workspace/MetaFileTable.py4
-rw-r--r--BaseTools/Source/Python/Workspace/WorkspaceDatabase.py320
-rw-r--r--BaseTools/Source/Python/build/build.py2
-rw-r--r--BaseTools/UserManuals/VfrCompiler_Utility_Man_Page.rtf116
-rw-r--r--BeagleBoardPkg/BeagleBoardPkg.dsc2
-rw-r--r--CryptoPkg/Library/BaseCryptLib/Rand/CryptRand.c11
-rw-r--r--CryptoPkg/Library/BaseCryptLib/Rand/CryptRandItc.c11
-rw-r--r--CryptoPkg/Library/BaseCryptLib/Rand/CryptRandTsc.c11
-rw-r--r--CryptoPkg/Library/BaseCryptLib/SysCall/Ia32/MathRShiftU64.S4
-rw-r--r--DuetPkg/DuetPkgIa32.dsc4
-rw-r--r--DuetPkg/DuetPkgX64.dsc4
-rw-r--r--EdkCompatibilityPkg/EdkCompatibilityPkg.dsc2
-rw-r--r--EdkCompatibilityPkg/Foundation/Library/Dxe/EfiDriverLib/Perf.c5
-rw-r--r--EdkCompatibilityPkg/Foundation/Library/EfiCommonLib/LinkedList.c2
-rw-r--r--EdkCompatibilityPkg/Foundation/Library/EfiCommonLib/ReportStatusCode.c2
-rw-r--r--EdkShellPkg/EdkShellPkg.dsc2
-rw-r--r--EmbeddedPkg/EmbeddedPkg.dec19
-rw-r--r--EmbeddedPkg/EmbeddedPkg.dsc15
-rw-r--r--FatBinPkg/EnhancedFatDxe/Ebc/Fat.efibin58432 -> 62784 bytes
-rw-r--r--FatBinPkg/EnhancedFatDxe/Ia32/Fat.efibin16512 -> 18048 bytes
-rw-r--r--FatBinPkg/EnhancedFatDxe/Ipf/Fat.efibin68192 -> 141568 bytes
-rw-r--r--FatBinPkg/EnhancedFatDxe/X64/Fat.efibin24448 -> 27136 bytes
-rw-r--r--FatBinPkg/ReadMe.txt7
-rw-r--r--IntelFrameworkModulePkg/Library/GenericBdsLib/BdsBoot.c2
-rw-r--r--MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpress.c2
-rw-r--r--MdeModulePkg/Bus/Pci/XhciDxe/Xhci.c95
-rw-r--r--MdeModulePkg/Bus/Pci/XhciDxe/XhciReg.h18
-rw-r--r--MdeModulePkg/Bus/Pci/XhciDxe/XhciSched.c50
-rw-r--r--MdeModulePkg/Bus/Usb/UsbBusDxe/UsbBus.h1
-rw-r--r--MdeModulePkg/Bus/Usb/UsbBusDxe/UsbDesc.c32
-rw-r--r--MdeModulePkg/Bus/Usb/UsbBusDxe/UsbEnumer.c76
-rw-r--r--MdeModulePkg/Bus/Usb/UsbBusDxe/UsbEnumer.h2
-rw-r--r--MdeModulePkg/Bus/Usb/UsbBusDxe/UsbHub.c23
-rw-r--r--MdeModulePkg/Core/Dxe/DxeMain.h2
-rw-r--r--MdeModulePkg/Core/Dxe/DxeMain.inf6
-rw-r--r--MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c32
-rw-r--r--MdeModulePkg/Core/Dxe/Event/Timer.c5
-rw-r--r--MdeModulePkg/Core/Dxe/Mem/Pool.c15
-rw-r--r--MdeModulePkg/Core/DxeIplPeim/DxeIpl.h3
-rw-r--r--MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf3
-rw-r--r--MdeModulePkg/Core/DxeIplPeim/Ia32/DxeLoadFunc.c28
-rw-r--r--MdeModulePkg/Core/DxeIplPeim/X64/DxeLoadFunc.c37
-rw-r--r--MdeModulePkg/Core/Pei/Dispatcher/Dispatcher.c186
-rw-r--r--MdeModulePkg/Core/Pei/PeiMain.h14
-rw-r--r--MdeModulePkg/Core/Pei/PeiMain.inf3
-rw-r--r--MdeModulePkg/Core/Pei/PeiMain/PeiMain.c34
-rw-r--r--MdeModulePkg/Core/Pei/Ppi/Ppi.c212
-rw-r--r--MdeModulePkg/Core/PiSmmCore/Notify.c36
-rw-r--r--MdeModulePkg/Include/Guid/PcdDataBaseSignatureGuid.h147
-rw-r--r--MdeModulePkg/Include/Library/CpuExceptionHandlerLib.h86
-rw-r--r--MdeModulePkg/Library/CpuExceptionHandlerLibNull/CpuExceptionHandlerLibNull.c86
-rw-r--r--MdeModulePkg/Library/CpuExceptionHandlerLibNull/CpuExceptionHandlerLibNull.inf4
-rw-r--r--MdeModulePkg/Library/DxeNetLib/DxeNetLib.c2
-rw-r--r--MdeModulePkg/MdeModulePkg.dec4
-rw-r--r--MdeModulePkg/Universal/Acpi/BootScriptExecutorDxe/BootScriptExecutorDxe.inf5
-rw-r--r--MdeModulePkg/Universal/Acpi/BootScriptExecutorDxe/IA32/SetIdtEntry.c6
-rw-r--r--MdeModulePkg/Universal/Acpi/BootScriptExecutorDxe/ScriptExecute.c244
-rw-r--r--MdeModulePkg/Universal/Acpi/BootScriptExecutorDxe/ScriptExecute.h7
-rw-r--r--MdeModulePkg/Universal/Acpi/BootScriptExecutorDxe/X64/SetIdtEntry.c28
-rw-r--r--MdeModulePkg/Universal/CapsulePei/X64/X64Entry.c5
-rw-r--r--MdeModulePkg/Universal/DisplayEngineDxe/FormDisplay.c942
-rw-r--r--MdeModulePkg/Universal/DisplayEngineDxe/ProcessOptions.c70
-rw-r--r--MdeModulePkg/Universal/HiiDatabaseDxe/ConfigRouting.c179
-rw-r--r--MdeModulePkg/Universal/HiiDatabaseDxe/Image.c5
-rw-r--r--MdeModulePkg/Universal/Network/IScsiDxe/IScsiDriver.c67
-rw-r--r--MdeModulePkg/Universal/Network/IScsiDxe/IScsiMisc.c55
-rw-r--r--MdeModulePkg/Universal/Network/IScsiDxe/IScsiMisc.h16
-rw-r--r--MdeModulePkg/Universal/PCD/Dxe/Pcd.c258
-rw-r--r--MdeModulePkg/Universal/PCD/Dxe/Pcd.inf41
-rw-r--r--MdeModulePkg/Universal/PCD/Dxe/Service.c755
-rw-r--r--MdeModulePkg/Universal/PCD/Dxe/Service.h108
-rw-r--r--MdeModulePkg/Universal/PCD/Pei/Pcd.c312
-rw-r--r--MdeModulePkg/Universal/PCD/Pei/Pcd.inf42
-rw-r--r--MdeModulePkg/Universal/PCD/Pei/Service.c492
-rw-r--r--MdeModulePkg/Universal/PCD/Pei/Service.h119
-rw-r--r--MdeModulePkg/Universal/SetupBrowserDxe/Expression.c88
-rw-r--r--MdeModulePkg/Universal/SetupBrowserDxe/IfrParse.c26
-rw-r--r--MdeModulePkg/Universal/SetupBrowserDxe/Presentation.c208
-rw-r--r--MdeModulePkg/Universal/SetupBrowserDxe/Setup.c680
-rw-r--r--MdeModulePkg/Universal/SetupBrowserDxe/Setup.h25
-rw-r--r--MdeModulePkg/Universal/Variable/RuntimeDxe/Reclaim.c24
-rw-r--r--MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.c272
-rw-r--r--MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.h6
-rw-r--r--MdePkg/Include/Guid/VectorHandoffTable.h33
-rw-r--r--MdePkg/Include/Library/PcdLib.h126
-rw-r--r--MdePkg/Include/Pi/PiDxeCis.h4
-rw-r--r--MdePkg/Include/Pi/PiMultiPhase.h31
-rw-r--r--MdePkg/Include/Pi/PiPeiCis.h2
-rw-r--r--MdePkg/Include/Pi/PiSmmCis.h6
-rw-r--r--MdePkg/Include/Ppi/Pcd.h38
-rw-r--r--MdePkg/Include/Ppi/PcdInfo.h105
-rw-r--r--MdePkg/Include/Ppi/PiPcd.h12
-rw-r--r--MdePkg/Include/Ppi/PiPcdInfo.h82
-rw-r--r--MdePkg/Include/Ppi/TemporaryRamDone.h52
-rw-r--r--MdePkg/Include/Ppi/VectorHandoffInfo.h75
-rw-r--r--MdePkg/Include/Protocol/Pcd.h37
-rw-r--r--MdePkg/Include/Protocol/PcdInfo.h105
-rw-r--r--MdePkg/Include/Protocol/PiPcdInfo.h83
-rw-r--r--MdePkg/Include/Protocol/Rng.h156
-rw-r--r--MdePkg/Include/Protocol/SimpleFileSystem.h165
-rw-r--r--MdePkg/Include/Uefi/UefiSpec.h7
-rw-r--r--MdePkg/Library/BaseLib/X64/Thunk16.S6
-rw-r--r--MdePkg/Library/BaseLib/X64/Thunk16.asm6
-rw-r--r--MdePkg/Library/BasePcdLibNull/PcdLib.c66
-rw-r--r--MdePkg/Library/BaseSmbusLibNull/BaseSmbusLibNull.c544
-rw-r--r--MdePkg/Library/BaseSmbusLibNull/BaseSmbusLibNull.inf34
-rw-r--r--MdePkg/Library/DxePcdLib/DxePcdLib.c136
-rw-r--r--MdePkg/Library/DxePcdLib/DxePcdLib.inf6
-rw-r--r--MdePkg/Library/PeiPcdLib/PeiPcdLib.c135
-rw-r--r--MdePkg/Library/PeiPcdLib/PeiPcdLib.inf8
-rw-r--r--MdePkg/Library/PeiServicesTablePointerLibIdt/PeiServicesTablePointer.c40
-rw-r--r--MdePkg/Library/PeiServicesTablePointerLibIdt/PeiServicesTablePointerLibIdt.inf7
-rw-r--r--MdePkg/Library/UefiDevicePathLib/DevicePathFromText.c112
-rw-r--r--MdePkg/Library/UefiDevicePathLib/DevicePathToText.c23
-rw-r--r--MdePkg/MdePkg.dec51
-rw-r--r--MdePkg/MdePkg.dsc1
-rw-r--r--NetworkPkg/IScsiDxe/IScsiConfigNVDataStruc.h6
-rw-r--r--NetworkPkg/IScsiDxe/IScsiDriver.c37
-rw-r--r--NetworkPkg/IScsiDxe/IScsiMisc.c96
-rw-r--r--NetworkPkg/IScsiDxe/IScsiMisc.h18
-rw-r--r--NetworkPkg/IScsiDxe/IScsiProto.c6
-rw-r--r--Nt32Pkg/Nt32Pkg.dsc13
-rw-r--r--OptionRomPkg/Bus/Usb/FtdiUsbSerialDxe/CompatibleDevices.txt5
-rw-r--r--OptionRomPkg/Bus/Usb/FtdiUsbSerialDxe/ComponentName.c224
-rw-r--r--OptionRomPkg/Bus/Usb/FtdiUsbSerialDxe/FtdiUsbSerialDriver.c2588
-rw-r--r--OptionRomPkg/Bus/Usb/FtdiUsbSerialDxe/FtdiUsbSerialDriver.h595
-rw-r--r--OptionRomPkg/Bus/Usb/FtdiUsbSerialDxe/FtdiUsbSerialDxe.inf61
-rw-r--r--OptionRomPkg/Bus/Usb/FtdiUsbSerialDxe/ReadMe.txt32
-rw-r--r--OptionRomPkg/OptionRomPkg.dsc1
-rw-r--r--OvmfPkg/AcpiPlatformDxe/AcpiPlatformDxe.inf1
-rw-r--r--OvmfPkg/AcpiPlatformDxe/Qemu.c2
-rw-r--r--OvmfPkg/EmuVariableFvbRuntimeDxe/Fvb.c6
-rw-r--r--OvmfPkg/Include/IndustryStandard/Virtio.h97
-rw-r--r--OvmfPkg/Library/PlatformBdsLib/BdsPlatform.c15
-rw-r--r--OvmfPkg/Library/PlatformBdsLib/PlatformBdsLib.inf1
-rw-r--r--OvmfPkg/OvmfPkg.dec13
-rw-r--r--OvmfPkg/OvmfPkgIa32.dsc10
-rw-r--r--OvmfPkg/OvmfPkgIa32.fdf110
-rw-r--r--OvmfPkg/OvmfPkgIa32X64.dsc10
-rw-r--r--OvmfPkg/OvmfPkgIa32X64.fdf110
-rw-r--r--OvmfPkg/OvmfPkgX64.dsc10
-rw-r--r--OvmfPkg/OvmfPkgX64.fdf110
-rw-r--r--OvmfPkg/PlatformPei/Platform.c2
-rw-r--r--OvmfPkg/QemuFlashFvbServicesRuntimeDxe/FvbInfo.c137
-rw-r--r--OvmfPkg/QemuFlashFvbServicesRuntimeDxe/FvbServicesRuntimeDxe.inf84
-rw-r--r--OvmfPkg/QemuFlashFvbServicesRuntimeDxe/FwBlockService.c1227
-rw-r--r--OvmfPkg/QemuFlashFvbServicesRuntimeDxe/FwBlockService.h184
-rw-r--r--OvmfPkg/QemuFlashFvbServicesRuntimeDxe/QemuFlash.c265
-rw-r--r--OvmfPkg/QemuFlashFvbServicesRuntimeDxe/QemuFlash.h89
-rw-r--r--OvmfPkg/QemuVideoDxe/Driver.c4
-rw-r--r--OvmfPkg/QemuVideoDxe/Gop.c1
-rw-r--r--OvmfPkg/README37
-rwxr-xr-xOvmfPkg/build.sh54
-rw-r--r--SecurityPkg/Application/RngTest/RngTest.c234
-rw-r--r--SecurityPkg/Application/RngTest/RngTest.inf50
-rw-r--r--SecurityPkg/Library/DxeDeferImageLoadLib/DxeDeferImageLoadLib.c218
-rw-r--r--SecurityPkg/Library/DxeDeferImageLoadLib/DxeDeferImageLoadLib.h3
-rw-r--r--SecurityPkg/Library/DxeDeferImageLoadLib/DxeDeferImageLoadLib.inf3
-rw-r--r--SecurityPkg/Library/DxeImageVerificationLib/DxeImageVerificationLib.c7
-rw-r--r--SecurityPkg/RandomNumberGenerator/RngDxe/AesCore.c304
-rw-r--r--SecurityPkg/RandomNumberGenerator/RngDxe/AesCore.h37
-rw-r--r--SecurityPkg/RandomNumberGenerator/RngDxe/IA32/AsmRdRand.asm67
-rw-r--r--SecurityPkg/RandomNumberGenerator/RngDxe/IA32/GccRdRand.c69
-rw-r--r--SecurityPkg/RandomNumberGenerator/RngDxe/IA32/RdRandWord.c104
-rw-r--r--SecurityPkg/RandomNumberGenerator/RngDxe/RdRand.c395
-rw-r--r--SecurityPkg/RandomNumberGenerator/RngDxe/RdRand.h213
-rw-r--r--SecurityPkg/RandomNumberGenerator/RngDxe/RngDxe.c219
-rw-r--r--SecurityPkg/RandomNumberGenerator/RngDxe/RngDxe.inf77
-rw-r--r--SecurityPkg/RandomNumberGenerator/RngDxe/X64/AsmRdRand.asm83
-rw-r--r--SecurityPkg/RandomNumberGenerator/RngDxe/X64/GccRdRand.c95
-rw-r--r--SecurityPkg/RandomNumberGenerator/RngDxe/X64/RdRandWord.c70
-rw-r--r--SecurityPkg/SecurityPkg.dec9
-rw-r--r--SecurityPkg/SecurityPkg.dsc5
-rw-r--r--SecurityPkg/Tcg/TcgSmm/Tpm.asl2
-rw-r--r--SecurityPkg/Tcg/TrEESmm/Tpm.asl2
-rw-r--r--SecurityPkg/VariableAuthenticated/RuntimeDxe/AuthService.c19
-rw-r--r--SecurityPkg/VariableAuthenticated/RuntimeDxe/AuthService.h1
-rw-r--r--SecurityPkg/VariableAuthenticated/RuntimeDxe/Reclaim.c24
-rw-r--r--SecurityPkg/VariableAuthenticated/RuntimeDxe/Variable.c381
-rw-r--r--SecurityPkg/VariableAuthenticated/RuntimeDxe/Variable.h16
-rw-r--r--SecurityPkg/VariableAuthenticated/RuntimeDxe/VariableDxe.c1
-rw-r--r--SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigImpl.c4
-rw-r--r--ShellPkg/Application/Shell/ConsoleLogger.c5
-rw-r--r--ShellPkg/Application/Shell/ConsoleWrappers.c34
-rw-r--r--ShellPkg/Application/Shell/ConsoleWrappers.h11
-rw-r--r--ShellPkg/Application/Shell/FileHandleWrappers.c43
-rw-r--r--ShellPkg/Application/Shell/Shell.c42
-rw-r--r--ShellPkg/Application/Shell/ShellManParser.c16
-rw-r--r--ShellPkg/Application/Shell/ShellParametersProtocol.c44
-rw-r--r--ShellPkg/Include/Library/ShellLib.h17
-rw-r--r--ShellPkg/Library/UefiHandleParsingLib/UefiHandleParsingLib.c17
-rw-r--r--ShellPkg/Library/UefiHandleParsingLib/UefiHandleParsingLib.h6
-rw-r--r--ShellPkg/Library/UefiHandleParsingLib/UefiHandleParsingLib.inf6
-rw-r--r--ShellPkg/Library/UefiHandleParsingLib/UefiHandleParsingLib.unibin24050 -> 24454 bytes
-rw-r--r--ShellPkg/Library/UefiShellDebug1CommandsLib/Mm.c37
-rw-r--r--ShellPkg/Library/UefiShellDebug1CommandsLib/Pci.c497
-rw-r--r--ShellPkg/Library/UefiShellDebug1CommandsLib/Pci.h3
-rw-r--r--ShellPkg/Library/UefiShellLevel1CommandsLib/For.c35
-rw-r--r--ShellPkg/Library/UefiShellLevel1CommandsLib/If.c9
-rw-r--r--ShellPkg/Library/UefiShellLevel1CommandsLib/UefiShellLevel1CommandsLib.c7
-rw-r--r--ShellPkg/Library/UefiShellLevel2CommandsLib/Map.c91
-rw-r--r--ShellPkg/Library/UefiShellLib/UefiShellLib.c28
-rw-r--r--SourceLevelDebugPkg/Library/DebugAgent/DebugAgentCommon/DebugAgent.c108
-rw-r--r--SourceLevelDebugPkg/Library/DebugAgent/DebugAgentCommon/DebugAgent.h12
-rw-r--r--SourceLevelDebugPkg/Library/DebugAgent/DebugAgentCommon/Ia32/AsmFuncs.S27
-rw-r--r--SourceLevelDebugPkg/Library/DebugAgent/DebugAgentCommon/Ia32/AsmFuncs.asm27
-rw-r--r--SourceLevelDebugPkg/Library/DebugAgent/DebugAgentCommon/X64/AsmFuncs.S27
-rw-r--r--SourceLevelDebugPkg/Library/DebugAgent/DebugAgentCommon/X64/AsmFuncs.asm27
-rw-r--r--SourceLevelDebugPkg/Library/DebugAgent/DxeDebugAgent/DxeDebugAgentLib.c45
-rw-r--r--SourceLevelDebugPkg/Library/DebugAgent/DxeDebugAgentLib.inf6
-rw-r--r--SourceLevelDebugPkg/Library/DebugAgent/SecPeiDebugAgent/SecPeiDebugAgentLib.c100
-rw-r--r--SourceLevelDebugPkg/Library/DebugAgent/SecPeiDebugAgentLib.inf1
-rw-r--r--SourceLevelDebugPkg/Library/DebugAgent/SmmDebugAgent/SmmDebugAgentLib.c15
-rw-r--r--SourceLevelDebugPkg/Library/DebugAgent/SmmDebugAgent/SmmDebugAgentLib.h3
-rw-r--r--SourceLevelDebugPkg/Library/DebugAgent/SmmDebugAgentLib.inf2
-rw-r--r--SourceLevelDebugPkg/Library/PeCoffExtraActionLibDebug/Ia32/IntHandlerFuncs.c9
-rw-r--r--SourceLevelDebugPkg/Library/PeCoffExtraActionLibDebug/PeCoffExtraActionLib.c17
-rw-r--r--SourceLevelDebugPkg/Library/PeCoffExtraActionLibDebug/PeCoffExtraActionLib.h7
-rw-r--r--SourceLevelDebugPkg/Library/PeCoffExtraActionLibDebug/X64/IntHandlerFuncs.c11
-rw-r--r--StdLib/EfiSocketLib/EfiSocketLib.inf2
-rw-r--r--StdLib/EfiSocketLib/Ip4.c275
-rw-r--r--StdLib/EfiSocketLib/Socket.c43
-rw-r--r--StdLib/EfiSocketLib/Socket.h20
-rw-r--r--StdLib/EfiSocketLib/Tcp4.c156
-rw-r--r--StdLib/EfiSocketLib/Tcp6.c259
-rw-r--r--StdLib/EfiSocketLib/Udp4.c265
-rw-r--r--StdLib/EfiSocketLib/Udp6.c391
-rw-r--r--StdLib/Fixes.txt41
-rw-r--r--StdLib/ISSUES.txt76
-rw-r--r--StdLib/Include/Efi/EfiSocketLib.h2
-rw-r--r--StdLib/ReadMe.txt209
-rw-r--r--StdLib/StdLib.dsc18
-rw-r--r--StdLibPrivateInternalFiles/ReadMe.txt209
-rw-r--r--UefiCpuPkg/CpuDxe/CpuDxe.c424
-rw-r--r--UefiCpuPkg/CpuDxe/CpuDxe.h45
-rw-r--r--UefiCpuPkg/CpuDxe/CpuDxe.inf9
-rw-r--r--UefiCpuPkg/CpuDxe/Ia32/CpuAsm.S310
-rw-r--r--UefiCpuPkg/CpuDxe/Ia32/CpuAsm.asm307
-rw-r--r--UefiCpuPkg/CpuDxe/Ia32/IvtAsm.S818
-rw-r--r--UefiCpuPkg/CpuDxe/Ia32/IvtAsm.asm51
-rw-r--r--UefiCpuPkg/CpuDxe/X64/CpuAsm.S287
-rw-r--r--UefiCpuPkg/CpuDxe/X64/CpuAsm.asm279
-rw-r--r--UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.c39
-rw-r--r--UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.h158
-rw-r--r--UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeCpuExceptionHandlerLib.inf (renamed from UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeSmmCpuExceptionHandlerLib.inf)20
-rw-r--r--UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeException.c170
-rw-r--r--UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeSmmCpuException.c264
-rw-r--r--UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ArchExceptionHandler.c104
-rw-r--r--UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ArchInterruptDefs.h44
-rw-r--r--UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ExceptionHandlerAsm.S342
-rw-r--r--UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ExceptionHandlerAsm.asm209
-rw-r--r--UefiCpuPkg/Library/CpuExceptionHandlerLib/SecPeiCpuException.c142
-rw-r--r--UefiCpuPkg/Library/CpuExceptionHandlerLib/SecPeiCpuExceptionHandlerLib.inf7
-rw-r--r--UefiCpuPkg/Library/CpuExceptionHandlerLib/SmmCpuExceptionHandlerLib.inf64
-rw-r--r--UefiCpuPkg/Library/CpuExceptionHandlerLib/SmmException.c101
-rw-r--r--UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchExceptionHandler.c115
-rw-r--r--UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchInterruptDefs.h46
-rw-r--r--UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ExceptionHandlerAsm.S343
-rw-r--r--UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ExceptionHandlerAsm.asm216
-rw-r--r--UefiCpuPkg/UefiCpuPkg.dsc8
391 files changed, 23918 insertions, 9135 deletions
diff --git a/AppPkg/AppPkg.dsc b/AppPkg/AppPkg.dsc
index 23ebf4773..d0aac2c50 100644
--- a/AppPkg/AppPkg.dsc
+++ b/AppPkg/AppPkg.dsc
@@ -27,11 +27,18 @@
BUILD_TARGETS = DEBUG|RELEASE
SKUID_IDENTIFIER = DEFAULT
+#
+# Debug output control
+#
+ DEFINE DEBUG_ENABLE_OUTPUT = FALSE # Set to TRUE to enable debug output
+ DEFINE DEBUG_PRINT_ERROR_LEVEL = 0x80000040 # Flags to control amount of debug output
+ DEFINE DEBUG_PROPERTY_MASK = 0
+
[PcdsFeatureFlag]
[PcdsFixedAtBuild]
- gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0x00
- gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0x80000040
+ gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|$(DEBUG_PROPERTY_MASK)
+ gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|$(DEBUG_PRINT_ERROR_LEVEL)
[PcdsFixedAtBuild.IPF]
@@ -53,12 +60,12 @@
MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf
UefiBootServicesTableLib|MdePkg/Library/UefiBootServicesTableLib/UefiBootServicesTableLib.inf
UefiRuntimeServicesTableLib|MdePkg/Library/UefiRuntimeServicesTableLib/UefiRuntimeServicesTableLib.inf
- #
- # To enable debugging:
- # Enable ONE of the following DebugLib instances, as appropriate for your platform.
- #
- DebugLib|MdePkg/Library/BaseDebugLibNull/BaseDebugLibNull.inf
-# DebugLib|MdePkg/Library/UefiDebugLibConOut/UefiDebugLibConOut.inf
+ !if $(DEBUG_ENABLE_OUTPUT)
+ DebugLib|MdePkg/Library/UefiDebugLibConOut/UefiDebugLibConOut.inf
+ DebugPrintErrorLevelLib|MdePkg/Library/BaseDebugPrintErrorLevelLib/BaseDebugPrintErrorLevelLib.inf
+ !else ## DEBUG_ENABLE_OUTPUT
+ DebugLib|MdePkg/Library/BaseDebugLibNull/BaseDebugLibNull.inf
+ !endif ## DEBUG_ENABLE_OUTPUT
DevicePathLib|MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.inf
PeCoffGetEntryPointLib|MdePkg/Library/BasePeCoffGetEntryPointLib/BasePeCoffGetEntryPointLib.inf
diff --git a/AppPkg/Applications/Python/PythonReadMe.txt b/AppPkg/Applications/Python/PythonReadMe.txt
index cf51b99ad..7d8b31f74 100644
--- a/AppPkg/Applications/Python/PythonReadMe.txt
+++ b/AppPkg/Applications/Python/PythonReadMe.txt
@@ -1,7 +1,7 @@
EDK II Python
ReadMe
- Beta Release
- 23 Mar. 2012
+ Release 1.02
+ 18 Jan. 2013
1. OVERVIEW
@@ -16,18 +16,19 @@ packages within that distribution.
2. Release Notes
================
- 1) There is no input line editing. Backspace, ^C, etc. do not work.
- 2) All C extension modules must be statically linked (built in)
- 3) The site and os modules must exist as discrete files in ...\lib\python.27
- 4) User-specific configurations are not supported.
- 5) Environment variables are not supported.
+ 1) All C extension modules must be statically linked (built in)
+ 2) The site and os modules must exist as discrete files in ...\lib\python.27
+ 3) User-specific configurations are not supported.
+ 4) Environment variables are not supported.
-3. Getting and Building the latest version of Python
+3. Getting and Building Python
======================================================
3.1 Getting Python
==================
- Currently only version 2.7.2 of the CPython distribution is supported. The
- source code can be downloaded from http://www.python.org/download/source/.
+ Currently only version 2.7.2 of the CPython distribution is supported. For development
+ ease, a subset of the Python 2.7.2 distribution has been included in the AppPkg source
+ tree. If a full distribution is desired, the Python-2.7.2 directory can be removed or
+ renamed and the full source code downloaded from http://www.python.org/ftp/python/2.7.2/.
A. Within your EDK II development tree, extract the Python distribution into
AppPkg/Applications/Python. This should create the
@@ -93,7 +94,8 @@ system as follows:
site types copy_reg linecache genericpath
* Python C Extension Modules built as dynamically loadable extensions go into
- the \Efi\StdLib\lib\python.27\lib-dynload directory.
+ the \Efi\StdLib\lib\python.27\lib-dynload directory. This functionality is not
+ yet implemented.
6. Example: Enabling socket support
@@ -191,6 +193,6 @@ Library that have been tested or used in some manner.
dummy_thread.py random.py weakref.py
fileinput.py re.py xmllib.py
formatter.py repr.py zipfile.py
- functools.py runpy.py
+ functools.py runpy.py expat
# # #
diff --git a/AppPkg/ReadMe.txt b/AppPkg/ReadMe.txt
index 003969196..35e3b6a87 100644
--- a/AppPkg/ReadMe.txt
+++ b/AppPkg/ReadMe.txt
@@ -1,9 +1,8 @@
- EADK
+ EADK
EDK II Standard Libraries and Applications
ReadMe
- Beta-1 Release
- 27 Jan. 2012
- DRAFT
+ Version 1.02
+ 21 Dec. 2012
OVERVIEW
@@ -17,8 +16,9 @@ At this time, applications developed with the EADK are intended to reside
on, and be loaded from, storage separate from the core firmware. This is
primarily due to size and environmental requirements.
-Some components of the EADK can be built as drivers. These will be identified
-explicitly in their documentation.
+This release of the EADK should only be used to produce UEFI Applications. Due to the execution
+environment built by the StdLib component, execution as a UEFI driver can cause system stability
+issues.
This document describes the EDK II specific aspects of installing, building,
and using the Standard C Library component of the EDK II Application
@@ -28,7 +28,7 @@ The EADK is comprised of three packages:
AppPkg, StdLib, and StdLibPrivateInternalFiles.
AppPkg This package contains applications which demonstrate use of the
- Standard C Library.
+ Standard C and Sockets Libraries.
These applications reside in AppPkg/Applications.
Enquire This is a program that determines many properties of the
@@ -43,7 +43,7 @@ The EADK is comprised of three packages:
Main This application is functionally identical to Hello, except that
it uses the Standard C Library to provide a main() entry point.
- Python A port of the Python-2.7.2 interpreter for UEFI. This
+ Python A port of the Python-2.7.2 interpreter for UEFI. Building this
application is disabled by default.
See the PythonReadMe.txt file, in the Python directory,
for information on configuring and building Python.
@@ -51,28 +51,19 @@ The EADK is comprised of three packages:
Sockets A collection of applications demonstrating use of the
EDK II Socket Libraries. These applications include:
- * DataSink
- * DataSource
- * GetAddrInfo
- * GetHostByAddr
- * GetHostByDns
- * GetHostByName
- * GetNetByAddr
- * GetNetByName
- * GetServByName
- * GetServByPort
- * OobRx
- * OobTx
- * RawIp4Rx
- * RawIp4Tx
- * RecvDgram
- * SetHostName
- * SetSockOpt
- * TftpServer
+ * DataSink * DataSource
+ * GetAddrInfo * GetHostByAddr
+ * GetHostByDns * GetHostByName
+ * GetNetByAddr * GetNetByName
+ * GetServByName * GetServByPort
+ * OobRx * OobTx
+ * RawIp4Rx * RawIp4Tx
+ * RecvDgram * SetHostName
+ * SetSockOpt * TftpServer
* WebServer
StdLib The StdLib package contains the standard header files as well as
- implementations of standards based libraries.
+ implementations of other standards-based libraries.
* BsdSocketLib
Support routines above the sockets layer and C interface for
@@ -109,44 +100,31 @@ RELEASE NOTES
=============
Fixes and Additions
-------------------
-Beginning with this release, applications built with the StdLib package
+Beginning with release 1.01, applications built with the StdLib package
no longer have a dependency on the TimerLib.
Known Issues
-----------------
This release of the EADK has some restrictions, as described below.
- 1. Only the Microsoft VS2005 and VS2008, Intel C Compiler 10.1 (or later),
- GCC 4.3 (mingw32), GCC 4.4, and GCC 4.5 C compilers are supported for
- Ia32 or X64 CPU architectures. Others may work but have not been tested.
-
- 2. The target machine must be running firmware which provides the
+ 1. The target machine must be running firmware which provides the
UEFI 2.3 HII protocol.
- 3. The EADK has not been through Intel's Quality Assurance process. This
- means that specified standards compliance has not been validated, nor
- has it undergone formal functionality testing.
-
- 4. Applications must be launched from within the EFI Shell.
+ 2. Applications must be launched from within the EFI Shell.
- 6. Absolute file paths may optionally be prefixed by a volume specifier
+ 3. Absolute file paths may optionally be prefixed by a volume specifier
such as "FS0:". The volume specifier is separated from the remainder
of the path by a single colon ':'. The volume specifier must be one of
the Shell's mapped volume names as shown by the "map" command.
- 7. Absolute file paths that don't begin with a volume specifier;
+ 4. Absolute file paths that don't begin with a volume specifier;
e.g. paths that begin with "/", are relative to the currently selected
volume. When the EFI Shell first starts, there is NO selected volume.
- 8. The tmpfile(), and related, functions require that the current volume
+ 5. The tmpfile(), and related, functions require that the current volume
have a temporary directory as specified in <paths.h>. This directory
is specified by macro _PATH_TMP as /Efi/StdLib/tmp.
- 9. Input line editing is not supported. Backspacing, deleting, or
- otherwise attempting to modify interactive input will result in a
- syntax error since the editing characters are interpreted the
- same as any other character.
-
The Standard C Library provided by this package is a "hosted" implementation
conforming to the ISO/IEC 9899-1990 C Language Standard with Addendum 1. This
is commonly referred to as the "C 95" specification or ISO/IEC 9899:199409.
@@ -164,21 +142,19 @@ installed by extracting, downloading or copying them to the root of your EDK II
source tree. The three package directories should be peers to the Conf,
MdePkg, Nt32Pkg, etc. directories.
-The Python 2.7.2 distribution must be downloaded from python.org before the
-Python application can be built. Extracting Python-2.7.2.tgz into the
-AppPkg\Applications\Python directory will produce a Python-2.7.2 directory
-containing the Python distribution. Python files that had to be modified for
-EDK II are in the AppPkg\Applications\Python\PyMod-2.7.2 directory. These
-files need to be copied into the corresponding directories within Python-2.7.2.
-
-The Python 2.7.1 port was superseded before it was completed. The PyMod-2.7.1
-directory tree will be deleted in the near future. Use the Python 2.7.2 port,
-as described above.
-
There are some boiler-plate declarations and definitions that need to be
included in your application's INF and DSC build files. These are described
in the CONFIGURATION section, below.
+A subset of the Python 2.7.2 distribution is included as part of AppPkg. If desired,
+the full Python 2.7.2 distribution may be downloaded from python.org and used instead.
+Delete or rename the existing Python-2.7.2 directory then extract the downloaded
+Python-2.7.2.tgz file into the AppPkg\Applications\Python directory. This will produce a
+Python-2.7.2 directory containing the full Python distribution. Python files that had to be
+modified for EDK II are in the AppPkg\Applications\Python\PyMod-2.7.2 directory. These
+files need to be copied into the corresponding directories within the extracted Python-2.7.2
+directory before Python can be built.
+
BUILDING
========
@@ -240,13 +216,13 @@ LibUefi sys/EfiSysCall.h Provides the UEFI system interface and
"System Calls"
LibWchar wchar.h Extended multibyte and wide character utilities
LibNetUtil Network address and number manipulation utilities
-DevConsole Automatically provided File I/O abstractions for
+DevConsole Automatically provided File I/O abstractions for
the UEFI Console device. No need to list this
library class in your INF file(s).
DevShell Add if desired File I/O abstractions using UEFI shell
facilities. Add this to the application's main
INF file if file-system access needed.
-DevUtility -- Do Not Use -- Utility functions used by the Device abstractions
+DevUtility -- Do Not Use -- Utility functions used internally by the Device abstractions
LibGdtoa -- Do Not Use -- This library is used internally and should not
need to be explicitly specified by an
application. It must be defined as one of the
@@ -256,6 +232,10 @@ LibGdtoa -- Do Not Use -- This library is used internally and should not
Table 1: Standard Libraries
============================
+The DevConsole and DevShell libraries provide device I/O functionality and are treated
+specially. DevConsole is automatically included so there is no need to reference it in your
+application's DSC or INF files. DevShell must be listed, in your application's INF file in the
+[LibraryClasses] section, if your application does file I/O.
These libraries must be fully described in the [LibraryClasses] section of the
application package's DSC file. Then, each individual application needs to
@@ -264,6 +244,11 @@ above table, in the [LibraryClasses] section of the application's INF file. The
AppPkg.dsc, StdLib.dsc, and Enquire.inf files provide good examples of this.
More details are in the CONFIGURATION section, below.
+In order to simplify this process, the [LibraryClasses] definitions, and others, are
+specified in the StdLib.inc file. If this file is included in the DSC file, usually at the
+end, then other DSC file changes or additions are unnecessary. This is further described in
+the CONFIGURATION section, below.
+
Within the source files of the application, use of the Standard headers and
library functions follow standard C programming practices as formalized by
ISO/IEC 9899:1990, with Addendum 1, (C 95) C language specification.
@@ -281,8 +266,44 @@ consolidated into a single file, StdLib/StdLib.inc, which can be included in
your .dsc file using the !include directive. The provided AppPkg.dsc and
StdLib.dsc files do this on their last line.
+The "boilerplate" text can be included using a !include directive in the
+package's .dsc file. The provided AppPkg.dsc and StdLib.dsc files include
+the following "boilerplate" text:
+
+ ##############################################################################
+ #
+ # Specify whether we are running in an emulation environment, or not.
+ # Define EMULATE if we are, else keep the DEFINE commented out.
+ #
+ # DEFINE EMULATE = 1
+
+ ##############################################################################
+ #
+ # Include Boilerplate text required for building with the Standard Libraries.
+ #
+ ##############################################################################
+ !include StdLib/StdLib.inc
+
+ Figure 1: "Boilerplate" Inclusion
+ =================================
+
+The EMULATE macro must be defined if one desires to do source-level debugging within one of
+the emulated environments such as NT32Pkg or UnixPkg.
+
+The final boilerplate line, in Figure 1, includes the StdLib.inc file.
Each section of StdLib/StdLib.inc is described below.
+If desired, all of the Socket applications, in AppPkg, can be built by including Sockets.inc:
+
+ !include AppPkg/Applications/Sockets/Sockets.inc
+
+ Figure 2: Socket Applications "Boilerplate" Inclusion
+ =====================================================
+
+
+Descriptions of the Library Classes comprising the Standard Libraries,
+as shown in Figure 3: Library Class Descriptions, are provided.
+
[LibraryClasses]
#
# C Standard Libraries
@@ -318,14 +339,11 @@ Each section of StdLib/StdLib.inc is described below.
[LibraryClasses.ARM.UEFI_APPLICATION]
NULL|ArmPkg/Library/CompilerIntrinsicsLib/CompilerIntrinsicsLib.inf
- Figure 1: Library Class Descriptions
+ Figure 3: Library Class Descriptions
====================================
-Descriptions of the Library Classes comprising the Standard Libraries,
-as shown above in Figure 1: Library Class Descriptions, are provided.
-
-The directives in Figure 2: Package Component Descriptions will create
+The directives in Figure 4: Package Component Descriptions will create
instances of the BaseLib and BaseMemoryLib library classes that are built
with Link-time-Code-Generation disabled. This is necessary when using the
Microsoft tool chains in order to allow the library's functions to be
@@ -354,50 +372,43 @@ A DXE driver version of the Socket library is also built.
##########
StdLib/SocketDxe/SocketDxe.inf
- Figure 2: Package Component Descriptions
+ Figure 4: Package Component Descriptions
========================================
Each compiler assumes, by default, that it will be used with standard libraries
and headers provided by the compiler vendor. Many of these assumptions are
incorrect for the UEFI environment. By including a BuildOptions section, as
-shown in Figure 3: Package Build Options, these assumptions can be
+shown in Figure 5: Package Build Options, these assumptions can be
tailored for compatibility with UEFI and the EDK II Standard Libraries.
+Note that the set of BuildOptions used is determined by the state of the EMULATE macro.
+
[BuildOptions]
+ !ifndef $(EMULATE)
+ # These Build Options are used when building the Standard Libraries to be run
+ # on real hardware.
INTEL:*_*_IA32_CC_FLAGS = /Qfreestanding
MSFT:*_*_IA32_CC_FLAGS = /X /Zc:wchar_t
GCC:*_*_IA32_CC_FLAGS = -nostdinc -nostdlib
- # The Build Options, below, are only used when building the C library
- # to be run under an emulation environment. They disable optimization
- # which facillitates debugging under the Emulation environment.
+ !else
+ # The Build Options, below, are only used when building the Standard Libraries
+ # to be run under an emulation environment.
+ # They disable optimization which facillitates debugging under the Emulation environment.
+ INTEL:*_*_IA32_CC_FLAGS = /Od
+ MSFT:*_*_IA32_CC_FLAGS = /Od
+ GCC:*_*_IA32_CC_FLAGS = -O0
- # INTEL:*_*_IA32_CC_FLAGS = /Od
- # MSFT:*_*_IA32_CC_FLAGS = /Od
- # GCC:*_*_IA32_CC_FLAGS = -O0
-
- Figure 4: Package Build Options
+ Figure 5: Package Build Options
===============================
-The "boilerplate" text can be included using a !include directive in the
-package's .dsc file. The provided AppPkg.dsc and StdLib.dsc files include
-the "boilerplate" text as follows:
-
- # Include Boilerplate text required for building with the Standard Libraries.
- #
- #############################################################################
- !include StdLib/StdLib.inc
-
- Figure 5: "Boilerplate" Inclusion
- =================================
-
INF Files
=========
The INF files for most modules will not require special directives in order to
-support the Standard Libraries. The two cases which could occur are described
-below.
+support the Standard Libraries. The two sections which require attention: LibraryClasses
+and BuildOptions, are described below.
[LibraryClasses]
UefiLib
@@ -410,9 +421,16 @@ below.
================================
-Modules of type UEFI_APPLICATION that perform file I/O should include library
+Modules of type UEFI_APPLICATION that perform file I/O must include library
class DevShell. Including this library class will allow file operations to be
-handled by the UEFI Shell. Without this class, only Console I/O is permitted.
+handled by the UEFI Shell. Without this class, only Console I/O is supported.
+
+
+An application's INF file might need to include a [BuildOptions] section
+specifying additional compiler and linker flags necessary to allow the
+application to be built. Usually, this section is not needed. When building
+code from external sources, though, it may be necessary to disable some
+warnings or enable/disable some compiler features.
[BuildOptions]
INTEL:*_*_*_CC_FLAGS = /Qdiag-disable:181,186
@@ -423,13 +441,6 @@ handled by the UEFI Shell. Without this class, only Console I/O is permitted.
==============================
-An application's INF file may need to include a [BuildOptions] section
-specifying additional compiler and linker flags necessary to allow the
-application to be built. Usually, this section is not needed. When building
-code from external sources, though, it may be necessary to disable some
-warnings or enable/disable some compiler features.
-
-
TARGET-SYSTEM INSTALLATION
==========================
Applications that use file system features or the Socket library depend upon
@@ -444,13 +455,13 @@ the application was loaded from. This tree structure is described below:
|- /tmp Temporary files created by tmpfile(), etc.
-The /Efi/StdLib/etc directory is populated from the StdLib/Efi/etc source
+The /Efi/StdLib/etc directory must be manually populated from the StdLib/Efi/etc source
directory.
IMPLEMENTATION-Specific Features
================================
It is very strongly recommended that applications not use the long or
-unsigned long types. The size of this type varies between compilers and is one
+unsigned long types. The size of these types varies between compilers and is one
of the less portable aspects of C. Instead, one should use the UEFI defined
types whenever possible. Use of these types, listed below for reference,
ensures that the declared objects have unambiguous, explicitly declared, sizes
diff --git a/ArmPkg/ArmPkg.dec b/ArmPkg/ArmPkg.dec
index 0f094c12a..1d6231c67 100644
--- a/ArmPkg/ArmPkg.dec
+++ b/ArmPkg/ArmPkg.dec
@@ -81,7 +81,7 @@
gArmTokenSpaceGuid.PcdCpuResetAddress|0x00000000|UINT32|0x00000005
#
- # ARM PL390 General Interrupt Controller
+ # ARM General Interrupt Controller
#
gArmTokenSpaceGuid.PcdGicDistributorBase|0|UINT32|0x0000000C
gArmTokenSpaceGuid.PcdGicInterruptInterfaceBase|0|UINT32|0x0000000D
diff --git a/ArmPkg/ArmPkg.dsc b/ArmPkg/ArmPkg.dsc
index eb9791c58..661453c29 100644
--- a/ArmPkg/ArmPkg.dsc
+++ b/ArmPkg/ArmPkg.dsc
@@ -62,7 +62,7 @@
DefaultExceptionHandlerLib|ArmPkg/Library/DefaultExceptionHandlerLib/DefaultExceptionHandlerLib.inf
CpuLib|MdePkg/Library/BaseCpuLib/BaseCpuLib.inf
- ArmGicLib|ArmPkg/Drivers/PL390Gic/PL390GicLib.inf
+ ArmGicLib|ArmPkg/Drivers/ArmGic/ArmGicLib.inf
ArmSmcLib|ArmPkg/Library/ArmSmcLib/ArmSmcLib.inf
ArmDisassemblerLib|ArmPkg/Library/ArmDisassemblerLib/ArmDisassemblerLib.inf
DmaLib|ArmPkg/Library/ArmDmaLib/ArmDmaLib.inf
@@ -119,9 +119,9 @@
ArmPkg/Drivers/CpuDxe/CpuDxe.inf
ArmPkg/Drivers/CpuPei/CpuPei.inf
- ArmPkg/Drivers/PL390Gic/PL390GicDxe.inf
- ArmPkg/Drivers/PL390Gic/PL390GicLib.inf
- ArmPkg/Drivers/PL390Gic/PL390GicSecLib.inf
+ ArmPkg/Drivers/ArmGic/ArmGicDxe.inf
+ ArmPkg/Drivers/ArmGic/ArmGicLib.inf
+ ArmPkg/Drivers/ArmGic/ArmGicSecLib.inf
ArmPkg/Drivers/TimerDxe/TimerDxe.inf
ArmPkg/Library/ArmSmcLib/ArmSmcLib.inf
diff --git a/ArmPkg/Drivers/PL390Gic/PL390Gic.c b/ArmPkg/Drivers/ArmGic/ArmGic.c
index 8a10d113f..8a10d113f 100644
--- a/ArmPkg/Drivers/PL390Gic/PL390Gic.c
+++ b/ArmPkg/Drivers/ArmGic/ArmGic.c
diff --git a/ArmPkg/Drivers/PL390Gic/PL390GicDxe.c b/ArmPkg/Drivers/ArmGic/ArmGicDxe.c
index 45a52be1c..111ce1443 100644
--- a/ArmPkg/Drivers/PL390Gic/PL390GicDxe.c
+++ b/ArmPkg/Drivers/ArmGic/ArmGicDxe.c
@@ -378,12 +378,12 @@ InterruptDxeInitialize (
CpuTarget = MmioRead32 (PcdGet32 (PcdGicDistributorBase) + ARM_GIC_ICDIPTR);
// The CPU target is a bit field mapping each CPU to a GIC CPU Interface. This value
- // is 0 when we run on a uniprocessor platform.
- if (CpuTarget != 0) {
- // The 8 first Interrupt Processor Targets Registers are read-only
- for (Index = 8; Index < (mGicNumInterrupts / 4); Index++) {
- MmioWrite32 (PcdGet32 (PcdGicDistributorBase) + ARM_GIC_ICDIPTR + (Index * 4), CpuTarget);
- }
+ // is 0 when we run on a uniprocessor platform.
+ if (CpuTarget != 0) {
+ // The 8 first Interrupt Processor Targets Registers are read-only
+ for (Index = 8; Index < (mGicNumInterrupts / 4); Index++) {
+ MmioWrite32 (PcdGet32 (PcdGicDistributorBase) + ARM_GIC_ICDIPTR + (Index * 4), CpuTarget);
+ }
}
// Set binary point reg to 0x7 (no preemption)
diff --git a/ArmPkg/Drivers/PL390Gic/PL390GicDxe.inf b/ArmPkg/Drivers/ArmGic/ArmGicDxe.inf
index cf0b8f3fe..9dc557a03 100644
--- a/ArmPkg/Drivers/PL390Gic/PL390GicDxe.inf
+++ b/ArmPkg/Drivers/ArmGic/ArmGicDxe.inf
@@ -15,7 +15,7 @@
[Defines]
INF_VERSION = 0x00010005
- BASE_NAME = PL390GicDxe
+ BASE_NAME = ArmGicDxe
FILE_GUID = DE371F7C-DEC4-4D21-ADF1-593ABCC15882
MODULE_TYPE = DXE_DRIVER
VERSION_STRING = 1.0
@@ -24,8 +24,8 @@
[Sources.common]
- PL390Gic.c
- PL390GicDxe.c
+ ArmGic.c
+ ArmGicDxe.c
[Packages]
MdePkg/MdePkg.dec
diff --git a/ArmPkg/Drivers/PL390Gic/PL390GicLib.inf b/ArmPkg/Drivers/ArmGic/ArmGicLib.inf
index d0cac0203..dab29b99c 100644
--- a/ArmPkg/Drivers/PL390Gic/PL390GicLib.inf
+++ b/ArmPkg/Drivers/ArmGic/ArmGicLib.inf
@@ -13,15 +13,15 @@
[Defines]
INF_VERSION = 0x00010005
- BASE_NAME = PL390GicLib
+ BASE_NAME = ArmGicLib
FILE_GUID = 03d05ee4-cdeb-458c-9dfc-993f09bdf405
MODULE_TYPE = SEC
VERSION_STRING = 1.0
LIBRARY_CLASS = ArmGicLib
[Sources]
- PL390Gic.c
- PL390GicNonSec.c
+ ArmGic.c
+ ArmGicNonSec.c
[LibraryClasses]
IoLib
diff --git a/ArmPkg/Drivers/PL390Gic/PL390GicNonSec.c b/ArmPkg/Drivers/ArmGic/ArmGicNonSec.c
index 55ff56e79..55ff56e79 100644
--- a/ArmPkg/Drivers/PL390Gic/PL390GicNonSec.c
+++ b/ArmPkg/Drivers/ArmGic/ArmGicNonSec.c
diff --git a/ArmPkg/Drivers/PL390Gic/PL390GicSec.c b/ArmPkg/Drivers/ArmGic/ArmGicSec.c
index bae76e441..bae76e441 100644
--- a/ArmPkg/Drivers/PL390Gic/PL390GicSec.c
+++ b/ArmPkg/Drivers/ArmGic/ArmGicSec.c
diff --git a/ArmPkg/Drivers/PL390Gic/PL390GicSecLib.inf b/ArmPkg/Drivers/ArmGic/ArmGicSecLib.inf
index 205e50342..bb7f24251 100644
--- a/ArmPkg/Drivers/PL390Gic/PL390GicSecLib.inf
+++ b/ArmPkg/Drivers/ArmGic/ArmGicSecLib.inf
@@ -13,15 +13,15 @@
[Defines]
INF_VERSION = 0x00010005
- BASE_NAME = PL390GicSecLib
+ BASE_NAME = ArmGicSecLib
FILE_GUID = 85f3cf80-b5f4-11df-9855-0002a5d5c51b
MODULE_TYPE = SEC
VERSION_STRING = 1.0
LIBRARY_CLASS = ArmGicLib
[Sources]
- PL390Gic.c
- PL390GicSec.c
+ ArmGic.c
+ ArmGicSec.c
[Packages]
ArmPkg/ArmPkg.dec
diff --git a/ArmPkg/Drivers/CpuDxe/ArmV6/ExceptionSupport.S b/ArmPkg/Drivers/CpuDxe/ArmV6/ExceptionSupport.S
index 612ca02c7..430bc5202 100644
--- a/ArmPkg/Drivers/CpuDxe/ArmV6/ExceptionSupport.S
+++ b/ArmPkg/Drivers/CpuDxe/ArmV6/ExceptionSupport.S
@@ -120,7 +120,6 @@ ASM_PFX(UndefinedInstructionEntry):
bx R1
ASM_PFX(SoftwareInterruptEntry):
- sub LR, LR, #4 @ Only -2 for Thumb, adjust in CommonExceptionEntry
srsdb #0x13! @ Store return state on SVC stack
@ We are already in SVC mode
stmfd SP!,{LR} @ Store the link register for the current mode
diff --git a/ArmPkg/Drivers/CpuDxe/ArmV6/ExceptionSupport.asm b/ArmPkg/Drivers/CpuDxe/ArmV6/ExceptionSupport.asm
index 780e1f7cd..f9672e4b6 100644
--- a/ArmPkg/Drivers/CpuDxe/ArmV6/ExceptionSupport.asm
+++ b/ArmPkg/Drivers/CpuDxe/ArmV6/ExceptionSupport.asm
@@ -115,7 +115,6 @@ UndefinedInstructionEntry
bx R1
SoftwareInterruptEntry
- sub LR, LR, #4 ; Only -2 for Thumb, adjust in CommonExceptionEntry
srsfd #0x13! ; Store return state on SVC stack
; We are already in SVC mode
stmfd SP!,{LR} ; Store the link register for the current mode
diff --git a/ArmPkg/Drivers/CpuPei/CpuPei.inf b/ArmPkg/Drivers/CpuPei/CpuPei.inf
index ec8b9f5c5..ebd1fe412 100755
--- a/ArmPkg/Drivers/CpuPei/CpuPei.inf
+++ b/ArmPkg/Drivers/CpuPei/CpuPei.inf
@@ -53,9 +53,6 @@
gEmbeddedTokenSpaceGuid.PcdPrePiCpuMemorySize
gEmbeddedTokenSpaceGuid.PcdPrePiCpuIoSize
-[FeaturePcd]
- gEmbeddedTokenSpaceGuid.PcdCacheEnable
-
-[depex]
+[Depex]
gEfiPeiMemoryDiscoveredPpiGuid
diff --git a/ArmPkg/Include/Chipset/AArch64.h b/ArmPkg/Include/Chipset/AArch64.h
index 8b6478600..e01158850 100644
--- a/ArmPkg/Include/Chipset/AArch64.h
+++ b/ArmPkg/Include/Chipset/AArch64.h
@@ -88,24 +88,6 @@ ArmWriteTpidrurw (
UINTN
EFIAPI
-ArmIsArchTimerImplemented (
- VOID
- );
-
-UINTN
-EFIAPI
-ArmReadIdPfr0 (
- VOID
- );
-
-UINTN
-EFIAPI
-ArmReadIdPfr1 (
- VOID
- );
-
-UINTN
-EFIAPI
ArmGetTCR (
VOID
);
diff --git a/ArmPkg/Include/Chipset/ArmV7.h b/ArmPkg/Include/Chipset/ArmV7.h
index 29922eca1..3fcc4264f 100644
--- a/ArmPkg/Include/Chipset/ArmV7.h
+++ b/ArmPkg/Include/Chipset/ArmV7.h
@@ -101,18 +101,6 @@ ArmWriteTpidrurw (
UINTN Value
);
-UINTN
-EFIAPI
-ArmIsArchTimerImplemented (
- VOID
- );
-
-UINTN
-EFIAPI
-ArmReadIdPfr1 (
- VOID
- );
-
UINT32
EFIAPI
ArmReadNsacr (
diff --git a/ArmPkg/Include/Library/ArmGicLib.h b/ArmPkg/Include/Library/ArmGicLib.h
index 429f8ade1..3280cf8ee 100644
--- a/ArmPkg/Include/Library/ArmGicLib.h
+++ b/ArmPkg/Include/Library/ArmGicLib.h
@@ -12,8 +12,8 @@
*
**/
-#ifndef __PL390GIC_H
-#define __PL390GIC_H
+#ifndef __ARMGIC_H
+#define __ARMGIC_H
//
// GIC definitions
diff --git a/ArmPkg/Include/Library/ArmLib.h b/ArmPkg/Include/Library/ArmLib.h
index bd1bbc40b..611622e1a 100644
--- a/ArmPkg/Include/Library/ArmLib.h
+++ b/ArmPkg/Include/Library/ArmLib.h
@@ -193,7 +193,25 @@ EFIAPI
ArmInstructionCacheLineLength (
VOID
);
-
+
+UINTN
+EFIAPI
+ArmIsArchTimerImplemented (
+ VOID
+ );
+
+UINTN
+EFIAPI
+ArmReadIdPfr0 (
+ VOID
+ );
+
+UINTN
+EFIAPI
+ArmReadIdPfr1 (
+ VOID
+ );
+
UINT32
EFIAPI
Cp15IdCode (
diff --git a/ArmPkg/Library/ArmArchTimerLib/ArmArchTimerLib.c b/ArmPkg/Library/ArmArchTimerLib/ArmArchTimerLib.c
index 970bde34c..4373e8c2e 100644
--- a/ArmPkg/Library/ArmArchTimerLib/ArmArchTimerLib.c
+++ b/ArmPkg/Library/ArmArchTimerLib/ArmArchTimerLib.c
@@ -1,7 +1,7 @@
/** @file
Generic ARM implementation of TimerLib.h
- Copyright (c) 2011-2012, ARM Limited. All rights reserved.
+ Copyright (c) 2011-2013, ARM Limited. All rights reserved.
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
@@ -15,12 +15,12 @@
#include <Base.h>
+#include <Library/ArmLib.h>
#include <Library/BaseLib.h>
#include <Library/TimerLib.h>
#include <Library/DebugLib.h>
#include <Library/PcdLib.h>
#include <Library/ArmArchTimerLib.h>
-#include <Chipset/ArmV7.h>
#define TICKS_PER_MICRO_SEC (PcdGet32 (PcdArmArchTimerFreqInHz)/1000000U)
diff --git a/ArmPkg/Library/BdsLib/BdsLinuxFdt.c b/ArmPkg/Library/BdsLib/BdsLinuxFdt.c
index 57d8dcc90..58db0bdd6 100644
--- a/ArmPkg/Library/BdsLib/BdsLinuxFdt.c
+++ b/ArmPkg/Library/BdsLib/BdsLinuxFdt.c
@@ -264,7 +264,7 @@ RelocateFdt (
{
EFI_STATUS Status;
INTN Error;
- UINT32 FdtAlignment;
+ UINT64 FdtAlignment;
*RelocatedFdtSize = OriginalFdtSize + FDT_ADDITIONAL_ENTRIES_SIZE;
diff --git a/ArmPkg/Library/DebugPeCoffExtraActionLib/DebugPeCoffExtraActionLib.c b/ArmPkg/Library/DebugPeCoffExtraActionLib/DebugPeCoffExtraActionLib.c
index 6d0bb988e..0758af8ac 100755
--- a/ArmPkg/Library/DebugPeCoffExtraActionLib/DebugPeCoffExtraActionLib.c
+++ b/ArmPkg/Library/DebugPeCoffExtraActionLib/DebugPeCoffExtraActionLib.c
@@ -87,14 +87,14 @@ PeCoffLoaderRelocateImageExtraAction (
#ifdef __CC_ARM
#if (__ARMCC_VERSION < 500000)
// Print out the command for the RVD debugger to load symbols for this image
- DEBUG ((EFI_D_ERROR, "load /a /ni /np %a &0x%08x\n", DeCygwinPathIfNeeded (ImageContext->PdbPointer, Temp, sizeof (Temp)), (UINTN)(ImageContext->ImageAddress + ImageContext->SizeOfHeaders)));
+ DEBUG ((EFI_D_ERROR, "load /a /ni /np %a &0x%p\n", DeCygwinPathIfNeeded (ImageContext->PdbPointer, Temp, sizeof (Temp)), (UINTN)(ImageContext->ImageAddress + ImageContext->SizeOfHeaders)));
#else
// Print out the command for the DS-5 to load symbols for this image
- DEBUG ((EFI_D_ERROR, "add-symbol-file %a 0x%08x\n", DeCygwinPathIfNeeded (ImageContext->PdbPointer, Temp, sizeof (Temp)), (UINTN)(ImageContext->ImageAddress + ImageContext->SizeOfHeaders)));
+ DEBUG ((EFI_D_ERROR, "add-symbol-file %a 0x%p\n", DeCygwinPathIfNeeded (ImageContext->PdbPointer, Temp, sizeof (Temp)), (UINTN)(ImageContext->ImageAddress + ImageContext->SizeOfHeaders)));
#endif
#elif __GNUC__
// This may not work correctly if you generate PE/COFF directlyas then the Offset would not be required
- DEBUG ((EFI_D_ERROR, "add-symbol-file %a 0x%08x\n", DeCygwinPathIfNeeded (ImageContext->PdbPointer, Temp, sizeof (Temp)), (UINTN)(ImageContext->ImageAddress + ImageContext->SizeOfHeaders)));
+ DEBUG ((EFI_D_ERROR, "add-symbol-file %a 0x%p\n", DeCygwinPathIfNeeded (ImageContext->PdbPointer, Temp, sizeof (Temp)), (UINTN)(ImageContext->ImageAddress + ImageContext->SizeOfHeaders)));
#else
DEBUG ((EFI_D_ERROR, "Loading driver at 0x%11p EntryPoint=0x%11p\n", (VOID *)(UINTN) ImageContext->ImageAddress, FUNCTION_ENTRY_POINT (ImageContext->EntryPoint)));
#endif
diff --git a/ArmPlatformPkg/ArmPlatformPkg-2ndstage.dsc b/ArmPlatformPkg/ArmPlatformPkg-2ndstage.dsc
index b8b439555..264099c7b 100644
--- a/ArmPlatformPkg/ArmPlatformPkg-2ndstage.dsc
+++ b/ArmPlatformPkg/ArmPlatformPkg-2ndstage.dsc
@@ -77,7 +77,7 @@
CpuExceptionHandlerLib|MdeModulePkg/Library/CpuExceptionHandlerLibNull/CpuExceptionHandlerLibNull.inf
ArmDisassemblerLib|ArmPkg/Library/ArmDisassemblerLib/ArmDisassemblerLib.inf
DmaLib|ArmPkg/Library/ArmDmaLib/ArmDmaLib.inf
- ArmGicLib|ArmPkg/Drivers/PL390Gic/PL390GicLib.inf
+ ArmGicLib|ArmPkg/Drivers/ArmGic/ArmGicLib.inf
ArmPlatformStackLib|ArmPlatformPkg/Library/ArmPlatformStackLib/ArmPlatformStackLib.inf
ArmSmcLib|ArmPkg/Library/ArmSmcLib/ArmSmcLib.inf
@@ -225,8 +225,6 @@
gArmPlatformTokenSpaceGuid.PcdFirmwareVendor|"ARM Platform"
gEmbeddedTokenSpaceGuid.PcdEmbeddedPrompt|"ArmPlatform"
- gEmbeddedTokenSpaceGuid.PcdPrePiCpuMemorySize|32
- gEmbeddedTokenSpaceGuid.PcdPrePiCpuIoSize|0
gEfiMdePkgTokenSpaceGuid.PcdMaximumUnicodeStringLength|1000000
gEfiMdePkgTokenSpaceGuid.PcdMaximumAsciiStringLength|1000000
gEfiMdePkgTokenSpaceGuid.PcdMaximumLinkedListLength|1000000
diff --git a/ArmPlatformPkg/ArmPlatformPkg.dsc b/ArmPlatformPkg/ArmPlatformPkg.dsc
index c353e6f90..ce31abcdc 100644
--- a/ArmPlatformPkg/ArmPlatformPkg.dsc
+++ b/ArmPlatformPkg/ArmPlatformPkg.dsc
@@ -77,7 +77,7 @@
CpuExceptionHandlerLib|MdeModulePkg/Library/CpuExceptionHandlerLibNull/CpuExceptionHandlerLibNull.inf
ArmDisassemblerLib|ArmPkg/Library/ArmDisassemblerLib/ArmDisassemblerLib.inf
DmaLib|ArmPkg/Library/ArmDmaLib/ArmDmaLib.inf
- ArmGicLib|ArmPkg/Drivers/PL390Gic/PL390GicLib.inf
+ ArmGicLib|ArmPkg/Drivers/ArmGic/ArmGicLib.inf
ArmSmcLib|ArmPkg/Library/ArmSmcLib/ArmSmcLib.inf
SerialPortLib|MdePkg/Library/BaseSerialPortLibNull/BaseSerialPortLibNull.inf
@@ -258,8 +258,6 @@
gArmPlatformTokenSpaceGuid.PcdFirmwareVendor|"ARM Platform"
gEmbeddedTokenSpaceGuid.PcdEmbeddedPrompt|"ArmPlatform"
- gEmbeddedTokenSpaceGuid.PcdPrePiCpuMemorySize|32
- gEmbeddedTokenSpaceGuid.PcdPrePiCpuIoSize|0
gEfiMdePkgTokenSpaceGuid.PcdMaximumUnicodeStringLength|1000000
gEfiMdePkgTokenSpaceGuid.PcdMaximumAsciiStringLength|1000000
gEfiMdePkgTokenSpaceGuid.PcdMaximumLinkedListLength|1000000
@@ -353,7 +351,7 @@
ArmPlatformPkg/Sec/Sec.inf {
<LibraryClasses>
# Use the implementation which set the Secure bits
- ArmGicLib|ArmPkg/Drivers/PL390Gic/PL390GicSecLib.inf
+ ArmGicLib|ArmPkg/Drivers/ArmGic/ArmGicSecLib.inf
}
#
diff --git a/ArmPlatformPkg/ArmRealViewEbPkg/ArmRealViewEb-RTSM-A8.dsc b/ArmPlatformPkg/ArmRealViewEbPkg/ArmRealViewEb-RTSM-A8.dsc
index c4a1df5a0..998b82629 100644
--- a/ArmPlatformPkg/ArmRealViewEbPkg/ArmRealViewEb-RTSM-A8.dsc
+++ b/ArmPlatformPkg/ArmRealViewEbPkg/ArmRealViewEb-RTSM-A8.dsc
@@ -123,7 +123,7 @@
gEfiMdeModulePkgTokenSpaceGuid.PcdSerialRegisterBase|0x10009000
#
- # ARM PL390 General Interrupt Controller
+ # ARM General Interrupt Controller
#
gArmTokenSpaceGuid.PcdGicDistributorBase|0x10041000
gArmTokenSpaceGuid.PcdGicInterruptInterfaceBase|0x10040000
@@ -142,7 +142,7 @@
ArmPlatformPkg/Sec/Sec.inf {
<LibraryClasses>
# Use the implementation which set the Secure bits
- ArmGicLib|ArmPkg/Drivers/PL390Gic/PL390GicSecLib.inf
+ ArmGicLib|ArmPkg/Drivers/ArmGic/ArmGicSecLib.inf
}
#
@@ -211,7 +211,7 @@
MdeModulePkg/Universal/Console/TerminalDxe/TerminalDxe.inf
EmbeddedPkg/SerialDxe/SerialDxe.inf
- ArmPkg/Drivers/PL390Gic/PL390GicDxe.inf
+ ArmPkg/Drivers/ArmGic/ArmGicDxe.inf
ArmPlatformPkg/Drivers/SP804TimerDxe/SP804TimerDxe.inf
ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashDxe.inf
diff --git a/ArmPlatformPkg/ArmRealViewEbPkg/ArmRealViewEb-RTSM-A9x2.dsc b/ArmPlatformPkg/ArmRealViewEbPkg/ArmRealViewEb-RTSM-A9x2.dsc
index 2686df4ee..36bd1ab3e 100644
--- a/ArmPlatformPkg/ArmRealViewEbPkg/ArmRealViewEb-RTSM-A9x2.dsc
+++ b/ArmPlatformPkg/ArmRealViewEbPkg/ArmRealViewEb-RTSM-A9x2.dsc
@@ -122,7 +122,7 @@
gEfiMdeModulePkgTokenSpaceGuid.PcdSerialRegisterBase|0x10009000
#
- # ARM PL390 General Interrupt Controller
+ # ARM General Interrupt Controller
#
gArmTokenSpaceGuid.PcdGicDistributorBase|0x1F001000
gArmTokenSpaceGuid.PcdGicInterruptInterfaceBase|0x1F000100
@@ -145,7 +145,7 @@
ArmPlatformPkg/Sec/Sec.inf {
<LibraryClasses>
# Use the implementation which set the Secure bits
- ArmGicLib|ArmPkg/Drivers/PL390Gic/PL390GicSecLib.inf
+ ArmGicLib|ArmPkg/Drivers/ArmGic/ArmGicSecLib.inf
}
#
@@ -211,7 +211,7 @@
MdeModulePkg/Universal/Console/TerminalDxe/TerminalDxe.inf
EmbeddedPkg/SerialDxe/SerialDxe.inf
- ArmPkg/Drivers/PL390Gic/PL390GicDxe.inf
+ ArmPkg/Drivers/ArmGic/ArmGicDxe.inf
ArmPlatformPkg/Drivers/SP804TimerDxe/SP804TimerDxe.inf
ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashDxe.inf
diff --git a/ArmPlatformPkg/ArmRealViewEbPkg/ArmRealViewEb-RTSM-MPCore.fdf b/ArmPlatformPkg/ArmRealViewEbPkg/ArmRealViewEb-RTSM-MPCore.fdf
index babadd87e..7b96b0e05 100644
--- a/ArmPlatformPkg/ArmRealViewEbPkg/ArmRealViewEb-RTSM-MPCore.fdf
+++ b/ArmPlatformPkg/ArmRealViewEbPkg/ArmRealViewEb-RTSM-MPCore.fdf
@@ -138,7 +138,7 @@ READ_LOCK_STATUS = TRUE
INF MdeModulePkg/Universal/Console/TerminalDxe/TerminalDxe.inf
INF EmbeddedPkg/SerialDxe/SerialDxe.inf
- INF ArmPkg/Drivers/PL390Gic/PL390GicDxe.inf
+ INF ArmPkg/Drivers/ArmGic/ArmGicDxe.inf
INF ArmPlatformPkg/Drivers/SP804TimerDxe/SP804TimerDxe.inf
INF ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashDxe.inf
diff --git a/ArmPlatformPkg/ArmRealViewEbPkg/ArmRealViewEb-RTSM-UniCore.fdf b/ArmPlatformPkg/ArmRealViewEbPkg/ArmRealViewEb-RTSM-UniCore.fdf
index 2e8ae2f50..705e21802 100644
--- a/ArmPlatformPkg/ArmRealViewEbPkg/ArmRealViewEb-RTSM-UniCore.fdf
+++ b/ArmPlatformPkg/ArmRealViewEbPkg/ArmRealViewEb-RTSM-UniCore.fdf
@@ -139,7 +139,7 @@ READ_LOCK_STATUS = TRUE
INF MdeModulePkg/Universal/Console/TerminalDxe/TerminalDxe.inf
INF EmbeddedPkg/SerialDxe/SerialDxe.inf
- INF ArmPkg/Drivers/PL390Gic/PL390GicDxe.inf
+ INF ArmPkg/Drivers/ArmGic/ArmGicDxe.inf
INF ArmPlatformPkg/Drivers/SP804TimerDxe/SP804TimerDxe.inf
INF ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashDxe.inf
diff --git a/ArmPlatformPkg/ArmRealViewEbPkg/ArmRealViewEb.dsc.inc b/ArmPlatformPkg/ArmRealViewEbPkg/ArmRealViewEb.dsc.inc
index bc4807f3f..3fb099ea6 100644
--- a/ArmPlatformPkg/ArmRealViewEbPkg/ArmRealViewEb.dsc.inc
+++ b/ArmPlatformPkg/ArmRealViewEbPkg/ArmRealViewEb.dsc.inc
@@ -60,7 +60,7 @@
CpuExceptionHandlerLib|MdeModulePkg/Library/CpuExceptionHandlerLibNull/CpuExceptionHandlerLibNull.inf
ArmDisassemblerLib|ArmPkg/Library/ArmDisassemblerLib/ArmDisassemblerLib.inf
DmaLib|ArmPkg/Library/ArmDmaLib/ArmDmaLib.inf
- ArmGicLib|ArmPkg/Drivers/PL390Gic/PL390GicLib.inf
+ ArmGicLib|ArmPkg/Drivers/ArmGic/ArmGicLib.inf
ArmSmcLib|ArmPkg/Library/ArmSmcLib/ArmSmcLib.inf
# RealView Emulation Board Specific Libraries
@@ -229,8 +229,6 @@
gEfiMdeModulePkgTokenSpaceGuid.PcdTurnOffUsbLegacySupport|TRUE
[PcdsFixedAtBuild.common]
- gEmbeddedTokenSpaceGuid.PcdPrePiCpuMemorySize|32
- gEmbeddedTokenSpaceGuid.PcdPrePiCpuIoSize|0
gEfiMdePkgTokenSpaceGuid.PcdMaximumUnicodeStringLength|1000000
gEfiMdePkgTokenSpaceGuid.PcdMaximumAsciiStringLength|1000000
gEfiMdePkgTokenSpaceGuid.PcdMaximumLinkedListLength|1000000
diff --git a/ArmPlatformPkg/ArmRealViewEbPkg/Library/ArmRealViewEbSecLibRTSM/ArmRealViewEbSecLib.inf b/ArmPlatformPkg/ArmRealViewEbPkg/Library/ArmRealViewEbSecLibRTSM/ArmRealViewEbSecLib.inf
index d4e383ace..68e355594 100644
--- a/ArmPlatformPkg/ArmRealViewEbPkg/Library/ArmRealViewEbSecLibRTSM/ArmRealViewEbSecLib.inf
+++ b/ArmPlatformPkg/ArmRealViewEbPkg/Library/ArmRealViewEbSecLibRTSM/ArmRealViewEbSecLib.inf
@@ -36,9 +36,6 @@
ArmRealViewEbBoot.asm | RVCT
ArmRealViewEbBoot.S | GCC
-[FeaturePcd]
- gEmbeddedTokenSpaceGuid.PcdCacheEnable
-
[FixedPcd]
gArmTokenSpaceGuid.PcdFvBaseAddress
diff --git a/ArmPlatformPkg/ArmVExpressPkg/ArmVExpress-CTA15-A7.dsc b/ArmPlatformPkg/ArmVExpressPkg/ArmVExpress-CTA15-A7.dsc
index abdeeabcb..5ea1d9008 100644
--- a/ArmPlatformPkg/ArmVExpressPkg/ArmVExpress-CTA15-A7.dsc
+++ b/ArmPlatformPkg/ArmVExpressPkg/ArmVExpress-CTA15-A7.dsc
@@ -43,8 +43,8 @@
#DebugAgentTimerLib|ArmPlatformPkg/ArmVExpressPkg/Library/DebugAgentTimerLib/DebugAgentTimerLib.inf
- # ARM PL390 General Interrupt Driver in Secure and Non-secure
- ArmGicLib|ArmPkg/Drivers/PL390Gic/PL390GicLib.inf
+ # ARM General Interrupt Driver in Secure and Non-secure
+ ArmGicLib|ArmPkg/Drivers/ArmGic/ArmGicLib.inf
LcdPlatformLib|ArmPlatformPkg/ArmVExpressPkg/Library/HdLcdArmVExpressLib/HdLcdArmVExpressLib.inf
@@ -167,7 +167,7 @@
#
- # ARM PL390 General Interrupt Controller
+ # ARM General Interrupt Controller
#
gArmTokenSpaceGuid.PcdGicDistributorBase|0x2C001000
gArmTokenSpaceGuid.PcdGicInterruptInterfaceBase|0x2C002000
@@ -184,7 +184,7 @@
gArmPlatformTokenSpaceGuid.PcdDefaultBootDevicePath|L"VenHw(09831032-6FA3-4484-AF4F-0A000A8D3A82)/HD(1,MBR,0x00000000,0x3F,0x19FC0)/uImage"
gArmPlatformTokenSpaceGuid.PcdDefaultBootInitrdPath|L"VenHw(09831032-6FA3-4484-AF4F-0A000A8D3A82)/HD(1,MBR,0x00000000,0x3F,0x19FC0)/uInitrd"
gArmPlatformTokenSpaceGuid.PcdDefaultFdtLocalDevicePath|L"VenHw(09831032-6FA3-4484-AF4F-0A000A8D3A82)/HD(1,MBR,0x00000000,0x3F,0x19FC0)/v2p-ca15-tc2.dtb"
- gArmPlatformTokenSpaceGuid.PcdDefaultBootArgument|"console=ttyAMA0,38400n8 root=/dev/mmcblk0p2 rootwait ro androidboot.console=ttyAMA0"
+ gArmPlatformTokenSpaceGuid.PcdDefaultBootArgument|"console=ttyAMA0,38400n8 rootwait root=/dev/mmcblk0p2"
gArmPlatformTokenSpaceGuid.PcdDefaultBootType|3
gArmPlatformTokenSpaceGuid.PcdFdtDevicePath|L"VenHw(09831032-6FA3-4484-AF4F-0A000A8D3A82)/HD(1,MBR,0x00000000,0x3F,0x19FC0)/v2p-ca15-tc2.dtb"
@@ -251,14 +251,7 @@
MdeModulePkg/Universal/HiiDatabaseDxe/HiiDatabaseDxe.inf
- #
- # ACPI Support
- #
- MdeModulePkg/Universal/Acpi/AcpiPlatformDxe/AcpiPlatformDxe.inf
- MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableDxe.inf
- ArmPkg/Drivers/AcpiTables/rtsm_ve-v7/AcpiTables.inf
-
- ArmPkg/Drivers/PL390Gic/PL390GicDxe.inf
+ ArmPkg/Drivers/ArmGic/ArmGicDxe.inf
ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashDxe.inf
#ArmPlatformPkg/Drivers/LcdGraphicsOutputDxe/PL111LcdGraphicsOutputDxe.inf
ArmPlatformPkg/Drivers/LcdGraphicsOutputDxe/HdLcdGraphicsOutputDxe.inf
@@ -285,6 +278,8 @@
MdeModulePkg/Universal/Disk/PartitionDxe/PartitionDxe.inf
MdeModulePkg/Universal/Disk/UnicodeCollation/EnglishDxe/EnglishDxe.inf
+ MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableDxe.inf
+
#
# Bds
#
diff --git a/ArmPlatformPkg/ArmVExpressPkg/ArmVExpress-CTA15-A7.fdf b/ArmPlatformPkg/ArmVExpressPkg/ArmVExpress-CTA15-A7.fdf
index ffd72cdc4..948985c6b 100644
--- a/ArmPlatformPkg/ArmVExpressPkg/ArmVExpress-CTA15-A7.fdf
+++ b/ArmPlatformPkg/ArmVExpressPkg/ArmVExpress-CTA15-A7.fdf
@@ -26,12 +26,12 @@
[FD.ARM_VEXPRESS_CTA15A7_EFI]
BaseAddress = 0x81000000|gArmTokenSpaceGuid.PcdFdBaseAddress # The base address of the Firmware in remapped DRAM.
-Size = 0x000D2000|gArmTokenSpaceGuid.PcdFdSize # The size in bytes of the FLASH Device
+Size = 0x000D5000|gArmTokenSpaceGuid.PcdFdSize # The size in bytes of the FLASH Device
ErasePolarity = 1
BlockSize = 0x00001000
-NumBlocks = 0xD2
+NumBlocks = 0xD5
-0x00000000|0x000D2000
+0x00000000|0x000D5000
gArmTokenSpaceGuid.PcdFvBaseAddress|gArmTokenSpaceGuid.PcdFvSize
FV = FVMAIN_COMPACT
@@ -82,14 +82,7 @@ READ_LOCK_STATUS = TRUE
INF EmbeddedPkg/MetronomeDxe/MetronomeDxe.inf
INF MdeModulePkg/Universal/HiiDatabaseDxe/HiiDatabaseDxe.inf
-
- #^M
- # ACPI Support^M
- #^M
- INF MdeModulePkg/Universal/Acpi/AcpiPlatformDxe/AcpiPlatformDxe.inf
- INF MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableDxe.inf
- INF RuleOverride=ACPITABLE ArmPkg/Drivers/AcpiTables/rtsm_ve-v7/AcpiTables.inf
-
+
#
# Multiple Console IO support
#
@@ -99,7 +92,7 @@ READ_LOCK_STATUS = TRUE
INF MdeModulePkg/Universal/Console/TerminalDxe/TerminalDxe.inf
INF EmbeddedPkg/SerialDxe/SerialDxe.inf
- INF ArmPkg/Drivers/PL390Gic/PL390GicDxe.inf
+ INF ArmPkg/Drivers/ArmGic/ArmGicDxe.inf
INF ArmPkg/Drivers/TimerDxe/TimerDxe.inf
INF ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashDxe.inf
#INF ArmPlatformPkg/Drivers/LcdGraphicsOutputDxe/PL111LcdGraphicsOutputDxe.inf
@@ -127,6 +120,8 @@ READ_LOCK_STATUS = TRUE
INF FatBinPkg/EnhancedFatDxe/Fat.inf
INF MdeModulePkg/Universal/Disk/UnicodeCollation/EnglishDxe/EnglishDxe.inf
+ INF MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableDxe.inf
+
#
# Networking stack
#
@@ -286,11 +281,3 @@ READ_LOCK_STATUS = TRUE
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
- UI STRING="$(MODULE_NAME)" Optional
- }
-
diff --git a/ArmPlatformPkg/ArmVExpressPkg/ArmVExpress-CTA15x2.dsc b/ArmPlatformPkg/ArmVExpressPkg/ArmVExpress-CTA15x2.dsc
index 2238936c2..79b5b2018 100644
--- a/ArmPlatformPkg/ArmVExpressPkg/ArmVExpress-CTA15x2.dsc
+++ b/ArmPlatformPkg/ArmVExpressPkg/ArmVExpress-CTA15x2.dsc
@@ -60,10 +60,6 @@
# Uncomment to turn on GDB stub in SEC.
#DebugAgentLib|EmbeddedPkg/Library/GdbDebugAgent/GdbDebugAgent.inf
-
- # ARM PL390 General Interrupt Driver in Secure and Non-secure
- ArmGicSecLib|ArmPkg/Drivers/PL390Gic/PL390GicSecLib.inf
- ArmGicLib|ArmPkg/Drivers/PL390Gic/PL390GicLib.inf
[BuildOptions]
RVCT:*_*_ARM_PLATFORM_FLAGS == --cpu Cortex-A15 -I$(WORKSPACE)/ArmPlatformPkg/ArmVExpressPkg/Include -I$(WORKSPACE)/ArmPlatformPkg/ArmVExpressPkg/Include/Platform/CTA15x2
@@ -181,7 +177,7 @@
gArmPlatformTokenSpaceGuid.PcdDefaultBootDevicePath|L"VenHw(09831032-6FA3-4484-AF4F-0A000A8D3A82)/HD(1,MBR,0x00000000,0x3F,0x19FC0)/uImage"
gArmPlatformTokenSpaceGuid.PcdDefaultBootInitrdPath|L"VenHw(09831032-6FA3-4484-AF4F-0A000A8D3A82)/HD(1,MBR,0x00000000,0x3F,0x19FC0)/uInitrd"
gArmPlatformTokenSpaceGuid.PcdDefaultFdtLocalDevicePath|L"VenHw(09831032-6FA3-4484-AF4F-0A000A8D3A82)/HD(1,MBR,0x00000000,0x3F,0x19FC0)/v2p-ca15-tc1.dtb"
- gArmPlatformTokenSpaceGuid.PcdDefaultBootArgument|"console=ttyAMA0,38400n8 root=/dev/mmcblk0p2 rootwait ro androidboot.console=ttyAMA0 mmci.fmax=12000000"
+ gArmPlatformTokenSpaceGuid.PcdDefaultBootArgument|"console=ttyAMA0,38400n8 rootwait root=/dev/mmcblk0p2"
gArmPlatformTokenSpaceGuid.PcdDefaultBootType|3
gArmPlatformTokenSpaceGuid.PcdFdtDevicePath|L"VenHw(09831032-6FA3-4484-AF4F-0A000A8D3A82)/HD(1,MBR,0x00000000,0x3F,0x19FC0)/v2p-ca15-tc1.dtb"
@@ -213,7 +209,7 @@
ArmPlatformPkg/Sec/Sec.inf {
<LibraryClasses>
# Use the implementation which set the Secure bits
- ArmGicLib|ArmPkg/Drivers/PL390Gic/PL390GicSecLib.inf
+ ArmGicLib|ArmPkg/Drivers/ArmGic/ArmGicSecLib.inf
}
#
@@ -292,7 +288,7 @@
MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableDxe.inf
ArmPkg/Drivers/AcpiTables/rtsm_ve-v7/AcpiTables.inf
- ArmPkg/Drivers/PL390Gic/PL390GicDxe.inf
+ ArmPkg/Drivers/ArmGic/ArmGicDxe.inf
ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashDxe.inf
ArmPlatformPkg/Drivers/SP804TimerDxe/SP804TimerDxe.inf
#ArmPlatformPkg/Drivers/LcdGraphicsOutputDxe/PL111LcdGraphicsOutputDxe.inf
diff --git a/ArmPlatformPkg/ArmVExpressPkg/ArmVExpress-CTA15x2.fdf b/ArmPlatformPkg/ArmVExpressPkg/ArmVExpress-CTA15x2.fdf
index cc53102c8..f28a0aa8d 100644
--- a/ArmPlatformPkg/ArmVExpressPkg/ArmVExpress-CTA15x2.fdf
+++ b/ArmPlatformPkg/ArmVExpressPkg/ArmVExpress-CTA15x2.fdf
@@ -156,7 +156,7 @@ READ_LOCK_STATUS = TRUE
INF MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableDxe.inf
INF RuleOverride=ACPITABLE ArmPkg/Drivers/AcpiTables/rtsm_ve-v7/AcpiTables.inf
- INF ArmPkg/Drivers/PL390Gic/PL390GicDxe.inf
+ INF ArmPkg/Drivers/ArmGic/ArmGicDxe.inf
INF ArmPlatformPkg/Drivers/SP804TimerDxe/SP804TimerDxe.inf
INF ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashDxe.inf
#INF ArmPlatformPkg/Drivers/LcdGraphicsOutputDxe/PL111LcdGraphicsOutputDxe.inf
diff --git a/ArmPlatformPkg/ArmVExpressPkg/ArmVExpress-CTA5s.dsc b/ArmPlatformPkg/ArmVExpressPkg/ArmVExpress-CTA5s.dsc
index 8f59e8ba0..e28d79f78 100644
--- a/ArmPlatformPkg/ArmVExpressPkg/ArmVExpress-CTA5s.dsc
+++ b/ArmPlatformPkg/ArmVExpressPkg/ArmVExpress-CTA5s.dsc
@@ -60,10 +60,6 @@
# Uncomment to turn on GDB stub in SEC.
#DebugAgentLib|EmbeddedPkg/Library/GdbDebugAgent/GdbDebugAgent.inf
-
- # ARM PL390 General Interrupt Driver in Secure and Non-secure
- ArmGicSecLib|ArmPkg/Drivers/PL390Gic/PL390GicSecLib.inf
- ArmGicLib|ArmPkg/Drivers/PL390Gic/PL390GicLib.inf
[BuildOptions]
RVCT:*_*_ARM_PLATFORM_FLAGS == --cpu Cortex-A5 -I$(WORKSPACE)/ArmPlatformPkg/ArmVExpressPkg/Include -I$(WORKSPACE)/ArmPlatformPkg/ArmVExpressPkg/Include/Platform/CTA5s
@@ -178,7 +174,7 @@
gArmPlatformTokenSpaceGuid.PcdDefaultBootDevicePath|L"VenHw(09831032-6FA3-4484-AF4F-0A000A8D3A82)/HD(1,MBR,0x00000000,0x3F,0x19FC0)/uImage"
gArmPlatformTokenSpaceGuid.PcdDefaultBootInitrdPath|L"VenHw(09831032-6FA3-4484-AF4F-0A000A8D3A82)/HD(1,MBR,0x00000000,0x3F,0x19FC0)/uInitrd"
gArmPlatformTokenSpaceGuid.PcdDefaultFdtLocalDevicePath|L"VenHw(09831032-6FA3-4484-AF4F-0A000A8D3A82)/HD(1,MBR,0x00000000,0x3F,0x19FC0)/v2p-ca5s.dtb"
- gArmPlatformTokenSpaceGuid.PcdDefaultBootArgument|"console=ttyAMA0,38400n8 root=/dev/mmcblk0p2 rootwait ro androidboot.console=ttyAMA0 mmci.fmax=12000000"
+ gArmPlatformTokenSpaceGuid.PcdDefaultBootArgument|"console=ttyAMA0,38400n8 rootwait root=/dev/mmcblk0p2"
gArmPlatformTokenSpaceGuid.PcdDefaultBootType|3
gArmPlatformTokenSpaceGuid.PcdFdtDevicePath|L"VenHw(09831032-6FA3-4484-AF4F-0A000A8D3A82)/HD(1,MBR,0x00000000,0x3F,0x19FC0)/v2p-ca5s.dtb"
@@ -204,7 +200,7 @@
ArmPlatformPkg/Sec/Sec.inf {
<LibraryClasses>
# Use the implementation which set the Secure bits
- ArmGicLib|ArmPkg/Drivers/PL390Gic/PL390GicSecLib.inf
+ ArmGicLib|ArmPkg/Drivers/ArmGic/ArmGicSecLib.inf
}
#
@@ -283,7 +279,7 @@
MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableDxe.inf
ArmPkg/Drivers/AcpiTables/rtsm_ve-v7/AcpiTables.inf
- ArmPkg/Drivers/PL390Gic/PL390GicDxe.inf
+ ArmPkg/Drivers/ArmGic/ArmGicDxe.inf
ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashDxe.inf
ArmPlatformPkg/Drivers/SP804TimerDxe/SP804TimerDxe.inf
#ArmPlatformPkg/Drivers/LcdGraphicsOutputDxe/PL111LcdGraphicsOutputDxe.inf
diff --git a/ArmPlatformPkg/ArmVExpressPkg/ArmVExpress-CTA5s.fdf b/ArmPlatformPkg/ArmVExpressPkg/ArmVExpress-CTA5s.fdf
index dc54a3bf2..109061803 100644
--- a/ArmPlatformPkg/ArmVExpressPkg/ArmVExpress-CTA5s.fdf
+++ b/ArmPlatformPkg/ArmVExpressPkg/ArmVExpress-CTA5s.fdf
@@ -156,7 +156,7 @@ READ_LOCK_STATUS = TRUE
INF MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableDxe.inf
INF RuleOverride=ACPITABLE ArmPkg/Drivers/AcpiTables/rtsm_ve-v7/AcpiTables.inf
- INF ArmPkg/Drivers/PL390Gic/PL390GicDxe.inf
+ INF ArmPkg/Drivers/ArmGic/ArmGicDxe.inf
INF ArmPlatformPkg/Drivers/SP804TimerDxe/SP804TimerDxe.inf
INF ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashDxe.inf
#INF ArmPlatformPkg/Drivers/LcdGraphicsOutputDxe/PL111LcdGraphicsOutputDxe.inf
diff --git a/ArmPlatformPkg/ArmVExpressPkg/ArmVExpress-CTA9x4.dsc b/ArmPlatformPkg/ArmVExpressPkg/ArmVExpress-CTA9x4.dsc
index 875d0a305..2c3ef61ca 100644
--- a/ArmPlatformPkg/ArmVExpressPkg/ArmVExpress-CTA9x4.dsc
+++ b/ArmPlatformPkg/ArmVExpressPkg/ArmVExpress-CTA9x4.dsc
@@ -92,7 +92,7 @@
################################################################################
[PcdsFeatureFlag.common]
-!ifdef EDK2_ARMVE_STANDALONE
+!if $(EDK2_ARMVE_STANDALONE) == 1
gArmPlatformTokenSpaceGuid.PcdStandalone|TRUE
!else
gArmPlatformTokenSpaceGuid.PcdStandalone|FALSE
@@ -178,7 +178,7 @@
gArmPlatformTokenSpaceGuid.PcdPL180MciBaseAddress|0x10005000
#
- # ARM PL390 General Interrupt Controller
+ # ARM General Interrupt Controller
#
gArmTokenSpaceGuid.PcdGicDistributorBase|0x1e001000
gArmTokenSpaceGuid.PcdGicInterruptInterfaceBase|0x1e000100
@@ -192,7 +192,7 @@
gArmPlatformTokenSpaceGuid.PcdDefaultBootDevicePath|L"VenHw(09831032-6FA3-4484-AF4F-0A000A8D3A82)/HD(1,MBR,0x00000000,0x3F,0x19FC0)/uImage"
gArmPlatformTokenSpaceGuid.PcdDefaultBootInitrdPath|L"VenHw(09831032-6FA3-4484-AF4F-0A000A8D3A82)/HD(1,MBR,0x00000000,0x3F,0x19FC0)/uInitrd"
gArmPlatformTokenSpaceGuid.PcdDefaultFdtLocalDevicePath|L"VenHw(09831032-6FA3-4484-AF4F-0A000A8D3A82)/HD(1,MBR,0x00000000,0x3F,0x19FC0)/v2p-ca9.dtb"
- gArmPlatformTokenSpaceGuid.PcdDefaultBootArgument|"console=ttyAMA0,38400n8 root=/dev/mmcblk0p2 rootwait ro androidboot.console=ttyAMA0"
+ gArmPlatformTokenSpaceGuid.PcdDefaultBootArgument|"console=ttyAMA0,38400n8 rootwait root=/dev/mmcblk0p2"
gArmPlatformTokenSpaceGuid.PcdDefaultBootType|3
gArmPlatformTokenSpaceGuid.PcdFdtDevicePath|L"VenHw(09831032-6FA3-4484-AF4F-0A000A8D3A82)/HD(1,MBR,0x00000000,0x3F,0x19FC0)/v2p-ca9.dtb"
@@ -223,7 +223,7 @@
ArmPlatformPkg/Sec/Sec.inf {
<LibraryClasses>
# Use the implementation which set the Secure bits
- ArmGicLib|ArmPkg/Drivers/PL390Gic/PL390GicSecLib.inf
+ ArmGicLib|ArmPkg/Drivers/ArmGic/ArmGicSecLib.inf
}
#
@@ -288,15 +288,15 @@
EmbeddedPkg/SerialDxe/SerialDxe.inf
MdeModulePkg/Universal/HiiDatabaseDxe/HiiDatabaseDxe.inf
+
+ #
+ # ACPI Support
+ #
+ MdeModulePkg/Universal/Acpi/AcpiPlatformDxe/AcpiPlatformDxe.inf
+ MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableDxe.inf
+ ArmPkg/Drivers/AcpiTables/rtsm_ve-v7/AcpiTables.inf
- #
- # ACPI Support
- #
- MdeModulePkg/Universal/Acpi/AcpiPlatformDxe/AcpiPlatformDxe.inf
- MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableDxe.inf
- ArmPkg/Drivers/AcpiTables/rtsm_ve-v7/AcpiTables.inf
-
- ArmPkg/Drivers/PL390Gic/PL390GicDxe.inf
+ ArmPkg/Drivers/ArmGic/ArmGicDxe.inf
ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashDxe.inf
ArmPlatformPkg/Drivers/SP804TimerDxe/SP804TimerDxe.inf
ArmPlatformPkg/Drivers/LcdGraphicsOutputDxe/PL111LcdGraphicsOutputDxe.inf
diff --git a/ArmPlatformPkg/ArmVExpressPkg/ArmVExpress-CTA9x4.fdf b/ArmPlatformPkg/ArmVExpressPkg/ArmVExpress-CTA9x4.fdf
index 51646c338..5abe648c6 100644
--- a/ArmPlatformPkg/ArmVExpressPkg/ArmVExpress-CTA9x4.fdf
+++ b/ArmPlatformPkg/ArmVExpressPkg/ArmVExpress-CTA9x4.fdf
@@ -186,15 +186,15 @@ READ_LOCK_STATUS = TRUE
INF EmbeddedPkg/SerialDxe/SerialDxe.inf
INF MdeModulePkg/Universal/HiiDatabaseDxe/HiiDatabaseDxe.inf
+
+ #
+ # ACPI Support
+ #
+ INF MdeModulePkg/Universal/Acpi/AcpiPlatformDxe/AcpiPlatformDxe.inf
+ INF MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableDxe.inf
+ INF RuleOverride=ACPITABLE ArmPkg/Drivers/AcpiTables/rtsm_ve-v7/AcpiTables.inf
- #
- # ACPI Support
- #
- INF MdeModulePkg/Universal/Acpi/AcpiPlatformDxe/AcpiPlatformDxe.inf
- INF MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableDxe.inf
- INF RuleOverride=ACPITABLE ArmPkg/Drivers/AcpiTables/rtsm_ve-v7/AcpiTables.inf
-
- INF ArmPkg/Drivers/PL390Gic/PL390GicDxe.inf
+ INF ArmPkg/Drivers/ArmGic/ArmGicDxe.inf
INF ArmPlatformPkg/Drivers/SP804TimerDxe/SP804TimerDxe.inf
INF ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashDxe.inf
INF ArmPlatformPkg/Drivers/LcdGraphicsOutputDxe/PL111LcdGraphicsOutputDxe.inf
@@ -393,11 +393,10 @@ READ_LOCK_STATUS = TRUE
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
- UI STRING="$(MODULE_NAME)" Optional
- }
-
+
+[Rule.Common.USER_DEFINED.ACPITABLE]
+ FILE FREEFORM = $(NAMED_GUID) {
+ RAW ACPI |.acpi
+ RAW ASL |.aml
+ UI STRING="$(MODULE_NAME)" Optional
+ }
diff --git a/ArmPlatformPkg/ArmVExpressPkg/ArmVExpress-FVP-AArch64.dsc b/ArmPlatformPkg/ArmVExpressPkg/ArmVExpress-FVP-AArch64.dsc
index 194be40a4..db61aa8e0 100755..100644
--- a/ArmPlatformPkg/ArmVExpressPkg/ArmVExpress-FVP-AArch64.dsc
+++ b/ArmPlatformPkg/ArmVExpressPkg/ArmVExpress-FVP-AArch64.dsc
@@ -1,256 +1,256 @@
-#
-# Copyright (c) 2011-2013, ARM Limited. All rights reserved.
-#
-# 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 = ArmVExpress-FVP-AArch64
- PLATFORM_GUID = 0de70077-9b3b-43bf-ba38-0ea37d77141b
- PLATFORM_VERSION = 0.1
- DSC_SPECIFICATION = 0x00010005
+#
+# Copyright (c) 2011-2013, ARM Limited. All rights reserved.
+#
+# 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 = ArmVExpress-FVP-AArch64
+ PLATFORM_GUID = 0de70077-9b3b-43bf-ba38-0ea37d77141b
+ PLATFORM_VERSION = 0.1
+ DSC_SPECIFICATION = 0x00010005
!ifdef $(EDK2_OUT_DIR)
OUTPUT_DIRECTORY = $(EDK2_OUT_DIR)
!else
- OUTPUT_DIRECTORY = Build/ArmVExpress-FVP-AArch64
+ OUTPUT_DIRECTORY = Build/ArmVExpress-FVP-AArch64
!endif
- SUPPORTED_ARCHITECTURES = AARCH64
- BUILD_TARGETS = DEBUG|RELEASE
- SKUID_IDENTIFIER = DEFAULT
- FLASH_DEFINITION = ArmPlatformPkg/ArmVExpressPkg/ArmVExpress-FVP-AArch64.fdf
-
-!include ArmPlatformPkg/ArmVExpressPkg/ArmVExpress.dsc.inc
-
-[LibraryClasses.common]
- ArmLib|ArmPkg/Library/ArmLib/AArch64/AArch64Lib.inf
- ArmCpuLib|ArmPkg/Drivers/ArmCpuLib/ArmCortexAEMv8Lib/ArmCortexAEMv8Lib.inf
- ArmPlatformLib|ArmPlatformPkg/ArmVExpressPkg/Library/ArmVExpressLibRTSM/ArmVExpressLib.inf
-
- ArmPlatformSysConfigLib|ArmPlatformPkg/ArmVExpressPkg/Library/ArmVExpressSysConfigLib/ArmVExpressSysConfigLib.inf
- NorFlashPlatformLib|ArmPlatformPkg/ArmVExpressPkg/Library/NorFlashArmVExpressLib/NorFlashArmVExpressLib.inf
-!ifndef ARM_FOUNDATION_FVP
- LcdPlatformLib|ArmPlatformPkg/ArmVExpressPkg/Library/PL111LcdArmVExpressLib/PL111LcdArmVExpressLib.inf
-!endif
-
- TimerLib|ArmPkg/Library/ArmArchTimerLib/ArmArchTimerLib.inf
-
-[LibraryClasses.common.SEC]
- ArmLib|ArmPkg/Library/ArmLib/AArch64/AArch64LibSec.inf
- ArmPlatformSecLib|ArmPlatformPkg/ArmVExpressPkg/Library/ArmVExpressSecLibRTSM/ArmVExpressSecLib.inf
- ArmPlatformLib|ArmPlatformPkg/ArmVExpressPkg/Library/ArmVExpressLibRTSM/ArmVExpressLibSec.inf
-
-[BuildOptions]
- GCC:*_*_AARCH64_PLATFORM_FLAGS == -I$(WORKSPACE)/ArmPlatformPkg/ArmVExpressPkg/Include -I$(WORKSPACE)/ArmPlatformPkg/ArmVExpressPkg/Include/Platform/RTSM
-
-
-################################################################################
-#
-# Pcd Section - list of all EDK II PCD Entries defined by this Platform
-#
-################################################################################
-
-[PcdsFeatureFlag.common]
-
- ## If TRUE, Graphics Output Protocol will be installed on virtual handle created by ConsplitterDxe.
- # It could be set FALSE to save size.
- gEfiMdeModulePkgTokenSpaceGuid.PcdConOutGopSupport|TRUE
-
- ## FVP platforms support hardware power control
- # Disabled for now as we have a version mismatch.
- gArmTokenSpaceGuid.PcdArmPsciSupport|FALSE
-
-[PcdsFixedAtBuild.common]
- gArmPlatformTokenSpaceGuid.PcdFirmwareVendor|"ARM Fixed Virtual Platform"
- gEmbeddedTokenSpaceGuid.PcdEmbeddedPrompt|"ARM-FVP"
-
- # Up to 8 cores on Base models. This works fine if model happens to have less.
- gArmPlatformTokenSpaceGuid.PcdCoreCount|8
-
- #
- # NV Storage PCDs. Use base of 0x0C000000 for NOR1
- #
- gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase|0x0FFC0000
- gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize|0x00010000
- gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingBase|0x0FFD0000
- gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingSize|0x00010000
- gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareBase|0x0FFE0000
- gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize|0x00010000
-
- gArmTokenSpaceGuid.PcdVFPEnabled|1
-
- # FVP models can have 2 clusters with 4 cpus each
- # Stacks for MPCores in Secure World
- # Trusted SRAM (DRAM on Foundation model)
- gArmPlatformTokenSpaceGuid.PcdCPUCoresSecStackBase|0x04000000
- gArmPlatformTokenSpaceGuid.PcdCPUCoreSecPrimaryStackSize|0x1000
- gArmPlatformTokenSpaceGuid.PcdCPUCoreSecSecondaryStackSize|0x800
-
- # Stacks for MPCores in Normal World
- # Non-Trusted SRAM
- gArmPlatformTokenSpaceGuid.PcdCPUCoresStackBase|0x2E000000
- gArmPlatformTokenSpaceGuid.PcdCPUCorePrimaryStackSize|0x4000
- gArmPlatformTokenSpaceGuid.PcdCPUCoreSecondaryStackSize|0x800
-
- # System Memory (2GB)
- gArmTokenSpaceGuid.PcdSystemMemoryBase|0x80000000
- gArmTokenSpaceGuid.PcdSystemMemorySize|0x80000000
-
- # Size of the region used by UEFI in permanent memory (Reserved 64MB)
- gArmPlatformTokenSpaceGuid.PcdSystemMemoryUefiRegionSize|0x04000000
-
- #
- # ARM Pcds
- #
- gArmTokenSpaceGuid.PcdArmUncachedMemoryMask|0x0000000040000000
-
- ## Trustzone enable (to make the transition from EL3 to NS EL2 in ArmPlatformPkg/Sec)
- gArmTokenSpaceGuid.PcdTrustzoneSupport|TRUE
-
- #
- # ARM PrimeCell
- #
-
- ## SP805 Watchdog - Motherboard Watchdog at 24MHz
- gArmPlatformTokenSpaceGuid.PcdSP805WatchdogBase|0x1C0F0000
- gArmPlatformTokenSpaceGuid.PcdSP805WatchdogClockFrequencyInHz|24000000
-
- ## PL011 - Serial Terminal
- gEfiMdeModulePkgTokenSpaceGuid.PcdSerialRegisterBase|0x1c090000
- gEfiMdePkgTokenSpaceGuid.PcdUartDefaultBaudRate|38400
-
- ## PL031 RealTimeClock
- gArmPlatformTokenSpaceGuid.PcdPL031RtcBase|0x1C170000
-
-!ifndef ARM_FOUNDATION_FVP
- ## PL111 Versatile Express Motherboard controller
- gArmPlatformTokenSpaceGuid.PcdPL111LcdBase|0x1C1F0000
-
- ## PL180 MMC/SD card controller
- gArmPlatformTokenSpaceGuid.PcdPL180SysMciRegAddress|0x1C010048
- gArmPlatformTokenSpaceGuid.PcdPL180MciBaseAddress|0x1C050000
-!endif
-
- #
- # ARM General Interrupt Controller
- #
-!ifdef ARM_FVP_LEGACY_GICV2_LOCATION
- gArmTokenSpaceGuid.PcdGicDistributorBase|0x2C001000
- gArmTokenSpaceGuid.PcdGicInterruptInterfaceBase|0x2C002000
-!else
- gArmTokenSpaceGuid.PcdGicDistributorBase|0x2f000000
- gArmTokenSpaceGuid.PcdGicInterruptInterfaceBase|0x2C000000
-!endif
-
+ SUPPORTED_ARCHITECTURES = AARCH64
+ BUILD_TARGETS = DEBUG|RELEASE
+ SKUID_IDENTIFIER = DEFAULT
+ FLASH_DEFINITION = ArmPlatformPkg/ArmVExpressPkg/ArmVExpress-FVP-AArch64.fdf
+
+!include ArmPlatformPkg/ArmVExpressPkg/ArmVExpress.dsc.inc
+
+[LibraryClasses.common]
+ ArmLib|ArmPkg/Library/ArmLib/AArch64/AArch64Lib.inf
+ ArmCpuLib|ArmPkg/Drivers/ArmCpuLib/ArmCortexAEMv8Lib/ArmCortexAEMv8Lib.inf
+ ArmPlatformLib|ArmPlatformPkg/ArmVExpressPkg/Library/ArmVExpressLibRTSM/ArmVExpressLib.inf
+
+ ArmPlatformSysConfigLib|ArmPlatformPkg/ArmVExpressPkg/Library/ArmVExpressSysConfigLib/ArmVExpressSysConfigLib.inf
+ NorFlashPlatformLib|ArmPlatformPkg/ArmVExpressPkg/Library/NorFlashArmVExpressLib/NorFlashArmVExpressLib.inf
+!ifndef ARM_FOUNDATION_FVP
+ LcdPlatformLib|ArmPlatformPkg/ArmVExpressPkg/Library/PL111LcdArmVExpressLib/PL111LcdArmVExpressLib.inf
+!endif
+
+ TimerLib|ArmPkg/Library/ArmArchTimerLib/ArmArchTimerLib.inf
+
+[LibraryClasses.common.SEC]
+ ArmLib|ArmPkg/Library/ArmLib/AArch64/AArch64LibSec.inf
+ ArmPlatformSecLib|ArmPlatformPkg/ArmVExpressPkg/Library/ArmVExpressSecLibRTSM/ArmVExpressSecLib.inf
+ ArmPlatformLib|ArmPlatformPkg/ArmVExpressPkg/Library/ArmVExpressLibRTSM/ArmVExpressLibSec.inf
+
+[BuildOptions]
+ GCC:*_*_AARCH64_PLATFORM_FLAGS == -I$(WORKSPACE)/ArmPlatformPkg/ArmVExpressPkg/Include -I$(WORKSPACE)/ArmPlatformPkg/ArmVExpressPkg/Include/Platform/RTSM
+
+
+################################################################################
+#
+# Pcd Section - list of all EDK II PCD Entries defined by this Platform
+#
+################################################################################
+
+[PcdsFeatureFlag.common]
+
+ ## If TRUE, Graphics Output Protocol will be installed on virtual handle created by ConsplitterDxe.
+ # It could be set FALSE to save size.
+ gEfiMdeModulePkgTokenSpaceGuid.PcdConOutGopSupport|TRUE
+
+ ## FVP platforms support hardware power control
+ # Disabled for now as we have a version mismatch.
+ gArmTokenSpaceGuid.PcdArmPsciSupport|FALSE
+
+[PcdsFixedAtBuild.common]
+ gArmPlatformTokenSpaceGuid.PcdFirmwareVendor|"ARM Fixed Virtual Platform"
+ gEmbeddedTokenSpaceGuid.PcdEmbeddedPrompt|"ARM-FVP"
+
+ # Up to 8 cores on Base models. This works fine if model happens to have less.
+ gArmPlatformTokenSpaceGuid.PcdCoreCount|8
+
+ #
+ # NV Storage PCDs. Use base of 0x0C000000 for NOR1
+ #
+ gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase|0x0FFC0000
+ gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize|0x00010000
+ gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingBase|0x0FFD0000
+ gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingSize|0x00010000
+ gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareBase|0x0FFE0000
+ gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize|0x00010000
+
+ gArmTokenSpaceGuid.PcdVFPEnabled|1
+
+ # FVP models can have 2 clusters with 4 cpus each
+ # Stacks for MPCores in Secure World
+ # Trusted SRAM (DRAM on Foundation model)
+ gArmPlatformTokenSpaceGuid.PcdCPUCoresSecStackBase|0x04000000
+ gArmPlatformTokenSpaceGuid.PcdCPUCoreSecPrimaryStackSize|0x1000
+ gArmPlatformTokenSpaceGuid.PcdCPUCoreSecSecondaryStackSize|0x800
+
+ # Stacks for MPCores in Normal World
+ # Non-Trusted SRAM
+ gArmPlatformTokenSpaceGuid.PcdCPUCoresStackBase|0x2E000000
+ gArmPlatformTokenSpaceGuid.PcdCPUCorePrimaryStackSize|0x4000
+ gArmPlatformTokenSpaceGuid.PcdCPUCoreSecondaryStackSize|0x800
+
+ # System Memory (2GB)
+ gArmTokenSpaceGuid.PcdSystemMemoryBase|0x80000000
+ gArmTokenSpaceGuid.PcdSystemMemorySize|0x80000000
+
+ # Size of the region used by UEFI in permanent memory (Reserved 64MB)
+ gArmPlatformTokenSpaceGuid.PcdSystemMemoryUefiRegionSize|0x04000000
+
+ #
+ # ARM Pcds
+ #
+ gArmTokenSpaceGuid.PcdArmUncachedMemoryMask|0x0000000040000000
+
+ ## Trustzone enable (to make the transition from EL3 to NS EL2 in ArmPlatformPkg/Sec)
+ gArmTokenSpaceGuid.PcdTrustzoneSupport|TRUE
+
+ #
+ # ARM PrimeCell
+ #
+
+ ## SP805 Watchdog - Motherboard Watchdog at 24MHz
+ gArmPlatformTokenSpaceGuid.PcdSP805WatchdogBase|0x1C0F0000
+ gArmPlatformTokenSpaceGuid.PcdSP805WatchdogClockFrequencyInHz|24000000
+
+ ## PL011 - Serial Terminal
+ gEfiMdeModulePkgTokenSpaceGuid.PcdSerialRegisterBase|0x1c090000
+ gEfiMdePkgTokenSpaceGuid.PcdUartDefaultBaudRate|38400
+
+ ## PL031 RealTimeClock
+ gArmPlatformTokenSpaceGuid.PcdPL031RtcBase|0x1C170000
+
+!ifndef ARM_FOUNDATION_FVP
+ ## PL111 Versatile Express Motherboard controller
+ gArmPlatformTokenSpaceGuid.PcdPL111LcdBase|0x1C1F0000
+
+ ## PL180 MMC/SD card controller
+ gArmPlatformTokenSpaceGuid.PcdPL180SysMciRegAddress|0x1C010048
+ gArmPlatformTokenSpaceGuid.PcdPL180MciBaseAddress|0x1C050000
+!endif
+
+ #
+ # ARM General Interrupt Controller
+ #
+!ifdef ARM_FVP_LEGACY_GICV2_LOCATION
+ gArmTokenSpaceGuid.PcdGicDistributorBase|0x2C001000
+ gArmTokenSpaceGuid.PcdGicInterruptInterfaceBase|0x2C002000
+!else
+ gArmTokenSpaceGuid.PcdGicDistributorBase|0x2f000000
+ gArmTokenSpaceGuid.PcdGicInterruptInterfaceBase|0x2C000000
+!endif
+
# Ethernet (SMSC 91C111)
gArmPlatformTokenSpaceGuid.PcdLan91xDxeBaseAddress|0x1A000000
-
- #
- # ARM OS Loader
- #
- # Versatile Express machine type (ARM VERSATILE EXPRESS = 2272) required for ARM Linux:
+ #
+ # ARM OS Loader
+ #
+ # Versatile Express machine type (ARM VERSATILE EXPRESS = 2272) required for ARM Linux:
gArmPlatformTokenSpaceGuid.PcdDefaultBootDescription|L"Linaro disk image on virtio"
!ifdef $(EDK2_USE_ANDROID_CONFIG)
gArmPlatformTokenSpaceGuid.PcdDefaultBootDevicePath|L"VenHw(C5B9C74A-6D72-4719-99AB-C59F199091EB)/kernel"
gArmPlatformTokenSpaceGuid.PcdDefaultBootInitrdPath|L"VenHw(C5B9C74A-6D72-4719-99AB-C59F199091EB)/ramdisk.img"
+ gArmPlatformTokenSpaceGuid.PcdDefaultFdtLocalDevicePath|L"VenHw(C5B9C74A-6D72-4719-99AB-C59F199091EB)/fvp-base-gicv2-psci.dtb"
!else
- gArmPlatformTokenSpaceGuid.PcdDefaultBootDevicePath|L"VenHw(C5B9C74A-6D72-4719-99AB-C59F199091EB)/Image"
+ gArmPlatformTokenSpaceGuid.PcdDefaultBootDevicePath|L"VenHw(C5B9C74A-6D72-4719-99AB-C59F199091EB)/Image"
gArmPlatformTokenSpaceGuid.PcdDefaultBootArgument|"console=ttyAMA0 earlyprintk=pl011,0x1c090000 debug user_debug=31 loglevel=9 root=/dev/vda2"
-!endif
gArmPlatformTokenSpaceGuid.PcdDefaultFdtLocalDevicePath|L"VenHw(C5B9C74A-6D72-4719-99AB-C59F199091EB)/fdt.dtb"
+!endif
gArmPlatformTokenSpaceGuid.PcdDefaultBootType|3
- gArmPlatformTokenSpaceGuid.PcdFdtDevicePath|L"VenHw(C5B9C74A-6D72-4719-99AB-C59F199091EB)/fdt.dtb"
-
- # Use the serial console (ConIn & ConOut) and the Graphic driver (ConOut)
- gArmPlatformTokenSpaceGuid.PcdDefaultConOutPaths|L"VenHw(D3987D4B-971A-435F-8CAF-4967EB627241)/Uart(38400,8,N,1)/VenPcAnsi();VenHw(407B4008-BF5B-11DF-9547-CF16E0D72085)"
- gArmPlatformTokenSpaceGuid.PcdDefaultConInPaths|L"VenHw(D3987D4B-971A-435F-8CAF-4967EB627241)/Uart(38400,8,N,1)/VenPcAnsi()"
-
- #
- # ARM Architectual Timer Frequency
- #
- # Set tick frequency value to 120Mhz
- gArmTokenSpaceGuid.PcdArmArchTimerFreqInHz|120000000
-
-################################################################################
-#
-# Components Section - list of all EDK II Modules needed by this Platform
-#
-################################################################################
-[Components.common]
-
- #
- # SEC
- #
- ArmPlatformPkg/Sec/Sec.inf {
- <LibraryClasses>
- # Use the implementation which set the Secure bits
- ArmGicLib|ArmPkg/Drivers/PL390Gic/PL390GicSecLib.inf
- }
-
- #
- # PEI Phase modules
- #
- ArmPlatformPkg/PrePeiCore/PrePeiCoreMPCore.inf {
- <LibraryClasses>
- ArmPlatformGlobalVariableLib|ArmPlatformPkg/Library/ArmPlatformGlobalVariableLib/Pei/PeiArmPlatformGlobalVariableLib.inf
- }
- MdeModulePkg/Core/Pei/PeiMain.inf
- MdeModulePkg/Universal/PCD/Pei/Pcd.inf {
- <LibraryClasses>
- PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
- }
- ArmPlatformPkg/PlatformPei/PlatformPeim.inf
- ArmPlatformPkg/MemoryInitPei/MemoryInitPeim.inf
- ArmPkg/Drivers/CpuPei/CpuPei.inf
- IntelFrameworkModulePkg/Universal/StatusCode/Pei/StatusCodePei.inf
- Nt32Pkg/BootModePei/BootModePei.inf
- MdeModulePkg/Universal/Variable/Pei/VariablePei.inf
- MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf {
- <LibraryClasses>
- NULL|IntelFrameworkModulePkg/Library/LzmaCustomDecompressLib/LzmaCustomDecompressLib.inf
- }
-
- #
- # DXE
- #
- MdeModulePkg/Core/Dxe/DxeMain.inf {
- <LibraryClasses>
- PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
- NULL|MdeModulePkg/Library/DxeCrc32GuidedSectionExtractLib/DxeCrc32GuidedSectionExtractLib.inf
- }
-
- #
- # Architectural Protocols
- #
- ArmPkg/Drivers/CpuDxe/CpuDxe.inf
- MdeModulePkg/Core/RuntimeDxe/RuntimeDxe.inf
- MdeModulePkg/Universal/SecurityStubDxe/SecurityStubDxe.inf
- MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleRuntimeDxe.inf
- MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf
- MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteDxe.inf
- MdeModulePkg/Universal/MonotonicCounterRuntimeDxe/MonotonicCounterRuntimeDxe.inf
- EmbeddedPkg/ResetRuntimeDxe/ResetRuntimeDxe.inf
- EmbeddedPkg/RealTimeClockRuntimeDxe/RealTimeClockRuntimeDxe.inf
- EmbeddedPkg/MetronomeDxe/MetronomeDxe.inf
-
- MdeModulePkg/Universal/Console/ConPlatformDxe/ConPlatformDxe.inf
- MdeModulePkg/Universal/Console/ConSplitterDxe/ConSplitterDxe.inf
- MdeModulePkg/Universal/Console/GraphicsConsoleDxe/GraphicsConsoleDxe.inf
- MdeModulePkg/Universal/Console/TerminalDxe/TerminalDxe.inf
- EmbeddedPkg/SerialDxe/SerialDxe.inf
-
- MdeModulePkg/Universal/HiiDatabaseDxe/HiiDatabaseDxe.inf
+ gArmPlatformTokenSpaceGuid.PcdFdtDevicePath|L"VenHw(C5B9C74A-6D72-4719-99AB-C59F199091EB)/fdt.dtb"
+
+ # Use the serial console (ConIn & ConOut) and the Graphic driver (ConOut)
+ gArmPlatformTokenSpaceGuid.PcdDefaultConOutPaths|L"VenHw(D3987D4B-971A-435F-8CAF-4967EB627241)/Uart(38400,8,N,1)/VenPcAnsi();VenHw(407B4008-BF5B-11DF-9547-CF16E0D72085)"
+ gArmPlatformTokenSpaceGuid.PcdDefaultConInPaths|L"VenHw(D3987D4B-971A-435F-8CAF-4967EB627241)/Uart(38400,8,N,1)/VenPcAnsi()"
+
+ #
+ # ARM Architectual Timer Frequency
+ #
+ # Set tick frequency value to 120Mhz
+ gArmTokenSpaceGuid.PcdArmArchTimerFreqInHz|120000000
+
+################################################################################
+#
+# Components Section - list of all EDK II Modules needed by this Platform
+#
+################################################################################
+[Components.common]
+
+ #
+ # SEC
+ #
+ ArmPlatformPkg/Sec/Sec.inf {
+ <LibraryClasses>
+ # Use the implementation which set the Secure bits
+ ArmGicLib|ArmPkg/Drivers/ArmGic/ArmGicSecLib.inf
+ }
+
+ #
+ # PEI Phase modules
+ #
+ ArmPlatformPkg/PrePeiCore/PrePeiCoreMPCore.inf {
+ <LibraryClasses>
+ ArmPlatformGlobalVariableLib|ArmPlatformPkg/Library/ArmPlatformGlobalVariableLib/Pei/PeiArmPlatformGlobalVariableLib.inf
+ }
+ MdeModulePkg/Core/Pei/PeiMain.inf
+ MdeModulePkg/Universal/PCD/Pei/Pcd.inf {
+ <LibraryClasses>
+ PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
+ }
+ ArmPlatformPkg/PlatformPei/PlatformPeim.inf
+ ArmPlatformPkg/MemoryInitPei/MemoryInitPeim.inf
+ ArmPkg/Drivers/CpuPei/CpuPei.inf
+ IntelFrameworkModulePkg/Universal/StatusCode/Pei/StatusCodePei.inf
+ Nt32Pkg/BootModePei/BootModePei.inf
+ MdeModulePkg/Universal/Variable/Pei/VariablePei.inf
+ MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf {
+ <LibraryClasses>
+ NULL|IntelFrameworkModulePkg/Library/LzmaCustomDecompressLib/LzmaCustomDecompressLib.inf
+ }
+
+ #
+ # DXE
+ #
+ MdeModulePkg/Core/Dxe/DxeMain.inf {
+ <LibraryClasses>
+ PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
+ NULL|MdeModulePkg/Library/DxeCrc32GuidedSectionExtractLib/DxeCrc32GuidedSectionExtractLib.inf
+ }
+
+ #
+ # Architectural Protocols
+ #
+ ArmPkg/Drivers/CpuDxe/CpuDxe.inf
+ MdeModulePkg/Core/RuntimeDxe/RuntimeDxe.inf
+ MdeModulePkg/Universal/SecurityStubDxe/SecurityStubDxe.inf
+ MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleRuntimeDxe.inf
+ MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf
+ MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteDxe.inf
+ MdeModulePkg/Universal/MonotonicCounterRuntimeDxe/MonotonicCounterRuntimeDxe.inf
+ EmbeddedPkg/ResetRuntimeDxe/ResetRuntimeDxe.inf
+ EmbeddedPkg/RealTimeClockRuntimeDxe/RealTimeClockRuntimeDxe.inf
+ EmbeddedPkg/MetronomeDxe/MetronomeDxe.inf
+
+ MdeModulePkg/Universal/Console/ConPlatformDxe/ConPlatformDxe.inf
+ MdeModulePkg/Universal/Console/ConSplitterDxe/ConSplitterDxe.inf
+ MdeModulePkg/Universal/Console/GraphicsConsoleDxe/GraphicsConsoleDxe.inf
+ MdeModulePkg/Universal/Console/TerminalDxe/TerminalDxe.inf
+ EmbeddedPkg/SerialDxe/SerialDxe.inf
+
+ MdeModulePkg/Universal/HiiDatabaseDxe/HiiDatabaseDxe.inf
#^M
# ACPI Support^M
@@ -258,37 +258,37 @@
MdeModulePkg/Universal/Acpi/AcpiPlatformDxe/AcpiPlatformDxe.inf
MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableDxe.inf
ArmPkg/Drivers/AcpiTables/rtsm_ve-aemv8a/AcpiTables.inf
-
- ArmPkg/Drivers/PL390Gic/PL390GicDxe.inf
- ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashDxe.inf
- ArmPkg/Drivers/TimerDxe/TimerDxe.inf
-!ifndef ARM_FOUNDATION_FVP
- ArmPlatformPkg/Drivers/LcdGraphicsOutputDxe/PL111LcdGraphicsOutputDxe.inf
-!endif
- ArmPlatformPkg/Drivers/SP805WatchdogDxe/SP805WatchdogDxe.inf
-
- #
- # Semi-hosting filesystem
- #
- ArmPkg/Filesystem/SemihostFs/SemihostFs.inf
-
-!ifndef ARM_FOUNDATION_FVP
- #
- # Multimedia Card Interface
- #
- EmbeddedPkg/Universal/MmcDxe/MmcDxe.inf
- ArmPlatformPkg/Drivers/PL180MciDxe/PL180MciDxe.inf
-!endif
-
- #
- # FAT filesystem + GPT/MBR partitioning
- #
- MdeModulePkg/Universal/Disk/DiskIoDxe/DiskIoDxe.inf
- MdeModulePkg/Universal/Disk/PartitionDxe/PartitionDxe.inf
- MdeModulePkg/Universal/Disk/UnicodeCollation/EnglishDxe/EnglishDxe.inf
-
- #
- # Bds
- #
- MdeModulePkg/Universal/DevicePathDxe/DevicePathDxe.inf
- ArmPlatformPkg/Bds/Bds.inf
+
+ ArmPkg/Drivers/ArmGic/ArmGicDxe.inf
+ ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashDxe.inf
+ ArmPkg/Drivers/TimerDxe/TimerDxe.inf
+!ifndef ARM_FOUNDATION_FVP
+ ArmPlatformPkg/Drivers/LcdGraphicsOutputDxe/PL111LcdGraphicsOutputDxe.inf
+!endif
+ ArmPlatformPkg/Drivers/SP805WatchdogDxe/SP805WatchdogDxe.inf
+
+ #
+ # Semi-hosting filesystem
+ #
+ ArmPkg/Filesystem/SemihostFs/SemihostFs.inf
+
+!ifndef ARM_FOUNDATION_FVP
+ #
+ # Multimedia Card Interface
+ #
+ EmbeddedPkg/Universal/MmcDxe/MmcDxe.inf
+ ArmPlatformPkg/Drivers/PL180MciDxe/PL180MciDxe.inf
+!endif
+
+ #
+ # FAT filesystem + GPT/MBR partitioning
+ #
+ MdeModulePkg/Universal/Disk/DiskIoDxe/DiskIoDxe.inf
+ MdeModulePkg/Universal/Disk/PartitionDxe/PartitionDxe.inf
+ MdeModulePkg/Universal/Disk/UnicodeCollation/EnglishDxe/EnglishDxe.inf
+
+ #
+ # Bds
+ #
+ MdeModulePkg/Universal/DevicePathDxe/DevicePathDxe.inf
+ ArmPlatformPkg/Bds/Bds.inf
diff --git a/ArmPlatformPkg/ArmVExpressPkg/ArmVExpress-FVP-AArch64.fdf b/ArmPlatformPkg/ArmVExpressPkg/ArmVExpress-FVP-AArch64.fdf
index b35a4da7e..1ceb7cbdf 100755..100644
--- a/ArmPlatformPkg/ArmVExpressPkg/ArmVExpress-FVP-AArch64.fdf
+++ b/ArmPlatformPkg/ArmVExpressPkg/ArmVExpress-FVP-AArch64.fdf
@@ -1,359 +1,358 @@
-#
-# Copyright (c) 2011 - 2013, ARM Limited. All rights reserved.
-#
-# 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.
-#
-
-################################################################################
-#
-# FD Section
-# The [FD] Section is made up of the definition statements and a
-# description of what goes into the Flash Device Image. Each FD section
-# defines one flash "device" image. A flash device image may be one of
-# the following: Removable media bootable image (like a boot floppy
-# image,) an Option ROM image (that would be "flashed" into an add-in
-# card,) a System "Flash" image (that would be burned into a system's
-# flash) or an Update ("Capsule") image that will be used to update and
-# existing system flash.
-#
-################################################################################
-
-[FD.FVP_AARCH64_EFI_SEC]
-BaseAddress = 0x00000000|gArmTokenSpaceGuid.PcdFdBaseAddress # The base address of the Firmware in SecureROM.
-Size = 0x04000000|gArmTokenSpaceGuid.PcdFdSize # The size in bytes of the device (64MiB).
-ErasePolarity = 1
-
-# This one is tricky, it must be: BlockSize * NumBlocks = Size
-BlockSize = 0x00001000
-NumBlocks = 0x4000
-
-################################################################################
-#
-# Following are lists of FD Region layout which correspond to the locations of different
-# images within the flash device.
-#
-# Regions must be defined in ascending order and may not overlap.
-#
-# A Layout Region start with a eight digit hex offset (leading "0x" required) followed by
-# the pipe "|" character, followed by the size of the region, also in hex with the leading
-# "0x" characters. Like:
-# Offset|Size
-# PcdOffsetCName|PcdSizeCName
-# RegionType <FV, DATA, or FILE>
-#
-################################################################################
-
-0x00000000|0x00080000
-gArmTokenSpaceGuid.PcdSecureFvBaseAddress|gArmTokenSpaceGuid.PcdSecureFvSize
-FV = FVMAIN_SEC
-
-[FD.FVP_AARCH64_EFI]
-BaseAddress = 0x08000000|gArmTokenSpaceGuid.PcdFdBaseAddress # The base address of the Firmware in Flash0.
-Size = 0x04000000|gArmTokenSpaceGuid.PcdFdSize # The size in bytes of the device (64MiB).
-ErasePolarity = 1
-
-# This one is tricky, it must be: BlockSize * NumBlocks = Size
-BlockSize = 0x00001000
-NumBlocks = 0x4000
-
-0x00000000|0x00280000
-gArmTokenSpaceGuid.PcdFvBaseAddress|gArmTokenSpaceGuid.PcdFvSize
-FV = FVMAIN_COMPACT
-
-################################################################################
-#
-# FV Section
-#
-# [FV] section is used to define what components or modules are placed within a flash
-# device file. This section also defines order the components and modules are positioned
-# within the image. The [FV] section consists of define statements, set statements and
-# module statements.
-#
-################################################################################
-
-[FV.FVMAIN_SEC]
-FvBaseAddress = 0x0 # Secure ROM
-FvForceRebase = TRUE
-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
-
- INF ArmPlatformPkg/Sec/Sec.inf
-
-
-[FV.FvMain]
-BlockSize = 0x40
-NumBlocks = 0 # This FV gets compressed so make it just big enough
-FvAlignment = 16 # FV alignment and FV attributes setting.
-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
-
- INF MdeModulePkg/Core/Dxe/DxeMain.inf
-
- #
- # PI DXE Drivers producing Architectural Protocols (EFI Services)
- #
- INF ArmPkg/Drivers/CpuDxe/CpuDxe.inf
- INF MdeModulePkg/Core/RuntimeDxe/RuntimeDxe.inf
- INF MdeModulePkg/Universal/SecurityStubDxe/SecurityStubDxe.inf
- INF MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleRuntimeDxe.inf
- INF MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf
- INF MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteDxe.inf
- INF MdeModulePkg/Universal/MonotonicCounterRuntimeDxe/MonotonicCounterRuntimeDxe.inf
- INF EmbeddedPkg/ResetRuntimeDxe/ResetRuntimeDxe.inf
- INF EmbeddedPkg/RealTimeClockRuntimeDxe/RealTimeClockRuntimeDxe.inf
- INF EmbeddedPkg/MetronomeDxe/MetronomeDxe.inf
-
- INF MdeModulePkg/Universal/HiiDatabaseDxe/HiiDatabaseDxe.inf
-
- #
- # ACPI Support^M
- #^M
- INF MdeModulePkg/Universal/Acpi/AcpiPlatformDxe/AcpiPlatformDxe.inf
- INF MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableDxe.inf
- INF RuleOverride=ACPITABLE ArmPkg/Drivers/AcpiTables/rtsm_ve-aemv8a/AcpiTables.inf
-
- #
- # Networking stack
- #
- INF MdeModulePkg/Universal/Network/DpcDxe/DpcDxe.inf
- INF MdeModulePkg/Universal/Network/ArpDxe/ArpDxe.inf
- INF MdeModulePkg/Universal/Network/Dhcp4Dxe/Dhcp4Dxe.inf
- INF MdeModulePkg/Universal/Network/Ip4ConfigDxe/Ip4ConfigDxe.inf
- INF MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Dxe.inf
- INF MdeModulePkg/Universal/Network/MnpDxe/MnpDxe.inf
- INF MdeModulePkg/Universal/Network/VlanConfigDxe/VlanConfigDxe.inf
- INF MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Dxe.inf
- INF MdeModulePkg/Universal/Network/Tcp4Dxe/Tcp4Dxe.inf
- INF MdeModulePkg/Universal/Network/Udp4Dxe/Udp4Dxe.inf
- INF MdeModulePkg/Universal/Network/UefiPxeBcDxe/UefiPxeBcDxe.inf
- INF MdeModulePkg/Universal/Network/IScsiDxe/IScsiDxe.inf
- INF ArmPlatformPkg/Drivers/LAN91xDxe/LAN91xDxe.inf
-
- #
- # Multiple Console IO support
- #
- 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 EmbeddedPkg/SerialDxe/SerialDxe.inf
-
- INF ArmPkg/Drivers/PL390Gic/PL390GicDxe.inf
- INF ArmPkg/Drivers/TimerDxe/TimerDxe.inf
- INF ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashDxe.inf
-!ifndef ARM_FOUNDATION_FVP
- INF ArmPlatformPkg/Drivers/LcdGraphicsOutputDxe/PL111LcdGraphicsOutputDxe.inf
-!endif
- INF ArmPlatformPkg/Drivers/SP805WatchdogDxe/SP805WatchdogDxe.inf
-
- #
- # Semi-hosting filesystem
- #
- INF ArmPkg/Filesystem/SemihostFs/SemihostFs.inf
-
- #
- # FAT filesystem + GPT/MBR partitioning
- #
- INF MdeModulePkg/Universal/Disk/DiskIoDxe/DiskIoDxe.inf
- INF MdeModulePkg/Universal/Disk/PartitionDxe/PartitionDxe.inf
- INF FatBinPkg/EnhancedFatDxe/Fat.inf
- INF MdeModulePkg/Universal/Disk/UnicodeCollation/EnglishDxe/EnglishDxe.inf
-
-!ifndef ARM_FOUNDATION_FVP
- #
- # Multimedia Card Interface
- #
- INF EmbeddedPkg/Universal/MmcDxe/MmcDxe.inf
- INF ArmPlatformPkg/Drivers/PL180MciDxe/PL180MciDxe.inf
-!endif
-
- #
- # UEFI application (Shell Embedded Boot Loader)
- #
- INF ShellBinPkg/UefiShell/UefiShell.inf
-
- #
- # Bds
- #
- INF MdeModulePkg/Universal/DevicePathDxe/DevicePathDxe.inf
- INF ArmPlatformPkg/Bds/Bds.inf
-
-
-[FV.FVMAIN_COMPACT]
-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
-
- INF ArmPlatformPkg/PrePeiCore/PrePeiCoreMPCore.inf
- INF MdeModulePkg/Core/Pei/PeiMain.inf
- INF ArmPlatformPkg/PlatformPei/PlatformPeim.inf
- INF ArmPlatformPkg/MemoryInitPei/MemoryInitPeim.inf
- INF ArmPkg/Drivers/CpuPei/CpuPei.inf
- INF MdeModulePkg/Universal/PCD/Pei/Pcd.inf
- INF IntelFrameworkModulePkg/Universal/StatusCode/Pei/StatusCodePei.inf
- INF MdeModulePkg/Universal/Variable/Pei/VariablePei.inf
- INF MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf
-
- FILE FV_IMAGE = 9E21FD93-9C72-4c15-8C4B-E77F1DB2D792 {
- SECTION GUIDED EE4E5898-3914-4259-9D6E-DC7BD79403CF PROCESSING_REQUIRED = TRUE {
- SECTION FV_IMAGE = FVMAIN
- }
- }
-
-
-################################################################################
-#
-# Rules are use with the [FV] section's module INF type to define
-# how an FFS file is created for a given INF file. The following Rule are the default
-# rules for the different module type. User can add the customized rules to define the
-# content of the FFS file.
-#
-################################################################################
-
-
-############################################################################
-# Example of a DXE_DRIVER FFS file with a Checksum encapsulation section #
-############################################################################
-#
-#[Rule.Common.DXE_DRIVER]
-# FILE DRIVER = $(NAMED_GUID) {
-# DXE_DEPEX DXE_DEPEX Optional $(INF_OUTPUT)/$(MODULE_NAME).depex
-# COMPRESS PI_STD {
-# GUIDED {
-# PE32 PE32 $(INF_OUTPUT)/$(MODULE_NAME).efi
-# UI STRING="$(MODULE_NAME)" Optional
-# VERSION STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
-# }
-# }
-# }
-#
-############################################################################
-
-[Rule.Common.SEC]
- FILE SEC = $(NAMED_GUID) RELOCS_STRIPPED {
- TE TE Align = 128 $(INF_OUTPUT)/$(MODULE_NAME).efi
- }
-
-[Rule.Common.PEI_CORE]
- FILE PEI_CORE = $(NAMED_GUID) {
- TE TE Align = 8 $(INF_OUTPUT)/$(MODULE_NAME).efi
- UI STRING ="$(MODULE_NAME)" Optional
- }
-
-[Rule.Common.PEIM]
- FILE PEIM = $(NAMED_GUID) {
- PEI_DEPEX PEI_DEPEX Optional $(INF_OUTPUT)/$(MODULE_NAME).depex
- TE TE Align = 8 $(INF_OUTPUT)/$(MODULE_NAME).efi
- UI STRING="$(MODULE_NAME)" Optional
- }
-
-[Rule.Common.PEIM.TIANOCOMPRESSED]
- FILE PEIM = $(NAMED_GUID) DEBUG_MYTOOLS_IA32 {
- PEI_DEPEX PEI_DEPEX Optional $(INF_OUTPUT)/$(MODULE_NAME).depex
- GUIDED A31280AD-481E-41B6-95E8-127F4C984779 PROCESSING_REQUIRED = TRUE {
- PE32 PE32 $(INF_OUTPUT)/$(MODULE_NAME).efi
- UI STRING="$(MODULE_NAME)" Optional
- }
- }
-
-[Rule.Common.DXE_CORE]
- FILE DXE_CORE = $(NAMED_GUID) {
- PE32 PE32 $(INF_OUTPUT)/$(MODULE_NAME).efi
- UI STRING="$(MODULE_NAME)" Optional
- }
-
-[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
- }
-
-[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
- }
-
-[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
- }
-
-[Rule.Common.UEFI_APPLICATION]
- FILE APPLICATION = $(NAMED_GUID) {
- UI STRING ="$(MODULE_NAME)" Optional
- PE32 PE32 $(INF_OUTPUT)/$(MODULE_NAME).efi
- }
-
-[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.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
- UI STRING="$(MODULE_NAME)" Optional
- }
-
+#
+# Copyright (c) 2011 - 2013, ARM Limited. All rights reserved.
+#
+# 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.
+#
+
+################################################################################
+#
+# FD Section
+# The [FD] Section is made up of the definition statements and a
+# description of what goes into the Flash Device Image. Each FD section
+# defines one flash "device" image. A flash device image may be one of
+# the following: Removable media bootable image (like a boot floppy
+# image,) an Option ROM image (that would be "flashed" into an add-in
+# card,) a System "Flash" image (that would be burned into a system's
+# flash) or an Update ("Capsule") image that will be used to update and
+# existing system flash.
+#
+################################################################################
+
+[FD.FVP_AARCH64_EFI_SEC]
+BaseAddress = 0x00000000|gArmTokenSpaceGuid.PcdFdBaseAddress # The base address of the Firmware in SecureROM.
+Size = 0x04000000|gArmTokenSpaceGuid.PcdFdSize # The size in bytes of the device (64MiB).
+ErasePolarity = 1
+
+# This one is tricky, it must be: BlockSize * NumBlocks = Size
+BlockSize = 0x00001000
+NumBlocks = 0x4000
+
+################################################################################
+#
+# Following are lists of FD Region layout which correspond to the locations of different
+# images within the flash device.
+#
+# Regions must be defined in ascending order and may not overlap.
+#
+# A Layout Region start with a eight digit hex offset (leading "0x" required) followed by
+# the pipe "|" character, followed by the size of the region, also in hex with the leading
+# "0x" characters. Like:
+# Offset|Size
+# PcdOffsetCName|PcdSizeCName
+# RegionType <FV, DATA, or FILE>
+#
+################################################################################
+
+0x00000000|0x00080000
+gArmTokenSpaceGuid.PcdSecureFvBaseAddress|gArmTokenSpaceGuid.PcdSecureFvSize
+FV = FVMAIN_SEC
+
+[FD.FVP_AARCH64_EFI]
+BaseAddress = 0x08000000|gArmTokenSpaceGuid.PcdFdBaseAddress # The base address of the Firmware in Flash0.
+Size = 0x04000000|gArmTokenSpaceGuid.PcdFdSize # The size in bytes of the device (64MiB).
+ErasePolarity = 1
+
+# This one is tricky, it must be: BlockSize * NumBlocks = Size
+BlockSize = 0x00001000
+NumBlocks = 0x4000
+
+0x00000000|0x00280000
+gArmTokenSpaceGuid.PcdFvBaseAddress|gArmTokenSpaceGuid.PcdFvSize
+FV = FVMAIN_COMPACT
+
+################################################################################
+#
+# FV Section
+#
+# [FV] section is used to define what components or modules are placed within a flash
+# device file. This section also defines order the components and modules are positioned
+# within the image. The [FV] section consists of define statements, set statements and
+# module statements.
+#
+################################################################################
+
+[FV.FVMAIN_SEC]
+FvBaseAddress = 0x0 # Secure ROM
+FvForceRebase = TRUE
+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
+
+ INF ArmPlatformPkg/Sec/Sec.inf
+
+
+[FV.FvMain]
+BlockSize = 0x40
+NumBlocks = 0 # This FV gets compressed so make it just big enough
+FvAlignment = 16 # FV alignment and FV attributes setting.
+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
+
+ INF MdeModulePkg/Core/Dxe/DxeMain.inf
+
+ #
+ # PI DXE Drivers producing Architectural Protocols (EFI Services)
+ #
+ INF ArmPkg/Drivers/CpuDxe/CpuDxe.inf
+ INF MdeModulePkg/Core/RuntimeDxe/RuntimeDxe.inf
+ INF MdeModulePkg/Universal/SecurityStubDxe/SecurityStubDxe.inf
+ INF MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleRuntimeDxe.inf
+ INF MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf
+ INF MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteDxe.inf
+ INF MdeModulePkg/Universal/MonotonicCounterRuntimeDxe/MonotonicCounterRuntimeDxe.inf
+ INF EmbeddedPkg/ResetRuntimeDxe/ResetRuntimeDxe.inf
+ INF EmbeddedPkg/RealTimeClockRuntimeDxe/RealTimeClockRuntimeDxe.inf
+ INF EmbeddedPkg/MetronomeDxe/MetronomeDxe.inf
+
+ INF MdeModulePkg/Universal/HiiDatabaseDxe/HiiDatabaseDxe.inf
+
+ # ACPI Support
+ #
+ INF MdeModulePkg/Universal/Acpi/AcpiPlatformDxe/AcpiPlatformDxe.inf
+ INF MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableDxe.inf
+ INF RuleOverride=ACPITABLE ArmPkg/Drivers/AcpiTables/rtsm_ve-aemv8a/AcpiTables.inf
+
+ #
+ # Networking stack
+ #
+ INF MdeModulePkg/Universal/Network/DpcDxe/DpcDxe.inf
+ INF MdeModulePkg/Universal/Network/ArpDxe/ArpDxe.inf
+ INF MdeModulePkg/Universal/Network/Dhcp4Dxe/Dhcp4Dxe.inf
+ INF MdeModulePkg/Universal/Network/Ip4ConfigDxe/Ip4ConfigDxe.inf
+ INF MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Dxe.inf
+ INF MdeModulePkg/Universal/Network/MnpDxe/MnpDxe.inf
+ INF MdeModulePkg/Universal/Network/VlanConfigDxe/VlanConfigDxe.inf
+ INF MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Dxe.inf
+ INF MdeModulePkg/Universal/Network/Tcp4Dxe/Tcp4Dxe.inf
+ INF MdeModulePkg/Universal/Network/Udp4Dxe/Udp4Dxe.inf
+ INF MdeModulePkg/Universal/Network/UefiPxeBcDxe/UefiPxeBcDxe.inf
+ INF MdeModulePkg/Universal/Network/IScsiDxe/IScsiDxe.inf
+ INF ArmPlatformPkg/Drivers/LAN91xDxe/LAN91xDxe.inf
+
+ #
+ # Multiple Console IO support
+ #
+ 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 EmbeddedPkg/SerialDxe/SerialDxe.inf
+
+ INF ArmPkg/Drivers/ArmGic/ArmGicDxe.inf
+ INF ArmPkg/Drivers/TimerDxe/TimerDxe.inf
+ INF ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashDxe.inf
+!ifndef ARM_FOUNDATION_FVP
+ INF ArmPlatformPkg/Drivers/LcdGraphicsOutputDxe/PL111LcdGraphicsOutputDxe.inf
+!endif
+ INF ArmPlatformPkg/Drivers/SP805WatchdogDxe/SP805WatchdogDxe.inf
+
+ #
+ # Semi-hosting filesystem
+ #
+ INF ArmPkg/Filesystem/SemihostFs/SemihostFs.inf
+
+ #
+ # FAT filesystem + GPT/MBR partitioning
+ #
+ INF MdeModulePkg/Universal/Disk/DiskIoDxe/DiskIoDxe.inf
+ INF MdeModulePkg/Universal/Disk/PartitionDxe/PartitionDxe.inf
+ INF FatBinPkg/EnhancedFatDxe/Fat.inf
+ INF MdeModulePkg/Universal/Disk/UnicodeCollation/EnglishDxe/EnglishDxe.inf
+
+!ifndef ARM_FOUNDATION_FVP
+ #
+ # Multimedia Card Interface
+ #
+ INF EmbeddedPkg/Universal/MmcDxe/MmcDxe.inf
+ INF ArmPlatformPkg/Drivers/PL180MciDxe/PL180MciDxe.inf
+!endif
+
+ #
+ # UEFI application (Shell Embedded Boot Loader)
+ #
+ INF ShellBinPkg/UefiShell/UefiShell.inf
+
+ #
+ # Bds
+ #
+ INF MdeModulePkg/Universal/DevicePathDxe/DevicePathDxe.inf
+ INF ArmPlatformPkg/Bds/Bds.inf
+
+
+[FV.FVMAIN_COMPACT]
+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
+
+ INF ArmPlatformPkg/PrePeiCore/PrePeiCoreMPCore.inf
+ INF MdeModulePkg/Core/Pei/PeiMain.inf
+ INF ArmPlatformPkg/PlatformPei/PlatformPeim.inf
+ INF ArmPlatformPkg/MemoryInitPei/MemoryInitPeim.inf
+ INF ArmPkg/Drivers/CpuPei/CpuPei.inf
+ INF MdeModulePkg/Universal/PCD/Pei/Pcd.inf
+ INF IntelFrameworkModulePkg/Universal/StatusCode/Pei/StatusCodePei.inf
+ INF MdeModulePkg/Universal/Variable/Pei/VariablePei.inf
+ INF MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf
+
+ FILE FV_IMAGE = 9E21FD93-9C72-4c15-8C4B-E77F1DB2D792 {
+ SECTION GUIDED EE4E5898-3914-4259-9D6E-DC7BD79403CF PROCESSING_REQUIRED = TRUE {
+ SECTION FV_IMAGE = FVMAIN
+ }
+ }
+
+
+################################################################################
+#
+# Rules are use with the [FV] section's module INF type to define
+# how an FFS file is created for a given INF file. The following Rule are the default
+# rules for the different module type. User can add the customized rules to define the
+# content of the FFS file.
+#
+################################################################################
+
+
+############################################################################
+# Example of a DXE_DRIVER FFS file with a Checksum encapsulation section #
+############################################################################
+#
+#[Rule.Common.DXE_DRIVER]
+# FILE DRIVER = $(NAMED_GUID) {
+# DXE_DEPEX DXE_DEPEX Optional $(INF_OUTPUT)/$(MODULE_NAME).depex
+# COMPRESS PI_STD {
+# GUIDED {
+# PE32 PE32 $(INF_OUTPUT)/$(MODULE_NAME).efi
+# UI STRING="$(MODULE_NAME)" Optional
+# VERSION STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
+# }
+# }
+# }
+#
+############################################################################
+
+[Rule.Common.SEC]
+ FILE SEC = $(NAMED_GUID) RELOCS_STRIPPED {
+ TE TE Align = 128 $(INF_OUTPUT)/$(MODULE_NAME).efi
+ }
+
+[Rule.Common.PEI_CORE]
+ FILE PEI_CORE = $(NAMED_GUID) {
+ TE TE Align = 8 $(INF_OUTPUT)/$(MODULE_NAME).efi
+ UI STRING ="$(MODULE_NAME)" Optional
+ }
+
+[Rule.Common.PEIM]
+ FILE PEIM = $(NAMED_GUID) {
+ PEI_DEPEX PEI_DEPEX Optional $(INF_OUTPUT)/$(MODULE_NAME).depex
+ TE TE Align = 8 $(INF_OUTPUT)/$(MODULE_NAME).efi
+ UI STRING="$(MODULE_NAME)" Optional
+ }
+
+[Rule.Common.PEIM.TIANOCOMPRESSED]
+ FILE PEIM = $(NAMED_GUID) DEBUG_MYTOOLS_IA32 {
+ PEI_DEPEX PEI_DEPEX Optional $(INF_OUTPUT)/$(MODULE_NAME).depex
+ GUIDED A31280AD-481E-41B6-95E8-127F4C984779 PROCESSING_REQUIRED = TRUE {
+ PE32 PE32 $(INF_OUTPUT)/$(MODULE_NAME).efi
+ UI STRING="$(MODULE_NAME)" Optional
+ }
+ }
+
+[Rule.Common.DXE_CORE]
+ FILE DXE_CORE = $(NAMED_GUID) {
+ PE32 PE32 $(INF_OUTPUT)/$(MODULE_NAME).efi
+ UI STRING="$(MODULE_NAME)" Optional
+ }
+
+[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
+ }
+
+[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
+ }
+
+[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
+ }
+
+[Rule.Common.UEFI_APPLICATION]
+ FILE APPLICATION = $(NAMED_GUID) {
+ UI STRING ="$(MODULE_NAME)" Optional
+ PE32 PE32 $(INF_OUTPUT)/$(MODULE_NAME).efi
+ }
+
+[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.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
+ UI STRING="$(MODULE_NAME)" Optional
+ }
+
diff --git a/ArmPlatformPkg/ArmVExpressPkg/ArmVExpress-RTSM-A15.dsc b/ArmPlatformPkg/ArmVExpressPkg/ArmVExpress-RTSM-A15.dsc
index aa124f6a8..6844f378f 100644
--- a/ArmPlatformPkg/ArmVExpressPkg/ArmVExpress-RTSM-A15.dsc
+++ b/ArmPlatformPkg/ArmVExpressPkg/ArmVExpress-RTSM-A15.dsc
@@ -81,13 +81,13 @@
#
# NV Storage PCDs. Use base of 0x0C000000 for NOR1
#
- gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase|0x0FF00000
+ gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase|0x0c000000
gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize|0x00040000
- gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingBase|0x0FF40000
+ gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingBase|0x0c040000
gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingSize|0x00040000
- gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareBase|0x0FF80000
+ gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareBase|0x0c080000
gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize|0x00040000
-
+
gArmTokenSpaceGuid.PcdVFPEnabled|1
# Stacks for MPCores in Secure World
@@ -136,7 +136,7 @@
gArmPlatformTokenSpaceGuid.PcdPL180MciBaseAddress|0x1C050000
#
- # ARM PL390 General Interrupt Controller
+ # ARM General Interrupt Controller
#
gArmTokenSpaceGuid.PcdGicDistributorBase|0x2C001000
gArmTokenSpaceGuid.PcdGicInterruptInterfaceBase|0x2C002000
@@ -153,7 +153,7 @@
gArmPlatformTokenSpaceGuid.PcdDefaultBootDevicePath|L"VenHw(09831032-6FA3-4484-AF4F-0A000A8D3A82)/HD(1,MBR,0x00000000,0x3F,0x19FC0)/uImage"
gArmPlatformTokenSpaceGuid.PcdDefaultBootInitrdPath|L"VenHw(09831032-6FA3-4484-AF4F-0A000A8D3A82)/HD(1,MBR,0x00000000,0x3F,0x19FC0)/uInitrd"
gArmPlatformTokenSpaceGuid.PcdDefaultFdtLocalDevicePath|L"VenHw(09831032-6FA3-4484-AF4F-0A000A8D3A82)/HD(1,MBR,0x00000000,0x3F,0x19FC0)/rtsm\\rtsm_ve-ca15x1.dtb"
- gArmPlatformTokenSpaceGuid.PcdDefaultBootArgument|"console=ttyAMA0,38400n8 root=/dev/mmcblk0p2 rootwait ro androidboot.console=ttyAMA0 mmci.fmax=12000000"
+ gArmPlatformTokenSpaceGuid.PcdDefaultBootArgument|"console=ttyAMA0,38400n8 rootwait root=/dev/mmcblk0p2"
gArmPlatformTokenSpaceGuid.PcdDefaultBootType|3
gArmPlatformTokenSpaceGuid.PcdFdtDevicePath|L"VenHw(09831032-6FA3-4484-AF4F-0A000A8D3A82)/HD(1,MBR,0x00000000,0x3F,0x19FC0)/rtsm\\rtsm_ve-ca15x1.dtb"
@@ -180,7 +180,7 @@
ArmPlatformPkg/Sec/Sec.inf {
<LibraryClasses>
# Use the implementation which set the Secure bits
- ArmGicLib|ArmPkg/Drivers/PL390Gic/PL390GicSecLib.inf
+ ArmGicLib|ArmPkg/Drivers/ArmGic/ArmGicSecLib.inf
}
#
@@ -246,14 +246,7 @@
MdeModulePkg/Universal/HiiDatabaseDxe/HiiDatabaseDxe.inf
- #
- # ACPI Support
- #
- MdeModulePkg/Universal/Acpi/AcpiPlatformDxe/AcpiPlatformDxe.inf
- MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableDxe.inf
- ArmPkg/Drivers/AcpiTables/rtsm_ve-v7/AcpiTables.inf
-
- ArmPkg/Drivers/PL390Gic/PL390GicDxe.inf
+ ArmPkg/Drivers/ArmGic/ArmGicDxe.inf
ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashDxe.inf
ArmPkg/Drivers/TimerDxe/TimerDxe.inf
ArmPlatformPkg/Drivers/LcdGraphicsOutputDxe/PL111LcdGraphicsOutputDxe.inf
diff --git a/ArmPlatformPkg/ArmVExpressPkg/ArmVExpress-RTSM-A15.fdf b/ArmPlatformPkg/ArmVExpressPkg/ArmVExpress-RTSM-A15.fdf
index 5ecfb27a6..ed3787794 100644
--- a/ArmPlatformPkg/ArmVExpressPkg/ArmVExpress-RTSM-A15.fdf
+++ b/ArmPlatformPkg/ArmVExpressPkg/ArmVExpress-RTSM-A15.fdf
@@ -128,14 +128,7 @@ READ_LOCK_STATUS = TRUE
INF EmbeddedPkg/MetronomeDxe/MetronomeDxe.inf
INF MdeModulePkg/Universal/HiiDatabaseDxe/HiiDatabaseDxe.inf
-
- #
- # ACPI Support
- #
- INF MdeModulePkg/Universal/Acpi/AcpiPlatformDxe/AcpiPlatformDxe.inf
- INF MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableDxe.inf
- INF RuleOverride=ACPITABLE ArmPkg/Drivers/AcpiTables/rtsm_ve-v7/AcpiTables.inf
-
+
#
# Networking stack
#
@@ -162,7 +155,7 @@ READ_LOCK_STATUS = TRUE
INF MdeModulePkg/Universal/Console/TerminalDxe/TerminalDxe.inf
INF EmbeddedPkg/SerialDxe/SerialDxe.inf
- INF ArmPkg/Drivers/PL390Gic/PL390GicDxe.inf
+ INF ArmPkg/Drivers/ArmGic/ArmGicDxe.inf
INF ArmPkg/Drivers/TimerDxe/TimerDxe.inf
INF ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashDxe.inf
INF ArmPlatformPkg/Drivers/LcdGraphicsOutputDxe/PL111LcdGraphicsOutputDxe.inf
@@ -340,11 +333,3 @@ READ_LOCK_STATUS = TRUE
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
- UI STRING="$(MODULE_NAME)" Optional
- }
-
diff --git a/ArmPlatformPkg/ArmVExpressPkg/ArmVExpress-RTSM-A15_MPCore.dsc b/ArmPlatformPkg/ArmVExpressPkg/ArmVExpress-RTSM-A15_MPCore.dsc
index eecb783e8..f46f16e40 100644
--- a/ArmPlatformPkg/ArmVExpressPkg/ArmVExpress-RTSM-A15_MPCore.dsc
+++ b/ArmPlatformPkg/ArmVExpressPkg/ArmVExpress-RTSM-A15_MPCore.dsc
@@ -83,11 +83,11 @@
#
# NV Storage PCDs. Use base of 0x0C000000 for NOR1
#
- gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase|0x0FF00000
+ gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase|0x0c000000
gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize|0x00040000
- gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingBase|0x0FF40000
+ gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingBase|0x0c040000
gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingSize|0x00040000
- gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareBase|0x0FF80000
+ gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareBase|0x0c080000
gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize|0x00040000
gArmTokenSpaceGuid.PcdVFPEnabled|1
@@ -138,7 +138,7 @@
gArmPlatformTokenSpaceGuid.PcdPL180MciBaseAddress|0x1C050000
#
- # ARM PL390 General Interrupt Controller
+ # ARM General Interrupt Controller
#
gArmTokenSpaceGuid.PcdGicDistributorBase|0x2C001000
gArmTokenSpaceGuid.PcdGicInterruptInterfaceBase|0x2C002000
@@ -155,7 +155,7 @@
gArmPlatformTokenSpaceGuid.PcdDefaultBootDevicePath|L"VenHw(09831032-6FA3-4484-AF4F-0A000A8D3A82)/HD(1,MBR,0x00000000,0x3F,0x19FC0)/uImage"
gArmPlatformTokenSpaceGuid.PcdDefaultBootInitrdPath|L"VenHw(09831032-6FA3-4484-AF4F-0A000A8D3A82)/HD(1,MBR,0x00000000,0x3F,0x19FC0)/uInitrd"
gArmPlatformTokenSpaceGuid.PcdDefaultFdtLocalDevicePath|L"VenHw(09831032-6FA3-4484-AF4F-0A000A8D3A82)/HD(1,MBR,0x00000000,0x3F,0x19FC0)/rtsm\\rtsm_ve-ca15x4.dtb"
- gArmPlatformTokenSpaceGuid.PcdDefaultBootArgument|"console=ttyAMA0,38400n8 root=/dev/mmcblk0p2 rootwait ro androidboot.console=ttyAMA0 mmci.fmax=12000000"
+ gArmPlatformTokenSpaceGuid.PcdDefaultBootArgument|"console=ttyAMA0,38400n8 rootwait root=/dev/mmcblk0p2"
gArmPlatformTokenSpaceGuid.PcdDefaultBootType|3
gArmPlatformTokenSpaceGuid.PcdFdtDevicePath|L"VenHw(09831032-6FA3-4484-AF4F-0A000A8D3A82)/HD(1,MBR,0x00000000,0x3F,0x19FC0)/rtsm\\rtsm_ve-ca15x4.dtb"
@@ -182,7 +182,7 @@
ArmPlatformPkg/Sec/Sec.inf {
<LibraryClasses>
# Use the implementation which set the Secure bits
- ArmGicLib|ArmPkg/Drivers/PL390Gic/PL390GicSecLib.inf
+ ArmGicLib|ArmPkg/Drivers/ArmGic/ArmGicSecLib.inf
}
#
@@ -248,14 +248,7 @@
MdeModulePkg/Universal/HiiDatabaseDxe/HiiDatabaseDxe.inf
- #
- # ACPI Support
- #
- MdeModulePkg/Universal/Acpi/AcpiPlatformDxe/AcpiPlatformDxe.inf
- MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableDxe.inf
- ArmPkg/Drivers/AcpiTables/rtsm_ve-v7/AcpiTables.inf
-
- ArmPkg/Drivers/PL390Gic/PL390GicDxe.inf
+ ArmPkg/Drivers/ArmGic/ArmGicDxe.inf
ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashDxe.inf
ArmPkg/Drivers/TimerDxe/TimerDxe.inf
ArmPlatformPkg/Drivers/LcdGraphicsOutputDxe/PL111LcdGraphicsOutputDxe.inf
diff --git a/ArmPlatformPkg/ArmVExpressPkg/ArmVExpress-RTSM-A15_MPCore.fdf b/ArmPlatformPkg/ArmVExpressPkg/ArmVExpress-RTSM-A15_MPCore.fdf
index 97bac4f5b..837985aae 100644
--- a/ArmPlatformPkg/ArmVExpressPkg/ArmVExpress-RTSM-A15_MPCore.fdf
+++ b/ArmPlatformPkg/ArmVExpressPkg/ArmVExpress-RTSM-A15_MPCore.fdf
@@ -128,14 +128,7 @@ READ_LOCK_STATUS = TRUE
INF EmbeddedPkg/MetronomeDxe/MetronomeDxe.inf
INF MdeModulePkg/Universal/HiiDatabaseDxe/HiiDatabaseDxe.inf
-
- #
- # ACPI Support
- #
- INF MdeModulePkg/Universal/Acpi/AcpiPlatformDxe/AcpiPlatformDxe.inf
- INF MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableDxe.inf
- INF RuleOverride=ACPITABLE ArmPkg/Drivers/AcpiTables/rtsm_ve-v7/AcpiTables.inf
-
+
#
# Networking stack
#
@@ -152,6 +145,7 @@ READ_LOCK_STATUS = TRUE
INF MdeModulePkg/Universal/Network/UefiPxeBcDxe/UefiPxeBcDxe.inf
INF MdeModulePkg/Universal/Network/IScsiDxe/IScsiDxe.inf
INF ArmPlatformPkg/Drivers/LAN91xDxe/LAN91xDxe.inf
+
#
# Multiple Console IO support
#
@@ -161,7 +155,7 @@ READ_LOCK_STATUS = TRUE
INF MdeModulePkg/Universal/Console/TerminalDxe/TerminalDxe.inf
INF EmbeddedPkg/SerialDxe/SerialDxe.inf
- INF ArmPkg/Drivers/PL390Gic/PL390GicDxe.inf
+ INF ArmPkg/Drivers/ArmGic/ArmGicDxe.inf
INF ArmPkg/Drivers/TimerDxe/TimerDxe.inf
INF ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashDxe.inf
INF ArmPlatformPkg/Drivers/LcdGraphicsOutputDxe/PL111LcdGraphicsOutputDxe.inf
@@ -339,11 +333,3 @@ READ_LOCK_STATUS = TRUE
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
- UI STRING="$(MODULE_NAME)" Optional
- }
-
diff --git a/ArmPlatformPkg/ArmVExpressPkg/ArmVExpress-RTSM-A9x4.dsc b/ArmPlatformPkg/ArmVExpressPkg/ArmVExpress-RTSM-A9x4.dsc
index 11f5efbab..337bf6bcb 100644
--- a/ArmPlatformPkg/ArmVExpressPkg/ArmVExpress-RTSM-A9x4.dsc
+++ b/ArmPlatformPkg/ArmVExpressPkg/ArmVExpress-RTSM-A9x4.dsc
@@ -148,7 +148,7 @@
gArmPlatformTokenSpaceGuid.PcdPL180MciBaseAddress|0x1C050000
#
- # ARM PL390 General Interrupt Controller
+ # ARM General Interrupt Controller
#
gArmTokenSpaceGuid.PcdGicDistributorBase|0x2C001000
gArmTokenSpaceGuid.PcdGicInterruptInterfaceBase|0x2C000100
@@ -165,7 +165,7 @@
gArmPlatformTokenSpaceGuid.PcdDefaultBootDevicePath|L"VenHw(09831032-6FA3-4484-AF4F-0A000A8D3A82)/HD(1,MBR,0x00000000,0x3F,0x19FC0)/uImage"
gArmPlatformTokenSpaceGuid.PcdDefaultBootInitrdPath|L"VenHw(09831032-6FA3-4484-AF4F-0A000A8D3A82)/HD(1,MBR,0x00000000,0x3F,0x19FC0)/uInitrd"
gArmPlatformTokenSpaceGuid.PcdDefaultFdtLocalDevicePath|L"VenHw(09831032-6FA3-4484-AF4F-0A000A8D3A82)/HD(1,MBR,0x00000000,0x3F,0x19FC0)/rtsm\\rtsm_ve-ca9x4.dtb"
- gArmPlatformTokenSpaceGuid.PcdDefaultBootArgument|"console=ttyAMA0,38400n8 root=/dev/mmcblk0p2 rootwait ro androidboot.console=ttyAMA0 mmci.fmax=12000000"
+ gArmPlatformTokenSpaceGuid.PcdDefaultBootArgument|"console=ttyAMA0,38400n8 rootwait root=/dev/mmcblk0p2"
gArmPlatformTokenSpaceGuid.PcdDefaultBootType|3
gArmPlatformTokenSpaceGuid.PcdFdtDevicePath|L"VenHw(09831032-6FA3-4484-AF4F-0A000A8D3A82)/HD(1,MBR,0x00000000,0x3F,0x19FC0)/rtsm\\rtsm_ve-ca9x4.dtb"
@@ -191,7 +191,7 @@
ArmPlatformPkg/Sec/Sec.inf {
<LibraryClasses>
# Use the implementation which set the Secure bits
- ArmGicLib|ArmPkg/Drivers/PL390Gic/PL390GicSecLib.inf
+ ArmGicLib|ArmPkg/Drivers/ArmGic/ArmGicSecLib.inf
}
#
@@ -264,7 +264,7 @@
MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableDxe.inf
ArmPkg/Drivers/AcpiTables/rtsm_ve-v7/AcpiTables.inf
- ArmPkg/Drivers/PL390Gic/PL390GicDxe.inf
+ ArmPkg/Drivers/ArmGic/ArmGicDxe.inf
ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashDxe.inf
ArmPlatformPkg/Drivers/SP804TimerDxe/SP804TimerDxe.inf
ArmPlatformPkg/Drivers/LcdGraphicsOutputDxe/PL111LcdGraphicsOutputDxe.inf
diff --git a/ArmPlatformPkg/ArmVExpressPkg/ArmVExpress-RTSM-A9x4.fdf b/ArmPlatformPkg/ArmVExpressPkg/ArmVExpress-RTSM-A9x4.fdf
index a3e50ff0d..75f18e4f2 100644
--- a/ArmPlatformPkg/ArmVExpressPkg/ArmVExpress-RTSM-A9x4.fdf
+++ b/ArmPlatformPkg/ArmVExpressPkg/ArmVExpress-RTSM-A9x4.fdf
@@ -127,14 +127,14 @@ READ_LOCK_STATUS = TRUE
INF EmbeddedPkg/MetronomeDxe/MetronomeDxe.inf
INF MdeModulePkg/Universal/HiiDatabaseDxe/HiiDatabaseDxe.inf
-
+
#
# ACPI Support
#
INF MdeModulePkg/Universal/Acpi/AcpiPlatformDxe/AcpiPlatformDxe.inf
INF MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableDxe.inf
INF RuleOverride=ACPITABLE ArmPkg/Drivers/AcpiTables/rtsm_ve-v7/AcpiTables.inf
-
+
#
# Networking stack
#
@@ -161,7 +161,7 @@ READ_LOCK_STATUS = TRUE
INF MdeModulePkg/Universal/Console/TerminalDxe/TerminalDxe.inf
INF EmbeddedPkg/SerialDxe/SerialDxe.inf
- INF ArmPkg/Drivers/PL390Gic/PL390GicDxe.inf
+ INF ArmPkg/Drivers/ArmGic/ArmGicDxe.inf
INF ArmPlatformPkg/Drivers/SP804TimerDxe/SP804TimerDxe.inf
INF ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashDxe.inf
INF ArmPlatformPkg/Drivers/LcdGraphicsOutputDxe/PL111LcdGraphicsOutputDxe.inf
diff --git a/ArmPlatformPkg/ArmVExpressPkg/ArmVExpress-RTSM-AEMv8Ax4-foundation.dsc b/ArmPlatformPkg/ArmVExpressPkg/ArmVExpress-RTSM-AEMv8Ax4-foundation.dsc
index 29dbbafef..0654ebb0b 100644
--- a/ArmPlatformPkg/ArmVExpressPkg/ArmVExpress-RTSM-AEMv8Ax4-foundation.dsc
+++ b/ArmPlatformPkg/ArmVExpressPkg/ArmVExpress-RTSM-AEMv8Ax4-foundation.dsc
@@ -115,7 +115,7 @@
gEfiMdePkgTokenSpaceGuid.PcdUartDefaultBaudRate|38400
#
- # ARM PL390 General Interrupt Controller
+ # ARM General Interrupt Controller
#
gArmTokenSpaceGuid.PcdGicDistributorBase|0x2C001000
gArmTokenSpaceGuid.PcdGicInterruptInterfaceBase|0x2C002000
@@ -153,7 +153,7 @@
ArmPlatformPkg/Sec/Sec.inf {
<LibraryClasses>
# Use the implementation which set the Secure bits
- ArmGicLib|ArmPkg/Drivers/PL390Gic/PL390GicSecLib.inf
+ ArmGicLib|ArmPkg/Drivers/ArmGic/ArmGicSecLib.inf
}
#
@@ -218,21 +218,20 @@
EmbeddedPkg/SerialDxe/SerialDxe.inf
MdeModulePkg/Universal/HiiDatabaseDxe/HiiDatabaseDxe.inf
-
- #
- # ACPI Support
- #
- MdeModulePkg/Universal/Acpi/AcpiPlatformDxe/AcpiPlatformDxe.inf
- MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableDxe.inf
- ArmPkg/Drivers/AcpiTables/foundation-v8/AcpiTables.inf
- #^M
- # SMBIOS Support^M
- #^M
+ #
+ # ACPI Support
+ #
+ MdeModulePkg/Universal/Acpi/AcpiPlatformDxe/AcpiPlatformDxe.inf
+ MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableDxe.inf
+ ArmPkg/Drivers/AcpiTables/foundation-v8/AcpiTables.inf
+ #
+ # SMBIOS Support
+ #
MdeModulePkg/Universal/SmbiosDxe/SmbiosDxe.inf
ArmPkg/Drivers/UpdateSmbios/UpdateSmbios.inf
- ArmPkg/Drivers/PL390Gic/PL390GicDxe.inf
+ ArmPkg/Drivers/ArmGic/ArmGicDxe.inf
ArmPkg/Drivers/TimerDxe/TimerDxe.inf
MdeModulePkg/Universal/WatchdogTimerDxe/WatchdogTimer.inf
diff --git a/ArmPlatformPkg/ArmVExpressPkg/ArmVExpress-RTSM-AEMv8Ax4-foundation.fdf b/ArmPlatformPkg/ArmVExpressPkg/ArmVExpress-RTSM-AEMv8Ax4-foundation.fdf
index 9981daf58..c070c571e 100644
--- a/ArmPlatformPkg/ArmVExpressPkg/ArmVExpress-RTSM-AEMv8Ax4-foundation.fdf
+++ b/ArmPlatformPkg/ArmVExpressPkg/ArmVExpress-RTSM-AEMv8Ax4-foundation.fdf
@@ -128,20 +128,20 @@ READ_LOCK_STATUS = TRUE
INF MdeModulePkg/Universal/HiiDatabaseDxe/HiiDatabaseDxe.inf
- #^M
- # SMBIOS Support^M
- #^M
+ #
+ # ACPI Support
+ #
+ INF MdeModulePkg/Universal/Acpi/AcpiPlatformDxe/AcpiPlatformDxe.inf
+ INF MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableDxe.inf
+ INF RuleOverride=ACPITABLE ArmPkg/Drivers/AcpiTables/foundation-v8/AcpiTables.inf
+
+ #
+ # SMBIOS Support
+ #
INF MdeModulePkg/Universal/SmbiosDxe/SmbiosDxe.inf
INF ArmPkg/Drivers/UpdateSmbios/UpdateSmbios.inf
#
- # ACPI Support
- #
- INF MdeModulePkg/Universal/Acpi/AcpiPlatformDxe/AcpiPlatformDxe.inf
- INF MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableDxe.inf
- INF RuleOverride=ACPITABLE ArmPkg/Drivers/AcpiTables/foundation-v8/AcpiTables.inf
-
- #
# Multiple Console IO support
#
INF MdeModulePkg/Universal/Console/ConPlatformDxe/ConPlatformDxe.inf
@@ -150,7 +150,7 @@ READ_LOCK_STATUS = TRUE
INF MdeModulePkg/Universal/Console/TerminalDxe/TerminalDxe.inf
INF EmbeddedPkg/SerialDxe/SerialDxe.inf
- INF ArmPkg/Drivers/PL390Gic/PL390GicDxe.inf
+ INF ArmPkg/Drivers/ArmGic/ArmGicDxe.inf
INF ArmPkg/Drivers/TimerDxe/TimerDxe.inf
INF MdeModulePkg/Universal/WatchdogTimerDxe/WatchdogTimer.inf
@@ -325,11 +325,11 @@ READ_LOCK_STATUS = TRUE
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
- UI STRING="$(MODULE_NAME)" Optional
- }
-
+
+[Rule.Common.USER_DEFINED.ACPITABLE]
+ FILE FREEFORM = $(NAMED_GUID) {
+ RAW ACPI |.acpi
+ RAW ASL |.aml
+ UI STRING="$(MODULE_NAME)" Optional
+ }
+
diff --git a/ArmPlatformPkg/ArmVExpressPkg/ArmVExpress-RTSM-AEMv8Ax4.dsc b/ArmPlatformPkg/ArmVExpressPkg/ArmVExpress-RTSM-AEMv8Ax4.dsc
index cf5823d9a..d61eb5d4c 100644
--- a/ArmPlatformPkg/ArmVExpressPkg/ArmVExpress-RTSM-AEMv8Ax4.dsc
+++ b/ArmPlatformPkg/ArmVExpressPkg/ArmVExpress-RTSM-AEMv8Ax4.dsc
@@ -137,7 +137,7 @@
gArmPlatformTokenSpaceGuid.PcdPL180MciBaseAddress|0x1C050000
#
- # ARM PL390 General Interrupt Controller
+ # ARM General Interrupt Controller
#
gArmTokenSpaceGuid.PcdGicDistributorBase|0x2C001000
gArmTokenSpaceGuid.PcdGicInterruptInterfaceBase|0x2C002000
@@ -175,7 +175,7 @@
ArmPlatformPkg/Sec/Sec.inf {
<LibraryClasses>
# Use the implementation which set the Secure bits
- ArmGicLib|ArmPkg/Drivers/PL390Gic/PL390GicSecLib.inf
+ ArmGicLib|ArmPkg/Drivers/ArmGic/ArmGicSecLib.inf
}
#
@@ -241,19 +241,20 @@
MdeModulePkg/Universal/HiiDatabaseDxe/HiiDatabaseDxe.inf
- #
- # ACPI Support
- #
- MdeModulePkg/Universal/Acpi/AcpiPlatformDxe/AcpiPlatformDxe.inf
- MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableDxe.inf
- ArmPkg/Drivers/AcpiTables/rtsm_ve-aemv8a/AcpiTables.inf
- #^M
- # SMBIOS Support^M
- #^M
+ #
+ # ACPI Support
+ #
+ MdeModulePkg/Universal/Acpi/AcpiPlatformDxe/AcpiPlatformDxe.inf
+ MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableDxe.inf
+ ArmPkg/Drivers/AcpiTables/rtsm_ve-aemv8a/AcpiTables.inf
+
+ #
+ # SMBIOS Support
+ #
MdeModulePkg/Universal/SmbiosDxe/SmbiosDxe.inf
ArmPkg/Drivers/UpdateSmbios/UpdateSmbios.inf
- ArmPkg/Drivers/PL390Gic/PL390GicDxe.inf
+ ArmPkg/Drivers/ArmGic/ArmGicDxe.inf
ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashDxe.inf
ArmPkg/Drivers/TimerDxe/TimerDxe.inf
ArmPlatformPkg/Drivers/LcdGraphicsOutputDxe/PL111LcdGraphicsOutputDxe.inf
diff --git a/ArmPlatformPkg/ArmVExpressPkg/ArmVExpress-RTSM-AEMv8Ax4.fdf b/ArmPlatformPkg/ArmVExpressPkg/ArmVExpress-RTSM-AEMv8Ax4.fdf
index af1b0fa97..107e8d415 100644
--- a/ArmPlatformPkg/ArmVExpressPkg/ArmVExpress-RTSM-AEMv8Ax4.fdf
+++ b/ArmPlatformPkg/ArmVExpressPkg/ArmVExpress-RTSM-AEMv8Ax4.fdf
@@ -130,20 +130,20 @@ READ_LOCK_STATUS = TRUE
INF MdeModulePkg/Universal/HiiDatabaseDxe/HiiDatabaseDxe.inf
- #^M
- # SMBIOS Support^M
- #^M
+ #
+ # ACPI Support
+ #
+ INF MdeModulePkg/Universal/Acpi/AcpiPlatformDxe/AcpiPlatformDxe.inf
+ INF MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableDxe.inf
+ INF RuleOverride=ACPITABLE ArmPkg/Drivers/AcpiTables/rtsm_ve-aemv8a/AcpiTables.inf
+
+ #
+ # SMBIOS Support
+ #
INF MdeModulePkg/Universal/SmbiosDxe/SmbiosDxe.inf
INF ArmPkg/Drivers/UpdateSmbios/UpdateSmbios.inf
#
- # ACPI Support
- #
- INF MdeModulePkg/Universal/Acpi/AcpiPlatformDxe/AcpiPlatformDxe.inf
- INF MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableDxe.inf
- INF RuleOverride=ACPITABLE ArmPkg/Drivers/AcpiTables/rtsm_ve-aemv8a/AcpiTables.inf
-
- #
# Multiple Console IO support
#
INF MdeModulePkg/Universal/Console/ConPlatformDxe/ConPlatformDxe.inf
@@ -152,7 +152,7 @@ READ_LOCK_STATUS = TRUE
INF MdeModulePkg/Universal/Console/TerminalDxe/TerminalDxe.inf
INF EmbeddedPkg/SerialDxe/SerialDxe.inf
- INF ArmPkg/Drivers/PL390Gic/PL390GicDxe.inf
+ INF ArmPkg/Drivers/ArmGic/ArmGicDxe.inf
INF ArmPkg/Drivers/TimerDxe/TimerDxe.inf
INF ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashDxe.inf
INF ArmPlatformPkg/Drivers/LcdGraphicsOutputDxe/PL111LcdGraphicsOutputDxe.inf
@@ -336,11 +336,10 @@ READ_LOCK_STATUS = TRUE
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
- UI STRING="$(MODULE_NAME)" Optional
- }
-
+
+[Rule.Common.USER_DEFINED.ACPITABLE]
+ FILE FREEFORM = $(NAMED_GUID) {
+ RAW ACPI |.acpi
+ RAW ASL |.aml
+ UI STRING="$(MODULE_NAME)" Optional
+ }
diff --git a/ArmPlatformPkg/ArmVExpressPkg/ArmVExpress.dsc.inc b/ArmPlatformPkg/ArmVExpressPkg/ArmVExpress.dsc.inc
index f36df9a13..ec52a6b5d 100644
--- a/ArmPlatformPkg/ArmVExpressPkg/ArmVExpress.dsc.inc
+++ b/ArmPlatformPkg/ArmVExpressPkg/ArmVExpress.dsc.inc
@@ -66,7 +66,7 @@
CpuExceptionHandlerLib|MdeModulePkg/Library/CpuExceptionHandlerLibNull/CpuExceptionHandlerLibNull.inf
ArmDisassemblerLib|ArmPkg/Library/ArmDisassemblerLib/ArmDisassemblerLib.inf
DmaLib|ArmPkg/Library/ArmDmaLib/ArmDmaLib.inf
- ArmGicLib|ArmPkg/Drivers/PL390Gic/PL390GicLib.inf
+ ArmGicLib|ArmPkg/Drivers/ArmGic/ArmGicLib.inf
ArmPlatformStackLib|ArmPlatformPkg/Library/ArmPlatformStackLib/ArmPlatformStackLib.inf
ArmSmcLib|ArmPkg/Library/ArmSmcLib/ArmSmcLib.inf
@@ -257,8 +257,6 @@
gArmPlatformTokenSpaceGuid.PcdFirmwareVendor|"ARM Versatile Express"
gEmbeddedTokenSpaceGuid.PcdEmbeddedPrompt|"VExpress"
- gEmbeddedTokenSpaceGuid.PcdPrePiCpuMemorySize|32
- gEmbeddedTokenSpaceGuid.PcdPrePiCpuIoSize|0
gEfiMdePkgTokenSpaceGuid.PcdMaximumUnicodeStringLength|1000000
gEfiMdePkgTokenSpaceGuid.PcdMaximumAsciiStringLength|1000000
gEfiMdePkgTokenSpaceGuid.PcdMaximumLinkedListLength|1000000
diff --git a/ArmPlatformPkg/ArmVExpressPkg/Library/ArmVExpressLibCTA15-A7/ArmVExpressLib.inf b/ArmPlatformPkg/ArmVExpressPkg/Library/ArmVExpressLibCTA15-A7/ArmVExpressLib.inf
index 373a8e9e9..a7f93b4f8 100644
--- a/ArmPlatformPkg/ArmVExpressPkg/Library/ArmVExpressLibCTA15-A7/ArmVExpressLib.inf
+++ b/ArmPlatformPkg/ArmVExpressPkg/Library/ArmVExpressLibCTA15-A7/ArmVExpressLib.inf
@@ -41,13 +41,10 @@
[FeaturePcd]
gEmbeddedTokenSpaceGuid.PcdCacheEnable
- gArmPlatformTokenSpaceGuid.PcdNorFlashRemapping
- gArmPlatformTokenSpaceGuid.PcdStandalone
[FixedPcd]
gArmPlatformTokenSpaceGuid.PcdCoreCount
- gArmTokenSpaceGuid.PcdTrustzoneSupport
gArmTokenSpaceGuid.PcdSystemMemoryBase
gArmTokenSpaceGuid.PcdSystemMemorySize
gArmTokenSpaceGuid.PcdFvBaseAddress
diff --git a/ArmPlatformPkg/ArmVExpressPkg/Library/ArmVExpressLibCTA9x4/ArmVExpressLib.inf b/ArmPlatformPkg/ArmVExpressPkg/Library/ArmVExpressLibCTA9x4/ArmVExpressLib.inf
index d160a4fc9..febc6ddf9 100644
--- a/ArmPlatformPkg/ArmVExpressPkg/Library/ArmVExpressLibCTA9x4/ArmVExpressLib.inf
+++ b/ArmPlatformPkg/ArmVExpressPkg/Library/ArmVExpressLibCTA9x4/ArmVExpressLib.inf
@@ -33,8 +33,6 @@
MemoryAllocationLib
PL341DmcLib
PL301AxiLib
- L2X0CacheLib
- SerialPortLib
[Sources.common]
CTA9x4Helper.asm | RVCT
@@ -49,11 +47,8 @@
gArmPlatformTokenSpaceGuid.PcdNorFlashRemapping
[FixedPcd]
- gArmTokenSpaceGuid.PcdTrustzoneSupport
gArmTokenSpaceGuid.PcdSystemMemoryBase
gArmTokenSpaceGuid.PcdSystemMemorySize
- gArmTokenSpaceGuid.PcdL2x0ControllerBase
-
gArmTokenSpaceGuid.PcdArmPrimaryCoreMask
gArmTokenSpaceGuid.PcdArmPrimaryCore
diff --git a/ArmPlatformPkg/ArmVExpressPkg/Library/ArmVExpressLibCTA9x4/ArmVExpressLibSec.inf b/ArmPlatformPkg/ArmVExpressPkg/Library/ArmVExpressLibCTA9x4/ArmVExpressLibSec.inf
index 4d9699d4a..418ee3369 100644
--- a/ArmPlatformPkg/ArmVExpressPkg/Library/ArmVExpressLibCTA9x4/ArmVExpressLibSec.inf
+++ b/ArmPlatformPkg/ArmVExpressPkg/Library/ArmVExpressLibCTA9x4/ArmVExpressLibSec.inf
@@ -44,11 +44,8 @@
gArmPlatformTokenSpaceGuid.PcdNorFlashRemapping
[FixedPcd]
- gArmTokenSpaceGuid.PcdTrustzoneSupport
gArmTokenSpaceGuid.PcdSystemMemoryBase
gArmTokenSpaceGuid.PcdSystemMemorySize
- gArmTokenSpaceGuid.PcdL2x0ControllerBase
-
gArmTokenSpaceGuid.PcdArmPrimaryCoreMask
gArmTokenSpaceGuid.PcdArmPrimaryCore
diff --git a/ArmPlatformPkg/ArmVExpressPkg/Library/ArmVExpressLibCTA9x4/CTA9x4.c b/ArmPlatformPkg/ArmVExpressPkg/Library/ArmVExpressLibCTA9x4/CTA9x4.c
index 55b611190..60cb09ecc 100644
--- a/ArmPlatformPkg/ArmVExpressPkg/Library/ArmVExpressLibCTA9x4/CTA9x4.c
+++ b/ArmPlatformPkg/ArmVExpressPkg/Library/ArmVExpressLibCTA9x4/CTA9x4.c
@@ -1,6 +1,6 @@
/** @file
*
-* Copyright (c) 2011-2012, ARM Limited. All rights reserved.
+* Copyright (c) 2011-2013, ARM Limited. All rights reserved.
*
* This program and the accompanying materials
* are licensed and made available under the terms and conditions of the BSD License
@@ -16,7 +16,6 @@
#include <Library/ArmPlatformLib.h>
#include <Library/DebugLib.h>
#include <Library/PcdLib.h>
-#include <Library/SerialPortLib.h>
#include <Drivers/PL341Dmc.h>
#include <Drivers/PL301Axi.h>
@@ -26,8 +25,6 @@
#include <ArmPlatform.h>
-#define SerialPrint(txt) SerialPortWrite ((UINT8*)(txt), AsciiStrLen(txt)+1);
-
ARM_CORE_INFO mVersatileExpressMpCoreInfoCTA9x4[] = {
{
// Cluster 0, Core 0
@@ -163,19 +160,8 @@ ArmPlatformInitializeSystemMemory (
VOID
)
{
- UINT32 Value;
-
- // Memory Map remapping
- if (FeaturePcdGet(PcdNorFlashRemapping)) {
- SerialPrint ("Secure ROM at 0x0\n\r");
- } else {
- Value = MmioRead32(ARM_VE_SYS_CFGRW1_REG); //Scc - CFGRW1
- // Remap the DRAM to 0x0
- MmioWrite32(ARM_VE_SYS_CFGRW1_REG, (Value & 0x0FFFFFFF) | ARM_VE_CFGRW1_REMAP_DRAM);
- }
-
- PL341DmcInit(ARM_VE_DMC_BASE, &DDRTimings);
- PL301AxiInit(ARM_VE_FAXI_BASE);
+ PL341DmcInit (ARM_VE_DMC_BASE, &DDRTimings);
+ PL301AxiInit (ARM_VE_FAXI_BASE);
}
EFI_STATUS
diff --git a/ArmPlatformPkg/ArmVExpressPkg/Library/ArmVExpressLibRTSM/ArmVExpressLib.inf b/ArmPlatformPkg/ArmVExpressPkg/Library/ArmVExpressLibRTSM/ArmVExpressLib.inf
index 0cf605bbd..ea8279456 100644
--- a/ArmPlatformPkg/ArmVExpressPkg/Library/ArmVExpressLibRTSM/ArmVExpressLib.inf
+++ b/ArmPlatformPkg/ArmVExpressPkg/Library/ArmVExpressLibRTSM/ArmVExpressLib.inf
@@ -46,7 +46,6 @@
[FeaturePcd]
gEmbeddedTokenSpaceGuid.PcdCacheEnable
gArmPlatformTokenSpaceGuid.PcdNorFlashRemapping
- gArmPlatformTokenSpaceGuid.PcdStandalone
[FixedPcd]
gArmTokenSpaceGuid.PcdSystemMemoryBase
diff --git a/ArmPlatformPkg/ArmVExpressPkg/Library/ArmVExpressLibRTSM/ArmVExpressLibSec.inf b/ArmPlatformPkg/ArmVExpressPkg/Library/ArmVExpressLibRTSM/ArmVExpressLibSec.inf
index 7cb666f79..e6d38d5e9 100644
--- a/ArmPlatformPkg/ArmVExpressPkg/Library/ArmVExpressLibRTSM/ArmVExpressLibSec.inf
+++ b/ArmPlatformPkg/ArmVExpressPkg/Library/ArmVExpressLibRTSM/ArmVExpressLibSec.inf
@@ -44,7 +44,6 @@
[FeaturePcd]
gEmbeddedTokenSpaceGuid.PcdCacheEnable
gArmPlatformTokenSpaceGuid.PcdNorFlashRemapping
- gArmPlatformTokenSpaceGuid.PcdStandalone
[FixedPcd]
gArmTokenSpaceGuid.PcdSystemMemoryBase
diff --git a/ArmPlatformPkg/ArmVExpressPkg/Library/ArmVExpressSecLibCTA9x4/ArmVExpressSecLib.inf b/ArmPlatformPkg/ArmVExpressPkg/Library/ArmVExpressSecLibCTA9x4/ArmVExpressSecLib.inf
index eeb4e0c5e..969a75644 100644
--- a/ArmPlatformPkg/ArmVExpressPkg/Library/ArmVExpressSecLibCTA9x4/ArmVExpressSecLib.inf
+++ b/ArmPlatformPkg/ArmVExpressPkg/Library/ArmVExpressSecLibCTA9x4/ArmVExpressSecLib.inf
@@ -1,5 +1,5 @@
#/* @file
-# Copyright (c) 2011-2012, ARM Limited. All rights reserved.
+# Copyright (c) 2011-2013, ARM Limited. All rights reserved.
#
# This program and the accompanying materials
# are licensed and made available under the terms and conditions of the BSD License
@@ -45,9 +45,8 @@
CTA9x4Boot.S | GCC
[FeaturePcd]
- gEmbeddedTokenSpaceGuid.PcdCacheEnable
- gArmPlatformTokenSpaceGuid.PcdNorFlashRemapping
gArmPlatformTokenSpaceGuid.PcdStandalone
+ gArmPlatformTokenSpaceGuid.PcdNorFlashRemapping
gArmPlatformTokenSpaceGuid.PcdSystemMemoryInitializeInSec
[FixedPcd]
diff --git a/ArmPlatformPkg/ArmVExpressPkg/Library/ArmVExpressSecLibCTA9x4/CTA9x4Sec.c b/ArmPlatformPkg/ArmVExpressPkg/Library/ArmVExpressSecLibCTA9x4/CTA9x4Sec.c
index a671f130f..eff714cca 100644
--- a/ArmPlatformPkg/ArmVExpressPkg/Library/ArmVExpressSecLibCTA9x4/CTA9x4Sec.c
+++ b/ArmPlatformPkg/ArmVExpressPkg/Library/ArmVExpressSecLibCTA9x4/CTA9x4Sec.c
@@ -1,6 +1,6 @@
/** @file
*
-* Copyright (c) 2011-2012, ARM Limited. All rights reserved.
+* Copyright (c) 2011-2013, ARM Limited. All rights reserved.
*
* This program and the accompanying materials
* are licensed and made available under the terms and conditions of the BSD License
@@ -17,12 +17,15 @@
#include <Library/DebugLib.h>
#include <Library/IoLib.h>
#include <Library/PcdLib.h>
+#include <Library/SerialPortLib.h>
#include <Drivers/ArmTrustzone.h>
#include <Drivers/PL310L2Cache.h>
#include <ArmPlatform.h>
+#define SerialPrint(txt) SerialPortWrite ((UINT8*)(txt), AsciiStrLen(txt)+1)
+
/**
Initialize the Secure peripherals and memory regions
@@ -119,6 +122,22 @@ ArmPlatformSecInitialize (
IN UINTN MpId
)
{
+ UINT32 Value;
+
+ // If the DRAM is remapped at 0x0 then we need to wake up the secondary cores from wfe
+ // (waiting for the memory to be initialized) as the instruction is still in the remapped
+ // flash region at 0x0 to jump in the C-code which lives in the NOR1 at 0x44000000 before
+ // the region 0x0 is remapped as DRAM.
+ if (!FeaturePcdGet (PcdNorFlashRemapping)) {
+ if (!ArmPlatformIsPrimaryCore (MpId)) {
+ // Replaced ArmCallWFE () in ArmPlatformPkg/Sec/SecEntryPoint.(S|asm)
+ ArmCallWFE ();
+ } else {
+ // Wake up the secondary core from ArmCallWFE () in ArmPlatformPkg/Sec/SecEntryPoint.(S|asm)
+ ArmCallSEV ();
+ }
+ }
+
// If it is not the primary core then there is nothing to do
if (!ArmPlatformIsPrimaryCore (MpId)) {
return RETURN_SUCCESS;
@@ -144,5 +163,14 @@ ArmPlatformSecInitialize (
ArmPlatformInitializeSystemMemory ();
}
+ // Memory Map remapping
+ if (FeaturePcdGet (PcdNorFlashRemapping)) {
+ SerialPrint ("Secure ROM at 0x0\n\r");
+ } else {
+ Value = MmioRead32 (ARM_VE_SYS_CFGRW1_REG); //Scc - CFGRW1
+ // Remap the DRAM to 0x0
+ MmioWrite32 (ARM_VE_SYS_CFGRW1_REG, (Value & 0x0FFFFFFF) | ARM_VE_CFGRW1_REMAP_DRAM);
+ }
+
return RETURN_SUCCESS;
}
diff --git a/ArmPlatformPkg/ArmVExpressPkg/Library/ArmVExpressSecLibRTSM/AArch64/GicV3.S b/ArmPlatformPkg/ArmVExpressPkg/Library/ArmVExpressSecLibRTSM/AArch64/GicV3.S
new file mode 100644
index 000000000..8d2bde2f8
--- /dev/null
+++ b/ArmPlatformPkg/ArmVExpressPkg/Library/ArmVExpressSecLibRTSM/AArch64/GicV3.S
@@ -0,0 +1,67 @@
+//
+// Copyright (c) 2013, ARM Limited. All rights reserved.
+//
+// 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 <AsmMacroIoLib.h>
+
+// Register definitions used by GCC for GICv3 access.
+// These are defined by ARMCC, so keep them in the GCC specific code for now.
+#define ICC_SRE_EL2 S3_4_C12_C9_5
+#define ICC_SRE_EL3 S3_6_C12_C12_5
+#define ICC_CTLR_EL1 S3_0_C12_C12_4
+#define ICC_CTLR_EL3 S3_6_C12_C12_4
+#define ICC_PMR_EL1 S3_0_C4_C6_0
+
+.text
+.align 3
+
+GCC_ASM_EXPORT(InitializeGicV3)
+
+/* Initialize GICv3 to expose it as a GICv2 as UEFI does not support GICv3 yet */
+ASM_PFX(InitializeGicV3):
+ // We have a GICv3. UEFI still uses the GICv2 mode. We must do enough setup
+ // to allow Linux to use GICv3 if it chooses.
+
+ // In order to setup NS side we need to enable it first.
+ mrs x0, scr_el3
+ orr x0, x0, #1
+ msr scr_el3, x0
+
+ // Enable SRE at EL3 and ICC_SRE_EL2 access
+ mov x0, #((1 << 3) | (1 << 0)) // Enable | SRE
+ mrs x1, ICC_SRE_EL3
+ orr x1, x1, x0
+ msr ICC_SRE_EL3, x1
+ isb
+
+ // Enable SRE at EL2 and ICC_SRE_EL1 access..
+ mrs x1, ICC_SRE_EL2
+ orr x1, x1, x0
+ msr ICC_SRE_EL2, x1
+ isb
+
+ // Configure CPU interface
+ msr ICC_CTLR_EL3, xzr
+ isb
+ msr ICC_CTLR_EL1, xzr
+ isb
+
+ // The MemoryMap view and Register view may not be consistent, So Set PMR again.
+ mov w1, #1 << 7 // allow NS access to GICC_PMR
+ msr ICC_PMR_EL1, x1
+ isb
+
+ // Remove the SCR.NS bit
+ mrs x0, scr_el3
+ bic x0, x0, #1
+ msr scr_el3, x0
+ ret
diff --git a/ArmPlatformPkg/ArmVExpressPkg/Library/ArmVExpressSecLibRTSM/Arm/GicV3.S b/ArmPlatformPkg/ArmVExpressPkg/Library/ArmVExpressSecLibRTSM/Arm/GicV3.S
new file mode 100644
index 000000000..4a82cdbd4
--- /dev/null
+++ b/ArmPlatformPkg/ArmVExpressPkg/Library/ArmVExpressSecLibRTSM/Arm/GicV3.S
@@ -0,0 +1,24 @@
+//
+// Copyright (c) 2013, ARM Limited. All rights reserved.
+//
+// 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 <AsmMacroIoLib.h>
+
+.text
+.align 3
+
+GCC_ASM_EXPORT(InitializeGicV3)
+
+/* Initialize GICv3 to expose it as a GICv2 as UEFI does not support GICv3 yet */
+ASM_PFX(InitializeGicV3):
+ // GICv3 Initialization not Supported yet
+ bx lr
diff --git a/ArmPlatformPkg/ArmVExpressPkg/Library/ArmVExpressSecLibRTSM/Arm/GicV3.asm b/ArmPlatformPkg/ArmVExpressPkg/Library/ArmVExpressSecLibRTSM/Arm/GicV3.asm
new file mode 100644
index 000000000..4578c1c31
--- /dev/null
+++ b/ArmPlatformPkg/ArmVExpressPkg/Library/ArmVExpressSecLibRTSM/Arm/GicV3.asm
@@ -0,0 +1,27 @@
+//
+// Copyright (c) 2013, ARM Limited. All rights reserved.
+//
+// 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 AsmMacroIoLib.inc
+
+ EXPORT InitializeGicV3
+
+ PRESERVE8
+ AREA GicV3, CODE, READONLY
+
+/* Initialize GICv3 to expose it as a GICv2 as UEFI does not support GICv3 yet */
+InitializeGicV3 FUNCTION
+ // GICv3 Initialization not Supported yet
+ bx lr
+ ENDFUNC
+
+ END
diff --git a/ArmPlatformPkg/ArmVExpressPkg/Library/ArmVExpressSecLibRTSM/ArmVExpressSecLib.inf b/ArmPlatformPkg/ArmVExpressPkg/Library/ArmVExpressSecLibRTSM/ArmVExpressSecLib.inf
index 27c78f42d..17720ef7e 100644
--- a/ArmPlatformPkg/ArmVExpressPkg/Library/ArmVExpressSecLibRTSM/ArmVExpressSecLib.inf
+++ b/ArmPlatformPkg/ArmVExpressPkg/Library/ArmVExpressSecLibRTSM/ArmVExpressSecLib.inf
@@ -1,13 +1,13 @@
#/* @file
-# Copyright (c) 2011-2012, ARM Limited. All rights reserved.
-#
-# 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
+# Copyright (c) 2011-2013, ARM Limited. All rights reserved.
#
-# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
-# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+# 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.
#
#*/
@@ -37,9 +37,13 @@
[Sources.ARM]
Arm/RTSMBoot.asm | RVCT
Arm/RTSMBoot.S | GCC
+ Arm/GicV3.asm | RVCT
+ Arm/GicV3.S | GCC
[Sources.AARCH64]
AArch64/RTSMBoot.S | GCC
+ AArch64/GicV3.S | GCC
[FixedPcd]
gArmTokenSpaceGuid.PcdFvBaseAddress
+ gArmTokenSpaceGuid.PcdGicInterruptInterfaceBase
diff --git a/ArmPlatformPkg/ArmVExpressPkg/Library/ArmVExpressSecLibRTSM/RTSMSec.c b/ArmPlatformPkg/ArmVExpressPkg/Library/ArmVExpressSecLibRTSM/RTSMSec.c
index bce834eea..4c018f767 100644
--- a/ArmPlatformPkg/ArmVExpressPkg/Library/ArmVExpressSecLibRTSM/RTSMSec.c
+++ b/ArmPlatformPkg/ArmVExpressPkg/Library/ArmVExpressSecLibRTSM/RTSMSec.c
@@ -1,18 +1,19 @@
/** @file
*
-* Copyright (c) 2011-2012, ARM Limited. All rights reserved.
-*
-* 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
+* Copyright (c) 2011-2013, ARM Limited. All rights reserved.
*
-* THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
-* WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+* 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/IoLib.h>
+#include <Library/ArmGicLib.h>
#include <Library/ArmPlatformLib.h>
#include <Library/DebugLib.h>
#include <Library/PcdLib.h>
@@ -22,6 +23,12 @@
#include <ArmPlatform.h>
+// Initialize GICv3 to expose it as a GICv2 as UEFI does not support GICv3 yet
+VOID
+InitializeGicV3 (
+ VOID
+ );
+
/**
Initialize the Secure peripherals and memory regions
@@ -49,6 +56,8 @@ ArmPlatformSecInitialize (
IN UINTN MpId
)
{
+ UINT32 Identification;
+
// If it is not the primary core then there is nothing to do
if (!ArmPlatformIsPrimaryCore (MpId)) {
return RETURN_SUCCESS;
@@ -63,6 +72,14 @@ ArmPlatformSecInitialize (
// Configure SP810 to use 1MHz clock and disable
MmioAndThenOr32 (SP810_CTRL_BASE + SP810_SYS_CTRL_REG, ~SP810_SYS_CTRL_TIMER3_EN, SP810_SYS_CTRL_TIMER3_TIMCLK);
+ // Read the GIC Identification Register
+ Identification = MmioRead32 (PcdGet32(PcdGicInterruptInterfaceBase) + ARM_GIC_ICCIDR);
+
+ // Check if we are GICv3
+ if (ARM_GIC_ICCIDR_GET_ARCH_VERSION(Identification) >= 0x3) {
+ InitializeGicV3 ();
+ }
+
return RETURN_SUCCESS;
}
diff --git a/ArmPlatformPkg/Library/DebugSecExtraActionLib/DebugSecExtraActionLib.c b/ArmPlatformPkg/Library/DebugSecExtraActionLib/DebugSecExtraActionLib.c
index f7c3ab214..f8f91e8fc 100755
--- a/ArmPlatformPkg/Library/DebugSecExtraActionLib/DebugSecExtraActionLib.c
+++ b/ArmPlatformPkg/Library/DebugSecExtraActionLib/DebugSecExtraActionLib.c
@@ -23,8 +23,6 @@
#include <Library/PrintLib.h>
#include <Library/SerialPortLib.h>
-#include <Chipset/ArmV7.h>
-
// When the firmware is built as not Standalone, the secondary cores need to wait the firmware
// entirely written into DRAM. It is the firmware from DRAM which will wake up the secondary cores.
VOID
diff --git a/ArmPlatformPkg/PrePi/AArch64/ModuleEntryPoint.S b/ArmPlatformPkg/PrePi/AArch64/ModuleEntryPoint.S
index e44281953..6358e3a27 100644
--- a/ArmPlatformPkg/PrePi/AArch64/ModuleEntryPoint.S
+++ b/ArmPlatformPkg/PrePi/AArch64/ModuleEntryPoint.S
@@ -16,8 +16,6 @@
#include <Library/PcdLib.h>
#include <AutoGen.h>
-#include <Chipset/ArmV7.h>
-
.text
.align 3
diff --git a/ArmPlatformPkg/PrePi/PeiMPCore.inf b/ArmPlatformPkg/PrePi/PeiMPCore.inf
index ee89c04ae..276a37226 100755
--- a/ArmPlatformPkg/PrePi/PeiMPCore.inf
+++ b/ArmPlatformPkg/PrePi/PeiMPCore.inf
@@ -70,7 +70,6 @@
gArmMpCoreInfoGuid
[FeaturePcd]
- gEmbeddedTokenSpaceGuid.PcdCacheEnable
gEmbeddedTokenSpaceGuid.PcdPrePiProduceMemoryTypeInformationHob
gArmPlatformTokenSpaceGuid.PcdSendSgiToBringUpSecondaryCores
diff --git a/ArmPlatformPkg/PrePi/PeiUniCore.inf b/ArmPlatformPkg/PrePi/PeiUniCore.inf
index 6cb94cbd7..160374eab 100755
--- a/ArmPlatformPkg/PrePi/PeiUniCore.inf
+++ b/ArmPlatformPkg/PrePi/PeiUniCore.inf
@@ -69,7 +69,6 @@
gArmMpCoreInfoGuid
[FeaturePcd]
- gEmbeddedTokenSpaceGuid.PcdCacheEnable
gEmbeddedTokenSpaceGuid.PcdPrePiProduceMemoryTypeInformationHob
gArmPlatformTokenSpaceGuid.PcdSendSgiToBringUpSecondaryCores
diff --git a/ArmPlatformPkg/Scripts/Ds5/system_table.py b/ArmPlatformPkg/Scripts/Ds5/system_table.py
index 2128e25f2..ff1db2f6e 100644
--- a/ArmPlatformPkg/Scripts/Ds5/system_table.py
+++ b/ArmPlatformPkg/Scripts/Ds5/system_table.py
@@ -29,14 +29,17 @@ class DebugInfoTable:
def get_debug_info(self):
# Get the information from EFI_DEBUG_IMAGE_INFO_TABLE_HEADER
count = self.ec.getMemoryService().readMemory32(self.base + 0x4)
- debug_info_table_base = self.ec.getMemoryService().readMemory32(self.base + 0x8)
+ if edk2_debugger.is_aarch64(self.ec):
+ debug_info_table_base = self.ec.getMemoryService().readMemory64(self.base + 0x8)
+ else:
+ debug_info_table_base = self.ec.getMemoryService().readMemory32(self.base + 0x8)
self.DebugInfos = []
for i in range(0, count):
# Get the address of the structure EFI_DEBUG_IMAGE_INFO
if edk2_debugger.is_aarch64(self.ec):
- debug_info = self.ec.getMemoryService().readMemory32(debug_info_table_base + (i * 8))
+ debug_info = self.ec.getMemoryService().readMemory64(debug_info_table_base + (i * 8))
else:
debug_info = self.ec.getMemoryService().readMemory32(debug_info_table_base + (i * 4))
@@ -46,9 +49,9 @@ class DebugInfoTable:
if debug_info_type == 1:
if edk2_debugger.is_aarch64(self.ec):
# Get the base address of the structure EFI_LOADED_IMAGE_PROTOCOL
- loaded_image_protocol = self.ec.getMemoryService().readMemory32(debug_info + 0x8)
+ loaded_image_protocol = self.ec.getMemoryService().readMemory64(debug_info + 0x8)
- image_base = self.ec.getMemoryService().readMemory32(loaded_image_protocol + 0x40)
+ image_base = self.ec.getMemoryService().readMemory64(loaded_image_protocol + 0x40)
image_size = self.ec.getMemoryService().readMemory32(loaded_image_protocol + 0x48)
else:
# Get the base address of the structure EFI_LOADED_IMAGE_PROTOCOL
@@ -135,7 +138,10 @@ class SystemTable:
raise Exception('SystemTable','Fail to access System Memory. Ensure all the memory in the region [0x%x;0x%X] is accessible.' % (membase,membase+memsize))
if signature == SystemTable.CONST_ST_SIGNATURE:
found = True
- self.system_table_base = self.ec.getMemoryService().readMemory32(offset + 0x8)
+ if edk2_debugger.is_aarch64(self.ec):
+ self.system_table_base = self.ec.getMemoryService().readMemory64(offset + 0x8)
+ else:
+ self.system_table_base = self.ec.getMemoryService().readMemory32(offset + 0x8)
break
offset = offset - 0x400000
@@ -148,7 +154,7 @@ class SystemTable:
conf_table_entry_count = self.ec.getMemoryService().readMemory32(self.system_table_base + 0x68)
# Get location of the Configuration Table entries
- conf_table_offset = self.ec.getMemoryService().readMemory32(self.system_table_base + 0x70)
+ conf_table_offset = self.ec.getMemoryService().readMemory64(self.system_table_base + 0x70)
else:
# Number of configuration Table entry
conf_table_entry_count = self.ec.getMemoryService().readMemory32(self.system_table_base + 0x40)
@@ -163,6 +169,9 @@ class SystemTable:
offset = conf_table_offset + (i * 0x14)
guid = struct.unpack("<IIII", self.ec.getMemoryService().read(str(offset), 16, 32))
if guid == conf_table_guid:
- return self.ec.getMemoryService().readMemory32(offset + 0x10)
+ if edk2_debugger.is_aarch64(self.ec):
+ return self.ec.getMemoryService().readMemory64(offset + 0x10)
+ else:
+ return self.ec.getMemoryService().readMemory32(offset + 0x10)
raise Exception('SystemTable','Configuration Table not found')
diff --git a/ArmPlatformPkg/Sec/Sec.inf b/ArmPlatformPkg/Sec/Sec.inf
index 3e9a246d7..c365f2621 100644
--- a/ArmPlatformPkg/Sec/Sec.inf
+++ b/ArmPlatformPkg/Sec/Sec.inf
@@ -55,9 +55,6 @@
PrintLib
SerialPortLib
-[FeaturePcd]
- gArmPlatformTokenSpaceGuid.PcdSystemMemoryInitializeInSec
-
[FixedPcd.common]
gEfiMdeModulePkgTokenSpaceGuid.PcdFirmwareVersionString
diff --git a/BaseTools/Bin/Win32/BPDG.exe b/BaseTools/Bin/Win32/BPDG.exe
index 1a684bb87..d81803a80 100644
--- a/BaseTools/Bin/Win32/BPDG.exe
+++ b/BaseTools/Bin/Win32/BPDG.exe
Binary files differ
diff --git a/BaseTools/Bin/Win32/BootSectImage.exe b/BaseTools/Bin/Win32/BootSectImage.exe
index 59b0b8458..4ba8c50e8 100755
--- a/BaseTools/Bin/Win32/BootSectImage.exe
+++ b/BaseTools/Bin/Win32/BootSectImage.exe
Binary files differ
diff --git a/BaseTools/Bin/Win32/EfiLdrImage.exe b/BaseTools/Bin/Win32/EfiLdrImage.exe
index c732a7330..a06534db8 100755
--- a/BaseTools/Bin/Win32/EfiLdrImage.exe
+++ b/BaseTools/Bin/Win32/EfiLdrImage.exe
Binary files differ
diff --git a/BaseTools/Bin/Win32/EfiRom.exe b/BaseTools/Bin/Win32/EfiRom.exe
index 2e761cc08..1baf7a99d 100755
--- a/BaseTools/Bin/Win32/EfiRom.exe
+++ b/BaseTools/Bin/Win32/EfiRom.exe
Binary files differ
diff --git a/BaseTools/Bin/Win32/GenBootSector.exe b/BaseTools/Bin/Win32/GenBootSector.exe
index 84d67f9b8..df8f019d2 100755
--- a/BaseTools/Bin/Win32/GenBootSector.exe
+++ b/BaseTools/Bin/Win32/GenBootSector.exe
Binary files differ
diff --git a/BaseTools/Bin/Win32/GenCrc32.exe b/BaseTools/Bin/Win32/GenCrc32.exe
index cdefa7589..4a440145e 100755
--- a/BaseTools/Bin/Win32/GenCrc32.exe
+++ b/BaseTools/Bin/Win32/GenCrc32.exe
Binary files differ
diff --git a/BaseTools/Bin/Win32/GenDepex.exe b/BaseTools/Bin/Win32/GenDepex.exe
index 2d7e20f60..ca008dbc3 100755
--- a/BaseTools/Bin/Win32/GenDepex.exe
+++ b/BaseTools/Bin/Win32/GenDepex.exe
Binary files differ
diff --git a/BaseTools/Bin/Win32/GenFds.exe b/BaseTools/Bin/Win32/GenFds.exe
index 6d2a1aa55..529d29152 100755
--- a/BaseTools/Bin/Win32/GenFds.exe
+++ b/BaseTools/Bin/Win32/GenFds.exe
Binary files differ
diff --git a/BaseTools/Bin/Win32/GenFfs.exe b/BaseTools/Bin/Win32/GenFfs.exe
index b419b0d17..3a57ec90f 100755
--- a/BaseTools/Bin/Win32/GenFfs.exe
+++ b/BaseTools/Bin/Win32/GenFfs.exe
Binary files differ
diff --git a/BaseTools/Bin/Win32/GenFv.exe b/BaseTools/Bin/Win32/GenFv.exe
index c6e3ad656..31b49654b 100755
--- a/BaseTools/Bin/Win32/GenFv.exe
+++ b/BaseTools/Bin/Win32/GenFv.exe
Binary files differ
diff --git a/BaseTools/Bin/Win32/GenFw.exe b/BaseTools/Bin/Win32/GenFw.exe
index 8e19c1724..7d53501b8 100755
--- a/BaseTools/Bin/Win32/GenFw.exe
+++ b/BaseTools/Bin/Win32/GenFw.exe
Binary files differ
diff --git a/BaseTools/Bin/Win32/GenPage.exe b/BaseTools/Bin/Win32/GenPage.exe
index a2a95bd30..3ccbb5b33 100755
--- a/BaseTools/Bin/Win32/GenPage.exe
+++ b/BaseTools/Bin/Win32/GenPage.exe
Binary files differ
diff --git a/BaseTools/Bin/Win32/GenPatchPcdTable.exe b/BaseTools/Bin/Win32/GenPatchPcdTable.exe
index 7f7aa5ab6..a978e64b9 100755
--- a/BaseTools/Bin/Win32/GenPatchPcdTable.exe
+++ b/BaseTools/Bin/Win32/GenPatchPcdTable.exe
Binary files differ
diff --git a/BaseTools/Bin/Win32/GenSec.exe b/BaseTools/Bin/Win32/GenSec.exe
index 2cb0c3b81..277d62338 100755
--- a/BaseTools/Bin/Win32/GenSec.exe
+++ b/BaseTools/Bin/Win32/GenSec.exe
Binary files differ
diff --git a/BaseTools/Bin/Win32/GenVtf.exe b/BaseTools/Bin/Win32/GenVtf.exe
index 7e38d68ba..fd936b071 100755
--- a/BaseTools/Bin/Win32/GenVtf.exe
+++ b/BaseTools/Bin/Win32/GenVtf.exe
Binary files differ
diff --git a/BaseTools/Bin/Win32/LzmaCompress.exe b/BaseTools/Bin/Win32/LzmaCompress.exe
index 9838c0e9b..1984cc73e 100755
--- a/BaseTools/Bin/Win32/LzmaCompress.exe
+++ b/BaseTools/Bin/Win32/LzmaCompress.exe
Binary files differ
diff --git a/BaseTools/Bin/Win32/PatchPcdValue.exe b/BaseTools/Bin/Win32/PatchPcdValue.exe
index 142d59a16..aa0e088f7 100755
--- a/BaseTools/Bin/Win32/PatchPcdValue.exe
+++ b/BaseTools/Bin/Win32/PatchPcdValue.exe
Binary files differ
diff --git a/BaseTools/Bin/Win32/Split.exe b/BaseTools/Bin/Win32/Split.exe
index 254590bbe..30451d4bc 100755
--- a/BaseTools/Bin/Win32/Split.exe
+++ b/BaseTools/Bin/Win32/Split.exe
Binary files differ
diff --git a/BaseTools/Bin/Win32/TargetTool.exe b/BaseTools/Bin/Win32/TargetTool.exe
index c8c23d5a3..c8b1006ed 100755
--- a/BaseTools/Bin/Win32/TargetTool.exe
+++ b/BaseTools/Bin/Win32/TargetTool.exe
Binary files differ
diff --git a/BaseTools/Bin/Win32/TianoCompress.exe b/BaseTools/Bin/Win32/TianoCompress.exe
index cdbe97f85..a574d075d 100755
--- a/BaseTools/Bin/Win32/TianoCompress.exe
+++ b/BaseTools/Bin/Win32/TianoCompress.exe
Binary files differ
diff --git a/BaseTools/Bin/Win32/Trim.exe b/BaseTools/Bin/Win32/Trim.exe
index 056581b00..8a8384159 100755
--- a/BaseTools/Bin/Win32/Trim.exe
+++ b/BaseTools/Bin/Win32/Trim.exe
Binary files differ
diff --git a/BaseTools/Bin/Win32/UPT.exe b/BaseTools/Bin/Win32/UPT.exe
index 3101afd61..5bb1d9e2c 100644
--- a/BaseTools/Bin/Win32/UPT.exe
+++ b/BaseTools/Bin/Win32/UPT.exe
Binary files differ
diff --git a/BaseTools/Bin/Win32/VfrCompile.exe b/BaseTools/Bin/Win32/VfrCompile.exe
index 1c1ca78f7..34df8a2dc 100755
--- a/BaseTools/Bin/Win32/VfrCompile.exe
+++ b/BaseTools/Bin/Win32/VfrCompile.exe
Binary files differ
diff --git a/BaseTools/Bin/Win32/VolInfo.exe b/BaseTools/Bin/Win32/VolInfo.exe
index c042d9222..f7a7591cf 100755
--- a/BaseTools/Bin/Win32/VolInfo.exe
+++ b/BaseTools/Bin/Win32/VolInfo.exe
Binary files differ
diff --git a/BaseTools/Bin/Win32/build.exe b/BaseTools/Bin/Win32/build.exe
index 3c03283bd..ee3f7eb9d 100755
--- a/BaseTools/Bin/Win32/build.exe
+++ b/BaseTools/Bin/Win32/build.exe
Binary files differ
diff --git a/BaseTools/Source/C/Common/FvLib.c b/BaseTools/Source/C/Common/FvLib.c
index 1b289d83c..4758749dc 100644
--- a/BaseTools/Source/C/Common/FvLib.c
+++ b/BaseTools/Source/C/Common/FvLib.c
@@ -1,6 +1,6 @@
/** @file
-Copyright (c) 2004 - 2008, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2004 - 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
@@ -181,7 +181,7 @@ Returns:
//
// Verify file is in this FV.
//
- if ((UINTN) CurrentFile + GetLength (CurrentFile->Size) > (UINTN) mFvHeader + mFvLength) {
+ if ((UINTN) CurrentFile + GetFfsFileLength(CurrentFile) > (UINTN) mFvHeader + mFvLength) {
*NextFile = NULL;
return EFI_SUCCESS;
}
@@ -194,20 +194,20 @@ Returns:
// Verify current file is in range
//
if (((UINTN) CurrentFile < (UINTN) mFvHeader + mFvHeader->HeaderLength) ||
- ((UINTN) CurrentFile + GetLength (CurrentFile->Size) > (UINTN) mFvHeader + mFvLength)
+ ((UINTN) CurrentFile + GetFfsFileLength(CurrentFile) > (UINTN) mFvHeader + mFvLength)
) {
return EFI_INVALID_PARAMETER;
}
//
// Get next file, compensate for 8 byte alignment if necessary.
//
- *NextFile = (EFI_FFS_FILE_HEADER *) ((((UINTN) CurrentFile - (UINTN) mFvHeader + GetLength (CurrentFile->Size) + 0x07) & (-1 << 3)) + (UINT8 *) mFvHeader);
+ *NextFile = (EFI_FFS_FILE_HEADER *) ((((UINTN) CurrentFile - (UINTN) mFvHeader + GetFfsFileLength(CurrentFile) + 0x07) & (-1 << 3)) + (UINT8 *) mFvHeader);
//
// Verify file is in this FV.
//
- if (((UINTN) *NextFile + sizeof (EFI_FFS_FILE_HEADER) >= (UINTN) mFvHeader + mFvLength) ||
- ((UINTN) *NextFile + GetLength ((*NextFile)->Size) > (UINTN) mFvHeader + mFvLength)
+ if (((UINTN) *NextFile + GetFfsHeaderLength(*NextFile) >= (UINTN) mFvHeader + mFvLength) ||
+ ((UINTN) *NextFile + GetFfsFileLength (*NextFile) > (UINTN) mFvHeader + mFvLength)
) {
*NextFile = NULL;
return EFI_SUCCESS;
@@ -434,7 +434,11 @@ Returns:
EFI_FILE_SECTION_POINTER InnerSection;
EFI_STATUS Status;
UINTN SectionSize;
+ UINT16 GuidSecAttr;
+ UINT16 GuidDataOffset;
+ GuidSecAttr = 0;
+ GuidDataOffset = 0;
CurrentSection = FirstSection;
while ((UINTN) CurrentSection.CommonHeader < (UINTN) SearchEnd) {
@@ -452,14 +456,21 @@ Returns:
// special processing, go ahead to search the requesting
// section inside the GUID-defined section.
//
+ if (CurrentSection.CommonHeader->Type == EFI_SECTION_GUID_DEFINED) {
+ if (GetLength(CurrentSection.CommonHeader->Size) == 0xffffff) {
+ GuidSecAttr = CurrentSection.GuidDefinedSection2->Attributes;
+ GuidDataOffset = CurrentSection.GuidDefinedSection2->DataOffset;
+ } else {
+ GuidSecAttr = CurrentSection.GuidDefinedSection->Attributes;
+ GuidDataOffset = CurrentSection.GuidDefinedSection->DataOffset;
+ }
+ }
if (SectionType != EFI_SECTION_GUID_DEFINED &&
CurrentSection.CommonHeader->Type == EFI_SECTION_GUID_DEFINED &&
- !(CurrentSection.GuidDefinedSection->Attributes & EFI_GUIDED_SECTION_PROCESSING_REQUIRED)) {
+ !(GuidSecAttr & EFI_GUIDED_SECTION_PROCESSING_REQUIRED)) {
InnerSection.CommonHeader = (EFI_COMMON_SECTION_HEADER *)
- ((UINTN) CurrentSection.CommonHeader + CurrentSection.GuidDefinedSection->DataOffset);
- SectionSize = CurrentSection.CommonHeader->Size[0] +
- (CurrentSection.CommonHeader->Size[1] << 8) +
- (CurrentSection.CommonHeader->Size[2] << 16);
+ ((UINTN) CurrentSection.CommonHeader + GuidDataOffset);
+ SectionSize = GetSectionFileLength(CurrentSection.CommonHeader);
Status = SearchSectionByType (
InnerSection,
(UINT8 *) ((UINTN) CurrentSection.CommonHeader + SectionSize),
@@ -475,7 +486,7 @@ Returns:
//
// Find next section (including compensating for alignment issues.
//
- CurrentSection.CommonHeader = (EFI_COMMON_SECTION_HEADER *) ((((UINTN) CurrentSection.CommonHeader) + GetLength (CurrentSection.CommonHeader->Size) + 0x03) & (-1 << 2));
+ CurrentSection.CommonHeader = (EFI_COMMON_SECTION_HEADER *) ((((UINTN) CurrentSection.CommonHeader) + GetSectionFileLength(CurrentSection.CommonHeader) + 0x03) & (-1 << 2));
}
return EFI_NOT_FOUND;
@@ -538,14 +549,14 @@ Returns:
//
// Get the first section
//
- CurrentSection.CommonHeader = (EFI_COMMON_SECTION_HEADER *) ((UINTN) File + sizeof (EFI_FFS_FILE_HEADER));
+ CurrentSection.CommonHeader = (EFI_COMMON_SECTION_HEADER *) ((UINTN) File + GetFfsHeaderLength(File));
//
// Depth-first manner to find section file.
//
Status = SearchSectionByType (
CurrentSection,
- (UINT8 *) ((UINTN) File + GetLength (File->Size)),
+ (UINT8 *) ((UINTN) File + GetFfsFileLength (File)),
SectionType,
&SectionCount,
Instance,
@@ -639,12 +650,14 @@ Returns:
{
BOOLEAN ErasePolarity;
EFI_STATUS Status;
- EFI_FFS_FILE_HEADER BlankHeader;
+ EFI_FFS_FILE_HEADER2 BlankHeader;
UINT8 Checksum;
UINT32 FileLength;
UINT8 SavedChecksum;
UINT8 SavedState;
UINT8 FileGuidString[80];
+ UINT32 FfsHeaderSize;
+
//
// Verify library has been initialized.
//
@@ -665,16 +678,18 @@ Returns:
if (EFI_ERROR (Status)) {
return EFI_ABORTED;
}
+
+ FfsHeaderSize = GetFfsHeaderLength(FfsHeader);
//
// Check if we have free space
//
if (ErasePolarity) {
- memset (&BlankHeader, -1, sizeof (EFI_FFS_FILE_HEADER));
+ memset (&BlankHeader, -1, FfsHeaderSize);
} else {
- memset (&BlankHeader, 0, sizeof (EFI_FFS_FILE_HEADER));
+ memset (&BlankHeader, 0, FfsHeaderSize);
}
- if (memcmp (&BlankHeader, FfsHeader, sizeof (EFI_FFS_FILE_HEADER)) == 0) {
+ if (memcmp (&BlankHeader, FfsHeader, FfsHeaderSize) == 0) {
return EFI_NOT_FOUND;
}
//
@@ -689,7 +704,7 @@ Returns:
FfsHeader->State = 0;
SavedChecksum = FfsHeader->IntegrityCheck.Checksum.File;
FfsHeader->IntegrityCheck.Checksum.File = 0;
- Checksum = CalculateSum8 ((UINT8 *) FfsHeader, sizeof (EFI_FFS_FILE_HEADER));
+ Checksum = CalculateSum8 ((UINT8 *) FfsHeader, FfsHeaderSize);
FfsHeader->State = SavedState;
FfsHeader->IntegrityCheck.Checksum.File = SavedChecksum;
if (Checksum != 0) {
@@ -703,8 +718,8 @@ Returns:
//
// Verify file data checksum
//
- FileLength = GetLength (FfsHeader->Size);
- Checksum = CalculateSum8 ((UINT8 *) (FfsHeader + 1), FileLength - sizeof (EFI_FFS_FILE_HEADER));
+ FileLength = GetFfsFileLength (FfsHeader);
+ Checksum = CalculateSum8 ((UINT8 *) ((UINT8 *)FfsHeader + FfsHeaderSize), FileLength - FfsHeaderSize);
Checksum = Checksum + FfsHeader->IntegrityCheck.Checksum.File;
if (Checksum != 0) {
Error (NULL, 0, 0006, "invalid FFS file checksum", "Ffs file with Guid %s", FileGuidString);
@@ -725,6 +740,80 @@ Returns:
}
UINT32
+GetFfsHeaderLength(
+ IN EFI_FFS_FILE_HEADER *FfsHeader
+ )
+{
+ if (FfsHeader == NULL) {
+ return 0;
+ }
+ if (FfsHeader->Attributes & FFS_ATTRIB_LARGE_FILE) {
+ return sizeof(EFI_FFS_FILE_HEADER2);
+ }
+ return sizeof(EFI_FFS_FILE_HEADER);
+}
+
+UINT32
+GetSectionHeaderLength(
+ IN EFI_COMMON_SECTION_HEADER *SectionHeader
+ )
+{
+ if (SectionHeader == NULL) {
+ return 0;
+ }
+ if (GetLength(SectionHeader->Size) == 0xffffff) {
+ return sizeof(EFI_COMMON_SECTION_HEADER2);
+ }
+ return sizeof(EFI_COMMON_SECTION_HEADER);
+}
+
+UINT32
+GetFfsFileLength (
+ EFI_FFS_FILE_HEADER *FfsHeader
+ )
+/*++
+
+Routine Description:
+
+ Get FFS file length including FFS header.
+
+Arguments:
+
+ FfsHeader Pointer to EFI_FFS_FILE_HEADER.
+
+Returns:
+
+ UINT32 Length of FFS file header.
+
+--*/
+{
+ if (FfsHeader == NULL) {
+ return 0;
+ }
+ if (FfsHeader->Attributes & FFS_ATTRIB_LARGE_FILE) {
+ return ((EFI_FFS_FILE_HEADER2 *)FfsHeader)->ExtendedSize;
+ } else {
+ return GetLength(FfsHeader->Size);
+ }
+}
+
+UINT32
+GetSectionFileLength (
+ EFI_COMMON_SECTION_HEADER *SectionHeader
+ )
+{
+ UINT32 Length;
+ if (SectionHeader == NULL) {
+ return 0;
+ }
+ Length = GetLength(SectionHeader->Size);
+ if (Length == 0xffffff) {
+ Length = ((EFI_COMMON_SECTION_HEADER2 *)SectionHeader)->ExtendedSize;
+ }
+ return Length;
+}
+
+UINT32
GetLength (
UINT8 *ThreeByteLength
)
diff --git a/BaseTools/Source/C/Common/FvLib.h b/BaseTools/Source/C/Common/FvLib.h
index 7815baae3..567430a37 100644
--- a/BaseTools/Source/C/Common/FvLib.h
+++ b/BaseTools/Source/C/Common/FvLib.h
@@ -1,6 +1,6 @@
/** @file
-Copyright (c) 2004 - 2008, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2004 - 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
@@ -90,6 +90,30 @@ VerifyFfsFile (
)
;
+UINT32
+GetFfsFileLength (
+ EFI_FFS_FILE_HEADER *FfsHeader
+ )
+;
+
+UINT32
+GetSectionFileLength (
+ EFI_COMMON_SECTION_HEADER *SectionHeader
+ )
+;
+
+UINT32
+GetFfsHeaderLength(
+ IN EFI_FFS_FILE_HEADER *FfsHeader
+ )
+;
+
+UINT32
+GetSectionHeaderLength(
+ IN EFI_COMMON_SECTION_HEADER *SectionHeader
+ )
+;
+
/*++
Routine Description:
diff --git a/BaseTools/Source/C/GenFfs/GenFfs.c b/BaseTools/Source/C/GenFfs/GenFfs.c
index 24081ebfc..6f4804e90 100644
--- a/BaseTools/Source/C/GenFfs/GenFfs.c
+++ b/BaseTools/Source/C/GenFfs/GenFfs.c
@@ -1,6 +1,6 @@
/**
-Copyright (c) 2004 - 2010, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2004 - 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
@@ -119,7 +119,7 @@ Returns:
//
// Copyright declaration
//
- fprintf (stdout, "Copyright (c) 2007 - 2010, Intel Corporation. All rights reserved.\n\n");
+ fprintf (stdout, "Copyright (c) 2007 - 2013, Intel Corporation. All rights reserved.\n\n");
//
// Details Option
@@ -284,10 +284,11 @@ Returns:
UINT32 Index;
FILE *InFile;
EFI_COMMON_SECTION_HEADER *SectHeader;
- EFI_COMMON_SECTION_HEADER TempSectHeader;
+ EFI_COMMON_SECTION_HEADER2 TempSectHeader;
EFI_TE_IMAGE_HEADER TeHeader;
UINT32 TeOffset;
EFI_GUID_DEFINED_SECTION GuidSectHeader;
+ EFI_GUID_DEFINED_SECTION2 GuidSectHeader2;
UINT32 HeaderSize;
Size = 0;
@@ -332,8 +333,12 @@ Returns:
// Check this section is Te/Pe section, and Calculate the numbers of Te/Pe section.
//
TeOffset = 0;
- HeaderSize = sizeof (EFI_COMMON_SECTION_HEADER);
- fread (&TempSectHeader, 1, sizeof (TempSectHeader), InFile);
+ if (FileSize >= MAX_FFS_SIZE) {
+ HeaderSize = sizeof (EFI_COMMON_SECTION_HEADER2);
+ } else {
+ HeaderSize = sizeof (EFI_COMMON_SECTION_HEADER);
+ }
+ fread (&TempSectHeader, 1, HeaderSize, InFile);
if (TempSectHeader.Type == EFI_SECTION_TE) {
(*PESectionNum) ++;
fread (&TeHeader, 1, sizeof (TeHeader), InFile);
@@ -344,9 +349,16 @@ Returns:
(*PESectionNum) ++;
} else if (TempSectHeader.Type == EFI_SECTION_GUID_DEFINED) {
fseek (InFile, 0, SEEK_SET);
- fread (&GuidSectHeader, 1, sizeof (GuidSectHeader), InFile);
- if ((GuidSectHeader.Attributes & EFI_GUIDED_SECTION_PROCESSING_REQUIRED) == 0) {
- HeaderSize = GuidSectHeader.DataOffset;
+ if (FileSize >= MAX_SECTION_SIZE) {
+ fread (&GuidSectHeader2, 1, sizeof (GuidSectHeader2), InFile);
+ if ((GuidSectHeader2.Attributes & EFI_GUIDED_SECTION_PROCESSING_REQUIRED) == 0) {
+ HeaderSize = GuidSectHeader2.DataOffset;
+ }
+ } else {
+ fread (&GuidSectHeader, 1, sizeof (GuidSectHeader), InFile);
+ if ((GuidSectHeader.Attributes & EFI_GUIDED_SECTION_PROCESSING_REQUIRED) == 0) {
+ HeaderSize = GuidSectHeader.DataOffset;
+ }
}
(*PESectionNum) ++;
} else if (TempSectHeader.Type == EFI_SECTION_COMPRESSION ||
@@ -378,6 +390,9 @@ Returns:
Offset = Offset - Size - HeaderSize - TeOffset;
if (FileBuffer != NULL && ((Size + Offset) < *BufferLength)) {
+ //
+ // The maximal alignment is 64K, the raw section size must be less than 0xffffff
+ //
memset (FileBuffer + Size, 0, Offset);
SectHeader = (EFI_COMMON_SECTION_HEADER *) (FileBuffer + Size);
SectHeader->Type = EFI_SECTION_RAW;
@@ -453,11 +468,12 @@ Returns:
UINT8 *FileBuffer;
UINT32 FileSize;
UINT32 MaxAlignment;
- EFI_FFS_FILE_HEADER FfsFileHeader;
+ EFI_FFS_FILE_HEADER2 FfsFileHeader;
FILE *FfsFile;
UINT32 Index;
UINT64 LogLevel;
UINT8 PeSectionNum;
+ UINT32 HeaderSize;
//
// Init local variables
@@ -816,7 +832,7 @@ Returns:
//
// Create Ffs file header.
//
- memset (&FfsFileHeader, 0, sizeof (EFI_FFS_FILE_HEADER));
+ memset (&FfsFileHeader, 0, sizeof (EFI_FFS_FILE_HEADER2));
memcpy (&FfsFileHeader.Name, &FileGuid, sizeof (EFI_GUID));
FfsFileHeader.Type = FfsFiletype;
//
@@ -832,16 +848,27 @@ Returns:
FfsAlign = Index;
}
VerboseMsg ("the alignment of the generated FFS file is %u", (unsigned) mFfsValidAlign [FfsAlign + 1]);
- FfsFileHeader.Attributes = (EFI_FFS_FILE_ATTRIBUTES) (FfsAttrib | (FfsAlign << 3));
//
// Now FileSize includes the EFI_FFS_FILE_HEADER
//
- FileSize += sizeof (EFI_FFS_FILE_HEADER);
+ if (FileSize + sizeof (EFI_FFS_FILE_HEADER) >= MAX_FFS_SIZE) {
+ HeaderSize = sizeof (EFI_FFS_FILE_HEADER2);
+ FileSize += sizeof (EFI_FFS_FILE_HEADER2);
+ FfsFileHeader.ExtendedSize = FileSize;
+ memset(FfsFileHeader.Size, 0, sizeof (UINT8) * 3);
+ FfsAttrib |= FFS_ATTRIB_LARGE_FILE;
+ } else {
+ HeaderSize = sizeof (EFI_FFS_FILE_HEADER);
+ FileSize += sizeof (EFI_FFS_FILE_HEADER);
+ FfsFileHeader.Size[0] = (UINT8) (FileSize & 0xFF);
+ FfsFileHeader.Size[1] = (UINT8) ((FileSize & 0xFF00) >> 8);
+ FfsFileHeader.Size[2] = (UINT8) ((FileSize & 0xFF0000) >> 16);
+ }
VerboseMsg ("the size of the generated FFS file is %u bytes", (unsigned) FileSize);
- FfsFileHeader.Size[0] = (UINT8) (FileSize & 0xFF);
- FfsFileHeader.Size[1] = (UINT8) ((FileSize & 0xFF00) >> 8);
- FfsFileHeader.Size[2] = (UINT8) ((FileSize & 0xFF0000) >> 16);
+
+ FfsFileHeader.Attributes = (EFI_FFS_FILE_ATTRIBUTES) (FfsAttrib | (FfsAlign << 3));
+
//
// Fill in checksums and state, these must be zero for checksumming
//
@@ -851,7 +878,7 @@ Returns:
//
FfsFileHeader.IntegrityCheck.Checksum.Header = CalculateChecksum8 (
(UINT8 *) &FfsFileHeader,
- sizeof (EFI_FFS_FILE_HEADER)
+ HeaderSize
);
if (FfsFileHeader.Attributes & FFS_ATTRIB_CHECKSUM) {
@@ -860,7 +887,7 @@ Returns:
//
FfsFileHeader.IntegrityCheck.Checksum.File = CalculateChecksum8 (
FileBuffer,
- FileSize - sizeof (EFI_FFS_FILE_HEADER)
+ FileSize - HeaderSize
);
} else {
FfsFileHeader.IntegrityCheck.Checksum.File = FFS_FIXED_CHECKSUM;
@@ -880,11 +907,11 @@ Returns:
//
// write header
//
- fwrite (&FfsFileHeader, 1, sizeof (FfsFileHeader), FfsFile);
+ fwrite (&FfsFileHeader, 1, HeaderSize, FfsFile);
//
// write data
//
- fwrite (FileBuffer, 1, FileSize - sizeof (EFI_FFS_FILE_HEADER), FfsFile);
+ fwrite (FileBuffer, 1, FileSize - HeaderSize, FfsFile);
fclose (FfsFile);
diff --git a/BaseTools/Source/C/GenFv/GenFv.c b/BaseTools/Source/C/GenFv/GenFv.c
index fa86d009d..8f837d269 100644
--- a/BaseTools/Source/C/GenFv/GenFv.c
+++ b/BaseTools/Source/C/GenFv/GenFv.c
@@ -1,6 +1,6 @@
/** @file
-Copyright (c) 2007 - 2010, Intel Corporation. All rights reserved.<BR>
+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
@@ -42,6 +42,7 @@ Abstract:
#define UTILITY_MINOR_VERSION 1
EFI_GUID mEfiFirmwareFileSystem2Guid = EFI_FIRMWARE_FILE_SYSTEM2_GUID;
+EFI_GUID mEfiFirmwareFileSystem3Guid = EFI_FIRMWARE_FILE_SYSTEM3_GUID;
STATIC
VOID
@@ -96,7 +97,7 @@ Returns:
//
// Copyright declaration
//
- fprintf (stdout, "Copyright (c) 2007 - 2010, Intel Corporation. All rights reserved.\n\n");
+ fprintf (stdout, "Copyright (c) 2007 - 2013, Intel Corporation. All rights reserved.\n\n");
//
// Details Option
@@ -143,6 +144,8 @@ Returns:
Its format is xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx\n");
fprintf (stdout, " --capflag CapFlag Capsule Reset Flag can be PersistAcrossReset,\n\
or PopulateSystemTable or InitiateReset or not set\n");
+ fprintf (stdout, " --capoemflag CapOEMFlag\n\
+ Capsule OEM Flag is an integer between 0x0000 and 0xffff\n");
fprintf (stdout, " --capheadsize HeadSize\n\
HeadSize is one HEX or DEC format value\n\
HeadSize is required by Capsule Image.\n");
@@ -439,6 +442,22 @@ Returns:
continue;
}
+ if (stricmp (argv[0], "--capoemflag") == 0) {
+ if (argv[1] == NULL) {
+ Error (NULL, 0, 1003, "Invalid option value", "Capsule OEM flag can't be null");
+ }
+ Status = AsciiStringToUint64(argv[1], FALSE, &TempNumber);
+ if (EFI_ERROR (Status) || TempNumber > 0xffff) {
+ Error (NULL, 0, 1003, "Invalid option value", "Capsule OEM flag value must be integer value between 0x0000 and 0xffff");
+ return STATUS_ERROR;
+ }
+ mCapDataInfo.Flags |= TempNumber;
+ DebugMsg( NULL, 0, 9, "Capsule OEM Flags", argv[1]);
+ argc -= 2;
+ argv += 2;
+ continue;
+ }
+
if (stricmp (argv[0], "--capguid") == 0) {
//
// Get the Capsule Guid
diff --git a/BaseTools/Source/C/GenFv/GenFvInternalLib.c b/BaseTools/Source/C/GenFv/GenFvInternalLib.c
index dd0e9ec3b..d0df4ac13 100644
--- a/BaseTools/Source/C/GenFv/GenFvInternalLib.c
+++ b/BaseTools/Source/C/GenFv/GenFvInternalLib.c
@@ -1,6 +1,6 @@
/** @file
-Copyright (c) 2004 - 2011, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2004 - 2013, Intel Corporation. All rights reserved.<BR>
Portions Copyright (c) 2011 - 2013, ARM Ltd. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
@@ -159,6 +159,7 @@ UINT8 m64kRecoveryStartupApDataArray[SIZEOF_ST
FV_INFO mFvDataInfo;
CAP_INFO mCapDataInfo;
+BOOLEAN mIsLargeFfs = FALSE;
EFI_PHYSICAL_ADDRESS mFvBaseAddress[0x10];
UINT32 mFvBaseAddressNumber = 0;
@@ -281,6 +282,19 @@ Returns:
}
//
+ // Read weak alignment flag
+ //
+ Status = FindToken (InfFile, ATTRIBUTES_SECTION_STRING, EFI_FV_WEAK_ALIGNMENT_STRING, 0, Value);
+ if (Status == EFI_SUCCESS) {
+ if ((strcmp (Value, TRUE_STRING) == 0) || (strcmp (Value, ONE_STRING) == 0)) {
+ FvInfo->FvAttributes |= EFI_FVB2_WEAK_ALIGNMENT;
+ } else if ((strcmp (Value, FALSE_STRING) != 0) && (strcmp (Value, ZERO_STRING) != 0)) {
+ Error (NULL, 0, 2000, "Invalid parameter", "Weak alignment value expected one of TRUE, FALSE, 1 or 0.");
+ return EFI_ABORTED;
+ }
+ }
+
+ //
// Read block maps
//
for (Index = 0; Index < MAX_NUMBER_OF_FV_BLOCKS; Index++) {
@@ -510,7 +524,8 @@ AddPadFile (
IN OUT MEMORY_FILE *FvImage,
IN UINT32 DataAlignment,
IN VOID *FvEnd,
- IN EFI_FIRMWARE_VOLUME_EXT_HEADER *ExtHeader
+ IN EFI_FIRMWARE_VOLUME_EXT_HEADER *ExtHeader,
+ IN UINT32 NextFfsSize
)
/*++
@@ -538,7 +553,10 @@ Returns:
{
EFI_FFS_FILE_HEADER *PadFile;
UINTN PadFileSize;
+ UINT32 NextFfsHeaderSize;
+ UINT32 CurFfsHeaderSize;
+ CurFfsHeaderSize = sizeof (EFI_FFS_FILE_HEADER);
//
// Verify input parameters.
//
@@ -547,42 +565,44 @@ Returns:
}
//
- // Check if a pad file is necessary
- //
- if ((ExtHeader == NULL) && (((UINTN) FvImage->CurrentFilePointer - (UINTN) FvImage->FileImage + sizeof (EFI_FFS_FILE_HEADER)) % DataAlignment == 0)) {
- return EFI_SUCCESS;
- }
-
- //
// Calculate the pad file size
//
- //
- // This is the earliest possible valid offset (current plus pad file header
- // plus the next file header)
- //
- PadFileSize = (UINTN) FvImage->CurrentFilePointer - (UINTN) FvImage->FileImage + (sizeof (EFI_FFS_FILE_HEADER) * 2);
//
- // Add whatever it takes to get to the next aligned address
- //
- while ((PadFileSize % DataAlignment) != 0) {
- PadFileSize++;
- }
- //
- // Subtract the next file header size
- //
- PadFileSize -= sizeof (EFI_FFS_FILE_HEADER);
-
- //
- // Subtract the starting offset to get size
- //
- PadFileSize -= (UINTN) FvImage->CurrentFilePointer - (UINTN) FvImage->FileImage;
-
- //
// Append extension header size
//
if (ExtHeader != NULL) {
- PadFileSize = PadFileSize + ExtHeader->ExtHeaderSize;
+ PadFileSize = ExtHeader->ExtHeaderSize;
+ if (PadFileSize + sizeof (EFI_FFS_FILE_HEADER) >= MAX_FFS_SIZE) {
+ CurFfsHeaderSize = sizeof (EFI_FFS_FILE_HEADER2);
+ }
+ PadFileSize += CurFfsHeaderSize;
+ } else {
+ NextFfsHeaderSize = sizeof (EFI_FFS_FILE_HEADER);
+ if (NextFfsSize >= MAX_FFS_SIZE) {
+ NextFfsHeaderSize = sizeof (EFI_FFS_FILE_HEADER2);
+ }
+ //
+ // Check if a pad file is necessary
+ //
+ if (((UINTN) FvImage->CurrentFilePointer - (UINTN) FvImage->FileImage + NextFfsHeaderSize) % DataAlignment == 0) {
+ return EFI_SUCCESS;
+ }
+ PadFileSize = (UINTN) FvImage->CurrentFilePointer - (UINTN) FvImage->FileImage + sizeof (EFI_FFS_FILE_HEADER) + NextFfsHeaderSize;
+ //
+ // Add whatever it takes to get to the next aligned address
+ //
+ while ((PadFileSize % DataAlignment) != 0) {
+ PadFileSize++;
+ }
+ //
+ // Subtract the next file header size
+ //
+ PadFileSize -= NextFfsHeaderSize;
+ //
+ // Subtract the starting offset to get size
+ //
+ PadFileSize -= (UINTN) FvImage->CurrentFilePointer - (UINTN) FvImage->FileImage;
}
//
@@ -606,9 +626,15 @@ Returns:
//
// Write pad file size (calculated size minus next file header size)
//
- PadFile->Size[0] = (UINT8) (PadFileSize & 0xFF);
- PadFile->Size[1] = (UINT8) ((PadFileSize >> 8) & 0xFF);
- PadFile->Size[2] = (UINT8) ((PadFileSize >> 16) & 0xFF);
+ if (PadFileSize >= MAX_FFS_SIZE) {
+ memset(PadFile->Size, 0, sizeof(UINT8) * 3);
+ ((EFI_FFS_FILE_HEADER2 *)PadFile)->ExtendedSize = PadFileSize;
+ PadFile->Attributes |= FFS_ATTRIB_LARGE_FILE;
+ } else {
+ PadFile->Size[0] = (UINT8) (PadFileSize & 0xFF);
+ PadFile->Size[1] = (UINT8) ((PadFileSize >> 8) & 0xFF);
+ PadFile->Size[2] = (UINT8) ((PadFileSize >> 16) & 0xFF);
+ }
//
// Fill in checksums and state, they must be 0 for checksumming.
@@ -616,7 +642,7 @@ Returns:
PadFile->IntegrityCheck.Checksum.Header = 0;
PadFile->IntegrityCheck.Checksum.File = 0;
PadFile->State = 0;
- PadFile->IntegrityCheck.Checksum.Header = CalculateChecksum8 ((UINT8 *) PadFile, sizeof (EFI_FFS_FILE_HEADER));
+ PadFile->IntegrityCheck.Checksum.Header = CalculateChecksum8 ((UINT8 *) PadFile, CurFfsHeaderSize);
PadFile->IntegrityCheck.Checksum.File = FFS_FIXED_CHECKSUM;
PadFile->State = EFI_FILE_HEADER_CONSTRUCTION | EFI_FILE_HEADER_VALID | EFI_FILE_DATA_VALID;
@@ -634,8 +660,8 @@ Returns:
//
// Copy Fv Extension Header and Set Fv Extension header offset
//
- memcpy (PadFile + 1, ExtHeader, ExtHeader->ExtHeaderSize);
- ((EFI_FIRMWARE_VOLUME_HEADER *) FvImage->FileImage)->ExtHeaderOffset = (UINT16) ((UINTN) (PadFile + 1) - (UINTN) FvImage->FileImage);
+ memcpy ((UINT8 *)PadFile + CurFfsHeaderSize, ExtHeader, ExtHeader->ExtHeaderSize);
+ ((EFI_FIRMWARE_VOLUME_HEADER *) FvImage->FileImage)->ExtHeaderOffset = (UINT16) ((UINTN) ((UINT8 *)PadFile + CurFfsHeaderSize) - (UINTN) FvImage->FileImage);
//
// Make next file start at QWord Boundry
//
@@ -1078,7 +1104,7 @@ Returns:
//
// Sanity check. The file MUST align appropriately
//
- if (((UINTN) *VtfFileImage + sizeof (EFI_FFS_FILE_HEADER) - (UINTN) FvImage->FileImage) % (1 << CurrentFileAlignment)) {
+ if (((UINTN) *VtfFileImage + GetFfsHeaderLength((EFI_FFS_FILE_HEADER *)FileBuffer) - (UINTN) FvImage->FileImage) % (1 << CurrentFileAlignment)) {
Error (NULL, 0, 3000, "Invalid", "VTF file cannot be aligned on a %u-byte boundary.", (unsigned) (1 << CurrentFileAlignment));
free (FileBuffer);
return EFI_ABORTED;
@@ -1116,7 +1142,7 @@ Returns:
//
// Add pad file if necessary
//
- Status = AddPadFile (FvImage, 1 << CurrentFileAlignment, *VtfFileImage, NULL);
+ Status = AddPadFile (FvImage, 1 << CurrentFileAlignment, *VtfFileImage, NULL, FileSize);
if (EFI_ERROR (Status)) {
Error (NULL, 0, 4002, "Resource", "FV space is full, could not add pad file for data alignment property.");
free (FileBuffer);
@@ -1190,6 +1216,7 @@ Returns:
{
EFI_FFS_FILE_HEADER *PadFile;
UINTN FileSize;
+ UINT32 FfsHeaderSize;
//
// If there is no VTF or the VTF naturally follows the previous file without a
@@ -1219,9 +1246,18 @@ Returns:
// FileSize includes the EFI_FFS_FILE_HEADER
//
FileSize = (UINTN) VtfFileImage - (UINTN) FvImage->CurrentFilePointer;
- PadFile->Size[0] = (UINT8) (FileSize & 0x000000FF);
- PadFile->Size[1] = (UINT8) ((FileSize & 0x0000FF00) >> 8);
- PadFile->Size[2] = (UINT8) ((FileSize & 0x00FF0000) >> 16);
+ if (FileSize >= MAX_FFS_SIZE) {
+ PadFile->Attributes |= FFS_ATTRIB_LARGE_FILE;
+ memset(PadFile->Size, 0, sizeof(UINT8) * 3);
+ ((EFI_FFS_FILE_HEADER2 *)PadFile)->ExtendedSize = FileSize;
+ FfsHeaderSize = sizeof(EFI_FFS_FILE_HEADER2);
+ mIsLargeFfs = TRUE;
+ } else {
+ PadFile->Size[0] = (UINT8) (FileSize & 0x000000FF);
+ PadFile->Size[1] = (UINT8) ((FileSize & 0x0000FF00) >> 8);
+ PadFile->Size[2] = (UINT8) ((FileSize & 0x00FF0000) >> 16);
+ FfsHeaderSize = sizeof(EFI_FFS_FILE_HEADER);
+ }
//
// Fill in checksums and state, must be zero during checksum calculation.
@@ -1229,7 +1265,7 @@ Returns:
PadFile->IntegrityCheck.Checksum.Header = 0;
PadFile->IntegrityCheck.Checksum.File = 0;
PadFile->State = 0;
- PadFile->IntegrityCheck.Checksum.Header = CalculateChecksum8 ((UINT8 *) PadFile, sizeof (EFI_FFS_FILE_HEADER));
+ PadFile->IntegrityCheck.Checksum.Header = CalculateChecksum8 ((UINT8 *) PadFile, FfsHeaderSize);
PadFile->IntegrityCheck.Checksum.File = FFS_FIXED_CHECKSUM;
PadFile->State = EFI_FILE_HEADER_CONSTRUCTION | EFI_FILE_HEADER_VALID | EFI_FILE_DATA_VALID;
@@ -1297,6 +1333,8 @@ Returns:
UINT64 FitAddress;
FIT_TABLE *FitTablePtr;
BOOLEAN Vtf0Detected;
+ UINT32 FfsHeaderSize;
+ UINT32 SecHeaderSize;
//
// Verify input parameters
@@ -1359,8 +1397,9 @@ Returns:
return EFI_ABORTED;
}
+ SecHeaderSize = GetSectionHeaderLength(Pe32Section.CommonHeader);
Status = GetPe32Info (
- (VOID *) ((UINTN) Pe32Section.Pe32Section + sizeof (EFI_SECTION_PE32)),
+ (VOID *) ((UINTN) Pe32Section.Pe32Section + SecHeaderSize),
&EntryPoint,
&BaseOfCode,
&MachineType
@@ -1388,7 +1427,7 @@ Returns:
// Physical address is FV base + offset of PE32 + offset of the entry point
//
SecCorePhysicalAddress = FvInfo->BaseAddress;
- SecCorePhysicalAddress += (UINTN) Pe32Section.Pe32Section + sizeof (EFI_SECTION_PE32) - (UINTN) FvImage->FileImage;
+ SecCorePhysicalAddress += (UINTN) Pe32Section.Pe32Section + SecHeaderSize - (UINTN) FvImage->FileImage;
SecCorePhysicalAddress += EntryPoint;
DebugMsg (NULL, 0, 9, "SecCore physical entry point address", "Address = 0x%llX", (unsigned long long) SecCorePhysicalAddress);
@@ -1413,8 +1452,9 @@ Returns:
return EFI_ABORTED;
}
+ SecHeaderSize = GetSectionHeaderLength(Pe32Section.CommonHeader);
Status = GetPe32Info (
- (VOID *) ((UINTN) Pe32Section.Pe32Section + sizeof (EFI_SECTION_PE32)),
+ (VOID *) ((UINTN) Pe32Section.Pe32Section + SecHeaderSize),
&EntryPoint,
&BaseOfCode,
&MachineType
@@ -1428,7 +1468,7 @@ Returns:
// Physical address is FV base + offset of PE32 + offset of the entry point
//
PeiCorePhysicalAddress = FvInfo->BaseAddress;
- PeiCorePhysicalAddress += (UINTN) Pe32Section.Pe32Section + sizeof (EFI_SECTION_PE32) - (UINTN) FvImage->FileImage;
+ PeiCorePhysicalAddress += (UINTN) Pe32Section.Pe32Section + SecHeaderSize - (UINTN) FvImage->FileImage;
PeiCorePhysicalAddress += EntryPoint;
DebugMsg (NULL, 0, 9, "PeiCore physical entry point address", "Address = 0x%llX", (unsigned long long) PeiCorePhysicalAddress);
@@ -1598,9 +1638,10 @@ Returns:
VtfFile->IntegrityCheck.Checksum.File = 0;
VtfFile->State = 0;
if (VtfFile->Attributes & FFS_ATTRIB_CHECKSUM) {
+ FfsHeaderSize = GetFfsHeaderLength(VtfFile);
VtfFile->IntegrityCheck.Checksum.File = CalculateChecksum8 (
- (UINT8 *) (VtfFile + 1),
- GetLength (VtfFile->Size) - sizeof (EFI_FFS_FILE_HEADER)
+ (UINT8 *) ((UINT8 *)VtfFile + FfsHeaderSize),
+ GetFfsFileLength (VtfFile) - FfsHeaderSize
);
} else {
VtfFile->IntegrityCheck.Checksum.File = FFS_FIXED_CHECKSUM;
@@ -1720,7 +1761,7 @@ Returns:
}
Status = GetPe32Info (
- (VOID *) ((UINTN) Pe32Section.Pe32Section + sizeof (EFI_SECTION_PE32)),
+ (VOID *) ((UINTN) Pe32Section.Pe32Section + GetSectionHeaderLength(Pe32Section.CommonHeader)),
&EntryPoint,
&BaseOfCode,
&MachineType
@@ -1734,7 +1775,7 @@ Returns:
// Physical address is FV base + offset of PE32 + offset of the entry point
//
PeiCorePhysicalAddress = FvInfo->BaseAddress;
- PeiCorePhysicalAddress += (UINTN) Pe32Section.Pe32Section + sizeof (EFI_SECTION_PE32) - (UINTN) FvImage->FileImage;
+ PeiCorePhysicalAddress += (UINTN) Pe32Section.Pe32Section + GetSectionHeaderLength(Pe32Section.CommonHeader) - (UINTN) FvImage->FileImage;
PeiCorePhysicalAddress += EntryPoint;
DebugMsg (NULL, 0, 9, "PeiCore physical entry point address", "Address = 0x%llX", (unsigned long long) PeiCorePhysicalAddress);
@@ -1768,7 +1809,7 @@ Returns:
}
Status = GetPe32Info (
- (VOID *) ((UINTN) Pe32Section.Pe32Section + sizeof (EFI_SECTION_PE32)),
+ (VOID *) ((UINTN) Pe32Section.Pe32Section + GetSectionHeaderLength(Pe32Section.CommonHeader)),
&EntryPoint,
&BaseOfCode,
&MachineType
@@ -1789,7 +1830,7 @@ Returns:
// Physical address is FV base + offset of PE32 + offset of the entry point
//
SecCorePhysicalAddress = FvInfo->BaseAddress;
- SecCorePhysicalAddress += (UINTN) Pe32Section.Pe32Section + sizeof (EFI_SECTION_PE32) - (UINTN) FvImage->FileImage;
+ SecCorePhysicalAddress += (UINTN) Pe32Section.Pe32Section + GetSectionHeaderLength(Pe32Section.CommonHeader) - (UINTN) FvImage->FileImage;
SecCorePhysicalAddress += EntryPoint;
DebugMsg (NULL, 0, 9, "SecCore physical entry point address", "Address = 0x%llX", (unsigned long long) SecCorePhysicalAddress);
@@ -1813,7 +1854,7 @@ Returns:
}
Status = GetPe32Info (
- (VOID *) ((UINTN) Pe32Section.Pe32Section + sizeof (EFI_SECTION_PE32)),
+ (VOID *) ((UINTN) Pe32Section.Pe32Section + GetSectionHeaderLength(Pe32Section.CommonHeader)),
&EntryPoint,
&BaseOfCode,
&MachineType
@@ -1827,7 +1868,7 @@ Returns:
// Physical address is FV base + offset of PE32 + offset of the entry point
//
PeiCorePhysicalAddress = FvInfo->BaseAddress;
- PeiCorePhysicalAddress += (UINTN) Pe32Section.Pe32Section + sizeof (EFI_SECTION_PE32) - (UINTN) FvImage->FileImage;
+ PeiCorePhysicalAddress += (UINTN) Pe32Section.Pe32Section + GetSectionHeaderLength(Pe32Section.CommonHeader) - (UINTN) FvImage->FileImage;
PeiCorePhysicalAddress += EntryPoint;
DebugMsg (NULL, 0, 9, "PeiCore physical entry point address", "Address = 0x%llX", (unsigned long long) PeiCorePhysicalAddress);
}
@@ -2344,7 +2385,7 @@ Returns:
//
// Add FV Extended Header contents to the FV as a PAD file
//
- AddPadFile (&FvImageMemoryFile, 4, VtfFileImage, FvExtHeader);
+ AddPadFile (&FvImageMemoryFile, 4, VtfFileImage, FvExtHeader, 0);
//
// Fv Extension header change update Fv Header Check sum
@@ -2419,7 +2460,8 @@ Returns:
//
// Update FV Alignment attribute to the largest alignment of all the FFS files in the FV
//
- if ((((FvHeader->Attributes & EFI_FVB2_ALIGNMENT) >> 16)) < MaxFfsAlignment) {
+ if (((FvHeader->Attributes & EFI_FVB2_WEAK_ALIGNMENT) != EFI_FVB2_WEAK_ALIGNMENT) &&
+ (((FvHeader->Attributes & EFI_FVB2_ALIGNMENT) >> 16)) < MaxFfsAlignment) {
FvHeader->Attributes = ((MaxFfsAlignment << 16) | (FvHeader->Attributes & 0xFFFF));
//
// Update Checksum for FvHeader
@@ -2428,6 +2470,15 @@ Returns:
FvHeader->Checksum = CalculateChecksum16 ((UINT16 *) FvHeader, FvHeader->HeaderLength / sizeof (UINT16));
}
+ //
+ // If there are large FFS in FV, the file system GUID should set to system 3 GUID.
+ //
+ if (mIsLargeFfs && CompareGuid (&FvHeader->FileSystemGuid, &mEfiFirmwareFileSystem2Guid) == 0) {
+ memcpy (&FvHeader->FileSystemGuid, &mEfiFirmwareFileSystem3Guid, sizeof (EFI_GUID));
+ FvHeader->Checksum = 0;
+ FvHeader->Checksum = CalculateChecksum16 ((UINT16 *) FvHeader, FvHeader->HeaderLength / sizeof (UINT16));
+ }
+
WriteFile:
//
// Write fv file
@@ -2564,6 +2615,7 @@ Returns:
UINTN FfsFileSize;
UINTN FvExtendHeaderSize;
UINT32 FfsAlignment;
+ UINT32 FfsHeaderSize;
EFI_FFS_FILE_HEADER FfsHeader;
BOOLEAN VtfFileFlag;
UINTN VtfFileSize;
@@ -2605,7 +2657,12 @@ Returns:
}
FvExtendHeaderSize = _filelength (fileno (fpin));
fclose (fpin);
- CurrentOffset += sizeof (EFI_FFS_FILE_HEADER) + FvExtendHeaderSize;
+ if (sizeof (EFI_FFS_FILE_HEADER) + FvExtendHeaderSize >= MAX_FFS_SIZE) {
+ CurrentOffset += sizeof (EFI_FFS_FILE_HEADER2) + FvExtendHeaderSize;
+ mIsLargeFfs = TRUE;
+ } else {
+ CurrentOffset += sizeof (EFI_FFS_FILE_HEADER) + FvExtendHeaderSize;
+ }
CurrentOffset = (CurrentOffset + 7) & (~7);
} else if (mFvDataInfo.FvNameGuidSet) {
CurrentOffset += sizeof (EFI_FFS_FILE_HEADER) + sizeof (EFI_FIRMWARE_VOLUME_EXT_HEADER);
@@ -2629,6 +2686,12 @@ Returns:
// Get the file size
//
FfsFileSize = _filelength (fileno (fpin));
+ if (FfsFileSize >= MAX_FFS_SIZE) {
+ FfsHeaderSize = sizeof(EFI_FFS_FILE_HEADER2);
+ mIsLargeFfs = TRUE;
+ } else {
+ FfsHeaderSize = sizeof(EFI_FFS_FILE_HEADER);
+ }
//
// Read Ffs File header
//
@@ -2662,9 +2725,12 @@ Returns:
//
// Add Pad file
//
- if (((CurrentOffset + sizeof (EFI_FFS_FILE_HEADER)) % FfsAlignment) != 0) {
- CurrentOffset = (CurrentOffset + sizeof (EFI_FFS_FILE_HEADER) * 2 + FfsAlignment - 1) & ~(FfsAlignment - 1);
- CurrentOffset -= sizeof (EFI_FFS_FILE_HEADER);
+ if (((CurrentOffset + FfsHeaderSize) % FfsAlignment) != 0) {
+ //
+ // Only EFI_FFS_FILE_HEADER is needed for a pad section.
+ //
+ CurrentOffset = (CurrentOffset + FfsHeaderSize + sizeof(EFI_FFS_FILE_HEADER) + FfsAlignment - 1) & ~(FfsAlignment - 1);
+ CurrentOffset -= FfsHeaderSize;
}
}
@@ -2792,7 +2858,7 @@ Returns:
if (EFI_ERROR (Status)) {
break;
}
- SubFvImageHeader = (EFI_FIRMWARE_VOLUME_HEADER *) ((UINT8 *) SubFvSection.FVImageSection + sizeof (EFI_FIRMWARE_VOLUME_IMAGE_SECTION));
+ SubFvImageHeader = (EFI_FIRMWARE_VOLUME_HEADER *) ((UINT8 *) SubFvSection.FVImageSection + GetSectionHeaderLength(SubFvSection.FVImageSection));
//
// Rebase on Flash
//
@@ -2854,6 +2920,8 @@ Returns:
UINT8 *PeFileBuffer;
UINT32 PeFileSize;
CHAR8 *PdbPointer;
+ UINT32 FfsHeaderSize;
+ UINT32 CurSecHdrSize;
Index = 0;
MemoryImagePointer = NULL;
@@ -2905,6 +2973,8 @@ Returns:
default:
return EFI_SUCCESS;
}
+
+ FfsHeaderSize = GetFfsHeaderLength(FfsFile);
//
// Rebase each PE32 section
//
@@ -2922,12 +2992,13 @@ Returns:
if (EFI_ERROR (Status)) {
break;
}
+ CurSecHdrSize = GetSectionHeaderLength(CurrentPe32Section.CommonHeader);
//
// Initialize context
//
memset (&ImageContext, 0, sizeof (ImageContext));
- ImageContext.Handle = (VOID *) ((UINTN) CurrentPe32Section.Pe32Section + sizeof (EFI_PE32_SECTION));
+ ImageContext.Handle = (VOID *) ((UINTN) CurrentPe32Section.Pe32Section + CurSecHdrSize);
ImageContext.ImageRead = (PE_COFF_LOADER_READ_FILE) FfsRebaseImageRead;
Status = PeCoffLoaderGetImageInfo (&ImageContext);
if (EFI_ERROR (Status)) {
@@ -2953,7 +3024,7 @@ Returns:
//
// Get PeHeader pointer
//
- ImgHdr = (EFI_IMAGE_OPTIONAL_HEADER_UNION *)((UINTN) CurrentPe32Section.Pe32Section + sizeof (EFI_PE32_SECTION) + ImageContext.PeCoffHeaderOffset);
+ ImgHdr = (EFI_IMAGE_OPTIONAL_HEADER_UNION *)((UINTN) CurrentPe32Section.Pe32Section + CurSecHdrSize + ImageContext.PeCoffHeaderOffset);
//
// Calculate the PE32 base address, based on file type
@@ -3030,7 +3101,7 @@ Returns:
ImageContext.RelocationsStripped = FALSE;
}
- NewPe32BaseAddress = XipBase + (UINTN) CurrentPe32Section.Pe32Section + sizeof (EFI_PE32_SECTION) - (UINTN)FfsFile;
+ NewPe32BaseAddress = XipBase + (UINTN) CurrentPe32Section.Pe32Section + CurSecHdrSize - (UINTN)FfsFile;
break;
case EFI_FV_FILETYPE_DRIVER:
@@ -3045,7 +3116,7 @@ Returns:
Error (NULL, 0, 3000, "Invalid", "Section-Alignment and File-Alignment do not match : %s.", FileName);
return EFI_ABORTED;
}
- NewPe32BaseAddress = XipBase + (UINTN) CurrentPe32Section.Pe32Section + sizeof (EFI_PE32_SECTION) - (UINTN)FfsFile;
+ NewPe32BaseAddress = XipBase + (UINTN) CurrentPe32Section.Pe32Section + CurSecHdrSize - (UINTN)FfsFile;
break;
default:
@@ -3104,7 +3175,7 @@ Returns:
for (Index = 0; Index < ImgHdr->Pe32.FileHeader.NumberOfSections; Index ++, SectionHeader ++) {
CopyMem (
- (UINT8 *) CurrentPe32Section.Pe32Section + sizeof (EFI_COMMON_SECTION_HEADER) + SectionHeader->PointerToRawData,
+ (UINT8 *) CurrentPe32Section.Pe32Section + CurSecHdrSize + SectionHeader->PointerToRawData,
(VOID*) (UINTN) (ImageContext.ImageAddress + SectionHeader->VirtualAddress),
SectionHeader->SizeOfRawData
);
@@ -3140,8 +3211,8 @@ Returns:
FfsFile->IntegrityCheck.Checksum.File = 0;
FfsFile->State = 0;
FfsFile->IntegrityCheck.Checksum.File = CalculateChecksum8 (
- (UINT8 *) (FfsFile + 1),
- GetLength (FfsFile->Size) - sizeof (EFI_FFS_FILE_HEADER)
+ (UINT8 *) ((UINT8 *)FfsFile + FfsHeaderSize),
+ GetFfsFileLength (FfsFile) - FfsHeaderSize
);
FfsFile->State = SavedState;
}
@@ -3185,12 +3256,14 @@ Returns:
if (EFI_ERROR (Status)) {
break;
}
+
+ CurSecHdrSize = GetSectionHeaderLength(CurrentPe32Section.CommonHeader);
//
// Calculate the TE base address, the FFS file base plus the offset of the TE section less the size stripped off
// by GenTEImage
//
- TEImageHeader = (EFI_TE_IMAGE_HEADER *) ((UINT8 *) CurrentPe32Section.Pe32Section + sizeof (EFI_COMMON_SECTION_HEADER));
+ TEImageHeader = (EFI_TE_IMAGE_HEADER *) ((UINT8 *) CurrentPe32Section.Pe32Section + CurSecHdrSize);
//
// Initialize context, load image info.
@@ -3365,8 +3438,8 @@ Returns:
FfsFile->IntegrityCheck.Checksum.File = 0;
FfsFile->State = 0;
FfsFile->IntegrityCheck.Checksum.File = CalculateChecksum8 (
- (UINT8 *)(FfsFile + 1),
- GetLength (FfsFile->Size) - sizeof (EFI_FFS_FILE_HEADER)
+ (UINT8 *)((UINT8 *)FfsFile + FfsHeaderSize),
+ GetFfsFileLength (FfsFile) - FfsHeaderSize
);
FfsFile->State = SavedState;
}
@@ -3436,12 +3509,12 @@ Returns:
//
// Get Pad file size.
//
- FileLength = (*(UINT32 *)(PadFile->Size)) & 0x00FFFFFF;
+ FileLength = GetFfsFileLength(PadFile);
FileLength = (FileLength + EFI_FFS_FILE_HEADER_ALIGNMENT - 1) & ~(EFI_FFS_FILE_HEADER_ALIGNMENT - 1);
//
// FixPoint must be align on 0x1000 relative to FvImage Header
//
- FixPoint = (UINT8*) PadFile + sizeof (EFI_FFS_FILE_HEADER);
+ FixPoint = (UINT8*) PadFile + GetFfsHeaderLength(PadFile);
FixPoint = FixPoint + 0x1000 - (((UINTN) FixPoint - (UINTN) FvImage->FileImage) & 0xFFF);
//
// FixPoint be larger at the last place of one fv image.
@@ -3451,7 +3524,7 @@ Returns:
}
FixPoint -= 0x1000;
- if ((UINTN) FixPoint < ((UINTN) PadFile + sizeof (EFI_FFS_FILE_HEADER))) {
+ if ((UINTN) FixPoint < ((UINTN) PadFile + GetFfsHeaderLength(PadFile))) {
//
// No alignment FixPoint in this Pad File.
//
@@ -3556,6 +3629,19 @@ Returns:
DebugMsg (NULL, 0, 9, "Capsule Flag", Value);
}
+ Status = FindToken (InfFile, OPTIONS_SECTION_STRING, EFI_OEM_CAPSULE_FLAGS_STRING, 0, Value);
+ if (Status == EFI_SUCCESS) {
+ Status = AsciiStringToUint64 (Value, FALSE, &Value64);
+ if (EFI_ERROR (Status) || Value64 > 0xffff) {
+ Error (NULL, 0, 2000, "Invalid parameter",
+ "invalid Flag setting for %s. Must be integer value between 0x0000 and 0xffff.",
+ EFI_OEM_CAPSULE_FLAGS_STRING);
+ return EFI_ABORTED;
+ }
+ CapInfo->Flags |= Value64;
+ DebugMsg (NULL, 0, 9, "Capsule Extend Flag", Value);
+ }
+
//
// Read Capsule File name
//
diff --git a/BaseTools/Source/C/GenFv/GenFvInternalLib.h b/BaseTools/Source/C/GenFv/GenFvInternalLib.h
index 40c23600a..21993b5e7 100644
--- a/BaseTools/Source/C/GenFv/GenFvInternalLib.h
+++ b/BaseTools/Source/C/GenFv/GenFvInternalLib.h
@@ -1,6 +1,6 @@
/** @file
-Copyright (c) 2004 - 2011, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2004 - 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
@@ -82,6 +82,7 @@ Abstract:
#define EFI_CAPSULE_GUID_STRING "EFI_CAPSULE_GUID"
#define EFI_CAPSULE_HEADER_SIZE_STRING "EFI_CAPSULE_HEADER_SIZE"
#define EFI_CAPSULE_FLAGS_STRING "EFI_CAPSULE_FLAGS"
+#define EFI_OEM_CAPSULE_FLAGS_STRING "EFI_OEM_CAPSULE_FLAGS"
#define EFI_CAPSULE_VERSION_STRING "EFI_CAPSULE_VERSION"
#define EFI_FV_TOTAL_SIZE_STRING "EFI_FV_TOTAL_SIZE"
@@ -144,6 +145,8 @@ Abstract:
#define EFI_FVB2_ALIGNMENT_1G_STRING "EFI_FVB2_ALIGNMENT_1G"
#define EFI_FVB2_ALIGNMENT_2G_STRING "EFI_FVB2_ALIGNMENT_2G"
+#define EFI_FV_WEAK_ALIGNMENT_STRING "EFI_WEAK_ALIGNMENT"
+
//
// File sections
//
@@ -259,6 +262,7 @@ typedef struct {
extern FV_INFO mFvDataInfo;
extern CAP_INFO mCapDataInfo;
extern EFI_GUID mEfiFirmwareFileSystem2Guid;
+extern EFI_GUID mEfiFirmwareFileSystem3Guid;
extern UINT32 mFvTotalSize;
extern UINT32 mFvTakenSize;
diff --git a/BaseTools/Source/C/GenFw/Elf32Convert.c b/BaseTools/Source/C/GenFw/Elf32Convert.c
index ddb45acc8..58ac33388 100644
--- a/BaseTools/Source/C/GenFw/Elf32Convert.c
+++ b/BaseTools/Source/C/GenFw/Elf32Convert.c
@@ -1,6 +1,7 @@
/** @file
Copyright (c) 2010 - 2011, Intel Corporation. All rights reserved.<BR>
+Portions copyright (c) 2013, ARM Ltd. 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
@@ -18,6 +19,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#include <windows.h>
#include <io.h>
#endif
+#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -264,9 +266,12 @@ ScanSections32 (
EFI_IMAGE_OPTIONAL_HEADER_UNION *NtHdr;
UINT32 CoffEntry;
UINT32 SectionCount;
+ BOOLEAN FoundText;
CoffEntry = 0;
mCoffOffset = 0;
+ mTextOffset = 0;
+ FoundText = FALSE;
//
// Coff file start with a DOS header.
@@ -291,7 +296,6 @@ ScanSections32 (
// First text sections.
//
mCoffOffset = CoffAlign(mCoffOffset);
- mTextOffset = mCoffOffset;
SectionCount = 0;
for (i = 0; i < mEhdr->e_shnum; i++) {
Elf_Shdr *shdr = GetShdrByIndex(i);
@@ -315,12 +319,26 @@ ScanSections32 (
(mEhdr->e_entry < shdr->sh_addr + shdr->sh_size)) {
CoffEntry = mCoffOffset + mEhdr->e_entry - shdr->sh_addr;
}
+
+ //
+ // Set mTextOffset with the offset of the first '.text' section
+ //
+ if (!FoundText) {
+ mTextOffset = mCoffOffset;
+ FoundText = TRUE;
+ }
+
mCoffSectionsOffset[i] = mCoffOffset;
mCoffOffset += shdr->sh_size;
SectionCount ++;
}
}
+ if (!FoundText) {
+ Error (NULL, 0, 3000, "Invalid", "Did not find any '.text' section.");
+ assert (FALSE);
+ }
+
if (mEhdr->e_machine != EM_ARM) {
mCoffOffset = CoffAlign(mCoffOffset);
}
diff --git a/BaseTools/Source/C/GenFw/Elf64Convert.c b/BaseTools/Source/C/GenFw/Elf64Convert.c
index 72d6cd16d..713f8f7e4 100644
--- a/BaseTools/Source/C/GenFw/Elf64Convert.c
+++ b/BaseTools/Source/C/GenFw/Elf64Convert.c
@@ -19,6 +19,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#include <windows.h>
#include <io.h>
#endif
+#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -258,9 +259,12 @@ ScanSections64 (
EFI_IMAGE_OPTIONAL_HEADER_UNION *NtHdr;
UINT32 CoffEntry;
UINT32 SectionCount;
+ BOOLEAN FoundText;
CoffEntry = 0;
mCoffOffset = 0;
+ mTextOffset = 0;
+ FoundText = FALSE;
//
// Coff file start with a DOS header.
@@ -286,7 +290,6 @@ ScanSections64 (
// First text sections.
//
mCoffOffset = CoffAlign(mCoffOffset);
- mTextOffset = mCoffOffset;
SectionCount = 0;
for (i = 0; i < mEhdr->e_shnum; i++) {
Elf_Shdr *shdr = GetShdrByIndex(i);
@@ -310,12 +313,26 @@ ScanSections64 (
(mEhdr->e_entry < shdr->sh_addr + shdr->sh_size)) {
CoffEntry = (UINT32) (mCoffOffset + mEhdr->e_entry - shdr->sh_addr);
}
+
+ //
+ // Set mTextOffset with the offset of the first '.text' section
+ //
+ if (!FoundText) {
+ mTextOffset = mCoffOffset;
+ FoundText = TRUE;
+ }
+
mCoffSectionsOffset[i] = mCoffOffset;
mCoffOffset += (UINT32) shdr->sh_size;
SectionCount ++;
}
}
+ if (!FoundText) {
+ Error (NULL, 0, 3000, "Invalid", "Did not find any '.text' section.");
+ assert (FALSE);
+ }
+
if (mEhdr->e_machine != EM_ARM) {
mCoffOffset = CoffAlign(mCoffOffset);
}
diff --git a/BaseTools/Source/C/GenSec/GenSec.c b/BaseTools/Source/C/GenSec/GenSec.c
index d6b22aee8..63e8e13e8 100644
--- a/BaseTools/Source/C/GenSec/GenSec.c
+++ b/BaseTools/Source/C/GenSec/GenSec.c
@@ -1,6 +1,6 @@
/** @file
-Copyright (c) 2004 - 2011, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2004 - 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
@@ -42,8 +42,6 @@ Abstract:
#define UTILITY_MAJOR_VERSION 0
#define UTILITY_MINOR_VERSION 1
-#define MAX_SECTION_SIZE 0x1000000
-
STATIC CHAR8 *mSectionTypeName[] = {
NULL, // 0x00 - reserved
"EFI_SECTION_COMPRESSION", // 0x01
@@ -94,6 +92,11 @@ typedef struct {
UINT32 CRC32Checksum;
} CRC32_SECTION_HEADER;
+typedef struct {
+ EFI_GUID_DEFINED_SECTION2 GuidSectionHeader;
+ UINT32 CRC32Checksum;
+} CRC32_SECTION_HEADER2;
+
STATIC EFI_GUID mZeroGuid = {0x0, 0x0, 0x0, {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}};
STATIC EFI_GUID mEfiCrc32SectionGuid = EFI_CRC32_GUIDED_SECTION_EXTRACTION_PROTOCOL_GUID;
@@ -150,7 +153,7 @@ Returns:
//
// Copyright declaration
//
- fprintf (stdout, "Copyright (c) 2007 - 2010, Intel Corporation. All rights reserved.\n\n");
+ fprintf (stdout, "Copyright (c) 2007 - 2013, Intel Corporation. All rights reserved.\n\n");
//
// Details Option
@@ -184,7 +187,7 @@ Returns:
fprintf (stdout, " -n String, --name String\n\
String is a NULL terminated string used in Ui section.\n");
fprintf (stdout, " -j Number, --buildnumber Number\n\
- Number is an integer value between 0000 and 9999\n\
+ Number is an integer value between 0 and 65535\n\
used in Ver section.\n");
fprintf (stdout, " --sectionalign SectionAlign\n\
SectionAlign points to section alignment, which support\n\
@@ -266,6 +269,7 @@ Returns:
FILE *InFile;
UINT8 *Buffer;
UINT32 TotalLength;
+ UINT32 HeaderLength;
EFI_COMMON_SECTION_HEADER *CommonSect;
STATUS Status;
@@ -298,9 +302,14 @@ Returns:
//
// Size must fit in 3 bytes
//
+ //if (TotalLength >= MAX_SECTION_SIZE) {
+ // Error (NULL, 0, 2000, "Invalid paramter", "%s file size (0x%X) exceeds section size limit(%uM).", InputFileName[0], (unsigned) TotalLength, MAX_SECTION_SIZE>>20);
+ // goto Done;
+ //}
+ HeaderLength = sizeof (EFI_COMMON_SECTION_HEADER);
if (TotalLength >= MAX_SECTION_SIZE) {
- Error (NULL, 0, 2000, "Invalid paramter", "%s file size (0x%X) exceeds section size limit(%uM).", InputFileName[0], (unsigned) TotalLength, MAX_SECTION_SIZE>>20);
- goto Done;
+ TotalLength = sizeof (EFI_COMMON_SECTION_HEADER2) + InputFileLength;
+ HeaderLength = sizeof (EFI_COMMON_SECTION_HEADER2);
}
VerboseMsg ("the size of the created section file is %u bytes", (unsigned) TotalLength);
//
@@ -313,15 +322,20 @@ Returns:
}
CommonSect = (EFI_COMMON_SECTION_HEADER *) Buffer;
CommonSect->Type = SectionType;
- CommonSect->Size[0] = (UINT8) (TotalLength & 0xff);
- CommonSect->Size[1] = (UINT8) ((TotalLength & 0xff00) >> 8);
- CommonSect->Size[2] = (UINT8) ((TotalLength & 0xff0000) >> 16);
+ if (TotalLength < MAX_SECTION_SIZE) {
+ CommonSect->Size[0] = (UINT8) (TotalLength & 0xff);
+ CommonSect->Size[1] = (UINT8) ((TotalLength & 0xff00) >> 8);
+ CommonSect->Size[2] = (UINT8) ((TotalLength & 0xff0000) >> 16);
+ } else {
+ memset(CommonSect->Size, 0xff, sizeof(UINT8) * 3);
+ ((EFI_COMMON_SECTION_HEADER2 *)CommonSect)->ExtendedSize = TotalLength;
+ }
//
// read data from the input file.
//
if (InputFileLength != 0) {
- if (fread (Buffer + sizeof (EFI_COMMON_SECTION_HEADER), (size_t) InputFileLength, 1, InFile) != 1) {
+ if (fread (Buffer + HeaderLength, (size_t) InputFileLength, 1, InFile) != 1) {
Error (NULL, 0, 0004, "Error reading file", InputFileName[0]);
goto Done;
}
@@ -421,10 +435,11 @@ Returns:
UINT32 Index;
FILE *InFile;
EFI_COMMON_SECTION_HEADER *SectHeader;
- EFI_COMMON_SECTION_HEADER TempSectHeader;
+ EFI_COMMON_SECTION_HEADER2 TempSectHeader;
EFI_TE_IMAGE_HEADER TeHeader;
UINT32 TeOffset;
EFI_GUID_DEFINED_SECTION GuidSectHeader;
+ EFI_GUID_DEFINED_SECTION2 GuidSectHeader2;
UINT32 HeaderSize;
if (InputFileNum < 1) {
@@ -476,8 +491,16 @@ Returns:
// Check this section is Te/Pe section, and Calculate the numbers of Te/Pe section.
//
TeOffset = 0;
- HeaderSize = sizeof (EFI_COMMON_SECTION_HEADER);
- fread (&TempSectHeader, 1, sizeof (TempSectHeader), InFile);
+ //
+ // The section might be EFI_COMMON_SECTION_HEADER2
+ // But only Type needs to be checked
+ //
+ if (FileSize >= MAX_SECTION_SIZE) {
+ HeaderSize = sizeof (EFI_COMMON_SECTION_HEADER2);
+ } else {
+ HeaderSize = sizeof (EFI_COMMON_SECTION_HEADER);
+ }
+ fread (&TempSectHeader, 1, HeaderSize, InFile);
if (TempSectHeader.Type == EFI_SECTION_TE) {
fread (&TeHeader, 1, sizeof (TeHeader), InFile);
if (TeHeader.Signature == EFI_TE_IMAGE_HEADER_SIGNATURE) {
@@ -485,9 +508,16 @@ Returns:
}
} else if (TempSectHeader.Type == EFI_SECTION_GUID_DEFINED) {
fseek (InFile, 0, SEEK_SET);
- fread (&GuidSectHeader, 1, sizeof (GuidSectHeader), InFile);
- if ((GuidSectHeader.Attributes & EFI_GUIDED_SECTION_PROCESSING_REQUIRED) == 0) {
- HeaderSize = GuidSectHeader.DataOffset;
+ if (FileSize >= MAX_SECTION_SIZE) {
+ fread (&GuidSectHeader2, 1, sizeof (GuidSectHeader2), InFile);
+ if ((GuidSectHeader2.Attributes & EFI_GUIDED_SECTION_PROCESSING_REQUIRED) == 0) {
+ HeaderSize = GuidSectHeader2.DataOffset;
+ }
+ } else {
+ fread (&GuidSectHeader, 1, sizeof (GuidSectHeader), InFile);
+ if ((GuidSectHeader.Attributes & EFI_GUIDED_SECTION_PROCESSING_REQUIRED) == 0) {
+ HeaderSize = GuidSectHeader.DataOffset;
+ }
}
}
@@ -510,6 +540,9 @@ Returns:
Offset = Offset - Size - HeaderSize - TeOffset;
if (FileBuffer != NULL && ((Size + Offset) < *BufferLength)) {
+ //
+ // The maximal alignment is 64K, the raw section size must be less than 0xffffff
+ //
memset (FileBuffer + Size, 0, Offset);
SectHeader = (EFI_COMMON_SECTION_HEADER *) (FileBuffer + Size);
SectHeader->Type = EFI_SECTION_RAW;
@@ -591,16 +624,19 @@ Returns:
UINT32 TotalLength;
UINT32 InputLength;
UINT32 CompressedLength;
+ UINT32 HeaderLength;
UINT8 *FileBuffer;
UINT8 *OutputBuffer;
EFI_STATUS Status;
EFI_COMPRESSION_SECTION *CompressionSect;
+ EFI_COMPRESSION_SECTION2 *CompressionSect2;
COMPRESS_FUNCTION CompressFunction;
InputLength = 0;
FileBuffer = NULL;
OutputBuffer = NULL;
CompressedLength = 0;
+ TotalLength = 0;
//
// read all input file contents into a buffer
// first get the size of all file contents
@@ -646,15 +682,21 @@ Returns:
switch (SectCompSubType) {
case EFI_NOT_COMPRESSED:
CompressedLength = InputLength;
+ HeaderLength = sizeof (EFI_COMPRESSION_SECTION);
+ if (CompressedLength + HeaderLength >= MAX_SECTION_SIZE) {
+ HeaderLength = sizeof (EFI_COMPRESSION_SECTION2);
+ }
+ TotalLength = CompressedLength + HeaderLength;
//
// Copy file buffer to the none compressed data.
//
- OutputBuffer = malloc (CompressedLength + sizeof (EFI_COMPRESSION_SECTION));
+ OutputBuffer = malloc (TotalLength);
if (OutputBuffer == NULL) {
free (FileBuffer);
return EFI_OUT_OF_RESOURCES;
}
- memcpy (OutputBuffer + sizeof (EFI_COMPRESSION_SECTION), FileBuffer, CompressedLength);
+ memcpy (OutputBuffer + HeaderLength, FileBuffer, CompressedLength);
+ free (FileBuffer);
FileBuffer = OutputBuffer;
break;
@@ -672,13 +714,18 @@ Returns:
Status = CompressFunction (FileBuffer, InputLength, OutputBuffer, &CompressedLength);
if (Status == EFI_BUFFER_TOO_SMALL) {
- OutputBuffer = malloc (CompressedLength + sizeof (EFI_COMPRESSION_SECTION));
+ HeaderLength = sizeof (EFI_COMPRESSION_SECTION);
+ if (CompressedLength + HeaderLength >= MAX_SECTION_SIZE) {
+ HeaderLength = sizeof (EFI_COMPRESSION_SECTION2);
+ }
+ TotalLength = CompressedLength + HeaderLength;
+ OutputBuffer = malloc (TotalLength);
if (!OutputBuffer) {
free (FileBuffer);
return EFI_OUT_OF_RESOURCES;
}
- Status = CompressFunction (FileBuffer, InputLength, OutputBuffer + sizeof (EFI_COMPRESSION_SECTION), &CompressedLength);
+ Status = CompressFunction (FileBuffer, InputLength, OutputBuffer + HeaderLength, &CompressedLength);
}
free (FileBuffer);
@@ -695,30 +742,40 @@ Returns:
DebugMsg (NULL, 0, 9, "comprss file size",
"the original section size is %d bytes and the compressed section size is %u bytes", (unsigned) InputLength, (unsigned) CompressedLength);
- TotalLength = CompressedLength + sizeof (EFI_COMPRESSION_SECTION);
- if (TotalLength >= MAX_SECTION_SIZE) {
- Error (NULL, 0, 2000, "Invalid paramter", "The size of all files exceeds section size limit(%uM).", MAX_SECTION_SIZE>>20);
- if (FileBuffer != NULL) {
- free (FileBuffer);
- }
- if (OutputBuffer != NULL) {
- free (OutputBuffer);
- }
- return STATUS_ERROR;
- }
+
+ //if (TotalLength >= MAX_SECTION_SIZE) {
+ // Error (NULL, 0, 2000, "Invalid paramter", "The size of all files exceeds section size limit(%uM).", MAX_SECTION_SIZE>>20);
+ // if (FileBuffer != NULL) {
+ // free (FileBuffer);
+ // }
+ // if (OutputBuffer != NULL) {
+ // free (OutputBuffer);
+ // }
+ // return STATUS_ERROR;
+ //}
VerboseMsg ("the size of the created section file is %u bytes", (unsigned) TotalLength);
//
// Add the section header for the compressed data
//
- CompressionSect = (EFI_COMPRESSION_SECTION *) FileBuffer;
-
- CompressionSect->CommonHeader.Type = EFI_SECTION_COMPRESSION;
- CompressionSect->CommonHeader.Size[0] = (UINT8) (TotalLength & 0xff);
- CompressionSect->CommonHeader.Size[1] = (UINT8) ((TotalLength & 0xff00) >> 8);
- CompressionSect->CommonHeader.Size[2] = (UINT8) ((TotalLength & 0xff0000) >> 16);
- CompressionSect->CompressionType = SectCompSubType;
- CompressionSect->UncompressedLength = InputLength;
+ if (TotalLength >= MAX_SECTION_SIZE) {
+ CompressionSect2 = (EFI_COMPRESSION_SECTION2 *)FileBuffer;
+
+ memset(CompressionSect2->CommonHeader.Size, 0xff, sizeof(UINT8) * 3);
+ CompressionSect2->CommonHeader.Type = EFI_SECTION_COMPRESSION;
+ CompressionSect2->CommonHeader.ExtendedSize = TotalLength;
+ CompressionSect2->CompressionType = SectCompSubType;
+ CompressionSect2->UncompressedLength = InputLength;
+ } else {
+ CompressionSect = (EFI_COMPRESSION_SECTION *) FileBuffer;
+
+ CompressionSect->CommonHeader.Type = EFI_SECTION_COMPRESSION;
+ CompressionSect->CommonHeader.Size[0] = (UINT8) (TotalLength & 0xff);
+ CompressionSect->CommonHeader.Size[1] = (UINT8) ((TotalLength & 0xff00) >> 8);
+ CompressionSect->CommonHeader.Size[2] = (UINT8) ((TotalLength & 0xff0000) >> 16);
+ CompressionSect->CompressionType = SectCompSubType;
+ CompressionSect->UncompressedLength = InputLength;
+ }
//
// Set OutFileBuffer
@@ -779,17 +836,14 @@ Returns:
UINT32 Crc32Checksum;
EFI_STATUS Status;
CRC32_SECTION_HEADER *Crc32GuidSect;
+ CRC32_SECTION_HEADER2 *Crc32GuidSect2;
EFI_GUID_DEFINED_SECTION *VendorGuidSect;
+ EFI_GUID_DEFINED_SECTION2 *VendorGuidSect2;
InputLength = 0;
Offset = 0;
FileBuffer = NULL;
-
- if (CompareGuid (VendorGuid, &mZeroGuid) == 0) {
- Offset = sizeof (CRC32_SECTION_HEADER);
- } else {
- Offset = sizeof (EFI_GUID_DEFINED_SECTION);
- }
+ TotalLength = 0;
//
// read all input file contents into a buffer
@@ -804,6 +858,19 @@ Returns:
);
if (Status == EFI_BUFFER_TOO_SMALL) {
+ if (CompareGuid (VendorGuid, &mZeroGuid) == 0) {
+ Offset = sizeof (CRC32_SECTION_HEADER);
+ if (InputLength + Offset >= MAX_SECTION_SIZE) {
+ Offset = sizeof (CRC32_SECTION_HEADER2);
+ }
+ } else {
+ Offset = sizeof (EFI_GUID_DEFINED_SECTION);
+ if (InputLength + Offset >= MAX_SECTION_SIZE) {
+ Offset = sizeof (EFI_GUID_DEFINED_SECTION2);
+ }
+ }
+ TotalLength = InputLength + Offset;
+
FileBuffer = (UINT8 *) malloc (InputLength + Offset);
if (FileBuffer == NULL) {
Error (NULL, 0, 4001, "Resource", "memory cannot be allcoated");
@@ -843,42 +910,54 @@ Returns:
//
Crc32Checksum = 0;
CalculateCrc32 (FileBuffer + Offset, InputLength, &Crc32Checksum);
-
- TotalLength = InputLength + sizeof (CRC32_SECTION_HEADER);
+
if (TotalLength >= MAX_SECTION_SIZE) {
- Error (NULL, 0, 2000, "Invalid paramter", "The size of all files exceeds section size limit(%uM).", MAX_SECTION_SIZE>>20);
- free (FileBuffer);
- return STATUS_ERROR;
+ Crc32GuidSect2 = (CRC32_SECTION_HEADER2 *) FileBuffer;
+ Crc32GuidSect2->GuidSectionHeader.CommonHeader.Type = EFI_SECTION_GUID_DEFINED;
+ Crc32GuidSect2->GuidSectionHeader.CommonHeader.Size[0] = (UINT8) 0xff;
+ Crc32GuidSect2->GuidSectionHeader.CommonHeader.Size[1] = (UINT8) 0xff;
+ Crc32GuidSect2->GuidSectionHeader.CommonHeader.Size[2] = (UINT8) 0xff;
+ Crc32GuidSect2->GuidSectionHeader.CommonHeader.ExtendedSize = TotalLength;
+ memcpy (&(Crc32GuidSect2->GuidSectionHeader.SectionDefinitionGuid), &mEfiCrc32SectionGuid, sizeof (EFI_GUID));
+ Crc32GuidSect2->GuidSectionHeader.Attributes = EFI_GUIDED_SECTION_AUTH_STATUS_VALID;
+ Crc32GuidSect2->GuidSectionHeader.DataOffset = sizeof (CRC32_SECTION_HEADER2);
+ Crc32GuidSect2->CRC32Checksum = Crc32Checksum;
+ DebugMsg (NULL, 0, 9, "Guided section", "Data offset is %u", Crc32GuidSect2->GuidSectionHeader.DataOffset);
+ } else {
+ Crc32GuidSect = (CRC32_SECTION_HEADER *) FileBuffer;
+ Crc32GuidSect->GuidSectionHeader.CommonHeader.Type = EFI_SECTION_GUID_DEFINED;
+ Crc32GuidSect->GuidSectionHeader.CommonHeader.Size[0] = (UINT8) (TotalLength & 0xff);
+ Crc32GuidSect->GuidSectionHeader.CommonHeader.Size[1] = (UINT8) ((TotalLength & 0xff00) >> 8);
+ Crc32GuidSect->GuidSectionHeader.CommonHeader.Size[2] = (UINT8) ((TotalLength & 0xff0000) >> 16);
+ memcpy (&(Crc32GuidSect->GuidSectionHeader.SectionDefinitionGuid), &mEfiCrc32SectionGuid, sizeof (EFI_GUID));
+ Crc32GuidSect->GuidSectionHeader.Attributes = EFI_GUIDED_SECTION_AUTH_STATUS_VALID;
+ Crc32GuidSect->GuidSectionHeader.DataOffset = sizeof (CRC32_SECTION_HEADER);
+ Crc32GuidSect->CRC32Checksum = Crc32Checksum;
+ DebugMsg (NULL, 0, 9, "Guided section", "Data offset is %u", Crc32GuidSect->GuidSectionHeader.DataOffset);
}
-
- Crc32GuidSect = (CRC32_SECTION_HEADER *) FileBuffer;
- Crc32GuidSect->GuidSectionHeader.CommonHeader.Type = EFI_SECTION_GUID_DEFINED;
- Crc32GuidSect->GuidSectionHeader.CommonHeader.Size[0] = (UINT8) (TotalLength & 0xff);
- Crc32GuidSect->GuidSectionHeader.CommonHeader.Size[1] = (UINT8) ((TotalLength & 0xff00) >> 8);
- Crc32GuidSect->GuidSectionHeader.CommonHeader.Size[2] = (UINT8) ((TotalLength & 0xff0000) >> 16);
- memcpy (&(Crc32GuidSect->GuidSectionHeader.SectionDefinitionGuid), &mEfiCrc32SectionGuid, sizeof (EFI_GUID));
- Crc32GuidSect->GuidSectionHeader.Attributes = EFI_GUIDED_SECTION_AUTH_STATUS_VALID;
- Crc32GuidSect->GuidSectionHeader.DataOffset = sizeof (CRC32_SECTION_HEADER);
- Crc32GuidSect->CRC32Checksum = Crc32Checksum;
- DebugMsg (NULL, 0, 9, "Guided section", "Data offset is %u", Crc32GuidSect->GuidSectionHeader.DataOffset);
-
} else {
- TotalLength = InputLength + sizeof (EFI_GUID_DEFINED_SECTION);
if (TotalLength >= MAX_SECTION_SIZE) {
- Error (NULL, 0, 2000, "Invalid paramter", "The size of all files exceeds section size limit(%uM).", MAX_SECTION_SIZE>>20);
- free (FileBuffer);
- return STATUS_ERROR;
+ VendorGuidSect2 = (EFI_GUID_DEFINED_SECTION2 *) FileBuffer;
+ VendorGuidSect2->CommonHeader.Type = EFI_SECTION_GUID_DEFINED;
+ VendorGuidSect2->CommonHeader.Size[0] = (UINT8) 0xff;
+ VendorGuidSect2->CommonHeader.Size[1] = (UINT8) 0xff;
+ VendorGuidSect2->CommonHeader.Size[2] = (UINT8) 0xff;
+ VendorGuidSect2->CommonHeader.ExtendedSize = InputLength + sizeof (EFI_GUID_DEFINED_SECTION2);
+ memcpy (&(VendorGuidSect2->SectionDefinitionGuid), VendorGuid, sizeof (EFI_GUID));
+ VendorGuidSect2->Attributes = DataAttribute;
+ VendorGuidSect2->DataOffset = (UINT16) (sizeof (EFI_GUID_DEFINED_SECTION2) + DataHeaderSize);
+ DebugMsg (NULL, 0, 9, "Guided section", "Data offset is %u", VendorGuidSect2->DataOffset);
+ } else {
+ VendorGuidSect = (EFI_GUID_DEFINED_SECTION *) FileBuffer;
+ VendorGuidSect->CommonHeader.Type = EFI_SECTION_GUID_DEFINED;
+ VendorGuidSect->CommonHeader.Size[0] = (UINT8) (TotalLength & 0xff);
+ VendorGuidSect->CommonHeader.Size[1] = (UINT8) ((TotalLength & 0xff00) >> 8);
+ VendorGuidSect->CommonHeader.Size[2] = (UINT8) ((TotalLength & 0xff0000) >> 16);
+ memcpy (&(VendorGuidSect->SectionDefinitionGuid), VendorGuid, sizeof (EFI_GUID));
+ VendorGuidSect->Attributes = DataAttribute;
+ VendorGuidSect->DataOffset = (UINT16) (sizeof (EFI_GUID_DEFINED_SECTION) + DataHeaderSize);
+ DebugMsg (NULL, 0, 9, "Guided section", "Data offset is %u", VendorGuidSect->DataOffset);
}
-
- VendorGuidSect = (EFI_GUID_DEFINED_SECTION *) FileBuffer;
- VendorGuidSect->CommonHeader.Type = EFI_SECTION_GUID_DEFINED;
- VendorGuidSect->CommonHeader.Size[0] = (UINT8) (TotalLength & 0xff);
- VendorGuidSect->CommonHeader.Size[1] = (UINT8) ((TotalLength & 0xff00) >> 8);
- VendorGuidSect->CommonHeader.Size[2] = (UINT8) ((TotalLength & 0xff0000) >> 16);
- memcpy (&(VendorGuidSect->SectionDefinitionGuid), VendorGuid, sizeof (EFI_GUID));
- VendorGuidSect->Attributes = DataAttribute;
- VendorGuidSect->DataOffset = (UINT16) (sizeof (EFI_GUID_DEFINED_SECTION) + DataHeaderSize);
- DebugMsg (NULL, 0, 9, "Guided section", "Data offset is %u", VendorGuidSect->DataOffset);
}
VerboseMsg ("the size of the created section file is %u bytes", (unsigned) TotalLength);
@@ -935,6 +1014,7 @@ Returns:
UINT64 LogLevel;
UINT32 *InputFileAlign;
UINT32 InputFileAlignNum;
+ EFI_COMMON_SECTION_HEADER *SectionHeader;
InputFileAlign = NULL;
InputFileAlignNum = 0;
@@ -1262,8 +1342,8 @@ Returns:
SectType = EFI_SECTION_SMM_DEPEX;
} else if (stricmp (SectionName, mSectionTypeName[EFI_SECTION_VERSION]) == 0) {
SectType = EFI_SECTION_VERSION;
- if (VersionNumber < 0 || VersionNumber > 9999) {
- Error (NULL, 0, 1003, "Invalid option value", "%d is not in 0~9999", VersionNumber);
+ if (VersionNumber < 0 || VersionNumber > 65535) {
+ Error (NULL, 0, 1003, "Invalid option value", "%d is not in 0~65535", VersionNumber);
goto Finish;
}
VerboseMsg ("Version section number is %d", VersionNumber);
@@ -1463,7 +1543,11 @@ Returns:
// Get output file length
//
if (SectType != EFI_SECTION_ALL) {
- InputLength = SECTION_SIZE (OutFileBuffer);
+ SectionHeader = (EFI_COMMON_SECTION_HEADER *)OutFileBuffer;
+ InputLength = *(UINT32 *)SectionHeader->Size & 0x00ffffff;
+ if (InputLength == 0xffffff) {
+ InputLength = ((EFI_COMMON_SECTION_HEADER2 *)SectionHeader)->ExtendedSize;
+ }
}
//
diff --git a/BaseTools/Source/C/Include/Common/BuildVersion.h b/BaseTools/Source/C/Include/Common/BuildVersion.h
index f524cefc9..b84bd0571 100644
--- a/BaseTools/Source/C/Include/Common/BuildVersion.h
+++ b/BaseTools/Source/C/Include/Common/BuildVersion.h
@@ -14,4 +14,4 @@
**/
-#define __BUILD_VERSION "Build 2601"
+#define __BUILD_VERSION "Build 2610"
diff --git a/BaseTools/Source/C/Include/Common/PiFirmwareFile.h b/BaseTools/Source/C/Include/Common/PiFirmwareFile.h
index e66f40ca4..1790c3a1e 100644
--- a/BaseTools/Source/C/Include/Common/PiFirmwareFile.h
+++ b/BaseTools/Source/C/Include/Common/PiFirmwareFile.h
@@ -1,7 +1,7 @@
/** @file
The firmware file related definitions in PI.
- Copyright (c) 2006 - 2008, Intel Corporation. All rights reserved.<BR>
+ 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
@@ -64,6 +64,7 @@ typedef UINT8 EFI_FFS_FILE_STATE;
//
// FFS File Attributes.
//
+#define FFS_ATTRIB_LARGE_FILE 0x01
#define FFS_ATTRIB_FIXED 0x04
#define FFS_ATTRIB_DATA_ALIGNMENT 0x38
#define FFS_ATTRIB_CHECKSUM 0x40
@@ -104,6 +105,17 @@ typedef struct {
EFI_FFS_FILE_STATE State;
} EFI_FFS_FILE_HEADER;
+typedef struct {
+ EFI_GUID Name;
+ EFI_FFS_INTEGRITY_CHECK IntegrityCheck;
+ EFI_FV_FILETYPE Type;
+ EFI_FFS_FILE_ATTRIBUTES Attributes;
+ UINT8 Size[3];
+ EFI_FFS_FILE_STATE State;
+ UINT32 ExtendedSize;
+} EFI_FFS_FILE_HEADER2;
+
+#define MAX_FFS_SIZE 0x1000000
typedef UINT8 EFI_SECTION_TYPE;
@@ -142,11 +154,20 @@ typedef struct {
EFI_SECTION_TYPE Type;
} EFI_COMMON_SECTION_HEADER;
+typedef struct {
+ UINT8 Size[3];
+ EFI_SECTION_TYPE Type;
+ UINT32 ExtendedSize;
+} EFI_COMMON_SECTION_HEADER2;
+
+#define MAX_SECTION_SIZE 0x1000000
+
//
// Leaf section type that contains an
// IA-32 16-bit executable image.
//
typedef EFI_COMMON_SECTION_HEADER EFI_COMPATIBILITY16_SECTION;
+typedef EFI_COMMON_SECTION_HEADER2 EFI_COMPATIBILITY16_SECTION2;
//
// CompressionType of EFI_COMPRESSION_SECTION.
@@ -163,15 +184,23 @@ typedef struct {
UINT8 CompressionType;
} EFI_COMPRESSION_SECTION;
+typedef struct {
+ EFI_COMMON_SECTION_HEADER2 CommonHeader;
+ UINT32 UncompressedLength;
+ UINT8 CompressionType;
+} EFI_COMPRESSION_SECTION2;
+
//
// Leaf section which could be used to determine the dispatch order of DXEs.
//
typedef EFI_COMMON_SECTION_HEADER EFI_DXE_DEPEX_SECTION;
+typedef EFI_COMMON_SECTION_HEADER2 EFI_DXE_DEPEX_SECTION2;
//
// Leaf section witch contains a PI FV.
//
typedef EFI_COMMON_SECTION_HEADER EFI_FIRMWARE_VOLUME_IMAGE_SECTION;
+typedef EFI_COMMON_SECTION_HEADER2 EFI_FIRMWARE_VOLUME_IMAGE_SECTION2;
//
// Leaf section which contains a single GUID.
@@ -181,6 +210,11 @@ typedef struct {
EFI_GUID SubTypeGuid;
} EFI_FREEFORM_SUBTYPE_GUID_SECTION;
+typedef struct {
+ EFI_COMMON_SECTION_HEADER2 CommonHeader;
+ EFI_GUID SubTypeGuid;
+} EFI_FREEFORM_SUBTYPE_GUID_SECTION2;
+
//
// Attributes of EFI_GUID_DEFINED_SECTION
//
@@ -196,30 +230,42 @@ typedef struct {
UINT16 Attributes;
} EFI_GUID_DEFINED_SECTION;
+typedef struct {
+ EFI_COMMON_SECTION_HEADER2 CommonHeader;
+ EFI_GUID SectionDefinitionGuid;
+ UINT16 DataOffset;
+ UINT16 Attributes;
+} EFI_GUID_DEFINED_SECTION2;
+
//
// Leaf section which contains PE32+ image.
//
typedef EFI_COMMON_SECTION_HEADER EFI_PE32_SECTION;
+typedef EFI_COMMON_SECTION_HEADER2 EFI_PE32_SECTION2;
//
// Leaf section which contains PIC image.
//
typedef EFI_COMMON_SECTION_HEADER EFI_PIC_SECTION;
+typedef EFI_COMMON_SECTION_HEADER2 EFI_PIC_SECTION2;
//
// Leaf section which used to determine the dispatch order of PEIMs.
//
typedef EFI_COMMON_SECTION_HEADER EFI_PEI_DEPEX_SECTION;
+typedef EFI_COMMON_SECTION_HEADER2 EFI_PEI_DEPEX_SECTION2;
//
// Leaf section which constains the position-independent-code image.
//
typedef EFI_COMMON_SECTION_HEADER EFI_TE_SECTION;
+typedef EFI_COMMON_SECTION_HEADER2 EFI_TE_SECTION2;
//
// Leaf section which contains an array of zero or more bytes.
//
typedef EFI_COMMON_SECTION_HEADER EFI_RAW_SECTION;
+typedef EFI_COMMON_SECTION_HEADER2 EFI_RAW_SECTION2;
//
// Leaf section which contains a unicode string that
@@ -234,6 +280,14 @@ typedef struct {
CHAR16 FileNameString[1];
} EFI_USER_INTERFACE_SECTION;
+typedef struct {
+ EFI_COMMON_SECTION_HEADER2 CommonHeader;
+
+ //
+ // Array of unicode string.
+ //
+ CHAR16 FileNameString[1];
+} EFI_USER_INTERFACE_SECTION2;
//
// Leaf section which contains a numeric build number and
@@ -245,6 +299,11 @@ typedef struct {
CHAR16 VersionString[1];
} EFI_VERSION_SECTION;
+typedef struct {
+ EFI_COMMON_SECTION_HEADER2 CommonHeader;
+ UINT16 BuildNumber;
+ CHAR16 VersionString[1];
+} EFI_VERSION_SECTION2;
#define SECTION_SIZE(SectionHeaderPtr) \
((UINT32) (*((UINT32 *) ((EFI_COMMON_SECTION_HEADER *) SectionHeaderPtr)->Size) & 0x00ffffff))
@@ -266,6 +325,23 @@ typedef union {
EFI_FIRMWARE_VOLUME_IMAGE_SECTION *FVImageSection;
EFI_FREEFORM_SUBTYPE_GUID_SECTION *FreeformSubtypeSection;
EFI_RAW_SECTION *RawSection;
+ //
+ // For section whose size is equal or greater than 0x1000000
+ //
+ EFI_COMMON_SECTION_HEADER2 *CommonHeader2;
+ EFI_COMPRESSION_SECTION2 *CompressionSection2;
+ EFI_GUID_DEFINED_SECTION2 *GuidDefinedSection2;
+ EFI_PE32_SECTION2 *Pe32Section2;
+ EFI_PIC_SECTION2 *PicSection2;
+ EFI_TE_SECTION2 *TeSection2;
+ EFI_PEI_DEPEX_SECTION2 *PeimHeaderSection2;
+ EFI_DXE_DEPEX_SECTION2 *DependencySection2;
+ EFI_VERSION_SECTION2 *VersionSection2;
+ EFI_USER_INTERFACE_SECTION2 *UISection2;
+ EFI_COMPATIBILITY16_SECTION2 *Code16Section2;
+ EFI_FIRMWARE_VOLUME_IMAGE_SECTION2 *FVImageSection2;
+ EFI_FREEFORM_SUBTYPE_GUID_SECTION2 *FreeformSubtypeSection2;
+ EFI_RAW_SECTION2 *RawSection2;
} EFI_FILE_SECTION_POINTER;
#endif
diff --git a/BaseTools/Source/C/Include/Common/PiFirmwareVolume.h b/BaseTools/Source/C/Include/Common/PiFirmwareVolume.h
index 0c8e29e1c..ea06eee69 100644
--- a/BaseTools/Source/C/Include/Common/PiFirmwareVolume.h
+++ b/BaseTools/Source/C/Include/Common/PiFirmwareVolume.h
@@ -1,7 +1,7 @@
/** @file
The firmware volume related definitions in PI.
- Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>
+ 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
@@ -54,6 +54,7 @@ typedef UINT32 EFI_FVB_ATTRIBUTES_2;
#define EFI_FVB2_WRITE_LOCK_CAP 0x00004000
#define EFI_FVB2_WRITE_LOCK_STATUS 0x00008000
#define EFI_FVB2_ALIGNMENT 0x001F0000
+#define EFI_FVB2_WEAK_ALIGNMENT 0x80000000
#define EFI_FVB2_ALIGNMENT_1 0x00000000
#define EFI_FVB2_ALIGNMENT_2 0x00010000
#define EFI_FVB2_ALIGNMENT_4 0x00020000
diff --git a/BaseTools/Source/C/Include/Guid/PiFirmwareFileSystem.h b/BaseTools/Source/C/Include/Guid/PiFirmwareFileSystem.h
index a1c6b55f1..3a4be3463 100644
--- a/BaseTools/Source/C/Include/Guid/PiFirmwareFileSystem.h
+++ b/BaseTools/Source/C/Include/Guid/PiFirmwareFileSystem.h
@@ -2,7 +2,7 @@
Guid used to define the Firmware File System. See PI spec volume 3 for more
details.
- Copyright (c) 2006 - 2008, Intel Corporation. All rights reserved.<BR>
+ 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
@@ -30,12 +30,18 @@
0x8c8ce578, 0x8a3d, 0x4f1c, {0x99, 0x35, 0x89, 0x61, 0x85, 0xc3, 0x2d, 0xd3 } \
}
+#define EFI_FIRMWARE_FILE_SYSTEM3_GUID \
+ { \
+ 0x5473c07a, 0x3dcb, 0x4dca, {0xbd, 0x6f, 0x1e, 0x96, 0x89, 0xe7, 0x34, 0x9a } \
+ }
+
#define EFI_FFS_VOLUME_TOP_FILE_GUID \
{ \
0x1BA0062E, 0xC779, 0x4582, {0x85, 0x66, 0x33, 0x6A, 0xE8, 0xF7, 0x8F, 0x09 } \
}
extern EFI_GUID gEfiFirmwareFileSystem2Guid;
+extern EFI_GUID gEfiFirmwareFileSystem3Guid;
extern EFI_GUID gEfiFirmwareVolumeTopFileGuid;
#endif
diff --git a/BaseTools/Source/C/VfrCompile/VfrSyntax.g b/BaseTools/Source/C/VfrCompile/VfrSyntax.g
index 61b68f5fb..6f15aaa45 100644
--- a/BaseTools/Source/C/VfrCompile/VfrSyntax.g
+++ b/BaseTools/Source/C/VfrCompile/VfrSyntax.g
@@ -136,6 +136,7 @@ VfrParserStart (
#token MapTitle("maptitle") "maptitle"
#token MapGuid("mapguid") "mapguid"
#token Subtitle("subtitle") "subtitle"
+#token EndSubtitle("endsubtitle") "endsubtitle"
#token Help("help") "help"
#token Text("text") "text"
#token Option("option") "option"
@@ -1018,12 +1019,29 @@ vfrStatementVarStoreNameValue :
<<
EFI_GUID Guid;
CIfrVarStoreNameValue VSNVObj;
- EFI_VARSTORE_ID VarStoreId;
+ EFI_VARSTORE_ID VarStoreId = EFI_VARSTORE_ID_INVALID;
+ BOOLEAN Created = FALSE;
>>
L:NameValueVarStore << VSNVObj.SetLineNo(L->getLine()); >>
- SN:StringIdentifier "," << _PCATCH(mCVfrDataStorage.DeclareNameVarStoreBegin (SN->getText()), SN); >>
+ SN:StringIdentifier ","
+ {
+ VarId "=" ID:Number "," <<
+ _PCATCH(
+ (INTN)(VarStoreId = _STOU16(ID->getText())) != 0,
+ (INTN)TRUE,
+ ID,
+ "varid 0 is not allowed."
+ );
+ >>
+ }
(
- Name "=" "STRING_TOKEN" "\(" N:Number "\)" "," << _PCATCH(mCVfrDataStorage.NameTableAddItem (_STOSID(N->getText())), SN); >>
+ Name "=" "STRING_TOKEN" "\(" N:Number "\)" "," <<
+ if (!Created) {
+ _PCATCH(mCVfrDataStorage.DeclareNameVarStoreBegin (SN->getText(), VarStoreId), SN);
+ Created = TRUE;
+ }
+ _PCATCH(mCVfrDataStorage.NameTableAddItem (_STOSID(N->getText())), SN);
+ >>
)+
Uuid "=" guidDefinition[Guid] << _PCATCH(mCVfrDataStorage.DeclareNameVarStoreEnd (&Guid), SN); >>
<<
@@ -1628,8 +1646,14 @@ vfrStatementSubTitle :
{
"," FLAGS "=" vfrSubtitleFlags[SObj]
}
- { vfrStatementStatTagList "," }
- E:";" << CRT_END_OP (E); >>
+ (
+ {vfrStatementStatTagList "," }
+ E:";" << CRT_END_OP (E); >>
+ |
+ { "," vfrStatementStatTagList}
+ { "," (vfrStatementStat | vfrStatementQuestions)*}
+ E: EndSubtitle ";" << CRT_END_OP (E); >>
+ )
;
vfrSubtitleFlags [CIfrSubtitle & SObj] :
diff --git a/BaseTools/Source/C/VfrCompile/VfrUtilityLib.cpp b/BaseTools/Source/C/VfrCompile/VfrUtilityLib.cpp
index 21a479db6..7c1383eb7 100644
--- a/BaseTools/Source/C/VfrCompile/VfrUtilityLib.cpp
+++ b/BaseTools/Source/C/VfrCompile/VfrUtilityLib.cpp
@@ -1512,21 +1512,30 @@ CVfrDataStorage::MarkVarStoreIdUnused (
EFI_VFR_RETURN_CODE
CVfrDataStorage::DeclareNameVarStoreBegin (
- IN CHAR8 *StoreName
+ IN CHAR8 *StoreName,
+ IN EFI_VARSTORE_ID VarStoreId
)
{
SVfrVarStorageNode *pNode = NULL;
- EFI_VARSTORE_ID VarStoreId;
+ EFI_VARSTORE_ID TmpVarStoreId;
if (StoreName == NULL) {
return VFR_RETURN_FATAL_ERROR;
}
- if (GetVarStoreId (StoreName, &VarStoreId) == VFR_RETURN_SUCCESS) {
+ if (GetVarStoreId (StoreName, &TmpVarStoreId) == VFR_RETURN_SUCCESS) {
return VFR_RETURN_REDEFINED;
}
+
+ if (VarStoreId == EFI_VARSTORE_ID_INVALID) {
+ VarStoreId = GetFreeVarStoreId (EFI_VFR_VARSTORE_NAME);
+ } else {
+ if (ChekVarStoreIdFree (VarStoreId) == FALSE) {
+ return VFR_RETURN_VARSTOREID_REDEFINED;
+ }
+ MarkVarStoreIdUsed (VarStoreId);
+ }
- VarStoreId = GetFreeVarStoreId (EFI_VFR_VARSTORE_NAME);
if ((pNode = new SVfrVarStorageNode (StoreName, VarStoreId)) == NULL) {
return VFR_RETURN_UNDEFINED;
}
@@ -2619,6 +2628,14 @@ CVfrQuestionDB::RegisterNewDateQuestion (
CHAR8 Index;
if (BaseVarId == NULL && Name == NULL) {
+ if (QuestionId == EFI_QUESTION_ID_INVALID) {
+ QuestionId = GetFreeQuestionId ();
+ } else {
+ if (ChekQuestionIdFree (QuestionId) == FALSE) {
+ goto Err;
+ }
+ MarkQuestionIdUsed (QuestionId);
+ }
return;
}
@@ -2787,6 +2804,14 @@ CVfrQuestionDB::RegisterNewTimeQuestion (
CHAR8 Index;
if (BaseVarId == NULL && Name == NULL) {
+ if (QuestionId == EFI_QUESTION_ID_INVALID) {
+ QuestionId = GetFreeQuestionId ();
+ } else {
+ if (ChekQuestionIdFree (QuestionId) == FALSE) {
+ goto Err;
+ }
+ MarkQuestionIdUsed (QuestionId);
+ }
return;
}
diff --git a/BaseTools/Source/C/VfrCompile/VfrUtilityLib.h b/BaseTools/Source/C/VfrCompile/VfrUtilityLib.h
index 2847a74a7..c8f533364 100644
--- a/BaseTools/Source/C/VfrCompile/VfrUtilityLib.h
+++ b/BaseTools/Source/C/VfrCompile/VfrUtilityLib.h
@@ -300,7 +300,7 @@ public:
SVfrVarStorageNode * GetEfiVarStoreList () {
return mEfiVarStoreList;
}
- EFI_VFR_RETURN_CODE DeclareNameVarStoreBegin (CHAR8 *);
+ EFI_VFR_RETURN_CODE DeclareNameVarStoreBegin (CHAR8 *, EFI_VARSTORE_ID);
EFI_VFR_RETURN_CODE NameTableAddItem (EFI_STRING_ID);
EFI_VFR_RETURN_CODE DeclareNameVarStoreEnd (EFI_GUID *);
diff --git a/BaseTools/Source/Python/AutoGen/AutoGen.py b/BaseTools/Source/Python/AutoGen/AutoGen.py
index 6711880f6..71d0d757d 100644
--- a/BaseTools/Source/Python/AutoGen/AutoGen.py
+++ b/BaseTools/Source/Python/AutoGen/AutoGen.py
@@ -1,7 +1,7 @@
## @file
# Generate AutoGen.h, AutoGen.c and *.depex files
#
-# Copyright (c) 2007 - 2011, Intel Corporation. All rights reserved.<BR>
+# 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
@@ -34,9 +34,12 @@ import Common.GlobalData as GlobalData
from GenFds.FdfParser import *
from CommonDataClass.CommonClass import SkuInfoClass
from Workspace.BuildClassObject import *
+from GenPatchPcdTable.GenPatchPcdTable import parsePcdInfoFromMapFile
import Common.VpdInfoFile as VpdInfoFile
+from GenPcdDb import CreatePcdDatabaseCode
+from Workspace.MetaFileCommentParser import UsageList
-## Regular expression for splitting Dependency Expression stirng into tokens
+## Regular expression for splitting Dependency Expression string into tokens
gDepexTokenPattern = re.compile("(\(|\)|\w+| \S+\.inf)")
## Mapping Makefile type
@@ -59,13 +62,7 @@ gAutoGenDepexFileName = "%(module_name)s.depex"
#
# Template string to generic AsBuilt INF
#
-gAsBuiltInfHeaderString = TemplateString("""## @file
-# ${module_name}
-#
-# DO NOT EDIT
-# FILE auto-generated Binary INF
-#
-##
+gAsBuiltInfHeaderString = TemplateString("""${header_comments}
[Defines]
INF_VERSION = 0x00010016
@@ -73,6 +70,7 @@ gAsBuiltInfHeaderString = TemplateString("""## @file
FILE_GUID = ${module_guid}
MODULE_TYPE = ${module_module_type}
VERSION_STRING = ${module_version_string}${BEGIN}
+ PCD_IS_DRIVER = ${pcd_is_driver_string}${END}${BEGIN}
UEFI_SPECIFICATION_VERSION = ${module_uefi_specification_version}${END}${BEGIN}
PI_SPECIFICATION_VERSION = ${module_pi_specification_version}${END}
@@ -82,8 +80,21 @@ gAsBuiltInfHeaderString = TemplateString("""## @file
[Binaries.${module_arch}]${BEGIN}
${binary_item}${END}
-[PcdEx]${BEGIN}
- ${pcd_item}${END}
+[PatchPcd.${module_arch}]${BEGIN}
+ ${patchablepcd_item}
+${END}
+[Protocols.${module_arch}]${BEGIN}
+ ${protocol_item}
+${END}
+[Ppis.${module_arch}]${BEGIN}
+ ${ppi_item}
+${END}
+[Guids.${module_arch}]${BEGIN}
+ ${guid_item}
+${END}
+[PcdEx.${module_arch}]${BEGIN}
+ ${pcd_item}
+${END}
## @AsBuilt${BEGIN}
## ${flags_item}${END}
@@ -228,15 +239,6 @@ class WorkspaceAutoGen(AutoGen):
ExtraData="Build target [%s] is not supported by the platform. [Valid target: %s]"
% (self.BuildTarget, " ".join(self.Platform.BuildTargets)))
- # Validate SKU ID
- if not self.SkuId:
- self.SkuId = 'DEFAULT'
-
- if self.SkuId not in self.Platform.SkuIds:
- EdkLogger.error("build", PARAMETER_INVALID,
- ExtraData="SKU-ID [%s] is not supported by the platform. [Valid SKU-ID: %s]"
- % (self.SkuId, " ".join(self.Platform.SkuIds.keys())))
-
# parse FDF file to get PCDs in it, if any
if not self.FdfFile:
self.FdfFile = self.Platform.FlashDefinition
@@ -867,7 +869,7 @@ class PlatformAutoGen(AutoGen):
for PcdFromModule in M.ModulePcdList+M.LibraryPcdList:
# make sure that the "VOID*" kind of datum has MaxDatumSize set
- if PcdFromModule.DatumType == "VOID*" and PcdFromModule.MaxDatumSize == None:
+ if PcdFromModule.DatumType == "VOID*" and PcdFromModule.MaxDatumSize in [None, '']:
NoDatumTypePcdList.add("%s.%s [%s]" % (PcdFromModule.TokenSpaceGuidCName, PcdFromModule.TokenCName, F))
if PcdFromModule.Type in GenC.gDynamicPcd or PcdFromModule.Type in GenC.gDynamicExPcd:
@@ -938,31 +940,19 @@ class PlatformAutoGen(AutoGen):
# Add VPD type PCD into VpdFile and determine whether the VPD PCD need to be fixed up.
#
for PcdKey in PlatformPcds:
- Pcd = self.Platform.Pcds[PcdKey]
- if Pcd.Type in [TAB_PCDS_DYNAMIC_VPD, TAB_PCDS_DYNAMIC_EX_VPD]:
- Pcd = VpdPcdDict[PcdKey]
- Sku = Pcd.SkuInfoList[Pcd.SkuInfoList.keys()[0]]
- Sku.VpdOffset = Sku.VpdOffset.strip()
- #
- # Fix the optional data of VPD PCD.
- #
- if (Pcd.DatumType.strip() != "VOID*"):
- if Sku.DefaultValue == '':
- Pcd.SkuInfoList[Pcd.SkuInfoList.keys()[0]].DefaultValue = Pcd.MaxDatumSize
- Pcd.MaxDatumSize = None
- else:
- EdkLogger.error("build", AUTOGEN_ERROR, "PCD setting error",
- File=self.MetaFile,
- ExtraData="\n\tPCD: %s.%s format incorrect in DSC: %s\n\t\t\n"
- % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName, self.Platform.MetaFile.Path))
-
- VpdFile.Add(Pcd, Sku.VpdOffset)
- # if the offset of a VPD is *, then it need to be fixed up by third party tool.
- if not NeedProcessVpdMapFile and Sku.VpdOffset == "*":
- NeedProcessVpdMapFile = True
- if self.Platform.VpdToolGuid == None or self.Platform.VpdToolGuid == '':
- EdkLogger.error("Build", FILE_NOT_FOUND, \
- "Fail to find third-party BPDG tool to process VPD PCDs. BPDG Guid tool need to be defined in tools_def.txt and VPD_TOOL_GUID need to be provided in DSC file.")
+ Pcd = self.Platform.Pcds[PcdKey]
+ if Pcd.Type in [TAB_PCDS_DYNAMIC_VPD, TAB_PCDS_DYNAMIC_EX_VPD] and \
+ PcdKey in VpdPcdDict:
+ Pcd = VpdPcdDict[PcdKey]
+ for (SkuName,Sku) in Pcd.SkuInfoList.items():
+ Sku.VpdOffset = Sku.VpdOffset.strip()
+ VpdFile.Add(Pcd, Sku.VpdOffset)
+ # if the offset of a VPD is *, then it need to be fixed up by third party tool.
+ if not NeedProcessVpdMapFile and Sku.VpdOffset == "*":
+ NeedProcessVpdMapFile = True
+ if self.Platform.VpdToolGuid == None or self.Platform.VpdToolGuid == '':
+ EdkLogger.error("Build", FILE_NOT_FOUND, \
+ "Fail to find third-party BPDG tool to process VPD PCDs. BPDG Guid tool need to be defined in tools_def.txt and VPD_TOOL_GUID need to be provided in DSC file.")
#
@@ -983,32 +973,46 @@ class PlatformAutoGen(AutoGen):
# Not found, it should be signature
if not FoundFlag :
# just pick the a value to determine whether is unicode string type
- Sku = DscPcdEntry.SkuInfoList[DscPcdEntry.SkuInfoList.keys()[0]]
- Sku.VpdOffset = Sku.VpdOffset.strip()
-
- # Need to iterate DEC pcd information to get the value & datumtype
- for eachDec in self.PackageList:
- for DecPcd in eachDec.Pcds:
- DecPcdEntry = eachDec.Pcds[DecPcd]
- if (DecPcdEntry.TokenSpaceGuidCName == DscPcdEntry.TokenSpaceGuidCName) and \
- (DecPcdEntry.TokenCName == DscPcdEntry.TokenCName):
- # Print warning message to let the developer make a determine.
- EdkLogger.warn("build", "Unreferenced vpd pcd used!",
- File=self.MetaFile, \
- ExtraData = "PCD: %s.%s used in the DSC file %s is unreferenced." \
- %(DscPcdEntry.TokenSpaceGuidCName, DscPcdEntry.TokenCName, self.Platform.MetaFile.Path))
-
- DscPcdEntry.DatumType = DecPcdEntry.DatumType
- DscPcdEntry.DefaultValue = DecPcdEntry.DefaultValue
- # Only fix the value while no value provided in DSC file.
- if (Sku.DefaultValue == "" or Sku.DefaultValue==None):
- DscPcdEntry.SkuInfoList[DscPcdEntry.SkuInfoList.keys()[0]].DefaultValue = DecPcdEntry.DefaultValue
-
+ for (SkuName,Sku) in DscPcdEntry.SkuInfoList.items():
+ Sku.VpdOffset = Sku.VpdOffset.strip()
+
+ # Need to iterate DEC pcd information to get the value & datumtype
+ for eachDec in self.PackageList:
+ for DecPcd in eachDec.Pcds:
+ DecPcdEntry = eachDec.Pcds[DecPcd]
+ if (DecPcdEntry.TokenSpaceGuidCName == DscPcdEntry.TokenSpaceGuidCName) and \
+ (DecPcdEntry.TokenCName == DscPcdEntry.TokenCName):
+ # Print warning message to let the developer make a determine.
+ EdkLogger.warn("build", "Unreferenced vpd pcd used!",
+ File=self.MetaFile, \
+ ExtraData = "PCD: %s.%s used in the DSC file %s is unreferenced." \
+ %(DscPcdEntry.TokenSpaceGuidCName, DscPcdEntry.TokenCName, self.Platform.MetaFile.Path))
+
+ DscPcdEntry.DatumType = DecPcdEntry.DatumType
+ DscPcdEntry.DefaultValue = DecPcdEntry.DefaultValue
+ DscPcdEntry.TokenValue = DecPcdEntry.TokenValue
+ DscPcdEntry.TokenSpaceGuidValue = eachDec.Guids[DecPcdEntry.TokenSpaceGuidCName]
+ # Only fix the value while no value provided in DSC file.
+ if (Sku.DefaultValue == "" or Sku.DefaultValue==None):
+ DscPcdEntry.SkuInfoList[DscPcdEntry.SkuInfoList.keys()[0]].DefaultValue = DecPcdEntry.DefaultValue
+
+ if DscPcdEntry not in self._DynamicPcdList:
+ self._DynamicPcdList.append(DscPcdEntry)
+# Sku = DscPcdEntry.SkuInfoList[DscPcdEntry.SkuInfoList.keys()[0]]
+ Sku.VpdOffset = Sku.VpdOffset.strip()
+ PcdValue = Sku.DefaultValue
+ VpdFile.Add(DscPcdEntry, Sku.VpdOffset)
+ if not NeedProcessVpdMapFile and Sku.VpdOffset == "*":
+ NeedProcessVpdMapFile = True
+ if DscPcdEntry.DatumType == 'VOID*' and PcdValue.startswith("L"):
+ UnicodePcdArray.append(DscPcdEntry)
+ elif len(Sku.VariableName) > 0:
+ HiiPcdArray.append(DscPcdEntry)
+ else:
+ OtherPcdArray.append(DscPcdEntry)
+
+ # if the offset of a VPD is *, then it need to be fixed up by third party tool.
- VpdFile.Add(DscPcdEntry, Sku.VpdOffset)
- # if the offset of a VPD is *, then it need to be fixed up by third party tool.
- if not NeedProcessVpdMapFile and Sku.VpdOffset == "*":
- NeedProcessVpdMapFile = True
if (self.Platform.FlashDefinition == None or self.Platform.FlashDefinition == '') and \
@@ -1055,9 +1059,11 @@ class PlatformAutoGen(AutoGen):
# Fixup "*" offset
for Pcd in self._DynamicPcdList:
# just pick the a value to determine whether is unicode string type
- Sku = Pcd.SkuInfoList[Pcd.SkuInfoList.keys()[0]]
- if Sku.VpdOffset == "*":
- Sku.VpdOffset = VpdFile.GetOffset(Pcd)[0].strip()
+ i = 0
+ for (SkuName,Sku) in Pcd.SkuInfoList.items():
+ if Sku.VpdOffset == "*":
+ Sku.VpdOffset = VpdFile.GetOffset(Pcd)[i].strip()
+ i += 1
else:
EdkLogger.error("build", FILE_READ_FAILURE, "Can not find VPD map file %s to fix up VPD offset." % VpdMapFilePath)
@@ -1605,13 +1611,13 @@ class PlatformAutoGen(AutoGen):
% (ToPcd.TokenSpaceGuidCName, ToPcd.TokenCName))
Value = ToPcd.DefaultValue
if Value in [None, '']:
- ToPcd.MaxDatumSize = 1
+ ToPcd.MaxDatumSize = '1'
elif Value[0] == 'L':
- ToPcd.MaxDatumSize = str(len(Value) * 2)
+ ToPcd.MaxDatumSize = str((len(Value) - 2) * 2)
elif Value[0] == '{':
ToPcd.MaxDatumSize = str(len(Value.split(',')))
else:
- ToPcd.MaxDatumSize = str(len(Value))
+ ToPcd.MaxDatumSize = str(len(Value) - 1)
# apply default SKU for dynamic PCDS if specified one is not available
if (ToPcd.Type in PCD_DYNAMIC_TYPE_LIST or ToPcd.Type in PCD_DYNAMIC_EX_TYPE_LIST) \
@@ -2004,9 +2010,14 @@ class ModuleAutoGen(AutoGen):
self._DerivedPackageList = None
self._ModulePcdList = None
self._LibraryPcdList = None
+ self._PcdComments = sdict()
self._GuidList = None
+ self._GuidsUsedByPcd = None
+ self._GuidComments = sdict()
self._ProtocolList = None
+ self._ProtocolComments = sdict()
self._PpiList = None
+ self._PpiComments = sdict()
self._DepexList = None
self._DepexExpressionList = None
self._BuildOption = None
@@ -2107,6 +2118,10 @@ class ModuleAutoGen(AutoGen):
self._LibraryFlag = False
return self._LibraryFlag
+ ## Check if the module is binary module or not
+ def _IsBinaryModule(self):
+ return self.Module.IsBinaryModule
+
## Return the directory to store intermediate files of the module
def _GetBuildDir(self):
if self._BuildDir == None:
@@ -2563,6 +2578,12 @@ class ModuleAutoGen(AutoGen):
self._DependentLibraryList = self.PlatformInfo.ApplyLibraryInstance(self.Module)
return self._DependentLibraryList
+ @staticmethod
+ def UpdateComments(Recver, Src):
+ for Key in Src:
+ if Key not in Recver:
+ Recver[Key] = []
+ Recver[Key].extend(Src[Key])
## Get the list of PCDs from current module
#
# @retval list The list of PCD
@@ -2571,6 +2592,7 @@ class ModuleAutoGen(AutoGen):
if self._ModulePcdList == None:
# apply PCD settings from platform
self._ModulePcdList = self.PlatformInfo.ApplyPcdSetting(self.Module, self.Module.Pcds)
+ self.UpdateComments(self._PcdComments, self.Module.PcdComments)
return self._ModulePcdList
## Get the list of PCDs from dependent libraries
@@ -2583,6 +2605,7 @@ class ModuleAutoGen(AutoGen):
if not self.IsLibrary:
# get PCDs from dependent libraries
for Library in self.DependentLibraryList:
+ self.UpdateComments(self._PcdComments, Library.PcdComments)
for Key in Library.Pcds:
# skip duplicated PCDs
if Key in self.Module.Pcds or Key in Pcds:
@@ -2603,8 +2626,17 @@ class ModuleAutoGen(AutoGen):
self._GuidList = self.Module.Guids
for Library in self.DependentLibraryList:
self._GuidList.update(Library.Guids)
+ self.UpdateComments(self._GuidComments, Library.GuidComments)
+ self.UpdateComments(self._GuidComments, self.Module.GuidComments)
return self._GuidList
+ def GetGuidsUsedByPcd(self):
+ if self._GuidsUsedByPcd == None:
+ self._GuidsUsedByPcd = sdict()
+ self._GuidsUsedByPcd.update(self.Module.GetGuidsUsedByPcd())
+ for Library in self.DependentLibraryList:
+ self._GuidsUsedByPcd.update(Library.GetGuidsUsedByPcd())
+ return self._GuidsUsedByPcd
## Get the protocol value mapping
#
# @retval dict The mapping between protocol cname and its value
@@ -2614,6 +2646,8 @@ class ModuleAutoGen(AutoGen):
self._ProtocolList = self.Module.Protocols
for Library in self.DependentLibraryList:
self._ProtocolList.update(Library.Protocols)
+ self.UpdateComments(self._ProtocolComments, Library.ProtocolComments)
+ self.UpdateComments(self._ProtocolComments, self.Module.ProtocolComments)
return self._ProtocolList
## Get the PPI value mapping
@@ -2625,6 +2659,8 @@ class ModuleAutoGen(AutoGen):
self._PpiList = self.Module.Ppis
for Library in self.DependentLibraryList:
self._PpiList.update(Library.Ppis)
+ self.UpdateComments(self._PpiComments, Library.PpiComments)
+ self.UpdateComments(self._PpiComments, self.Module.PpiComments)
return self._PpiList
## Get the list of include search path
@@ -2681,38 +2717,74 @@ class ModuleAutoGen(AutoGen):
### TODO: How to handles mixed source and binary modules
- # Find all DynamicEx PCDs used by this module and dependent libraries
+ # Find all DynamicEx and PatchableInModule PCDs used by this module and dependent libraries
# Also find all packages that the DynamicEx PCDs depend on
Pcds = []
+ PatchablePcds = {}
Packages = []
+ PcdCheckList = []
+ PcdTokenSpaceList = []
for Pcd in self.ModulePcdList + self.LibraryPcdList:
- if Pcd.Type in GenC.gDynamicExPcd:
- if Pcd not in Pcds:
- Pcds += [Pcd]
- for Package in self.DerivedPackageList:
- if Package not in Packages:
- if (Pcd.TokenCName, Pcd.TokenSpaceGuidCName, 'DynamicEx') in Package.Pcds:
- Packages += [Package]
- elif (Pcd.TokenCName, Pcd.TokenSpaceGuidCName, 'Dynamic') in Package.Pcds:
- Packages += [Package]
+ if Pcd.Type == TAB_PCDS_PATCHABLE_IN_MODULE:
+ PatchablePcds[Pcd.TokenCName] = Pcd
+ PcdCheckList.append((Pcd.TokenCName, Pcd.TokenSpaceGuidCName, 'PatchableInModule'))
+ elif Pcd.Type in GenC.gDynamicExPcd:
+ if Pcd not in Pcds:
+ Pcds += [Pcd]
+ PcdCheckList.append((Pcd.TokenCName, Pcd.TokenSpaceGuidCName, 'DynamicEx'))
+ PcdCheckList.append((Pcd.TokenCName, Pcd.TokenSpaceGuidCName, 'Dynamic'))
+ PcdTokenSpaceList.append(Pcd.TokenSpaceGuidCName)
+ GuidList = sdict()
+ GuidList.update(self.GuidList)
+ for TokenSpace in self.GetGuidsUsedByPcd():
+ # If token space is not referred by patch PCD or Ex PCD, remove the GUID from GUID list
+ # The GUIDs in GUIDs section should really be the GUIDs in source INF or referred by Ex an patch PCDs
+ if TokenSpace not in PcdTokenSpaceList and TokenSpace in GuidList:
+ GuidList.pop(TokenSpace)
+ CheckList = (GuidList, self.PpiList, self.ProtocolList, PcdCheckList)
+ for Package in self.DerivedPackageList:
+ if Package in Packages:
+ continue
+ BeChecked = (Package.Guids, Package.Ppis, Package.Protocols, Package.Pcds)
+ Found = False
+ for Index in range(len(BeChecked)):
+ for Item in CheckList[Index]:
+ if Item in BeChecked[Index]:
+ Packages += [Package]
+ Found = True
+ break
+ if Found: break
ModuleType = self.ModuleType
if ModuleType == 'UEFI_DRIVER' and self.DepexGenerated:
- ModuleType = 'DXE_DRIVER'
+ ModuleType = 'DXE_DRIVER'
+
+ DriverType = ''
+ if self.PcdIsDriver != '':
+ DriverType = self.PcdIsDriver
AsBuiltInfDict = {
'module_name' : self.Name,
'module_guid' : self.Guid,
'module_module_type' : ModuleType,
'module_version_string' : self.Version,
+ 'pcd_is_driver_string' : [],
'module_uefi_specification_version' : [],
'module_pi_specification_version' : [],
'module_arch' : self.Arch,
'package_item' : ['%s' % (Package.MetaFile.File.replace('\\','/')) for Package in Packages],
'binary_item' : [],
+ 'patchablepcd_item' : [],
'pcd_item' : [],
- 'flags_item' : []
+ 'protocol_item' : [],
+ 'ppi_item' : [],
+ 'guid_item' : [],
+ 'flags_item' : [],
+ 'libraryclasses_item' : []
}
+ AsBuiltInfDict['module_inf_version'] = '0x%08x' % self.AutoGenVersion
+ if DriverType:
+ AsBuiltInfDict['pcd_is_driver_string'] += [DriverType]
if 'UEFI_SPECIFICATION_VERSION' in self.Specification:
AsBuiltInfDict['module_uefi_specification_version'] += [self.Specification['UEFI_SPECIFICATION_VERSION']]
@@ -2744,9 +2816,125 @@ class ModuleAutoGen(AutoGen):
if self.ModuleType in ['DXE_SMM_DRIVER']:
AsBuiltInfDict['binary_item'] += ['SMM_DEPEX|' + self.Name + '.depex']
+ for Root, Dirs, Files in os.walk(OutputDir):
+ for File in Files:
+ if File.lower().endswith('.pdb'):
+ AsBuiltInfDict['binary_item'] += ['DISPOSABLE|' + File]
+ HeaderComments = self.Module.HeaderComments
+ StartPos = 0
+ for Index in range(len(HeaderComments)):
+ if HeaderComments[Index].find('@BinaryHeader') != -1:
+ HeaderComments[Index] = HeaderComments[Index].replace('@BinaryHeader', '@file')
+ StartPos = Index
+ break
+ AsBuiltInfDict['header_comments'] = '\n'.join(HeaderComments[StartPos:]).replace(':#', '://')
+ GenList = [
+ (self.ProtocolList, self._ProtocolComments, 'protocol_item'),
+ (self.PpiList, self._PpiComments, 'ppi_item'),
+ (GuidList, self._GuidComments, 'guid_item')
+ ]
+ for Item in GenList:
+ for CName in Item[0]:
+ Comments = ''
+ if CName in Item[1]:
+ Comments = '\n '.join(Item[1][CName])
+ Entry = CName
+ if Comments:
+ Entry = Comments + '\n ' + CName
+ AsBuiltInfDict[Item[2]].append(Entry)
+ PatchList = parsePcdInfoFromMapFile(
+ os.path.join(self.OutputDir, self.Name + '.map'),
+ os.path.join(self.OutputDir, self.Name + '.efi')
+ )
+ if PatchList:
+ for PatchPcd in PatchList:
+ if PatchPcd[0] not in PatchablePcds:
+ continue
+ Pcd = PatchablePcds[PatchPcd[0]]
+ PcdValue = ''
+ if Pcd.DatumType != 'VOID*':
+ HexFormat = '0x%02x'
+ if Pcd.DatumType == 'UINT16':
+ HexFormat = '0x%04x'
+ elif Pcd.DatumType == 'UINT32':
+ HexFormat = '0x%08x'
+ elif Pcd.DatumType == 'UINT64':
+ HexFormat = '0x%016x'
+ PcdValue = HexFormat % int(Pcd.DefaultValue, 0)
+ else:
+ if Pcd.MaxDatumSize == None or Pcd.MaxDatumSize == '':
+ EdkLogger.error("build", AUTOGEN_ERROR,
+ "Unknown [MaxDatumSize] of PCD [%s.%s]" % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName)
+ )
+ ArraySize = int(Pcd.MaxDatumSize, 0)
+ PcdValue = Pcd.DefaultValue
+ if PcdValue[0] != '{':
+ Unicode = False
+ if PcdValue[0] == 'L':
+ Unicode = True
+ PcdValue = PcdValue.lstrip('L')
+ PcdValue = eval(PcdValue)
+ NewValue = '{'
+ for Index in range(0, len(PcdValue)):
+ if Unicode:
+ CharVal = ord(PcdValue[Index])
+ NewValue = NewValue + '0x%02x' % (CharVal & 0x00FF) + ', ' \
+ + '0x%02x' % (CharVal >> 8) + ', '
+ else:
+ NewValue = NewValue + '0x%02x' % (ord(PcdValue[Index]) % 0x100) + ', '
+ Padding = '0x00, '
+ if Unicode:
+ Padding = Padding * 2
+ ArraySize = ArraySize / 2
+ if ArraySize < (len(PcdValue) + 1):
+ EdkLogger.error("build", AUTOGEN_ERROR,
+ "The maximum size of VOID* type PCD '%s.%s' is less than its actual size occupied." % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName)
+ )
+ if ArraySize > len(PcdValue) + 1:
+ NewValue = NewValue + Padding * (ArraySize - len(PcdValue) - 1)
+ PcdValue = NewValue + Padding.strip().rstrip(',') + '}'
+ elif len(PcdValue.split(',')) <= ArraySize:
+ PcdValue = PcdValue.rstrip('}') + ', 0x00' * (ArraySize - len(PcdValue.split(',')))
+ PcdValue += '}'
+ else:
+ EdkLogger.error("build", AUTOGEN_ERROR,
+ "The maximum size of VOID* type PCD '%s.%s' is less than its actual size occupied." % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName)
+ )
+ PcdItem = '%s.%s|%s|0x%X' % \
+ (Pcd.TokenSpaceGuidCName, Pcd.TokenCName, PcdValue, PatchPcd[1])
+ PcdComments = ''
+ if (Pcd.TokenSpaceGuidCName, Pcd.TokenCName) in self._PcdComments:
+ PcdComments = '\n '.join(self._PcdComments[Pcd.TokenSpaceGuidCName, Pcd.TokenCName])
+ if PcdComments:
+ PcdItem = PcdComments + '\n ' + PcdItem
+ AsBuiltInfDict['patchablepcd_item'].append(PcdItem)
for Pcd in Pcds:
- AsBuiltInfDict['pcd_item'] += [Pcd.TokenSpaceGuidCName + '.' + Pcd.TokenCName]
-
+ PcdComments = ''
+ PcdCommentList = []
+ HiiInfo = ''
+ if Pcd.Type == TAB_PCDS_DYNAMIC_EX_HII:
+ for SkuName in Pcd.SkuInfoList:
+ SkuInfo = Pcd.SkuInfoList[SkuName]
+ HiiInfo = '## %s|%s|%s' % (SkuInfo.VariableName, SkuInfo.VariableGuid, SkuInfo.VariableOffset)
+ break
+ if (Pcd.TokenSpaceGuidCName, Pcd.TokenCName) in self._PcdComments:
+ PcdCommentList = self._PcdComments[Pcd.TokenSpaceGuidCName, Pcd.TokenCName][:]
+ if HiiInfo:
+ UsageIndex = -1
+ for Index, Comment in enumerate(PcdCommentList):
+ for Usage in UsageList:
+ if Comment.find(Usage) != -1:
+ UsageIndex = Index
+ break
+ if UsageIndex != -1:
+ PcdCommentList[UsageIndex] = PcdCommentList[UsageIndex] + ' ' + HiiInfo
+ else:
+ PcdCommentList.append('## ' + HiiInfo)
+ PcdComments = '\n '.join(PcdCommentList)
+ PcdEntry = Pcd.TokenSpaceGuidCName + '.' + Pcd.TokenCName
+ if PcdComments:
+ PcdEntry = PcdComments + '\n ' + PcdEntry
+ AsBuiltInfDict['pcd_item'] += [PcdEntry]
for Item in self.BuildOption:
if 'FLAGS' in self.BuildOption[Item]:
AsBuiltInfDict['flags_item'] += ['%s:%s_%s_%s_%s_FLAGS = %s' % (self.ToolChainFamily, self.BuildTarget, self.ToolChain, self.Arch, Item, self.BuildOption[Item]['FLAGS'].strip())]
@@ -2793,6 +2981,11 @@ class ModuleAutoGen(AutoGen):
if self.IsCodeFileCreated:
return
+ # Need to generate PcdDatabase even PcdDriver is binarymodule
+ if self.IsBinaryModule and self.PcdIsDriver != '':
+ CreatePcdDatabaseCode(self, TemplateString(), TemplateString())
+ return
+
if not self.IsLibrary and CreateLibraryCodeFile:
for LibraryAutoGen in self.LibraryAutoGenList:
LibraryAutoGen.CreateCodeFile()
@@ -2875,7 +3068,7 @@ class ModuleAutoGen(AutoGen):
Specification = property(_GetSpecification)
IsLibrary = property(_IsLibrary)
-
+ IsBinaryModule = property(_IsBinaryModule)
BuildDir = property(_GetBuildDir)
OutputDir = property(_GetOutputDir)
DebugDir = property(_GetDebugDir)
diff --git a/BaseTools/Source/Python/AutoGen/GenC.py b/BaseTools/Source/Python/AutoGen/GenC.py
index 2eb920417..63ba2b241 100644
--- a/BaseTools/Source/Python/AutoGen/GenC.py
+++ b/BaseTools/Source/Python/AutoGen/GenC.py
@@ -1,7 +1,7 @@
## @file
# Routines for generating AutoGen.h and AutoGen.c
#
-# Copyright (c) 2007 - 2012, Intel Corporation. All rights reserved.<BR>
+# 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
@@ -22,6 +22,7 @@ from Common.DataType import *
from Common.Misc import *
from Common.String import StringToArray
from StrGather import *
+from GenPcdDb import CreatePcdDatabaseCode
## PCD type string
gItemTypeStringDatabase = {
@@ -49,252 +50,6 @@ gDatumSizeStringDatabase = {'UINT8':'8','UINT16':'16','UINT32':'32','UINT64':'64
gDatumSizeStringDatabaseH = {'UINT8':'8','UINT16':'16','UINT32':'32','UINT64':'64','BOOLEAN':'BOOL','VOID*':'PTR'}
gDatumSizeStringDatabaseLib = {'UINT8':'8','UINT16':'16','UINT32':'32','UINT64':'64','BOOLEAN':'Bool','VOID*':'Ptr'}
-## Mapping between PCD driver type and EFI phase
-gPcdPhaseMap = {
- "PEI_PCD_DRIVER" : "PEI",
- "DXE_PCD_DRIVER" : "DXE"
-}
-
-gPcdDatabaseCommonAutoGenH = """
-//
-// The following definition will be generated by build tool
-//
-
-//
-// Common definitions
-//
-typedef UINT8 SKU_ID;
-
-#define PCD_TYPE_SHIFT 28
-
-#define PCD_TYPE_DATA (0x0U << PCD_TYPE_SHIFT)
-#define PCD_TYPE_HII (0x8U << PCD_TYPE_SHIFT)
-#define PCD_TYPE_VPD (0x4U << PCD_TYPE_SHIFT)
-#define PCD_TYPE_SKU_ENABLED (0x2U << PCD_TYPE_SHIFT)
-#define PCD_TYPE_STRING (0x1U << PCD_TYPE_SHIFT)
-
-#define PCD_TYPE_ALL_SET (PCD_TYPE_DATA | PCD_TYPE_HII | PCD_TYPE_VPD | PCD_TYPE_SKU_ENABLED | PCD_TYPE_STRING)
-
-#define PCD_DATUM_TYPE_SHIFT 24
-
-#define PCD_DATUM_TYPE_POINTER (0x0U << PCD_DATUM_TYPE_SHIFT)
-#define PCD_DATUM_TYPE_UINT8 (0x1U << PCD_DATUM_TYPE_SHIFT)
-#define PCD_DATUM_TYPE_UINT16 (0x2U << PCD_DATUM_TYPE_SHIFT)
-#define PCD_DATUM_TYPE_UINT32 (0x4U << PCD_DATUM_TYPE_SHIFT)
-#define PCD_DATUM_TYPE_UINT64 (0x8U << PCD_DATUM_TYPE_SHIFT)
-
-#define PCD_DATUM_TYPE_ALL_SET (PCD_DATUM_TYPE_POINTER | \\
- PCD_DATUM_TYPE_UINT8 | \\
- PCD_DATUM_TYPE_UINT16 | \\
- PCD_DATUM_TYPE_UINT32 | \\
- PCD_DATUM_TYPE_UINT64)
-
-#define PCD_DATABASE_OFFSET_MASK (~(PCD_TYPE_ALL_SET | PCD_DATUM_TYPE_ALL_SET))
-
-typedef struct {
- UINT32 ExTokenNumber;
- UINT16 LocalTokenNumber; // PCD Number of this particular platform build
- UINT16 ExGuidIndex; // Index of GuidTable
-} DYNAMICEX_MAPPING;
-
-typedef struct {
- UINT32 SkuDataStartOffset; //We have to use offsetof MACRO as we don't know padding done by compiler
- UINT32 SkuIdTableOffset; //Offset from the PCD_DB
-} SKU_HEAD;
-
-typedef struct {
- UINT32 StringIndex; // Offset in String Table in units of UINT32.
- UINT32 DefaultValueOffset; // Offset of the Default Value
- UINT16 GuidTableIndex; // Offset in Guid Table in units of GUID.
- UINT16 Offset; // Offset in Variable
-} VARIABLE_HEAD;
-
-typedef struct {
- UINT32 Offset;
-} VPD_HEAD;
-
-typedef UINT32 STRING_HEAD;
-
-typedef UINT16 SIZE_INFO;
-
-#define offsetof(s,m) (UINT32) (UINTN) &(((s *)0)->m)
-
-"""
-
-gPcdDatabaseEpilogueAutoGenH = """
-typedef struct {
- PEI_PCD_DATABASE PeiDb;
- DXE_PCD_DATABASE DxeDb;
-} PCD_DATABASE;
-
-#define PCD_TOTAL_TOKEN_NUMBER (PEI_LOCAL_TOKEN_NUMBER + DXE_LOCAL_TOKEN_NUMBER)
-
-"""
-
-gPcdDatabaseAutoGenH = TemplateString("""
-#define ${PHASE}_GUID_TABLE_SIZE ${GUID_TABLE_SIZE}
-#define ${PHASE}_STRING_TABLE_SIZE ${STRING_TABLE_SIZE}
-#define ${PHASE}_SKUID_TABLE_SIZE ${SKUID_TABLE_SIZE}
-#define ${PHASE}_LOCAL_TOKEN_NUMBER_TABLE_SIZE ${LOCAL_TOKEN_NUMBER_TABLE_SIZE}
-#define ${PHASE}_LOCAL_TOKEN_NUMBER ${LOCAL_TOKEN_NUMBER}
-#define ${PHASE}_EXMAPPING_TABLE_SIZE ${EXMAPPING_TABLE_SIZE}
-#define ${PHASE}_EX_TOKEN_NUMBER ${EX_TOKEN_NUMBER}
-#define ${PHASE}_SIZE_TABLE_SIZE ${SIZE_TABLE_SIZE}
-#define ${PHASE}_GUID_TABLE_EMPTY ${GUID_TABLE_EMPTY}
-#define ${PHASE}_STRING_TABLE_EMPTY ${STRING_TABLE_EMPTY}
-#define ${PHASE}_SKUID_TABLE_EMPTY ${SKUID_TABLE_EMPTY}
-#define ${PHASE}_DATABASE_EMPTY ${DATABASE_EMPTY}
-#define ${PHASE}_EXMAP_TABLE_EMPTY ${EXMAP_TABLE_EMPTY}
-
-typedef struct {
-${BEGIN} UINT64 ${INIT_CNAME_DECL_UINT64}_${INIT_GUID_DECL_UINT64}[${INIT_NUMSKUS_DECL_UINT64}];
-${END}
-${BEGIN} UINT64 ${VARDEF_CNAME_UINT64}_${VARDEF_GUID_UINT64}_VariableDefault_${VARDEF_SKUID_UINT64};
-${END}
-${BEGIN} UINT32 ${INIT_CNAME_DECL_UINT32}_${INIT_GUID_DECL_UINT32}[${INIT_NUMSKUS_DECL_UINT32}];
-${END}
-${BEGIN} UINT32 ${VARDEF_CNAME_UINT32}_${VARDEF_GUID_UINT32}_VariableDefault_${VARDEF_SKUID_UINT32};
-${END}
-${BEGIN} VPD_HEAD ${VPD_HEAD_CNAME_DECL}_${VPD_HEAD_GUID_DECL}[${VPD_HEAD_NUMSKUS_DECL}];
-${END}
- DYNAMICEX_MAPPING ExMapTable[${PHASE}_EXMAPPING_TABLE_SIZE];
- UINT32 LocalTokenNumberTable[${PHASE}_LOCAL_TOKEN_NUMBER_TABLE_SIZE];
- GUID GuidTable[${PHASE}_GUID_TABLE_SIZE];
-${BEGIN} STRING_HEAD ${STRING_HEAD_CNAME_DECL}_${STRING_HEAD_GUID_DECL}[${STRING_HEAD_NUMSKUS_DECL}];
-${END}
-${BEGIN} VARIABLE_HEAD ${VARIABLE_HEAD_CNAME_DECL}_${VARIABLE_HEAD_GUID_DECL}_Variable_Header[${VARIABLE_HEAD_NUMSKUS_DECL}];
-${END}
-${BEGIN} UINT8 StringTable${STRING_TABLE_INDEX}[${STRING_TABLE_LENGTH}]; /* ${STRING_TABLE_CNAME}_${STRING_TABLE_GUID} */
-${END}
- SIZE_INFO SizeTable[${PHASE}_SIZE_TABLE_SIZE];
-${BEGIN} UINT16 ${INIT_CNAME_DECL_UINT16}_${INIT_GUID_DECL_UINT16}[${INIT_NUMSKUS_DECL_UINT16}];
-${END}
-${BEGIN} UINT16 ${VARDEF_CNAME_UINT16}_${VARDEF_GUID_UINT16}_VariableDefault_${VARDEF_SKUID_UINT16};
-${END}
-${BEGIN} UINT8 ${INIT_CNAME_DECL_UINT8}_${INIT_GUID_DECL_UINT8}[${INIT_NUMSKUS_DECL_UINT8}];
-${END}
-${BEGIN} UINT8 ${VARDEF_CNAME_UINT8}_${VARDEF_GUID_UINT8}_VariableDefault_${VARDEF_SKUID_UINT8};
-${END}
-${BEGIN} BOOLEAN ${INIT_CNAME_DECL_BOOLEAN}_${INIT_GUID_DECL_BOOLEAN}[${INIT_NUMSKUS_DECL_BOOLEAN}];
-${END}
-${BEGIN} BOOLEAN ${VARDEF_CNAME_BOOLEAN}_${VARDEF_GUID_BOOLEAN}_VariableDefault_${VARDEF_SKUID_BOOLEAN};
-${END}
- UINT8 SkuIdTable[${PHASE}_SKUID_TABLE_SIZE];
-${SYSTEM_SKU_ID}
-} ${PHASE}_PCD_DATABASE_INIT;
-
-typedef struct {
-${PCD_DATABASE_UNINIT_EMPTY}
-${BEGIN} UINT64 ${UNINIT_CNAME_DECL_UINT64}_${UNINIT_GUID_DECL_UINT64}[${UNINIT_NUMSKUS_DECL_UINT64}];
-${END}
-${BEGIN} UINT32 ${UNINIT_CNAME_DECL_UINT32}_${UNINIT_GUID_DECL_UINT32}[${UNINIT_NUMSKUS_DECL_UINT32}];
-${END}
-${BEGIN} UINT16 ${UNINIT_CNAME_DECL_UINT16}_${UNINIT_GUID_DECL_UINT16}[${UNINIT_NUMSKUS_DECL_UINT16}];
-${END}
-${BEGIN} UINT8 ${UNINIT_CNAME_DECL_UINT8}_${UNINIT_GUID_DECL_UINT8}[${UNINIT_NUMSKUS_DECL_UINT8}];
-${END}
-${BEGIN} BOOLEAN ${UNINIT_CNAME_DECL_BOOLEAN}_${UNINIT_GUID_DECL_BOOLEAN}[${UNINIT_NUMSKUS_DECL_BOOLEAN}];
-${END}
-} ${PHASE}_PCD_DATABASE_UNINIT;
-
-#define PCD_${PHASE}_SERVICE_DRIVER_VERSION 2
-
-typedef struct {
- ${PHASE}_PCD_DATABASE_INIT Init;
- ${PHASE}_PCD_DATABASE_UNINIT Uninit;
-} ${PHASE}_PCD_DATABASE;
-
-#define ${PHASE}_NEX_TOKEN_NUMBER (${PHASE}_LOCAL_TOKEN_NUMBER - ${PHASE}_EX_TOKEN_NUMBER)
-""")
-
-gEmptyPcdDatabaseAutoGenC = TemplateString("""
-${PHASE}_PCD_DATABASE_INIT g${PHASE}PcdDbInit = {
- /* ExMapTable */
- {
- {0, 0, 0}
- },
- /* LocalTokenNumberTable */
- {
- 0
- },
- /* GuidTable */
- {
- {0x00000000, 0x0000, 0x0000, {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}
- },
- /* StringTable */
- { 0 },
- /* SizeTable */
- {
- 0, 0
- },
- /* SkuIdTable */
- { 0 },
- ${SYSTEM_SKU_ID_VALUE}
-};
-""")
-
-gPcdDatabaseAutoGenC = TemplateString("""
-${PHASE}_PCD_DATABASE_INIT g${PHASE}PcdDbInit = {
-${BEGIN} { ${INIT_VALUE_UINT64} }, /* ${INIT_CNAME_DECL_UINT64}_${INIT_GUID_DECL_UINT64}[${INIT_NUMSKUS_DECL_UINT64}] */
-${END}
-${BEGIN} ${VARDEF_VALUE_UINT64}, /* ${VARDEF_CNAME_UINT64}_${VARDEF_GUID_UINT64}_VariableDefault_${VARDEF_SKUID_UINT64} */
-${END}
-${BEGIN} { ${INIT_VALUE_UINT32} }, /* ${INIT_CNAME_DECL_UINT32}_${INIT_GUID_DECL_UINT32}[${INIT_NUMSKUS_DECL_UINT32}] */
-${END}
-${BEGIN} ${VARDEF_VALUE_UINT32}, /* ${VARDEF_CNAME_UINT32}_${VARDEF_GUID_UINT32}_VariableDefault_${VARDEF_SKUID_UINT32} */
-${END}
- /* VPD */
-${BEGIN} { ${VPD_HEAD_VALUE} }, /* ${VPD_HEAD_CNAME_DECL}_${VPD_HEAD_GUID_DECL}[${VPD_HEAD_NUMSKUS_DECL}] */
-${END}
- /* ExMapTable */
- {
-${BEGIN} { ${EXMAPPING_TABLE_EXTOKEN}, ${EXMAPPING_TABLE_LOCAL_TOKEN}, ${EXMAPPING_TABLE_GUID_INDEX} },
-${END}
- },
- /* LocalTokenNumberTable */
- {
-${BEGIN} offsetof(${PHASE}_PCD_DATABASE, ${TOKEN_INIT}.${TOKEN_CNAME}_${TOKEN_GUID}${VARDEF_HEADER}) | ${TOKEN_TYPE},
-${END}
- },
- /* GuidTable */
- {
-${BEGIN} ${GUID_STRUCTURE},
-${END}
- },
-${BEGIN} { ${STRING_HEAD_VALUE} }, /* ${STRING_HEAD_CNAME_DECL}_${STRING_HEAD_GUID_DECL}[${STRING_HEAD_NUMSKUS_DECL}] */
-${END}
-${BEGIN} /* ${VARIABLE_HEAD_CNAME_DECL}_${VARIABLE_HEAD_GUID_DECL}_Variable_Header[${VARIABLE_HEAD_NUMSKUS_DECL}] */
- {
- ${VARIABLE_HEAD_VALUE}
- },
-${END}
- /* StringTable */
-${BEGIN} ${STRING_TABLE_VALUE}, /* ${STRING_TABLE_CNAME}_${STRING_TABLE_GUID} */
-${END}
- /* SizeTable */
- {
-${BEGIN} ${SIZE_TABLE_MAXIMUM_LENGTH}, ${SIZE_TABLE_CURRENT_LENGTH}, /* ${SIZE_TABLE_CNAME}_${SIZE_TABLE_GUID} */
-${END}
- },
-${BEGIN} { ${INIT_VALUE_UINT16} }, /* ${INIT_CNAME_DECL_UINT16}_${INIT_GUID_DECL_UINT16}[${INIT_NUMSKUS_DECL_UINT16}] */
-${END}
-${BEGIN} ${VARDEF_VALUE_UINT16}, /* ${VARDEF_CNAME_UINT16}_${VARDEF_GUID_UINT16}_VariableDefault_${VARDEF_SKUID_UINT16} */
-${END}
-${BEGIN} { ${INIT_VALUE_UINT8} }, /* ${INIT_CNAME_DECL_UINT8}_${INIT_GUID_DECL_UINT8}[${INIT_NUMSKUS_DECL_UINT8}] */
-${END}
-${BEGIN} ${VARDEF_VALUE_UINT8}, /* ${VARDEF_CNAME_UINT8}_${VARDEF_GUID_UINT8}_VariableDefault_${VARDEF_SKUID_UINT8} */
-${END}
-${BEGIN} { ${INIT_VALUE_BOOLEAN} }, /* ${INIT_CNAME_DECL_BOOLEAN}_${INIT_GUID_DECL_BOOLEAN}[${INIT_NUMSKUS_DECL_BOOLEAN}] */
-${END}
-${BEGIN} ${VARDEF_VALUE_BOOLEAN}, /* ${VARDEF_CNAME_BOOLEAN}_${VARDEF_GUID_BOOLEAN}_VariableDefault_${VARDEF_SKUID_BOOLEAN} */
-${END}
- /* SkuIdTable */
- { ${BEGIN}${SKUID_VALUE}, ${END} },
- ${SYSTEM_SKU_ID_VALUE}
-};
-""")
-
-
## AutoGen File Header Templates
gAutoGenHeaderString = TemplateString("""\
/**
@@ -907,6 +662,76 @@ gModuleTypeHeaderFile = {
"USER_DEFINED" : [gBasicHeaderFile]
}
+## Autogen internal worker macro to define DynamicEx PCD name includes both the TokenSpaceGuidName
+# the TokenName and Guid comparison to avoid define name collisions.
+#
+# @param Info The ModuleAutoGen object
+# @param AutoGenH The TemplateString object for header file
+#
+#
+def DynExPcdTokenNumberMapping(Info, AutoGenH):
+ ExTokenCNameList = []
+ PcdExList = []
+ if Info.IsLibrary:
+ PcdList = Info.LibraryPcdList
+ else:
+ PcdList = Info.ModulePcdList
+ for Pcd in PcdList:
+ if Pcd.Type in gDynamicExPcd:
+ ExTokenCNameList.append(Pcd.TokenCName)
+ PcdExList.append(Pcd)
+ if len(ExTokenCNameList) == 0:
+ return
+ AutoGenH.Append('\n#define COMPAREGUID(Guid1, Guid2) (BOOLEAN)(*(CONST UINT64*)Guid1 == *(CONST UINT64*)Guid2 && *((CONST UINT64*)Guid1 + 1) == *((CONST UINT64*)Guid2 + 1))\n')
+ # AutoGen for each PCD listed in a [PcdEx] section of a Module/Lib INF file.
+ # Auto generate a macro for each TokenName that takes a Guid pointer as a parameter.
+ # Use the Guid pointer to see if it matches any of the token space GUIDs.
+ TokenCNameList = []
+ for TokenCName in ExTokenCNameList:
+ if TokenCName in TokenCNameList:
+ continue
+ Index = 0
+ Count = ExTokenCNameList.count(TokenCName)
+ for Pcd in PcdExList:
+ if Pcd.TokenCName == TokenCName:
+ Index = Index + 1
+ if Index == 1:
+ AutoGenH.Append('\n#define __PCD_%s_ADDR_CMP(GuidPtr) (' % (Pcd.TokenCName))
+ AutoGenH.Append('\\\n (GuidPtr == &%s) ? _PCD_TOKEN_%s_%s:'
+ % (Pcd.TokenSpaceGuidCName, Pcd.TokenSpaceGuidCName, Pcd.TokenCName))
+ else:
+ AutoGenH.Append('\\\n (GuidPtr == &%s) ? _PCD_TOKEN_%s_%s:'
+ % (Pcd.TokenSpaceGuidCName, Pcd.TokenSpaceGuidCName, Pcd.TokenCName))
+ if Index == Count:
+ AutoGenH.Append('0 \\\n )\n')
+ TokenCNameList.append(TokenCName)
+
+ TokenCNameList = []
+ for TokenCName in ExTokenCNameList:
+ if TokenCName in TokenCNameList:
+ continue
+ Index = 0
+ Count = ExTokenCNameList.count(TokenCName)
+ for Pcd in PcdExList:
+ if Pcd.Type in gDynamicExPcd and Pcd.TokenCName == TokenCName:
+ Index = Index + 1
+ if Index == 1:
+ AutoGenH.Append('\n#define __PCD_%s_VAL_CMP(GuidPtr) (' % (Pcd.TokenCName))
+ AutoGenH.Append('\\\n COMPAREGUID (GuidPtr, &%s) ? _PCD_TOKEN_%s_%s:'
+ % (Pcd.TokenSpaceGuidCName, Pcd.TokenSpaceGuidCName, Pcd.TokenCName))
+ else:
+ AutoGenH.Append('\\\n COMPAREGUID (GuidPtr, &%s) ? _PCD_TOKEN_%s_%s:'
+ % (Pcd.TokenSpaceGuidCName, Pcd.TokenSpaceGuidCName, Pcd.TokenCName))
+ if Index == Count:
+ AutoGenH.Append('0 \\\n )\n')
+ # Autogen internal worker macro to compare GUIDs. Guid1 is a pointer to a GUID.
+ # Guid2 is a C name for a GUID. Compare pointers first because optimizing compiler
+ # can do this at build time on CONST GUID pointers and optimize away call to COMPAREGUID().
+ # COMPAREGUID() will only be used if the Guid passed in is local to the module.
+ AutoGenH.Append('#define _PCD_TOKEN_EX_%s(GuidPtr) __PCD_%s_ADDR_CMP(GuidPtr) ? __PCD_%s_ADDR_CMP(GuidPtr) : __PCD_%s_VAL_CMP(GuidPtr) \n'
+ % (Pcd.TokenCName, Pcd.TokenCName, Pcd.TokenCName, Pcd.TokenCName))
+ TokenCNameList.append(TokenCName)
+
## Create code for module PCDs
#
# @param Info The ModuleAutoGen object
@@ -923,13 +748,29 @@ def CreateModulePcdCode(Info, AutoGenC, AutoGenH, Pcd):
PcdTokenName = '_PCD_TOKEN_' + Pcd.TokenCName
if Pcd.Type in gDynamicExPcd:
TokenNumber = int(Pcd.TokenValue, 0)
+ # Add TokenSpaceGuidValue value to PcdTokenName to discriminate the DynamicEx PCDs with
+ # different Guids but same TokenCName
+ PcdExTokenName = '_PCD_TOKEN_' + Pcd.TokenSpaceGuidCName + '_' + Pcd.TokenCName
+ AutoGenH.Append('\n#define %s %dU\n' % (PcdExTokenName, TokenNumber))
else:
if (Pcd.TokenCName, Pcd.TokenSpaceGuidCName) not in PcdTokenNumber:
- EdkLogger.error("build", AUTOGEN_ERROR,
- "No generated token number for %s.%s\n" % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName),
- ExtraData="[%s]" % str(Info))
- TokenNumber = PcdTokenNumber[Pcd.TokenCName, Pcd.TokenSpaceGuidCName]
- AutoGenH.Append('\n#define %s %dU\n' % (PcdTokenName, TokenNumber))
+ # If one of the Source built modules listed in the DSC is not listed in FDF modules,
+ # and the INF lists a PCD can only use the PcdsDynamic access method (it is only
+ # listed in the DEC file that declares the PCD as PcdsDynamic), then build tool will
+ # report warning message notify the PI that they are attempting to build a module
+ # that must be included in a flash image in order to be functional. These Dynamic PCD
+ # will not be added into the Database unless it is used by other modules that are
+ # included in the FDF file.
+ # In this case, just assign an invalid token number to make it pass build.
+ if Pcd.Type in PCD_DYNAMIC_TYPE_LIST:
+ TokenNumber = 0
+ else:
+ EdkLogger.error("build", AUTOGEN_ERROR,
+ "No generated token number for %s.%s\n" % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName),
+ ExtraData="[%s]" % str(Info))
+ else:
+ TokenNumber = PcdTokenNumber[Pcd.TokenCName, Pcd.TokenSpaceGuidCName]
+ AutoGenH.Append('\n#define %s %dU\n' % (PcdTokenName, TokenNumber))
EdkLogger.debug(EdkLogger.DEBUG_3, "Creating code for " + Pcd.TokenCName + "." + Pcd.TokenSpaceGuidCName)
if Pcd.Type not in gItemTypeStringDatabase:
@@ -946,12 +787,33 @@ def CreateModulePcdCode(Info, AutoGenC, AutoGenH, Pcd):
GetModeName = '_PCD_GET_MODE_' + gDatumSizeStringDatabaseH[Pcd.DatumType] + '_' + Pcd.TokenCName
SetModeName = '_PCD_SET_MODE_' + gDatumSizeStringDatabaseH[Pcd.DatumType] + '_' + Pcd.TokenCName
+ PcdExCNameList = []
if Pcd.Type in gDynamicExPcd:
- AutoGenH.Append('#define %s LibPcdGetEx%s(&%s, %s)\n' % (GetModeName, DatumSizeLib, Pcd.TokenSpaceGuidCName, PcdTokenName))
- if Pcd.DatumType == 'VOID*':
- AutoGenH.Append('#define %s(SizeOfBuffer, Buffer) LibPcdSetEx%s(&%s, %s, (SizeOfBuffer), (Buffer))\n' % (SetModeName, DatumSizeLib, Pcd.TokenSpaceGuidCName, PcdTokenName))
+ if Info.IsLibrary:
+ PcdList = Info.LibraryPcdList
else:
- AutoGenH.Append('#define %s(Value) LibPcdSetEx%s(&%s, %s, (Value))\n' % (SetModeName, DatumSizeLib, Pcd.TokenSpaceGuidCName, PcdTokenName))
+ PcdList = Info.ModulePcdList
+ for PcdModule in PcdList:
+ if PcdModule.Type in gDynamicExPcd:
+ PcdExCNameList.append(PcdModule.TokenCName)
+ # Be compatible with the current code which using PcdToken and PcdGet/Set for DynamicEx Pcd.
+ # If only PcdToken and PcdGet/Set used in all Pcds with different CName, it should succeed to build.
+ # If PcdToken and PcdGet/Set used in the Pcds with different Guids but same CName, it should failed to build.
+ if PcdExCNameList.count(Pcd.TokenCName) > 1:
+ AutoGenH.Append('// Disabled the macros, as PcdToken and PcdGet/Set are not allowed in the case that more than one DynamicEx Pcds are different Guids but same CName.\n')
+ AutoGenH.Append('// #define %s %s\n' % (PcdTokenName, PcdExTokenName))
+ AutoGenH.Append('// #define %s LibPcdGetEx%s(&%s, %s)\n' % (GetModeName, DatumSizeLib, Pcd.TokenSpaceGuidCName, PcdTokenName))
+ if Pcd.DatumType == 'VOID*':
+ AutoGenH.Append('// #define %s(SizeOfBuffer, Buffer) LibPcdSetEx%s(&%s, %s, (SizeOfBuffer), (Buffer))\n' % (SetModeName, DatumSizeLib, Pcd.TokenSpaceGuidCName, PcdTokenName))
+ else:
+ AutoGenH.Append('// #define %s(Value) LibPcdSetEx%s(&%s, %s, (Value))\n' % (SetModeName, DatumSizeLib, Pcd.TokenSpaceGuidCName, PcdTokenName))
+ else:
+ AutoGenH.Append('#define %s %s\n' % (PcdTokenName, PcdExTokenName))
+ AutoGenH.Append('#define %s LibPcdGetEx%s(&%s, %s)\n' % (GetModeName, DatumSizeLib, Pcd.TokenSpaceGuidCName, PcdTokenName))
+ if Pcd.DatumType == 'VOID*':
+ AutoGenH.Append('#define %s(SizeOfBuffer, Buffer) LibPcdSetEx%s(&%s, %s, (SizeOfBuffer), (Buffer))\n' % (SetModeName, DatumSizeLib, Pcd.TokenSpaceGuidCName, PcdTokenName))
+ else:
+ AutoGenH.Append('#define %s(Value) LibPcdSetEx%s(&%s, %s, (Value))\n' % (SetModeName, DatumSizeLib, Pcd.TokenSpaceGuidCName, PcdTokenName))
elif Pcd.Type in gDynamicPcd:
AutoGenH.Append('#define %s LibPcdGet%s(%s)\n' % (GetModeName, DatumSizeLib, PcdTokenName))
if Pcd.DatumType == 'VOID*':
@@ -1117,16 +979,30 @@ def CreateLibraryPcdCode(Info, AutoGenC, AutoGenH, Pcd):
PcdTokenNumber = Info.PlatformInfo.PcdTokenNumber
TokenSpaceGuidCName = Pcd.TokenSpaceGuidCName
TokenCName = Pcd.TokenCName
- TokenSpaceGuidValue = Pcd.TokenSpaceGuidValue #Info.GuidList[TokenSpaceGuidCName]
- if (Pcd.TokenCName, Pcd.TokenSpaceGuidCName) not in PcdTokenNumber:
- EdkLogger.error("build", AUTOGEN_ERROR,
- "No generated token number for %s.%s\n" % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName),
- ExtraData="[%s]" % str(Info))
- TokenNumber = PcdTokenNumber[TokenCName, TokenSpaceGuidCName]
-
- # If PCD is DynamicEx, then use TokenNumber declared in DEC file
+ PcdTokenName = '_PCD_TOKEN_' + TokenCName
+ #
+ # Write PCDs
+ #
if Pcd.Type in gDynamicExPcd:
TokenNumber = int(Pcd.TokenValue, 0)
+ else:
+ if (Pcd.TokenCName, Pcd.TokenSpaceGuidCName) not in PcdTokenNumber:
+ # If one of the Source built modules listed in the DSC is not listed in FDF modules,
+ # and the INF lists a PCD can only use the PcdsDynamic access method (it is only
+ # listed in the DEC file that declares the PCD as PcdsDynamic), then build tool will
+ # report warning message notify the PI that they are attempting to build a module
+ # that must be included in a flash image in order to be functional. These Dynamic PCD
+ # will not be added into the Database unless it is used by other modules that are
+ # included in the FDF file.
+ # In this case, just assign an invalid token number to make it pass build.
+ if Pcd.Type in PCD_DYNAMIC_TYPE_LIST:
+ TokenNumber = 0
+ else:
+ EdkLogger.error("build", AUTOGEN_ERROR,
+ "No generated token number for %s.%s\n" % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName),
+ ExtraData="[%s]" % str(Info))
+ else:
+ TokenNumber = PcdTokenNumber[Pcd.TokenCName, Pcd.TokenSpaceGuidCName]
if Pcd.Type not in gItemTypeStringDatabase:
EdkLogger.error("build", AUTOGEN_ERROR,
@@ -1148,23 +1024,40 @@ def CreateLibraryPcdCode(Info, AutoGenC, AutoGenH, Pcd):
if Pcd.DatumType == 'VOID*':
Type = '(VOID *)'
Array = '[]'
-
- AutoGenH.Append('#define _PCD_TOKEN_%s %dU\n' % (TokenCName, TokenNumber))
-
PcdItemType = Pcd.Type
- #if PcdItemType in gDynamicPcd:
- # PcdItemType = TAB_PCDS_FIXED_AT_BUILD
- # if (TokenCName, TokenSpaceGuidCName) in Info.PlatformInfo.Platform.Pcds:
- # PcdItemType = Info.PlatformInfo.Platform.Pcds[TokenCName, TokenSpaceGuidCName].Type
+ PcdExCNameList = []
if PcdItemType in gDynamicExPcd:
- PcdTokenName = '_PCD_TOKEN_' + TokenCName
- AutoGenH.Append('#define %s LibPcdGetEx%s(&%s, %s)\n' % (GetModeName, DatumSizeLib, TokenSpaceGuidCName, PcdTokenName))
- if DatumType == 'VOID*':
- AutoGenH.Append('#define %s(SizeOfBuffer, Buffer) LibPcdSetEx%s(&%s, %s, (SizeOfBuffer), (Buffer))\n' % (SetModeName,DatumSizeLib, TokenSpaceGuidCName, PcdTokenName))
+ PcdExTokenName = '_PCD_TOKEN_' + TokenSpaceGuidCName + '_' + Pcd.TokenCName
+ AutoGenH.Append('\n#define %s %dU\n' % (PcdExTokenName, TokenNumber))
+
+ if Info.IsLibrary:
+ PcdList = Info.LibraryPcdList
+ else:
+ PcdList = Info.ModulePcdList
+ for PcdModule in PcdList:
+ if PcdModule.Type in gDynamicExPcd:
+ PcdExCNameList.append(PcdModule.TokenCName)
+ # Be compatible with the current code which using PcdGet/Set for DynamicEx Pcd.
+ # If only PcdGet/Set used in all Pcds with different CName, it should succeed to build.
+ # If PcdGet/Set used in the Pcds with different Guids but same CName, it should failed to build.
+ if PcdExCNameList.count(Pcd.TokenCName) > 1:
+ AutoGenH.Append('// Disabled the macros, as PcdToken and PcdGet/Set are not allowed in the case that more than one DynamicEx Pcds are different Guids but same CName.\n')
+ AutoGenH.Append('// #define %s %s\n' % (PcdTokenName, PcdExTokenName))
+ AutoGenH.Append('// #define %s LibPcdGetEx%s(&%s, %s)\n' % (GetModeName, DatumSizeLib, Pcd.TokenSpaceGuidCName, PcdTokenName))
+ if Pcd.DatumType == 'VOID*':
+ AutoGenH.Append('// #define %s(SizeOfBuffer, Buffer) LibPcdSetEx%s(&%s, %s, (SizeOfBuffer), (Buffer))\n' % (SetModeName, DatumSizeLib, Pcd.TokenSpaceGuidCName, PcdTokenName))
+ else:
+ AutoGenH.Append('// #define %s(Value) LibPcdSetEx%s(&%s, %s, (Value))\n' % (SetModeName, DatumSizeLib, Pcd.TokenSpaceGuidCName, PcdTokenName))
else:
- AutoGenH.Append('#define %s(Value) LibPcdSetEx%s(&%s, %s, (Value))\n' % (SetModeName, DatumSizeLib, TokenSpaceGuidCName, PcdTokenName))
+ AutoGenH.Append('#define %s %s\n' % (PcdTokenName, PcdExTokenName))
+ AutoGenH.Append('#define %s LibPcdGetEx%s(&%s, %s)\n' % (GetModeName, DatumSizeLib, Pcd.TokenSpaceGuidCName, PcdTokenName))
+ if Pcd.DatumType == 'VOID*':
+ AutoGenH.Append('#define %s(SizeOfBuffer, Buffer) LibPcdSetEx%s(&%s, %s, (SizeOfBuffer), (Buffer))\n' % (SetModeName, DatumSizeLib, Pcd.TokenSpaceGuidCName, PcdTokenName))
+ else:
+ AutoGenH.Append('#define %s(Value) LibPcdSetEx%s(&%s, %s, (Value))\n' % (SetModeName, DatumSizeLib, Pcd.TokenSpaceGuidCName, PcdTokenName))
+ else:
+ AutoGenH.Append('#define _PCD_TOKEN_%s %dU\n' % (TokenCName, TokenNumber))
if PcdItemType in gDynamicPcd:
- PcdTokenName = '_PCD_TOKEN_' + TokenCName
AutoGenH.Append('#define %s LibPcdGet%s(%s)\n' % (GetModeName, DatumSizeLib, PcdTokenName))
if DatumType == 'VOID*':
AutoGenH.Append('#define %s(SizeOfBuffer, Buffer) LibPcdSet%s(%s, (SizeOfBuffer), (Buffer))\n' %(SetModeName, DatumSizeLib, PcdTokenName))
@@ -1172,468 +1065,15 @@ def CreateLibraryPcdCode(Info, AutoGenC, AutoGenH, Pcd):
AutoGenH.Append('#define %s(Value) LibPcdSet%s(%s, (Value))\n' % (SetModeName, DatumSizeLib, PcdTokenName))
if PcdItemType == TAB_PCDS_PATCHABLE_IN_MODULE:
PcdVariableName = '_gPcd_' + gItemTypeStringDatabase[TAB_PCDS_PATCHABLE_IN_MODULE] + '_' + TokenCName
- AutoGenH.Append('extern %s _gPcd_BinaryPatch_%s%s;\n' %(DatumType, TokenCName, Array) )
+ AutoGenH.Append('extern volatile %s _gPcd_BinaryPatch_%s%s;\n' %(DatumType, TokenCName, Array) )
AutoGenH.Append('#define %s %s_gPcd_BinaryPatch_%s\n' %(GetModeName, Type, TokenCName))
AutoGenH.Append('#define %s(Value) (%s = (Value))\n' % (SetModeName, PcdVariableName))
if PcdItemType == TAB_PCDS_FIXED_AT_BUILD or PcdItemType == TAB_PCDS_FEATURE_FLAG:
AutoGenH.Append('extern const %s _gPcd_FixedAtBuild_%s%s;\n' %(DatumType, TokenCName, Array))
- #AutoGenH.Append('#define _PCD_VALUE_%s _gPcd_FixedAtBuild_%s\n' %(TokenCName, TokenCName))
AutoGenH.Append('#define %s %s_gPcd_FixedAtBuild_%s\n' %(GetModeName, Type, TokenCName))
AutoGenH.Append('//#define %s ASSERT(FALSE) // It is not allowed to set value for a FIXED_AT_BUILD PCD\n' % SetModeName)
-## Create code for PCD database in DXE or PEI phase
-#
-# @param Platform The platform object
-# @retval tuple Two TemplateString objects for C code and header file,
-# respectively
-#
-def CreatePcdDatabasePhaseSpecificAutoGen (Platform, Phase):
- AutoGenC = TemplateString()
- AutoGenH = TemplateString()
-
- Dict = {
- 'PHASE' : Phase,
- 'GUID_TABLE_SIZE' : '1U',
- 'STRING_TABLE_SIZE' : '1U',
- 'SKUID_TABLE_SIZE' : '1U',
- 'LOCAL_TOKEN_NUMBER_TABLE_SIZE' : '1U',
- 'LOCAL_TOKEN_NUMBER' : '0U',
- 'EXMAPPING_TABLE_SIZE' : '1U',
- 'EX_TOKEN_NUMBER' : '0U',
- 'SIZE_TABLE_SIZE' : '2U',
- 'GUID_TABLE_EMPTY' : 'TRUE',
- 'STRING_TABLE_EMPTY' : 'TRUE',
- 'SKUID_TABLE_EMPTY' : 'TRUE',
- 'DATABASE_EMPTY' : 'TRUE',
- 'EXMAP_TABLE_EMPTY' : 'TRUE',
- 'PCD_DATABASE_UNINIT_EMPTY' : ' UINT8 dummy; /* PCD_DATABASE_UNINIT is emptry */',
- 'SYSTEM_SKU_ID' : ' SKU_ID SystemSkuId;',
- 'SYSTEM_SKU_ID_VALUE' : '0U'
- }
-
- for DatumType in ['UINT64','UINT32','UINT16','UINT8','BOOLEAN', "VOID*"]:
- Dict['VARDEF_CNAME_' + DatumType] = []
- Dict['VARDEF_GUID_' + DatumType] = []
- Dict['VARDEF_SKUID_' + DatumType] = []
- Dict['VARDEF_VALUE_' + DatumType] = []
- for Init in ['INIT','UNINIT']:
- Dict[Init+'_CNAME_DECL_' + DatumType] = []
- Dict[Init+'_GUID_DECL_' + DatumType] = []
- Dict[Init+'_NUMSKUS_DECL_' + DatumType] = []
- Dict[Init+'_VALUE_' + DatumType] = []
-
- for Type in ['STRING_HEAD','VPD_HEAD','VARIABLE_HEAD']:
- Dict[Type + '_CNAME_DECL'] = []
- Dict[Type + '_GUID_DECL'] = []
- Dict[Type + '_NUMSKUS_DECL'] = []
- Dict[Type + '_VALUE'] = []
-
- Dict['STRING_TABLE_INDEX'] = []
- Dict['STRING_TABLE_LENGTH'] = []
- Dict['STRING_TABLE_CNAME'] = []
- Dict['STRING_TABLE_GUID'] = []
- Dict['STRING_TABLE_VALUE'] = []
-
- Dict['SIZE_TABLE_CNAME'] = []
- Dict['SIZE_TABLE_GUID'] = []
- Dict['SIZE_TABLE_CURRENT_LENGTH'] = []
- Dict['SIZE_TABLE_MAXIMUM_LENGTH'] = []
-
- Dict['EXMAPPING_TABLE_EXTOKEN'] = []
- Dict['EXMAPPING_TABLE_LOCAL_TOKEN'] = []
- Dict['EXMAPPING_TABLE_GUID_INDEX'] = []
-
- Dict['GUID_STRUCTURE'] = []
-
- Dict['SKUID_VALUE'] = []
- Dict['VARDEF_HEADER'] = []
- if Phase == 'DXE':
- Dict['SYSTEM_SKU_ID'] = ''
- Dict['SYSTEM_SKU_ID_VALUE'] = ''
-
- StringTableIndex = 0
- StringTableSize = 0
- NumberOfLocalTokens = 0
- NumberOfPeiLocalTokens = 0
- NumberOfDxeLocalTokens = 0
- NumberOfExTokens = 0
- NumberOfSizeItems = 0
- GuidList = []
-
- for Pcd in Platform.DynamicPcdList:
- CName = Pcd.TokenCName
- TokenSpaceGuidCName = Pcd.TokenSpaceGuidCName
-
- EdkLogger.debug(EdkLogger.DEBUG_3, "PCD: %s %s (%s : %s)" % (CName, TokenSpaceGuidCName, Pcd.Phase, Phase))
- if Pcd.DatumType not in gDatumSizeStringDatabase:
- EdkLogger.error("build", AUTOGEN_ERROR,
- "Unknown datum type [%s] of PCD %s.%s" % (Pcd.DatumType, Pcd.TokenSpaceGuidCName, Pcd.TokenCName),
- ExtraData="[%s]" % str(Platform))
-
- if Pcd.Phase == 'PEI':
- NumberOfPeiLocalTokens += 1
- if Pcd.Phase == 'DXE':
- NumberOfDxeLocalTokens += 1
- if Pcd.Phase != Phase:
- continue
-
- #
- # TODO: need GetGuidValue() definition
- #
- TokenSpaceGuidStructure = Pcd.TokenSpaceGuidValue
- TokenSpaceGuid = GuidStructureStringToGuidValueName(TokenSpaceGuidStructure)
- if Pcd.Type in gDynamicExPcd:
- if TokenSpaceGuid not in GuidList:
- GuidList += [TokenSpaceGuid]
- Dict['GUID_STRUCTURE'].append(TokenSpaceGuidStructure)
- NumberOfExTokens += 1
- ValueList = []
- StringHeadOffsetList = []
- VpdHeadOffsetList = []
- VariableHeadValueList = []
- Pcd.InitString = 'UNINIT'
-
- if Pcd.DatumType == 'VOID*':
- if Pcd.Type not in ["DynamicVpd", "DynamicExVpd"]:
- Pcd.TokenTypeList = ['PCD_TYPE_STRING']
- else:
- Pcd.TokenTypeList = []
- elif Pcd.DatumType == 'BOOLEAN':
- Pcd.TokenTypeList = ['PCD_DATUM_TYPE_UINT8']
- else:
- Pcd.TokenTypeList = ['PCD_DATUM_TYPE_' + Pcd.DatumType]
-
- if len(Pcd.SkuInfoList) > 1:
- Pcd.TokenTypeList += ['PCD_TYPE_SKU_ENABLED']
-
- for SkuName in Pcd.SkuInfoList:
- Sku = Pcd.SkuInfoList[SkuName]
- SkuId = Sku.SkuId
- if SkuId == None or SkuId == '':
- continue
-
- if (SkuId + 'U') not in Dict['SKUID_VALUE']:
- Dict['SKUID_VALUE'].append(SkuId + 'U')
-
- SkuIdIndex = Dict['SKUID_VALUE'].index(SkuId + 'U')
- if len(Sku.VariableName) > 0:
- Pcd.TokenTypeList += ['PCD_TYPE_HII']
- Pcd.InitString = 'INIT'
- VariableNameStructure = StringToArray(Sku.VariableName)
- if VariableNameStructure not in Dict['STRING_TABLE_VALUE']:
- Dict['STRING_TABLE_CNAME'].append(CName)
- Dict['STRING_TABLE_GUID'].append(TokenSpaceGuid)
- if StringTableIndex == 0:
- Dict['STRING_TABLE_INDEX'].append('')
- else:
- Dict['STRING_TABLE_INDEX'].append('_%d' % StringTableIndex)
-
- Dict['STRING_TABLE_LENGTH'].append((len(Sku.VariableName) - 3 + 1) * 2)
- Dict['STRING_TABLE_VALUE'].append(VariableNameStructure)
- StringTableIndex += 1
- StringTableSize += (len(Sku.VariableName) - 3 + 1) * 2
-
- VariableHeadStringIndex = 0
- for Index in range(Dict['STRING_TABLE_VALUE'].index(VariableNameStructure)):
- VariableHeadStringIndex += Dict['STRING_TABLE_LENGTH'][Index]
-
- VariableGuidStructure = Sku.VariableGuidValue
- VariableGuid = GuidStructureStringToGuidValueName(VariableGuidStructure)
- if VariableGuid not in GuidList:
- GuidList += [VariableGuid]
- Dict['GUID_STRUCTURE'].append(VariableGuidStructure)
- VariableHeadGuidIndex = GuidList.index(VariableGuid)
-
- if "PCD_TYPE_STRING" in Pcd.TokenTypeList:
- VariableHeadValueList.append('%dU, offsetof(%s_PCD_DATABASE, Init.%s_%s), %dU, %sU' %
- (VariableHeadStringIndex, Phase, CName, TokenSpaceGuid,
- VariableHeadGuidIndex, Sku.VariableOffset))
- else:
- VariableHeadValueList.append('%dU, offsetof(%s_PCD_DATABASE, Init.%s_%s_VariableDefault_%s), %dU, %sU' %
- (VariableHeadStringIndex, Phase, CName, TokenSpaceGuid, SkuIdIndex,
- VariableHeadGuidIndex, Sku.VariableOffset))
- Dict['VARDEF_CNAME_'+Pcd.DatumType].append(CName)
- Dict['VARDEF_GUID_'+Pcd.DatumType].append(TokenSpaceGuid)
- Dict['VARDEF_SKUID_'+Pcd.DatumType].append(SkuIdIndex)
- if "PCD_TYPE_STRING" in Pcd.TokenTypeList:
- Dict['VARDEF_VALUE_' + Pcd.DatumType].append("%s_%s[%d]" % (Pcd.TokenCName, TokenSpaceGuid, SkuIdIndex))
- else:
- #
- # ULL (for UINT64) or U(other integer type) should be append to avoid
- # warning under linux building environment.
- #
- if Pcd.DatumType == "UINT64":
- Dict['VARDEF_VALUE_'+Pcd.DatumType].append(Sku.HiiDefaultValue + "ULL")
- elif Pcd.DatumType in ("UINT32", "UINT16", "UINT8"):
- Dict['VARDEF_VALUE_'+Pcd.DatumType].append(Sku.HiiDefaultValue + "U")
- elif Pcd.DatumType == "BOOLEAN":
- if Sku.HiiDefaultValue in ["1", "0"]:
- Dict['VARDEF_VALUE_'+Pcd.DatumType].append(Sku.HiiDefaultValue + "U")
- else:
- Dict['VARDEF_VALUE_'+Pcd.DatumType].append(Sku.HiiDefaultValue)
-
- elif Sku.VpdOffset != '':
- Pcd.TokenTypeList += ['PCD_TYPE_VPD']
- Pcd.InitString = 'INIT'
- VpdHeadOffsetList.append(str(Sku.VpdOffset) + 'U')
- continue
-
- if Pcd.DatumType == 'VOID*':
- Pcd.TokenTypeList += ['PCD_TYPE_STRING']
- Pcd.InitString = 'INIT'
- if Sku.HiiDefaultValue != '' and Sku.DefaultValue == '':
- Sku.DefaultValue = Sku.HiiDefaultValue
- if Sku.DefaultValue != '':
- NumberOfSizeItems += 1
- Dict['STRING_TABLE_CNAME'].append(CName)
- Dict['STRING_TABLE_GUID'].append(TokenSpaceGuid)
-
- if StringTableIndex == 0:
- Dict['STRING_TABLE_INDEX'].append('')
- else:
- Dict['STRING_TABLE_INDEX'].append('_%d' % StringTableIndex)
- if Sku.DefaultValue[0] == 'L':
- Size = (len(Sku.DefaultValue) - 3 + 1) * 2
- Dict['STRING_TABLE_VALUE'].append(StringToArray(Sku.DefaultValue))
- elif Sku.DefaultValue[0] == '"':
- Size = len(Sku.DefaultValue) - 2 + 1
- Dict['STRING_TABLE_VALUE'].append(StringToArray(Sku.DefaultValue))
- elif Sku.DefaultValue[0] == '{':
- Size = len(Sku.DefaultValue.replace(',',' ').split())
- Dict['STRING_TABLE_VALUE'].append(Sku.DefaultValue)
-
- StringHeadOffsetList.append(str(StringTableSize) + 'U')
- Dict['SIZE_TABLE_CNAME'].append(CName)
- Dict['SIZE_TABLE_GUID'].append(TokenSpaceGuid)
- Dict['SIZE_TABLE_CURRENT_LENGTH'].append(str(Size) + 'U')
- Dict['SIZE_TABLE_MAXIMUM_LENGTH'].append(str(Pcd.MaxDatumSize) + 'U')
- if Pcd.MaxDatumSize != '':
- MaxDatumSize = int(Pcd.MaxDatumSize, 0)
- if MaxDatumSize < Size:
- EdkLogger.error("build", AUTOGEN_ERROR,
- "The maximum size of VOID* type PCD '%s.%s' is less than its actual size occupied." % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName),
- ExtraData="[%s]" % str(Platform))
- Size = MaxDatumSize
- Dict['STRING_TABLE_LENGTH'].append(Size)
- StringTableIndex += 1
- StringTableSize += (Size)
- else:
- if "PCD_TYPE_HII" not in Pcd.TokenTypeList:
- Pcd.TokenTypeList += ['PCD_TYPE_DATA']
- if Sku.DefaultValue == 'TRUE':
- Pcd.InitString = 'INIT'
- else:
- try:
- if int(Sku.DefaultValue, 0) != 0:
- Pcd.InitString = 'INIT'
- except:
- pass
-
- #
- # For UNIT64 type PCD's value, ULL should be append to avoid
- # warning under linux building environment.
- #
- if Pcd.DatumType == "UINT64":
- ValueList.append(Sku.DefaultValue + "ULL")
- elif Pcd.DatumType in ("UINT32", "UINT16", "UINT8"):
- ValueList.append(Sku.DefaultValue + "U")
- elif Pcd.DatumType == "BOOLEAN":
- if Sku.DefaultValue in ["1", "0"]:
- ValueList.append(Sku.DefaultValue + "U")
- else:
- ValueList.append(Sku.DefaultValue)
-
- Pcd.TokenTypeList = list(set(Pcd.TokenTypeList))
-
-
- if 'PCD_TYPE_HII' in Pcd.TokenTypeList:
- Dict['VARIABLE_HEAD_CNAME_DECL'].append(CName)
- Dict['VARIABLE_HEAD_GUID_DECL'].append(TokenSpaceGuid)
- Dict['VARIABLE_HEAD_NUMSKUS_DECL'].append(len(Pcd.SkuInfoList))
- Dict['VARIABLE_HEAD_VALUE'].append('{ %s }\n' % ' },\n { '.join(VariableHeadValueList))
- Dict['VARDEF_HEADER'].append('_Variable_Header')
- else:
- Dict['VARDEF_HEADER'].append('')
- if 'PCD_TYPE_VPD' in Pcd.TokenTypeList:
- Dict['VPD_HEAD_CNAME_DECL'].append(CName)
- Dict['VPD_HEAD_GUID_DECL'].append(TokenSpaceGuid)
- Dict['VPD_HEAD_NUMSKUS_DECL'].append(len(Pcd.SkuInfoList))
- Dict['VPD_HEAD_VALUE'].append('{ %s }' % ' }, { '.join(VpdHeadOffsetList))
- if 'PCD_TYPE_STRING' in Pcd.TokenTypeList:
- Dict['STRING_HEAD_CNAME_DECL'].append(CName)
- Dict['STRING_HEAD_GUID_DECL'].append(TokenSpaceGuid)
- Dict['STRING_HEAD_NUMSKUS_DECL'].append(len(Pcd.SkuInfoList))
- Dict['STRING_HEAD_VALUE'].append(', '.join(StringHeadOffsetList))
- if 'PCD_TYPE_DATA' in Pcd.TokenTypeList:
- Dict[Pcd.InitString+'_CNAME_DECL_'+Pcd.DatumType].append(CName)
- Dict[Pcd.InitString+'_GUID_DECL_'+Pcd.DatumType].append(TokenSpaceGuid)
- Dict[Pcd.InitString+'_NUMSKUS_DECL_'+Pcd.DatumType].append(len(Pcd.SkuInfoList))
- if Pcd.InitString == 'UNINIT':
- Dict['PCD_DATABASE_UNINIT_EMPTY'] = ''
- else:
- Dict[Pcd.InitString+'_VALUE_'+Pcd.DatumType].append(', '.join(ValueList))
-
- if Phase == 'PEI':
- NumberOfLocalTokens = NumberOfPeiLocalTokens
- if Phase == 'DXE':
- NumberOfLocalTokens = NumberOfDxeLocalTokens
-
- Dict['TOKEN_INIT'] = ['' for x in range(NumberOfLocalTokens)]
- Dict['TOKEN_CNAME'] = ['' for x in range(NumberOfLocalTokens)]
- Dict['TOKEN_GUID'] = ['' for x in range(NumberOfLocalTokens)]
- Dict['TOKEN_TYPE'] = ['' for x in range(NumberOfLocalTokens)]
-
- for Pcd in Platform.DynamicPcdList:
- CName = Pcd.TokenCName
- TokenSpaceGuidCName = Pcd.TokenSpaceGuidCName
- if Pcd.Phase != Phase:
- continue
-
- TokenSpaceGuid = GuidStructureStringToGuidValueName(Pcd.TokenSpaceGuidValue) #(Platform.PackageList, TokenSpaceGuidCName))
- GeneratedTokenNumber = Platform.PcdTokenNumber[CName, TokenSpaceGuidCName] - 1
- if Phase == 'DXE':
- GeneratedTokenNumber -= NumberOfPeiLocalTokens
-
- EdkLogger.debug(EdkLogger.DEBUG_1, "PCD = %s.%s" % (CName, TokenSpaceGuidCName))
- EdkLogger.debug(EdkLogger.DEBUG_1, "phase = %s" % Phase)
- EdkLogger.debug(EdkLogger.DEBUG_1, "GeneratedTokenNumber = %s" % str(GeneratedTokenNumber))
-
- Dict['TOKEN_INIT'][GeneratedTokenNumber] = 'Init'
- if Pcd.InitString == 'UNINIT':
- Dict['TOKEN_INIT'][GeneratedTokenNumber] = 'Uninit'
- Dict['TOKEN_CNAME'][GeneratedTokenNumber] = CName
- Dict['TOKEN_GUID'][GeneratedTokenNumber] = TokenSpaceGuid
- Dict['TOKEN_TYPE'][GeneratedTokenNumber] = ' | '.join(Pcd.TokenTypeList)
-
- Pcd.TokenTypeList = list(set(Pcd.TokenTypeList))
- #
- # Update VARDEF_HEADER
- #
- if 'PCD_TYPE_HII' in Pcd.TokenTypeList:
- Dict['VARDEF_HEADER'][GeneratedTokenNumber] = '_Variable_Header'
- else:
- Dict['VARDEF_HEADER'][GeneratedTokenNumber] = ''
-
-
- if Pcd.Type in gDynamicExPcd:
- Dict['EXMAPPING_TABLE_EXTOKEN'].append(str(Pcd.TokenValue) + 'U')
- if Phase == 'DXE':
- GeneratedTokenNumber += NumberOfPeiLocalTokens
- #
- # Per, PCD architecture specification, PCD Token Number is 1 based and 0 is defined as invalid token number.
- # For each EX type PCD, a PCD Token Number is assigned. When the
- # PCD Driver/PEIM map EX_GUID and EX_TOKEN_NUMBER to the PCD Token Number,
- # the non-EX Protocol/PPI interface can be called to get/set the value. This assumption is made by
- # Pcd Driver/PEIM in MdeModulePkg.
- # Therefore, 1 is added to GeneratedTokenNumber to generate a PCD Token Number before being inserted
- # to the EXMAPPING_TABLE.
- #
- Dict['EXMAPPING_TABLE_LOCAL_TOKEN'].append(str(GeneratedTokenNumber + 1) + 'U')
- Dict['EXMAPPING_TABLE_GUID_INDEX'].append(str(GuidList.index(TokenSpaceGuid)) + 'U')
-
- if GuidList != []:
- Dict['GUID_TABLE_EMPTY'] = 'FALSE'
- Dict['GUID_TABLE_SIZE'] = str(len(GuidList)) + 'U'
- else:
- Dict['GUID_STRUCTURE'] = [GuidStringToGuidStructureString('00000000-0000-0000-0000-000000000000')]
-
- if StringTableIndex == 0:
- Dict['STRING_TABLE_INDEX'].append('')
- Dict['STRING_TABLE_LENGTH'].append(1)
- Dict['STRING_TABLE_CNAME'].append('')
- Dict['STRING_TABLE_GUID'].append('')
- Dict['STRING_TABLE_VALUE'].append('{ 0 }')
- else:
- Dict['STRING_TABLE_EMPTY'] = 'FALSE'
- Dict['STRING_TABLE_SIZE'] = str(StringTableSize) + 'U'
-
- if Dict['SIZE_TABLE_CNAME'] == []:
- Dict['SIZE_TABLE_CNAME'].append('')
- Dict['SIZE_TABLE_GUID'].append('')
- Dict['SIZE_TABLE_CURRENT_LENGTH'].append('0U')
- Dict['SIZE_TABLE_MAXIMUM_LENGTH'].append('0U')
-
- if NumberOfLocalTokens != 0:
- Dict['DATABASE_EMPTY'] = 'FALSE'
- Dict['LOCAL_TOKEN_NUMBER_TABLE_SIZE'] = NumberOfLocalTokens
- Dict['LOCAL_TOKEN_NUMBER'] = NumberOfLocalTokens
-
- if NumberOfExTokens != 0:
- Dict['EXMAP_TABLE_EMPTY'] = 'FALSE'
- Dict['EXMAPPING_TABLE_SIZE'] = str(NumberOfExTokens) + 'U'
- Dict['EX_TOKEN_NUMBER'] = str(NumberOfExTokens) + 'U'
- else:
- Dict['EXMAPPING_TABLE_EXTOKEN'].append('0U')
- Dict['EXMAPPING_TABLE_LOCAL_TOKEN'].append('0U')
- Dict['EXMAPPING_TABLE_GUID_INDEX'].append('0U')
-
- if NumberOfSizeItems != 0:
- Dict['SIZE_TABLE_SIZE'] = str(NumberOfSizeItems * 2) + 'U'
-
- AutoGenH.Append(gPcdDatabaseAutoGenH.Replace(Dict))
- if NumberOfLocalTokens == 0:
- AutoGenC.Append(gEmptyPcdDatabaseAutoGenC.Replace(Dict))
- else:
- #
- # Update Size Table to the right order, it should be same with LocalTokenNumberTable
- #
- SizeCNameTempList = []
- SizeGuidTempList = []
- SizeCurLenTempList = []
- SizeMaxLenTempList = []
- ReOrderFlag = True
-
- if len(Dict['SIZE_TABLE_CNAME']) == 1:
- if not (Dict['SIZE_TABLE_CNAME'][0] and Dict['SIZE_TABLE_GUID'][0]):
- ReOrderFlag = False
-
- if ReOrderFlag:
- for Count in range(len(Dict['TOKEN_CNAME'])):
- for Count1 in range(len(Dict['SIZE_TABLE_CNAME'])):
- if Dict['TOKEN_CNAME'][Count] == Dict['SIZE_TABLE_CNAME'][Count1] and \
- Dict['TOKEN_GUID'][Count] == Dict['SIZE_TABLE_GUID'][Count1]:
- SizeCNameTempList.append(Dict['SIZE_TABLE_CNAME'][Count1])
- SizeGuidTempList.append(Dict['SIZE_TABLE_GUID'][Count1])
- SizeCurLenTempList.append(Dict['SIZE_TABLE_CURRENT_LENGTH'][Count1])
- SizeMaxLenTempList.append(Dict['SIZE_TABLE_MAXIMUM_LENGTH'][Count1])
-
- for Count in range(len(Dict['SIZE_TABLE_CNAME'])):
- Dict['SIZE_TABLE_CNAME'][Count] = SizeCNameTempList[Count]
- Dict['SIZE_TABLE_GUID'][Count] = SizeGuidTempList[Count]
- Dict['SIZE_TABLE_CURRENT_LENGTH'][Count] = SizeCurLenTempList[Count]
- Dict['SIZE_TABLE_MAXIMUM_LENGTH'][Count] = SizeMaxLenTempList[Count]
-
- AutoGenC.Append(gPcdDatabaseAutoGenC.Replace(Dict))
-
- return AutoGenH, AutoGenC
-
-## Create code for PCD database
-#
-# @param Info The ModuleAutoGen object
-# @param AutoGenC The TemplateString object for C code
-# @param AutoGenH The TemplateString object for header file
-#
-def CreatePcdDatabaseCode (Info, AutoGenC, AutoGenH):
- if Info.PcdIsDriver == "":
- return
- if Info.PcdIsDriver not in gPcdPhaseMap:
- EdkLogger.error("build", AUTOGEN_ERROR, "Not supported PcdIsDriver type:%s" % Info.PcdIsDriver,
- ExtraData="[%s]" % str(Info))
-
- AutoGenH.Append(gPcdDatabaseCommonAutoGenH)
- AdditionalAutoGenH, AdditionalAutoGenC = CreatePcdDatabasePhaseSpecificAutoGen (Info.PlatformInfo, 'PEI')
- AutoGenH.Append(AdditionalAutoGenH.String)
-
- Phase = gPcdPhaseMap[Info.PcdIsDriver]
- if Phase == 'PEI':
- AutoGenC.Append(AdditionalAutoGenC.String)
-
- if Phase == 'DXE':
- AdditionalAutoGenH, AdditionalAutoGenC = CreatePcdDatabasePhaseSpecificAutoGen (Info.PlatformInfo, Phase)
- AutoGenH.Append(AdditionalAutoGenH.String)
- AutoGenC.Append(AdditionalAutoGenC.String)
- AutoGenH.Append(gPcdDatabaseEpilogueAutoGenH)
## Create code for library constructor
#
@@ -1920,7 +1360,7 @@ def CreatePcdCode(Info, AutoGenC, AutoGenH):
# Collect Token Space GUIDs used by DynamicEc PCDs
TokenSpaceList = []
for Pcd in Info.ModulePcdList:
- if Pcd.Type in gDynamicExPcd and Pcd.TokenSpaceGuidCName not in TokenSpaceList:
+ if Pcd.Type in gDynamicExPcd and Pcd.TokenSpaceGuidCName not in TokenSpaceList:
TokenSpaceList += [Pcd.TokenSpaceGuidCName]
# Add extern declarations to AutoGen.h if one or more Token Space GUIDs were found
@@ -1938,13 +1378,14 @@ def CreatePcdCode(Info, AutoGenC, AutoGenH):
AutoGenH.Append("\n// PCD definitions\n")
for Pcd in Info.ModulePcdList:
CreateLibraryPcdCode(Info, AutoGenC, AutoGenH, Pcd)
+ DynExPcdTokenNumberMapping (Info, AutoGenH)
else:
if Info.ModulePcdList:
AutoGenH.Append("\n// Definition of PCDs used in this module\n")
AutoGenC.Append("\n// Definition of PCDs used in this module\n")
for Pcd in Info.ModulePcdList:
CreateModulePcdCode(Info, AutoGenC, AutoGenH, Pcd)
-
+ DynExPcdTokenNumberMapping (Info, AutoGenH)
if Info.LibraryPcdList:
AutoGenH.Append("\n// Definition of PCDs used in libraries is in AutoGen.c\n")
AutoGenC.Append("\n// Definition of PCDs used in libraries\n")
diff --git a/BaseTools/Source/Python/AutoGen/GenPcdDb.py b/BaseTools/Source/Python/AutoGen/GenPcdDb.py
new file mode 100644
index 000000000..08719fa73
--- /dev/null
+++ b/BaseTools/Source/Python/AutoGen/GenPcdDb.py
@@ -0,0 +1,1566 @@
+## @file
+# Routines for generating Pcd Database
+#
+# Copyright (c) 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.
+#
+from StringIO import StringIO
+from Common.Misc import *
+from Common.String import StringToArray
+from struct import pack
+
+DATABASE_VERSION = 4
+
+gPcdDatabaseAutoGenC = TemplateString("""
+//
+// External PCD database debug information
+//
+#if 0
+${PHASE}_PCD_DATABASE_INIT g${PHASE}PcdDbInit = {
+${BEGIN} { ${INIT_VALUE_UINT64} }, /* ${INIT_CNAME_DECL_UINT64}_${INIT_GUID_DECL_UINT64}[${INIT_NUMSKUS_DECL_UINT64}] */
+${END}
+${BEGIN} ${VARDEF_VALUE_UINT64}, /* ${VARDEF_CNAME_UINT64}_${VARDEF_GUID_UINT64}_VariableDefault_${VARDEF_SKUID_UINT64} */
+${END}
+${BEGIN} { ${INIT_VALUE_UINT32} }, /* ${INIT_CNAME_DECL_UINT32}_${INIT_GUID_DECL_UINT32}[${INIT_NUMSKUS_DECL_UINT32}] */
+${END}
+${BEGIN} ${VARDEF_VALUE_UINT32}, /* ${VARDEF_CNAME_UINT32}_${VARDEF_GUID_UINT32}_VariableDefault_${VARDEF_SKUID_UINT32} */
+${END}
+ /* VPD */
+${BEGIN} { ${VPD_HEAD_VALUE} }, /* ${VPD_HEAD_CNAME_DECL}_${VPD_HEAD_GUID_DECL}[${VPD_HEAD_NUMSKUS_DECL}] */
+${END}
+ /* ExMapTable */
+ {
+${BEGIN} { ${EXMAPPING_TABLE_EXTOKEN}, ${EXMAPPING_TABLE_LOCAL_TOKEN}, ${EXMAPPING_TABLE_GUID_INDEX} },
+${END}
+ },
+ /* LocalTokenNumberTable */
+ {
+${BEGIN} offsetof(${PHASE}_PCD_DATABASE, ${TOKEN_INIT}.${TOKEN_CNAME}_${TOKEN_GUID}${VARDEF_HEADER}) | ${TOKEN_TYPE},
+${END}
+ },
+ /* GuidTable */
+ {
+${BEGIN} ${GUID_STRUCTURE},
+${END}
+ },
+${BEGIN} { ${STRING_HEAD_VALUE} }, /* ${STRING_HEAD_CNAME_DECL}_${STRING_HEAD_GUID_DECL}[${STRING_HEAD_NUMSKUS_DECL}] */
+${END}
+${BEGIN} /* ${VARIABLE_HEAD_CNAME_DECL}_${VARIABLE_HEAD_GUID_DECL}_Variable_Header[${VARIABLE_HEAD_NUMSKUS_DECL}] */
+ {
+ ${VARIABLE_HEAD_VALUE}
+ },
+${END}
+/* SkuHead */
+ {
+ ${BEGIN} offsetof (${PHASE}_PCD_DATABASE, ${TOKEN_INIT}.${TOKEN_CNAME}_${TOKEN_GUID}${VARDEF_HEADER}) | ${TOKEN_TYPE}, /* */
+ offsetof (${PHASE}_PCD_DATABASE, ${TOKEN_INIT}.SkuHead) /* */
+ ${END}
+ },
+ /* StringTable */
+${BEGIN} ${STRING_TABLE_VALUE}, /* ${STRING_TABLE_CNAME}_${STRING_TABLE_GUID} */
+${END}
+ /* SizeTable */
+ {
+${BEGIN} ${SIZE_TABLE_MAXIMUM_LENGTH}, ${SIZE_TABLE_CURRENT_LENGTH}, /* ${SIZE_TABLE_CNAME}_${SIZE_TABLE_GUID} */
+${END}
+ },
+${BEGIN} { ${INIT_VALUE_UINT16} }, /* ${INIT_CNAME_DECL_UINT16}_${INIT_GUID_DECL_UINT16}[${INIT_NUMSKUS_DECL_UINT16}] */
+${END}
+${BEGIN} ${VARDEF_VALUE_UINT16}, /* ${VARDEF_CNAME_UINT16}_${VARDEF_GUID_UINT16}_VariableDefault_${VARDEF_SKUID_UINT16} */
+${END}
+${BEGIN} { ${INIT_VALUE_UINT8} }, /* ${INIT_CNAME_DECL_UINT8}_${INIT_GUID_DECL_UINT8}[${INIT_NUMSKUS_DECL_UINT8}] */
+${END}
+${BEGIN} ${VARDEF_VALUE_UINT8}, /* ${VARDEF_CNAME_UINT8}_${VARDEF_GUID_UINT8}_VariableDefault_${VARDEF_SKUID_UINT8} */
+${END}
+${BEGIN} { ${INIT_VALUE_BOOLEAN} }, /* ${INIT_CNAME_DECL_BOOLEAN}_${INIT_GUID_DECL_BOOLEAN}[${INIT_NUMSKUS_DECL_BOOLEAN}] */
+${END}
+${BEGIN} ${VARDEF_VALUE_BOOLEAN}, /* ${VARDEF_CNAME_BOOLEAN}_${VARDEF_GUID_BOOLEAN}_VariableDefault_${VARDEF_SKUID_BOOLEAN} */
+${END}
+ /* SkuIdTable */
+ { ${BEGIN}${SKUID_VALUE}, ${END} },
+ ${SYSTEM_SKU_ID_VALUE}
+};
+#endif
+""")
+
+## Mapping between PCD driver type and EFI phase
+gPcdPhaseMap = {
+ "PEI_PCD_DRIVER" : "PEI",
+ "DXE_PCD_DRIVER" : "DXE"
+}
+
+gPcdDatabaseAutoGenH = TemplateString("""
+#define PCD_${PHASE}_SERVICE_DRIVER_VERSION ${SERVICE_DRIVER_VERSION}
+
+//
+// External PCD database debug information
+//
+#if 0
+#define ${PHASE}_GUID_TABLE_SIZE ${GUID_TABLE_SIZE}
+#define ${PHASE}_STRING_TABLE_SIZE ${STRING_TABLE_SIZE}
+#define ${PHASE}_SKUID_TABLE_SIZE ${SKUID_TABLE_SIZE}
+#define ${PHASE}_LOCAL_TOKEN_NUMBER_TABLE_SIZE ${LOCAL_TOKEN_NUMBER_TABLE_SIZE}
+#define ${PHASE}_LOCAL_TOKEN_NUMBER ${LOCAL_TOKEN_NUMBER}
+#define ${PHASE}_EXMAPPING_TABLE_SIZE ${EXMAPPING_TABLE_SIZE}
+#define ${PHASE}_EX_TOKEN_NUMBER ${EX_TOKEN_NUMBER}
+#define ${PHASE}_SIZE_TABLE_SIZE ${SIZE_TABLE_SIZE}
+#define ${PHASE}_SKU_HEAD_SIZE ${SKU_HEAD_SIZE}
+#define ${PHASE}_GUID_TABLE_EMPTY ${GUID_TABLE_EMPTY}
+#define ${PHASE}_STRING_TABLE_EMPTY ${STRING_TABLE_EMPTY}
+#define ${PHASE}_SKUID_TABLE_EMPTY ${SKUID_TABLE_EMPTY}
+#define ${PHASE}_DATABASE_EMPTY ${DATABASE_EMPTY}
+#define ${PHASE}_EXMAP_TABLE_EMPTY ${EXMAP_TABLE_EMPTY}
+
+typedef struct {
+${BEGIN} UINT64 ${INIT_CNAME_DECL_UINT64}_${INIT_GUID_DECL_UINT64}[${INIT_NUMSKUS_DECL_UINT64}];
+${END}
+${BEGIN} UINT64 ${VARDEF_CNAME_UINT64}_${VARDEF_GUID_UINT64}_VariableDefault_${VARDEF_SKUID_UINT64};
+${END}
+${BEGIN} UINT32 ${INIT_CNAME_DECL_UINT32}_${INIT_GUID_DECL_UINT32}[${INIT_NUMSKUS_DECL_UINT32}];
+${END}
+${BEGIN} UINT32 ${VARDEF_CNAME_UINT32}_${VARDEF_GUID_UINT32}_VariableDefault_${VARDEF_SKUID_UINT32};
+${END}
+${BEGIN} VPD_HEAD ${VPD_HEAD_CNAME_DECL}_${VPD_HEAD_GUID_DECL}[${VPD_HEAD_NUMSKUS_DECL}];
+${END}
+ DYNAMICEX_MAPPING ExMapTable[${PHASE}_EXMAPPING_TABLE_SIZE];
+ UINT32 LocalTokenNumberTable[${PHASE}_LOCAL_TOKEN_NUMBER_TABLE_SIZE];
+ GUID GuidTable[${PHASE}_GUID_TABLE_SIZE];
+${BEGIN} STRING_HEAD ${STRING_HEAD_CNAME_DECL}_${STRING_HEAD_GUID_DECL}[${STRING_HEAD_NUMSKUS_DECL}];
+${END}
+${BEGIN} VARIABLE_HEAD ${VARIABLE_HEAD_CNAME_DECL}_${VARIABLE_HEAD_GUID_DECL}_Variable_Header[${VARIABLE_HEAD_NUMSKUS_DECL}];
+${END}
+${BEGIN} SKU_HEAD SkuHead[${PHASE}_SKU_HEAD_SIZE];
+${END}
+${BEGIN} UINT8 StringTable${STRING_TABLE_INDEX}[${STRING_TABLE_LENGTH}]; /* ${STRING_TABLE_CNAME}_${STRING_TABLE_GUID} */
+${END}
+ SIZE_INFO SizeTable[${PHASE}_SIZE_TABLE_SIZE];
+${BEGIN} UINT16 ${INIT_CNAME_DECL_UINT16}_${INIT_GUID_DECL_UINT16}[${INIT_NUMSKUS_DECL_UINT16}];
+${END}
+${BEGIN} UINT16 ${VARDEF_CNAME_UINT16}_${VARDEF_GUID_UINT16}_VariableDefault_${VARDEF_SKUID_UINT16};
+${END}
+${BEGIN} UINT8 ${INIT_CNAME_DECL_UINT8}_${INIT_GUID_DECL_UINT8}[${INIT_NUMSKUS_DECL_UINT8}];
+${END}
+${BEGIN} UINT8 ${VARDEF_CNAME_UINT8}_${VARDEF_GUID_UINT8}_VariableDefault_${VARDEF_SKUID_UINT8};
+${END}
+${BEGIN} BOOLEAN ${INIT_CNAME_DECL_BOOLEAN}_${INIT_GUID_DECL_BOOLEAN}[${INIT_NUMSKUS_DECL_BOOLEAN}];
+${END}
+${BEGIN} BOOLEAN ${VARDEF_CNAME_BOOLEAN}_${VARDEF_GUID_BOOLEAN}_VariableDefault_${VARDEF_SKUID_BOOLEAN};
+${END}
+ UINT8 SkuIdTable[${PHASE}_SKUID_TABLE_SIZE];
+${SYSTEM_SKU_ID}
+} ${PHASE}_PCD_DATABASE_INIT;
+
+typedef struct {
+${PCD_DATABASE_UNINIT_EMPTY}
+${BEGIN} UINT64 ${UNINIT_CNAME_DECL_UINT64}_${UNINIT_GUID_DECL_UINT64}[${UNINIT_NUMSKUS_DECL_UINT64}];
+${END}
+${BEGIN} UINT32 ${UNINIT_CNAME_DECL_UINT32}_${UNINIT_GUID_DECL_UINT32}[${UNINIT_NUMSKUS_DECL_UINT32}];
+${END}
+${BEGIN} UINT16 ${UNINIT_CNAME_DECL_UINT16}_${UNINIT_GUID_DECL_UINT16}[${UNINIT_NUMSKUS_DECL_UINT16}];
+${END}
+${BEGIN} UINT8 ${UNINIT_CNAME_DECL_UINT8}_${UNINIT_GUID_DECL_UINT8}[${UNINIT_NUMSKUS_DECL_UINT8}];
+${END}
+${BEGIN} BOOLEAN ${UNINIT_CNAME_DECL_BOOLEAN}_${UNINIT_GUID_DECL_BOOLEAN}[${UNINIT_NUMSKUS_DECL_BOOLEAN}];
+${END}
+} ${PHASE}_PCD_DATABASE_UNINIT;
+
+typedef struct {
+ //GUID Signature; // PcdDataBaseGuid
+ //UINT32 Length;
+ //UINT32 UninitDataBaseSize;// Total size for PCD those default value with 0.
+ //TABLE_OFFSET LocalTokenNumberTableOffset;
+ //TABLE_OFFSET ExMapTableOffset;
+ //TABLE_OFFSET GuidTableOffset;
+ //TABLE_OFFSET StringTableOffset;
+ //TABLE_OFFSET SizeTableOffset;
+ //TABLE_OFFSET SkuIdTableOffset;
+ //UINT16 LocalTokenCount; // LOCAL_TOKEN_NUMBER for all
+ //UINT16 ExTokenCount; // EX_TOKEN_NUMBER for DynamicEx
+ //UINT16 GuidTableCount; // The Number of Guid in GuidTable
+ //SKU_ID SystemSkuId; // Current SkuId value.
+ //UINT8 Pad;
+ ${PHASE}_PCD_DATABASE_INIT Init;
+ ${PHASE}_PCD_DATABASE_UNINIT Uninit;
+} ${PHASE}_PCD_DATABASE;
+
+#define ${PHASE}_NEX_TOKEN_NUMBER (${PHASE}_LOCAL_TOKEN_NUMBER - ${PHASE}_EX_TOKEN_NUMBER)
+#endif
+""")
+
+
+gEmptyPcdDatabaseAutoGenC = TemplateString("""
+//
+// External PCD database debug information
+//
+#if 0
+${PHASE}_PCD_DATABASE_INIT g${PHASE}PcdDbInit = {
+ /* ExMapTable */
+ {
+ {0, 0, 0}
+ },
+ /* LocalTokenNumberTable */
+ {
+ 0
+ },
+ /* GuidTable */
+ {
+ {0x00000000, 0x0000, 0x0000, {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}
+ },
+ /* StringTable */
+ { 0 },
+ /* SkuHead */
+ {
+ 0, 0
+ },
+ /* SizeTable */
+ {
+ 0, 0
+ },
+ /* SkuIdTable */
+ { 0 },
+ ${SYSTEM_SKU_ID_VALUE}
+};
+#endif
+""")
+
+## PackGuid
+#
+# Pack the GUID value in C structure format into data array
+#
+# @param GuidStructureValue: The GUID value in C structure format
+#
+# @retval Buffer: a data array contains the Guid
+#
+def PackGuid(GuidStructureValue):
+ GuidString = GuidStructureStringToGuidString(GuidStructureValue)
+ Guid = GuidString.split('-')
+ Buffer = pack('=LHHBBBBBBBB',
+ int(Guid[0], 16),
+ int(Guid[1], 16),
+ int(Guid[2], 16),
+ int(Guid[3][-4:-2], 16),
+ int(Guid[3][-2:], 16),
+ int(Guid[4][-12:-10], 16),
+ int(Guid[4][-10:-8], 16),
+ int(Guid[4][-8:-6], 16),
+ int(Guid[4][-6:-4], 16),
+ int(Guid[4][-4:-2], 16),
+ int(Guid[4][-2:], 16)
+ )
+ return Buffer
+
+def toHex(s):
+ lst = []
+ for ch in s:
+ hv = hex(ord(ch)).replace('0x', ' ')
+ if len(hv) == 1:
+ hv = '0'+hv
+ lst.append(hv)
+ if lst:
+ return reduce(lambda x,y:x+y, lst)
+ else:
+ return 'empty'
+## DbItemList
+#
+# The class holds the Pcd database items. ItemSize if not zero should match the item datum type in the C structure.
+# When the structure is changed, remember to check the ItemSize and the related PackStr in PackData()
+# RawDataList is the RawData that may need some kind of calculation or transformation,
+# the DataList corresponds to the data that need to be written to database. If DataList is not present, then RawDataList
+# will be written to the database.
+#
+class DbItemList:
+ def __init__(self, ItemSize, DataList=None, RawDataList=None):
+ if DataList is None:
+ DataList = []
+ if RawDataList is None:
+ RawDataList = []
+ self.ItemSize = ItemSize
+ self.DataList = DataList
+ self.RawDataList = RawDataList
+ self.ListSize = 0
+
+ def GetInterOffset(self, Index):
+ Offset = 0
+ if self.ItemSize == 0:
+ #
+ # Variable length, need to calculate one by one
+ #
+ assert(Index < len(self.RawDataList))
+ for ItemIndex in xrange(Index):
+ Offset += len(self.RawDataList[ItemIndex])
+ else:
+ for Datas in self.RawDataList:
+ Offset = self.ItemSize * Index
+
+ return Offset
+
+ def GetListSize(self):
+ if self.ListSize:
+ return self.ListSize
+ if len(self.RawDataList) == 0:
+ self.ListSize = 0
+ return self.ListSize
+ if self.ItemSize == 0:
+ self.ListSize = self.GetInterOffset(len(self.RawDataList) - 1) + len(self.RawDataList[len(self.RawDataList)-1])
+ else:
+ self.ListSize = self.ItemSize * len(self.RawDataList)
+ return self.ListSize
+
+ def PackData(self):
+ if self.ItemSize == 8:
+ PackStr = "=Q"
+ elif self.ItemSize == 4:
+ PackStr = "=L"
+ elif self.ItemSize == 2:
+ PackStr = "=H"
+ elif self.ItemSize == 1:
+ PackStr = "=B"
+ elif self.ItemSize == 0:
+ PackStr = "=B"
+ elif self.ItemSize == 16:
+ # pack Guid
+ PackStr = ''
+ else:
+ # should not reach here
+ assert(False)
+
+ Buffer = ''
+ for Datas in self.RawDataList:
+ if type(Datas) in (list, tuple):
+ for Data in Datas:
+ if PackStr:
+ Buffer += pack(PackStr, GetIntegerValue(Data))
+ else:
+ Buffer += PackGuid(Data)
+ else:
+ if PackStr:
+ Buffer += pack(PackStr, GetIntegerValue(Datas))
+ else:
+ Buffer += PackGuid(Datas)
+
+ return Buffer
+
+## DbExMapTblItemList
+#
+# The class holds the ExMap table
+#
+class DbExMapTblItemList (DbItemList):
+ def __init__(self, ItemSize, DataList=None, RawDataList=None):
+ if DataList is None:
+ DataList = []
+ if RawDataList is None:
+ RawDataList = []
+ DbItemList.__init__(self, ItemSize, DataList, RawDataList)
+ def PackData(self):
+ Buffer = ''
+ PackStr = "=LHH"
+ for Datas in self.RawDataList:
+ Buffer += pack(PackStr,
+ GetIntegerValue(Datas[0]),
+ GetIntegerValue(Datas[1]),
+ GetIntegerValue(Datas[2]))
+ return Buffer
+
+## DbComItemList
+#
+# The DbComItemList is a special kind of DbItemList in case that the size of the List can not be computed by the
+# ItemSize multiply the ItemCount.
+#
+class DbComItemList (DbItemList):
+ def __init__(self, ItemSize, DataList=None, RawDataList=None):
+ if DataList is None:
+ DataList = []
+ if RawDataList is None:
+ RawDataList = []
+ DbItemList.__init__(self, ItemSize, DataList, RawDataList)
+ def GetInterOffset(self, Index):
+ Offset = 0
+ if self.ItemSize == 0:
+ #
+ # Variable length, need to calculte one by one
+ # The only variable table is stringtable, it is not Composite item, should not reach here
+ #
+ assert(False)
+ else:
+ assert(Index < len(self.RawDataList))
+ for ItemIndex in xrange(Index):
+ Offset += len(self.RawDataList[ItemIndex]) * self.ItemSize
+
+ return Offset
+
+ def GetListSize(self):
+ if self.ListSize:
+ return self.ListSize
+ if self.ItemSize == 0:
+ assert(False)
+ else:
+ if len(self.RawDataList) == 0:
+ self.ListSize = 0
+ else:
+ self.ListSize = self.GetInterOffset(len(self.RawDataList) - 1) + len(self.RawDataList[len(self.RawDataList)-1]) * self.ItemSize
+
+ return self.ListSize
+
+ def PackData(self):
+ if self.ItemSize == 8:
+ PackStr = "=Q"
+ elif self.ItemSize == 4:
+ PackStr = "=L"
+ elif self.ItemSize == 2:
+ PackStr = "=H"
+ elif self.ItemSize == 1:
+ PackStr = "=B"
+ elif self.ItemSize == 0:
+ PackStr = "=B"
+ else:
+ assert(False)
+
+ Buffer = ''
+ for DataList in self.RawDataList:
+ for Data in DataList:
+ if type(Data) in (list, tuple):
+ for SingleData in Data:
+ Buffer += pack(PackStr, GetIntegerValue(SingleData))
+ else:
+ Buffer += pack(PackStr, GetIntegerValue(Data))
+
+ return Buffer
+
+## DbVariableTableItemList
+#
+# The class holds the Variable header value table
+#
+class DbVariableTableItemList (DbComItemList):
+ def __init__(self, ItemSize, DataList=None, RawDataList=None):
+ if DataList is None:
+ DataList = []
+ if RawDataList is None:
+ RawDataList = []
+ DbComItemList.__init__(self, ItemSize, DataList, RawDataList)
+ def PackData(self):
+ PackStr = "=LLHH"
+ Buffer = ''
+ for DataList in self.RawDataList:
+ for Data in DataList:
+ Buffer += pack(PackStr,
+ GetIntegerValue(Data[0]),
+ GetIntegerValue(Data[1]),
+ GetIntegerValue(Data[2]),
+ GetIntegerValue(Data[3]))
+ return Buffer
+
+class DbStringHeadTableItemList(DbItemList):
+ def __init__(self,ItemSize,DataList=None,RawDataList=None):
+ if DataList is None:
+ DataList = []
+ if RawDataList is None:
+ RawDataList = []
+ DbItemList.__init__(self, ItemSize, DataList, RawDataList)
+
+ def GetInterOffset(self, Index):
+ Offset = 0
+ if self.ItemSize == 0:
+ #
+ # Variable length, need to calculate one by one
+ #
+ assert(Index < len(self.RawDataList))
+ for ItemIndex in xrange(Index):
+ Offset += len(self.RawDataList[ItemIndex])
+ else:
+ for innerIndex in range(Index):
+ if type(self.RawDataList[innerIndex]) in (list, tuple):
+ Offset += len(self.RawDataList[innerIndex]) * self.ItemSize
+ else:
+ Offset += self.ItemSize
+
+ return Offset
+
+ def GetListSize(self):
+ if self.ListSize:
+ return self.ListSize
+ if len(self.RawDataList) == 0:
+ self.ListSize = 0
+ return self.ListSize
+ if self.ItemSize == 0:
+ self.ListSize = self.GetInterOffset(len(self.RawDataList) - 1) + len(self.RawDataList[len(self.RawDataList)-1])
+ else:
+ for Datas in self.RawDataList:
+ if type(Datas) in (list, tuple):
+ self.ListSize += len(Datas) * self.ItemSize
+ else:
+ self.ListSize += self.ItemSize
+ return self.ListSize
+
+## DbSkuHeadTableItemList
+#
+# The class holds the Sku header value table
+#
+class DbSkuHeadTableItemList (DbItemList):
+ def __init__(self, ItemSize, DataList=None, RawDataList=None):
+ if DataList is None:
+ DataList = []
+ if RawDataList is None:
+ RawDataList = []
+ DbItemList.__init__(self, ItemSize, DataList, RawDataList)
+ def PackData(self):
+ PackStr = "=LL"
+ Buffer = ''
+ for Data in self.RawDataList:
+ Buffer += pack(PackStr,
+ GetIntegerValue(Data[0]),
+ GetIntegerValue(Data[1]))
+ return Buffer
+
+## DbSizeTableItemList
+#
+# The class holds the size table
+#
+class DbSizeTableItemList (DbItemList):
+ def __init__(self, ItemSize, DataList=None, RawDataList=None):
+ if DataList is None:
+ DataList = []
+ if RawDataList is None:
+ RawDataList = []
+ DbItemList.__init__(self, ItemSize, DataList, RawDataList)
+ def PackData(self):
+ PackStr = "=HH"
+ Buffer = ''
+ for Data in self.RawDataList:
+ Buffer += pack(PackStr,
+ GetIntegerValue(Data[0]),
+ GetIntegerValue(Data[1]))
+ return Buffer
+
+## DbStringItemList
+#
+# The class holds the string table
+#
+class DbStringItemList (DbComItemList):
+ def __init__(self, ItemSize, DataList=None, RawDataList=None, LenList=None):
+ if DataList is None:
+ DataList = []
+ if RawDataList is None:
+ RawDataList = []
+ if LenList is None:
+ LenList = []
+
+ assert(len(RawDataList) == len(LenList))
+ DataList = []
+ # adjust DataList according to the LenList
+ for Index in xrange(len(RawDataList)):
+ Len = LenList[Index]
+ RawDatas = RawDataList[Index]
+ assert(Len >= len(RawDatas))
+ ActualDatas = []
+ for i in xrange(len(RawDatas)):
+ ActualDatas.append(RawDatas[i])
+ for i in xrange(len(RawDatas), Len):
+ ActualDatas.append(0)
+ DataList.append(ActualDatas)
+ self.LenList = LenList
+ DbComItemList.__init__(self, ItemSize, DataList, RawDataList)
+ def GetInterOffset(self, Index):
+ Offset = 0
+
+ assert(Index < len(self.LenList))
+ for ItemIndex in xrange(Index):
+ Offset += self.LenList[ItemIndex]
+
+ return Offset
+
+ def GetListSize(self):
+ if self.ListSize:
+ return self.ListSize
+
+ if len(self.LenList) == 0:
+ self.ListSize = 0
+ else:
+ self.ListSize = self.GetInterOffset(len(self.LenList) - 1) + self.LenList[len(self.LenList)-1]
+
+ return self.ListSize
+
+ def PackData(self):
+ self.RawDataList = self.DataList
+ return DbComItemList.PackData(self)
+
+
+
+## Find the index in two list where the item matches the key separately
+#
+# @param Key1 The key used to search the List1
+# @param List1 The list that Key1 will be searched
+# @param Key2 The key used to search the List2
+# @param List2 The list that Key2 will be searched
+#
+# @retval Index The position inside the list where list1[Index] == Key1 and list2[Index] == Key2
+#
+def GetMatchedIndex(Key1, List1, Key2, List2):
+ StartPos = 0
+ while StartPos < len(List1):
+ Index = List1.index(Key1, StartPos)
+ if List2[Index] == Key2:
+ return Index
+ else:
+ StartPos = Index + 1
+
+ return -1
+
+
+## Get the integer value from string like "14U" or integer like 2
+#
+# @param Input The object that may be either a integer value or a string
+#
+# @retval Value The integer value that the input represents
+#
+def GetIntegerValue(Input):
+ if type(Input) in (int, long):
+ return Input
+ String = Input
+ if String.endswith("U"):
+ String = String[:-1]
+ if String.endswith("ULL"):
+ String = String[:-3]
+ if String.endswith("LL"):
+ String = String[:-2]
+
+ if String.startswith("0x") or String.startswith("0X"):
+ return int(String, 16)
+ elif String == '':
+ return 0
+ else:
+ return int(String)
+
+
+## convert StringArray like {0x36, 0x00, 0x34, 0x00, 0x21, 0x00, 0x36, 0x00, 0x34, 0x00, 0x00, 0x00}
+# to List like [0x36, 0x00, 0x34, 0x00, 0x21, 0x00, 0x36, 0x00, 0x34, 0x00, 0x00, 0x00]
+#
+# @param StringArray A string array like {0x36, 0x00, 0x34, 0x00, 0x21, 0x00, 0x36, 0x00, 0x34, 0x00, 0x00, 0x00}
+#
+# @retval A list object of integer items
+#
+def StringArrayToList(StringArray):
+ StringArray = StringArray[1:-1]
+ StringArray = '[' + StringArray + ']'
+ return eval(StringArray)
+
+
+## Convert TokenType String like "PCD_DATUM_TYPE_UINT32 | PCD_TYPE_HII" to TokenType value
+#
+# @param TokenType A TokenType string like "PCD_DATUM_TYPE_UINT32 | PCD_TYPE_HII"
+#
+# @retval A integer representation of the TokenType
+#
+def GetTokenTypeValue(TokenType):
+ TokenTypeDict = {
+ "PCD_TYPE_SHIFT":28,
+ "PCD_TYPE_DATA":(0x0 << 28),
+ "PCD_TYPE_HII":(0x8 << 28),
+ "PCD_TYPE_VPD":(0x4 << 28),
+ "PCD_TYPE_SKU_ENABLED":(0x2 << 28),
+ "PCD_TYPE_STRING":(0x1 << 28),
+
+ "PCD_DATUM_TYPE_SHIFT":24,
+ "PCD_DATUM_TYPE_POINTER":(0x0 << 24),
+ "PCD_DATUM_TYPE_UINT8":(0x1 << 24),
+ "PCD_DATUM_TYPE_UINT16":(0x2 << 24),
+ "PCD_DATUM_TYPE_UINT32":(0x4 << 24),
+ "PCD_DATUM_TYPE_UINT64":(0x8 << 24),
+
+ "PCD_DATUM_TYPE_SHIFT2":20,
+ "PCD_DATUM_TYPE_UINT8_BOOLEAN":(0x1 << 20 | 0x1 << 24),
+ }
+ return eval(TokenType, TokenTypeDict)
+
+## construct the external Pcd database using data from Dict
+#
+# @param Dict A dictionary contains Pcd related tables
+#
+# @retval Buffer A byte stream of the Pcd database
+#
+def BuildExDataBase(Dict):
+ # init Db items
+ InitValueUint64 = Dict['INIT_DB_VALUE_UINT64']
+ DbInitValueUint64 = DbComItemList(8, RawDataList = InitValueUint64)
+ VardefValueUint64 = Dict['VARDEF_DB_VALUE_UINT64']
+ DbVardefValueUint64 = DbItemList(8, RawDataList = VardefValueUint64)
+ InitValueUint32 = Dict['INIT_DB_VALUE_UINT32']
+ DbInitValueUint32 = DbComItemList(4, RawDataList = InitValueUint32)
+ VardefValueUint32 = Dict['VARDEF_DB_VALUE_UINT32']
+ DbVardefValueUint32 = DbItemList(4, RawDataList = VardefValueUint32)
+ VpdHeadValue = Dict['VPD_DB_VALUE']
+ DbVpdHeadValue = DbComItemList(4, RawDataList = VpdHeadValue)
+ ExMapTable = zip(Dict['EXMAPPING_TABLE_EXTOKEN'], Dict['EXMAPPING_TABLE_LOCAL_TOKEN'], Dict['EXMAPPING_TABLE_GUID_INDEX'])
+ DbExMapTable = DbExMapTblItemList(8, RawDataList = ExMapTable)
+ LocalTokenNumberTable = Dict['LOCAL_TOKEN_NUMBER_DB_VALUE']
+ DbLocalTokenNumberTable = DbItemList(4, RawDataList = LocalTokenNumberTable)
+ GuidTable = Dict['GUID_STRUCTURE']
+ DbGuidTable = DbItemList(16, RawDataList = GuidTable)
+ StringHeadValue = Dict['STRING_DB_VALUE']
+ # DbItemList to DbStringHeadTableItemList
+ DbStringHeadValue = DbStringHeadTableItemList(4, RawDataList = StringHeadValue)
+ VariableTable = Dict['VARIABLE_DB_VALUE']
+ DbVariableTable = DbVariableTableItemList(12, RawDataList = VariableTable)
+ NumberOfSkuEnabledPcd = GetIntegerValue(Dict['SKU_HEAD_SIZE'])
+ Dict['SKUHEAD_TABLE_VALUE'] = [(0,0) for i in xrange(NumberOfSkuEnabledPcd)]
+ SkuTable = Dict['SKUHEAD_TABLE_VALUE'] # Generated later
+ DbSkuTable = DbSkuHeadTableItemList(8, RawDataList = SkuTable)
+ Dict['STRING_TABLE_DB_VALUE'] = [StringArrayToList(x) for x in Dict['STRING_TABLE_VALUE']]
+
+ StringTableValue = Dict['STRING_TABLE_DB_VALUE']
+ # when calcute the offset, should use StringTableLen instead of StringTableValue, as string maxium len may be different with actual len
+ StringTableLen = Dict['STRING_TABLE_LENGTH']
+ DbStringTableLen = DbStringItemList(0, RawDataList = StringTableValue, LenList = StringTableLen)
+
+
+ PcdTokenTable = Dict['PCD_TOKENSPACE']
+ PcdTokenLen = Dict['PCD_TOKENSPACE_LENGTH']
+ PcdTokenTableValue = [StringArrayToList(x) for x in Dict['PCD_TOKENSPACE']]
+ DbPcdTokenTable = DbStringItemList(0, RawDataList = PcdTokenTableValue, LenList = PcdTokenLen)
+
+ PcdCNameTable = Dict['PCD_CNAME']
+ PcdCNameLen = Dict['PCD_CNAME_LENGTH']
+ PcdCNameTableValue = [StringArrayToList(x) for x in Dict['PCD_CNAME']]
+ DbPcdCNameTable = DbStringItemList(0, RawDataList = PcdCNameTableValue, LenList = PcdCNameLen)
+
+ PcdNameOffsetTable = Dict['PCD_NAME_OFFSET']
+ DbPcdNameOffsetTable = DbItemList(4,RawDataList = PcdNameOffsetTable)
+
+ SizeTableValue = zip(Dict['SIZE_TABLE_MAXIMUM_LENGTH'], Dict['SIZE_TABLE_CURRENT_LENGTH'])
+ DbSizeTableValue = DbSizeTableItemList(4, RawDataList = SizeTableValue)
+ InitValueUint16 = Dict['INIT_DB_VALUE_UINT16']
+ DbInitValueUint16 = DbComItemList(2, RawDataList = InitValueUint16)
+ VardefValueUint16 = Dict['VARDEF_DB_VALUE_UINT16']
+ DbVardefValueUint16 = DbItemList(2, RawDataList = VardefValueUint16)
+ InitValueUint8 = Dict['INIT_DB_VALUE_UINT8']
+ DbInitValueUint8 = DbComItemList(1, RawDataList = InitValueUint8)
+ VardefValueUint8 = Dict['VARDEF_DB_VALUE_UINT8']
+ DbVardefValueUint8 = DbItemList(1, RawDataList = VardefValueUint8)
+ InitValueBoolean = Dict['INIT_DB_VALUE_BOOLEAN']
+ DbInitValueBoolean = DbComItemList(1, RawDataList = InitValueBoolean)
+ VardefValueBoolean = Dict['VARDEF_DB_VALUE_BOOLEAN']
+ DbVardefValueBoolean = DbItemList(1, RawDataList = VardefValueBoolean)
+ SkuidValue = Dict['SKUID_VALUE']
+ DbSkuidValue = DbItemList(1, RawDataList = SkuidValue)
+ SkuIndexValue = Dict['SKU_INDEX_VALUE']
+ DbSkuIndexValue = DbItemList(0,RawDataList = SkuIndexValue)
+
+ # Unit Db Items
+ UnInitValueUint64 = Dict['UNINIT_GUID_DECL_UINT64']
+ DbUnInitValueUint64 = DbItemList(8, RawDataList = UnInitValueUint64)
+ UnInitValueUint32 = Dict['UNINIT_GUID_DECL_UINT32']
+ DbUnInitValueUint32 = DbItemList(4, RawDataList = UnInitValueUint32)
+ UnInitValueUint16 = Dict['UNINIT_GUID_DECL_UINT16']
+ DbUnInitValueUint16 = DbItemList(2, RawDataList = UnInitValueUint16)
+ UnInitValueUint8 = Dict['UNINIT_GUID_DECL_UINT8']
+ DbUnInitValueUint8 = DbItemList(1, RawDataList = UnInitValueUint8)
+ UnInitValueBoolean = Dict['UNINIT_GUID_DECL_BOOLEAN']
+ DbUnInitValueBoolean = DbItemList(1, RawDataList = UnInitValueBoolean)
+
+ DbNameTotle = ["InitValueUint64", "VardefValueUint64", "InitValueUint32", "VardefValueUint32", "VpdHeadValue", "ExMapTable",
+ "LocalTokenNumberTable", "GuidTable", "StringHeadValue", "PcdNameOffsetTable","VariableTable","SkuTable", "StringTableLen", "PcdTokenTable", "PcdCNameTable",
+ "SizeTableValue", "InitValueUint16", "VardefValueUint16", "InitValueUint8", "VardefValueUint8", "InitValueBoolean",
+ "VardefValueBoolean", "SkuidValue", "SkuIndexValue","UnInitValueUint64", "UnInitValueUint32", "UnInitValueUint16", "UnInitValueUint8", "UnInitValueBoolean"]
+
+ DbTotal = [InitValueUint64, VardefValueUint64, InitValueUint32, VardefValueUint32, VpdHeadValue, ExMapTable,
+ LocalTokenNumberTable, GuidTable, StringHeadValue, PcdNameOffsetTable,VariableTable,SkuTable, StringTableLen, PcdTokenTable,PcdCNameTable,
+ SizeTableValue, InitValueUint16, VardefValueUint16,InitValueUint8, VardefValueUint8, InitValueBoolean,
+ VardefValueBoolean, SkuidValue, SkuIndexValue, UnInitValueUint64, UnInitValueUint32, UnInitValueUint16, UnInitValueUint8, UnInitValueBoolean]
+ DbItemTotal = [DbInitValueUint64, DbVardefValueUint64, DbInitValueUint32, DbVardefValueUint32, DbVpdHeadValue, DbExMapTable,
+ DbLocalTokenNumberTable, DbGuidTable, DbStringHeadValue, DbPcdNameOffsetTable,DbVariableTable,DbSkuTable, DbStringTableLen, DbPcdTokenTable, DbPcdCNameTable,
+ DbSizeTableValue, DbInitValueUint16, DbVardefValueUint16,DbInitValueUint8, DbVardefValueUint8, DbInitValueBoolean,
+ DbVardefValueBoolean, DbSkuidValue, DbSkuIndexValue, DbUnInitValueUint64, DbUnInitValueUint32, DbUnInitValueUint16, DbUnInitValueUint8, DbUnInitValueBoolean]
+
+ # SkuidValue is the last table in the init table items
+ InitTableNum = DbTotal.index(SkuidValue) + 1 + 1 # +1 is for SkuIndexValue table
+ # The FixedHeader length of the PCD_DATABASE_INIT, from Signature to Pad
+ FixedHeaderLen = 64
+
+ # Get offset of SkuId table in the database
+ SkuIdTableOffset = FixedHeaderLen
+ for DbIndex in xrange(len(DbTotal)):
+ if DbTotal[DbIndex] is SkuidValue:
+ break
+ SkuIdTableOffset += DbItemTotal[DbIndex].GetListSize()
+
+
+ # Get offset of SkuValue table in the database
+ SkuTableOffset = FixedHeaderLen
+ for DbIndex in xrange(len(DbTotal)):
+ if DbTotal[DbIndex] is SkuTable:
+ break
+ SkuTableOffset += DbItemTotal[DbIndex].GetListSize()
+ PcdTokenTableDbOffset = FixedHeaderLen
+ for DbIndex in xrange(len(DbTotal)):
+ if DbTotal[DbIndex] is PcdTokenTable:
+ break
+ PcdTokenTableDbOffset += DbItemTotal[DbIndex].GetListSize()
+
+ PcdCNameTableDbOffset = FixedHeaderLen
+ for DbIndex in xrange(len(DbTotal)):
+ if DbTotal[DbIndex] is PcdCNameTable:
+ break
+ PcdCNameTableDbOffset += DbItemTotal[DbIndex].GetListSize()
+ # Fix up the LocalTokenNumberTable, SkuHeader table
+ SkuHeaderIndex = 0
+ if len(Dict['SKU_INDEX_VALUE']) > 0:
+ SkuIndexIndexTable = [(0) for i in xrange(len(Dict['SKU_INDEX_VALUE']))]
+ SkuIndexIndexTable[0] = 0 #Dict['SKU_INDEX_VALUE'][0][0]
+ for i in range(1,len(Dict['SKU_INDEX_VALUE'])):
+ SkuIndexIndexTable[i] = SkuIndexIndexTable[i-1]+Dict['SKU_INDEX_VALUE'][i-1][0]
+ for (LocalTokenNumberTableIndex, (Offset, Table)) in enumerate(LocalTokenNumberTable):
+ DbIndex = 0
+ DbOffset = FixedHeaderLen
+ for DbIndex in xrange(len(DbTotal)):
+ if DbTotal[DbIndex] is Table:
+ DbOffset += DbItemTotal[DbIndex].GetInterOffset(Offset)
+ break
+ DbOffset += DbItemTotal[DbIndex].GetListSize()
+ else:
+ assert(False)
+
+ TokenTypeValue = Dict['TOKEN_TYPE'][LocalTokenNumberTableIndex]
+ TokenTypeValue = GetTokenTypeValue(TokenTypeValue)
+ LocalTokenNumberTable[LocalTokenNumberTableIndex] = DbOffset|int(TokenTypeValue)
+ # if PCD_TYPE_SKU_ENABLED, then we need to fix up the SkuTable
+
+ SkuIndexTabalOffset = SkuIdTableOffset + Dict['SKUID_VALUE'][0]
+ if (TokenTypeValue & (0x2 << 28)):
+ SkuTable[SkuHeaderIndex] = (DbOffset|int(TokenTypeValue & ~(0x2<<28)), SkuIndexTabalOffset + SkuIndexIndexTable[SkuHeaderIndex])
+ LocalTokenNumberTable[LocalTokenNumberTableIndex] = (SkuTableOffset + SkuHeaderIndex * 8) | int(TokenTypeValue)
+ SkuHeaderIndex += 1
+
+
+ if SkuHeaderIndex == 0:
+ SkuHeaderIndex = 1
+ assert(SkuHeaderIndex == NumberOfSkuEnabledPcd)
+
+ # resolve variable table offset
+ for VariableEntries in VariableTable:
+ for VariableEntryPerSku in VariableEntries:
+ (VariableHeadGuidIndex, VariableHeadStringIndex, SKUVariableOffset, VariableOffset, VariableRefTable) = VariableEntryPerSku[:]
+ DbIndex = 0
+ DbOffset = FixedHeaderLen
+ for DbIndex in xrange(len(DbTotal)):
+ if DbTotal[DbIndex] is VariableRefTable:
+ DbOffset += DbItemTotal[DbIndex].GetInterOffset(VariableOffset)
+ break
+ DbOffset += DbItemTotal[DbIndex].GetListSize()
+ else:
+ assert(False)
+
+ if DbIndex >= InitTableNum:
+ assert(False)
+
+ VariableEntryPerSku[:] = (VariableHeadStringIndex, DbOffset, VariableHeadGuidIndex, SKUVariableOffset)
+
+ # calculate various table offset now
+ DbTotalLength = FixedHeaderLen
+ for DbIndex in xrange(len(DbItemTotal)):
+ if DbItemTotal[DbIndex] is DbLocalTokenNumberTable:
+ LocalTokenNumberTableOffset = DbTotalLength
+ elif DbItemTotal[DbIndex] is DbExMapTable:
+ ExMapTableOffset = DbTotalLength
+ elif DbItemTotal[DbIndex] is DbGuidTable:
+ GuidTableOffset = DbTotalLength
+ elif DbItemTotal[DbIndex] is DbStringTableLen:
+ StringTableOffset = DbTotalLength
+ elif DbItemTotal[DbIndex] is DbSizeTableValue:
+ SizeTableOffset = DbTotalLength
+ elif DbItemTotal[DbIndex] is DbSkuidValue:
+ SkuIdTableOffset = DbTotalLength
+ elif DbItemTotal[DbIndex] is DbPcdNameOffsetTable:
+ DbPcdNameOffset = DbTotalLength
+
+ DbTotalLength += DbItemTotal[DbIndex].GetListSize()
+ if not Dict['PCD_INFO_FLAG']:
+ DbPcdNameOffset = 0
+ LocalTokenCount = GetIntegerValue(Dict['LOCAL_TOKEN_NUMBER'])
+ ExTokenCount = GetIntegerValue(Dict['EX_TOKEN_NUMBER'])
+ GuidTableCount = GetIntegerValue(Dict['GUID_TABLE_SIZE'])
+ SystemSkuId = GetIntegerValue(Dict['SYSTEM_SKU_ID_VALUE'])
+ Pad = 0xDA
+
+ UninitDataBaseSize = 0
+ for Item in (DbUnInitValueUint64, DbUnInitValueUint32, DbUnInitValueUint16, DbUnInitValueUint8, DbUnInitValueBoolean):
+ UninitDataBaseSize += Item.GetListSize()
+
+ # Construct the database buffer
+ Guid = "{0x3c7d193c, 0x682c, 0x4c14, 0xa6, 0x8f, 0x55, 0x2d, 0xea, 0x4f, 0x43, 0x7e}"
+ Guid = StringArrayToList(Guid)
+ Buffer = pack('=LHHBBBBBBBB',
+ Guid[0],
+ Guid[1],
+ Guid[2],
+ Guid[3],
+ Guid[4],
+ Guid[5],
+ Guid[6],
+ Guid[7],
+ Guid[8],
+ Guid[9],
+ Guid[10],
+ )
+
+ b = pack("=L", DATABASE_VERSION)
+ Buffer += b
+
+ b = pack('=L', DbTotalLength - UninitDataBaseSize)
+
+ Buffer += b
+ b = pack('=L', UninitDataBaseSize)
+
+ Buffer += b
+ b = pack('=L', LocalTokenNumberTableOffset)
+
+ Buffer += b
+ b = pack('=L', ExMapTableOffset)
+
+ Buffer += b
+ b = pack('=L', GuidTableOffset)
+
+ Buffer += b
+ b = pack('=L', StringTableOffset)
+
+ Buffer += b
+ b = pack('=L', SizeTableOffset)
+
+ Buffer += b
+ b = pack('=L', SkuIdTableOffset)
+
+ Buffer += b
+ b = pack('=L', DbPcdNameOffset)
+
+ Buffer += b
+ b = pack('=H', LocalTokenCount)
+
+ Buffer += b
+ b = pack('=H', ExTokenCount)
+
+ Buffer += b
+ b = pack('=H', GuidTableCount)
+
+ Buffer += b
+ b = pack('=B', SystemSkuId)
+
+ Buffer += b
+ b = pack('=B', Pad)
+
+ Buffer += b
+
+ Index = 0
+ for Item in DbItemTotal:
+ Index +=1
+ b = Item.PackData()
+ Buffer += b
+ if Index == InitTableNum:
+ break
+ return Buffer
+
+## Create code for PCD database
+#
+# @param Info The ModuleAutoGen object
+# @param AutoGenC The TemplateString object for C code
+# @param AutoGenH The TemplateString object for header file
+#
+def CreatePcdDatabaseCode (Info, AutoGenC, AutoGenH):
+ if Info.PcdIsDriver == "":
+ return
+ if Info.PcdIsDriver not in gPcdPhaseMap:
+ EdkLogger.error("build", AUTOGEN_ERROR, "Not supported PcdIsDriver type:%s" % Info.PcdIsDriver,
+ ExtraData="[%s]" % str(Info))
+
+ AdditionalAutoGenH, AdditionalAutoGenC, PcdDbBuffer = CreatePcdDatabasePhaseSpecificAutoGen (Info.PlatformInfo, 'PEI')
+ AutoGenH.Append(AdditionalAutoGenH.String)
+
+ Phase = gPcdPhaseMap[Info.PcdIsDriver]
+ if Phase == 'PEI':
+ AutoGenC.Append(AdditionalAutoGenC.String)
+
+ if Phase == 'DXE':
+ AdditionalAutoGenH, AdditionalAutoGenC, PcdDbBuffer = CreatePcdDatabasePhaseSpecificAutoGen (Info.PlatformInfo, Phase)
+ AutoGenH.Append(AdditionalAutoGenH.String)
+ AutoGenC.Append(AdditionalAutoGenC.String)
+
+ if Info.IsBinaryModule:
+ DbFileName = os.path.join(Info.PlatformInfo.BuildDir, "FV", Phase + "PcdDataBase.raw")
+ else:
+ DbFileName = os.path.join(Info.OutputDir, Phase + "PcdDataBase.raw")
+ DbFile = StringIO()
+ DbFile.write(PcdDbBuffer)
+ Changed = SaveFileOnChange(DbFileName, DbFile.getvalue(), True)
+
+
+def CArrayToArray(carray):
+ return "{%s, 0x00}" % ", ".join(["0x%02x" % ord(C) for C in carray])
+
+## Create PCD database in DXE or PEI phase
+#
+# @param Platform The platform object
+# @retval tuple Two TemplateString objects for C code and header file,
+# respectively
+#
+def CreatePcdDatabasePhaseSpecificAutoGen (Platform, Phase):
+ AutoGenC = TemplateString()
+ AutoGenH = TemplateString()
+
+ Dict = {
+ 'PHASE' : Phase,
+ 'SERVICE_DRIVER_VERSION' : DATABASE_VERSION,
+ 'GUID_TABLE_SIZE' : '1U',
+ 'STRING_TABLE_SIZE' : '1U',
+ 'SKUID_TABLE_SIZE' : '1U',
+ 'LOCAL_TOKEN_NUMBER_TABLE_SIZE' : '0U',
+ 'LOCAL_TOKEN_NUMBER' : '0U',
+ 'EXMAPPING_TABLE_SIZE' : '1U',
+ 'EX_TOKEN_NUMBER' : '0U',
+ 'SIZE_TABLE_SIZE' : '2U',
+ 'SKU_HEAD_SIZE' : '1U',
+ 'GUID_TABLE_EMPTY' : 'TRUE',
+ 'STRING_TABLE_EMPTY' : 'TRUE',
+ 'SKUID_TABLE_EMPTY' : 'TRUE',
+ 'DATABASE_EMPTY' : 'TRUE',
+ 'EXMAP_TABLE_EMPTY' : 'TRUE',
+ 'PCD_DATABASE_UNINIT_EMPTY' : ' UINT8 dummy; /* PCD_DATABASE_UNINIT is emptry */',
+ 'SYSTEM_SKU_ID' : ' SKU_ID SystemSkuId;',
+ 'SYSTEM_SKU_ID_VALUE' : '0U'
+ }
+
+
+ SkuObj = SkuClass(Platform.Platform.SkuName,Platform.Platform.SkuIds)
+ Dict['SYSTEM_SKU_ID_VALUE'] = Platform.Platform.SkuIds[SkuObj.SystemSkuId]
+
+ Dict['PCD_INFO_FLAG'] = Platform.Platform.PcdInfoFlag
+
+ for DatumType in ['UINT64','UINT32','UINT16','UINT8','BOOLEAN', "VOID*"]:
+ Dict['VARDEF_CNAME_' + DatumType] = []
+ Dict['VARDEF_GUID_' + DatumType] = []
+ Dict['VARDEF_SKUID_' + DatumType] = []
+ Dict['VARDEF_VALUE_' + DatumType] = []
+ Dict['VARDEF_DB_VALUE_' + DatumType] = []
+ for Init in ['INIT','UNINIT']:
+ Dict[Init+'_CNAME_DECL_' + DatumType] = []
+ Dict[Init+'_GUID_DECL_' + DatumType] = []
+ Dict[Init+'_NUMSKUS_DECL_' + DatumType] = []
+ Dict[Init+'_VALUE_' + DatumType] = []
+ Dict[Init+'_DB_VALUE_'+DatumType] = []
+
+ for Type in ['STRING_HEAD','VPD_HEAD','VARIABLE_HEAD']:
+ Dict[Type + '_CNAME_DECL'] = []
+ Dict[Type + '_GUID_DECL'] = []
+ Dict[Type + '_NUMSKUS_DECL'] = []
+ Dict[Type + '_VALUE'] = []
+
+ Dict['STRING_DB_VALUE'] = []
+ Dict['VPD_DB_VALUE'] = []
+ Dict['VARIABLE_DB_VALUE'] = []
+
+ Dict['STRING_TABLE_INDEX'] = []
+ Dict['STRING_TABLE_LENGTH'] = []
+ Dict['STRING_TABLE_CNAME'] = []
+ Dict['STRING_TABLE_GUID'] = []
+ Dict['STRING_TABLE_VALUE'] = []
+ Dict['STRING_TABLE_DB_VALUE'] = []
+
+ Dict['SIZE_TABLE_CNAME'] = []
+ Dict['SIZE_TABLE_GUID'] = []
+ Dict['SIZE_TABLE_CURRENT_LENGTH'] = []
+ Dict['SIZE_TABLE_MAXIMUM_LENGTH'] = []
+
+ Dict['EXMAPPING_TABLE_EXTOKEN'] = []
+ Dict['EXMAPPING_TABLE_LOCAL_TOKEN'] = []
+ Dict['EXMAPPING_TABLE_GUID_INDEX'] = []
+
+ Dict['GUID_STRUCTURE'] = []
+ Dict['SKUID_VALUE'] = [0] # init Dict length
+ Dict['VARDEF_HEADER'] = []
+
+ Dict['LOCAL_TOKEN_NUMBER_DB_VALUE'] = []
+ Dict['VARIABLE_DB_VALUE'] = []
+ Dict['SKUHEAD_TABLE_VALUE'] = []
+ Dict['SKU_INDEX_VALUE'] = []
+
+ Dict['PCD_TOKENSPACE'] = []
+ Dict['PCD_CNAME'] = []
+ Dict['PCD_TOKENSPACE_LENGTH'] = []
+ Dict['PCD_CNAME_LENGTH'] = []
+ Dict['PCD_TOKENSPACE_OFFSET'] = []
+ Dict['PCD_CNAME_OFFSET'] = []
+ Dict['PCD_TOKENSPACE_MAP'] = []
+ Dict['PCD_NAME_OFFSET'] = []
+
+ StringTableIndex = 0
+ StringTableSize = 0
+ NumberOfLocalTokens = 0
+ NumberOfPeiLocalTokens = 0
+ NumberOfDxeLocalTokens = 0
+ NumberOfExTokens = 0
+ NumberOfSizeItems = 0
+ NumberOfSkuEnabledPcd = 0
+ GuidList = []
+ i = 0
+ for Pcd in Platform.DynamicPcdList:
+ i += 1
+ CName = Pcd.TokenCName
+ TokenSpaceGuidCName = Pcd.TokenSpaceGuidCName
+
+ EdkLogger.debug(EdkLogger.DEBUG_3, "PCD: %s %s (%s : %s)" % (CName, TokenSpaceGuidCName, Pcd.Phase, Phase))
+
+ if Pcd.Phase == 'PEI':
+ NumberOfPeiLocalTokens += 1
+ if Pcd.Phase == 'DXE':
+ NumberOfDxeLocalTokens += 1
+ if Pcd.Phase != Phase:
+ continue
+
+ #
+ # TODO: need GetGuidValue() definition
+ #
+ TokenSpaceGuidStructure = Pcd.TokenSpaceGuidValue
+ TokenSpaceGuid = GuidStructureStringToGuidValueName(TokenSpaceGuidStructure)
+ if Pcd.Type in gDynamicExPcd:
+ if TokenSpaceGuid not in GuidList:
+ GuidList += [TokenSpaceGuid]
+ Dict['GUID_STRUCTURE'].append(TokenSpaceGuidStructure)
+ NumberOfExTokens += 1
+
+ ValueList = []
+ DbValueList = []
+ StringHeadOffsetList = []
+ StringDbOffsetList = []
+ VpdHeadOffsetList = []
+ VpdDbOffsetList = []
+ VariableHeadValueList = []
+ VariableDbValueList = []
+ Pcd.InitString = 'UNINIT'
+
+ if Pcd.DatumType == 'VOID*':
+ if Pcd.Type not in ["DynamicVpd", "DynamicExVpd"]:
+ Pcd.TokenTypeList = ['PCD_TYPE_STRING']
+ else:
+ Pcd.TokenTypeList = []
+ elif Pcd.DatumType == 'BOOLEAN':
+ Pcd.TokenTypeList = ['PCD_DATUM_TYPE_UINT8_BOOLEAN']
+ else:
+ Pcd.TokenTypeList = ['PCD_DATUM_TYPE_' + Pcd.DatumType]
+
+ if len(Pcd.SkuInfoList) > 1:
+ Pcd.TokenTypeList += ['PCD_TYPE_SKU_ENABLED']
+ NumberOfSkuEnabledPcd += 1
+
+ SkuIndexTableTmp = []
+ SkuIndexTableTmp.append(0)
+ SkuIdIndex = 1
+ for SkuName in Pcd.SkuInfoList:
+ Sku = Pcd.SkuInfoList[SkuName]
+ SkuId = Sku.SkuId
+ if SkuId == None or SkuId == '':
+ continue
+
+ if (SkuId + 'U') not in Dict['SKUID_VALUE']:
+ Dict['SKUID_VALUE'].append(SkuId + 'U')
+
+ SkuIndexTableTmp.append(SkuId+'U')
+ SkuIdIndex += 1
+
+ if len(Sku.VariableName) > 0:
+ Pcd.TokenTypeList += ['PCD_TYPE_HII']
+ Pcd.InitString = 'INIT'
+ # store VariableName to stringTable and calculate the VariableHeadStringIndex
+ if Sku.VariableName.startswith('{'):
+ VariableNameStructure = CArrayToArray(Sku.VariableName)
+ else:
+ VariableNameStructure = StringToArray(Sku.VariableName)
+ if VariableNameStructure not in Dict['STRING_TABLE_VALUE']:
+ Dict['STRING_TABLE_CNAME'].append(CName)
+ Dict['STRING_TABLE_GUID'].append(TokenSpaceGuid)
+ if StringTableIndex == 0:
+ Dict['STRING_TABLE_INDEX'].append('')
+ else:
+ Dict['STRING_TABLE_INDEX'].append('_%d' % StringTableIndex)
+
+ Dict['STRING_TABLE_LENGTH'].append((len(Sku.VariableName) - 3 + 1) * 2 )
+ Dict['STRING_TABLE_VALUE'].append(VariableNameStructure)
+ StringTableIndex += 1
+ StringTableSize += (len(Sku.VariableName) - 3 + 1) * 2
+ VariableHeadStringIndex = 0
+ for Index in range(Dict['STRING_TABLE_VALUE'].index(VariableNameStructure)):
+ VariableHeadStringIndex += Dict['STRING_TABLE_LENGTH'][Index]
+
+ # store VariableGuid to GuidTable and get the VariableHeadGuidIndex
+ VariableGuidStructure = Sku.VariableGuidValue
+ VariableGuid = GuidStructureStringToGuidValueName(VariableGuidStructure)
+
+ if VariableGuid not in GuidList:
+ GuidList += [VariableGuid]
+ Dict['GUID_STRUCTURE'].append(VariableGuidStructure)
+ VariableHeadGuidIndex = GuidList.index(VariableGuid)
+
+ if "PCD_TYPE_STRING" in Pcd.TokenTypeList:
+ VariableHeadValueList.append('%dU, offsetof(%s_PCD_DATABASE, Init.%s_%s), %dU, %sU' %
+ (VariableHeadStringIndex, Phase, CName, TokenSpaceGuid,
+ VariableHeadGuidIndex, Sku.VariableOffset))
+ else:
+ VariableHeadValueList.append('%dU, offsetof(%s_PCD_DATABASE, Init.%s_%s_VariableDefault_%s), %dU, %sU' %
+ (VariableHeadStringIndex, Phase, CName, TokenSpaceGuid, SkuIdIndex,
+ VariableHeadGuidIndex, Sku.VariableOffset))
+ Dict['VARDEF_CNAME_'+Pcd.DatumType].append(CName)
+ Dict['VARDEF_GUID_'+Pcd.DatumType].append(TokenSpaceGuid)
+ Dict['VARDEF_SKUID_'+Pcd.DatumType].append(SkuIdIndex)
+ if "PCD_TYPE_STRING" in Pcd.TokenTypeList:
+ Dict['VARDEF_VALUE_' + Pcd.DatumType].append("%s_%s[%d]" % (Pcd.TokenCName, TokenSpaceGuid, SkuIdIndex))
+ else:
+ #
+ # ULL (for UINT64) or U(other integer type) should be append to avoid
+ # warning under linux building environment.
+ #
+ Dict['VARDEF_DB_VALUE_'+Pcd.DatumType].append(Sku.HiiDefaultValue)
+
+ if Pcd.DatumType == "UINT64":
+ Dict['VARDEF_VALUE_'+Pcd.DatumType].append(Sku.HiiDefaultValue + "ULL")
+ elif Pcd.DatumType in ("UINT32", "UINT16", "UINT8"):
+ Dict['VARDEF_VALUE_'+Pcd.DatumType].append(Sku.HiiDefaultValue + "U")
+ elif Pcd.DatumType == "BOOLEAN":
+ if eval(Sku.HiiDefaultValue) in [1,0]:
+ Dict['VARDEF_VALUE_'+Pcd.DatumType].append(str(eval(Sku.HiiDefaultValue)) + "U")
+ else:
+ Dict['VARDEF_VALUE_'+Pcd.DatumType].append(Sku.HiiDefaultValue)
+
+ # construct the VariableHeader value
+ if "PCD_TYPE_STRING" in Pcd.TokenTypeList:
+ VariableHeadValueList.append('%dU, %dU, %sU, offsetof(%s_PCD_DATABASE, Init.%s_%s)' %
+ (VariableHeadGuidIndex, VariableHeadStringIndex, Sku.VariableOffset,
+ Phase, CName, TokenSpaceGuid))
+ # the Pcd default value will be filled later on
+ VariableOffset = len(Dict['STRING_DB_VALUE'])
+ VariableRefTable = Dict['STRING_DB_VALUE']
+ else:
+ VariableHeadValueList.append('%dU, %dU, %sU, offsetof(%s_PCD_DATABASE, Init.%s_%s_VariableDefault_%s)' %
+ (VariableHeadGuidIndex, VariableHeadStringIndex, Sku.VariableOffset,
+ Phase, CName, TokenSpaceGuid, SkuIdIndex))
+ # the Pcd default value was filled before
+ VariableOffset = len(Dict['VARDEF_DB_VALUE_' + Pcd.DatumType]) - 1
+ VariableRefTable = Dict['VARDEF_DB_VALUE_' + Pcd.DatumType]
+ VariableDbValueList.append([VariableHeadGuidIndex, VariableHeadStringIndex, Sku.VariableOffset, VariableOffset, VariableRefTable])
+
+ elif Sku.VpdOffset != '':
+ Pcd.TokenTypeList += ['PCD_TYPE_VPD']
+ Pcd.InitString = 'INIT'
+ VpdHeadOffsetList.append(str(Sku.VpdOffset) + 'U')
+ VpdDbOffsetList.append(Sku.VpdOffset)
+ # Also add the VOID* string of VPD PCD to SizeTable
+ if Pcd.DatumType == 'VOID*':
+ NumberOfSizeItems += 1
+ Dict['SIZE_TABLE_CNAME'].append(CName)
+ Dict['SIZE_TABLE_GUID'].append(TokenSpaceGuid)
+ # For VPD type of PCD, its current size is equal to its MAX size.
+ Dict['SIZE_TABLE_CURRENT_LENGTH'].append(str(Pcd.MaxDatumSize) + 'U')
+ Dict['SIZE_TABLE_MAXIMUM_LENGTH'].append(str(Pcd.MaxDatumSize) + 'U')
+ continue
+
+ if Pcd.DatumType == 'VOID*':
+ Pcd.TokenTypeList += ['PCD_TYPE_STRING']
+ Pcd.InitString = 'INIT'
+ if Sku.HiiDefaultValue != '' and Sku.DefaultValue == '':
+ Sku.DefaultValue = Sku.HiiDefaultValue
+ if Sku.DefaultValue != '':
+ NumberOfSizeItems += 1
+ Dict['STRING_TABLE_CNAME'].append(CName)
+ Dict['STRING_TABLE_GUID'].append(TokenSpaceGuid)
+
+ if StringTableIndex == 0:
+ Dict['STRING_TABLE_INDEX'].append('')
+ else:
+ Dict['STRING_TABLE_INDEX'].append('_%d' % StringTableIndex)
+ if Sku.DefaultValue[0] == 'L':
+ Size = (len(Sku.DefaultValue) - 3 + 1) * 2
+ Dict['STRING_TABLE_VALUE'].append(StringToArray(Sku.DefaultValue))
+ elif Sku.DefaultValue[0] == '"':
+ Size = len(Sku.DefaultValue) - 2 + 1
+ Dict['STRING_TABLE_VALUE'].append(StringToArray(Sku.DefaultValue))
+ elif Sku.DefaultValue[0] == '{':
+ Size = len(Sku.DefaultValue.replace(',',' ').split())
+ Dict['STRING_TABLE_VALUE'].append(Sku.DefaultValue)
+
+ StringHeadOffsetList.append(str(StringTableSize) + 'U')
+ StringDbOffsetList.append(StringTableSize)
+ Dict['SIZE_TABLE_CNAME'].append(CName)
+ Dict['SIZE_TABLE_GUID'].append(TokenSpaceGuid)
+ Dict['SIZE_TABLE_CURRENT_LENGTH'].append(str(Size) + 'U')
+ Dict['SIZE_TABLE_MAXIMUM_LENGTH'].append(str(Pcd.MaxDatumSize) + 'U')
+ if Pcd.MaxDatumSize != '':
+ MaxDatumSize = int(Pcd.MaxDatumSize, 0)
+ if MaxDatumSize < Size:
+ MaxDatumSize = Size
+ Size = MaxDatumSize
+ Dict['STRING_TABLE_LENGTH'].append(Size)
+ StringTableIndex += 1
+ StringTableSize += (Size)
+ else:
+ if "PCD_TYPE_HII" not in Pcd.TokenTypeList:
+ Pcd.TokenTypeList += ['PCD_TYPE_DATA']
+ if Sku.DefaultValue == 'TRUE':
+ Pcd.InitString = 'INIT'
+ else:
+ if int(Sku.DefaultValue, 0) != 0:
+ Pcd.InitString = 'INIT'
+ #
+ # For UNIT64 type PCD's value, ULL should be append to avoid
+ # warning under linux building environment.
+ #
+ if Pcd.DatumType == "UINT64":
+ ValueList.append(Sku.DefaultValue + "ULL")
+ elif Pcd.DatumType in ("UINT32", "UINT16", "UINT8"):
+ ValueList.append(Sku.DefaultValue + "U")
+ elif Pcd.DatumType == "BOOLEAN":
+ if Sku.DefaultValue in ["1", "0"]:
+ ValueList.append(Sku.DefaultValue + "U")
+ else:
+ ValueList.append(Sku.DefaultValue)
+
+ DbValueList.append(Sku.DefaultValue)
+
+ Pcd.TokenTypeList = list(set(Pcd.TokenTypeList))
+
+ SkuIndexTableTmp[0] = len(SkuIndexTableTmp)
+ if len(Pcd.SkuInfoList) > 1:
+ Dict['SKU_INDEX_VALUE'].append(SkuIndexTableTmp)
+
+ if 'PCD_TYPE_HII' in Pcd.TokenTypeList:
+ Dict['VARIABLE_HEAD_CNAME_DECL'].append(CName)
+ Dict['VARIABLE_HEAD_GUID_DECL'].append(TokenSpaceGuid)
+ Dict['VARIABLE_HEAD_NUMSKUS_DECL'].append(len(Pcd.SkuInfoList))
+ Dict['VARIABLE_HEAD_VALUE'].append('{ %s }\n' % ' },\n { '.join(VariableHeadValueList))
+ Dict['VARDEF_HEADER'].append('_Variable_Header')
+ Dict['VARIABLE_DB_VALUE'].append(VariableDbValueList)
+ else:
+ Dict['VARDEF_HEADER'].append('')
+ if 'PCD_TYPE_VPD' in Pcd.TokenTypeList:
+ Dict['VPD_HEAD_CNAME_DECL'].append(CName)
+ Dict['VPD_HEAD_GUID_DECL'].append(TokenSpaceGuid)
+ Dict['VPD_HEAD_NUMSKUS_DECL'].append(len(Pcd.SkuInfoList))
+ Dict['VPD_HEAD_VALUE'].append('{ %s }' % ' }, { '.join(VpdHeadOffsetList))
+ Dict['VPD_DB_VALUE'].append(VpdDbOffsetList)
+ if 'PCD_TYPE_STRING' in Pcd.TokenTypeList:
+ Dict['STRING_HEAD_CNAME_DECL'].append(CName)
+ Dict['STRING_HEAD_GUID_DECL'].append(TokenSpaceGuid)
+ Dict['STRING_HEAD_NUMSKUS_DECL'].append(len(Pcd.SkuInfoList))
+ Dict['STRING_HEAD_VALUE'].append(', '.join(StringHeadOffsetList))
+ Dict['STRING_DB_VALUE'].append(StringDbOffsetList)
+ if 'PCD_TYPE_DATA' in Pcd.TokenTypeList:
+ Dict[Pcd.InitString+'_CNAME_DECL_'+Pcd.DatumType].append(CName)
+ Dict[Pcd.InitString+'_GUID_DECL_'+Pcd.DatumType].append(TokenSpaceGuid)
+ Dict[Pcd.InitString+'_NUMSKUS_DECL_'+Pcd.DatumType].append(len(Pcd.SkuInfoList))
+ if Pcd.InitString == 'UNINIT':
+ Dict['PCD_DATABASE_UNINIT_EMPTY'] = ''
+ else:
+ Dict[Pcd.InitString+'_VALUE_'+Pcd.DatumType].append(', '.join(ValueList))
+ Dict[Pcd.InitString+'_DB_VALUE_'+Pcd.DatumType].append(DbValueList)
+
+ if Phase == 'PEI':
+ NumberOfLocalTokens = NumberOfPeiLocalTokens
+ if Phase == 'DXE':
+ NumberOfLocalTokens = NumberOfDxeLocalTokens
+
+ Dict['TOKEN_INIT'] = ['' for x in range(NumberOfLocalTokens)]
+ Dict['TOKEN_CNAME'] = ['' for x in range(NumberOfLocalTokens)]
+ Dict['TOKEN_GUID'] = ['' for x in range(NumberOfLocalTokens)]
+ Dict['TOKEN_TYPE'] = ['' for x in range(NumberOfLocalTokens)]
+ Dict['LOCAL_TOKEN_NUMBER_DB_VALUE'] = ['' for x in range(NumberOfLocalTokens)]
+ Dict['PCD_CNAME'] = ['' for x in range(NumberOfLocalTokens)]
+ Dict['PCD_TOKENSPACE_MAP'] = ['' for x in range(NumberOfLocalTokens)]
+ Dict['PCD_CNAME_LENGTH'] = [0 for x in range(NumberOfLocalTokens)]
+ for Pcd in Platform.DynamicPcdList:
+ CName = Pcd.TokenCName
+ TokenSpaceGuidCName = Pcd.TokenSpaceGuidCName
+ if Pcd.Phase != Phase:
+ continue
+
+ TokenSpaceGuid = GuidStructureStringToGuidValueName(Pcd.TokenSpaceGuidValue) #(Platform.PackageList, TokenSpaceGuidCName))
+ GeneratedTokenNumber = Platform.PcdTokenNumber[CName, TokenSpaceGuidCName] - 1
+ if Phase == 'DXE':
+ GeneratedTokenNumber -= NumberOfPeiLocalTokens
+
+ EdkLogger.debug(EdkLogger.DEBUG_1, "PCD = %s.%s" % (CName, TokenSpaceGuidCName))
+ EdkLogger.debug(EdkLogger.DEBUG_1, "phase = %s" % Phase)
+ EdkLogger.debug(EdkLogger.DEBUG_1, "GeneratedTokenNumber = %s" % str(GeneratedTokenNumber))
+
+ #
+ # following four Dict items hold the information for LocalTokenNumberTable
+ #
+ Dict['TOKEN_INIT'][GeneratedTokenNumber] = 'Init'
+ if Pcd.InitString == 'UNINIT':
+ Dict['TOKEN_INIT'][GeneratedTokenNumber] = 'Uninit'
+
+ Dict['TOKEN_CNAME'][GeneratedTokenNumber] = CName
+ Dict['TOKEN_GUID'][GeneratedTokenNumber] = TokenSpaceGuid
+ Dict['TOKEN_TYPE'][GeneratedTokenNumber] = ' | '.join(Pcd.TokenTypeList)
+
+ if Platform.Platform.PcdInfoFlag:
+ TokenSpaceGuidCNameArray = StringToArray('"' + TokenSpaceGuidCName + '"' )
+ if TokenSpaceGuidCNameArray not in Dict['PCD_TOKENSPACE']:
+ Dict['PCD_TOKENSPACE'].append(TokenSpaceGuidCNameArray)
+ Dict['PCD_TOKENSPACE_LENGTH'].append( len(TokenSpaceGuidCName) + 1 )
+ Dict['PCD_TOKENSPACE_MAP'][GeneratedTokenNumber] = Dict['PCD_TOKENSPACE'].index(TokenSpaceGuidCNameArray)
+ Dict['PCD_CNAME'][GeneratedTokenNumber] = StringToArray('"' + CName + '"' )
+
+ Dict['PCD_CNAME_LENGTH'][GeneratedTokenNumber] = len(CName) + 1
+
+
+ Pcd.TokenTypeList = list(set(Pcd.TokenTypeList))
+
+ # search the Offset and Table, used by LocalTokenNumberTableOffset
+ if 'PCD_TYPE_HII' in Pcd.TokenTypeList:
+ # Find index by CName, TokenSpaceGuid
+ Offset = GetMatchedIndex(CName, Dict['VARIABLE_HEAD_CNAME_DECL'], TokenSpaceGuid, Dict['VARIABLE_HEAD_GUID_DECL'])
+ assert(Offset != -1)
+ Table = Dict['VARIABLE_DB_VALUE']
+ if 'PCD_TYPE_VPD' in Pcd.TokenTypeList:
+ Offset = GetMatchedIndex(CName, Dict['VPD_HEAD_CNAME_DECL'], TokenSpaceGuid, Dict['VPD_HEAD_GUID_DECL'])
+ assert(Offset != -1)
+ Table = Dict['VPD_DB_VALUE']
+ if 'PCD_TYPE_STRING' in Pcd.TokenTypeList and 'PCD_TYPE_HII' not in Pcd.TokenTypeList:
+ # Find index by CName, TokenSpaceGuid
+ Offset = GetMatchedIndex(CName, Dict['STRING_HEAD_CNAME_DECL'], TokenSpaceGuid, Dict['STRING_HEAD_GUID_DECL'])
+ assert(Offset != -1)
+ Table = Dict['STRING_DB_VALUE']
+ if 'PCD_TYPE_DATA' in Pcd.TokenTypeList:
+ # need to store whether it is in init table or not
+ Offset = GetMatchedIndex(CName, Dict[Pcd.InitString+'_CNAME_DECL_'+Pcd.DatumType], TokenSpaceGuid, Dict[Pcd.InitString+'_GUID_DECL_'+Pcd.DatumType])
+ assert(Offset != -1)
+ if Pcd.InitString == 'UNINIT':
+ Table = Dict[Pcd.InitString+'_GUID_DECL_'+Pcd.DatumType]
+ else:
+ Table = Dict[Pcd.InitString+'_DB_VALUE_'+Pcd.DatumType]
+ Dict['LOCAL_TOKEN_NUMBER_DB_VALUE'][GeneratedTokenNumber] = (Offset, Table)
+
+ #
+ # Update VARDEF_HEADER
+ #
+ if 'PCD_TYPE_HII' in Pcd.TokenTypeList:
+ Dict['VARDEF_HEADER'][GeneratedTokenNumber] = '_Variable_Header'
+ else:
+ Dict['VARDEF_HEADER'][GeneratedTokenNumber] = ''
+
+
+ if Pcd.Type in gDynamicExPcd:
+
+ if Phase == 'DXE':
+ GeneratedTokenNumber += NumberOfPeiLocalTokens
+ #
+ # Per, PCD architecture specification, PCD Token Number is 1 based and 0 is defined as invalid token number.
+ # For each EX type PCD, a PCD Token Number is assigned. When the
+ # PCD Driver/PEIM map EX_GUID and EX_TOKEN_NUMBER to the PCD Token Number,
+ # the non-EX Protocol/PPI interface can be called to get/set the value. This assumption is made by
+ # Pcd Driver/PEIM in MdeModulePkg.
+ # Therefore, 1 is added to GeneratedTokenNumber to generate a PCD Token Number before being inserted
+ # to the EXMAPPING_TABLE.
+ #
+
+
+ Dict['EXMAPPING_TABLE_EXTOKEN'].append(str(Pcd.TokenValue) + 'U')
+ Dict['EXMAPPING_TABLE_LOCAL_TOKEN'].append(str(GeneratedTokenNumber + 1) + 'U')
+ Dict['EXMAPPING_TABLE_GUID_INDEX'].append(str(GuidList.index(TokenSpaceGuid)) + 'U')
+
+ if Platform.Platform.PcdInfoFlag:
+ for index in range(len(Dict['PCD_TOKENSPACE_MAP'])):
+ TokenSpaceIndex = StringTableSize
+ for i in range(Dict['PCD_TOKENSPACE_MAP'][index]):
+ TokenSpaceIndex += Dict['PCD_TOKENSPACE_LENGTH'][i]
+ Dict['PCD_TOKENSPACE_OFFSET'].append(TokenSpaceIndex)
+ for index in range(len(Dict['PCD_TOKENSPACE'])):
+ StringTableSize += Dict['PCD_TOKENSPACE_LENGTH'][index]
+
+ for index in range(len(Dict['PCD_CNAME'])):
+ Dict['PCD_CNAME_OFFSET'].append(StringTableSize)
+ Dict['PCD_NAME_OFFSET'].append(Dict['PCD_TOKENSPACE_OFFSET'][index])
+ Dict['PCD_NAME_OFFSET'].append(StringTableSize)
+ StringTableSize += Dict['PCD_CNAME_LENGTH'][index]
+
+ if GuidList != []:
+ Dict['GUID_TABLE_EMPTY'] = 'FALSE'
+ Dict['GUID_TABLE_SIZE'] = str(len(GuidList)) + 'U'
+ else:
+ Dict['GUID_STRUCTURE'] = [GuidStringToGuidStructureString('00000000-0000-0000-0000-000000000000')]
+
+ if StringTableIndex == 0:
+ Dict['STRING_TABLE_INDEX'].append('')
+ Dict['STRING_TABLE_LENGTH'].append(1)
+ Dict['STRING_TABLE_CNAME'].append('')
+ Dict['STRING_TABLE_GUID'].append('')
+ Dict['STRING_TABLE_VALUE'].append('{ 0 }')
+ else:
+ Dict['STRING_TABLE_EMPTY'] = 'FALSE'
+ Dict['STRING_TABLE_SIZE'] = str(StringTableSize) + 'U'
+
+ if Dict['SIZE_TABLE_CNAME'] == []:
+ Dict['SIZE_TABLE_CNAME'].append('')
+ Dict['SIZE_TABLE_GUID'].append('')
+ Dict['SIZE_TABLE_CURRENT_LENGTH'].append('0U')
+ Dict['SIZE_TABLE_MAXIMUM_LENGTH'].append('0U')
+
+ if NumberOfLocalTokens != 0:
+ Dict['DATABASE_EMPTY'] = 'FALSE'
+ Dict['LOCAL_TOKEN_NUMBER_TABLE_SIZE'] = NumberOfLocalTokens
+ Dict['LOCAL_TOKEN_NUMBER'] = NumberOfLocalTokens
+
+ if NumberOfExTokens != 0:
+ Dict['EXMAP_TABLE_EMPTY'] = 'FALSE'
+ Dict['EXMAPPING_TABLE_SIZE'] = str(NumberOfExTokens) + 'U'
+ Dict['EX_TOKEN_NUMBER'] = str(NumberOfExTokens) + 'U'
+ else:
+ Dict['EXMAPPING_TABLE_EXTOKEN'].append('0U')
+ Dict['EXMAPPING_TABLE_LOCAL_TOKEN'].append('0U')
+ Dict['EXMAPPING_TABLE_GUID_INDEX'].append('0U')
+
+ if NumberOfSizeItems != 0:
+ Dict['SIZE_TABLE_SIZE'] = str(NumberOfSizeItems * 2) + 'U'
+
+ if NumberOfSkuEnabledPcd != 0:
+ Dict['SKU_HEAD_SIZE'] = str(NumberOfSkuEnabledPcd) + 'U'
+
+ Dict['SKUID_VALUE'][0] = len(Dict['SKUID_VALUE'])
+
+ AutoGenH.Append(gPcdDatabaseAutoGenH.Replace(Dict))
+ if NumberOfLocalTokens == 0:
+ AutoGenC.Append(gEmptyPcdDatabaseAutoGenC.Replace(Dict))
+ else:
+ #
+ # Update Size Table to the right order, it should be same with LocalTokenNumberTable
+ #
+ SizeCNameTempList = []
+ SizeGuidTempList = []
+ SizeCurLenTempList = []
+ SizeMaxLenTempList = []
+ ReOrderFlag = True
+
+ if len(Dict['SIZE_TABLE_CNAME']) == 1:
+ if not (Dict['SIZE_TABLE_CNAME'][0] and Dict['SIZE_TABLE_GUID'][0]):
+ ReOrderFlag = False
+
+ if ReOrderFlag:
+ for Count in range(len(Dict['TOKEN_CNAME'])):
+ for Count1 in range(len(Dict['SIZE_TABLE_CNAME'])):
+ if Dict['TOKEN_CNAME'][Count] == Dict['SIZE_TABLE_CNAME'][Count1] and \
+ Dict['TOKEN_GUID'][Count] == Dict['SIZE_TABLE_GUID'][Count1]:
+ SizeCNameTempList.append(Dict['SIZE_TABLE_CNAME'][Count1])
+ SizeGuidTempList.append(Dict['SIZE_TABLE_GUID'][Count1])
+ SizeCurLenTempList.append(Dict['SIZE_TABLE_CURRENT_LENGTH'][Count1])
+ SizeMaxLenTempList.append(Dict['SIZE_TABLE_MAXIMUM_LENGTH'][Count1])
+
+ for Count in range(len(Dict['SIZE_TABLE_CNAME'])):
+ Dict['SIZE_TABLE_CNAME'][Count] = SizeCNameTempList[Count]
+ Dict['SIZE_TABLE_GUID'][Count] = SizeGuidTempList[Count]
+ Dict['SIZE_TABLE_CURRENT_LENGTH'][Count] = SizeCurLenTempList[Count]
+ Dict['SIZE_TABLE_MAXIMUM_LENGTH'][Count] = SizeMaxLenTempList[Count]
+
+ AutoGenC.Append(gPcdDatabaseAutoGenC.Replace(Dict))
+
+ Buffer = BuildExDataBase(Dict)
+ return AutoGenH, AutoGenC, Buffer
+
diff --git a/BaseTools/Source/Python/BPDG/GenVpd.py b/BaseTools/Source/Python/BPDG/GenVpd.py
index cc4985062..356457178 100644
--- a/BaseTools/Source/Python/BPDG/GenVpd.py
+++ b/BaseTools/Source/Python/BPDG/GenVpd.py
@@ -34,9 +34,10 @@ _FORMAT_CHAR = {1: 'B',
# This class contain method to format and pack pcd's value.
#
class PcdEntry:
- def __init__(self, PcdCName, PcdOffset, PcdSize, PcdValue, Lineno=None, FileName=None, PcdUnpackValue=None,
+ def __init__(self, PcdCName, SkuId,PcdOffset, PcdSize, PcdValue, Lineno=None, FileName=None, PcdUnpackValue=None,
PcdBinOffset=None, PcdBinSize=None):
self.PcdCName = PcdCName.strip()
+ self.SkuId = SkuId.strip()
self.PcdOffset = PcdOffset.strip()
self.PcdSize = PcdSize.strip()
self.PcdValue = PcdValue.strip()
@@ -284,7 +285,7 @@ class PcdEntry:
"Invalid unicode character %s in unicode string %s(File: %s Line: %s)" % \
(Value, UnicodeString, self.FileName, self.Lineno))
- for Index in range(len(UnicodeString) * 2, Size):
+ for Index in xrange(len(UnicodeString) * 2, Size):
ReturnArray.append(0)
self.PcdValue = ReturnArray.tolist()
@@ -343,7 +344,7 @@ class GenVPD :
#
# Enhanced for support "|" character in the string.
#
- ValueList = ['', '', '', '']
+ ValueList = ['', '', '', '','']
ValueRe = re.compile(r'\s*L?\".*\|.*\"\s*$')
PtrValue = ValueRe.findall(line)
@@ -358,7 +359,7 @@ class GenVPD :
ValueList[0:len(TokenList)] = TokenList
if ValueUpdateFlag:
- ValueList[3] = PtrValue[0]
+ ValueList[4] = PtrValue[0]
self.FileLinesList[count] = ValueList
# Store the line number
self.FileLinesList[count].append(str(count+1))
@@ -393,9 +394,10 @@ class GenVPD :
count = 0
for line in self.FileLinesList:
if line != None :
- PCD = PcdEntry(line[0], line[1], line[2], line[3], line[4], self.InputFileName)
+ PCD = PcdEntry(line[0], line[1], line[2], line[3], line[4],line[5], self.InputFileName)
# Strip the space char
PCD.PcdCName = PCD.PcdCName.strip(' ')
+ PCD.SkuId = PCD.SkuId.strip(' ')
PCD.PcdOffset = PCD.PcdOffset.strip(' ')
PCD.PcdSize = PCD.PcdSize.strip(' ')
PCD.PcdValue = PCD.PcdValue.strip(' ')
@@ -639,7 +641,7 @@ class GenVPD :
for eachPcd in self.PcdFixedOffsetSizeList :
# write map file
try :
- fMapFile.write("%s | %s | %s | %s \n" % (eachPcd.PcdCName, eachPcd.PcdOffset, eachPcd.PcdSize,eachPcd.PcdUnpackValue))
+ fMapFile.write("%s | %s | %s | %s | %s \n" % (eachPcd.PcdCName, eachPcd.SkuId,eachPcd.PcdOffset, eachPcd.PcdSize,eachPcd.PcdUnpackValue))
except:
EdkLogger.error("BPDG", BuildToolError.FILE_WRITE_FAILURE, "Write data to file %s failed, please check whether the file been locked or using by other applications." %self.MapFileName,None)
diff --git a/BaseTools/Source/Python/Common/BuildVersion.py b/BaseTools/Source/Python/Common/BuildVersion.py
index 25546cdfe..2a3b0aa68 100644
--- a/BaseTools/Source/Python/Common/BuildVersion.py
+++ b/BaseTools/Source/Python/Common/BuildVersion.py
@@ -13,4 +13,4 @@
# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#
-gBUILD_VERSION = "Build 2601"
+gBUILD_VERSION = "Build 2610"
diff --git a/BaseTools/Source/Python/Common/DataType.py b/BaseTools/Source/Python/Common/DataType.py
index 3a8236210..dbe7215f4 100644
--- a/BaseTools/Source/Python/Common/DataType.py
+++ b/BaseTools/Source/Python/Common/DataType.py
@@ -397,6 +397,7 @@ TAB_DSC_DEFINES_OUTPUT_DIRECTORY = 'OUTPUT_DIRECTORY'
TAB_DSC_DEFINES_SUPPORTED_ARCHITECTURES = 'SUPPORTED_ARCHITECTURES'
TAB_DSC_DEFINES_BUILD_TARGETS = 'BUILD_TARGETS'
TAB_DSC_DEFINES_SKUID_IDENTIFIER = 'SKUID_IDENTIFIER'
+TAB_DSC_DEFINES_PCD_INFO_GENERATION = 'PCD_INFO_GENERATION'
TAB_DSC_DEFINES_FLASH_DEFINITION = 'FLASH_DEFINITION'
TAB_DSC_DEFINES_BUILD_NUMBER = 'BUILD_NUMBER'
TAB_DSC_DEFINES_MAKEFILE_NAME = 'MAKEFILE_NAME'
diff --git a/BaseTools/Source/Python/Common/GlobalData.py b/BaseTools/Source/Python/Common/GlobalData.py
index d566a5784..4fbe72182 100644
--- a/BaseTools/Source/Python/Common/GlobalData.py
+++ b/BaseTools/Source/Python/Common/GlobalData.py
@@ -50,3 +50,22 @@ gWideStringPattern = re.compile('(\W|\A)L"')
#
gAutoGenPhase = False
+#
+# The Conf dir outside the workspace dir
+#
+gConfDirectory = ''
+
+#
+# The relative default database file path
+#
+gDatabasePath = ".cache/build.db"
+
+#
+# Build flag for binary build
+#
+gIgnoreSource = False
+
+#
+# FDF parser
+#
+gFdfParser = None
diff --git a/BaseTools/Source/Python/Common/Misc.py b/BaseTools/Source/Python/Common/Misc.py
index afdfb93ad..960581581 100644
--- a/BaseTools/Source/Python/Common/Misc.py
+++ b/BaseTools/Source/Python/Common/Misc.py
@@ -31,6 +31,7 @@ from Common import GlobalData as GlobalData
from DataType import *
from BuildToolError import *
from CommonDataClass.DataClass import *
+from Parsing import GetSplitValueList
## Regular expression used to find out place holders in string template
gPlaceholderPattern = re.compile("\$\{([^$()\s]+)\}", re.MULTILINE|re.UNICODE)
@@ -1248,8 +1249,13 @@ def AnalyzeDscPcd(Setting, PcdType, DataType=''):
Size = Type = ''
if len(FieldList) > 1:
Type = FieldList[1]
+ else:
+ Type = DataType
if len(FieldList) > 2:
Size = FieldList[2]
+ else:
+ if Type == 'VOID*':
+ Size = str(len(Value))
if DataType == 'VOID*':
IsValid = (len(FieldList) <= 3)
else:
@@ -1322,25 +1328,13 @@ def AnalyzePcdData(Setting):
#
# @retval ValueList: A List contaian VariableName, VariableGuid, VariableOffset, DefaultValue.
#
-def AnalyzeHiiPcdData(Setting):
- ValueList = ['', '', '', '']
-
- ValueRe = re.compile(r'^\s*L?\".*\|.*\"')
- PtrValue = ValueRe.findall(Setting)
-
- ValueUpdateFlag = False
-
- if len(PtrValue) >= 1:
- Setting = re.sub(ValueRe, '', Setting)
- ValueUpdateFlag = True
+def AnalyzeHiiPcdData(Setting):
+ ValueList = ['', '', '', '']
- TokenList = Setting.split(TAB_VALUE_SPLIT)
+ TokenList = GetSplitValueList(Setting)
ValueList[0:len(TokenList)] = TokenList
-
- if ValueUpdateFlag:
- ValueList[0] = PtrValue[0]
-
- return ValueList
+
+ return ValueList
## AnalyzeVpdPcdData
#
@@ -1679,7 +1673,60 @@ class PeImageClass():
for index in range(len(ByteList) - 1, -1, -1):
Value = (Value << 8) | int(ByteList[index])
return Value
+
+
+class SkuClass():
+
+ DEFAULT = 0
+ SINGLE = 1
+ MULTIPLE =2
+
+ def __init__(self,SkuIdentifier='', SkuIds={}):
+
+ self.AvailableSkuIds = sdict()
+ self.SkuIdSet = []
+
+ if SkuIdentifier == '' or SkuIdentifier is None:
+ self.SkuIdSet = ['DEFAULT']
+ elif SkuIdentifier == 'ALL':
+ self.SkuIdSet = SkuIds.keys()
+ else:
+ r = SkuIdentifier.split('|')
+ self.SkuIdSet=[r[k].strip() for k in range(len(r))]
+ if len(self.SkuIdSet) == 2 and 'DEFAULT' in self.SkuIdSet and SkuIdentifier != 'ALL':
+ self.SkuIdSet.remove('DEFAULT')
+
+ for each in self.SkuIdSet:
+ if each in SkuIds:
+ self.AvailableSkuIds[each] = SkuIds[each]
+ else:
+ EdkLogger.error("build", PARAMETER_INVALID,
+ ExtraData="SKU-ID [%s] is not supported by the platform. [Valid SKU-ID: %s]"
+ % (each, " ".join(SkuIds.keys())))
+ def __SkuUsageType(self):
+
+ if len(self.SkuIdSet) == 1:
+ if self.SkuIdSet[0] == 'DEFAULT':
+ return SkuClass.DEFAULT
+ else:
+ return SkuClass.SINGLE
+ else:
+ return SkuClass.MULTIPLE
+
+ def __GetAvailableSkuIds(self):
+ return self.AvailableSkuIds
+
+ def __GetSystemSkuID(self):
+ if self.__SkuUsageType() == SkuClass.SINGLE:
+ return self.SkuIdSet[0]
+ else:
+ return 'DEFAULT'
+
+ SystemSkuId = property(__GetSystemSkuID)
+ AvailableSkuIdSet = property(__GetAvailableSkuIds)
+ SkuUsageType = property(__SkuUsageType)
+
##
#
# This acts like the main() function for the script, unless it is 'import'ed into another
diff --git a/BaseTools/Source/Python/Common/VpdInfoFile.py b/BaseTools/Source/Python/Common/VpdInfoFile.py
index 207cc8735..18f6f5663 100644
--- a/BaseTools/Source/Python/Common/VpdInfoFile.py
+++ b/BaseTools/Source/Python/Common/VpdInfoFile.py
@@ -138,12 +138,14 @@ class VpdInfoFile:
Pcds = self._VpdArray.keys()
Pcds.sort()
for Pcd in Pcds:
+ i = 0
for Offset in self._VpdArray[Pcd]:
- PcdValue = str(Pcd.SkuInfoList[Pcd.SkuInfoList.keys()[0]].DefaultValue).strip()
+ PcdValue = str(Pcd.SkuInfoList[Pcd.SkuInfoList.keys()[i]].DefaultValue).strip()
if PcdValue == "" :
PcdValue = Pcd.DefaultValue
- fd.write("%s.%s|%s|%s|%s \n" % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName, str(Offset).strip(), str(Pcd.MaxDatumSize).strip(),PcdValue))
+ fd.write("%s.%s|%s|%s|%s|%s \n" % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName, str(Pcd.SkuInfoList.keys()[i]),str(Offset).strip(), str(Pcd.MaxDatumSize).strip(),PcdValue))
+ i += 1
except:
EdkLogger.error("VpdInfoFile",
BuildToolError.FILE_WRITE_FAILURE,
@@ -174,21 +176,22 @@ class VpdInfoFile:
# the line must follow output format defined in BPDG spec.
#
try:
- PcdName, Offset, Size, Value = Line.split("#")[0].split("|")
+ PcdName, SkuId,Offset, Size, Value = Line.split("#")[0].split("|")
+ PcdName, SkuId,Offset, Size, Value = PcdName.strip(), SkuId.strip(),Offset.strip(), Size.strip(), Value.strip()
TokenSpaceName, PcdTokenName = PcdName.split(".")
except:
EdkLogger.error("BPDG", BuildToolError.PARSER_ERROR, "Fail to parse VPD information file %s" % FilePath)
Found = False
+
for VpdObject in self._VpdArray.keys():
- if VpdObject.TokenSpaceGuidCName == TokenSpaceName and VpdObject.TokenCName == PcdTokenName.strip():
- if self._VpdArray[VpdObject][0] == "*":
- if Offset == "*":
- EdkLogger.error("BPDG", BuildToolError.FORMAT_INVALID, "The offset of %s has not been fixed up by third-party BPDG tool." % PcdName)
-
- self._VpdArray[VpdObject][0] = Offset
- Found = True
- break
+ for sku in VpdObject.SkuInfoList.keys():
+ if VpdObject.TokenSpaceGuidCName == TokenSpaceName and VpdObject.TokenCName == PcdTokenName.strip() and sku == SkuId:
+ if self._VpdArray[VpdObject][VpdObject.SkuInfoList.keys().index(sku)] == "*":
+ if Offset == "*":
+ EdkLogger.error("BPDG", BuildToolError.FORMAT_INVALID, "The offset of %s has not been fixed up by third-party BPDG tool." % PcdName)
+ self._VpdArray[VpdObject][VpdObject.SkuInfoList.keys().index(sku)] = Offset
+ Found = True
if not Found:
EdkLogger.error("BPDG", BuildToolError.PARSER_ERROR, "Can not find PCD defined in VPD guid file.")
diff --git a/BaseTools/Source/Python/CommonDataClass/DataClass.py b/BaseTools/Source/Python/CommonDataClass/DataClass.py
index 3d971c84c..c69152b9b 100644
--- a/BaseTools/Source/Python/CommonDataClass/DataClass.py
+++ b/BaseTools/Source/Python/CommonDataClass/DataClass.py
@@ -77,6 +77,7 @@ MODEL_PCD_DYNAMIC_DEFAULT = 4009
MODEL_PCD_DYNAMIC_VPD = 4010
MODEL_PCD_DYNAMIC_HII = 4011
+MODEL_META_DATA_HEADER_COMMENT = 5000
MODEL_META_DATA_HEADER = 5001
MODEL_META_DATA_INCLUDE = 5002
MODEL_META_DATA_DEFINE = 5003
diff --git a/BaseTools/Source/Python/CommonDataClass/FdfClass.py b/BaseTools/Source/Python/CommonDataClass/FdfClass.py
index 996468d6a..ce3df1205 100644
--- a/BaseTools/Source/Python/CommonDataClass/FdfClass.py
+++ b/BaseTools/Source/Python/CommonDataClass/FdfClass.py
@@ -1,7 +1,7 @@
## @file
# classes represent data in FDF
#
-# Copyright (c) 2007 - 2010, Intel Corporation. All rights reserved.<BR>
+# 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
@@ -27,7 +27,7 @@ class FDClassObject:
self.BaseAddressPcd = None
self.Size = None
self.SizePcd = None
- self.ErasePolarity = '1'
+ self.ErasePolarity = None
# 3-tuple list (blockSize, numBlocks, pcd)
self.BlockSizeList = []
# DefineVarDict[var] = value
diff --git a/BaseTools/Source/Python/Ecc/MetaFileWorkspace/MetaFileParser.py b/BaseTools/Source/Python/Ecc/MetaFileWorkspace/MetaFileParser.py
index d10265e97..98a899e76 100644
--- a/BaseTools/Source/Python/Ecc/MetaFileWorkspace/MetaFileParser.py
+++ b/BaseTools/Source/Python/Ecc/MetaFileWorkspace/MetaFileParser.py
@@ -719,6 +719,7 @@ class DscParser(MetaFileParser):
"PLATFORM_GUID",
"PLATFORM_VERSION",
"SKUID_IDENTIFIER",
+ "PCD_INFO_GENERATION",
"SUPPORTED_ARCHITECTURES",
"BUILD_TARGETS",
"OUTPUT_DIRECTORY",
diff --git a/BaseTools/Source/Python/GenFds/FdfParser.py b/BaseTools/Source/Python/GenFds/FdfParser.py
index a468a5ec9..661e16ae4 100644
--- a/BaseTools/Source/Python/GenFds/FdfParser.py
+++ b/BaseTools/Source/Python/GenFds/FdfParser.py
@@ -1,7 +1,7 @@
## @file
# parse FDF file
#
-# Copyright (c) 2007 - 2010, Intel Corporation. All rights reserved.<BR>
+# 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
@@ -1423,7 +1423,15 @@ class FdfParser:
if not Status:
raise Warning("FD name error", self.FileName, self.CurrentLineNumber)
- self.__GetTokenStatements(FdObj)
+ while self.__GetTokenStatements(FdObj):
+ pass
+ for Attr in ("BaseAddress", "Size", "ErasePolarity"):
+ if getattr(FdObj, Attr) == None:
+ self.__GetNextToken()
+ raise Warning("Keyword %s missing" % Attr, self.FileName, self.CurrentLineNumber)
+
+ if not FdObj.BlockSizeList:
+ FdObj.BlockSizeList.append((1, FdObj.Size, None))
self.__GetDefineStatements(FdObj)
@@ -1480,58 +1488,54 @@ class FdfParser:
# @param Obj for whom token statement is got
#
def __GetTokenStatements(self, Obj):
- if not self.__IsKeyword( "BaseAddress"):
- raise Warning("BaseAddress missing", self.FileName, self.CurrentLineNumber)
-
- if not self.__IsToken( "="):
- raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
-
- if not self.__GetNextHexNumber():
- raise Warning("expected Hex base address", self.FileName, self.CurrentLineNumber)
-
- Obj.BaseAddress = self.__Token
-
- if self.__IsToken( "|"):
- pcdPair = self.__GetNextPcdName()
- Obj.BaseAddressPcd = pcdPair
- self.Profile.PcdDict[pcdPair] = Obj.BaseAddress
- FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)
- self.Profile.PcdFileLineDict[pcdPair] = FileLineTuple
-
- if not self.__IsKeyword( "Size"):
- raise Warning("Size missing", self.FileName, self.CurrentLineNumber)
-
- if not self.__IsToken( "="):
- raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
-
- if not self.__GetNextHexNumber():
- raise Warning("expected Hex size", self.FileName, self.CurrentLineNumber)
-
-
- Size = self.__Token
- if self.__IsToken( "|"):
- pcdPair = self.__GetNextPcdName()
- Obj.SizePcd = pcdPair
- self.Profile.PcdDict[pcdPair] = Size
- FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)
- self.Profile.PcdFileLineDict[pcdPair] = FileLineTuple
- Obj.Size = long(Size, 0)
-
- if not self.__IsKeyword( "ErasePolarity"):
- raise Warning("ErasePolarity missing", self.FileName, self.CurrentLineNumber)
-
- if not self.__IsToken( "="):
- raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
+ if self.__IsKeyword( "BaseAddress"):
+ if not self.__IsToken( "="):
+ raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
+
+ if not self.__GetNextHexNumber():
+ raise Warning("expected Hex base address", self.FileName, self.CurrentLineNumber)
+
+ Obj.BaseAddress = self.__Token
+
+ if self.__IsToken( "|"):
+ pcdPair = self.__GetNextPcdName()
+ Obj.BaseAddressPcd = pcdPair
+ self.Profile.PcdDict[pcdPair] = Obj.BaseAddress
+ FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)
+ self.Profile.PcdFileLineDict[pcdPair] = FileLineTuple
+ return True
- if not self.__GetNextToken():
- raise Warning("expected Erase Polarity", self.FileName, self.CurrentLineNumber)
+ if self.__IsKeyword( "Size"):
+ if not self.__IsToken( "="):
+ raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
+
+ if not self.__GetNextHexNumber():
+ raise Warning("expected Hex size", self.FileName, self.CurrentLineNumber)
- if self.__Token != "1" and self.__Token != "0":
- raise Warning("expected 1 or 0 Erase Polarity", self.FileName, self.CurrentLineNumber)
+ Size = self.__Token
+ if self.__IsToken( "|"):
+ pcdPair = self.__GetNextPcdName()
+ Obj.SizePcd = pcdPair
+ self.Profile.PcdDict[pcdPair] = Size
+ FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)
+ self.Profile.PcdFileLineDict[pcdPair] = FileLineTuple
+ Obj.Size = long(Size, 0)
+ return True
- Obj.ErasePolarity = self.__Token
+ if self.__IsKeyword( "ErasePolarity"):
+ if not self.__IsToken( "="):
+ raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
+
+ if not self.__GetNextToken():
+ raise Warning("expected Erase Polarity", self.FileName, self.CurrentLineNumber)
+
+ if self.__Token != "1" and self.__Token != "0":
+ raise Warning("expected 1 or 0 Erase Polarity", self.FileName, self.CurrentLineNumber)
+
+ Obj.ErasePolarity = self.__Token
+ return True
- self.__GetBlockStatements(Obj)
+ return self.__GetBlockStatements(Obj)
## __GetAddressStatements() method
#
@@ -1572,18 +1576,14 @@ class FdfParser:
# @param Obj for whom block statement is got
#
def __GetBlockStatements(self, Obj):
-
- if not self.__GetBlockStatement(Obj):
- #set default block size is 1
- Obj.BlockSizeList.append((1, Obj.Size, None))
- return
-
+ IsBlock = False
while self.__GetBlockStatement(Obj):
- pass
+ IsBlock = True
- for Item in Obj.BlockSizeList:
+ Item = Obj.BlockSizeList[-1]
if Item[0] == None or Item[1] == None:
raise Warning("expected block statement", self.FileName, self.CurrentLineNumber)
+ return IsBlock
## __GetBlockStatement() method
#
@@ -2038,27 +2038,16 @@ class FdfParser:
self.__GetAddressStatements(FvObj)
- while self.__GetBlockStatement(FvObj):
- pass
-
- self.__GetSetStatements(FvObj)
-
- self.__GetFvBaseAddress(FvObj)
-
- self.__GetFvForceRebase(FvObj)
-
- self.__GetFvAlignment(FvObj)
-
- self.__GetFvAttributes(FvObj)
-
- self.__GetFvNameGuid(FvObj)
-
FvObj.FvExtEntryTypeValue = []
FvObj.FvExtEntryType = []
FvObj.FvExtEntryData = []
while True:
- isFvExtEntry = self.__GetFvExtEntryStatement(FvObj)
- if not isFvExtEntry:
+ self.__GetSetStatements(FvObj)
+
+ if not (self.__GetBlockStatement(FvObj) or self.__GetFvBaseAddress(FvObj) or
+ self.__GetFvForceRebase(FvObj) or self.__GetFvAlignment(FvObj) or
+ self.__GetFvAttributes(FvObj) or self.__GetFvNameGuid(FvObj) or
+ self.__GetFvExtEntryStatement(FvObj)):
break
self.__GetAprioriSection(FvObj, FvObj.DefineVarDict.copy())
@@ -2177,9 +2166,9 @@ class FdfParser:
"WRITE_DISABLED_CAP", "WRITE_STATUS", "READ_ENABLED_CAP", \
"READ_DISABLED_CAP", "READ_STATUS", "READ_LOCK_CAP", \
"READ_LOCK_STATUS", "WRITE_LOCK_CAP", "WRITE_LOCK_STATUS", \
- "WRITE_POLICY_RELIABLE"):
+ "WRITE_POLICY_RELIABLE", "WEAK_ALIGNMENT"):
self.__UndoToken()
- return
+ return False
if not self.__IsToken( "="):
raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
@@ -2189,7 +2178,7 @@ class FdfParser:
FvObj.FvAttributeDict[name] = self.__Token
- return
+ return True
## __GetFvNameGuid() method
#
@@ -2202,7 +2191,7 @@ class FdfParser:
def __GetFvNameGuid(self, FvObj):
if not self.__IsKeyword( "FvNameGuid"):
- return
+ return False
if not self.__IsToken( "="):
raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
@@ -2212,7 +2201,7 @@ class FdfParser:
FvObj.FvNameGuid = self.__Token
- return
+ return True
def __GetFvExtEntryStatement(self, FvObj):
@@ -3058,7 +3047,7 @@ class FdfParser:
def __GetCapsuleTokens(self, Obj):
if not self.__GetNextToken():
return False
- while self.__Token in ("CAPSULE_GUID", "CAPSULE_HEADER_SIZE", "CAPSULE_FLAGS"):
+ while self.__Token in ("CAPSULE_GUID", "CAPSULE_HEADER_SIZE", "CAPSULE_FLAGS", "OEM_CAPSULE_FLAGS"):
Name = self.__Token.strip()
if not self.__IsToken("="):
raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
@@ -3075,6 +3064,15 @@ class FdfParser:
if not self.__Token in ("PersistAcrossReset", "PopulateSystemTable", "InitiateReset"):
raise Warning("expected PersistAcrossReset, PopulateSystemTable, or InitiateReset", self.FileName, self.CurrentLineNumber)
Value += self.__Token.strip()
+ elif Name == 'OEM_CAPSULE_FLAGS':
+ Value = self.__Token.strip()
+ try:
+ Value = int(Value, 0)
+ except ValueError:
+ raise Warning("expected integer value between 0x0000 and 0xFFFF", self.FileName, self.CurrentLineNumber)
+ if not 0x0000 <= Value <= 0xFFFF:
+ raise Warning("expected integer value between 0x0000 and 0xFFFF", self.FileName, self.CurrentLineNumber)
+ Value = self.__Token.strip()
else:
Value = self.__Token.strip()
Obj.TokensDict[Name] = Value
diff --git a/BaseTools/Source/Python/GenFds/FfsInfStatement.py b/BaseTools/Source/Python/GenFds/FfsInfStatement.py
index 71acd2992..3d16398c3 100644
--- a/BaseTools/Source/Python/GenFds/FfsInfStatement.py
+++ b/BaseTools/Source/Python/GenFds/FfsInfStatement.py
@@ -37,6 +37,7 @@ from GuidSection import GuidSection
from FvImageSection import FvImageSection
from Common.Misc import PeImageClass
from AutoGen.GenDepex import DependencyExpression
+from PatchPcdValue.PatchPcdValue import PatchBinaryFile
## generate FFS from INF
#
@@ -203,14 +204,80 @@ class FfsInfStatement(FfsInfStatementClassObject):
if Inf._Defs != None and len(Inf._Defs) > 0:
self.OptRomDefs.update(Inf._Defs)
-
+ self.PatchPcds = []
+ InfPcds = Inf.Pcds
+ Platform = GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, self.CurrentArch, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag]
+ FdfPcdDict = GenFdsGlobalVariable.FdfParser.Profile.PcdDict
+ DscModules = {}
+ for DscModule in Platform.Modules:
+ DscModules[str(DscModule).lower()] = Platform.Modules[DscModule]
+ for PcdKey in InfPcds:
+ Pcd = InfPcds[PcdKey]
+ if not hasattr(Pcd, 'Offset'):
+ continue
+ if Pcd.Type != 'PatchableInModule':
+ continue
+ PatchPcd = None
+ InfLowerPath = str(PathClassObj).lower()
+ if InfLowerPath in DscModules and PcdKey in DscModules[InfLowerPath].Pcds:
+ PatchPcd = DscModules[InfLowerPath].Pcds[PcdKey]
+ elif PcdKey in Platform.Pcds:
+ PatchPcd = Platform.Pcds[PcdKey]
+ DscOverride = False
+ if PatchPcd and Pcd.Type == PatchPcd.Type:
+ DefaultValue = PatchPcd.DefaultValue
+ DscOverride = True
+ FdfOverride = False
+ if PcdKey in FdfPcdDict:
+ DefaultValue = FdfPcdDict[PcdKey]
+ FdfOverride = True
+ if not DscOverride and not FdfOverride:
+ continue
+ if Pcd.DatumType == "VOID*":
+ if Pcd.DefaultValue == DefaultValue or DefaultValue in [None, '']:
+ continue
+ if DefaultValue[0] == 'L':
+ MaxDatumSize = str((len(DefaultValue) - 2) * 2)
+ elif DefaultValue[0] == '{':
+ MaxDatumSize = str(len(DefaultValue.split(',')))
+ else:
+ MaxDatumSize = str(len(DefaultValue) - 1)
+ if DscOverride:
+ Pcd.MaxDatumSize = PatchPcd.MaxDatumSize
+ if Pcd.MaxDatumSize in ['', None]:
+ Pcd.MaxDatumSize = str(len(Pcd.DefaultValue.split(',')))
+ else:
+ Base1 = Base2 = 10
+ if Pcd.DefaultValue.upper().startswith('0X'):
+ Base1 = 16
+ if DefaultValue.upper().startswith('0X'):
+ Base2 = 16
+ try:
+ PcdValueInImg = int(Pcd.DefaultValue, Base1)
+ PcdValueInDscOrFdf = int(DefaultValue, Base2)
+ if PcdValueInImg == PcdValueInDscOrFdf:
+ continue
+ except:
+ continue
+ if Pcd.DatumType == "VOID*":
+ if int(MaxDatumSize) > int(Pcd.MaxDatumSize):
+ EdkLogger.error("GenFds", GENFDS_ERROR, "The size of VOID* type PCD '%s.%s' exceeds its maximum size %d bytes." \
+ % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName, int(MaxDatumSize) - int(Pcd.MaxDatumSize)))
+ else:
+ if PcdValueInDscOrFdf > FfsInfStatement._MAX_SIZE_TYPE[Pcd.DatumType] \
+ or PcdValueInImg > FfsInfStatement._MAX_SIZE_TYPE[Pcd.DatumType]:
+ EdkLogger.error("GenFds", GENFDS_ERROR, "The size of %s type PCD '%s.%s' doesn't match its data type." \
+ % (Pcd.DatumType, Pcd.TokenSpaceGuidCName, Pcd.TokenCName))
+ Pcd.DefaultValue = DefaultValue
+ self.PatchPcds.append(Pcd)
self.InfModule = Inf
-
- GenFdsGlobalVariable.VerboseLogger( "BaseName : %s" %self.BaseName)
- GenFdsGlobalVariable.VerboseLogger("ModuleGuid : %s" %self.ModuleGuid)
- GenFdsGlobalVariable.VerboseLogger("ModuleType : %s" %self.ModuleType)
- GenFdsGlobalVariable.VerboseLogger("VersionString : %s" %self.VersionString)
- GenFdsGlobalVariable.VerboseLogger("InfFileName :%s" %self.InfFileName)
+ self.PcdIsDriver = Inf.PcdIsDriver
+ self.IsBinaryModule = Inf.IsBinaryModule
+ GenFdsGlobalVariable.VerboseLogger("BaseName : %s" % self.BaseName)
+ GenFdsGlobalVariable.VerboseLogger("ModuleGuid : %s" % self.ModuleGuid)
+ GenFdsGlobalVariable.VerboseLogger("ModuleType : %s" % self.ModuleType)
+ GenFdsGlobalVariable.VerboseLogger("VersionString : %s" % self.VersionString)
+ GenFdsGlobalVariable.VerboseLogger("InfFileName :%s" % self.InfFileName)
#
# Set OutputPath = ${WorkSpace}\Build\Fv\Ffs\${ModuleGuid}+ ${MdouleName}\
@@ -224,6 +291,27 @@ class FfsInfStatement(FfsInfStatementClassObject):
self.EfiOutputPath = self.__GetEFIOutPutPath__()
GenFdsGlobalVariable.VerboseLogger( "ModuelEFIPath: " + self.EfiOutputPath)
+## PatchEfiFile
+ #
+ # Patch EFI file with patch PCD
+ #
+ # @param EfiFile: EFI file needs to be patched.
+ # @retval: Full path of patched EFI file: self.OutputPath + EfiFile base name
+ # If passed in file does not end with efi, return as is
+ #
+ def PatchEfiFile(self, EfiFile):
+ if os.path.splitext(EfiFile)[1].lower() != '.efi':
+ return EfiFile
+ if not self.PatchPcds:
+ return EfiFile
+ Basename = os.path.basename(EfiFile)
+ Output = os.path.join(self.OutputPath, Basename)
+ CopyLongFilePath(EfiFile, Output)
+ for Pcd in self.PatchPcds:
+ RetVal, RetStr = PatchBinaryFile(Output, int(Pcd.Offset, 0), Pcd.DatumType, Pcd.DefaultValue, Pcd.MaxDatumSize)
+ if RetVal:
+ EdkLogger.error("GenFds", GENFDS_ERROR, RetStr, File=self.InfFileName)
+ return Output
## GenFfs() method
#
# Generate FFS
@@ -668,6 +756,30 @@ class FfsInfStatement(FfsInfStatementClassObject):
SectAlignments = []
Index = 1
HasGneratedFlag = False
+ if self.PcdIsDriver == 'PEI_PCD_DRIVER':
+ if self.IsBinaryModule:
+ PcdExDbFileName = os.path.join(GenFdsGlobalVariable.FvDir, "PEIPcdDataBase.raw")
+ else:
+ PcdExDbFileName = os.path.join(self.EfiOutputPath, "PEIPcdDataBase.raw")
+ PcdExDbSecName = os.path.join(self.OutputPath, "PEIPcdDataBaseSec.raw")
+ GenFdsGlobalVariable.GenerateSection(PcdExDbSecName,
+ [PcdExDbFileName],
+ "EFI_SECTION_RAW",
+ )
+ SectFiles.append(PcdExDbSecName)
+ SectAlignments.append(None)
+ elif self.PcdIsDriver == 'DXE_PCD_DRIVER':
+ if self.IsBinaryModule:
+ PcdExDbFileName = os.path.join(GenFdsGlobalVariable.FvDir, "DXEPcdDataBase.raw")
+ else:
+ PcdExDbFileName = os.path.join(self.EfiOutputPath, "DXEPcdDataBase.raw")
+ PcdExDbSecName = os.path.join(self.OutputPath, "DXEPcdDataBaseSec.raw")
+ GenFdsGlobalVariable.GenerateSection(PcdExDbSecName,
+ [PcdExDbFileName],
+ "EFI_SECTION_RAW",
+ )
+ SectFiles.append(PcdExDbSecName)
+ SectAlignments.append(None)
for Sect in Rule.SectionList:
SecIndex = '%d' %Index
SectList = []
diff --git a/BaseTools/Source/Python/GenFds/Section.py b/BaseTools/Source/Python/GenFds/Section.py
index 6f57ad568..819bb51a7 100644
--- a/BaseTools/Source/Python/GenFds/Section.py
+++ b/BaseTools/Source/Python/GenFds/Section.py
@@ -131,7 +131,7 @@ class Section (SectionClassObject):
if File.Arch == "COMMON" or FfsInf.CurrentArch == File.Arch:
if File.Type == FileType or (int(FfsInf.PiSpecVersion, 16) >= 0x0001000A and FileType == 'DXE_DPEX'and File.Type == 'SMM_DEPEX'):
if '*' in FfsInf.TargetOverrideList or File.Target == '*' or File.Target in FfsInf.TargetOverrideList or FfsInf.TargetOverrideList == []:
- FileList.append(File.Path)
+ FileList.append(FfsInf.PatchEfiFile(File.Path))
else:
GenFdsGlobalVariable.InfLogger ("\nBuild Target \'%s\' of File %s is not in the Scope of %s specified by INF %s in FDF" %(File.Target, File.File, FfsInf.TargetOverrideList, FfsInf.InfFileName))
else:
diff --git a/BaseTools/Source/Python/GenPatchPcdTable/GenPatchPcdTable.py b/BaseTools/Source/Python/GenPatchPcdTable/GenPatchPcdTable.py
index ca4440f9a..6deb0f847 100644
--- a/BaseTools/Source/Python/GenPatchPcdTable/GenPatchPcdTable.py
+++ b/BaseTools/Source/Python/GenPatchPcdTable/GenPatchPcdTable.py
@@ -5,7 +5,7 @@
# PCD Name Offset in binary
# ======== ================
#
-# Copyright (c) 2008 - 2010, Intel Corporation. All rights reserved.<BR>
+# Copyright (c) 2008 - 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
@@ -54,39 +54,54 @@ def parsePcdInfoFromMapFile(mapfilepath, efifilepath):
if len(lines) == 0: return None
if lines[0].strip().find("Archive member included because of file (symbol)") != -1:
- return _parseForGCC(lines)
+ return _parseForGCC(lines, efifilepath)
return _parseGeneral(lines, efifilepath)
-
-def _parseForGCC(lines):
+
+def _parseForGCC(lines, efifilepath):
""" Parse map file generated by GCC linker """
- status = 0
- imageBase = -1
- lastSectionName = None
- pcds = []
+ status = 0
+ imageBase = -1
+ sections = []
+ bpcds = []
for line in lines:
line = line.strip()
# status machine transection
- if status == 0 and line == "Linker script and memory map":
+ if status == 0 and line == "Memory Configuration":
status = 1
continue
- elif status == 1 and line == 'START GROUP':
+ elif status == 1 and line == 'Linker script and memory map':
status = 2
continue
-
- # status handler:
- if status == 1:
- m = re.match('^[\da-fA-FxhH]+ +__image_base__ += +([\da-fA-FhxH]+)', line)
- if m != None:
- imageBase = int(m.groups(0)[0], 16)
+ elif status ==2 and line == 'START GROUP':
+ status = 3
+ continue
+
+ # status handler
if status == 2:
- m = re.match('^([\w_\.]+) +([\da-fA-Fx]+) +([\da-fA-Fx]+)', line)
+ m = re.match('^([\w_\.]+) +([\da-fA-Fx]+) +([\da-fA-Fx]+)$', line)
if m != None:
- lastSectionName = m.groups(0)[0]
+ sections.append(m.groups(0))
if status == 2:
- m = re.match("^([\da-fA-Fx]+) +[_]+gPcd_BinaryPatch_([\w_\d]+)", line)
+ m = re.match("^([\da-fA-Fx]+) +[_]+gPcd_BinaryPatch_([\w_\d]+)$", line)
if m != None:
- assert imageBase != -1, "Fail to get Binary PCD offsest for unknown image base address"
- pcds.append((m.groups(0)[1], int(m.groups(0)[0], 16) - imageBase, lastSectionName))
+ bpcds.append((m.groups(0)[1], int(m.groups(0)[0], 16) , int(sections[-1][1], 16), sections[-1][0]))
+
+ # get section information from efi file
+ efisecs = PeImageClass(efifilepath).SectionHeaderList
+ if efisecs == None or len(efisecs) == 0:
+ return None
+ #redirection
+ redirection = 0
+ for efisec in efisecs:
+ for section in sections:
+ if section[0].strip() == efisec[0].strip() and section[0].strip() == '.text':
+ redirection = int(section[1], 16) - efisec[1]
+ pcds = []
+ for pcd in bpcds:
+ for efisec in efisecs:
+ if pcd[1] >= efisec[1] and pcd[1] < efisec[1]+efisec[3]:
+ #assert efisec[0].strip() == pcd[3].strip() and efisec[1] + redirection == pcd[2], "There are some differences between map file and efi file"
+ pcds.append([pcd[0], efisec[2] + pcd[1] - efisec[1] - redirection, efisec[0]])
return pcds
def _parseGeneral(lines, efifilepath):
diff --git a/BaseTools/Source/Python/PatchPcdValue/PatchPcdValue.py b/BaseTools/Source/Python/PatchPcdValue/PatchPcdValue.py
index 3f6c57512..69c824479 100644
--- a/BaseTools/Source/Python/PatchPcdValue/PatchPcdValue.py
+++ b/BaseTools/Source/Python/PatchPcdValue/PatchPcdValue.py
@@ -72,7 +72,7 @@ def PatchBinaryFile(FileName, ValueOffset, TypeName, ValueString, MaxSize=0):
elif TypeName == 'VOID*':
if MaxSize == 0:
return OPTION_MISSING, "PcdMaxSize is not specified for VOID* type PCD."
- ValueLength = MaxSize
+ ValueLength = int(MaxSize)
else:
return PARAMETER_INVALID, "PCD type %s is not valid." %(CommandOptions.PcdTypeName)
#
@@ -97,6 +97,7 @@ def PatchBinaryFile(FileName, ValueOffset, TypeName, ValueString, MaxSize=0):
#
# Patch value into offset
#
+ SavedStr = ValueString
ValueString = ValueString.upper()
ValueNumber = 0
if TypeName == 'BOOLEAN':
@@ -109,9 +110,9 @@ def PatchBinaryFile(FileName, ValueOffset, TypeName, ValueString, MaxSize=0):
elif ValueString == 'FALSE':
ValueNumber = 0
elif ValueString.startswith('0X'):
- ValueNumber = int (Value, 16)
+ ValueNumber = int (ValueString, 16)
else:
- ValueNumber = int (Value)
+ ValueNumber = int (ValueString)
if ValueNumber != 0:
ValueNumber = 1
except:
@@ -138,12 +139,13 @@ def PatchBinaryFile(FileName, ValueOffset, TypeName, ValueString, MaxSize=0):
ByteList[ValueOffset + Index] = ValueNumber % 0x100
ValueNumber = ValueNumber / 0x100
elif TypeName == 'VOID*':
- if ValueString.startswith("L "):
+ ValueString = SavedStr
+ if ValueString.startswith('L"'):
#
# Patch Unicode String
#
Index = 0
- for ByteString in ValueString[2:]:
+ for ByteString in ValueString[2:-1]:
#
# Reserve zero as unicode tail
#
@@ -177,7 +179,7 @@ def PatchBinaryFile(FileName, ValueOffset, TypeName, ValueString, MaxSize=0):
# Patch ascii string
#
Index = 0
- for ByteString in ValueString:
+ for ByteString in ValueString[1:-1]:
#
# Reserve zero as string tail
#
diff --git a/BaseTools/Source/Python/UPT/BuildVersion.py b/BaseTools/Source/Python/UPT/BuildVersion.py
index fa6c26aa7..2858e32c0 100644
--- a/BaseTools/Source/Python/UPT/BuildVersion.py
+++ b/BaseTools/Source/Python/UPT/BuildVersion.py
@@ -17,4 +17,4 @@
Build version information
'''
-gBUILD_VERSION = "Build 2601"
+gBUILD_VERSION = "Build 2610"
diff --git a/BaseTools/Source/Python/Workspace/MetaFileCommentParser.py b/BaseTools/Source/Python/Workspace/MetaFileCommentParser.py
new file mode 100644
index 000000000..ee6f5ac2b
--- /dev/null
+++ b/BaseTools/Source/Python/Workspace/MetaFileCommentParser.py
@@ -0,0 +1,28 @@
+## @file
+# This file is used to check format of comments
+#
+# Copyright (c) 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.
+#
+
+from CommonDataClass.DataClass import (
+ MODEL_PCD_PATCHABLE_IN_MODULE,
+ MODEL_PCD_DYNAMIC_EX,
+ MODEL_PCD_DYNAMIC,
+ MODEL_EFI_GUID,
+ MODEL_EFI_PPI,
+ MODEL_EFI_PROTOCOL
+)
+from Common.BuildToolError import FORMAT_INVALID
+import Common.EdkLogger as EdkLogger
+
+UsageList = ("PRODUCES", "PRODUCED", "ALWAYS_PRODUCES", "ALWAYS_PRODUCED", "SOMETIMES_PRODUCES",
+ "SOMETIMES_PRODUCED", "CONSUMES", "CONSUMED", "ALWAYS_CONSUMES", "ALWAYS_CONSUMED",
+ "SOMETIMES_CONSUMES", "SOMETIMES_CONSUMED", "SOMETIME_CONSUMES")
+
diff --git a/BaseTools/Source/Python/Workspace/MetaFileParser.py b/BaseTools/Source/Python/Workspace/MetaFileParser.py
index 34000b5e8..2419d270a 100644
--- a/BaseTools/Source/Python/Workspace/MetaFileParser.py
+++ b/BaseTools/Source/Python/Workspace/MetaFileParser.py
@@ -287,7 +287,7 @@ class MetaFileParser(object):
if self._SectionName in self.DataType:
self._SectionType = self.DataType[self._SectionName]
# Check if the section name is valid
- if self._SectionName not in SECTIONS_HAVE_ITEM_AFTER_ARCH and len(ItemList) > 2:
+ if self._SectionName not in SECTIONS_HAVE_ITEM_AFTER_ARCH and len(ItemList) > 3:
EdkLogger.error("Parser", FORMAT_UNKNOWN_ERROR, "%s is not a valid section name" % Item,
self.MetaFile, self._LineIndex + 1, self._CurrentLine)
elif self._Version >= 0x00010005:
@@ -495,14 +495,18 @@ class InfParser(MetaFileParser):
# parse the file line by line
IsFindBlockComment = False
+ GetHeaderComment = False
+ Comments = []
for Index in range(0, len(Content)):
# skip empty, commented, block commented lines
- Line = CleanString(Content[Index], AllowCppStyleComment=True)
+ Line, Comment = CleanString2(Content[Index], AllowCppStyleComment=True)
NextLine = ''
if Index + 1 < len(Content):
- NextLine = CleanString(Content[Index + 1])
+ NextLine, NextComment = CleanString2(Content[Index + 1])
if Line == '':
+ if Comment:
+ Comments.append((Comment, Index + 1))
continue
if Line.find(DataType.TAB_COMMENT_EDK_START) > -1:
IsFindBlockComment = True
@@ -518,6 +522,12 @@ class InfParser(MetaFileParser):
# section header
if Line[0] == TAB_SECTION_START and Line[-1] == TAB_SECTION_END:
+ if not GetHeaderComment:
+ for Cmt, LNo in Comments:
+ self._Store(MODEL_META_DATA_HEADER_COMMENT, Cmt, '', '', 'COMMON',
+ 'COMMON', self._Owner[-1], LNo, -1, LNo, -1, 0)
+ GetHeaderComment = True
+ Comments = []
self._SectionHeaderParser()
# Check invalid sections
if self._Version < 0x00010005:
@@ -566,13 +576,16 @@ class InfParser(MetaFileParser):
self._SectionParser[self._SectionType](self)
if self._ValueList == None or self._ItemType == MODEL_META_DATA_DEFINE:
self._ItemType = -1
+ Comments = []
continue
+ if Comment:
+ Comments.append((Comment, Index + 1))
#
# Model, Value1, Value2, Value3, Arch, Platform, BelongsToItem=-1,
# LineBegin=-1, ColumnBegin=-1, LineEnd=-1, ColumnEnd=-1, Enabled=-1
#
for Arch, Platform in self._Scope:
- self._Store(self._SectionType,
+ LastItem = self._Store(self._SectionType,
self._ValueList[0],
self._ValueList[1],
self._ValueList[2],
@@ -585,6 +598,10 @@ class InfParser(MetaFileParser):
- 1,
0
)
+ for Comment, LineNo in Comments:
+ self._Store(MODEL_META_DATA_COMMENT, Comment, '', '', Arch, Platform,
+ LastItem, LineNo, -1, LineNo, -1, 0)
+ Comments = []
if IsFindBlockComment:
EdkLogger.error("Parser", FORMAT_INVALID, "Open block comments (starting with /*) are expected to end with */",
File=self.MetaFile)
@@ -770,6 +787,7 @@ class DscParser(MetaFileParser):
"PLATFORM_GUID",
"PLATFORM_VERSION",
"SKUID_IDENTIFIER",
+ "PCD_INFO_GENERATION",
"SUPPORTED_ARCHITECTURES",
"BUILD_TARGETS",
"OUTPUT_DIRECTORY",
diff --git a/BaseTools/Source/Python/Workspace/MetaFileTable.py b/BaseTools/Source/Python/Workspace/MetaFileTable.py
index 088a118de..607225a0e 100644
--- a/BaseTools/Source/Python/Workspace/MetaFileTable.py
+++ b/BaseTools/Source/Python/Workspace/MetaFileTable.py
@@ -134,7 +134,7 @@ class ModuleTable(MetaFileTable):
#
# @retval: A recordSet of all found records
#
- def Query(self, Model, Arch=None, Platform=None):
+ def Query(self, Model, Arch=None, Platform=None, BelongsToItem=None):
ConditionString = "Model=%s AND Enabled>=0" % Model
ValueString = "Value1,Value2,Value3,Scope1,Scope2,ID,StartLine"
@@ -142,6 +142,8 @@ class ModuleTable(MetaFileTable):
ConditionString += " AND (Scope1='%s' OR Scope1='COMMON')" % Arch
if Platform != None and Platform != 'COMMON':
ConditionString += " AND (Scope2='%s' OR Scope2='COMMON' OR Scope2='DEFAULT')" % Platform
+ if BelongsToItem != None:
+ ConditionString += " AND BelongsToItem=%s" % BelongsToItem
SqlCommand = "SELECT %s FROM %s WHERE %s" % (ValueString, self.Table, ConditionString)
return self.Exec(SqlCommand)
diff --git a/BaseTools/Source/Python/Workspace/WorkspaceDatabase.py b/BaseTools/Source/Python/Workspace/WorkspaceDatabase.py
index 19c00ca78..04e3d14df 100644
--- a/BaseTools/Source/Python/Workspace/WorkspaceDatabase.py
+++ b/BaseTools/Source/Python/Workspace/WorkspaceDatabase.py
@@ -70,7 +70,7 @@ class DscBuildData(PlatformBuildClassObject):
#TAB_DSC_DEFINES_OUTPUT_DIRECTORY : "_OutputDirectory",
#TAB_DSC_DEFINES_SUPPORTED_ARCHITECTURES : "_SupArchList",
#TAB_DSC_DEFINES_BUILD_TARGETS : "_BuildTargets",
- #TAB_DSC_DEFINES_SKUID_IDENTIFIER : "_SkuName",
+ TAB_DSC_DEFINES_SKUID_IDENTIFIER : "_SkuName",
#TAB_DSC_DEFINES_FLASH_DEFINITION : "_FlashDefinition",
TAB_DSC_DEFINES_BUILD_NUMBER : "_BuildNumber",
TAB_DSC_DEFINES_MAKEFILE_NAME : "_MakefileName",
@@ -126,6 +126,8 @@ class DscBuildData(PlatformBuildClassObject):
self._SupArchList = None
self._BuildTargets = None
self._SkuName = None
+ self._SkuIdentifier = None
+ self._PcdInfoFlag = None
self._FlashDefinition = None
self._BuildNumber = None
self._MakefileName = None
@@ -181,10 +183,9 @@ class DscBuildData(PlatformBuildClassObject):
for Record in RecordList:
Name = Record[1]
# items defined _PROPERTY_ don't need additional processing
- if Name in self:
- self[Name] = Record[2]
+
# some special items in [Defines] section need special treatment
- elif Name == TAB_DSC_DEFINES_OUTPUT_DIRECTORY:
+ if Name == TAB_DSC_DEFINES_OUTPUT_DIRECTORY:
self._OutputDirectory = NormPath(Record[2], self._Macros)
if ' ' in self._OutputDirectory:
EdkLogger.error("build", FORMAT_NOT_SUPPORTED, "No space is allowed in OUTPUT_DIRECTORY",
@@ -203,6 +204,9 @@ class DscBuildData(PlatformBuildClassObject):
elif Name == TAB_DSC_DEFINES_SKUID_IDENTIFIER:
if self._SkuName == None:
self._SkuName = Record[2]
+ self._SkuIdentifier = Record[2]
+ elif Name == TAB_DSC_DEFINES_PCD_INFO_GENERATION:
+ self._PcdInfoFlag = Record[2]
elif Name == TAB_FIX_LOAD_TOP_MEMORY_ADDRESS:
try:
self._LoadFixAddress = int (Record[2], 0)
@@ -247,6 +251,8 @@ class DscBuildData(PlatformBuildClassObject):
except:
EdkLogger.error("build", FORMAT_INVALID, "Invalid GUID format for VPD_TOOL_GUID", File=self.MetaFile)
self._VpdToolGuid = Record[2]
+ elif Name in self:
+ self[Name] = Record[2]
# set _Header to non-None in order to avoid database re-querying
self._Header = 'DUMMY'
@@ -312,7 +318,20 @@ class DscBuildData(PlatformBuildClassObject):
if self._BuildTargets == None:
EdkLogger.error('build', ATTRIBUTE_NOT_AVAILABLE, "No BUILD_TARGETS", File=self.MetaFile)
return self._BuildTargets
-
+
+ def _GetPcdInfoFlag(self):
+ if self._PcdInfoFlag == None or self._PcdInfoFlag.upper() == 'FALSE':
+ return False
+ elif self._PcdInfoFlag.upper() == 'TRUE':
+ return True
+ else:
+ return False
+
+ def _GetSkuIdentifier(self):
+ if self._SkuIdentifier == None:
+ if self._Header == None:
+ self._GetHeaderInfo()
+ return self._SkuIdentifier
## Retrieve SKUID_IDENTIFIER
def _GetSkuName(self):
if self._SkuName == None:
@@ -441,9 +460,11 @@ class DscBuildData(PlatformBuildClassObject):
if Record[1] in [None, '']:
EdkLogger.error('build', FORMAT_INVALID, 'No Sku ID name',
File=self.MetaFile, Line=Record[-1])
- self._SkuIds[Record[1]] = Record[0]
+ self._SkuIds[Record[1].upper()] = Record[0]
if 'DEFAULT' not in self._SkuIds:
self._SkuIds['DEFAULT'] = '0'
+ if 'COMMON' not in self._SkuIds:
+ self._SkuIds['COMMON'] = '0'
return self._SkuIds
## Retrieve [Components] section information
@@ -701,19 +722,45 @@ class DscBuildData(PlatformBuildClassObject):
# tdict is a special dict kind of type, used for selecting correct
# PCD settings for certain ARCH
#
+
+ SkuObj = SkuClass(self.SkuIdentifier,self.SkuIds)
+
PcdDict = tdict(True, 3)
PcdSet = set()
# Find out all possible PCD candidates for self._Arch
RecordList = self._RawData[Type, self._Arch]
+ PcdValueDict = sdict()
for TokenSpaceGuid, PcdCName, Setting, Arch, SkuName, Dummy3, Dummy4 in RecordList:
- PcdSet.add((PcdCName, TokenSpaceGuid, Dummy4))
- PcdDict[Arch, PcdCName, TokenSpaceGuid] = Setting
- # Remove redundant PCD candidates
- for PcdCName, TokenSpaceGuid, Dummy4 in PcdSet:
- Setting = PcdDict[self._Arch, PcdCName, TokenSpaceGuid]
+ SkuName = SkuName.upper()
+ if SkuName in (SkuObj.SystemSkuId,'DEFAULT','COMMON'):
+ PcdSet.add((PcdCName, TokenSpaceGuid, SkuName,Dummy4))
+ PcdDict[Arch, PcdCName, TokenSpaceGuid,SkuName] = Setting
+
+ #handle pcd value override
+ for PcdCName, TokenSpaceGuid, SkuName,Dummy4 in PcdSet:
+ Setting = PcdDict[self._Arch, PcdCName, TokenSpaceGuid,SkuName]
if Setting == None:
continue
PcdValue, DatumType, MaxDatumSize = self._ValidatePcd(PcdCName, TokenSpaceGuid, Setting, Type, Dummy4)
+ if (PcdCName, TokenSpaceGuid) in PcdValueDict:
+ PcdValueDict[PcdCName, TokenSpaceGuid][SkuName] = (PcdValue,DatumType,MaxDatumSize)
+ else:
+ PcdValueDict[PcdCName, TokenSpaceGuid] = {SkuName:(PcdValue,DatumType,MaxDatumSize)}
+
+ PcdsKeys = PcdValueDict.keys()
+ for PcdCName,TokenSpaceGuid in PcdsKeys:
+
+ PcdSetting = PcdValueDict[PcdCName, TokenSpaceGuid]
+ PcdValue = None
+ DatumType = None
+ MaxDatumSize = None
+ if 'COMMON' in PcdSetting:
+ PcdValue,DatumType,MaxDatumSize = PcdSetting['COMMON']
+ if 'DEFAULT' in PcdSetting:
+ PcdValue,DatumType,MaxDatumSize = PcdSetting['DEFAULT']
+ if SkuObj.SystemSkuId in PcdSetting:
+ PcdValue,DatumType,MaxDatumSize = PcdSetting[SkuObj.SystemSkuId]
+
Pcds[PcdCName, TokenSpaceGuid] = PcdClassObject(
PcdCName,
TokenSpaceGuid,
@@ -735,6 +782,9 @@ class DscBuildData(PlatformBuildClassObject):
# @retval a dict object contains settings of given PCD type
#
def _GetDynamicPcd(self, Type):
+
+ SkuObj = SkuClass(self.SkuIdentifier,self.SkuIds)
+
Pcds = sdict()
#
# tdict is a special dict kind of type, used for selecting correct
@@ -744,30 +794,68 @@ class DscBuildData(PlatformBuildClassObject):
PcdList = []
# Find out all possible PCD candidates for self._Arch
RecordList = self._RawData[Type, self._Arch]
+ AvailableSkuIdSet = SkuObj.AvailableSkuIdSet.copy()
+
+ AvailableSkuIdSet.update({'DEFAULT':0,'COMMON':0})
for TokenSpaceGuid, PcdCName, Setting, Arch, SkuName, Dummy3, Dummy4 in RecordList:
- PcdList.append((PcdCName, TokenSpaceGuid, Dummy4))
+ SkuName = SkuName.upper()
+ if SkuName not in AvailableSkuIdSet:
+ continue
+
+ PcdList.append((PcdCName, TokenSpaceGuid, SkuName,Dummy4))
PcdDict[Arch, SkuName, PcdCName, TokenSpaceGuid] = Setting
# Remove redundant PCD candidates, per the ARCH and SKU
- for PcdCName, TokenSpaceGuid, Dummy4 in PcdList:
- Setting = PcdDict[self._Arch, self.SkuName, PcdCName, TokenSpaceGuid]
+ for PcdCName, TokenSpaceGuid, SkuName, Dummy4 in PcdList:
+
+ Setting = PcdDict[self._Arch, SkuName, PcdCName, TokenSpaceGuid]
if Setting == None:
continue
PcdValue, DatumType, MaxDatumSize = self._ValidatePcd(PcdCName, TokenSpaceGuid, Setting, Type, Dummy4)
+ SkuInfo = SkuInfoClass(SkuName, self.SkuIds[SkuName], '', '', '', '', '', PcdValue)
+ if (PcdCName,TokenSpaceGuid) in Pcds.keys():
+ pcdObject = Pcds[PcdCName,TokenSpaceGuid]
+ pcdObject.SkuInfoList[SkuName] = SkuInfo
+ else:
+ Pcds[PcdCName, TokenSpaceGuid] = PcdClassObject(
+ PcdCName,
+ TokenSpaceGuid,
+ self._PCD_TYPE_STRING_[Type],
+ DatumType,
+ PcdValue,
+ '',
+ MaxDatumSize,
+ {SkuName : SkuInfo},
+ False,
+ None
+ )
+
+ for pcd in Pcds.values():
+ if 'DEFAULT' not in pcd.SkuInfoList.keys() and 'COMMON' not in pcd.SkuInfoList.keys():
+ pcdDecObject = self._DecPcds[pcd.TokenCName,pcd.TokenSpaceGuidCName]
+ valuefromDec = pcdDecObject.DefaultValue
+ SkuInfo = SkuInfoClass('DEFAULT', '0', '', '', '', '', '', valuefromDec)
+ pcd.SkuInfoList['DEFAULT'] = SkuInfo
+ elif 'DEFAULT' not in pcd.SkuInfoList.keys() and 'COMMON' in pcd.SkuInfoList.keys():
+ pcd.SkuInfoList['DEFAULT'] = pcd.SkuInfoList['COMMON']
+ del(pcd.SkuInfoList['COMMON'])
+ elif 'DEFAULT' in pcd.SkuInfoList.keys() and 'COMMON' in pcd.SkuInfoList.keys():
+ del(pcd.SkuInfoList['COMMON'])
+ if SkuObj.SkuUsageType == SkuObj.SINGLE:
+ if 'DEFAULT' in pcd.SkuInfoList.keys() and SkuObj.SystemSkuId not in pcd.SkuInfoList.keys():
+ pcd.SkuInfoList[SkuObj.SystemSkuId] = pcd.SkuInfoList['DEFAULT']
+ del(pcd.SkuInfoList['DEFAULT'])
+
+ if SkuObj.SkuUsageType == SkuObj.MULTIPLE:
+ if pcd.DatumType == "VOID*":
+ MaxSize = int(pcd.MaxDatumSize,0)
+ for (skuname,skuobj) in pcd.SkuInfoList.items():
+ datalen = len(skuobj.DefaultValue)
+ if datalen>MaxSize:
+ MaxSize = datalen
+ pcd.MaxDatumSize = str(MaxSize)
+
- SkuInfo = SkuInfoClass(self.SkuName, self.SkuIds[self.SkuName], '', '', '', '', '', PcdValue)
- Pcds[PcdCName, TokenSpaceGuid] = PcdClassObject(
- PcdCName,
- TokenSpaceGuid,
- self._PCD_TYPE_STRING_[Type],
- DatumType,
- PcdValue,
- '',
- MaxDatumSize,
- {self.SkuName : SkuInfo},
- False,
- None
- )
return Pcds
## Retrieve dynamic HII PCD settings
@@ -777,6 +865,9 @@ class DscBuildData(PlatformBuildClassObject):
# @retval a dict object contains settings of given PCD type
#
def _GetDynamicHiiPcd(self, Type):
+
+ SkuObj = SkuClass(self.SkuIdentifier,self.SkuIds)
+
Pcds = sdict()
#
# tdict is a special dict kind of type, used for selecting correct
@@ -786,17 +877,28 @@ class DscBuildData(PlatformBuildClassObject):
PcdSet = set()
RecordList = self._RawData[Type, self._Arch]
# Find out all possible PCD candidates for self._Arch
+ AvailableSkuIdSet = SkuObj.AvailableSkuIdSet.copy()
+
+ AvailableSkuIdSet.update({'DEFAULT':0,'COMMON':0})
for TokenSpaceGuid, PcdCName, Setting, Arch, SkuName, Dummy3, Dummy4 in RecordList:
- PcdSet.add((PcdCName, TokenSpaceGuid, Dummy4))
+ SkuName = SkuName.upper()
+ if SkuName not in AvailableSkuIdSet:
+ continue
+ PcdSet.add((PcdCName, TokenSpaceGuid, SkuName,Dummy4))
PcdDict[Arch, SkuName, PcdCName, TokenSpaceGuid] = Setting
# Remove redundant PCD candidates, per the ARCH and SKU
- for PcdCName, TokenSpaceGuid, Dummy4 in PcdSet:
- Setting = PcdDict[self._Arch, self.SkuName, PcdCName, TokenSpaceGuid]
+ for PcdCName, TokenSpaceGuid,SkuName, Dummy4 in PcdSet:
+
+ Setting = PcdDict[self._Arch, SkuName, PcdCName, TokenSpaceGuid]
if Setting == None:
continue
VariableName, VariableGuid, VariableOffset, DefaultValue = self._ValidatePcd(PcdCName, TokenSpaceGuid, Setting, Type, Dummy4)
- SkuInfo = SkuInfoClass(self.SkuName, self.SkuIds[self.SkuName], VariableName, VariableGuid, VariableOffset, DefaultValue)
- Pcds[PcdCName, TokenSpaceGuid] = PcdClassObject(
+ SkuInfo = SkuInfoClass(SkuName, self.SkuIds[SkuName], VariableName, VariableGuid, VariableOffset, DefaultValue)
+ if (PcdCName,TokenSpaceGuid) in Pcds.keys():
+ pcdObject = Pcds[PcdCName,TokenSpaceGuid]
+ pcdObject.SkuInfoList[SkuName] = SkuInfo
+ else:
+ Pcds[PcdCName, TokenSpaceGuid] = PcdClassObject(
PcdCName,
TokenSpaceGuid,
self._PCD_TYPE_STRING_[Type],
@@ -804,10 +906,29 @@ class DscBuildData(PlatformBuildClassObject):
DefaultValue,
'',
'',
- {self.SkuName : SkuInfo},
+ {SkuName : SkuInfo},
False,
None
)
+
+
+ for pcd in Pcds.values():
+ SkuInfoObj = pcd.SkuInfoList.values()[0]
+ if 'DEFAULT' not in pcd.SkuInfoList.keys() and 'COMMON' not in pcd.SkuInfoList.keys():
+ pcdDecObject = self._DecPcds[pcd.TokenCName,pcd.TokenSpaceGuidCName]
+ valuefromDec = pcdDecObject.DefaultValue
+ SkuInfo = SkuInfoClass('DEFAULT', '0', SkuInfoObj.VariableName, SkuInfoObj.VariableGuid, SkuInfoObj.VariableOffset, valuefromDec)
+ pcd.SkuInfoList['DEFAULT'] = SkuInfo
+ elif 'DEFAULT' not in pcd.SkuInfoList.keys() and 'COMMON' in pcd.SkuInfoList.keys():
+ pcd.SkuInfoList['DEFAULT'] = pcd.SkuInfoList['COMMON']
+ del(pcd.SkuInfoList['COMMON'])
+ elif 'DEFAULT' in pcd.SkuInfoList.keys() and 'COMMON' in pcd.SkuInfoList.keys():
+ del(pcd.SkuInfoList['COMMON'])
+
+ if SkuObj.SkuUsageType == SkuObj.SINGLE:
+ if 'DEFAULT' in pcd.SkuInfoList.keys() and SkuObj.SystemSkuId not in pcd.SkuInfoList.keys():
+ pcd.SkuInfoList[SkuObj.SystemSkuId] = pcd.SkuInfoList['DEFAULT']
+ del(pcd.SkuInfoList['DEFAULT'])
return Pcds
## Retrieve dynamic VPD PCD settings
@@ -817,6 +938,9 @@ class DscBuildData(PlatformBuildClassObject):
# @retval a dict object contains settings of given PCD type
#
def _GetDynamicVpdPcd(self, Type):
+
+ SkuObj = SkuClass(self.SkuIdentifier,self.SkuIds)
+
Pcds = sdict()
#
# tdict is a special dict kind of type, used for selecting correct
@@ -826,12 +950,19 @@ class DscBuildData(PlatformBuildClassObject):
PcdList = []
# Find out all possible PCD candidates for self._Arch
RecordList = self._RawData[Type, self._Arch]
+ AvailableSkuIdSet = SkuObj.AvailableSkuIdSet.copy()
+
+ AvailableSkuIdSet.update({'DEFAULT':0,'COMMON':0})
for TokenSpaceGuid, PcdCName, Setting, Arch, SkuName, Dummy3, Dummy4 in RecordList:
- PcdList.append((PcdCName, TokenSpaceGuid, Dummy4))
+ SkuName = SkuName.upper()
+ if SkuName not in AvailableSkuIdSet:
+ continue
+
+ PcdList.append((PcdCName, TokenSpaceGuid,SkuName, Dummy4))
PcdDict[Arch, SkuName, PcdCName, TokenSpaceGuid] = Setting
# Remove redundant PCD candidates, per the ARCH and SKU
- for PcdCName, TokenSpaceGuid, Dummy4 in PcdList:
- Setting = PcdDict[self._Arch, self.SkuName, PcdCName, TokenSpaceGuid]
+ for PcdCName, TokenSpaceGuid, SkuName,Dummy4 in PcdList:
+ Setting = PcdDict[self._Arch, SkuName, PcdCName, TokenSpaceGuid]
if Setting == None:
continue
#
@@ -841,9 +972,12 @@ class DscBuildData(PlatformBuildClassObject):
# until the DEC parser has been called.
#
VpdOffset, MaxDatumSize, InitialValue = self._ValidatePcd(PcdCName, TokenSpaceGuid, Setting, Type, Dummy4)
-
- SkuInfo = SkuInfoClass(self.SkuName, self.SkuIds[self.SkuName], '', '', '', '', VpdOffset, InitialValue)
- Pcds[PcdCName, TokenSpaceGuid] = PcdClassObject(
+ SkuInfo = SkuInfoClass(SkuName, self.SkuIds[SkuName], '', '', '', '', VpdOffset, InitialValue)
+ if (PcdCName,TokenSpaceGuid) in Pcds.keys():
+ pcdObject = Pcds[PcdCName,TokenSpaceGuid]
+ pcdObject.SkuInfoList[SkuName] = SkuInfo
+ else:
+ Pcds[PcdCName, TokenSpaceGuid] = PcdClassObject(
PcdCName,
TokenSpaceGuid,
self._PCD_TYPE_STRING_[Type],
@@ -851,10 +985,35 @@ class DscBuildData(PlatformBuildClassObject):
'',
'',
MaxDatumSize,
- {self.SkuName : SkuInfo},
+ {SkuName : SkuInfo},
False,
None
)
+ for pcd in Pcds.values():
+ SkuInfoObj = pcd.SkuInfoList.values()[0]
+ if 'DEFAULT' not in pcd.SkuInfoList.keys() and 'COMMON' not in pcd.SkuInfoList.keys():
+ pcdDecObject = self._DecPcds[pcd.TokenCName,pcd.TokenSpaceGuidCName]
+ valuefromDec = pcdDecObject.DefaultValue
+ SkuInfo = SkuInfoClass('DEFAULT', '0', '', '', '','',SkuInfoObj.VpdOffset, valuefromDec)
+ pcd.SkuInfoList['DEFAULT'] = SkuInfo
+ elif 'DEFAULT' not in pcd.SkuInfoList.keys() and 'COMMON' in pcd.SkuInfoList.keys():
+ pcd.SkuInfoList['DEFAULT'] = pcd.SkuInfoList['COMMON']
+ del(pcd.SkuInfoList['COMMON'])
+ elif 'DEFAULT' in pcd.SkuInfoList.keys() and 'COMMON' in pcd.SkuInfoList.keys():
+ del(pcd.SkuInfoList['COMMON'])
+ if SkuObj.SkuUsageType == SkuObj.SINGLE:
+ if 'DEFAULT' in pcd.SkuInfoList.keys() and SkuObj.SystemSkuId not in pcd.SkuInfoList.keys():
+ pcd.SkuInfoList[SkuObj.SystemSkuId] = pcd.SkuInfoList['DEFAULT']
+ del(pcd.SkuInfoList['DEFAULT'])
+
+ if SkuObj.SkuUsageType == SkuObj.MULTIPLE:
+ if pcd.MaxDatumSize.strip():
+ MaxSize = int(pcd.MaxDatumSize,0)
+ for (skuname,skuobj) in pcd.SkuInfoList.items():
+ datalen = len(skuobj.DefaultValue)
+ if datalen>MaxSize:
+ MaxSize = datalen
+ pcd.MaxDatumSize = str(MaxSize)
return Pcds
## Add external modules
@@ -896,6 +1055,8 @@ class DscBuildData(PlatformBuildClassObject):
SupArchList = property(_GetSupArch)
BuildTargets = property(_GetBuildTarget)
SkuName = property(_GetSkuName, _SetSkuName)
+ SkuIdentifier = property(_GetSkuIdentifier)
+ PcdInfoFlag = property(_GetPcdInfoFlag)
FlashDefinition = property(_GetFdfFile)
BuildNumber = property(_GetBuildNumber)
MakefileName = property(_GetMakefileName)
@@ -1358,6 +1519,7 @@ class InfBuildData(ModuleBuildClassObject):
## Set all internal used members of InfBuildData to None
def _Clear(self):
+ self._HeaderComments = None
self._Header_ = None
self._AutoGenVersion = None
self._BaseName = None
@@ -1384,11 +1546,16 @@ class InfBuildData(ModuleBuildClassObject):
self._LibraryClasses = None
self._Libraries = None
self._Protocols = None
+ self._ProtocolComments = None
self._Ppis = None
+ self._PpiComments = None
self._Guids = None
+ self._GuidsUsedByPcd = sdict()
+ self._GuidComments = None
self._Includes = None
self._Packages = None
self._Pcds = None
+ self._PcdComments = None
self._BuildOptions = None
self._Depex = None
self._DepexExpression = None
@@ -1438,6 +1605,13 @@ class InfBuildData(ModuleBuildClassObject):
return
self._Platform = Value
self._Clear()
+ def _GetHeaderComments(self):
+ if not self._HeaderComments:
+ self._HeaderComments = []
+ RecordList = self._RawData[MODEL_META_DATA_HEADER_COMMENT]
+ for Record in RecordList:
+ self._HeaderComments.append(Record[0])
+ return self._HeaderComments
## Retrieve all information in [Defines] section
#
@@ -1873,10 +2047,14 @@ class InfBuildData(ModuleBuildClassObject):
self._Libraries.append(LibraryName)
return self._Libraries
+ def _GetProtocolComments(self):
+ self._GetProtocols()
+ return self._ProtocolComments
## Retrieve protocols consumed/produced by this module
def _GetProtocols(self):
if self._Protocols == None:
self._Protocols = sdict()
+ self._ProtocolComments = sdict()
RecordList = self._RawData[MODEL_EFI_PROTOCOL, self._Arch, self._Platform]
for Record in RecordList:
CName = Record[0]
@@ -1887,12 +2065,21 @@ class InfBuildData(ModuleBuildClassObject):
"Value of Protocol [%s] is not found under [Protocols] section in" % CName,
ExtraData=PackageList, File=self.MetaFile, Line=Record[-1])
self._Protocols[CName] = Value
+ CommentRecords = self._RawData[MODEL_META_DATA_COMMENT, self._Arch, self._Platform, Record[5]]
+ Comments = []
+ for CmtRec in CommentRecords:
+ Comments.append(CmtRec[0])
+ self._ProtocolComments[CName] = Comments
return self._Protocols
+ def _GetPpiComments(self):
+ self._GetPpis()
+ return self._PpiComments
## Retrieve PPIs consumed/produced by this module
def _GetPpis(self):
if self._Ppis == None:
self._Ppis = sdict()
+ self._PpiComments = sdict()
RecordList = self._RawData[MODEL_EFI_PPI, self._Arch, self._Platform]
for Record in RecordList:
CName = Record[0]
@@ -1903,12 +2090,21 @@ class InfBuildData(ModuleBuildClassObject):
"Value of PPI [%s] is not found under [Ppis] section in " % CName,
ExtraData=PackageList, File=self.MetaFile, Line=Record[-1])
self._Ppis[CName] = Value
+ CommentRecords = self._RawData[MODEL_META_DATA_COMMENT, self._Arch, self._Platform, Record[5]]
+ Comments = []
+ for CmtRec in CommentRecords:
+ Comments.append(CmtRec[0])
+ self._PpiComments[CName] = Comments
return self._Ppis
+ def _GetGuidComments(self):
+ self._GetGuids()
+ return self._GuidComments
## Retrieve GUIDs consumed/produced by this module
def _GetGuids(self):
if self._Guids == None:
self._Guids = sdict()
+ self._GuidComments = sdict()
RecordList = self._RawData[MODEL_EFI_GUID, self._Arch, self._Platform]
for Record in RecordList:
CName = Record[0]
@@ -1919,6 +2115,11 @@ class InfBuildData(ModuleBuildClassObject):
"Value of Guid [%s] is not found under [Guids] section in" % CName,
ExtraData=PackageList, File=self.MetaFile, Line=Record[-1])
self._Guids[CName] = Value
+ CommentRecords = self._RawData[MODEL_META_DATA_COMMENT, self._Arch, self._Platform, Record[5]]
+ Comments = []
+ for CmtRec in CommentRecords:
+ Comments.append(CmtRec[0])
+ self._GuidComments[CName] = Comments
return self._Guids
## Retrieve include paths necessary for this module (for Edk.x style of modules)
@@ -1986,10 +2187,15 @@ class InfBuildData(ModuleBuildClassObject):
self._Packages.append(Package)
return self._Packages
+ ## Retrieve PCD comments
+ def _GetPcdComments(self):
+ self._GetPcds()
+ return self._PcdComments
## Retrieve PCDs used in this module
def _GetPcds(self):
if self._Pcds == None:
self._Pcds = sdict()
+ self._PcdComments = sdict()
self._Pcds.update(self._GetPcd(MODEL_PCD_FIXED_AT_BUILD))
self._Pcds.update(self._GetPcd(MODEL_PCD_PATCHABLE_IN_MODULE))
self._Pcds.update(self._GetPcd(MODEL_PCD_FEATURE_FLAG))
@@ -2087,13 +2293,15 @@ class InfBuildData(ModuleBuildClassObject):
self._DepexExpression[Arch, ModuleType] = DepexExpression[Arch, ModuleType]
return self._DepexExpression
+ def GetGuidsUsedByPcd(self):
+ return self._GuidsUsedByPcd
## Retrieve PCD for given type
def _GetPcd(self, Type):
Pcds = sdict()
PcdDict = tdict(True, 4)
PcdList = []
RecordList = self._RawData[Type, self._Arch, self._Platform]
- for TokenSpaceGuid, PcdCName, Setting, Arch, Platform, Dummy1, LineNo in RecordList:
+ for TokenSpaceGuid, PcdCName, Setting, Arch, Platform, Id, LineNo in RecordList:
PcdDict[Arch, Platform, PcdCName, TokenSpaceGuid] = (Setting, LineNo)
PcdList.append((PcdCName, TokenSpaceGuid))
# get the guid value
@@ -2105,6 +2313,12 @@ class InfBuildData(ModuleBuildClassObject):
"Value of Guid [%s] is not found under [Guids] section in" % TokenSpaceGuid,
ExtraData=PackageList, File=self.MetaFile, Line=LineNo)
self.Guids[TokenSpaceGuid] = Value
+ self._GuidsUsedByPcd[TokenSpaceGuid] = Value
+ CommentRecords = self._RawData[MODEL_META_DATA_COMMENT, self._Arch, self._Platform, Id]
+ Comments = []
+ for CmtRec in CommentRecords:
+ Comments.append(CmtRec[0])
+ self._PcdComments[TokenSpaceGuid, PcdCName] = Comments
# resolve PCD type, value, datum info, etc. by getting its definition from package
for PcdCName, TokenSpaceGuid in PcdList:
@@ -2125,6 +2339,9 @@ class InfBuildData(ModuleBuildClassObject):
False,
self.Guids[TokenSpaceGuid]
)
+ if Type == MODEL_PCD_PATCHABLE_IN_MODULE and ValueList[1]:
+ # Patch PCD: TokenSpace.PcdCName|Value|Offset
+ Pcd.Offset = ValueList[1]
# get necessary info from package declaring this PCD
for Package in self.Packages:
@@ -2216,10 +2433,20 @@ class InfBuildData(ModuleBuildClassObject):
return Pcds
- _Macros = property(_GetMacros)
- Arch = property(_GetArch, _SetArch)
- Platform = property(_GetPlatform, _SetPlatform)
+ ## check whether current module is binary module
+ def _IsBinaryModule(self):
+ if self.Binaries and not self.Sources:
+ return True
+ elif GlobalData.gIgnoreSource:
+ return True
+ else:
+ return False
+
+ _Macros = property(_GetMacros)
+ Arch = property(_GetArch, _SetArch)
+ Platform = property(_GetPlatform, _SetPlatform)
+ HeaderComments = property(_GetHeaderComments)
AutoGenVersion = property(_GetInfVersion)
BaseName = property(_GetBaseName)
ModuleType = property(_GetModuleType)
@@ -2244,14 +2471,19 @@ class InfBuildData(ModuleBuildClassObject):
LibraryClasses = property(_GetLibraryClassUses)
Libraries = property(_GetLibraryNames)
Protocols = property(_GetProtocols)
+ ProtocolComments = property(_GetProtocolComments)
Ppis = property(_GetPpis)
+ PpiComments = property(_GetPpiComments)
Guids = property(_GetGuids)
+ GuidComments = property(_GetGuidComments)
Includes = property(_GetIncludes)
Packages = property(_GetPackages)
Pcds = property(_GetPcds)
+ PcdComments = property(_GetPcdComments)
BuildOptions = property(_GetBuildOptions)
Depex = property(_GetDepex)
DepexExpression = property(_GetDepexExpression)
+ IsBinaryModule = property(_IsBinaryModule)
## Database
#
diff --git a/BaseTools/Source/Python/build/build.py b/BaseTools/Source/Python/build/build.py
index 24a6ed816..fca36d180 100644
--- a/BaseTools/Source/Python/build/build.py
+++ b/BaseTools/Source/Python/build/build.py
@@ -1433,8 +1433,8 @@ class Build():
Ma.CreateAsBuiltInf()
if self.Target == "genmake":
continue
- self.Progress.Stop("done!")
pModules.append(Ma)
+ self.Progress.Stop("done!")
for Ma in pModules:
# Generate build task for the module
diff --git a/BaseTools/UserManuals/VfrCompiler_Utility_Man_Page.rtf b/BaseTools/UserManuals/VfrCompiler_Utility_Man_Page.rtf
index 81980fc19..e37d7187a 100644
--- a/BaseTools/UserManuals/VfrCompiler_Utility_Man_Page.rtf
+++ b/BaseTools/UserManuals/VfrCompiler_Utility_Man_Page.rtf
@@ -1,27 +1,26 @@
-{\rtf1\adeflang1025\ansi\ansicpg1252\uc2\adeff0\deff0\stshfdbch31505\stshfloch31506\stshfhich31506\stshfbi0\deflang1033\deflangfe2052\themelang1033\themelangfe2052\themelangcs0{\fonttbl{\f0\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\f1\fbidi \fswiss\fcharset0\fprq2{\*\panose 020b0604020202020204}Arial;}
-{\f2\fbidi \fmodern\fcharset0\fprq1{\*\panose 02070309020205020404}Courier New;}{\f13\fbidi \fnil\fcharset134\fprq2{\*\panose 02010600030101010101}\'cb\'ce\'cc\'e5{\*\falt SimSun};}
-{\f34\fbidi \froman\fcharset0\fprq2{\*\panose 02040503050406030204}Cambria Math;}{\f37\fbidi \fswiss\fcharset0\fprq2{\*\panose 020f0502020204030204}Calibri;}{\f38\fbidi \fswiss\fcharset0\fprq2{\*\panose 020b0604030504040204}Tahoma;}
-{\f39\fbidi \fswiss\fcharset0\fprq2{\*\panose 00000000000000000000}Verdana{\*\falt Verdana};}{\f40\fbidi \fnil\fcharset134\fprq2{\*\panose 02010600030101010101}@\'cb\'ce\'cc\'e5;}
-{\f41\fbidi \fmodern\fcharset0\fprq1{\*\panose 020b0609020204030204}Consolas;}{\flomajor\f31500\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}
-{\fdbmajor\f31501\fbidi \fnil\fcharset134\fprq2{\*\panose 02010600030101010101}\'cb\'ce\'cc\'e5{\*\falt SimSun};}{\fhimajor\f31502\fbidi \froman\fcharset0\fprq2{\*\panose 02040503050406030204}Cambria;}
+{\rtf1\adeflang1025\ansi\ansicpg1252\uc1\adeff0\deff0\stshfdbch31505\stshfloch31506\stshfhich31506\stshfbi0\deflang1033\deflangfe2052\themelang1033\themelangfe2052\themelangcs0{\fonttbl{\f0\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\f1\fbidi \fswiss\fcharset0\fprq2{\*\panose 020b0604020202020204}Arial;}
+{\f2\fbidi \fmodern\fcharset0\fprq1{\*\panose 02070309020205020404}Courier New;}{\f13\fbidi \fnil\fcharset134\fprq2{\*\panose 02010600030101010101}SimSun{\*\falt SimSun};}{\f34\fbidi \froman\fcharset0\fprq2{\*\panose 02040503050406030204}Cambria Math;}
+{\f37\fbidi \fswiss\fcharset0\fprq2{\*\panose 020f0502020204030204}Calibri;}{\f38\fbidi \fswiss\fcharset0\fprq2{\*\panose 020b0604030504040204}Tahoma;}{\f39\fbidi \fswiss\fcharset0\fprq2{\*\panose 00000000000000000000}Verdana{\*\falt Verdana};}
+{\f40\fbidi \fnil\fcharset134\fprq2{\*\panose 00000000000000000000}@SimSun;}{\f41\fbidi \fmodern\fcharset0\fprq1{\*\panose 00000000000000000000}Consolas;}{\flomajor\f31500\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}
+{\fdbmajor\f31501\fbidi \fnil\fcharset134\fprq2{\*\panose 02010600030101010101}SimSun{\*\falt SimSun};}{\fhimajor\f31502\fbidi \froman\fcharset0\fprq2{\*\panose 02040503050406030204}Cambria;}
{\fbimajor\f31503\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\flominor\f31504\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}
-{\fdbminor\f31505\fbidi \fnil\fcharset134\fprq2{\*\panose 02010600030101010101}\'cb\'ce\'cc\'e5{\*\falt SimSun};}{\fhiminor\f31506\fbidi \fswiss\fcharset0\fprq2{\*\panose 020f0502020204030204}Calibri;}
-{\fbiminor\f31507\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\f43\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}{\f44\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;}
-{\f46\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\f47\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\f48\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\f49\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}
-{\f50\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\f51\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}{\f53\fbidi \fswiss\fcharset238\fprq2 Arial CE;}{\f54\fbidi \fswiss\fcharset204\fprq2 Arial Cyr;}
-{\f56\fbidi \fswiss\fcharset161\fprq2 Arial Greek;}{\f57\fbidi \fswiss\fcharset162\fprq2 Arial Tur;}{\f58\fbidi \fswiss\fcharset177\fprq2 Arial (Hebrew);}{\f59\fbidi \fswiss\fcharset178\fprq2 Arial (Arabic);}
-{\f60\fbidi \fswiss\fcharset186\fprq2 Arial Baltic;}{\f61\fbidi \fswiss\fcharset163\fprq2 Arial (Vietnamese);}{\f63\fbidi \fmodern\fcharset238\fprq1 Courier New CE;}{\f64\fbidi \fmodern\fcharset204\fprq1 Courier New Cyr;}
-{\f66\fbidi \fmodern\fcharset161\fprq1 Courier New Greek;}{\f67\fbidi \fmodern\fcharset162\fprq1 Courier New Tur;}{\f68\fbidi \fmodern\fcharset177\fprq1 Courier New (Hebrew);}{\f69\fbidi \fmodern\fcharset178\fprq1 Courier New (Arabic);}
-{\f70\fbidi \fmodern\fcharset186\fprq1 Courier New Baltic;}{\f71\fbidi \fmodern\fcharset163\fprq1 Courier New (Vietnamese);}{\f175\fbidi \fnil\fcharset0\fprq2 SimSun Western{\*\falt SimSun};}{\f383\fbidi \froman\fcharset238\fprq2 Cambria Math CE;}
-{\f384\fbidi \froman\fcharset204\fprq2 Cambria Math Cyr;}{\f386\fbidi \froman\fcharset161\fprq2 Cambria Math Greek;}{\f387\fbidi \froman\fcharset162\fprq2 Cambria Math Tur;}{\f390\fbidi \froman\fcharset186\fprq2 Cambria Math Baltic;}
-{\f391\fbidi \froman\fcharset163\fprq2 Cambria Math (Vietnamese);}{\f413\fbidi \fswiss\fcharset238\fprq2 Calibri CE;}{\f414\fbidi \fswiss\fcharset204\fprq2 Calibri Cyr;}{\f416\fbidi \fswiss\fcharset161\fprq2 Calibri Greek;}
-{\f417\fbidi \fswiss\fcharset162\fprq2 Calibri Tur;}{\f420\fbidi \fswiss\fcharset186\fprq2 Calibri Baltic;}{\f421\fbidi \fswiss\fcharset163\fprq2 Calibri (Vietnamese);}{\f423\fbidi \fswiss\fcharset238\fprq2 Tahoma CE;}
-{\f424\fbidi \fswiss\fcharset204\fprq2 Tahoma Cyr;}{\f426\fbidi \fswiss\fcharset161\fprq2 Tahoma Greek;}{\f427\fbidi \fswiss\fcharset162\fprq2 Tahoma Tur;}{\f428\fbidi \fswiss\fcharset177\fprq2 Tahoma (Hebrew);}
-{\f429\fbidi \fswiss\fcharset178\fprq2 Tahoma (Arabic);}{\f430\fbidi \fswiss\fcharset186\fprq2 Tahoma Baltic;}{\f431\fbidi \fswiss\fcharset163\fprq2 Tahoma (Vietnamese);}{\f432\fbidi \fswiss\fcharset222\fprq2 Tahoma (Thai);}
-{\f433\fbidi \fswiss\fcharset238\fprq2 Verdana CE{\*\falt Verdana};}{\f434\fbidi \fswiss\fcharset204\fprq2 Verdana Cyr{\*\falt Verdana};}{\f436\fbidi \fswiss\fcharset161\fprq2 Verdana Greek{\*\falt Verdana};}
-{\f437\fbidi \fswiss\fcharset162\fprq2 Verdana Tur{\*\falt Verdana};}{\f440\fbidi \fswiss\fcharset186\fprq2 Verdana Baltic{\*\falt Verdana};}{\f441\fbidi \fswiss\fcharset163\fprq2 Verdana (Vietnamese){\*\falt Verdana};}
-{\f445\fbidi \fnil\fcharset0\fprq2 @\'cb\'ce\'cc\'e5 Western;}{\f453\fbidi \fmodern\fcharset238\fprq1 Consolas CE;}{\f454\fbidi \fmodern\fcharset204\fprq1 Consolas Cyr;}{\f456\fbidi \fmodern\fcharset161\fprq1 Consolas Greek;}
-{\f457\fbidi \fmodern\fcharset162\fprq1 Consolas Tur;}{\f460\fbidi \fmodern\fcharset186\fprq1 Consolas Baltic;}{\f461\fbidi \fmodern\fcharset163\fprq1 Consolas (Vietnamese);}{\flomajor\f31508\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}
+{\fdbminor\f31505\fbidi \fnil\fcharset134\fprq2{\*\panose 02010600030101010101}SimSun{\*\falt SimSun};}{\fhiminor\f31506\fbidi \fswiss\fcharset0\fprq2{\*\panose 020f0502020204030204}Calibri;}
+{\fbiminor\f31507\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\f42\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}{\f43\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;}
+{\f45\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\f46\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\f47\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\f48\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}
+{\f49\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\f50\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}{\f52\fbidi \fswiss\fcharset238\fprq2 Arial CE;}{\f53\fbidi \fswiss\fcharset204\fprq2 Arial Cyr;}
+{\f55\fbidi \fswiss\fcharset161\fprq2 Arial Greek;}{\f56\fbidi \fswiss\fcharset162\fprq2 Arial Tur;}{\f57\fbidi \fswiss\fcharset177\fprq2 Arial (Hebrew);}{\f58\fbidi \fswiss\fcharset178\fprq2 Arial (Arabic);}
+{\f59\fbidi \fswiss\fcharset186\fprq2 Arial Baltic;}{\f60\fbidi \fswiss\fcharset163\fprq2 Arial (Vietnamese);}{\f62\fbidi \fmodern\fcharset238\fprq1 Courier New CE;}{\f63\fbidi \fmodern\fcharset204\fprq1 Courier New Cyr;}
+{\f65\fbidi \fmodern\fcharset161\fprq1 Courier New Greek;}{\f66\fbidi \fmodern\fcharset162\fprq1 Courier New Tur;}{\f67\fbidi \fmodern\fcharset177\fprq1 Courier New (Hebrew);}{\f68\fbidi \fmodern\fcharset178\fprq1 Courier New (Arabic);}
+{\f69\fbidi \fmodern\fcharset186\fprq1 Courier New Baltic;}{\f70\fbidi \fmodern\fcharset163\fprq1 Courier New (Vietnamese);}{\f174\fbidi \fnil\fcharset0\fprq2 SimSun Western{\*\falt SimSun};}{\f382\fbidi \froman\fcharset238\fprq2 Cambria Math CE;}
+{\f383\fbidi \froman\fcharset204\fprq2 Cambria Math Cyr;}{\f385\fbidi \froman\fcharset161\fprq2 Cambria Math Greek;}{\f386\fbidi \froman\fcharset162\fprq2 Cambria Math Tur;}{\f389\fbidi \froman\fcharset186\fprq2 Cambria Math Baltic;}
+{\f390\fbidi \froman\fcharset163\fprq2 Cambria Math (Vietnamese);}{\f412\fbidi \fswiss\fcharset238\fprq2 Calibri CE;}{\f413\fbidi \fswiss\fcharset204\fprq2 Calibri Cyr;}{\f415\fbidi \fswiss\fcharset161\fprq2 Calibri Greek;}
+{\f416\fbidi \fswiss\fcharset162\fprq2 Calibri Tur;}{\f419\fbidi \fswiss\fcharset186\fprq2 Calibri Baltic;}{\f420\fbidi \fswiss\fcharset163\fprq2 Calibri (Vietnamese);}{\f422\fbidi \fswiss\fcharset238\fprq2 Tahoma CE;}
+{\f423\fbidi \fswiss\fcharset204\fprq2 Tahoma Cyr;}{\f425\fbidi \fswiss\fcharset161\fprq2 Tahoma Greek;}{\f426\fbidi \fswiss\fcharset162\fprq2 Tahoma Tur;}{\f427\fbidi \fswiss\fcharset177\fprq2 Tahoma (Hebrew);}
+{\f428\fbidi \fswiss\fcharset178\fprq2 Tahoma (Arabic);}{\f429\fbidi \fswiss\fcharset186\fprq2 Tahoma Baltic;}{\f430\fbidi \fswiss\fcharset163\fprq2 Tahoma (Vietnamese);}{\f431\fbidi \fswiss\fcharset222\fprq2 Tahoma (Thai);}
+{\f432\fbidi \fswiss\fcharset238\fprq2 Verdana CE{\*\falt Verdana};}{\f433\fbidi \fswiss\fcharset204\fprq2 Verdana Cyr{\*\falt Verdana};}{\f435\fbidi \fswiss\fcharset161\fprq2 Verdana Greek{\*\falt Verdana};}
+{\f436\fbidi \fswiss\fcharset162\fprq2 Verdana Tur{\*\falt Verdana};}{\f439\fbidi \fswiss\fcharset186\fprq2 Verdana Baltic{\*\falt Verdana};}{\f440\fbidi \fswiss\fcharset163\fprq2 Verdana (Vietnamese){\*\falt Verdana};}
+{\f444\fbidi \fnil\fcharset0\fprq2 @SimSun Western;}{\f452\fbidi \fmodern\fcharset238\fprq1 Consolas CE;}{\f453\fbidi \fmodern\fcharset204\fprq1 Consolas Cyr;}{\f455\fbidi \fmodern\fcharset161\fprq1 Consolas Greek;}
+{\f456\fbidi \fmodern\fcharset162\fprq1 Consolas Tur;}{\f459\fbidi \fmodern\fcharset186\fprq1 Consolas Baltic;}{\f460\fbidi \fmodern\fcharset163\fprq1 Consolas (Vietnamese);}{\flomajor\f31508\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}
{\flomajor\f31509\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;}{\flomajor\f31511\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\flomajor\f31512\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}
{\flomajor\f31513\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\flomajor\f31514\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}{\flomajor\f31515\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}
{\flomajor\f31516\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}{\fdbmajor\f31520\fbidi \fnil\fcharset0\fprq2 SimSun Western{\*\falt SimSun};}{\fhimajor\f31528\fbidi \froman\fcharset238\fprq2 Cambria CE;}
@@ -58,17 +57,16 @@ Normal Table;}{\*\cs15 \additive \rtlch\fcs1 \ab\af0\afs32 \ltrch\fcs0 \b\fs32\k
\brdrs\brdrw10 \trbrdrl\brdrs\brdrw10 \trbrdrb\brdrs\brdrw10 \trbrdrr\brdrs\brdrw10 \trbrdrh\brdrs\brdrw10 \trbrdrv\brdrs\brdrw10
\trftsWidthB3\trpaddl108\trpaddr108\trpaddfl3\trpaddft3\trpaddfb3\trpaddfr3\tblind0\tblindtype3\tsvertalt\tsbrdrt\tsbrdrl\tsbrdrb\tsbrdrr\tsbrdrdgl\tsbrdrdgr\tsbrdrh\tsbrdrv
\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch\fcs1 \af0\afs22\alang1025 \ltrch\fcs0 \fs22\lang1033\langfe2052\loch\f31506\hich\af31506\dbch\af31505\cgrid\langnp1033\langfenp2052
-\sbasedon11 \snext27 \spriority59 \styrsid4289583 Table Grid;}}{\*\rsidtbl \rsid83254\rsid1204842\rsid2570438\rsid3956845\rsid4289583\rsid4999604\rsid5715948\rsid5911148\rsid6448922\rsid6635418\rsid7634258\rsid8089322\rsid8600807\rsid9190531\rsid9200893
-\rsid10094212\rsid11500129\rsid11950970\rsid12476259\rsid12931970\rsid14109446\rsid14166490}{\mmathPr\mmathFont34\mbrkBin0\mbrkBinSub0\msmallFrac0\mdispDef1\mlMargin0\mrMargin0\mdefJc1\mwrapIndent1440\mintLim0\mnaryLim1}{\info{\operator Dong, Yong}
-{\creatim\yr2010\mo10\dy6\hr16\min18}{\revtim\yr2011\mo9\dy7\hr10\min32}{\version13}{\edmins49}{\nofpages3}{\nofwords681}{\nofchars3883}{\nofcharsws4555}{\vern49255}}{\*\xmlnstbl {\xmlns1 http://schemas.microsoft.com/office/word/2003/wordml}}
-\paperw12240\paperh15840\margl1440\margr1440\margt1440\margb1440\gutter0\ltrsect
+\sbasedon11 \snext27 \spriority59 \styrsid4289583 Table Grid;}}{\*\revtbl {Unknown;}{ydong10;}}{\*\rsidtbl \rsid83254\rsid1204842\rsid2570438\rsid3809922\rsid3956845\rsid4289583\rsid4999604\rsid5008786\rsid5715948\rsid5911148\rsid6448922\rsid6635418\rsid7634258\rsid8089322
+\rsid8600807\rsid9190531\rsid9200893\rsid10094212\rsid11500129\rsid11950970\rsid12476259\rsid12931970\rsid14109446\rsid14166490}{\mmathPr\mmathFont34\mbrkBin0\mbrkBinSub0\msmallFrac0\mdispDef1\mlMargin0\mrMargin0\mdefJc1\mwrapIndent1440\mintLim0\mnaryLim1
+}{\info{\operator ydong10}{\creatim\yr2010\mo10\dy6\hr16\min18}{\revtim\yr2013\mo10\dy21\hr13\min47}{\version15}{\edmins108}{\nofpages3}{\nofwords696}{\nofchars3968}{\nofcharsws4655}{\vern49167}}{\*\xmlnstbl {\xmlns1 http://schemas.microsoft.com/office/wo
+rd/2003/wordml}}\paperw12240\paperh15840\margl1440\margr1440\margt1440\margb1440\gutter0\ltrsect
\deftab360\widowctrl\ftnbj\aenddoc\revisions\trackmoves0\trackformatting1\donotembedsysfont0\relyonvml0\donotembedlingdata1\grfdocevents0\validatexml0\showplaceholdtext0\ignoremixedcontent0\saveinvalidxml0\showxmlerrors0\horzdoc\dghspace120\dgvspace120
-\dghorigin1701\dgvorigin1984\dghshow0\dgvshow3\jcompress\viewkind1\viewscale135\rsidroot14166490 \fet0{\*\wgrffmtfilter 2450}\ilfomacatclnup0\ltrpar \sectd \ltrsect\linex0\sectdefaultcl\sftnbj {\*\pnseclvl1\pnucrm\pnstart1\pnindent720\pnhang
-{\pntxta \hich .}}{\*\pnseclvl2\pnucltr\pnstart1\pnindent720\pnhang {\pntxta \hich .}}{\*\pnseclvl3\pndec\pnstart1\pnindent720\pnhang {\pntxta \hich .}}{\*\pnseclvl4\pnlcltr\pnstart1\pnindent720\pnhang {\pntxta \hich )}}{\*\pnseclvl5
-\pndec\pnstart1\pnindent720\pnhang {\pntxtb \hich (}{\pntxta \hich )}}{\*\pnseclvl6\pnlcltr\pnstart1\pnindent720\pnhang {\pntxtb \hich (}{\pntxta \hich )}}{\*\pnseclvl7\pnlcrm\pnstart1\pnindent720\pnhang {\pntxtb \hich (}{\pntxta \hich )}}{\*\pnseclvl8
-\pnlcltr\pnstart1\pnindent720\pnhang {\pntxtb \hich (}{\pntxta \hich )}}{\*\pnseclvl9\pnlcrm\pnstart1\pnindent720\pnhang {\pntxtb \hich (}{\pntxta \hich )}}\pard\plain \ltrpar\s2\ql \li-1440\ri0\sb400\sa60\sl-340\slmult0
-\keep\keepn\nowidctlpar\wrapdefault\faauto\outlinelevel1\rin0\lin-1440\itap0 \rtlch\fcs1 \af0\afs24\alang1025 \ltrch\fcs0 \fs24\lang1033\langfe1033\loch\af39\hich\af39\dbch\af31505\cgrid\langnp1033\langfenp1033 {\rtlch\fcs1 \ab\af39\afs28 \ltrch\fcs0
-\b\fs28\cf18\insrsid14166490 \hich\af39\dbch\af31505\loch\f39 Name
+\dghorigin1701\dgvorigin1984\dghshow0\dgvshow3\jcompress\viewkind1\viewscale135\rsidroot14166490 \fet0{\*\wgrffmtfilter 2450}\ilfomacatclnup0\ltrpar \sectd \ltrsect\linex0\sectdefaultcl\sftnbj {\*\pnseclvl1\pnucrm\pnstart1\pnindent720\pnhang {\pntxta .}}
+{\*\pnseclvl2\pnucltr\pnstart1\pnindent720\pnhang {\pntxta .}}{\*\pnseclvl3\pndec\pnstart1\pnindent720\pnhang {\pntxta .}}{\*\pnseclvl4\pnlcltr\pnstart1\pnindent720\pnhang {\pntxta )}}{\*\pnseclvl5\pndec\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}
+{\*\pnseclvl6\pnlcltr\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}{\*\pnseclvl7\pnlcrm\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}{\*\pnseclvl8\pnlcltr\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}{\*\pnseclvl9
+\pnlcrm\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}\pard\plain \ltrpar\s2\ql \li-1440\ri0\sb400\sa60\sl-340\slmult0\keep\keepn\nowidctlpar\wrapdefault\faauto\outlinelevel1\rin0\lin-1440\itap0 \rtlch\fcs1 \af0\afs24\alang1025 \ltrch\fcs0
+\fs24\lang1033\langfe1033\loch\af39\hich\af39\dbch\af31505\cgrid\langnp1033\langfenp1033 {\rtlch\fcs1 \ab\af39\afs28 \ltrch\fcs0 \b\fs28\cf18\insrsid14166490 \hich\af39\dbch\af31505\loch\f39 Name
\par }\pard\plain \ltrpar\ql \li0\ri0\sb200\nowidctlpar\wrapdefault\faauto\rin0\lin0\itap0 \rtlch\fcs1 \af0\afs24\alang1025 \ltrch\fcs0 \fs24\lang1033\langfe1033\loch\af39\hich\af39\dbch\af31505\cgrid\langnp1033\langfenp1033 {\rtlch\fcs1 \af39\afs18
\ltrch\fcs0 \fs18\cf1\insrsid14166490 \hich\af39\dbch\af31505\loch\f39 VfrCompile.exe \hich\f39 \endash \loch\f39 Compile the framework VFR and UEFI VFR file to UEFI IFR opcode table and binary.
\par }\pard\plain \ltrpar\s2\ql \li-1440\ri0\sb400\sa60\sl-340\slmult0\keep\keepn\nowidctlpar\tx1440\wrapdefault\faauto\outlinelevel1\rin0\lin-1440\itap0 \rtlch\fcs1 \af0\afs24\alang1025 \ltrch\fcs0
@@ -104,8 +102,15 @@ The generated file will be placed into the output directory sp\hich\af39\dbch\af
\par \hich\af39\dbch\af31505\loch\f39 This }{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \fs18\cf1\insrsid9200893 \hich\af39\dbch\af31505\loch\f39 is not a }{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \fs18\cf1\insrsid6635418 \hich\af39\dbch\af31505\loch\f39 standalone. }{
\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \fs18\cf1\insrsid14166490 \hich\af39\dbch\af31505\loch\f39 It is used together with the comp\hich\af39\dbch\af31505\loch\f39 iler preprocessor, }{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \fs18\cf1\insrsid9200893
\hich\af39\dbch\af31505\loch\f39 and }{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \fs18\cf1\insrsid14166490 \hich\af39\dbch\af31505\loch\f39 EDKII trim too}{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \fs18\cf1\insrsid9200893 \hich\af39\dbch\af31505\loch\f39
-. The VFR file is first preprocessed by the cCompiler and the output file is then trimmed to remove the unused definitions}{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \fs18\cf1\insrsid1204842 \hich\af39\dbch\af31505\loch\f39
- before being compiled by the VfrCompile tool to generated the UEFI IFR opcode. }{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \fs18\cf1\insrsid9200893
+. The VFR file is first preprocessed by the c}{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \fs18\cf1\revised\revauth1\revdttm656059242\insrsid3809922 \hich\af39\dbch\af31505\loch\f39 }{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \fs18\cf1\insrsid9200893
+\hich\af39\dbch\af31505\loch\f39 Compiler and the output file is then trimmed to remove the unused definitions}{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \fs18\cf1\insrsid1204842 \hich\af39\dbch\af31505\loch\f39 before being compiled by the VfrCompile tool to
+}{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \deleted\fs18\cf1\revauthdel1\revdttmdel656059243\insrsid1204842\delrsid3809922 \hich\af39\dbch\af31505\loch\f39 generated}{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0
+\fs18\cf1\revised\revauth1\revdttm656059243\insrsid3809922 \hich\af39\dbch\af31505\loch\f39 generate}{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \fs18\cf1\insrsid1204842 \hich\af39\dbch\af31505\loch\f39 the UEFI IFR opcode.}{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0
+\fs18\cf1\revised\revauth1\revdttm656059242\insrsid3809922 \hich\af39\dbch\af31505\loch\f39 So the C\hich\af39\dbch\af31505\loch\f39 style}{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \fs18\cf1\revised\revauth1\revdttm656059243\insrsid3809922
+\hich\af39\dbch\af31505\loch\f39 }{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \fs18\cf1\revised\revauth1\revdttm656059246\insrsid5008786\charrsid5008786 \hich\af39\dbch\af31505\loch\f39 preprocessor directives }{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0
+\fs18\cf1\revised\revauth1\revdttm656059247\insrsid5008786 \hich\af39\dbch\af31505\loch\f39 are}{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \fs18\cf1\revised\revauth1\revdttm656059243\insrsid3809922 \hich\af39\dbch\af31505\loch\f39
+ supported in VFR file, such as #define, #ifdef}{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \fs18\cf1\revised\revauth1\revdttm656059247\insrsid5008786 .}{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0
+\deleted\fs18\cf1\revauthdel1\revdttmdel656059243\insrsid1204842\delrsid3809922 \hich\af39\dbch\af31505\loch\f39 }{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \fs18\cf1\insrsid9200893
\par }\pard\plain \ltrpar\s2\ql \li-1440\ri0\sb400\sa60\sl-340\slmult0\keep\keepn\nowidctlpar\wrapdefault\faauto\outlinelevel1\rin0\lin-1440\itap0 \rtlch\fcs1 \af0\afs24\alang1025 \ltrch\fcs0
\fs24\lang1033\langfe1033\loch\af39\hich\af39\dbch\af31505\cgrid\langnp1033\langfenp1033 {\rtlch\fcs1 \ab\af39\afs28 \ltrch\fcs0 \b\fs28\cf18\insrsid14166490 \hich\af39\dbch\af31505\loch\f39 Options
\par }\pard\plain \ltrpar\ql \li0\ri0\sb200\nowidctlpar\wrapdefault\faauto\rin0\lin0\itap0 \rtlch\fcs1 \af0\afs24\alang1025 \ltrch\fcs0 \fs24\lang1033\langfe1033\loch\af39\hich\af39\dbch\af31505\cgrid\langnp1033\langfenp1033 {\rtlch\fcs1 \ab\af39\afs18
@@ -116,25 +121,24 @@ The generated file will be placed into the output directory sp\hich\af39\dbch\af
\hich\af39\dbch\af31505\loch\f39 the}{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \fs18\cf1\insrsid14166490 \hich\af39\dbch\af31505\loch\f39 Trim tool. The generated output file is VfrFileName.c.
\par }\pard \ltrpar\ql \li0\ri0\sb200\nowidctlpar\wrapdefault\faauto\rin0\lin0\itap0 {\rtlch\fcs1 \ab\af39\afs18 \ltrch\fcs0 \b\fs18\cf1\insrsid14166490 \hich\af39\dbch\af31505\loch\f39 -o DIR, --output-directory DIR
\par }\pard \ltrpar\ql \li360\ri0\sb200\nowidctlpar\wrapdefault\faauto\rin0\lin360\itap0 {\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \fs18\cf1\insrsid14166490 \hich\af39\dbch\af31505\loch\f39 All generated files }{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0
-\fs18\cf1\insrsid1204842 \hich\af39\dbch\af31505\loch\f39 are}{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \fs18\cf1\insrsid14166490 \hich\af39\dbch\af31505\loch\f39 placed into output directory. If this option is \hich\af39\dbch\af31505\loch\f39
-not specified, the default output directory is current directory.
+\fs18\cf1\insrsid1204842 \hich\af39\dbch\af31505\loch\f39 are}{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \fs18\cf1\insrsid14166490 \hich\af39\dbch\af31505\loch\f39
+ placed into output directory. If this option is not specified, the default output directory is current directory.
\par }\pard \ltrpar\ql \li0\ri0\sb200\nowidctlpar\wrapdefault\faauto\rin0\lin0\itap0 {\rtlch\fcs1 \ab\af39\afs18 \ltrch\fcs0 \b\fs18\cf1\insrsid14166490 \hich\af39\dbch\af31505\loch\f39 -b, --create-ifr-package
\par }\pard \ltrpar\ql \li360\ri0\sb200\nowidctlpar\wrapdefault\faauto\rin0\lin360\itap0 {\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \fs18\cf1\insrsid14166490 \hich\af39\dbch\af31505\loch\f39 Create}{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \fs18\cf1\insrsid1204842
-\hich\af39\dbch\af31505\loch\f39 s}{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \fs18\cf1\insrsid14166490 \hich\af39\dbch\af31505\loch\f39 an UEFI IFR Binary HII pack file. The generated file name is VfrFileName.hpk.
+\hich\af39\dbch\af31505\loch\f39 s}{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \fs18\cf1\insrsid14166490 \hich\af39\dbch\af31505\loch\f39 an UEFI IFR Binary HII pack file. The generated file n\hich\af39\dbch\af31505\loch\f39 ame is VfrFileName.hpk.
\par }\pard \ltrpar\ql \li0\ri0\sb200\nowidctlpar\wrapdefault\faauto\rin0\lin0\itap0 {\rtlch\fcs1 \ab\af39\afs18 \ltrch\fcs0 \b\fs18\cf1\insrsid14166490 \hich\af39\dbch\af31505\loch\f39 -l create an output IFR listing file
\par }\pard \ltrpar\ql \li360\ri0\sb200\nowidctlpar\wrapdefault\faauto\rin0\lin360\itap0 {\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \fs18\cf1\insrsid14166490 \hich\af39\dbch\af31505\loch\f39 Create}{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \fs18\cf1\insrsid1204842
-\hich\af39\dbch\af31505\loch\f39 s}{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \fs18\cf1\insrsid14166490 \hich\af39\dbch\af31505\loch\f39 an output IFR listing file (VfrFi\hich\af39\dbch\af31505\loch\f39 leName.lst) to list each IFR opcode for each VFR}{
-\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \fs18\cf1\insrsid1204842 \hich\af39\dbch\af31505\loch\f39 }{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \fs18\cf1\insrsid14166490 \hich\af39\dbch\af31505\loch\f39 statement.}{\rtlch\fcs1 \ab\af0\afs18 \ltrch\fcs0
-\b\f0\fs18\cf1\insrsid14166490
+\hich\af39\dbch\af31505\loch\f39 s}{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \fs18\cf1\insrsid14166490 \hich\af39\dbch\af31505\loch\f39 an output IFR listing file (VfrFileName.lst) to list each IFR opcode for each VFR}{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0
+\fs18\cf1\insrsid1204842 \hich\af39\dbch\af31505\loch\f39 }{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \fs18\cf1\insrsid14166490 \hich\af39\dbch\af31505\loch\f39 statement.}{\rtlch\fcs1 \ab\af0\afs18 \ltrch\fcs0 \b\f0\fs18\cf1\insrsid14166490
\par }\pard \ltrpar\ql \li0\ri0\sb200\nowidctlpar\wrapdefault\faauto\rin0\lin0\itap0 {\rtlch\fcs1 \ab\af39\afs18 \ltrch\fcs0 \b\fs18\cf1\insrsid14166490 \hich\af39\dbch\af31505\loch\f39 -n, --no-pre-processing
\par }\pard \ltrpar\ql \li360\ri0\sb200\nowidctlpar\wrapdefault\faauto\rin0\lin360\itap0 {\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \fs18\cf1\insrsid14166490 \hich\af39\dbch\af31505\loch\f39 Do not preprocess}{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0
\fs18\cf1\insrsid2570438 \hich\af39\dbch\af31505\loch\f39 t}{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \fs18\cf1\insrsid1204842 \hich\af39\dbch\af31505\loch\f39 he}{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \fs18\cf1\insrsid14166490 \hich\af39\dbch\af31505\loch\f39
- input vfr file. The input VFR file has been processed. If this option is not specified, the default behavior is same to set this option.
+ input vfr file. The input VFR file has been pro\hich\af39\dbch\af31505\loch\f39 cessed. If this option is not specified, the default behavior is same to set this option.
\par }{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \fs18\cf1\insrsid83254 \hich\af39\dbch\af31505\loch\f39 Selecting this option disables preprocessing of VFR files. }{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \fs18\cf1\insrsid2570438
\par }\pard \ltrpar\ql \li0\ri0\sb200\nowidctlpar\wrapdefault\faauto\rin0\lin0\itap0 {\rtlch\fcs1 \ab\af39\afs18 \ltrch\fcs0 \b\fs18\cf1\insrsid14166490 \hich\af39\dbch\af31505\loch\f39 -c, --compatible-framework
\par }\pard \ltrpar\ql \li360\ri0\sb200\nowidctlpar\wrapdefault\faauto\rin0\lin360\itap0 {\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \fs18\cf1\insrsid14166490 \hich\af39\dbch\af31505\loch\f39 Recognize}{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \fs18\cf1\insrsid83254
-\hich\af39\dbch\af31505\loch\f39 s}{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \fs18\cf1\insrsid14166490 \hich\af39\dbch\af31505\loch\f39 the input VFR file is the framework VFR syntax. If this option is not specified, the UEFI syntax is default }{\rtlch\fcs1
-\af39\afs18 \ltrch\fcs0 \fs18\cf1\insrsid83254 \hich\af39\dbch\af31505\loch\f39 the VFR }{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \fs18\cf1\insrsid14166490 \hich\af39\dbch\af31505\loch\f39 syntax.
+\hich\af39\dbch\af31505\loch\f39 s}{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \fs18\cf1\insrsid14166490 \hich\af39\dbch\af31505\loch\f39 the input VFR file is the framework VFR syntax. If this option is n\hich\af39\dbch\af31505\loch\f39
+ot specified, the UEFI syntax is default }{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \fs18\cf1\insrsid83254 \hich\af39\dbch\af31505\loch\f39 the VFR }{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \fs18\cf1\insrsid14166490 \hich\af39\dbch\af31505\loch\f39 syntax.
\par }\pard \ltrpar\ql \li0\ri0\sb200\nowidctlpar\wrapdefault\faauto\rin0\lin0\itap0 {\rtlch\fcs1 \ab\af39\afs18 \ltrch\fcs0 \b\fs18\cf1\insrsid14166490 \hich\af39\dbch\af31505\loch\f39 -h, --help
\par }\pard \ltrpar\ql \fi360\li0\ri0\sb200\nowidctlpar\wrapdefault\faauto\rin0\lin0\itap0 {\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \fs18\cf1\insrsid14166490 \hich\af39\dbch\af31505\loch\f39 Print version and usage of this program and exit.
\par }\pard \ltrpar\ql \li0\ri0\sb200\nowidctlpar\wrapdefault\faauto\rin0\lin0\itap0\pararsid12931970 {\rtlch\fcs1 \ab\af39\afs18 \ltrch\fcs0 \b\fs18\insrsid12931970\charrsid6448922 \hich\af39\dbch\af31505\loch\f39 -s, --string-db
@@ -180,18 +184,18 @@ n C file (Vfr_Uefi.c) and UEFI IFR Binary File (Vfr_Uefi.hpk)
\par }{\rtlch\fcs1 \ab\af39\afs18 \ltrch\fcs0 \b\fs18\cf1\insrsid14166490 \hich\af39\dbch\af31505\loch\f39 VfrCompile -n -b -l Vfr_Uefi.iii
\par }{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \fs18\cf1\insrsid14166490 \hich\af39\dbch\af31505\loch\f39 4. Parse the preprocessed Framework VFR file (Vfr_Framework.iii) to generate the UEFI IFR opcode table in autogen C file (Vfr_Framework.c).
\par }{\rtlch\fcs1 \ab\af39\afs18 \ltrch\fcs0 \b\fs18\cf1\insrsid14166490 \hich\af39\dbch\af31505\loch\f39 VfrCompile -n -c Vfr_Framework.iii
-\par }\pard \ltrpar\ql \li0\ri0\sb200\nowidctlpar\wrapdefault\faauto\rin0\lin0\itap0\pararsid14109446 {\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \fs18\insrsid14109446\charrsid6448922 \hich\af39\dbch\af31505\loch\f39 5. Parse the preprocessed UEFI VFR file (Vfr_Uefi
-\hich\af39\dbch\af31505\loch\f39 .iii) to generate the UEFI IFR opcode table in autogen C file (Vfr_Uefi.c), also base on the string token number to get efi varstore name from the string binary file (Vfr_Uefi.hpk).
-\par }{\rtlch\fcs1 \ab\af39\afs18 \ltrch\fcs0 \b\fs18\insrsid14109446\charrsid6448922 \hich\af39\dbch\af31505\loch\f39 VfrCompile -n \hich\f39 \endash \loch\f39 s Vfr_Uefi.hpk Vfr_Uefi.iii
-\par }{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \fs18\insrsid14109446\charrsid6448922 \hich\af39\dbch\af31505\loch\f39 6. Parse the preprocessed UEFI \hich\af39\dbch\af31505\loch\f39
-VFR file (Vfr_Uefi.iii) to generate the UEFI IFR opcode table in autogen C file (Vfr_Uefi.c), also override class guid with the input one.
+\par }\pard \ltrpar\ql \li0\ri0\sb200\nowidctlpar\wrapdefault\faauto\rin0\lin0\itap0\pararsid14109446 {\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \fs18\insrsid14109446\charrsid6448922 \hich\af39\dbch\af31505\loch\f39
+5. Parse the preprocessed UEFI VFR file (Vfr_Uefi.iii) to generate the UEFI IFR opcode table in autogen C file (Vfr_Uefi.c), also base on the string token number to get efi varstore name from the string binary file (Vfr_Uefi.hpk).
+\par }{\rtlch\fcs1 \ab\af39\afs18 \ltrch\fcs0 \b\fs18\insrsid14109446\charrsid6448922 \hich\af39\dbch\af31505\loch\f39 VfrCompile -n \hich\f39 \endash \loch\f39 s Vfr_Uefi\hich\af39\dbch\af31505\loch\f39 .hpk Vfr_Uefi.iii
+\par }{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \fs18\insrsid14109446\charrsid6448922 \hich\af39\dbch\af31505\loch\f39
+6. Parse the preprocessed UEFI VFR file (Vfr_Uefi.iii) to generate the UEFI IFR opcode table in autogen C file (Vfr_Uefi.c), also override class guid with the input one.
\par }\pard \ltrpar\ql \li0\ri0\sb200\nowidctlpar\wrapdefault\faauto\rin0\lin0\itap0 {\rtlch\fcs1 \ab\af39\afs18 \ltrch\fcs0 \b\fs18\insrsid14109446\charrsid6448922 \hich\af39\dbch\af31505\loch\f39 VfrCompile -n \hich\f39 \endash \loch\f39
-g C153B68D-EBFC-488E-B110-662867745B87 Vfr_Uefi.iii}{\rtlch\fcs1 \ab\af39\afs18 \ltrch\fcs0 \b\fs18\insrsid14109446\charrsid7634258
+g C153B68D-EBFC-488E-B110-662867745B87 Vfr_Uefi.ii\hich\af39\dbch\af31505\loch\f39 i}{\rtlch\fcs1 \ab\af39\afs18 \ltrch\fcs0 \b\fs18\insrsid14109446\charrsid7634258
\par }\pard\plain \ltrpar\s2\ql \li-1440\ri0\sb400\sa60\sl-340\slmult0\keep\keepn\nowidctlpar\wrapdefault\faauto\outlinelevel1\rin0\lin-1440\itap0 \rtlch\fcs1 \af0\afs24\alang1025 \ltrch\fcs0
\fs24\lang1033\langfe1033\loch\af39\hich\af39\dbch\af31505\cgrid\langnp1033\langfenp1033 {\rtlch\fcs1 \ab\af39\afs28 \ltrch\fcs0 \b\fs28\cf18\insrsid14166490 \hich\af39\dbch\af31505\loch\f39 Bugs
\par }\pard\plain \ltrpar\ql \li0\ri0\sb200\nowidctlpar\wrapdefault\faauto\rin0\lin0\itap0 \rtlch\fcs1 \af0\afs24\alang1025 \ltrch\fcs0 \fs24\lang1033\langfe1033\loch\af39\hich\af39\dbch\af31505\cgrid\langnp1033\langfenp1033 {\rtlch\fcs1 \af39\afs18
\ltrch\fcs0 \fs18\cf1\insrsid14166490 \hich\af39\dbch\af31505\loch\f39 No known }{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \fs18\cf1\insrsid1204842 \hich\af39\dbch\af31505\loch\f39 issues}{\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \fs18\cf1\insrsid14166490 .
-\par \hich\af39\dbch\af31505\loch\f39 Report bugs to edk2-build\hich\af39\dbch\af31505\loch\f39 tools-devel@lists.sourceforge.net}{\rtlch\fcs1 \af0\afs18 \ltrch\fcs0 \f0\fs18\cf1\insrsid14166490
+\par \hich\af39\dbch\af31505\loch\f39 Report bugs to edk2-buildtools-devel@lists.sourceforge.net}{\rtlch\fcs1 \af0\afs18 \ltrch\fcs0 \f0\fs18\cf1\insrsid14166490
\par }\pard\plain \ltrpar\s2\ql \li-1440\ri0\sb400\sa60\sl-340\slmult0\keep\keepn\nowidctlpar\wrapdefault\faauto\outlinelevel1\rin0\lin-1440\itap0 \rtlch\fcs1 \af0\afs24\alang1025 \ltrch\fcs0
\fs24\lang1033\langfe1033\loch\af39\hich\af39\dbch\af31505\cgrid\langnp1033\langfenp1033 {\rtlch\fcs1 \ab\af39\afs28 \ltrch\fcs0 \b\fs28\cf18\insrsid14166490 \hich\af39\dbch\af31505\loch\f39 Files
\par }\pard\plain \ltrpar\ql \li0\ri0\sb200\nowidctlpar\wrapdefault\faauto\rin0\lin0\itap0 \rtlch\fcs1 \af0\afs24\alang1025 \ltrch\fcs0 \fs24\lang1033\langfe1033\loch\af39\hich\af39\dbch\af31505\cgrid\langnp1033\langfenp1033 {\rtlch\fcs1 \af39\afs18
@@ -208,11 +212,11 @@ g C153B68D-EBFC-488E-B110-662867745B87 Vfr_Uefi.iii}{\rtlch\fcs1 \ab\af39\afs18
\par \hich\af39\dbch\af31505\loch\f39 This program and the accompanying materials are licensed and made available
\par \hich\af39\dbch\af31505\loch\f39 under the terms and conditions of the BSD License which accompanies this
\par \hich\af39\dbch\af31505\loch\f39 distribution. The full text of the license may be found at
-\par \hich\af39\dbch\af31505\loch\f39 http://opensource.org/licenses/bsd-license.php
+\par \hich\af39\dbch\af31505\loch\f39 http://opensource.org/licenses/bsd-license.ph\hich\af39\dbch\af31505\loch\f39 p
\par
\par \hich\af39\dbch\af31505\loch\f39 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
-\par }\pard \ltrpar\ql \li0\ri0\sb200\nowidctlpar\wrapdefault\faauto\rin0\lin0\itap0 {\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \fs18\cf1\insrsid14166490 \hich\af39\dbch\af31505\loch\f39 WITH\hich\af39\dbch\af31505\loch\f39
-OUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+\par }\pard \ltrpar\ql \li0\ri0\sb200\nowidctlpar\wrapdefault\faauto\rin0\lin0\itap0 {\rtlch\fcs1 \af39\afs18 \ltrch\fcs0 \fs18\cf1\insrsid14166490 \hich\af39\dbch\af31505\loch\f39 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
\par }\pard \ltrpar\ql \li0\ri0\nowidctlpar\wrapdefault\faauto\rin0\lin0\itap0 {\rtlch\fcs1 \af1\afs20 \ltrch\fcs0 \f1\fs20\insrsid14166490
\par }{\*\themedata 504b030414000600080000002100e9de0fbfff0000001c020000130000005b436f6e74656e745f54797065735d2e786d6cac91cb4ec3301045f748fc83e52d4a
9cb2400825e982c78ec7a27cc0c8992416c9d8b2a755fbf74cd25442a820166c2cd933f79e3be372bd1f07b5c3989ca74aaff2422b24eb1b475da5df374fd9ad
@@ -319,8 +323,8 @@ fffffffffffffffffdfffffffeffffffffffffffffffffffffffffffffffffffffffffffffffffff
ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-ffffffffffffffffffffffffffffffff52006f006f007400200045006e00740072007900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000016000500ffffffffffffffffffffffff0c6ad98892f1d411a65f0040963251e5000000000000000000000000f0d4
-6273066dcc01feffffff00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffff00000000000000000000000000000000000000000000000000000000
+ffffffffffffffffffffffffffffffff52006f006f007400200045006e00740072007900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000016000500ffffffffffffffffffffffff0c6ad98892f1d411a65f0040963251e50000000000000000000000000072
+d90d21cece01feffffff00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffff00000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffff0000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffff000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000105000000000000}} \ No newline at end of file
diff --git a/BeagleBoardPkg/BeagleBoardPkg.dsc b/BeagleBoardPkg/BeagleBoardPkg.dsc
index 1223944be..07b8c4719 100644
--- a/BeagleBoardPkg/BeagleBoardPkg.dsc
+++ b/BeagleBoardPkg/BeagleBoardPkg.dsc
@@ -257,8 +257,6 @@
gArmPlatformTokenSpaceGuid.PcdFirmwareVendor|"Beagle Board"
gEmbeddedTokenSpaceGuid.PcdEmbeddedPrompt|"BeagleEdk2"
- gEmbeddedTokenSpaceGuid.PcdPrePiCpuMemorySize|32
- gEmbeddedTokenSpaceGuid.PcdPrePiCpuIoSize|0
gEfiMdePkgTokenSpaceGuid.PcdMaximumUnicodeStringLength|1000000
gEfiMdePkgTokenSpaceGuid.PcdMaximumAsciiStringLength|1000000
gEfiMdePkgTokenSpaceGuid.PcdMaximumLinkedListLength|1000000
diff --git a/CryptoPkg/Library/BaseCryptLib/Rand/CryptRand.c b/CryptoPkg/Library/BaseCryptLib/Rand/CryptRand.c
index dc3ab992d..895ce83fa 100644
--- a/CryptoPkg/Library/BaseCryptLib/Rand/CryptRand.c
+++ b/CryptoPkg/Library/BaseCryptLib/Rand/CryptRand.c
@@ -1,7 +1,7 @@
/** @file
Pseudorandom Number Generator Wrapper Implementation over OpenSSL.
-Copyright (c) 2010 - 2012, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2010 - 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
@@ -14,6 +14,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#include "InternalCryptLib.h"
#include <openssl/rand.h>
+#include <openssl/evp.h>
//
// Default seed for UEFI Crypto Library
@@ -48,6 +49,14 @@ RandomSeed (
}
//
+ // The software PRNG implementation built in OpenSSL depends on message digest algorithm.
+ // Make sure SHA-1 digest algorithm is available here.
+ //
+ if (EVP_add_digest (EVP_sha1 ()) == 0) {
+ return FALSE;
+ }
+
+ //
// Seed the pseudorandom number generator with user-supplied value.
// NOTE: A cryptographic PRNG must be seeded with unpredictable data.
//
diff --git a/CryptoPkg/Library/BaseCryptLib/Rand/CryptRandItc.c b/CryptoPkg/Library/BaseCryptLib/Rand/CryptRandItc.c
index 0f27f253d..9f8708744 100644
--- a/CryptoPkg/Library/BaseCryptLib/Rand/CryptRandItc.c
+++ b/CryptoPkg/Library/BaseCryptLib/Rand/CryptRandItc.c
@@ -1,7 +1,7 @@
/** @file
Pseudorandom Number Generator Wrapper Implementation over OpenSSL.
-Copyright (c) 2012, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2012 - 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
@@ -14,6 +14,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#include "InternalCryptLib.h"
#include <openssl/rand.h>
+#include <openssl/evp.h>
#include <Library/PrintLib.h>
/**
@@ -46,6 +47,14 @@ RandomSeed (
}
//
+ // The software PRNG implementation built in OpenSSL depends on message digest algorithm.
+ // Make sure SHA-1 digest algorithm is available here.
+ //
+ if (EVP_add_digest (EVP_sha1 ()) == 0) {
+ return FALSE;
+ }
+
+ //
// Seed the pseudorandom number generator with user-supplied value.
// NOTE: A cryptographic PRNG must be seeded with unpredictable data.
//
diff --git a/CryptoPkg/Library/BaseCryptLib/Rand/CryptRandTsc.c b/CryptoPkg/Library/BaseCryptLib/Rand/CryptRandTsc.c
index dbdd6383a..9bd349df4 100644
--- a/CryptoPkg/Library/BaseCryptLib/Rand/CryptRandTsc.c
+++ b/CryptoPkg/Library/BaseCryptLib/Rand/CryptRandTsc.c
@@ -1,7 +1,7 @@
/** @file
Pseudorandom Number Generator Wrapper Implementation over OpenSSL.
-Copyright (c) 2012, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2012 - 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
@@ -14,6 +14,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#include "InternalCryptLib.h"
#include <openssl/rand.h>
+#include <openssl/evp.h>
#include <Library/PrintLib.h>
/**
@@ -46,6 +47,14 @@ RandomSeed (
}
//
+ // The software PRNG implementation built in OpenSSL depends on message digest algorithm.
+ // Make sure SHA-1 digest algorithm is available here.
+ //
+ if (EVP_add_digest (EVP_sha1 ()) == 0) {
+ return FALSE;
+ }
+
+ //
// Seed the pseudorandom number generator with user-supplied value.
// NOTE: A cryptographic PRNG must be seeded with unpredictable data.
//
diff --git a/CryptoPkg/Library/BaseCryptLib/SysCall/Ia32/MathRShiftU64.S b/CryptoPkg/Library/BaseCryptLib/SysCall/Ia32/MathRShiftU64.S
index 3a8a13256..bf0587502 100644
--- a/CryptoPkg/Library/BaseCryptLib/SysCall/Ia32/MathRShiftU64.S
+++ b/CryptoPkg/Library/BaseCryptLib/SysCall/Ia32/MathRShiftU64.S
@@ -1,6 +1,6 @@
#------------------------------------------------------------------------------
#
-# Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.<BR>
+# Copyright (c) 2009 - 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
@@ -53,7 +53,7 @@ ASM_PFX(__ashrdi3):
More32:
movl %edx, %eax
xor %edx, %edx
- and $32, %cl
+ and $31, %cl
shr %cl, %eax
ret
diff --git a/DuetPkg/DuetPkgIa32.dsc b/DuetPkg/DuetPkgIa32.dsc
index 117bffb0e..db1f7b648 100644
--- a/DuetPkg/DuetPkgIa32.dsc
+++ b/DuetPkg/DuetPkgIa32.dsc
@@ -4,7 +4,7 @@
# Developer's UEFI Emulation. DUET provides an EFI/UEFI IA32/X64 environment on legacy BIOS,
# to help developing and debugging native EFI/UEFI drivers.
#
-# Copyright (c) 2010 - 2012, Intel Corporation. All rights reserved.<BR>
+# Copyright (c) 2010 - 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
@@ -103,7 +103,7 @@
PlatformHookLib|MdeModulePkg/Library/BasePlatformHookLibNull/BasePlatformHookLibNull.inf
SerialPortLib|MdeModulePkg/Library/BaseSerialPortLib16550/BaseSerialPortLib16550.inf
MtrrLib|UefiCpuPkg/Library/MtrrLib/MtrrLib.inf
- CpuExceptionHandlerLib|MdeModulePkg/Library/CpuExceptionHandlerLibNull/CpuExceptionHandlerLibNull.inf
+ CpuExceptionHandlerLib|UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeCpuExceptionHandlerLib.inf
LocalApicLib|UefiCpuPkg/Library/BaseXApicLib/BaseXApicLib.inf
#
diff --git a/DuetPkg/DuetPkgX64.dsc b/DuetPkg/DuetPkgX64.dsc
index 70b159dd8..eeae767f1 100644
--- a/DuetPkg/DuetPkgX64.dsc
+++ b/DuetPkg/DuetPkgX64.dsc
@@ -4,7 +4,7 @@
# Developer's UEFI Emulation. DUET provides an EFI/UEFI IA32/X64 environment on legacy BIOS,
# to help developing and debugging native EFI/UEFI drivers.
#
-# Copyright (c) 2010 - 2012, Intel Corporation. All rights reserved.<BR>
+# Copyright (c) 2010 - 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
@@ -104,7 +104,7 @@
SerialPortLib|MdeModulePkg/Library/BaseSerialPortLib16550/BaseSerialPortLib16550.inf
MtrrLib|UefiCpuPkg/Library/MtrrLib/MtrrLib.inf
LockBoxLib|MdeModulePkg/Library/LockBoxNullLib/LockBoxNullLib.inf
- CpuExceptionHandlerLib|MdeModulePkg/Library/CpuExceptionHandlerLibNull/CpuExceptionHandlerLibNull.inf
+ CpuExceptionHandlerLib|UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeCpuExceptionHandlerLib.inf
LocalApicLib|UefiCpuPkg/Library/BaseXApicLib/BaseXApicLib.inf
#
diff --git a/EdkCompatibilityPkg/EdkCompatibilityPkg.dsc b/EdkCompatibilityPkg/EdkCompatibilityPkg.dsc
index 825fa4019..016e9adee 100644
--- a/EdkCompatibilityPkg/EdkCompatibilityPkg.dsc
+++ b/EdkCompatibilityPkg/EdkCompatibilityPkg.dsc
@@ -85,7 +85,7 @@ DEFINE GCC_MACRO = -DEFI_SPECIFICATION_VERSION=0x00020000 -DPI_S
ReportStatusCodeLib|MdeModulePkg/Library/SmmReportStatusCodeLib/SmmReportStatusCodeLib.inf
MemoryAllocationLib|MdePkg/Library/SmmMemoryAllocationLib/SmmMemoryAllocationLib.inf
-[BuildOptions]
+[BuildOptions.Common.EDK]
GCC:*_*_IA32_CC_FLAGS = -DEFI32 $(GCC_MACRO)
GCC:*_*_IA32_ASM_FLAGS =
GCC:*_*_IA32_VFRPP_FLAGS = -DEFI32 $(GCC_MACRO)
diff --git a/EdkCompatibilityPkg/Foundation/Library/Dxe/EfiDriverLib/Perf.c b/EdkCompatibilityPkg/Foundation/Library/Dxe/EfiDriverLib/Perf.c
index b8809d18b..b5f9a4ae5 100644
--- a/EdkCompatibilityPkg/Foundation/Library/Dxe/EfiDriverLib/Perf.c
+++ b/EdkCompatibilityPkg/Foundation/Library/Dxe/EfiDriverLib/Perf.c
@@ -515,12 +515,10 @@ Returns:
--*/
{
- EFI_PERFORMANCE_INSTANCE *PerfInstance;
EFI_PERF_DATA_LIST *Node;
UINT64 TimerValue;
TimerValue = 0;
- PerfInstance = EFI_PERFORMANCE_FROM_THIS (This);
Node = GetDataNode (Handle, Token, Host, NULL, NULL);
if (!Node) {
@@ -573,11 +571,8 @@ Returns:
--*/
{
- EFI_PERFORMANCE_INSTANCE *PerfInstance;
EFI_PERF_DATA_LIST *Node;
- PerfInstance = EFI_PERFORMANCE_FROM_THIS (This);
-
Node = GetDataNode (Handle, Token, Host, NULL, PrevGauge);
if (Node != NULL) {
return &(Node->GaugeData);
diff --git a/EdkCompatibilityPkg/Foundation/Library/EfiCommonLib/LinkedList.c b/EdkCompatibilityPkg/Foundation/Library/EfiCommonLib/LinkedList.c
index 7e9bfa889..2ba4d1c26 100644
--- a/EdkCompatibilityPkg/Foundation/Library/EfiCommonLib/LinkedList.c
+++ b/EdkCompatibilityPkg/Foundation/Library/EfiCommonLib/LinkedList.c
@@ -212,14 +212,12 @@ Returns:
--*/
{
- EFI_LIST_ENTRY *Entry1ForwardLink;
EFI_LIST_ENTRY *Entry1BackLink;
EFI_LIST_ENTRY *Entry2ForwardLink;
EFI_LIST_ENTRY *Entry2BackLink;
Entry2ForwardLink = Entry2->ForwardLink;
Entry2BackLink = Entry2->BackLink;
- Entry1ForwardLink = Entry1->ForwardLink;
Entry1BackLink = Entry1->BackLink;
Entry2BackLink->ForwardLink = Entry2ForwardLink;
Entry2ForwardLink->BackLink = Entry2BackLink;
diff --git a/EdkCompatibilityPkg/Foundation/Library/EfiCommonLib/ReportStatusCode.c b/EdkCompatibilityPkg/Foundation/Library/EfiCommonLib/ReportStatusCode.c
index ce56fcf36..775b7c36b 100644
--- a/EdkCompatibilityPkg/Foundation/Library/EfiCommonLib/ReportStatusCode.c
+++ b/EdkCompatibilityPkg/Foundation/Library/EfiCommonLib/ReportStatusCode.c
@@ -339,6 +339,6 @@ Returns:
#else
*Marker = (VA_LIST) (DebugInfo + 1);
*Format = (CHAR8 *)(((UINT64 *)*Marker) + 12);
-#endif
return TRUE;
+#endif
}
diff --git a/EdkShellPkg/EdkShellPkg.dsc b/EdkShellPkg/EdkShellPkg.dsc
index 6127919a0..90eac0f09 100644
--- a/EdkShellPkg/EdkShellPkg.dsc
+++ b/EdkShellPkg/EdkShellPkg.dsc
@@ -188,7 +188,7 @@ DEFINE GCC_MACRO = -DEFI_SPECIFICATION_VERSION=0x0002000A -DPI_S
$(EDK_SHELL_DIR)/ver/Ver.inf
$(EDK_SHELL_DIR)/vol/Vol.inf
-[BuildOptions]
+[BuildOptions.Common.EDK]
MSFT:*_*_IA32_CC_FLAGS = /D EFI_SPECIFICATION_VERSION=0x0002000A /D PI_SPECIFICATION_VERSION=0x00010000 /D TIANO_RELEASE_VERSION=0x00080006 /D EFI32
MSFT:*_*_IA32_ASM_FLAGS = /DEFI32
MSFT:*_*_IA32_VFRPP_FLAGS = /D EFI_SPECIFICATION_VERSION=0x0002000A /D PI_SPECIFICATION_VERSION=0x00010000 /D TIANO_RELEASE_VERSION=0x00080006 /D EFI32
diff --git a/EmbeddedPkg/EmbeddedPkg.dec b/EmbeddedPkg/EmbeddedPkg.dec
index f4cf1b312..1b8ef158a 100644
--- a/EmbeddedPkg/EmbeddedPkg.dec
+++ b/EmbeddedPkg/EmbeddedPkg.dec
@@ -82,8 +82,6 @@
gEmbeddedTokenSpaceGuid.PcdPrePiHobBase|131072|UINT32|0x00000040
gEmbeddedTokenSpaceGuid.PcdPrePiStackBase|0|UINT32|0x0000000b
gEmbeddedTokenSpaceGuid.PcdPrePiStackSize|131072|UINT32|0x0000000c
- gEmbeddedTokenSpaceGuid.PcdPrePiCpuMemorySize|32|UINT8|0x00000010
- gEmbeddedTokenSpaceGuid.PcdPrePiCpuIoSize|0|UINT8|0x00000011
gEmbeddedTokenSpaceGuid.PcdMemoryBase|0x0|UINT32|0x0000004e
gEmbeddedTokenSpaceGuid.PcdMemorySize|0x0|UINT32|0x0000004f
@@ -126,6 +124,19 @@
gEmbeddedTokenSpaceGuid.PcdGdbUartPort|0x3f8|UINT32|0x0000004b
gEmbeddedTokenSpaceGuid.PcdGdbMaxPacketRetryCount|10000000|UINT32|0x0000004c
gEmbeddedTokenSpaceGuid.PcdGdbTimerPeriodMilliseconds|250|UINT32|0x0000004d
-
-
+[PcdsFixedAtBuild.ARM]
+ gEmbeddedTokenSpaceGuid.PcdPrePiCpuMemorySize|32|UINT8|0x00000010
+ gEmbeddedTokenSpaceGuid.PcdPrePiCpuIoSize|0|UINT8|0x00000011
+
+[PcdsFixedAtBuild.AARCH64]
+ gEmbeddedTokenSpaceGuid.PcdPrePiCpuMemorySize|48|UINT8|0x00000010
+ gEmbeddedTokenSpaceGuid.PcdPrePiCpuIoSize|0|UINT8|0x00000011
+
+[PcdsFixedAtBuild.IA32]
+ gEmbeddedTokenSpaceGuid.PcdPrePiCpuMemorySize|36|UINT8|0x00000010
+ gEmbeddedTokenSpaceGuid.PcdPrePiCpuIoSize|16|UINT8|0x00000011
+
+[PcdsFixedAtBuild.X64]
+ gEmbeddedTokenSpaceGuid.PcdPrePiCpuMemorySize|52|UINT8|0x00000010
+ gEmbeddedTokenSpaceGuid.PcdPrePiCpuIoSize|16|UINT8|0x00000011
diff --git a/EmbeddedPkg/EmbeddedPkg.dsc b/EmbeddedPkg/EmbeddedPkg.dsc
index 6c9d05a25..908b81947 100644
--- a/EmbeddedPkg/EmbeddedPkg.dsc
+++ b/EmbeddedPkg/EmbeddedPkg.dsc
@@ -202,21 +202,6 @@
gEmbeddedTokenSpaceGuid.PcdTimerVector|7
gEmbeddedTokenSpaceGuid.PcdTimerPeriod|100000
-
-[PcdsFixedAtBuild.ARM]
- gEmbeddedTokenSpaceGuid.PcdPrePiCpuMemorySize|32
- gEmbeddedTokenSpaceGuid.PcdPrePiCpuIoSize|0
-
-[PcdsFixedAtBuild.IA32]
- gEmbeddedTokenSpaceGuid.PcdPrePiCpuMemorySize|36
- gEmbeddedTokenSpaceGuid.PcdPrePiCpuIoSize|16
-
-[PcdsFixedAtBuild.X64]
- gEmbeddedTokenSpaceGuid.PcdPrePiCpuMemorySize|52
- gEmbeddedTokenSpaceGuid.PcdPrePiCpuIoSize|16
-
-
-
[PcdsFixedAtBuild.IPF]
gEfiMdePkgTokenSpaceGuid.PcdIoBlockBaseAddressForIpf|0x0ffffc000000
diff --git a/FatBinPkg/EnhancedFatDxe/Ebc/Fat.efi b/FatBinPkg/EnhancedFatDxe/Ebc/Fat.efi
index 55d6ce5b1..f94488fd7 100644
--- a/FatBinPkg/EnhancedFatDxe/Ebc/Fat.efi
+++ b/FatBinPkg/EnhancedFatDxe/Ebc/Fat.efi
Binary files differ
diff --git a/FatBinPkg/EnhancedFatDxe/Ia32/Fat.efi b/FatBinPkg/EnhancedFatDxe/Ia32/Fat.efi
index d789861a9..878497ea5 100644
--- a/FatBinPkg/EnhancedFatDxe/Ia32/Fat.efi
+++ b/FatBinPkg/EnhancedFatDxe/Ia32/Fat.efi
Binary files differ
diff --git a/FatBinPkg/EnhancedFatDxe/Ipf/Fat.efi b/FatBinPkg/EnhancedFatDxe/Ipf/Fat.efi
index a4847deab..e944b59a8 100644
--- a/FatBinPkg/EnhancedFatDxe/Ipf/Fat.efi
+++ b/FatBinPkg/EnhancedFatDxe/Ipf/Fat.efi
Binary files differ
diff --git a/FatBinPkg/EnhancedFatDxe/X64/Fat.efi b/FatBinPkg/EnhancedFatDxe/X64/Fat.efi
index 158e14a52..97680767d 100644
--- a/FatBinPkg/EnhancedFatDxe/X64/Fat.efi
+++ b/FatBinPkg/EnhancedFatDxe/X64/Fat.efi
Binary files differ
diff --git a/FatBinPkg/ReadMe.txt b/FatBinPkg/ReadMe.txt
index d3d7b5312..8b3e61143 100644
--- a/FatBinPkg/ReadMe.txt
+++ b/FatBinPkg/ReadMe.txt
@@ -1,12 +1,9 @@
-The binaries of FatBinPkg are generated with RELEASE_MYTOOLS from FatPkgDev Combo at the following SVN address:
-https://svn.code.sf.net/p/edk2-fatdriver2/code/trunk/Combo/FatPkgDev
-
# Ebc, Ia32, Ipf, X64
- The binaries in this package currently are built from UDK2010.SR1 release: MdePkg and BaseTools (r12898), FatPkg (r67)
+ The binaries in this package currently are built from EDK2 release: MdePkg and BaseTools (head), FatPkg (r81)
The binaries are built with no debug info (RELEASE TARGET).
The Component Name 2 Protocol and Unicode Collation 2 Protocol are supported.
# ARM
The binaries in this package currently are built from EDK2 release: MdePkg and BaseTools (r13646), FatPkg (r71)
The binaries are built with no debug info (RELEASE TARGET).
- Build Instructions: http://sourceforge.net/apps/mediawiki/tianocore/index.php?title=ArmPkg/Binaries \ No newline at end of file
+ Build Instructions: http://sourceforge.net/apps/mediawiki/tianocore/index.php?title=ArmPkg/Binaries
diff --git a/IntelFrameworkModulePkg/Library/GenericBdsLib/BdsBoot.c b/IntelFrameworkModulePkg/Library/GenericBdsLib/BdsBoot.c
index 29afe45f3..3701434ef 100644
--- a/IntelFrameworkModulePkg/Library/GenericBdsLib/BdsBoot.c
+++ b/IntelFrameworkModulePkg/Library/GenericBdsLib/BdsBoot.c
@@ -40,7 +40,7 @@ GenericBdsLibConstructor (
gBdsLibStringPackHandle = HiiAddPackages (
&gBdsLibStringPackageGuid,
- &ImageHandle,
+ ImageHandle,
GenericBdsLibStrings,
NULL
);
diff --git a/MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpress.c b/MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpress.c
index ed1c4bf39..4f187e3ab 100644
--- a/MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpress.c
+++ b/MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpress.c
@@ -129,7 +129,7 @@ EnumerateNvmeDevNamespace (
Device->Media.WriteCaching = FALSE;
Flbas = NamespaceData->Flbas;
- LbaFmtIdx = Flbas & 3;
+ LbaFmtIdx = Flbas & 0xF;
Lbads = NamespaceData->LbaFormat[LbaFmtIdx].Lbads;
Device->Media.BlockSize = (UINT32)1 << Lbads;
diff --git a/MdeModulePkg/Bus/Pci/XhciDxe/Xhci.c b/MdeModulePkg/Bus/Pci/XhciDxe/Xhci.c
index 443df729d..5ca58fbb9 100644
--- a/MdeModulePkg/Bus/Pci/XhciDxe/Xhci.c
+++ b/MdeModulePkg/Bus/Pci/XhciDxe/Xhci.c
@@ -32,6 +32,13 @@ USB_PORT_STATE_MAP mUsbPortChangeMap[] = {
{XHC_PORTSC_PRC, USB_PORT_STAT_C_RESET}
};
+USB_CLEAR_PORT_MAP mUsbClearPortChangeMap[] = {
+ {XHC_PORTSC_CSC, EfiUsbPortConnectChange},
+ {XHC_PORTSC_PEC, EfiUsbPortEnableChange},
+ {XHC_PORTSC_OCC, EfiUsbPortOverCurrentChange},
+ {XHC_PORTSC_PRC, EfiUsbPortResetChange}
+};
+
USB_PORT_STATE_MAP mUsbHubPortStateMap[] = {
{XHC_HUB_PORTSC_CCS, USB_PORT_STAT_CONNECTION},
{XHC_HUB_PORTSC_PED, USB_PORT_STAT_ENABLE},
@@ -46,6 +53,14 @@ USB_PORT_STATE_MAP mUsbHubPortChangeMap[] = {
{XHC_HUB_PORTSC_PRC, USB_PORT_STAT_C_RESET}
};
+USB_CLEAR_PORT_MAP mUsbHubClearPortChangeMap[] = {
+ {XHC_HUB_PORTSC_CSC, EfiUsbPortConnectChange},
+ {XHC_HUB_PORTSC_PEC, EfiUsbPortEnableChange},
+ {XHC_HUB_PORTSC_OCC, EfiUsbPortOverCurrentChange},
+ {XHC_HUB_PORTSC_PRC, EfiUsbPortResetChange},
+ {XHC_HUB_PORTSC_BHRC, Usb3PortBHPortResetChange}
+};
+
EFI_DRIVER_BINDING_PROTOCOL gXhciDriverBinding = {
XhcDriverBindingSupported,
XhcDriverBindingStart,
@@ -432,6 +447,14 @@ XhcGetRootHubPortStatus (
}
}
+ MapSize = sizeof (mUsbClearPortChangeMap) / sizeof (USB_CLEAR_PORT_MAP);
+
+ for (Index = 0; Index < MapSize; Index++) {
+ if (XHC_BIT_IS_SET (State, mUsbClearPortChangeMap[Index].HwState)) {
+ XhcClearRootHubPortFeature (This, PortNumber, mUsbClearPortChangeMap[Index].Selector);
+ }
+ }
+
//
// Poll the root port status register to enable/disable corresponding device slot if there is a device attached/detached.
// For those devices behind hub, we get its attach/detach event by hooking Get_Port_Status request at control transfer for those hub.
@@ -469,8 +492,6 @@ XhcSetRootHubPortFeature (
UINT32 Offset;
UINT32 State;
UINT32 TotalPort;
- UINT8 SlotId;
- USB_DEV_ROUTE RouteChart;
EFI_STATUS Status;
EFI_TPL OldTpl;
@@ -526,24 +547,13 @@ XhcSetRootHubPortFeature (
}
}
- RouteChart.Route.RouteString = 0;
- RouteChart.Route.RootPortNum = PortNumber + 1;
- RouteChart.Route.TierNum = 1;
//
- // If the port reset operation happens after the usb super speed device is enabled,
- // The subsequent configuration, such as getting device descriptor, will fail.
- // So here a workaround is introduced to skip the reset operation if the device is enabled.
+ // 4.3.1 Resetting a Root Hub Port
+ // 1) Write the PORTSC register with the Port Reset (PR) bit set to '1'.
//
- SlotId = XhcRouteStringToSlotId (Xhc, RouteChart);
- if (SlotId == 0) {
- //
- // 4.3.1 Resetting a Root Hub Port
- // 1) Write the PORTSC register with the Port Reset (PR) bit set to '1'.
- //
- State |= XHC_PORTSC_RESET;
- XhcWriteOpReg (Xhc, Offset, State);
- XhcWaitOpRegBit(Xhc, Offset, XHC_PORTSC_PRC, TRUE, XHC_GENERIC_TIMEOUT);
- }
+ State |= XHC_PORTSC_RESET;
+ XhcWriteOpReg (Xhc, Offset, State);
+ XhcWaitOpRegBit(Xhc, Offset, XHC_PORTSC_PRC, TRUE, XHC_GENERIC_TIMEOUT);
break;
case EfiUsbPortPower:
@@ -763,6 +773,8 @@ XhcControlTransfer (
UINTN MapSize;
EFI_USB_PORT_STATUS PortStatus;
UINT32 State;
+ EFI_USB_DEVICE_REQUEST ClearPortRequest;
+ UINTN Len;
//
// Validate parameters
@@ -808,6 +820,7 @@ XhcControlTransfer (
Status = EFI_DEVICE_ERROR;
*TransferResult = EFI_USB_ERR_SYSTEM;
+ Len = 0;
if (XhcIsHalt (Xhc) || XhcIsSysError (Xhc)) {
DEBUG ((EFI_D_ERROR, "XhcControlTransfer: HC halted at entrance\n"));
@@ -839,6 +852,11 @@ XhcControlTransfer (
Xhc->UsbDevContext[Index + 1].BusDevAddr = 0;
}
}
+
+ if (Xhc->UsbDevContext[SlotId].XhciDevAddr == 0) {
+ Status = EFI_DEVICE_ERROR;
+ goto ON_EXIT;
+ }
//
// The actual device address has been assigned by XHCI during initializing the device slot.
// So we just need establish the mapping relationship between the device address requested from UsbBus
@@ -849,20 +867,6 @@ XhcControlTransfer (
Status = EFI_SUCCESS;
goto ON_EXIT;
}
-
- //
- // If the port reset operation happens after the usb super speed device is enabled,
- // The subsequent configuration, such as getting device descriptor, will fail.
- // So here a workaround is introduced to skip the reset operation if the device is enabled.
- //
- if ((Request->Request == USB_REQ_SET_FEATURE) &&
- (Request->RequestType == USB_REQUEST_TYPE (EfiUsbNoData, USB_REQ_TYPE_CLASS, USB_TARGET_OTHER)) &&
- (Request->Value == EfiUsbPortReset)) {
- if (DeviceSpeed == EFI_USB_SPEED_SUPER) {
- Status = EFI_SUCCESS;
- goto ON_EXIT;
- }
- }
//
// Create a new URB, insert it into the asynchronous
@@ -1050,6 +1054,33 @@ XhcControlTransfer (
}
}
+ MapSize = sizeof (mUsbHubClearPortChangeMap) / sizeof (USB_CLEAR_PORT_MAP);
+
+ for (Index = 0; Index < MapSize; Index++) {
+ if (XHC_BIT_IS_SET (State, mUsbHubClearPortChangeMap[Index].HwState)) {
+ ZeroMem (&ClearPortRequest, sizeof (EFI_USB_DEVICE_REQUEST));
+ ClearPortRequest.RequestType = USB_REQUEST_TYPE (EfiUsbNoData, USB_REQ_TYPE_CLASS, USB_TARGET_OTHER);
+ ClearPortRequest.Request = (UINT8) USB_REQ_CLEAR_FEATURE;
+ ClearPortRequest.Value = mUsbHubClearPortChangeMap[Index].Selector;
+ ClearPortRequest.Index = Request->Index;
+ ClearPortRequest.Length = 0;
+
+ XhcControlTransfer (
+ This,
+ DeviceAddress,
+ DeviceSpeed,
+ MaximumPacketLength,
+ &ClearPortRequest,
+ EfiUsbNoData,
+ NULL,
+ &Len,
+ Timeout,
+ Translator,
+ TransferResult
+ );
+ }
+ }
+
XhcPollPortStatusChange (Xhc, Xhc->UsbDevContext[SlotId].RouteString, (UINT8)Request->Index, &PortStatus);
*(UINT32 *)Data = *(UINT32*)&PortStatus;
diff --git a/MdeModulePkg/Bus/Pci/XhciDxe/XhciReg.h b/MdeModulePkg/Bus/Pci/XhciDxe/XhciReg.h
index 20a5510bf..dc8281198 100644
--- a/MdeModulePkg/Bus/Pci/XhciDxe/XhciReg.h
+++ b/MdeModulePkg/Bus/Pci/XhciDxe/XhciReg.h
@@ -2,7 +2,7 @@
This file contains the register definition of XHCI host controller.
-Copyright (c) 2011 - 2012, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2011 - 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
@@ -169,7 +169,7 @@ typedef union {
#define XHC_PORTSC_RESET BIT4 // Port Reset
#define XHC_PORTSC_PLS (BIT5|BIT6|BIT7|BIT8) // Port Link State
#define XHC_PORTSC_PP BIT9 // Port Power
-#define XHC_PORTSC_PS (BIT10|BIT11|BIT12|BIT13) // Port Speed
+#define XHC_PORTSC_PS (BIT10|BIT11|BIT12) // Port Speed
#define XHC_PORTSC_LWS BIT16 // Port Link State Write Strobe
#define XHC_PORTSC_CSC BIT17 // Connect Status Change
#define XHC_PORTSC_PEC BIT18 // Port Enabled/Disabled Change
@@ -189,6 +189,7 @@ typedef union {
#define XHC_HUB_PORTSC_PEC BIT17 // Hub's Port Enabled/Disabled Change
#define XHC_HUB_PORTSC_OCC BIT19 // Hub's Over-Current Change
#define XHC_HUB_PORTSC_PRC BIT20 // Hub's Port Reset Change
+#define XHC_HUB_PORTSC_BHRC BIT21 // Hub's Port Warm Reset Change
#define XHC_IMAN_IP BIT0 // Interrupt Pending
#define XHC_IMAN_IE BIT1 // Interrupt Enable
@@ -196,6 +197,11 @@ typedef union {
#define XHC_IMODC_MASK 0xFFFF0000 // Interrupt Moderation Counter
//
+// Hub Class Feature Selector for Clear Port Feature Request
+//
+#define Usb3PortBHPortResetChange 29
+
+//
// Structure to map the hardware port states to the
// UEFI's port states.
//
@@ -204,6 +210,14 @@ typedef struct {
UINT16 UefiState;
} USB_PORT_STATE_MAP;
+//
+// Structure to map the hardware port states to feature selector for clear port feature request.
+//
+typedef struct {
+ UINT32 HwState;
+ UINT16 Selector;
+} USB_CLEAR_PORT_MAP;
+
/**
Read 1-byte width XHCI capability register.
diff --git a/MdeModulePkg/Bus/Pci/XhciDxe/XhciSched.c b/MdeModulePkg/Bus/Pci/XhciDxe/XhciSched.c
index dea5b1af1..ec13e49a7 100644
--- a/MdeModulePkg/Bus/Pci/XhciDxe/XhciSched.c
+++ b/MdeModulePkg/Bus/Pci/XhciDxe/XhciSched.c
@@ -1105,25 +1105,25 @@ XhcCheckUrbResult (
CheckedUrb->Result |= EFI_USB_ERR_STALL;
CheckedUrb->Finished = TRUE;
DEBUG ((EFI_D_ERROR, "XhcCheckUrbResult: STALL_ERROR! Completecode = %x\n",EvtTrb->Completecode));
- break;
+ goto EXIT;
case TRB_COMPLETION_BABBLE_ERROR:
CheckedUrb->Result |= EFI_USB_ERR_BABBLE;
CheckedUrb->Finished = TRUE;
DEBUG ((EFI_D_ERROR, "XhcCheckUrbResult: BABBLE_ERROR! Completecode = %x\n",EvtTrb->Completecode));
- break;
+ goto EXIT;
case TRB_COMPLETION_DATA_BUFFER_ERROR:
CheckedUrb->Result |= EFI_USB_ERR_BUFFER;
CheckedUrb->Finished = TRUE;
DEBUG ((EFI_D_ERROR, "XhcCheckUrbResult: ERR_BUFFER! Completecode = %x\n",EvtTrb->Completecode));
- break;
+ goto EXIT;
case TRB_COMPLETION_USB_TRANSACTION_ERROR:
CheckedUrb->Result |= EFI_USB_ERR_TIMEOUT;
CheckedUrb->Finished = TRUE;
DEBUG ((EFI_D_ERROR, "XhcCheckUrbResult: TRANSACTION_ERROR! Completecode = %x\n",EvtTrb->Completecode));
- break;
+ goto EXIT;
case TRB_COMPLETION_SHORT_PACKET:
case TRB_COMPLETION_SUCCESS:
@@ -1144,7 +1144,7 @@ XhcCheckUrbResult (
DEBUG ((EFI_D_ERROR, "Transfer Default Error Occur! Completecode = 0x%x!\n",EvtTrb->Completecode));
CheckedUrb->Result |= EFI_USB_ERR_TIMEOUT;
CheckedUrb->Finished = TRUE;
- break;
+ goto EXIT;
}
//
@@ -1535,6 +1535,10 @@ XhcPollPortStatusChange (
Status = EFI_SUCCESS;
+ if ((PortState->PortChangeStatus & (USB_PORT_STAT_C_CONNECTION | USB_PORT_STAT_C_ENABLE | USB_PORT_STAT_C_OVERCURRENT | USB_PORT_STAT_C_RESET)) == 0) {
+ return EFI_SUCCESS;
+ }
+
if (ParentRouteChart.Dword == 0) {
RouteChart.Route.RouteString = 0;
RouteChart.Route.RootPortNum = Port + 1;
@@ -1549,6 +1553,15 @@ XhcPollPortStatusChange (
RouteChart.Route.TierNum = ParentRouteChart.Route.TierNum + 1;
}
+ SlotId = XhcRouteStringToSlotId (Xhc, RouteChart);
+ if (SlotId != 0) {
+ if (Xhc->HcCParams.Data.Csz == 0) {
+ Status = XhcDisableSlotCmd (Xhc, SlotId);
+ } else {
+ Status = XhcDisableSlotCmd64 (Xhc, SlotId);
+ }
+ }
+
if (((PortState->PortStatus & USB_PORT_STAT_ENABLE) != 0) &&
((PortState->PortStatus & USB_PORT_STAT_CONNECTION) != 0)) {
//
@@ -1566,26 +1579,15 @@ XhcPollPortStatusChange (
// Execute Enable_Slot cmd for attached device, initialize device context and assign device address.
//
SlotId = XhcRouteStringToSlotId (Xhc, RouteChart);
- if (SlotId == 0) {
+ if ((SlotId == 0) && ((PortState->PortChangeStatus & USB_PORT_STAT_C_RESET) != 0)) {
if (Xhc->HcCParams.Data.Csz == 0) {
Status = XhcInitializeDeviceSlot (Xhc, ParentRouteChart, Port, RouteChart, Speed);
} else {
Status = XhcInitializeDeviceSlot64 (Xhc, ParentRouteChart, Port, RouteChart, Speed);
}
}
- } else if ((PortState->PortStatus & USB_PORT_STAT_CONNECTION) == 0) {
- //
- // Device is detached. Disable the allocated device slot and release resource.
- //
- SlotId = XhcRouteStringToSlotId (Xhc, RouteChart);
- if (SlotId != 0) {
- if (Xhc->HcCParams.Data.Csz == 0) {
- Status = XhcDisableSlotCmd (Xhc, SlotId);
- } else {
- Status = XhcDisableSlotCmd64 (Xhc, SlotId);
- }
- }
- }
+ }
+
return Status;
}
@@ -2633,9 +2635,10 @@ XhcSetConfigCmd (
if ((DeviceSpeed == EFI_USB_SPEED_FULL) || (DeviceSpeed == EFI_USB_SPEED_LOW)) {
Interval = EpDesc->Interval;
//
- // Hard code the interval to MAX first, need calculate through the bInterval field of Endpoint descriptor.
+ // Calculate through the bInterval field of Endpoint descriptor.
//
- InputContext->EP[Dci-1].Interval = 6;
+ ASSERT (Interval != 0);
+ InputContext->EP[Dci-1].Interval = (UINT32)HighBitSet32((UINT32)Interval) + 3;
} else if ((DeviceSpeed == EFI_USB_SPEED_HIGH) || (DeviceSpeed == EFI_USB_SPEED_SUPER)) {
Interval = EpDesc->Interval;
ASSERT (Interval >= 1 && Interval <= 16);
@@ -2830,9 +2833,10 @@ XhcSetConfigCmd64 (
if ((DeviceSpeed == EFI_USB_SPEED_FULL) || (DeviceSpeed == EFI_USB_SPEED_LOW)) {
Interval = EpDesc->Interval;
//
- // Hard code the interval to MAX first, need calculate through the bInterval field of Endpoint descriptor.
+ // Calculate through the bInterval field of Endpoint descriptor.
//
- InputContext->EP[Dci-1].Interval = 6;
+ ASSERT (Interval != 0);
+ InputContext->EP[Dci-1].Interval = (UINT32)HighBitSet32((UINT32)Interval) + 3;
} else if ((DeviceSpeed == EFI_USB_SPEED_HIGH) || (DeviceSpeed == EFI_USB_SPEED_SUPER)) {
Interval = EpDesc->Interval;
ASSERT (Interval >= 1 && Interval <= 16);
diff --git a/MdeModulePkg/Bus/Usb/UsbBusDxe/UsbBus.h b/MdeModulePkg/Bus/Usb/UsbBusDxe/UsbBus.h
index d503a278a..9ede83ab7 100644
--- a/MdeModulePkg/Bus/Usb/UsbBusDxe/UsbBus.h
+++ b/MdeModulePkg/Bus/Usb/UsbBusDxe/UsbBus.h
@@ -198,6 +198,7 @@ struct _USB_DEVICE {
USB_INTERFACE *ParentIf;
UINT8 ParentPort; // Start at 0
UINT8 Tier;
+ BOOLEAN DisconnectFail;
};
//
diff --git a/MdeModulePkg/Bus/Usb/UsbBusDxe/UsbDesc.c b/MdeModulePkg/Bus/Usb/UsbBusDxe/UsbDesc.c
index b2401ca40..9687eb0bc 100644
--- a/MdeModulePkg/Bus/Usb/UsbBusDxe/UsbDesc.c
+++ b/MdeModulePkg/Bus/Usb/UsbBusDxe/UsbDesc.c
@@ -142,15 +142,15 @@ UsbFreeDevDesc (
VOID *
UsbCreateDesc (
IN UINT8 *DescBuf,
- IN INTN Len,
+ IN UINTN Len,
IN UINT8 Type,
- OUT INTN *Consumed
+ OUT UINTN *Consumed
)
{
USB_DESC_HEAD *Head;
- INTN DescLen;
- INTN CtrlLen;
- INTN Offset;
+ UINTN DescLen;
+ UINTN CtrlLen;
+ UINTN Offset;
VOID *Desc;
DescLen = 0;
@@ -188,7 +188,15 @@ UsbCreateDesc (
while ((Offset < Len) && (Head->Type != Type)) {
Offset += Head->Len;
+ if (Len <= Offset) {
+ DEBUG (( EFI_D_ERROR, "UsbCreateDesc: met mal-format descriptor, Beyond boundary!\n"));
+ return NULL;
+ }
Head = (USB_DESC_HEAD*)(DescBuf + Offset);
+ if (Head->Len == 0) {
+ DEBUG (( EFI_D_ERROR, "UsbCreateDesc: met mal-format descriptor, Head->Len = 0!\n"));
+ return NULL;
+ }
}
if ((Len <= Offset) || (Len < Offset + DescLen) ||
@@ -223,16 +231,16 @@ UsbCreateDesc (
USB_INTERFACE_SETTING *
UsbParseInterfaceDesc (
IN UINT8 *DescBuf,
- IN INTN Len,
- OUT INTN *Consumed
+ IN UINTN Len,
+ OUT UINTN *Consumed
)
{
USB_INTERFACE_SETTING *Setting;
USB_ENDPOINT_DESC *Ep;
UINTN Index;
UINTN NumEp;
- INTN Used;
- INTN Offset;
+ UINTN Used;
+ UINTN Offset;
*Consumed = 0;
Setting = UsbCreateDesc (DescBuf, Len, USB_DESC_TYPE_INTERFACE, &Used);
@@ -265,7 +273,7 @@ UsbParseInterfaceDesc (
//
// Create the endpoints for this interface
//
- for (Index = 0; Index < NumEp; Index++) {
+ for (Index = 0; (Index < NumEp) && (Offset < Len); Index++) {
Ep = UsbCreateDesc (DescBuf + Offset, Len - Offset, USB_DESC_TYPE_ENDPOINT, &Used);
if (Ep == NULL) {
@@ -300,7 +308,7 @@ ON_ERROR:
USB_CONFIG_DESC *
UsbParseConfigDesc (
IN UINT8 *DescBuf,
- IN INTN Len
+ IN UINTN Len
)
{
USB_CONFIG_DESC *Config;
@@ -308,7 +316,7 @@ UsbParseConfigDesc (
USB_INTERFACE_DESC *Interface;
UINTN Index;
UINTN NumIf;
- INTN Consumed;
+ UINTN Consumed;
ASSERT (DescBuf != NULL);
diff --git a/MdeModulePkg/Bus/Usb/UsbBusDxe/UsbEnumer.c b/MdeModulePkg/Bus/Usb/UsbBusDxe/UsbEnumer.c
index 79635cb18..430f5aa3d 100644
--- a/MdeModulePkg/Bus/Usb/UsbBusDxe/UsbEnumer.c
+++ b/MdeModulePkg/Bus/Usb/UsbBusDxe/UsbEnumer.c
@@ -450,7 +450,7 @@ UsbSelectConfig (
@param UsbIf The interface to disconnect driver from.
**/
-VOID
+EFI_STATUS
UsbDisconnectDriver (
IN USB_INTERFACE *UsbIf
)
@@ -462,8 +462,9 @@ UsbDisconnectDriver (
// Release the hub if it's a hub controller, otherwise
// disconnect the driver if it is managed by other drivers.
//
+ Status = EFI_SUCCESS;
if (UsbIf->IsHub) {
- UsbIf->HubApi->Release (UsbIf);
+ Status = UsbIf->HubApi->Release (UsbIf);
} else if (UsbIf->IsManaged) {
//
@@ -479,13 +480,17 @@ UsbDisconnectDriver (
gBS->RestoreTPL (TPL_CALLBACK);
Status = gBS->DisconnectController (UsbIf->Handle, NULL, NULL);
- UsbIf->IsManaged = FALSE;
-
+ if (!EFI_ERROR (Status)) {
+ UsbIf->IsManaged = FALSE;
+ }
+
DEBUG (( EFI_D_INFO, "UsbDisconnectDriver: TPL after disconnect is %d, %d\n", (UINT32)UsbGetCurrentTpl(), Status));
ASSERT (UsbGetCurrentTpl () == TPL_CALLBACK);
gBS->RaiseTPL (OldTpl);
}
+
+ return Status;
}
@@ -495,17 +500,20 @@ UsbDisconnectDriver (
@param Device The USB device to remove configuration from.
**/
-VOID
+EFI_STATUS
UsbRemoveConfig (
IN USB_DEVICE *Device
)
{
USB_INTERFACE *UsbIf;
UINTN Index;
+ EFI_STATUS Status;
+ EFI_STATUS ReturnStatus;
//
// Remove each interface of the device
//
+ ReturnStatus = EFI_SUCCESS;
for (Index = 0; Index < Device->NumOfInterface; Index++) {
ASSERT (Index < USB_MAX_INTERFACE);
UsbIf = Device->Interfaces[Index];
@@ -514,13 +522,17 @@ UsbRemoveConfig (
continue;
}
- UsbDisconnectDriver (UsbIf);
- UsbFreeInterface (UsbIf);
- Device->Interfaces[Index] = NULL;
+ Status = UsbDisconnectDriver (UsbIf);
+ if (!EFI_ERROR (Status)) {
+ UsbFreeInterface (UsbIf);
+ Device->Interfaces[Index] = NULL;
+ } else {
+ ReturnStatus = Status;
+ }
}
Device->ActiveConfig = NULL;
- Device->NumOfInterface = 0;
+ return ReturnStatus;
}
@@ -540,6 +552,7 @@ UsbRemoveDevice (
USB_BUS *Bus;
USB_DEVICE *Child;
EFI_STATUS Status;
+ EFI_STATUS ReturnStatus;
UINTN Index;
Bus = Device->Bus;
@@ -548,6 +561,7 @@ UsbRemoveDevice (
// Remove all the devices on its downstream ports. Search from devices[1].
// Devices[0] is the root hub.
//
+ ReturnStatus = EFI_SUCCESS;
for (Index = 1; Index < Bus->MaxDevices; Index++) {
Child = Bus->Devices[Index];
@@ -557,21 +571,31 @@ UsbRemoveDevice (
Status = UsbRemoveDevice (Child);
- if (EFI_ERROR (Status)) {
- DEBUG ((EFI_D_ERROR, "UsbRemoveDevice: failed to remove child, ignore error\n"));
+ if (!EFI_ERROR (Status)) {
Bus->Devices[Index] = NULL;
+ } else {
+ Bus->Devices[Index]->DisconnectFail = TRUE;
+ ReturnStatus = Status;
+ DEBUG ((EFI_D_INFO, "UsbRemoveDevice: failed to remove child %p at parent %p\n", Child, Device));
}
}
- UsbRemoveConfig (Device);
+ if (EFI_ERROR (ReturnStatus)) {
+ return ReturnStatus;
+ }
- DEBUG (( EFI_D_INFO, "UsbRemoveDevice: device %d removed\n", Device->Address));
+ Status = UsbRemoveConfig (Device);
- ASSERT (Device->Address < Bus->MaxDevices);
- Bus->Devices[Device->Address] = NULL;
- UsbFreeDevice (Device);
+ if (!EFI_ERROR (Status)) {
+ DEBUG (( EFI_D_INFO, "UsbRemoveDevice: device %d removed\n", Device->Address));
- return EFI_SUCCESS;
+ ASSERT (Device->Address < Bus->MaxDevices);
+ Bus->Devices[Device->Address] = NULL;
+ UsbFreeDevice (Device);
+ } else {
+ Bus->Devices[Device->Address]->DisconnectFail = TRUE;
+ }
+ return Status;
}
@@ -968,11 +992,20 @@ UsbHubEnumeration (
UINT8 Byte;
UINT8 Bit;
UINT8 Index;
-
+ USB_DEVICE *Child;
+
ASSERT (Context != NULL);
HubIf = (USB_INTERFACE *) Context;
+ for (Index = 0; Index < HubIf->NumOfPort; Index++) {
+ Child = UsbFindChild (HubIf, Index);
+ if ((Child != NULL) && (Child->DisconnectFail == TRUE)) {
+ DEBUG (( EFI_D_INFO, "UsbEnumeratePort: The device disconnect fails at port %d from hub %p, try again\n", Index, HubIf));
+ UsbRemoveDevice (Child);
+ }
+ }
+
if (HubIf->ChangeMap == NULL) {
return ;
}
@@ -1015,10 +1048,17 @@ UsbRootHubEnumeration (
{
USB_INTERFACE *RootHub;
UINT8 Index;
+ USB_DEVICE *Child;
RootHub = (USB_INTERFACE *) Context;
for (Index = 0; Index < RootHub->NumOfPort; Index++) {
+ Child = UsbFindChild (RootHub, Index);
+ if ((Child != NULL) && (Child->DisconnectFail == TRUE)) {
+ DEBUG (( EFI_D_INFO, "UsbEnumeratePort: The device disconnect fails at port %d from root hub %p, try again\n", Index, RootHub));
+ UsbRemoveDevice (Child);
+ }
+
UsbEnumeratePort (RootHub, Index);
}
}
diff --git a/MdeModulePkg/Bus/Usb/UsbBusDxe/UsbEnumer.h b/MdeModulePkg/Bus/Usb/UsbBusDxe/UsbEnumer.h
index 288d38f63..ef7d44091 100644
--- a/MdeModulePkg/Bus/Usb/UsbBusDxe/UsbEnumer.h
+++ b/MdeModulePkg/Bus/Usb/UsbBusDxe/UsbEnumer.h
@@ -151,7 +151,7 @@ UsbSelectConfig (
@return None.
**/
-VOID
+EFI_STATUS
UsbRemoveConfig (
IN USB_DEVICE *Device
);
diff --git a/MdeModulePkg/Bus/Usb/UsbBusDxe/UsbHub.c b/MdeModulePkg/Bus/Usb/UsbBusDxe/UsbHub.c
index 9e5299c0e..e3752d1f8 100644
--- a/MdeModulePkg/Bus/Usb/UsbBusDxe/UsbHub.c
+++ b/MdeModulePkg/Bus/Usb/UsbBusDxe/UsbHub.c
@@ -968,6 +968,15 @@ UsbHubResetPort (
UINTN Index;
EFI_STATUS Status;
+ Status = UsbHubGetPortStatus (HubIf, Port, &PortState);
+
+ if (EFI_ERROR (Status)) {
+ return Status;
+ } else if (USB_BIT_IS_SET (PortState.PortChangeStatus, USB_PORT_STAT_C_RESET)) {
+ DEBUG (( EFI_D_INFO, "UsbHubResetPort: skip reset on hub %p port %d\n", HubIf, Port));
+ return EFI_SUCCESS;
+ }
+
Status = UsbHubSetPortFeature (HubIf, Port, (EFI_USB_PORT_FEATURE) USB_HUB_PORT_RESET);
if (EFI_ERROR (Status)) {
@@ -988,6 +997,10 @@ UsbHubResetPort (
for (Index = 0; Index < USB_WAIT_PORT_STS_CHANGE_LOOP; Index++) {
Status = UsbHubGetPortStatus (HubIf, Port, &PortState);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
if (!EFI_ERROR (Status) &&
USB_BIT_IS_SET (PortState.PortChangeStatus, USB_PORT_STAT_C_RESET)) {
gBS->Stall (USB_SET_PORT_RECOVERY_STALL);
@@ -1268,6 +1281,16 @@ UsbRootHubResetPort (
// should be handled in the EHCI driver.
//
Bus = RootIf->Device->Bus;
+
+ Status = UsbHcGetRootHubPortStatus (Bus, Port, &PortState);
+
+ if (EFI_ERROR (Status)) {
+ return Status;
+ } else if (USB_BIT_IS_SET (PortState.PortChangeStatus, USB_PORT_STAT_C_RESET)) {
+ DEBUG (( EFI_D_INFO, "UsbRootHubResetPort: skip reset on root port %d\n", Port));
+ return EFI_SUCCESS;
+ }
+
Status = UsbHcSetRootHubPortFeature (Bus, Port, EfiUsbPortReset);
if (EFI_ERROR (Status)) {
diff --git a/MdeModulePkg/Core/Dxe/DxeMain.h b/MdeModulePkg/Core/Dxe/DxeMain.h
index 1e057a5d9..3b2b11d27 100644
--- a/MdeModulePkg/Core/Dxe/DxeMain.h
+++ b/MdeModulePkg/Core/Dxe/DxeMain.h
@@ -67,6 +67,8 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#include <Guid/EventExitBootServiceFailed.h>
#include <Guid/LoadModuleAtFixedAddress.h>
#include <Guid/IdleLoopEvent.h>
+#include <Guid/VectorHandoffTable.h>
+#include <Ppi/VectorHandoffInfo.h>
#include <Library/DxeCoreEntryPoint.h>
#include <Library/DebugLib.h>
diff --git a/MdeModulePkg/Core/Dxe/DxeMain.inf b/MdeModulePkg/Core/Dxe/DxeMain.inf
index 58a4dd9b5..bd9a4bd56 100644
--- a/MdeModulePkg/Core/Dxe/DxeMain.inf
+++ b/MdeModulePkg/Core/Dxe/DxeMain.inf
@@ -2,7 +2,7 @@
# This is core module in DXE phase. It provides an implementation of DXE Core that is
# compliant with DXE CIS.
#
-# Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.<BR>
+# 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
@@ -112,6 +112,10 @@
gLoadFixedAddressConfigurationTableGuid ## SOMETIMES_CONSUMES
gIdleLoopEventGuid ## CONSUMES ## GUID
gEventExitBootServicesFailedGuid ## CONSUMES ## GUID
+ gEfiVectorHandoffTableGuid ## SOMETIMES_PRODUCES ## Configuration
+
+[Ppis]
+ gEfiVectorHandoffInfoPpiGuid ## UNDEFINED
[Protocols]
gEfiStatusCodeRuntimeProtocolGuid ## SOMETIMES_CONSUMES
diff --git a/MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c b/MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c
index ed5a3c9e1..6d2ff8202 100644
--- a/MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c
+++ b/MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c
@@ -1,7 +1,7 @@
/** @file
DXE Core Main Entry Point
-Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.<BR>
+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
@@ -242,11 +242,21 @@ DxeMain (
EFI_PHYSICAL_ADDRESS MemoryBaseAddress;
UINT64 MemoryLength;
PE_COFF_LOADER_IMAGE_CONTEXT ImageContext;
+ UINTN Index;
+ EFI_HOB_GUID_TYPE *GuidHob;
+ EFI_VECTOR_HANDOFF_INFO *VectorInfoList;
+ EFI_VECTOR_HANDOFF_INFO *VectorInfo;
//
// Setup the default exception handlers
//
- SetupCpuExceptionHandlers ();
+ VectorInfoList = NULL;
+ GuidHob = GetNextGuidHob (&gEfiVectorHandoffInfoPpiGuid, HobStart);
+ if (GuidHob != NULL) {
+ VectorInfoList = (EFI_VECTOR_HANDOFF_INFO *) (GET_GUID_HOB_DATA(GuidHob));
+ }
+ Status = InitializeCpuExceptionHandlers (VectorInfoList);
+ ASSERT_EFI_ERROR (Status);
//
// Initialize Debug Agent to support source level debug in DXE phase
@@ -371,6 +381,24 @@ DxeMain (
Status = CoreInitializeEventServices ();
ASSERT_EFI_ERROR (Status);
+ //
+ // Get persisted vector hand-off info from GUIDeed HOB again due to HobStart may be updated,
+ // and install configuration table
+ //
+ GuidHob = GetNextGuidHob (&gEfiVectorHandoffInfoPpiGuid, HobStart);
+ if (GuidHob != NULL) {
+ VectorInfoList = (EFI_VECTOR_HANDOFF_INFO *) (GET_GUID_HOB_DATA(GuidHob));
+ VectorInfo = VectorInfoList;
+ Index = 1;
+ while (VectorInfo->Attribute != EFI_VECTOR_HANDOFF_LAST_ENTRY) {
+ VectorInfo ++;
+ Index ++;
+ }
+ VectorInfo = AllocateCopyPool (sizeof (EFI_VECTOR_HANDOFF_INFO) * Index, (VOID *) VectorInfoList);
+ ASSERT (VectorInfo != NULL);
+ Status = CoreInstallConfigurationTable (&gEfiVectorHandoffTableGuid, (VOID *) VectorInfo);
+ ASSERT_EFI_ERROR (Status);
+ }
//
// Get the Protocols that were passed in from PEI to DXE through GUIDed HOBs
diff --git a/MdeModulePkg/Core/Dxe/Event/Timer.c b/MdeModulePkg/Core/Dxe/Event/Timer.c
index 3b17ae917..087e55e64 100644
--- a/MdeModulePkg/Core/Dxe/Event/Timer.c
+++ b/MdeModulePkg/Core/Dxe/Event/Timer.c
@@ -1,7 +1,7 @@
/** @file
Core Timer Services
-Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.<BR>
+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
@@ -281,6 +281,9 @@ CoreSetTimer (
if (Type != TimerCancel) {
if (Type == TimerPeriodic) {
+ if (TriggerTime == 0) {
+ gTimer->GetTimerPeriod (gTimer, &TriggerTime);
+ }
Event->Timer.Period = TriggerTime;
}
diff --git a/MdeModulePkg/Core/Dxe/Mem/Pool.c b/MdeModulePkg/Core/Dxe/Mem/Pool.c
index e0f0869e5..bc785a8b9 100644
--- a/MdeModulePkg/Core/Dxe/Mem/Pool.c
+++ b/MdeModulePkg/Core/Dxe/Mem/Pool.c
@@ -1,7 +1,7 @@
/** @file
UEFI Memory pool management functions.
-Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.<BR>
+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
@@ -26,9 +26,9 @@ typedef struct {
#define POOL_HEAD_SIGNATURE SIGNATURE_32('p','h','d','0')
typedef struct {
UINT32 Signature;
- UINT32 Size;
+ UINT32 Reserved;
EFI_MEMORY_TYPE Type;
- UINTN Reserved;
+ UINTN Size;
CHAR8 Data[1];
} POOL_HEAD;
@@ -37,7 +37,8 @@ typedef struct {
#define POOL_TAIL_SIGNATURE SIGNATURE_32('p','t','a','l')
typedef struct {
UINT32 Signature;
- UINT32 Size;
+ UINT32 Reserved;
+ UINTN Size;
} POOL_TAIL;
@@ -97,7 +98,7 @@ CoreInitializePool (
mPoolHead[Type].Used = 0;
mPoolHead[Type].MemoryType = (EFI_MEMORY_TYPE) Type;
for (Index=0; Index < MAX_POOL_LIST; Index++) {
- InitializeListHead (&mPoolHead[Type].FreeList[Index]);
+ InitializeListHead (&mPoolHead[Type].FreeList[Index]);
}
}
}
@@ -331,11 +332,11 @@ Done:
// If we have a pool buffer, fill in the header & tail info
//
Head->Signature = POOL_HEAD_SIGNATURE;
- Head->Size = (UINT32) Size;
+ Head->Size = Size;
Head->Type = (EFI_MEMORY_TYPE) PoolType;
Tail = HEAD_TO_TAIL (Head);
Tail->Signature = POOL_TAIL_SIGNATURE;
- Tail->Size = (UINT32) Size;
+ Tail->Size = Size;
Buffer = Head->Data;
DEBUG_CLEAR_MEMORY (Buffer, Size - POOL_OVERHEAD);
diff --git a/MdeModulePkg/Core/DxeIplPeim/DxeIpl.h b/MdeModulePkg/Core/DxeIplPeim/DxeIpl.h
index 97086345a..75372ace8 100644
--- a/MdeModulePkg/Core/DxeIplPeim/DxeIpl.h
+++ b/MdeModulePkg/Core/DxeIplPeim/DxeIpl.h
@@ -2,7 +2,7 @@
Master header file for DxeIpl PEIM. All source files in this module should
include this file for common definitions.
-Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>
+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
@@ -27,6 +27,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#include <Ppi/LoadFile.h>
#include <Ppi/S3Resume2.h>
#include <Ppi/RecoveryModule.h>
+#include <Ppi/VectorHandoffInfo.h>
#include <Guid/MemoryTypeInformation.h>
#include <Guid/MemoryAllocationHob.h>
diff --git a/MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf b/MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf
index 986250bdc..85d0069c2 100644
--- a/MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf
+++ b/MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf
@@ -5,7 +5,7 @@
# PPI to discover and dispatch the DXE Foundation and components that are
# needed to run the DXE Foundation.
#
-# Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>
+# 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
@@ -83,6 +83,7 @@
gEfiPeiLoadFilePpiGuid ## CONSUMES
gEfiPeiS3Resume2PpiGuid ## SOMETIMES_CONSUMES(Consumed on S3 boot path)
gEfiPeiRecoveryModulePpiGuid ## SOMETIMES_CONSUMES(Consumed on recovery boot path)
+ gEfiVectorHandoffInfoPpiGuid ## SOMETIMES_CONSUMES
[Guids]
gEfiMemoryTypeInformationGuid ## SOMETIMES_CONSUMES ## Variable:L"MemoryTypeInformation"
diff --git a/MdeModulePkg/Core/DxeIplPeim/Ia32/DxeLoadFunc.c b/MdeModulePkg/Core/DxeIplPeim/Ia32/DxeLoadFunc.c
index b121e2439..38832cc36 100644
--- a/MdeModulePkg/Core/DxeIplPeim/Ia32/DxeLoadFunc.c
+++ b/MdeModulePkg/Core/DxeIplPeim/Ia32/DxeLoadFunc.c
@@ -1,7 +1,7 @@
/** @file
Ia32-specific functionality for DxeLoad.
-Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>
+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
@@ -83,6 +83,8 @@ HandOffToDxeCore (
EFI_PHYSICAL_ADDRESS VectorAddress;
UINT32 Index;
X64_IDT_TABLE *IdtTableForX64;
+ EFI_VECTOR_HANDOFF_INFO *VectorInfo;
+ EFI_PEI_VECTOR_HANDOFF_INFO_PPI *VectorHandoffInfoPpi;
Status = PeiServicesAllocatePages (EfiBootServicesData, EFI_SIZE_TO_PAGES (STACK_SIZE), &BaseOfStack);
ASSERT_EFI_ERROR (Status);
@@ -183,6 +185,30 @@ HandOffToDxeCore (
);
} else {
//
+ // Get Vector Hand-off Info PPI and build Guided HOB
+ //
+ Status = PeiServicesLocatePpi (
+ &gEfiVectorHandoffInfoPpiGuid,
+ 0,
+ NULL,
+ (VOID **)&VectorHandoffInfoPpi
+ );
+ if (Status == EFI_SUCCESS) {
+ DEBUG ((EFI_D_INFO, "Vector Hand-off Info PPI is gotten, GUIDed HOB is created!\n"));
+ VectorInfo = VectorHandoffInfoPpi->Info;
+ Index = 1;
+ while (VectorInfo->Attribute != EFI_VECTOR_HANDOFF_LAST_ENTRY) {
+ VectorInfo ++;
+ Index ++;
+ }
+ BuildGuidDataHob (
+ &gEfiVectorHandoffInfoPpiGuid,
+ VectorHandoffInfoPpi->Info,
+ sizeof (EFI_VECTOR_HANDOFF_INFO) * Index
+ );
+ }
+
+ //
// Compute the top of the stack we were allocated. Pre-allocate a UINTN
// for safety.
//
diff --git a/MdeModulePkg/Core/DxeIplPeim/X64/DxeLoadFunc.c b/MdeModulePkg/Core/DxeIplPeim/X64/DxeLoadFunc.c
index a6e5c2804..88f1f4746 100644
--- a/MdeModulePkg/Core/DxeIplPeim/X64/DxeLoadFunc.c
+++ b/MdeModulePkg/Core/DxeIplPeim/X64/DxeLoadFunc.c
@@ -1,7 +1,7 @@
/** @file
x64-specifc functionality for DxeLoad.
-Copyright (c) 2006 - 2008, Intel Corporation. All rights reserved.<BR>
+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
@@ -34,10 +34,37 @@ HandOffToDxeCore (
IN EFI_PEI_HOB_POINTERS HobList
)
{
- VOID *BaseOfStack;
- VOID *TopOfStack;
- EFI_STATUS Status;
- UINTN PageTables;
+ VOID *BaseOfStack;
+ VOID *TopOfStack;
+ EFI_STATUS Status;
+ UINTN PageTables;
+ UINT32 Index;
+ EFI_VECTOR_HANDOFF_INFO *VectorInfo;
+ EFI_PEI_VECTOR_HANDOFF_INFO_PPI *VectorHandoffInfoPpi;
+
+ //
+ // Get Vector Hand-off Info PPI and build Guided HOB
+ //
+ Status = PeiServicesLocatePpi (
+ &gEfiVectorHandoffInfoPpiGuid,
+ 0,
+ NULL,
+ (VOID **)&VectorHandoffInfoPpi
+ );
+ if (Status == EFI_SUCCESS) {
+ DEBUG ((EFI_D_INFO, "Vector Hand-off Info PPI is gotten, GUIDed HOB is created!\n"));
+ VectorInfo = VectorHandoffInfoPpi->Info;
+ Index = 1;
+ while (VectorInfo->Attribute != EFI_VECTOR_HANDOFF_LAST_ENTRY) {
+ VectorInfo ++;
+ Index ++;
+ }
+ BuildGuidDataHob (
+ &gEfiVectorHandoffInfoPpiGuid,
+ VectorHandoffInfoPpi->Info,
+ sizeof (EFI_VECTOR_HANDOFF_INFO) * Index
+ );
+ }
//
// Allocate 128KB for the Stack
diff --git a/MdeModulePkg/Core/Pei/Dispatcher/Dispatcher.c b/MdeModulePkg/Core/Pei/Dispatcher/Dispatcher.c
index f4392b78d..96381cd8c 100644
--- a/MdeModulePkg/Core/Pei/Dispatcher/Dispatcher.c
+++ b/MdeModulePkg/Core/Pei/Dispatcher/Dispatcher.c
@@ -606,6 +606,29 @@ PeiLoadFixAddressHook(
PrivateData->PhysicalMemoryBegin = TopLoadingAddress - TotalReservedMemorySize;
PrivateData->FreePhysicalMemoryTop = PrivateData->PhysicalMemoryBegin + PeiMemorySize;
}
+
+/**
+ This routine is invoked in switch stack as PeiCore Entry.
+
+ @param SecCoreData Points to a data structure containing information about the PEI core's operating
+ environment, such as the size and location of temporary RAM, the stack location and
+ the BFV location.
+ @param Private Pointer to old core data that is used to initialize the
+ core's data areas.
+**/
+VOID
+EFIAPI
+PeiCoreEntry (
+ IN CONST EFI_SEC_PEI_HAND_OFF *SecCoreData,
+ IN PEI_CORE_INSTANCE *Private
+ )
+{
+ //
+ // Entry PEI Phase 2
+ //
+ PeiCore (SecCoreData, NULL, Private);
+}
+
/**
Conduct PEIM dispatch.
@@ -637,17 +660,28 @@ PeiDispatcher (
PEIM_FILE_HANDLE_EXTENDED_DATA ExtendedData;
EFI_PEI_TEMPORARY_RAM_SUPPORT_PPI *TemporaryRamSupportPpi;
UINT64 NewStackSize;
+ EFI_PHYSICAL_ADDRESS BaseOfNewHeap;
EFI_PHYSICAL_ADDRESS TopOfNewStack;
EFI_PHYSICAL_ADDRESS TopOfOldStack;
EFI_PHYSICAL_ADDRESS TemporaryRamBase;
UINTN TemporaryRamSize;
- EFI_PHYSICAL_ADDRESS TemporaryStackSize;
+ UINTN TemporaryStackSize;
+ VOID *TemporaryStackBase;
+ UINTN PeiTemporaryRamSize;
+ VOID *PeiTemporaryRamBase;
UINTN StackOffset;
BOOLEAN StackOffsetPositive;
+ EFI_PHYSICAL_ADDRESS HoleMemBase;
+ UINTN HoleMemSize;
EFI_FV_FILE_INFO FvFileInfo;
PEI_CORE_FV_HANDLE *CoreFvHandle;
VOID *LoadFixPeiCodeBegin;
-
+ EFI_PHYSICAL_ADDRESS TempBase1;
+ UINTN TempSize1;
+ EFI_PHYSICAL_ADDRESS TempBase2;
+ UINTN TempSize2;
+ UINTN Index;
+
PeiServices = (CONST EFI_PEI_SERVICES **) &Private->Ps;
PeimEntryPoint = NULL;
PeimFileHandle = NULL;
@@ -881,13 +915,6 @@ PeiDispatcher (
//
TopOfOldStack = (UINTN)SecCoreData->StackBase + SecCoreData->StackSize;
TopOfNewStack = Private->PhysicalMemoryBegin + NewStackSize;
- if (TopOfNewStack >= (UINTN)SecCoreData->PeiTemporaryRamBase) {
- Private->HeapOffsetPositive = TRUE;
- Private->HeapOffset = (UINTN)(TopOfNewStack - (UINTN)SecCoreData->PeiTemporaryRamBase);
- } else {
- Private->HeapOffsetPositive = FALSE;
- Private->HeapOffset = (UINTN)((UINTN)SecCoreData->PeiTemporaryRamBase - TopOfNewStack);
- }
if (TopOfNewStack >= TopOfOldStack) {
StackOffsetPositive = TRUE;
StackOffset = (UINTN)(TopOfNewStack - TopOfOldStack);
@@ -909,21 +936,13 @@ PeiDispatcher (
//
// Cache information from SecCoreData into locals before SecCoreData is converted to a permanent memory address
//
- TemporaryRamBase = (EFI_PHYSICAL_ADDRESS)(UINTN)SecCoreData->TemporaryRamBase;
- TemporaryRamSize = SecCoreData->TemporaryRamSize;
- TemporaryStackSize = SecCoreData->StackSize;
-
- //
- // Caculate new HandOffTable and PrivateData address in permanent memory's stack
- //
- if (StackOffsetPositive) {
- SecCoreData = (CONST EFI_SEC_PEI_HAND_OFF *)((UINTN)(VOID *)SecCoreData + StackOffset);
- Private = (PEI_CORE_INSTANCE *)((UINTN)(VOID *)Private + StackOffset);
- } else {
- SecCoreData = (CONST EFI_SEC_PEI_HAND_OFF *)((UINTN)(VOID *)SecCoreData - StackOffset);
- Private = (PEI_CORE_INSTANCE *)((UINTN)(VOID *)Private - StackOffset);
- }
-
+ TemporaryRamBase = (EFI_PHYSICAL_ADDRESS)(UINTN)SecCoreData->TemporaryRamBase;
+ TemporaryRamSize = SecCoreData->TemporaryRamSize;
+ TemporaryStackSize = SecCoreData->StackSize;
+ TemporaryStackBase = SecCoreData->StackBase;
+ PeiTemporaryRamSize = SecCoreData->PeiTemporaryRamSize;
+ PeiTemporaryRamBase = SecCoreData->PeiTemporaryRamBase;
+
//
// TemporaryRamSupportPpi is produced by platform's SEC
//
@@ -935,6 +954,29 @@ PeiDispatcher (
);
if (!EFI_ERROR (Status)) {
//
+ // Heap Offset
+ //
+ BaseOfNewHeap = TopOfNewStack;
+ if (BaseOfNewHeap >= (UINTN)SecCoreData->PeiTemporaryRamBase) {
+ Private->HeapOffsetPositive = TRUE;
+ Private->HeapOffset = (UINTN)(BaseOfNewHeap - (UINTN)SecCoreData->PeiTemporaryRamBase);
+ } else {
+ Private->HeapOffsetPositive = FALSE;
+ Private->HeapOffset = (UINTN)((UINTN)SecCoreData->PeiTemporaryRamBase - BaseOfNewHeap);
+ }
+
+ //
+ // Caculate new HandOffTable and PrivateData address in permanent memory's stack
+ //
+ if (StackOffsetPositive) {
+ SecCoreData = (CONST EFI_SEC_PEI_HAND_OFF *)((UINTN)(VOID *)SecCoreData + StackOffset);
+ Private = (PEI_CORE_INSTANCE *)((UINTN)(VOID *)Private + StackOffset);
+ } else {
+ SecCoreData = (CONST EFI_SEC_PEI_HAND_OFF *)((UINTN)(VOID *)SecCoreData - StackOffset);
+ Private = (PEI_CORE_INSTANCE *)((UINTN)(VOID *)Private - StackOffset);
+ }
+
+ //
// Temporary Ram Support PPI is provided by platform, it will copy
// temporary memory to permenent memory and do stack switching.
// After invoking Temporary Ram Support PPI, the following code's
@@ -947,18 +989,98 @@ PeiDispatcher (
TemporaryRamSize
);
+ //
+ // Entry PEI Phase 2
+ //
+ PeiCore (SecCoreData, NULL, Private);
} else {
//
- // In IA32/x64/Itanium architecture, we need platform provide
- // TEMPORARY_RAM_MIGRATION_PPI.
+ // Heap Offset
//
- ASSERT (FALSE);
- }
+ BaseOfNewHeap = TopOfNewStack;
+ HoleMemBase = TopOfNewStack;
+ HoleMemSize = TemporaryRamSize - PeiTemporaryRamSize - TemporaryStackSize;
+ if (HoleMemSize != 0) {
+ BaseOfNewHeap = BaseOfNewHeap + HoleMemSize;
+ }
+ if (BaseOfNewHeap >= (UINTN)SecCoreData->PeiTemporaryRamBase) {
+ Private->HeapOffsetPositive = TRUE;
+ Private->HeapOffset = (UINTN)(BaseOfNewHeap - (UINTN)SecCoreData->PeiTemporaryRamBase);
+ } else {
+ Private->HeapOffsetPositive = FALSE;
+ Private->HeapOffset = (UINTN)((UINTN)SecCoreData->PeiTemporaryRamBase - BaseOfNewHeap);
+ }
- //
- // Entry PEI Phase 2
- //
- PeiCore (SecCoreData, NULL, Private);
+ //
+ // Migrate Heap
+ //
+ CopyMem ((UINT8 *) (UINTN) BaseOfNewHeap, (UINT8 *) PeiTemporaryRamBase, PeiTemporaryRamSize);
+
+ //
+ // Migrate Stack
+ //
+ CopyMem ((UINT8 *) (UINTN) (TopOfNewStack - TemporaryStackSize), TemporaryStackBase, TemporaryStackSize);
+
+ //
+ // Copy Hole Range Data
+ // Convert PPI from Hole.
+ //
+ if (HoleMemSize != 0) {
+ //
+ // Prepare Hole
+ //
+ if (PeiTemporaryRamBase < TemporaryStackBase) {
+ TempBase1 = (EFI_PHYSICAL_ADDRESS) (UINTN) PeiTemporaryRamBase;
+ TempSize1 = PeiTemporaryRamSize;
+ TempBase2 = (EFI_PHYSICAL_ADDRESS) (UINTN) TemporaryStackBase;
+ TempSize2 = TemporaryStackSize;
+ } else {
+ TempBase1 = (EFI_PHYSICAL_ADDRESS) (UINTN) TemporaryStackBase;
+ TempSize1 = TemporaryStackSize;
+ TempBase2 =(EFI_PHYSICAL_ADDRESS) (UINTN) PeiTemporaryRamBase;
+ TempSize2 = PeiTemporaryRamSize;
+ }
+ if (TemporaryRamBase < TempBase1) {
+ Private->HoleData[0].Base = TemporaryRamBase;
+ Private->HoleData[0].Size = (UINTN) (TempBase1 - TemporaryRamBase);
+ }
+ if (TempBase1 + TempSize1 < TempBase2) {
+ Private->HoleData[1].Base = TempBase1 + TempSize1;
+ Private->HoleData[1].Size = (UINTN) (TempBase2 - TempBase1 - TempSize1);
+ }
+ if (TempBase2 + TempSize2 < TemporaryRamBase + TemporaryRamSize) {
+ Private->HoleData[2].Base = TempBase2 + TempSize2;
+ Private->HoleData[2].Size = (UINTN) (TemporaryRamBase + TemporaryRamSize - TempBase2 - TempSize2);
+ }
+
+ //
+ // Copy Hole Range data.
+ //
+ for (Index = 0; Index < HOLE_MAX_NUMBER; Index ++) {
+ if (Private->HoleData[Index].Size > 0) {
+ if (HoleMemBase > Private->HoleData[Index].Base) {
+ Private->HoleData[Index].OffsetPositive = TRUE;
+ Private->HoleData[Index].Offset = (UINTN) (HoleMemBase - Private->HoleData[Index].Base);
+ } else {
+ Private->HoleData[Index].OffsetPositive = FALSE;
+ Private->HoleData[Index].Offset = (UINTN) (Private->HoleData[Index].Base - HoleMemBase);
+ }
+ CopyMem ((VOID *) (UINTN) HoleMemBase, (VOID *) (UINTN) Private->HoleData[Index].Base, Private->HoleData[Index].Size);
+ HoleMemBase = HoleMemBase + Private->HoleData[Index].Size;
+ }
+ }
+ }
+
+ //
+ // Switch new stack
+ //
+ SwitchStack (
+ (SWITCH_STACK_ENTRY_POINT)(UINTN)PeiCoreEntry,
+ (VOID *) SecCoreData,
+ (VOID *) Private,
+ (VOID *) (UINTN) TopOfNewStack
+ );
+ }
//
// Code should not come here
diff --git a/MdeModulePkg/Core/Pei/PeiMain.h b/MdeModulePkg/Core/Pei/PeiMain.h
index 6a9feb03c..9656f0718 100644
--- a/MdeModulePkg/Core/Pei/PeiMain.h
+++ b/MdeModulePkg/Core/Pei/PeiMain.h
@@ -28,6 +28,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#include <Ppi/LoadFile.h>
#include <Ppi/Security2.h>
#include <Ppi/TemporaryRamSupport.h>
+#include <Ppi/TemporaryRamDone.h>
#include <Library/DebugLib.h>
#include <Library/PeiCoreEntryPoint.h>
#include <Library/BaseLib.h>
@@ -132,6 +133,14 @@ typedef struct {
UINTN SectionIndex;
} CACHE_SECTION_DATA;
+#define HOLE_MAX_NUMBER 0x3
+typedef struct {
+ EFI_PHYSICAL_ADDRESS Base;
+ UINTN Size;
+ UINTN Offset;
+ BOOLEAN OffsetPositive;
+} HOLE_MEMORY_DATA;
+
///
/// Forward declaration for PEI_CORE_INSTANCE
///
@@ -225,6 +234,11 @@ struct _PEI_CORE_INSTANCE {
// This field points to the shadowed image read function
//
PE_COFF_LOADER_READ_FILE ShadowedImageRead;
+ //
+ // Temp Memory Range is not covered by PeiTempMem and Stack.
+ // Those Memory Range will be migrated into phisical memory.
+ //
+ HOLE_MEMORY_DATA HoleData[HOLE_MAX_NUMBER];
};
///
diff --git a/MdeModulePkg/Core/Pei/PeiMain.inf b/MdeModulePkg/Core/Pei/PeiMain.inf
index 26d1c49d5..27e754283 100644
--- a/MdeModulePkg/Core/Pei/PeiMain.inf
+++ b/MdeModulePkg/Core/Pei/PeiMain.inf
@@ -84,7 +84,8 @@
gEfiPeiFirmwareVolumeInfo2PpiGuid ## NOTIFY ## SOMETIMES_PRODUCES (Produce FvInfo2Ppi if the encapsulated FvImage is found)
gEfiPeiLoadFilePpiGuid ## PRODUCES ## SOMETIMES_CONSUMES (The default load PeImage logic will be used when this PPI doesn't exist)
gEfiPeiSecurity2PpiGuid ## NOTIFY
- gEfiTemporaryRamSupportPpiGuid ## CONSUMES
+ gEfiTemporaryRamSupportPpiGuid ## SOMETIMES_CONSUMES
+ gEfiTemporaryRamDonePpiGuid ## SOMETIMES_CONSUMES
[FixedPcd]
gEfiMdeModulePkgTokenSpaceGuid.PcdPeiCoreMaxFvSupported ## CONSUMES
diff --git a/MdeModulePkg/Core/Pei/PeiMain/PeiMain.c b/MdeModulePkg/Core/Pei/PeiMain/PeiMain.c
index bf000229a..6429ad3a2 100644
--- a/MdeModulePkg/Core/Pei/PeiMain/PeiMain.c
+++ b/MdeModulePkg/Core/Pei/PeiMain/PeiMain.c
@@ -120,7 +120,7 @@ ShadowPeiCore (
from SEC to PEI. After switching stack in the PEI core, it will restart
with the old core data.
- @param SecCoreData Points to a data structure containing information about the PEI core's operating
+ @param SecCoreDataPtr Points to a data structure containing information about the PEI core's operating
environment, such as the size and location of temporary RAM, the stack location and
the BFV location.
@param PpiList Points to a list of one or more PPI descriptors to be installed initially by the PEI core.
@@ -137,23 +137,27 @@ ShadowPeiCore (
VOID
EFIAPI
PeiCore (
- IN CONST EFI_SEC_PEI_HAND_OFF *SecCoreData,
+ IN CONST EFI_SEC_PEI_HAND_OFF *SecCoreDataPtr,
IN CONST EFI_PEI_PPI_DESCRIPTOR *PpiList,
IN VOID *Data
)
{
PEI_CORE_INSTANCE PrivateData;
+ EFI_SEC_PEI_HAND_OFF *SecCoreData;
+ EFI_SEC_PEI_HAND_OFF NewSecCoreData;
EFI_STATUS Status;
PEI_CORE_TEMP_POINTERS TempPtr;
PEI_CORE_INSTANCE *OldCoreData;
EFI_PEI_CPU_IO_PPI *CpuIo;
EFI_PEI_PCI_CFG2_PPI *PciCfg;
EFI_HOB_HANDOFF_INFO_TABLE *HandoffInformationTable;
-
+ EFI_PEI_TEMPORARY_RAM_DONE_PPI *TemporaryRamDonePpi;
+
//
// Retrieve context passed into PEI Core
//
- OldCoreData = (PEI_CORE_INSTANCE *)Data;
+ OldCoreData = (PEI_CORE_INSTANCE *) Data;
+ SecCoreData = (EFI_SEC_PEI_HAND_OFF *) SecCoreDataPtr;
//
// Perform PEI Core phase specific actions.
@@ -250,9 +254,11 @@ PeiCore (
//
// Memory is available to the PEI Core and the PEI Core has been shadowed to memory.
//
-
+ CopyMem (&NewSecCoreData, SecCoreDataPtr, sizeof (NewSecCoreData));
+ SecCoreData = &NewSecCoreData;
+
CopyMem (&PrivateData, OldCoreData, sizeof (PrivateData));
-
+
CpuIo = (VOID*)PrivateData.ServiceTableShadow.CpuIo;
PciCfg = (VOID*)PrivateData.ServiceTableShadow.PciCfg;
@@ -329,6 +335,22 @@ PeiCore (
}
} else {
//
+ // Try to locate Temporary RAM Done Ppi.
+ //
+ Status = PeiServicesLocatePpi (
+ &gEfiTemporaryRamDonePpiGuid,
+ 0,
+ NULL,
+ (VOID**)&TemporaryRamDonePpi
+ );
+ if (!EFI_ERROR (Status)) {
+ //
+ // Disable the use of Temporary RAM after the transition from Temporary RAM to Permanent RAM is complete.
+ //
+ TemporaryRamDonePpi->TemporaryRamDone ();
+ }
+
+ //
// Alert any listeners that there is permanent memory available
//
PERF_START (NULL,"DisMem", NULL, 0);
diff --git a/MdeModulePkg/Core/Pei/Ppi/Ppi.c b/MdeModulePkg/Core/Pei/Ppi/Ppi.c
index 6664b5b89..9fe95acb8 100644
--- a/MdeModulePkg/Core/Pei/Ppi/Ppi.c
+++ b/MdeModulePkg/Core/Pei/Ppi/Ppi.c
@@ -1,7 +1,7 @@
/** @file
EFI PEI Core PPI services
-Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>
+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
@@ -38,7 +38,72 @@ InitializePpiServices (
/**
- Migrate the Hob list from the temporary memory stack to PEI installed memory.
+ Migrate Single PPI Pointer from the temporary memory to PEI installed memory.
+
+ @param PpiPointer Pointer to Ppi
+ @param TempBottom Base of old temporary memory
+ @param TempTop Top of old temporary memory
+ @param Offset Offset of new memory to old temporary memory.
+ @param OffsetPositive Positive flag of Offset value.
+
+**/
+VOID
+ConverSinglePpiPointer (
+ IN PEI_PPI_LIST_POINTERS *PpiPointer,
+ IN UINTN TempBottom,
+ IN UINTN TempTop,
+ IN UINTN Offset,
+ IN BOOLEAN OffsetPositive
+ )
+{
+ if (((UINTN)PpiPointer->Raw < TempTop) &&
+ ((UINTN)PpiPointer->Raw >= TempBottom)) {
+ //
+ // Convert the pointer to the PPI descriptor from the old TempRam
+ // to the relocated physical memory.
+ //
+ if (OffsetPositive) {
+ PpiPointer->Raw = (VOID *) ((UINTN)PpiPointer->Raw + Offset);
+ } else {
+ PpiPointer->Raw = (VOID *) ((UINTN)PpiPointer->Raw - Offset);
+ }
+
+ //
+ // Only when the PEIM descriptor is in the old TempRam should it be necessary
+ // to try to convert the pointers in the PEIM descriptor
+ //
+
+ if (((UINTN)PpiPointer->Ppi->Guid < TempTop) &&
+ ((UINTN)PpiPointer->Ppi->Guid >= TempBottom)) {
+ //
+ // Convert the pointer to the GUID in the PPI or NOTIFY descriptor
+ // from the old TempRam to the relocated physical memory.
+ //
+ if (OffsetPositive) {
+ PpiPointer->Ppi->Guid = (VOID *) ((UINTN)PpiPointer->Ppi->Guid + Offset);
+ } else {
+ PpiPointer->Ppi->Guid = (VOID *) ((UINTN)PpiPointer->Ppi->Guid - Offset);
+ }
+ }
+
+ //
+ // Convert the pointer to the PPI interface structure in the PPI descriptor
+ // from the old TempRam to the relocated physical memory.
+ //
+ if ((UINTN)PpiPointer->Ppi->Ppi < TempTop &&
+ (UINTN)PpiPointer->Ppi->Ppi >= TempBottom) {
+ if (OffsetPositive) {
+ PpiPointer->Ppi->Ppi = (VOID *) ((UINTN)PpiPointer->Ppi->Ppi + Offset);
+ } else {
+ PpiPointer->Ppi->Ppi = (VOID *) ((UINTN)PpiPointer->Ppi->Ppi - Offset);
+ }
+ }
+ }
+}
+
+/**
+
+ Migrate PPI Pointers from the temporary memory stack to PEI installed memory.
@param SecCoreData Points to a data structure containing SEC to PEI handoff data, such as the size
and location of temporary RAM, the stack location and the BFV location.
@@ -52,114 +117,47 @@ ConvertPpiPointers (
)
{
UINT8 Index;
- PEI_PPI_LIST_POINTERS *PpiPointer;
- UINTN OldHeapTop;
- UINTN OldHeapBottom;
- UINTN OldStackTop;
- UINTN OldStackBottom;
-
- OldHeapBottom = (UINTN)SecCoreData->PeiTemporaryRamBase;
- OldHeapTop = (UINTN)SecCoreData->PeiTemporaryRamBase + SecCoreData->PeiTemporaryRamSize;
- OldStackBottom = (UINTN)SecCoreData->StackBase;
- OldStackTop = (UINTN)SecCoreData->StackBase + SecCoreData->StackSize;
+ UINT8 IndexHole;
for (Index = 0; Index < FixedPcdGet32 (PcdPeiCoreMaxPpiSupported); Index++) {
- if (Index < PrivateData->PpiData.PpiListEnd ||
- Index > PrivateData->PpiData.NotifyListEnd) {
- PpiPointer = &PrivateData->PpiData.PpiListPtrs[Index];
-
- if (((UINTN)PpiPointer->Raw < OldHeapTop) &&
- ((UINTN)PpiPointer->Raw >= OldHeapBottom)) {
- //
- // Convert the pointer to the PPI descriptor from the old HOB heap
- // to the relocated HOB heap.
- //
- if (PrivateData->HeapOffsetPositive) {
- PpiPointer->Raw = (VOID *) ((UINTN)PpiPointer->Raw + PrivateData->HeapOffset);
- } else {
- PpiPointer->Raw = (VOID *) ((UINTN)PpiPointer->Raw - PrivateData->HeapOffset);
- }
-
- //
- // Only when the PEIM descriptor is in the old HOB should it be necessary
- // to try to convert the pointers in the PEIM descriptor
- //
-
- if (((UINTN)PpiPointer->Ppi->Guid < OldHeapTop) &&
- ((UINTN)PpiPointer->Ppi->Guid >= OldHeapBottom)) {
- //
- // Convert the pointer to the GUID in the PPI or NOTIFY descriptor
- // from the old HOB heap to the relocated HOB heap.
- //
- if (PrivateData->HeapOffsetPositive) {
- PpiPointer->Ppi->Guid = (VOID *) ((UINTN)PpiPointer->Ppi->Guid + PrivateData->HeapOffset);
- } else {
- PpiPointer->Ppi->Guid = (VOID *) ((UINTN)PpiPointer->Ppi->Guid - PrivateData->HeapOffset);
- }
- }
-
- //
- // Assume that no code is located in the temporary memory, so the pointer to
- // the notification function in the NOTIFY descriptor needs not be converted.
- //
- if (Index < PrivateData->PpiData.PpiListEnd &&
- (UINTN)PpiPointer->Ppi->Ppi < OldHeapTop &&
- (UINTN)PpiPointer->Ppi->Ppi >= OldHeapBottom) {
- //
- // Convert the pointer to the PPI interface structure in the PPI descriptor
- // from the old HOB heap to the relocated HOB heap.
- //
- if (PrivateData->HeapOffsetPositive) {
- PpiPointer->Ppi->Ppi = (VOID *) ((UINTN)PpiPointer->Ppi->Ppi + PrivateData->HeapOffset);
- } else {
- PpiPointer->Ppi->Ppi = (VOID *) ((UINTN)PpiPointer->Ppi->Ppi - PrivateData->HeapOffset);
- }
- }
- } else if (((UINTN)PpiPointer->Raw < OldStackTop) && ((UINTN)PpiPointer->Raw >= OldStackBottom)) {
- //
- // Convert the pointer to the PPI descriptor from the temporary stack
- // to the permanent PEI stack.
- //
- if (PrivateData->StackOffsetPositive) {
- PpiPointer->Raw = (VOID *) ((UINTN)PpiPointer->Raw + PrivateData->StackOffset);
- } else {
- PpiPointer->Raw = (VOID *) ((UINTN)PpiPointer->Raw - PrivateData->StackOffset);
- }
-
- //
- // Try to convert the pointers in the PEIM descriptor
- //
-
- if (((UINTN)PpiPointer->Ppi->Guid < OldStackTop) &&
- ((UINTN)PpiPointer->Ppi->Guid >= OldStackBottom)) {
- //
- // Convert the pointer to the GUID in the PPI or NOTIFY descriptor
- // from the the temporary stack to the permanent PEI stack.
- //
- if (PrivateData->StackOffsetPositive) {
- PpiPointer->Ppi->Guid = (VOID *) ((UINTN)PpiPointer->Ppi->Guid + PrivateData->StackOffset);
- } else {
- PpiPointer->Ppi->Guid = (VOID *) ((UINTN)PpiPointer->Ppi->Guid - PrivateData->StackOffset);
- }
- }
-
- //
- // Assume that no code is located in the temporary memory, so the pointer to
- // the notification function in the NOTIFY descriptor needs not be converted.
- //
- if (Index < PrivateData->PpiData.PpiListEnd &&
- (UINTN)PpiPointer->Ppi->Ppi < OldStackTop &&
- (UINTN)PpiPointer->Ppi->Ppi >= OldStackBottom) {
- //
- // Convert the pointer to the PPI interface structure in the PPI descriptor
- // from the the temporary stack to the permanent PEI stack.
- //
- if (PrivateData->StackOffsetPositive) {
- PpiPointer->Ppi->Ppi = (VOID *) ((UINTN)PpiPointer->Ppi->Ppi + PrivateData->StackOffset);
- } else {
- PpiPointer->Ppi->Ppi = (VOID *) ((UINTN)PpiPointer->Ppi->Ppi - PrivateData->StackOffset);
- }
+ if (Index < PrivateData->PpiData.PpiListEnd || Index > PrivateData->PpiData.NotifyListEnd) {
+ //
+ // Convert PPI pointer in old Heap
+ //
+ ConverSinglePpiPointer (
+ &PrivateData->PpiData.PpiListPtrs[Index],
+ (UINTN)SecCoreData->PeiTemporaryRamBase,
+ (UINTN)SecCoreData->PeiTemporaryRamBase + SecCoreData->PeiTemporaryRamSize,
+ PrivateData->HeapOffset,
+ PrivateData->HeapOffsetPositive
+ );
+
+ //
+ // Convert PPI pointer in old Stack
+ //
+ ConverSinglePpiPointer (
+ &PrivateData->PpiData.PpiListPtrs[Index],
+ (UINTN)SecCoreData->StackBase,
+ (UINTN)SecCoreData->StackBase + SecCoreData->StackSize,
+ PrivateData->StackOffset,
+ PrivateData->StackOffsetPositive
+ );
+
+ //
+ // Convert PPI pointer in old TempRam Hole
+ //
+ for (IndexHole = 0; IndexHole < HOLE_MAX_NUMBER; IndexHole ++) {
+ if (PrivateData->HoleData[IndexHole].Size == 0) {
+ continue;
}
+
+ ConverSinglePpiPointer (
+ &PrivateData->PpiData.PpiListPtrs[Index],
+ (UINTN)PrivateData->HoleData[IndexHole].Base,
+ (UINTN)PrivateData->HoleData[IndexHole].Base + PrivateData->HoleData[IndexHole].Size,
+ PrivateData->HoleData[IndexHole].Offset,
+ PrivateData->HoleData[IndexHole].OffsetPositive
+ );
}
}
}
diff --git a/MdeModulePkg/Core/PiSmmCore/Notify.c b/MdeModulePkg/Core/PiSmmCore/Notify.c
index eb5059dd7..5ec0aa71a 100644
--- a/MdeModulePkg/Core/PiSmmCore/Notify.c
+++ b/MdeModulePkg/Core/PiSmmCore/Notify.c
@@ -1,7 +1,7 @@
/** @file
Support functions for UEFI protocol notification infrastructure.
- Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.<BR>
+ Copyright (c) 2009 - 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
@@ -94,6 +94,8 @@ SmmRemoveInterfaceFromProtocol (
@retval EFI_INVALID_PARAMETER Invalid parameter
@retval EFI_SUCCESS Successfully returned the registration record
that has been added
+ @retval EFI_OUT_OF_RESOURCES Not enough memory resource to finish the request
+ @retval EFI_NOT_FOUND If the registration is not found when Function == NULL
**/
EFI_STATUS
@@ -109,10 +111,40 @@ SmmRegisterProtocolNotify (
LIST_ENTRY *Link;
EFI_STATUS Status;
- if ((Protocol == NULL) || (Function == NULL) || (Registration == NULL)) {
+ if (Protocol == NULL || Registration == NULL) {
return EFI_INVALID_PARAMETER;
}
+ if (Function == NULL) {
+ //
+ // Get the protocol entry per Protocol
+ //
+ ProtEntry = SmmFindProtocolEntry ((EFI_GUID *) Protocol, FALSE);
+ if (ProtEntry != NULL) {
+ ProtNotify = (PROTOCOL_NOTIFY * )*Registration;
+ for (Link = ProtEntry->Notify.ForwardLink;
+ Link != &ProtEntry->Notify;
+ Link = Link->ForwardLink) {
+ //
+ // Compare the notification record
+ //
+ if (ProtNotify == (CR(Link, PROTOCOL_NOTIFY, Link, PROTOCOL_NOTIFY_SIGNATURE))){
+ //
+ // If Registration is an existing registration, then unhook it
+ //
+ ProtNotify->Signature = 0;
+ RemoveEntryList (&ProtNotify->Link);
+ FreePool (ProtNotify);
+ return EFI_SUCCESS;
+ }
+ }
+ }
+ //
+ // If the registration is not found
+ //
+ return EFI_NOT_FOUND;
+ }
+
ProtNotify = NULL;
//
diff --git a/MdeModulePkg/Include/Guid/PcdDataBaseSignatureGuid.h b/MdeModulePkg/Include/Guid/PcdDataBaseSignatureGuid.h
new file mode 100644
index 000000000..22c0d95f6
--- /dev/null
+++ b/MdeModulePkg/Include/Guid/PcdDataBaseSignatureGuid.h
@@ -0,0 +1,147 @@
+/** @file
+ Guid for Pcd DataBase Signature.
+
+Copyright (c) 2012 - 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 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.
+
+**/
+
+#ifndef _PCD_DATABASE_SIGNATURE_GUID_H_
+#define _PCD_DATABASE_SIGNATURE_GUID_H_
+
+#define PCD_DATA_BASE_SIGNATURE_GUID \
+{ 0x3c7d193c, 0x682c, 0x4c14, { 0xa6, 0x8f, 0x55, 0x2d, 0xea, 0x4f, 0x43, 0x7e } }
+
+extern EFI_GUID gPcdDataBaseSignatureGuid;
+
+//
+// Common definitions
+//
+typedef UINT8 SKU_ID;
+
+#define PCD_TYPE_SHIFT 28
+
+#define PCD_TYPE_DATA (0x0U << PCD_TYPE_SHIFT)
+#define PCD_TYPE_HII (0x8U << PCD_TYPE_SHIFT)
+#define PCD_TYPE_VPD (0x4U << PCD_TYPE_SHIFT)
+#define PCD_TYPE_SKU_ENABLED (0x2U << PCD_TYPE_SHIFT)
+#define PCD_TYPE_STRING (0x1U << PCD_TYPE_SHIFT)
+
+#define PCD_TYPE_ALL_SET (PCD_TYPE_DATA | PCD_TYPE_HII | PCD_TYPE_VPD | PCD_TYPE_SKU_ENABLED | PCD_TYPE_STRING)
+
+#define PCD_DATUM_TYPE_SHIFT 24
+
+#define PCD_DATUM_TYPE_POINTER (0x0U << PCD_DATUM_TYPE_SHIFT)
+#define PCD_DATUM_TYPE_UINT8 (0x1U << PCD_DATUM_TYPE_SHIFT)
+#define PCD_DATUM_TYPE_UINT16 (0x2U << PCD_DATUM_TYPE_SHIFT)
+#define PCD_DATUM_TYPE_UINT32 (0x4U << PCD_DATUM_TYPE_SHIFT)
+#define PCD_DATUM_TYPE_UINT64 (0x8U << PCD_DATUM_TYPE_SHIFT)
+
+#define PCD_DATUM_TYPE_ALL_SET (PCD_DATUM_TYPE_POINTER | \
+ PCD_DATUM_TYPE_UINT8 | \
+ PCD_DATUM_TYPE_UINT16 | \
+ PCD_DATUM_TYPE_UINT32 | \
+ PCD_DATUM_TYPE_UINT64)
+
+#define PCD_DATUM_TYPE_SHIFT2 20
+
+#define PCD_DATUM_TYPE_UINT8_BOOLEAN (0x1U << PCD_DATUM_TYPE_SHIFT2)
+
+#define PCD_DATABASE_OFFSET_MASK (~(PCD_TYPE_ALL_SET | PCD_DATUM_TYPE_ALL_SET | PCD_DATUM_TYPE_UINT8_BOOLEAN))
+
+typedef struct {
+ UINT32 ExTokenNumber;
+ UINT16 TokenNumber; // Token Number for Dynamic-Ex PCD.
+ UINT16 ExGuidIndex; // Index of GuidTable in units of GUID.
+} DYNAMICEX_MAPPING;
+
+typedef struct {
+ UINT32 SkuDataStartOffset; // Offset(with TYPE info) from the PCD_DB.
+ UINT32 SkuIdTableOffset; // Offset from the PCD_DB.
+} SKU_HEAD;
+
+typedef struct {
+ UINT32 StringIndex; // Offset in String Table in units of UINT8.
+ UINT32 DefaultValueOffset; // Offset of the Default Value.
+ UINT16 GuidTableIndex; // Offset in Guid Table in units of GUID.
+ UINT16 Offset; // Offset in Variable.
+} VARIABLE_HEAD;
+
+typedef struct {
+ UINT32 Offset;
+} VPD_HEAD;
+
+typedef UINT32 STRING_HEAD;
+
+typedef UINT16 SIZE_INFO;
+
+typedef struct {
+ UINT32 TokenSpaceCNameIndex; // Offset in String Table in units of UINT8.
+ UINT32 PcdCNameIndex; // Offset in String Table in units of UINT8.
+} PCD_NAME_INDEX;
+
+typedef UINT32 TABLE_OFFSET;
+
+typedef struct {
+ GUID Signature; // PcdDataBaseGuid.
+ UINT32 BuildVersion;
+ UINT32 Length;
+ UINT32 UninitDataBaseSize; // Total size for PCD those default value with 0.
+ TABLE_OFFSET LocalTokenNumberTableOffset;
+ TABLE_OFFSET ExMapTableOffset;
+ TABLE_OFFSET GuidTableOffset;
+ TABLE_OFFSET StringTableOffset;
+ TABLE_OFFSET SizeTableOffset;
+ TABLE_OFFSET SkuIdTableOffset;
+ TABLE_OFFSET PcdNameTableOffset;
+ UINT16 LocalTokenCount; // LOCAL_TOKEN_NUMBER for all.
+ UINT16 ExTokenCount; // EX_TOKEN_NUMBER for DynamicEx.
+ UINT16 GuidTableCount; // The Number of Guid in GuidTable.
+ SKU_ID SystemSkuId; // Current SkuId value.
+ UINT8 Pad; // Pad bytes to satisfy the alignment.
+
+ //
+ // Default initialized external PCD database binary structure
+ //
+ // Padding is needed to keep necessary alignment
+ //
+ //UINT64 ValueUint64[];
+ //UINT32 ValueUint32[];
+ //VPD_HEAD VpdHead[]; // VPD Offset
+ //DYNAMICEX_MAPPING ExMapTable[]; // DynamicEx PCD mapped to LocalIndex in LocalTokenNumberTable. It can be accessed by the ExMapTableOffset.
+ //UINT32 LocalTokenNumberTable[]; // Offset | DataType | PCD Type. It can be accessed by LocalTokenNumberTableOffset.
+ //GUID GuidTable[]; // GUID for DynamicEx and HII PCD variable Guid. It can be accessed by the GuidTableOffset.
+ //STRING_HEAD StringHead[]; // String PCD
+ //PCD_NAME_INDEX PcdNameTable[]; // PCD name index info. It can be accessed by the PcdNameTableOffset.
+ //VARIABLE_HEAD VariableHead[]; // HII PCD
+ //SKU_HEAD SkuHead[]; // Store SKU info for each PCD with SKU enable.
+ //UINT8 StringTable[]; // String for String PCD value and HII PCD Variable Name. It can be accessed by StringTableOffset.
+ //SIZE_INFO SizeTable[]; // MaxSize and CurSize for String PCD. It can be accessed by SizeTableOffset.
+ //UINT16 ValueUint16[];
+ //UINT8 ValueUint8[];
+ //BOOLEAN ValueBoolean[];
+ //UINT8 SkuIdTable[]; // SkuIds system supports.
+ //UINT8 SkuIndexTable[]; // SkuIds for each PCD with SKU enable.
+
+} PCD_DATABASE_INIT;
+
+//
+// PEI and DXE Pcd driver use the same PCD database
+//
+typedef PCD_DATABASE_INIT PEI_PCD_DATABASE;
+typedef PCD_DATABASE_INIT DXE_PCD_DATABASE;
+
+
+typedef struct {
+ PEI_PCD_DATABASE *PeiDb;
+ DXE_PCD_DATABASE *DxeDb;
+} PCD_DATABASE;
+
+
+#endif
diff --git a/MdeModulePkg/Include/Library/CpuExceptionHandlerLib.h b/MdeModulePkg/Include/Library/CpuExceptionHandlerLib.h
index 6be32b232..16384f831 100644
--- a/MdeModulePkg/Include/Library/CpuExceptionHandlerLib.h
+++ b/MdeModulePkg/Include/Library/CpuExceptionHandlerLib.h
@@ -1,7 +1,8 @@
/** @file
- CPU Exception library provides the CPU exception handler.
+ CPU Exception library provides the default CPU interrupt/exception handler.
+ It also provides capability to register user interrupt/exception handler.
- Copyright (c) 2012, Intel Corporation. All rights reserved.<BR>
+ Copyright (c) 2012 - 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
@@ -12,17 +13,84 @@
**/
-#ifndef __CPU_EXCEPTION_LIB_H__
-#define __CPU_EXCEPTION_LIB_H__
+#ifndef __CPU_EXCEPTION_HANDLER_LIB_H__
+#define __CPU_EXCEPTION_HANDLER_LIB_H__
+
+#include <Ppi/VectorHandoffInfo.h>
+#include <Protocol/Cpu.h>
/**
- Setup CPU exception handlers.
-
+ Initializes all CPU exceptions entries and provides the default exception handlers.
+
+ Caller should try to get an array of interrupt and/or exception vectors that are in use and need to
+ persist by EFI_VECTOR_HANDOFF_INFO defined in PI 1.3 specification.
+ If caller cannot get reserved vector list or it does not exists, set VectorInfo to NULL.
+ If VectorInfo is not NULL, the exception vectors will be initialized per vector attribute accordingly.
+
+ @param[in] VectorInfo Pointer to reserved vector list.
+
+ @retval EFI_SUCCESS CPU Exception Entries have been successfully initialized
+ with default exception handlers.
+ @retval EFI_INVALID_PARAMETER VectorInfo includes the invalid content if VectorInfo is not NULL.
+ @retval EFI_UNSUPPORTED This function is not supported.
+
**/
-VOID
+EFI_STATUS
+EFIAPI
+InitializeCpuExceptionHandlers (
+ IN EFI_VECTOR_HANDOFF_INFO *VectorInfo OPTIONAL
+ );
+
+/**
+ Initializes all CPU interrupt/exceptions entries and provides the default interrupt/exception handlers.
+
+ Caller should try to get an array of interrupt and/or exception vectors that are in use and need to
+ persist by EFI_VECTOR_HANDOFF_INFO defined in PI 1.3 specification.
+ If caller cannot get reserved vector list or it does not exists, set VectorInfo to NULL.
+ If VectorInfo is not NULL, the exception vectors will be initialized per vector attribute accordingly.
+
+ @param[in] VectorInfo Pointer to reserved vector list.
+
+ @retval EFI_SUCCESS All CPU interrupt/exception entries have been successfully initialized
+ with default interrupt/exception handlers.
+ @retval EFI_INVALID_PARAMETER VectorInfo includes the invalid content if VectorInfo is not NULL.
+ @retval EFI_UNSUPPORTED This function is not supported.
+
+**/
+EFI_STATUS
+EFIAPI
+InitializeCpuInterruptHandlers (
+ IN EFI_VECTOR_HANDOFF_INFO *VectorInfo OPTIONAL
+ );
+
+/**
+ Registers a function to be called from the processor interrupt handler.
+
+ This function registers and enables the handler specified by InterruptHandler for a processor
+ interrupt or exception type specified by InterruptType. If InterruptHandler is NULL, then the
+ handler for the processor interrupt or exception type specified by InterruptType is uninstalled.
+ The installed handler is called once for each processor interrupt or exception.
+ NOTE: This function should be invoked after InitializeCpuExceptionHandlers() or
+ InitializeCpuInterruptHandlers() invoked, otherwise EFI_UNSUPPORTED returned.
+
+ @param[in] InterruptType Defines which interrupt or exception to hook.
+ @param[in] InterruptHandler A pointer to a function of type EFI_CPU_INTERRUPT_HANDLER that is called
+ when a processor interrupt occurs. If this parameter is NULL, then the handler
+ will be uninstalled.
+
+ @retval EFI_SUCCESS The handler for the processor interrupt was successfully installed or uninstalled.
+ @retval EFI_ALREADY_STARTED InterruptHandler is not NULL, and a handler for InterruptType was
+ previously installed.
+ @retval EFI_INVALID_PARAMETER InterruptHandler is NULL, and a handler for InterruptType was not
+ previously installed.
+ @retval EFI_UNSUPPORTED The interrupt specified by InterruptType is not supported,
+ or this function is not supported.
+*/
+EFI_STATUS
EFIAPI
-SetupCpuExceptionHandlers (
- VOID
+RegisterCpuInterruptHandler (
+ IN EFI_EXCEPTION_TYPE InterruptType,
+ IN EFI_CPU_INTERRUPT_HANDLER InterruptHandler
);
#endif
diff --git a/MdeModulePkg/Library/CpuExceptionHandlerLibNull/CpuExceptionHandlerLibNull.c b/MdeModulePkg/Library/CpuExceptionHandlerLibNull/CpuExceptionHandlerLibNull.c
index 3dd9da8b8..ded14a335 100644
--- a/MdeModulePkg/Library/CpuExceptionHandlerLibNull/CpuExceptionHandlerLibNull.c
+++ b/MdeModulePkg/Library/CpuExceptionHandlerLibNull/CpuExceptionHandlerLibNull.c
@@ -1,7 +1,7 @@
/** @file
CPU Exception Handler library implementition with empty functions.
- Copyright (c) 2012, Intel Corporation. All rights reserved.<BR>
+ Copyright (c) 2012 - 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
@@ -11,17 +11,89 @@
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
+#include <PiPei.h>
+#include <Library/CpuExceptionHandlerLib.h>
+/**
+ Initializes all CPU exceptions entries and provides the default exception handlers.
+
+ Caller should try to get an array of interrupt and/or exception vectors that are in use and need to
+ persist by EFI_VECTOR_HANDOFF_INFO defined in PI 1.3 specification.
+ If caller cannot get reserved vector list or it does not exists, set VectorInfo to NULL.
+ If VectorInfo is not NULL, the exception vectors will be initialized per vector attribute accordingly.
+
+ @param[in] VectorInfo Pointer to reserved vector list.
+
+ @retval EFI_SUCCESS CPU Exception Entries have been successfully initialized
+ with default exception handlers.
+ @retval EFI_INVALID_PARAMETER VectorInfo includes the invalid content if VectorInfo is not NULL.
+ @retval EFI_UNSUPPORTED This function is not supported.
+
+**/
+EFI_STATUS
+EFIAPI
+InitializeCpuExceptionHandlers (
+ IN EFI_VECTOR_HANDOFF_INFO *VectorInfo OPTIONAL
+ )
+{
+ return EFI_SUCCESS;
+}
/**
- Setup CPU exception handlers.
-
+ Initializes all CPU interrupt/exceptions entries and provides the default interrupt/exception handlers.
+
+ Caller should try to get an array of interrupt and/or exception vectors that are in use and need to
+ persist by EFI_VECTOR_HANDOFF_INFO defined in PI 1.3 specification.
+ If caller cannot get reserved vector list or it does not exists, set VectorInfo to NULL.
+ If VectorInfo is not NULL, the exception vectors will be initialized per vector attribute accordingly.
+
+ @param[in] VectorInfo Pointer to reserved vector list.
+
+ @retval EFI_SUCCESS All CPU interrupt/exception entries have been successfully initialized
+ with default interrupt/exception handlers.
+ @retval EFI_INVALID_PARAMETER VectorInfo includes the invalid content if VectorInfo is not NULL.
+ @retval EFI_UNSUPPORTED This function is not supported.
+
**/
-VOID
+EFI_STATUS
+EFIAPI
+InitializeCpuInterruptHandlers (
+ IN EFI_VECTOR_HANDOFF_INFO *VectorInfo OPTIONAL
+ )
+{
+ return EFI_SUCCESS;
+}
+
+/**
+ Registers a function to be called from the processor interrupt handler.
+
+ This function registers and enables the handler specified by InterruptHandler for a processor
+ interrupt or exception type specified by InterruptType. If InterruptHandler is NULL, then the
+ handler for the processor interrupt or exception type specified by InterruptType is uninstalled.
+ The installed handler is called once for each processor interrupt or exception.
+ NOTE: This function should be invoked after InitializeCpuExceptionHandlers() or
+ InitializeCpuInterruptHandlers() invoked, otherwise EFI_UNSUPPORTED returned.
+
+ @param[in] InterruptType Defines which interrupt or exception to hook.
+ @param[in] InterruptHandler A pointer to a function of type EFI_CPU_INTERRUPT_HANDLER that is called
+ when a processor interrupt occurs. If this parameter is NULL, then the handler
+ will be uninstalled.
+
+ @retval EFI_SUCCESS The handler for the processor interrupt was successfully installed or uninstalled.
+ @retval EFI_ALREADY_STARTED InterruptHandler is not NULL, and a handler for InterruptType was
+ previously installed.
+ @retval EFI_INVALID_PARAMETER InterruptHandler is NULL, and a handler for InterruptType was not
+ previously installed.
+ @retval EFI_UNSUPPORTED The interrupt specified by InterruptType is not supported,
+ or this function is not supported.
+*/
+EFI_STATUS
EFIAPI
-SetupCpuExceptionHandlers (
- VOID
+RegisterCpuInterruptHandler (
+ IN EFI_EXCEPTION_TYPE InterruptType,
+ IN EFI_CPU_INTERRUPT_HANDLER InterruptHandler
)
-{
+{
+ return EFI_SUCCESS;
}
diff --git a/MdeModulePkg/Library/CpuExceptionHandlerLibNull/CpuExceptionHandlerLibNull.inf b/MdeModulePkg/Library/CpuExceptionHandlerLibNull/CpuExceptionHandlerLibNull.inf
index 47e55feee..0ec02ac41 100644
--- a/MdeModulePkg/Library/CpuExceptionHandlerLibNull/CpuExceptionHandlerLibNull.inf
+++ b/MdeModulePkg/Library/CpuExceptionHandlerLibNull/CpuExceptionHandlerLibNull.inf
@@ -1,7 +1,7 @@
## @file
# Null instance of CPU Exception Handler Library with empty functions.
#
-# Copyright (c) 2012, Intel Corporation. All rights reserved.<BR>
+# Copyright (c) 2012 - 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
@@ -16,7 +16,7 @@
INF_VERSION = 0x00010005
BASE_NAME = CpuExceptionHandlerLibNull
FILE_GUID = 3175E6B9-4B01-496a-9A2B-64AF02D87E34
- MODULE_TYPE = BASE
+ MODULE_TYPE = PEIM
VERSION_STRING = 1.0
LIBRARY_CLASS = CpuExceptionHandlerLib
diff --git a/MdeModulePkg/Library/DxeNetLib/DxeNetLib.c b/MdeModulePkg/Library/DxeNetLib/DxeNetLib.c
index cfda3962b..467b82280 100644
--- a/MdeModulePkg/Library/DxeNetLib/DxeNetLib.c
+++ b/MdeModulePkg/Library/DxeNetLib/DxeNetLib.c
@@ -2250,7 +2250,7 @@ NetLibGetMacAddress (
// Try to get SNP mode from MNP
//
Status = Mnp->GetModeData (Mnp, NULL, &SnpModeData);
- if (EFI_ERROR (Status)) {
+ if (EFI_ERROR (Status) && (Status != EFI_NOT_STARTED)) {
MnpSb->DestroyChild (MnpSb, MnpChildHandle);
return Status;
}
diff --git a/MdeModulePkg/MdeModulePkg.dec b/MdeModulePkg/MdeModulePkg.dec
index fc9f9ccd9..b627eb101 100644
--- a/MdeModulePkg/MdeModulePkg.dec
+++ b/MdeModulePkg/MdeModulePkg.dec
@@ -111,6 +111,10 @@
# Include/Guid/PcdDataBaseHobGuid.h
gPcdDataBaseHobGuid = { 0xEA296D92, 0x0B69, 0x423C, { 0x8C, 0x28, 0x33, 0xB4, 0xE0, 0xA9, 0x12, 0x68 }}
+ ## Guid for PCD DataBase signature.
+ # Include/Guid/PcdDataBaseSignatureGuid.h
+ gPcdDataBaseSignatureGuid = { 0x3c7d193c, 0x682c, 0x4c14, { 0xa6, 0x8f, 0x55, 0x2d, 0xea, 0x4f, 0x43, 0x7e }}
+
## Guid for EDKII implementation GUIDed opcodes
# Include/Guid/MdeModuleHii.h
gEfiIfrTianoGuid = { 0xf0b1735, 0x87a0, 0x4193, {0xb2, 0x66, 0x53, 0x8c, 0x38, 0xaf, 0x48, 0xce }}
diff --git a/MdeModulePkg/Universal/Acpi/BootScriptExecutorDxe/BootScriptExecutorDxe.inf b/MdeModulePkg/Universal/Acpi/BootScriptExecutorDxe/BootScriptExecutorDxe.inf
index 04d4893a9..4777f9d2e 100644
--- a/MdeModulePkg/Universal/Acpi/BootScriptExecutorDxe/BootScriptExecutorDxe.inf
+++ b/MdeModulePkg/Universal/Acpi/BootScriptExecutorDxe/BootScriptExecutorDxe.inf
@@ -4,7 +4,7 @@
# This is a standalone Boot Script Executor. Standalone means it does not
# depends on any PEI or DXE service.
#
-# Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.<BR>
+# 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
@@ -75,6 +75,9 @@
gPerformanceProtocolGuid
gEfiEventExitBootServicesGuid
+[Protocols]
+ gEfiDxeSmmReadyToLockProtocolGuid
+
[FeaturePcd]
gEfiMdeModulePkgTokenSpaceGuid.PcdDxeIplSwitchToLongMode
diff --git a/MdeModulePkg/Universal/Acpi/BootScriptExecutorDxe/IA32/SetIdtEntry.c b/MdeModulePkg/Universal/Acpi/BootScriptExecutorDxe/IA32/SetIdtEntry.c
index 04eba0d75..63b06ba5d 100644
--- a/MdeModulePkg/Universal/Acpi/BootScriptExecutorDxe/IA32/SetIdtEntry.c
+++ b/MdeModulePkg/Universal/Acpi/BootScriptExecutorDxe/IA32/SetIdtEntry.c
@@ -3,7 +3,7 @@
Set a IDT entry for interrupt vector 3 for debug purpose for IA32 platform
-Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.<BR>
+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
@@ -30,6 +30,7 @@ SetIdtEntry (
IA32_IDT_GATE_DESCRIPTOR *IdtEntry;
IA32_DESCRIPTOR *IdtDescriptor;
UINTN S3DebugBuffer;
+ EFI_STATUS Status;
//
// Restore IDT for debug
@@ -40,7 +41,8 @@ SetIdtEntry (
//
// Setup the default CPU exception handlers
//
- SetupCpuExceptionHandlers ();
+ Status = InitializeCpuExceptionHandlers (NULL);
+ ASSERT_EFI_ERROR (Status);
DEBUG_CODE (
//
diff --git a/MdeModulePkg/Universal/Acpi/BootScriptExecutorDxe/ScriptExecute.c b/MdeModulePkg/Universal/Acpi/BootScriptExecutorDxe/ScriptExecute.c
index c5eec24e0..651a9dea5 100644
--- a/MdeModulePkg/Universal/Acpi/BootScriptExecutorDxe/ScriptExecute.c
+++ b/MdeModulePkg/Universal/Acpi/BootScriptExecutorDxe/ScriptExecute.c
@@ -1,10 +1,10 @@
/** @file
This is the code for Boot Script Executer module.
- This driver is dispatched by Dxe core and the driver will reload itself to ACPI NVS memory
+ This driver is dispatched by Dxe core and the driver will reload itself to ACPI reserved memory
in the entry point. The functionality is to interpret and restore the S3 boot script
-Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.<BR>
+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
@@ -22,6 +22,8 @@ EFI_GUID mBootScriptExecutorImageGuid = {
0x9a8d3433, 0x9fe8, 0x42b6, { 0x87, 0xb, 0x1e, 0x31, 0xc8, 0x4e, 0xbe, 0x3b }
};
+BOOLEAN mPage1GSupport = FALSE;
+
/**
Entry function of Boot script exector. This function will be executed in
S3 boot path.
@@ -68,6 +70,16 @@ S3BootScriptExecutorEntryFunction (
// for that parameter.
//
Status = S3BootScriptExecute ();
+
+ //
+ // If invalid script table or opcode in S3 boot script table.
+ //
+ ASSERT_EFI_ERROR (Status);
+
+ if (EFI_ERROR (Status)) {
+ CpuDeadLoop ();
+ return Status;
+ }
AsmWbinvd ();
@@ -195,6 +207,121 @@ S3BootScriptExecutorEntryFunction (
CpuDeadLoop();
return EFI_UNSUPPORTED;
}
+
+/**
+ This is the Event notification function to reload BootScriptExecutor image
+ to RESERVED mem and save it to LockBox.
+
+ @param Event Pointer to this event
+ @param Context Event hanlder private data
+ **/
+VOID
+EFIAPI
+ReadyToLockEventNotify (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+{
+ EFI_STATUS Status;
+ VOID *Interface;
+ UINT8 *Buffer;
+ UINTN BufferSize;
+ EFI_HANDLE NewImageHandle;
+ UINTN Pages;
+ EFI_PHYSICAL_ADDRESS FfsBuffer;
+ PE_COFF_LOADER_IMAGE_CONTEXT ImageContext;
+
+ Status = gBS->LocateProtocol (&gEfiDxeSmmReadyToLockProtocolGuid, NULL, &Interface);
+ if (EFI_ERROR (Status)) {
+ return;
+ }
+
+ //
+ // A workaround: Here we install a dummy handle
+ //
+ NewImageHandle = NULL;
+ Status = gBS->InstallProtocolInterface (
+ &NewImageHandle,
+ &gEfiCallerIdGuid,
+ EFI_NATIVE_INTERFACE,
+ NULL
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Reload BootScriptExecutor image itself to RESERVED mem
+ //
+ Status = GetSectionFromAnyFv (
+ &gEfiCallerIdGuid,
+ EFI_SECTION_PE32,
+ 0,
+ (VOID **) &Buffer,
+ &BufferSize
+ );
+ ASSERT_EFI_ERROR (Status);
+ ImageContext.Handle = Buffer;
+ ImageContext.ImageRead = PeCoffLoaderImageReadFromMemory;
+ //
+ // Get information about the image being loaded
+ //
+ Status = PeCoffLoaderGetImageInfo (&ImageContext);
+ ASSERT_EFI_ERROR (Status);
+ Pages = EFI_SIZE_TO_PAGES(BufferSize + ImageContext.SectionAlignment);
+ FfsBuffer = 0xFFFFFFFF;
+ Status = gBS->AllocatePages (
+ AllocateMaxAddress,
+ EfiReservedMemoryType,
+ Pages,
+ &FfsBuffer
+ );
+ ASSERT_EFI_ERROR (Status);
+ ImageContext.ImageAddress = (PHYSICAL_ADDRESS)(UINTN)FfsBuffer;
+ //
+ // Align buffer on section boundry
+ //
+ ImageContext.ImageAddress += ImageContext.SectionAlignment - 1;
+ ImageContext.ImageAddress &= ~(ImageContext.SectionAlignment - 1);
+ //
+ // Load the image to our new buffer
+ //
+ Status = PeCoffLoaderLoadImage (&ImageContext);
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Relocate the image in our new buffer
+ //
+ Status = PeCoffLoaderRelocateImage (&ImageContext);
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Free the buffer allocated by ReadSection since the image has been relocated in the new buffer
+ //
+ gBS->FreePool (Buffer);
+
+ //
+ // 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, gST);
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Additional step for BootScript integrity
+ // Save BootScriptExecutor image
+ //
+ Status = SaveLockBox (
+ &mBootScriptExecutorImageGuid,
+ (VOID *)(UINTN)ImageContext.ImageAddress,
+ (UINTN)ImageContext.ImageSize
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ Status = SetLockBoxAttributes (&mBootScriptExecutorImageGuid, LOCK_BOX_ATTRIBUTE_RESTORE_IN_PLACE);
+ ASSERT_EFI_ERROR (Status);
+
+ gBS->CloseEvent (Event);
+}
+
/**
Entrypoint of Boot script exector driver, this function will be executed in
normal boot phase and invoked by DXE dispatch.
@@ -212,16 +339,16 @@ BootScriptExecutorEntryPoint (
IN EFI_SYSTEM_TABLE *SystemTable
)
{
- UINT8 *Buffer;
UINTN BufferSize;
UINTN Pages;
- EFI_PHYSICAL_ADDRESS FfsBuffer;
- PE_COFF_LOADER_IMAGE_CONTEXT ImageContext;
BOOT_SCRIPT_EXECUTOR_VARIABLE *EfiBootScriptExecutorVariable;
EFI_PHYSICAL_ADDRESS BootScriptExecutorBuffer;
EFI_STATUS Status;
VOID *DevicePath;
- EFI_HANDLE NewImageHandle;
+ EFI_EVENT ReadyToLockEvent;
+ VOID *Registration;
+ UINT32 RegEax;
+ UINT32 RegEdx;
//
// Test if the gEfiCallerIdGuid of this image is already installed. if not, the entry
@@ -230,94 +357,32 @@ BootScriptExecutorEntryPoint (
//
Status = gBS->LocateProtocol (&gEfiCallerIdGuid, NULL, &DevicePath);
if (EFI_ERROR (Status)) {
-
- //
- // This is the first-time loaded by DXE core. reload itself to RESERVED mem
- //
- //
- // A workaround: Here we install a dummy handle
- //
- NewImageHandle = NULL;
- Status = gBS->InstallProtocolInterface (
- &NewImageHandle,
- &gEfiCallerIdGuid,
- EFI_NATIVE_INTERFACE,
- NULL
- );
- ASSERT_EFI_ERROR (Status);
-
- Status = GetSectionFromAnyFv (
- &gEfiCallerIdGuid,
- EFI_SECTION_PE32,
- 0,
- (VOID **) &Buffer,
- &BufferSize
- );
- ASSERT_EFI_ERROR (Status);
- ImageContext.Handle = Buffer;
- ImageContext.ImageRead = PeCoffLoaderImageReadFromMemory;
- //
- // Get information about the image being loaded
- //
- Status = PeCoffLoaderGetImageInfo (&ImageContext);
- ASSERT_EFI_ERROR (Status);
- Pages = EFI_SIZE_TO_PAGES(BufferSize + ImageContext.SectionAlignment);
- FfsBuffer = 0xFFFFFFFF;
- Status = gBS->AllocatePages (
- AllocateMaxAddress,
- EfiReservedMemoryType,
- Pages,
- &FfsBuffer
- );
- ASSERT_EFI_ERROR (Status);
- ImageContext.ImageAddress = (PHYSICAL_ADDRESS)(UINTN)FfsBuffer;
- //
- // Align buffer on section boundry
- //
- ImageContext.ImageAddress += ImageContext.SectionAlignment - 1;
- ImageContext.ImageAddress &= ~(ImageContext.SectionAlignment - 1);
//
- // Load the image to our new buffer
+ // Create ReadyToLock event to reload BootScriptExecutor image
+ // to RESERVED mem and save it to LockBox.
//
- Status = PeCoffLoaderLoadImage (&ImageContext);
- ASSERT_EFI_ERROR (Status);
-
- //
- // Relocate the image in our new buffer
- //
- Status = PeCoffLoaderRelocateImage (&ImageContext);
- ASSERT_EFI_ERROR (Status);
-
- //
- // Free the buffer allocated by ReadSection since the image has been relocated in the new buffer
- //
- gBS->FreePool (Buffer);
-
- //
- // 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);
- ASSERT_EFI_ERROR (Status);
-
- //
- // Additional step for BootScript integrity
- // Save BootScriptExecutor image
- //
- Status = SaveLockBox (
- &mBootScriptExecutorImageGuid,
- (VOID *)(UINTN)ImageContext.ImageAddress,
- (UINTN)ImageContext.ImageSize
- );
- ASSERT_EFI_ERROR (Status);
-
- Status = SetLockBoxAttributes (&mBootScriptExecutorImageGuid, LOCK_BOX_ATTRIBUTE_RESTORE_IN_PLACE);
- ASSERT_EFI_ERROR (Status);
-
+ ReadyToLockEvent = EfiCreateProtocolNotifyEvent (
+ &gEfiDxeSmmReadyToLockProtocolGuid,
+ TPL_NOTIFY,
+ ReadyToLockEventNotify,
+ NULL,
+ &Registration
+ );
+ ASSERT (ReadyToLockEvent != NULL);
} else {
//
// the entry point is invoked after reloading. following code only run in RESERVED mem
//
+ if (PcdGetBool(PcdUse1GPageTable)) {
+ AsmCpuid (0x80000000, &RegEax, NULL, NULL, NULL);
+ if (RegEax >= 0x80000001) {
+ AsmCpuid (0x80000001, NULL, NULL, NULL, &RegEdx);
+ if ((RegEdx & BIT26) != 0) {
+ mPage1GSupport = TRUE;
+ }
+ }
+ }
+
BufferSize = sizeof (BOOT_SCRIPT_EXECUTOR_VARIABLE);
BootScriptExecutorBuffer = 0xFFFFFFFF;
@@ -353,11 +418,8 @@ BootScriptExecutorEntryPoint (
Status = SetLockBoxAttributes (&gEfiBootScriptExecutorContextGuid, LOCK_BOX_ATTRIBUTE_RESTORE_IN_PLACE);
ASSERT_EFI_ERROR (Status);
-
}
return EFI_SUCCESS;
}
-
-
diff --git a/MdeModulePkg/Universal/Acpi/BootScriptExecutorDxe/ScriptExecute.h b/MdeModulePkg/Universal/Acpi/BootScriptExecutorDxe/ScriptExecute.h
index 707ab8ca6..a3522905a 100644
--- a/MdeModulePkg/Universal/Acpi/BootScriptExecutorDxe/ScriptExecute.h
+++ b/MdeModulePkg/Universal/Acpi/BootScriptExecutorDxe/ScriptExecute.h
@@ -1,10 +1,10 @@
/** @file
The header file for Boot Script Executer module.
- This driver is dispatched by Dxe core and the driver will reload itself to ACPI NVS memory
+ This driver is dispatched by Dxe core and the driver will reload itself to ACPI reserved memory
in the entry point. The functionality is to interpret and restore the S3 boot script
-Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.<BR>
+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
@@ -39,7 +39,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#include <Guid/AcpiS3Context.h>
#include <Guid/BootScriptExecutorVariable.h>
-#include <Guid/EventGroup.h>
+#include <Protocol/DxeSmmReadyToLock.h>
#include <IndustryStandard/Acpi.h>
/**
a ASM function to transfer control to OS.
@@ -83,5 +83,6 @@ SetIdtEntry (
extern UINT32 AsmFixAddress16;
extern UINT32 AsmJmpAddr32;
+extern BOOLEAN mPage1GSupport;
#endif //_BOOT_SCRIPT_EXECUTOR_H_
diff --git a/MdeModulePkg/Universal/Acpi/BootScriptExecutorDxe/X64/SetIdtEntry.c b/MdeModulePkg/Universal/Acpi/BootScriptExecutorDxe/X64/SetIdtEntry.c
index a8944e600..e42e6d4fe 100644
--- a/MdeModulePkg/Universal/Acpi/BootScriptExecutorDxe/X64/SetIdtEntry.c
+++ b/MdeModulePkg/Universal/Acpi/BootScriptExecutorDxe/X64/SetIdtEntry.c
@@ -21,7 +21,6 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#define IA32_PG_PS BIT7
UINT64 mPhyMask;
-BOOLEAN mPage1GSupport;
VOID *mOriginalHandler;
UINTN mS3NvsPageTableAddress;
@@ -47,23 +46,18 @@ HookPageFaultHandler (
)
{
UINT32 RegEax;
- UINT32 RegEdx;
+ UINT8 PhysicalAddressBits;
UINTN PageFaultHandlerHookAddress;
- AsmCpuid (0x80000008, &RegEax, NULL, NULL, NULL);
- mPhyMask = LShiftU64 (1, (UINT8)RegEax) - 1;
- mPhyMask &= (1ull << 48) - SIZE_4KB;
-
- mPage1GSupport = FALSE;
- if (PcdGetBool(PcdUse1GPageTable)) {
- AsmCpuid (0x80000000, &RegEax, NULL, NULL, NULL);
- if (RegEax >= 0x80000001) {
- AsmCpuid (0x80000001, NULL, NULL, NULL, &RegEdx);
- if ((RegEdx & BIT26) != 0) {
- mPage1GSupport = TRUE;
- }
- }
+ AsmCpuid (0x80000000, &RegEax, NULL, NULL, NULL);
+ if (RegEax >= 0x80000008) {
+ AsmCpuid (0x80000008, &RegEax, NULL, NULL, NULL);
+ PhysicalAddressBits = (UINT8) RegEax;
+ } else {
+ PhysicalAddressBits = 36;
}
+ mPhyMask = LShiftU64 (1, PhysicalAddressBits) - 1;
+ mPhyMask &= (1ull << 48) - SIZE_4KB;
//
// Set Page Fault entry to catch >4G access
@@ -99,6 +93,7 @@ SetIdtEntry (
IA32_IDT_GATE_DESCRIPTOR *IdtEntry;
IA32_DESCRIPTOR *IdtDescriptor;
UINTN S3DebugBuffer;
+ EFI_STATUS Status;
//
// Restore IDT for debug
@@ -109,7 +104,8 @@ SetIdtEntry (
//
// Setup the default CPU exception handlers
//
- SetupCpuExceptionHandlers ();
+ Status = InitializeCpuExceptionHandlers (NULL);
+ ASSERT_EFI_ERROR (Status);
DEBUG_CODE (
//
diff --git a/MdeModulePkg/Universal/CapsulePei/X64/X64Entry.c b/MdeModulePkg/Universal/CapsulePei/X64/X64Entry.c
index 56913e6b0..88cfc8fe9 100644
--- a/MdeModulePkg/Universal/CapsulePei/X64/X64Entry.c
+++ b/MdeModulePkg/Universal/CapsulePei/X64/X64Entry.c
@@ -1,7 +1,7 @@
/** @file
The X64 entrypoint is used to process capsule in long mode.
-Copyright (c) 2011 - 2012, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2011 - 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
@@ -58,7 +58,8 @@ _ModuleEntryPoint (
//
// Setup the default CPU exception handlers
//
- SetupCpuExceptionHandlers ();
+ Status = InitializeCpuExceptionHandlers (NULL);
+ ASSERT_EFI_ERROR (Status);
//
// Initialize Debug Agent to support source level debug
diff --git a/MdeModulePkg/Universal/DisplayEngineDxe/FormDisplay.c b/MdeModulePkg/Universal/DisplayEngineDxe/FormDisplay.c
index 9f6c96315..dbc5685b0 100644
--- a/MdeModulePkg/Universal/DisplayEngineDxe/FormDisplay.c
+++ b/MdeModulePkg/Universal/DisplayEngineDxe/FormDisplay.c
@@ -853,6 +853,54 @@ UpdateOptionSkipLines (
}
/**
+ Check whether this Menu Option could be print.
+
+ Check Prompt string, option string or text two string not NULL.
+
+ This is an internal function.
+
+ @param MenuOption The MenuOption to be checked.
+
+ @retval TRUE This Menu Option is printable.
+ @retval FALSE This Menu Option could not be printable.
+
+**/
+BOOLEAN
+PrintableMenu (
+ UI_MENU_OPTION *MenuOption
+ )
+{
+ EFI_STATUS Status;
+ EFI_STRING OptionString;
+
+ OptionString = NULL;
+
+ if (MenuOption->Description[0] != '\0') {
+ return TRUE;
+ }
+
+ Status = ProcessOptions (MenuOption, FALSE, &OptionString, FALSE);
+ if (EFI_ERROR (Status)) {
+ return FALSE;
+ }
+ if (OptionString != NULL && OptionString[0] != '\0') {
+ FreePool (OptionString);
+ return TRUE;
+ }
+
+ if ((MenuOption->ThisTag->OpCode->OpCode == EFI_IFR_TEXT_OP) && (((EFI_IFR_TEXT*)MenuOption->ThisTag->OpCode)->TextTwo != 0)) {
+ OptionString = GetToken (((EFI_IFR_TEXT*)MenuOption->ThisTag->OpCode)->TextTwo, gFormData->HiiHandle);
+ ASSERT (OptionString != NULL);
+ if (OptionString[0] != '\0'){
+ FreePool (OptionString);
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
+/**
Check whether this Menu Option could be highlighted.
This is an internal function.
@@ -869,7 +917,7 @@ IsSelectable (
)
{
if ((MenuOption->ThisTag->OpCode->OpCode == EFI_IFR_SUBTITLE_OP) ||
- MenuOption->GrayOut || MenuOption->ReadOnly) {
+ MenuOption->GrayOut || MenuOption->ReadOnly || !PrintableMenu (MenuOption)) {
return FALSE;
} else {
return TRUE;
@@ -884,19 +932,24 @@ IsSelectable (
@param GoUp The navigation direction. TRUE: up, FALSE: down.
@param CurrentPosition Current position.
@param GapToTop Gap position to top or bottom.
+ @param FindInForm Whether find menu in current form or beyond.
@return The row distance from current MenuOption to next selectable MenuOption.
@retval -1 Reach the begin of the menu, still can't find the selectable menu.
- @retval Value Find the selectable menu, maybe the truly selectable, maybe the l
- last menu showing at current form.
+ @retval Value Find the selectable menu, maybe the truly selectable, maybe the
+ first menu showing beyond current form or last menu showing in
+ current form.
+ The value is the line number between the new selected menu and the
+ current select menu, not include the new selected menu.
**/
INTN
MoveToNextStatement (
IN BOOLEAN GoUp,
IN OUT LIST_ENTRY **CurrentPosition,
- IN UINTN GapToTop
+ IN UINTN GapToTop,
+ IN BOOLEAN FindInForm
)
{
INTN Distance;
@@ -906,6 +959,11 @@ MoveToNextStatement (
Distance = 0;
Pos = *CurrentPosition;
+
+ if (Pos == &gMenuOption) {
+ return -1;
+ }
+
PreMenuOption = MENU_OPTION_FROM_LINK (Pos);
while (TRUE) {
@@ -917,28 +975,24 @@ MoveToNextStatement (
if (NextMenuOption->Row == 0) {
UpdateOptionSkipLines (NextMenuOption);
}
-
- if (GoUp && (PreMenuOption != NextMenuOption)) {
- //
- // In this case, still can't find the selectable menu,
- // return the last one in the showing form.
- //
- if ((UINTN) Distance + NextMenuOption->Skip > GapToTop) {
- NextMenuOption = PreMenuOption;
- break;
- }
- //
- // Current Position doesn't need to be caculated when go up.
- // Caculate distanct at first when go up
- //
- Distance += NextMenuOption->Skip;
+ if (IsSelectable (NextMenuOption)) {
+ break;
}
- if (IsSelectable (NextMenuOption)) {
+ //
+ // In this case, still can't find the selectable menu,
+ // return the first one beyond the showing form.
+ //
+ if ((UINTN) Distance + NextMenuOption->Skip > GapToTop) {
+ if (FindInForm) {
+ NextMenuOption = PreMenuOption;
+ }
break;
}
+ Distance += NextMenuOption->Skip;
+
//
// Arrive at begin of the menu list.
//
@@ -947,21 +1001,8 @@ MoveToNextStatement (
break;
}
- if (!GoUp) {
- //
- // In this case, still can't find the selectable menu,
- // return the last one in the showing form.
- //
- if ((UINTN) Distance + NextMenuOption->Skip > GapToTop) {
- NextMenuOption = PreMenuOption;
- break;
- }
-
- Distance += NextMenuOption->Skip;
- }
-
- PreMenuOption = NextMenuOption;
Pos = (GoUp ? Pos->BackLink : Pos->ForwardLink);
+ PreMenuOption = NextMenuOption;
}
*CurrentPosition = &NextMenuOption->Link;
@@ -1355,6 +1396,58 @@ GetQuestionIdInfo (
return QuestionHeader->QuestionId;
}
+
+/**
+ Find the top of screen menu base on the current menu.
+
+ @param CurPos Current input menu.
+ @param Rows Totol screen rows.
+ @param SkipValue SkipValue for this new form.
+
+ @retval TopOfScreen Top of screen menu for the new form.
+
+**/
+LIST_ENTRY *
+FindTopOfScreenMenu (
+ IN LIST_ENTRY *CurPos,
+ IN UINTN Rows,
+ OUT UINTN *SkipValue
+ )
+{
+ LIST_ENTRY *Link;
+ LIST_ENTRY *TopOfScreen;
+ UI_MENU_OPTION *PreviousMenuOption;
+
+ Link = CurPos;
+ PreviousMenuOption = NULL;
+
+ while (Link->BackLink != &gMenuOption) {
+ Link = Link->BackLink;
+ PreviousMenuOption = MENU_OPTION_FROM_LINK (Link);
+ if (PreviousMenuOption->Row == 0) {
+ UpdateOptionSkipLines (PreviousMenuOption);
+ }
+ if (Rows <= PreviousMenuOption->Skip) {
+ break;
+ }
+ Rows = Rows - PreviousMenuOption->Skip;
+ }
+
+ if (Link->BackLink == &gMenuOption) {
+ TopOfScreen = gMenuOption.ForwardLink;
+ if (PreviousMenuOption != NULL && Rows < PreviousMenuOption->Skip) {
+ *SkipValue = PreviousMenuOption->Skip - Rows;
+ } else {
+ *SkipValue = 0;
+ }
+ } else {
+ TopOfScreen = Link;
+ *SkipValue = PreviousMenuOption->Skip - Rows;
+ }
+
+ return TopOfScreen;
+}
+
/**
Find the first menu which will be show at the top.
@@ -1369,16 +1462,14 @@ FindTopMenu (
IN FORM_DISPLAY_ENGINE_FORM *FormData,
OUT LIST_ENTRY **TopOfScreen,
OUT LIST_ENTRY **HighlightMenu,
- OUT INTN *SkipValue
+ OUT UINTN *SkipValue
)
{
- LIST_ENTRY *Link;
LIST_ENTRY *NewPos;
UINTN TopRow;
UINTN BottomRow;
- UINTN Index;
UI_MENU_OPTION *SavedMenuOption;
- UINTN EndRow;
+ UINTN TmpValue;
TopRow = gStatementDimensions.TopRow + SCROLL_ARROW_HEIGHT;
BottomRow = gStatementDimensions.BottomRow - SCROLL_ARROW_HEIGHT;
@@ -1390,7 +1481,7 @@ FindTopMenu (
*TopOfScreen = gMenuOption.ForwardLink;
*HighlightMenu = gMenuOption.ForwardLink;
if (!IsListEmpty (&gMenuOption)) {
- MoveToNextStatement (FALSE, HighlightMenu, BottomRow - TopRow);
+ MoveToNextStatement (FALSE, HighlightMenu, BottomRow - TopRow, TRUE);
}
*SkipValue = 0;
return;
@@ -1431,53 +1522,17 @@ FindTopMenu (
//
// Still show the highlight menu before exit from display engine.
//
- EndRow = gHighligthMenuInfo.DisplayRow + SavedMenuOption->Skip;
- } else {
- EndRow = BottomRow;
- }
-
- //
- // Base on the selected menu will show at the bottome of next page,
- // select the menu show at the top of the next page.
- //
- Link = NewPos;
- for (Index = TopRow + SavedMenuOption->Skip; Index <= EndRow; ) {
- Link = Link->BackLink;
- //
- // Already find the first menu in this form, means highlight menu
- // will show in first page of this form.
- //
- if (Link == &gMenuOption) {
- *TopOfScreen = gMenuOption.ForwardLink;
- *SkipValue = 0;
- return;
- }
- SavedMenuOption = MENU_OPTION_FROM_LINK (Link);
- UpdateOptionSkipLines (SavedMenuOption);
- Index += SavedMenuOption->Skip;
+ BottomRow = gHighligthMenuInfo.DisplayRow + SavedMenuOption->Skip;
}
- //
- // Found the menu which will show at the top of the page.
- //
- if (Link == NewPos) {
- //
- // The menu can show more than one pages, just show the menu at the top of the page.
- //
- *SkipValue = 0;
- *TopOfScreen = Link;
+ if (SavedMenuOption->Skip >= BottomRow - TopRow) {
+ TmpValue = 0;
+ *TopOfScreen = NewPos;
} else {
- //
- // Check whether need to skip some line for menu shows at the top of the page.
- //
- *SkipValue = Index - EndRow;
- if (*SkipValue > 0 && *SkipValue < (INTN) SavedMenuOption->Skip) {
- *TopOfScreen = Link;
- } else {
- *SkipValue = 0;
- *TopOfScreen = Link->ForwardLink;
- }
+ *TopOfScreen = FindTopOfScreenMenu(NewPos, BottomRow - TopRow - SavedMenuOption->Skip, &TmpValue);
}
+
+ *SkipValue = TmpValue;
}
/**
@@ -1855,6 +1910,12 @@ DisplayOneMenu (
if (StrLen (&StringPtr[Index]) != 0) {
if (Temp3 == 0) {
Row++;
+ //
+ // If the rows for text two is greater than or equal to the skip value, increase the skip value
+ //
+ if ((Row - MenuOption->Row) >= MenuOption->Skip) {
+ MenuOption->Skip++;
+ }
}
}
@@ -1901,7 +1962,7 @@ UiDisplayMenu (
IN FORM_DISPLAY_ENGINE_FORM *FormData
)
{
- INTN SkipValue;
+ UINTN SkipValue;
INTN Difference;
UINTN DistanceValue;
UINTN Row;
@@ -1910,7 +1971,6 @@ UiDisplayMenu (
UINTN Temp2;
UINTN TopRow;
UINTN BottomRow;
- UINTN OriginalRow;
UINTN Index;
UINT16 Width;
CHAR16 *StringPtr;
@@ -1945,7 +2005,6 @@ UiDisplayMenu (
UINTN HelpHeaderLine;
UINTN HelpBottomLine;
BOOLEAN MultiHelpPage;
- UINT16 GlyphWidth;
UINT16 EachLineWidth;
UINT16 HeaderLineWidth;
UINT16 BottomLineWidth;
@@ -2165,10 +2224,6 @@ UiDisplayMenu (
}
MenuOption = NULL;
-
- if (IsListEmpty (&gMenuOption)) {
- ControlFlag = CfReadKey;
- }
}
break;
@@ -2188,6 +2243,14 @@ UiDisplayMenu (
break;
}
+ if (IsListEmpty (&gMenuOption)) {
+ //
+ // No menu option, just update the hotkey filed.
+ //
+ RefreshKeyHelp(gFormData, NULL, FALSE);
+ break;
+ }
+
if (MenuOption != NULL && TopOfScreen == &MenuOption->Link) {
Temp = SkipValue;
} else {
@@ -2202,79 +2265,15 @@ UiDisplayMenu (
if (NewPos != NULL && (MenuOption == NULL || NewPos != &MenuOption->Link)) {
if (MenuOption != NULL) {
//
- // Remove highlight on last Menu Option
+ // Remove the old highlight menu.
//
- gST->ConOut->SetCursorPosition (gST->ConOut, MenuOption->Col, MenuOption->Row);
- ProcessOptions (MenuOption, FALSE, &OptionString, TRUE);
- gST->ConOut->SetAttribute (gST->ConOut, GetFieldTextColor ());
- if (OptionString != NULL) {
- if ((MenuOption->ThisTag->OpCode->OpCode == EFI_IFR_DATE_OP) ||
- (MenuOption->ThisTag->OpCode->OpCode == EFI_IFR_TIME_OP)
- ) {
- ProcessStringForDateTime(MenuOption, OptionString, FALSE);
- }
-
- Width = (UINT16) gOptionBlockWidth - 1;
- OriginalRow = MenuOption->Row;
- GlyphWidth = 1;
-
- for (Index = 0; GetLineByWidth (OptionString, Width, &GlyphWidth, &Index, &OutputString) != 0x0000;) {
- if ((Temp == 0) && (MenuOption->Row >= TopRow) && (MenuOption->Row <= BottomRow)) {
- PrintStringAt (MenuOption->OptCol, MenuOption->Row, OutputString);
- }
- //
- // If there is more string to process print on the next row and increment the Skip value
- //
- if (StrLen (&OptionString[Index]) != 0) {
- if (Temp == 0) {
- MenuOption->Row++;
- }
- }
-
- FreePool (OutputString);
- if (Temp != 0) {
- Temp--;
- }
- }
-
- MenuOption->Row = OriginalRow;
-
- FreePool (OptionString);
- } else {
- if (NewLine) {
- if (MenuOption->GrayOut) {
- gST->ConOut->SetAttribute (gST->ConOut, GetGrayedTextColor ());
- } else if (MenuOption->ThisTag->OpCode->OpCode == EFI_IFR_SUBTITLE_OP) {
- gST->ConOut->SetAttribute (gST->ConOut, GetSubTitleTextColor ());
- }
-
- OriginalRow = MenuOption->Row;
- Width = GetWidth (MenuOption, NULL);
- GlyphWidth = 1;
-
- for (Index = 0; GetLineByWidth (MenuOption->Description, Width, &GlyphWidth, &Index, &OutputString) != 0x0000;) {
- if ((Temp == 0) && (MenuOption->Row >= TopRow) && (MenuOption->Row <= BottomRow)) {
- PrintStringAt (MenuOption->Col, MenuOption->Row, OutputString);
- }
- //
- // If there is more string to process print on the next row and increment the Skip value
- //
- if (StrLen (&MenuOption->Description[Index]) != 0) {
- if (Temp == 0) {
- MenuOption->Row++;
- }
- }
-
- FreePool (OutputString);
- if (Temp != 0) {
- Temp--;
- }
- }
-
- MenuOption->Row = OriginalRow;
- gST->ConOut->SetAttribute (gST->ConOut, GetFieldTextColor ());
- }
- }
+ Status = DisplayOneMenu (MenuOption,
+ MenuOption->Col - gStatementDimensions.LeftColumn,
+ gStatementDimensions.LeftColumn,
+ Temp,
+ BottomRow,
+ FALSE
+ );
}
//
@@ -2289,79 +2288,13 @@ UiDisplayMenu (
break;
}
- //
- // Set reverse attribute
- //
- gST->ConOut->SetAttribute (gST->ConOut, GetHighlightTextColor ());
- gST->ConOut->SetCursorPosition (gST->ConOut, MenuOption->Col, MenuOption->Row);
-
- ProcessOptions (MenuOption, FALSE, &OptionString, TRUE);
- if (OptionString != NULL) {
- if (Statement->OpCode->OpCode == EFI_IFR_DATE_OP || Statement->OpCode->OpCode == EFI_IFR_TIME_OP) {
- ProcessStringForDateTime(MenuOption, OptionString, FALSE);
- }
- Width = (UINT16) gOptionBlockWidth - 1;
-
- OriginalRow = MenuOption->Row;
- GlyphWidth = 1;
-
- for (Index = 0; GetLineByWidth (OptionString, Width, &GlyphWidth, &Index, &OutputString) != 0x0000;) {
- if ((Temp2 == 0) && (MenuOption->Row >= TopRow) && (MenuOption->Row <= BottomRow) ) {
- PrintStringAt (MenuOption->OptCol, MenuOption->Row, OutputString);
- }
- //
- // If there is more string to process print on the next row and increment the Skip value
- //
- if (StrLen (&OptionString[Index]) != 0) {
- if (Temp2 == 0) {
- MenuOption->Row++;
- }
- }
-
- FreePool (OutputString);
- if (Temp2 != 0) {
- Temp2--;
- }
- }
-
- MenuOption->Row = OriginalRow;
-
- FreePool (OptionString);
- } else {
- if (NewLine) {
- OriginalRow = MenuOption->Row;
-
- Width = GetWidth (MenuOption, NULL);
- GlyphWidth = 1;
-
- for (Index = 0; GetLineByWidth (MenuOption->Description, Width, &GlyphWidth, &Index, &OutputString) != 0x0000;) {
- if ((Temp2 == 0) && (MenuOption->Row >= TopRow) && (MenuOption->Row <= BottomRow) ) {
- PrintStringAt (MenuOption->Col, MenuOption->Row, OutputString);
- }
- //
- // If there is more string to process print on the next row and increment the Skip value
- //
- if (StrLen (&MenuOption->Description[Index]) != 0) {
- if (Temp2 == 0) {
- MenuOption->Row++;
- }
- }
-
- FreePool (OutputString);
- if (Temp2 != 0) {
- Temp2--;
- }
- }
-
- MenuOption->Row = OriginalRow;
-
- }
- }
-
- //
- // Clear reverse attribute
- //
- gST->ConOut->SetAttribute (gST->ConOut, GetFieldTextColor ());
+ Status = DisplayOneMenu (MenuOption,
+ MenuOption->Col - gStatementDimensions.LeftColumn,
+ gStatementDimensions.LeftColumn,
+ Temp2,
+ BottomRow,
+ TRUE
+ );
}
break;
@@ -2371,16 +2304,27 @@ UiDisplayMenu (
break;
}
+ //
+ // NewLine means only update highlight menu (remove old highlight and highlith
+ // the new one), not need to full repain the form.
+ //
if (Repaint || NewLine) {
- //
- // Don't print anything if it is a NULL help token
- //
- ASSERT(MenuOption != NULL);
- HelpInfo = ((EFI_IFR_STATEMENT_HEADER *) ((CHAR8 *)MenuOption->ThisTag->OpCode + sizeof (EFI_IFR_OP_HEADER)))->Help;
- if (HelpInfo == 0 || !IsSelectable (MenuOption)) {
+ if (IsListEmpty (&gMenuOption)) {
+ //
+ // Don't print anything if no mwnu option.
+ //
StringPtr = GetToken (STRING_TOKEN (EMPTY_STRING), gHiiHandle);
} else {
- StringPtr = GetToken (HelpInfo, gFormData->HiiHandle);
+ //
+ // Don't print anything if it is a NULL help token
+ //
+ ASSERT(MenuOption != NULL);
+ HelpInfo = ((EFI_IFR_STATEMENT_HEADER *) ((CHAR8 *)MenuOption->ThisTag->OpCode + sizeof (EFI_IFR_OP_HEADER)))->Help;
+ if (HelpInfo == 0 || !IsSelectable (MenuOption)) {
+ StringPtr = GetToken (STRING_TOKEN (EMPTY_STRING), gHiiHandle);
+ } else {
+ StringPtr = GetToken (HelpInfo, gFormData->HiiHandle);
+ }
}
RowCount = BottomRow - TopRow + 1;
@@ -2706,9 +2650,9 @@ UiDisplayMenu (
break;
case CfScreenOperation:
- if (ScreenOperation != UiReset) {
+ if ((ScreenOperation != UiReset) && (ScreenOperation != UiHotKey)) {
//
- // If the screen has no menu items, and the user didn't select UiReset
+ // If the screen has no menu items, and the user didn't select UiReset or UiHotKey
// ignore the selection and go back to reading keys.
//
if (IsListEmpty (&gMenuOption)) {
@@ -2827,6 +2771,7 @@ UiDisplayMenu (
case CfUiUp:
ControlFlag = CfRepaint;
+ NewLine = TRUE;
SavedListEntry = NewPos;
@@ -2835,191 +2780,99 @@ UiDisplayMenu (
// Adjust Date/Time position before we advance forward.
//
AdjustDateAndTimePosition (TRUE, &NewPos);
- if (NewPos->BackLink != &gMenuOption) {
- MenuOption = MENU_OPTION_FROM_LINK (NewPos);
- ASSERT (MenuOption != NULL);
- NewLine = TRUE;
- NewPos = NewPos->BackLink;
- PreviousMenuOption = MENU_OPTION_FROM_LINK (NewPos);
- if (PreviousMenuOption->Row == 0) {
- UpdateOptionSkipLines (PreviousMenuOption);
- }
- DistanceValue = PreviousMenuOption->Skip;
- Difference = 0;
- if (MenuOption->Row >= DistanceValue + TopRow) {
- Difference = MoveToNextStatement (TRUE, &NewPos, MenuOption->Row - TopRow - DistanceValue);
- }
- NextMenuOption = MENU_OPTION_FROM_LINK (NewPos);
-
- if (Difference < 0) {
+ MenuOption = MENU_OPTION_FROM_LINK (NewPos);
+ ASSERT (MenuOption != NULL);
+
+ NewPos = NewPos->BackLink;
+ //
+ // Find next selectable menu or the first menu beyond current form.
+ //
+ Difference = MoveToNextStatement (TRUE, &NewPos, MenuOption->Row - TopRow, FALSE);
+ if (Difference < 0) {
+ //
+ // We hit the begining MenuOption that can be focused
+ // so we simply scroll to the top.
+ //
+ Repaint = TRUE;
+ if (TopOfScreen != gMenuOption.ForwardLink || SkipValue != 0) {
+ TopOfScreen = gMenuOption.ForwardLink;
+ NewPos = SavedListEntry;
+ SkipValue = 0;
+ } else {
//
- // We hit the begining MenuOption that can be focused
- // so we simply scroll to the top.
+ // Scroll up to the last page when we have arrived at top page.
//
- if (TopOfScreen != gMenuOption.ForwardLink) {
- TopOfScreen = gMenuOption.ForwardLink;
- Repaint = TRUE;
- } else {
- //
- // Scroll up to the last page when we have arrived at top page.
- //
- NewPos = &gMenuOption;
- TopOfScreen = &gMenuOption;
- MenuOption = MENU_OPTION_FROM_LINK (SavedListEntry);
- ScreenOperation = UiPageUp;
- ControlFlag = CfScreenOperation;
- break;
- }
- } else if (MenuOption->Row < TopRow + DistanceValue + Difference) {
+ TopOfScreen = FindTopOfScreenMenu (gMenuOption.BackLink, BottomRow - TopRow, &SkipValue);
+ NewPos = gMenuOption.BackLink;
+ MoveToNextStatement (TRUE, &NewPos, BottomRow - TopRow, TRUE);
+ }
+ } else {
+ NextMenuOption = MENU_OPTION_FROM_LINK (NewPos);
+
+ if (MenuOption->Row < TopRow + Difference + NextMenuOption->Skip) {
//
// Previous focus MenuOption is above the TopOfScreen, so we need to scroll
//
TopOfScreen = NewPos;
Repaint = TRUE;
- SkipValue = 0;
- } else if (!IsSelectable (NextMenuOption)) {
- //
- // Continue to go up until scroll to next page or the selectable option is found.
- //
- ScreenOperation = UiUp;
- ControlFlag = CfScreenOperation;
+ SkipValue = 0;
}
//
- // If we encounter a Date/Time op-code set, rewind to the first op-code of the set.
+ // Check whether new highlight menu is selectable, if not, keep highlight on the old one.
//
- AdjustDateAndTimePosition (TRUE, &TopOfScreen);
- AdjustDateAndTimePosition (TRUE, &NewPos);
- MenuOption = MENU_OPTION_FROM_LINK (SavedListEntry);
- UpdateStatusBar (INPUT_ERROR, FALSE);
- } else {
- if (NewPos->ForwardLink == &gMenuOption) {
- NewLine = FALSE;
- Repaint = FALSE;
- break;
+ // BottomRow - TopRow + 1 means the total rows current forms supported.
+ // Difference + NextMenuOption->Skip + 1 means the distance between last highlight menu
+ // and new top menu. New top menu will all shows in next form, but last highlight menu
+ // may only shows 1 line. + 1 at right part means at least need to keep 1 line for the
+ // last highlight menu.
+ //
+ if (!IsSelectable(NextMenuOption) && IsSelectable(MenuOption) &&
+ (BottomRow - TopRow + 1 >= Difference + NextMenuOption->Skip + 1)) {
+ NewPos = SavedListEntry;
}
- //
- // Scroll up to the last page.
- //
- NewPos = &gMenuOption;
- TopOfScreen = &gMenuOption;
- MenuOption = MENU_OPTION_FROM_LINK (SavedListEntry);
- ScreenOperation = UiPageUp;
- ControlFlag = CfScreenOperation;
- SkipValue = 0;
}
- break;
- case CfUiPageUp:
- //
- // SkipValue means lines is skipped when show the top menu option.
- //
- ControlFlag = CfRepaint;
+ UpdateStatusBar (INPUT_ERROR, FALSE);
- ASSERT(NewPos != NULL);
//
- // Already at the first menu option, Check the skip value.
+ // If we encounter a Date/Time op-code set, rewind to the first op-code of the set.
//
- if (NewPos->BackLink == &gMenuOption) {
- if (SkipValue == 0) {
- NewLine = FALSE;
- Repaint = FALSE;
- } else {
- NewLine = TRUE;
- Repaint = TRUE;
- SkipValue = 0;
- }
- break;
- }
-
- NewLine = TRUE;
- Repaint = TRUE;
+ AdjustDateAndTimePosition (TRUE, &TopOfScreen);
+ AdjustDateAndTimePosition (TRUE, &NewPos);
+ break;
+ case CfUiPageUp:
//
- // SkipValue > (BottomRow - TopRow + 1) means current menu has more than one
- // form of options to be show, so just update the SkipValue to show the next
- // parts of options.
+ // SkipValue means lines is skipped when show the top menu option.
//
- if (SkipValue > (INTN) (BottomRow - TopRow + 1)) {
- SkipValue -= BottomRow - TopRow + 1;
- break;
- }
+ ControlFlag = CfRepaint;
+ NewLine = TRUE;
+ Repaint = TRUE;
Link = TopOfScreen;
//
// First minus the menu of the top screen, it's value is SkipValue.
//
- Index = (BottomRow + 1) - SkipValue;
- while ((Index > TopRow) && (Link->BackLink != &gMenuOption)) {
- Link = Link->BackLink;
- PreviousMenuOption = MENU_OPTION_FROM_LINK (Link);
- if (PreviousMenuOption->Row == 0) {
- UpdateOptionSkipLines (PreviousMenuOption);
- }
- if (Index < PreviousMenuOption->Skip) {
- break;
- }
- Index = Index - PreviousMenuOption->Skip;
- }
-
- if ((Link->BackLink == &gMenuOption) && (Index >= TopRow)) {
- if (TopOfScreen == &gMenuOption) {
- TopOfScreen = gMenuOption.ForwardLink;
- NewPos = gMenuOption.BackLink;
- MoveToNextStatement (TRUE, &NewPos, BottomRow - TopRow);
- if (Index < PreviousMenuOption->Skip) {
- Repaint = TRUE;
- SkipValue = PreviousMenuOption->Skip - (Index - TopRow);
- } else {
- Repaint = FALSE;
- SkipValue = 0;
- }
- } else if (TopOfScreen != Link) {
- TopOfScreen = Link;
- NewPos = Link;
- MoveToNextStatement (FALSE, &NewPos, BottomRow - TopRow);
- SkipValue = 0;
- } else {
- //
- // Finally we know that NewPos is the last MenuOption can be focused.
- //
- if (SkipValue == 0) {
- Repaint = FALSE;
- }
- NewPos = Link;
- MoveToNextStatement (FALSE, &NewPos, BottomRow - TopRow);
- SkipValue = 0;
- }
- } else {
- if (Index > TopRow) {
- //
- // At here, only case "Index < PreviousMenuOption->Skip" can reach here.
- //
- SkipValue = PreviousMenuOption->Skip - (Index - TopRow);
- } else if (Index == TopRow) {
- SkipValue = 0;
- } else {
- SkipValue = TopRow - Index;
- }
-
- //
- // Move to the option in Next page.
+ if (SkipValue >= BottomRow - TopRow + 1) {
//
- if (TopOfScreen == &gMenuOption) {
- NewPos = gMenuOption.BackLink;
- MoveToNextStatement (TRUE, &NewPos, BottomRow - TopRow);
- } else {
- NewPos = Link;
- MoveToNextStatement (FALSE, &NewPos, BottomRow - TopRow);
- }
-
- //
- // There are more MenuOption needing scrolling up.
+ // SkipValue > (BottomRow - TopRow + 1) means current menu has more than one
+ // form of options to be show, so just update the SkipValue to show the next
+ // parts of options.
//
- TopOfScreen = Link;
- MenuOption = NULL;
+ SkipValue -= BottomRow - TopRow + 1;
+ NewPos = TopOfScreen;
+ break;
+ } else {
+ Index = (BottomRow + 1) - SkipValue - TopRow;
}
+
+ TopOfScreen = FindTopOfScreenMenu(TopOfScreen, Index, &SkipValue);
+ NewPos = TopOfScreen;
+ MoveToNextStatement (FALSE, &NewPos, BottomRow - TopRow, FALSE);
+
+ UpdateStatusBar (INPUT_ERROR, FALSE);
//
// If we encounter a Date/Time op-code set, rewind to the first op-code of the set.
@@ -3033,24 +2886,10 @@ UiDisplayMenu (
//
// SkipValue means lines is skipped when show the top menu option.
//
- ControlFlag = CfRepaint;
-
- ASSERT (NewPos != NULL);
- if (NewPos->ForwardLink == &gMenuOption) {
- MenuOption = MENU_OPTION_FROM_LINK (NewPos);
- if (SkipValue + BottomRow - TopRow + 1 < MenuOption->Skip) {
- SkipValue += BottomRow - TopRow + 1;
- NewLine = TRUE;
- Repaint = TRUE;
- break;
- }
- NewLine = FALSE;
- Repaint = FALSE;
- break;
- }
+ ControlFlag = CfRepaint;
+ NewLine = TRUE;
+ Repaint = TRUE;
- NewLine = TRUE;
- Repaint = TRUE;
Link = TopOfScreen;
NextMenuOption = MENU_OPTION_FROM_LINK (Link);
Index = TopRow + NextMenuOption->Skip - SkipValue;
@@ -3065,10 +2904,10 @@ UiDisplayMenu (
if ((Link->ForwardLink == &gMenuOption) && (Index <= BottomRow + 1)) {
//
- // Finally we know that NewPos is the last MenuOption can be focused.
+ // Highlight on the last menu which can be highlight.
//
Repaint = FALSE;
- MoveToNextStatement (TRUE, &Link, Index - TopRow);
+ MoveToNextStatement (TRUE, &Link, Index - TopRow, TRUE);
} else {
//
// Calculate the skip line for top of screen menu.
@@ -3081,13 +2920,12 @@ UiDisplayMenu (
} else {
SkipValue = NextMenuOption->Skip - (Index - (BottomRow + 1));
}
-
TopOfScreen = Link;
MenuOption = NULL;
//
// Move to the Next selectable menu.
//
- MoveToNextStatement (FALSE, &Link, BottomRow - TopRow);
+ MoveToNextStatement (FALSE, &Link, BottomRow - TopRow, TRUE);
}
//
@@ -3095,6 +2933,8 @@ UiDisplayMenu (
//
NewPos = Link;
+ UpdateStatusBar (INPUT_ERROR, FALSE);
+
//
// If we encounter a Date/Time op-code set, rewind to the first op-code of the set.
// Don't do this when we are already in the last page.
@@ -3109,7 +2949,15 @@ UiDisplayMenu (
// NewPos points to the menu which is highlighted now.
//
ControlFlag = CfRepaint;
+ NewLine = TRUE;
+
+ if (NewPos == TopOfScreen) {
+ Temp2 = SkipValue;
+ } else {
+ Temp2 = 0;
+ }
+ SavedListEntry = NewPos;
//
// Since the behavior of hitting the down arrow on a Date/Time op-code is intended
// to be one that progresses to the next set of op-codes, we need to advance to the last
@@ -3118,182 +2966,134 @@ UiDisplayMenu (
// op-code is the last entry in the menu, we need to rewind back to the first op-code of
// the Date/Time op-code.
//
- SavedListEntry = NewPos;
AdjustDateAndTimePosition (FALSE, &NewPos);
- if (NewPos->ForwardLink != &gMenuOption) {
- if (NewPos == TopOfScreen) {
- Temp2 = SkipValue;
+ MenuOption = MENU_OPTION_FROM_LINK (NewPos);
+ NewPos = NewPos->ForwardLink;
+ //
+ // Find the next selectable menu.
+ //
+ if (MenuOption->Row + MenuOption->Skip - Temp2 > BottomRow + 1) {
+ if (gMenuOption.ForwardLink == NewPos || &gMenuOption == NewPos) {
+ Difference = -1;
} else {
- Temp2 = 0;
+ Difference = 0;
}
+ } else {
+ Difference = MoveToNextStatement (FALSE, &NewPos, BottomRow + 1 - (MenuOption->Row + MenuOption->Skip - Temp2), FALSE);
+ }
+ if (Difference < 0) {
+ //
+ // Scroll to the first page.
+ //
+ if (TopOfScreen != gMenuOption.ForwardLink || SkipValue != 0) {
+ TopOfScreen = gMenuOption.ForwardLink;
+ Repaint = TRUE;
+ MenuOption = NULL;
+ } else {
+ MenuOption = MENU_OPTION_FROM_LINK (SavedListEntry);
+ }
+ NewPos = gMenuOption.ForwardLink;
+ MoveToNextStatement (FALSE, &NewPos, BottomRow - TopRow, TRUE);
- MenuOption = MENU_OPTION_FROM_LINK (NewPos);
- NewLine = TRUE;
- NewPos = NewPos->ForwardLink;
+ SkipValue = 0;
+ //
+ // If we are at the end of the list and sitting on a Date/Time op, rewind to the head.
+ //
+ AdjustDateAndTimePosition (TRUE, &TopOfScreen);
+ AdjustDateAndTimePosition (TRUE, &NewPos);
+ break;
+ }
+
+ //
+ // Get next selected menu info.
+ //
+ AdjustDateAndTimePosition (FALSE, &NewPos);
+ NextMenuOption = MENU_OPTION_FROM_LINK (NewPos);
+ if (NextMenuOption->Row == 0) {
+ UpdateOptionSkipLines (NextMenuOption);
+ }
- Difference = 0;
+ //
+ // Calculate new highlight menu end row.
+ //
+ Temp = (MenuOption->Row + MenuOption->Skip - Temp2) + Difference + NextMenuOption->Skip - 1;
+ if (Temp > BottomRow) {
//
- // Current menu not at the bottom of the form.
+ // Get the top screen menu info.
//
- if (BottomRow >= MenuOption->Row + MenuOption->Skip - Temp2) {
- //
- // Find the next selectable menu.
- //
- Difference = MoveToNextStatement (FALSE, &NewPos, BottomRow - MenuOption->Row - MenuOption->Skip + Temp2);
+ AdjustDateAndTimePosition (FALSE, &TopOfScreen);
+ SavedMenuOption = MENU_OPTION_FROM_LINK (TopOfScreen);
+
+ //
+ // Current Top screen menu occupy (SavedMenuOption->Skip - SkipValue) rows.
+ // Full shows the new selected menu need to skip (Temp - BottomRow - 1) rows.
+ //
+ if ((Temp - BottomRow) >= (SavedMenuOption->Skip - SkipValue)) {
//
- // We hit the end of MenuOption that can be focused
- // so we simply scroll to the first page.
+ // Skip the top op-code
//
- if (Difference < 0) {
- //
- // Scroll to the first page.
- //
- if (TopOfScreen != gMenuOption.ForwardLink) {
- TopOfScreen = gMenuOption.ForwardLink;
- Repaint = TRUE;
- MenuOption = NULL;
- } else {
- MenuOption = MENU_OPTION_FROM_LINK (SavedListEntry);
- }
- NewPos = gMenuOption.ForwardLink;
- MoveToNextStatement (FALSE, &NewPos, BottomRow - TopRow);
+ TopOfScreen = TopOfScreen->ForwardLink;
+ DistanceValue = (Temp - BottomRow) - (SavedMenuOption->Skip - SkipValue);
- SkipValue = 0;
- //
- // If we are at the end of the list and sitting on a Date/Time op, rewind to the head.
- //
- AdjustDateAndTimePosition (TRUE, &TopOfScreen);
- AdjustDateAndTimePosition (TRUE, &NewPos);
- break;
- }
- }
- NextMenuOption = MENU_OPTION_FROM_LINK (NewPos);
- if (NextMenuOption->Row == 0) {
- UpdateOptionSkipLines (NextMenuOption);
- }
- DistanceValue = Difference + NextMenuOption->Skip - Temp2;
-
- Temp = MenuOption->Row + MenuOption->Skip + DistanceValue - 1;
- if ((MenuOption->Row + MenuOption->Skip - Temp2 == BottomRow + 1) &&
- (NextMenuOption->ThisTag->OpCode->OpCode == EFI_IFR_DATE_OP ||
- NextMenuOption->ThisTag->OpCode->OpCode == EFI_IFR_TIME_OP)
- ) {
- Temp ++;
- }
+ SavedMenuOption = MENU_OPTION_FROM_LINK (TopOfScreen);
- //
- // If we are going to scroll, update TopOfScreen
- //
- if (Temp > BottomRow) {
- do {
+ //
+ // If we have a remainder, skip that many more op-codes until we drain the remainder
+ // Special case is the selected highlight menu has more than one form of menus.
+ //
+ while (DistanceValue >= SavedMenuOption->Skip && TopOfScreen != NewPos) {
//
- // Is the current top of screen a zero-advance op-code?
- // If so, keep moving forward till we hit a >0 advance op-code
+ // Since the Difference is greater than or equal to this op-code's skip value, skip it
//
+ DistanceValue = DistanceValue - (INTN) SavedMenuOption->Skip;
+ TopOfScreen = TopOfScreen->ForwardLink;
SavedMenuOption = MENU_OPTION_FROM_LINK (TopOfScreen);
-
- //
- // If bottom op-code is more than one line or top op-code is more than one line
- //
- if ((DistanceValue > 1) || (SavedMenuOption->Skip > 1)) {
- //
- // Is the bottom op-code greater than or equal in size to the top op-code?
- //
- if ((Temp - BottomRow) >= (SavedMenuOption->Skip - SkipValue)) {
- //
- // Skip the top op-code
- //
- TopOfScreen = TopOfScreen->ForwardLink;
- Difference = (Temp - BottomRow) - (SavedMenuOption->Skip - SkipValue);
-
- SavedMenuOption = MENU_OPTION_FROM_LINK (TopOfScreen);
-
- //
- // If we have a remainder, skip that many more op-codes until we drain the remainder
- //
- while (Difference >= (INTN) SavedMenuOption->Skip) {
- //
- // Since the Difference is greater than or equal to this op-code's skip value, skip it
- //
- Difference = Difference - (INTN) SavedMenuOption->Skip;
- TopOfScreen = TopOfScreen->ForwardLink;
- SavedMenuOption = MENU_OPTION_FROM_LINK (TopOfScreen);
- }
- //
- // Since we will act on this op-code in the next routine, and increment the
- // SkipValue, set the skips to one less than what is required.
- //
- SkipValue = Difference - 1;
- } else {
- //
- // Since we will act on this op-code in the next routine, and increment the
- // SkipValue, set the skips to one less than what is required.
- //
- SkipValue += (Temp - BottomRow) - 1;
- }
- } else {
- if ((SkipValue + 1) == (INTN) SavedMenuOption->Skip) {
- TopOfScreen = TopOfScreen->ForwardLink;
- break;
- }
- }
- //
- // If the op-code at the top of the screen is more than one line, let's not skip it yet
- // Let's set a skip flag to smoothly scroll the top of the screen.
- //
- if (SavedMenuOption->Skip > 1) {
- if (SavedMenuOption == NextMenuOption) {
- SkipValue = 0;
- } else {
- SkipValue++;
- }
- } else if (SavedMenuOption->Skip == 1) {
- SkipValue = 0;
- } else {
- SkipValue = 0;
- TopOfScreen = TopOfScreen->ForwardLink;
- }
- } while (SavedMenuOption->Skip == 0);
-
- Repaint = TRUE;
- } else if (!IsSelectable (NextMenuOption)) {
+ }
//
- // Continue to go down until scroll to next page or the selectable option is found.
+ // Since we will act on this op-code in the next routine, and increment the
+ // SkipValue, set the skips to one less than what is required.
//
- ScreenOperation = UiDown;
- ControlFlag = CfScreenOperation;
- }
-
- MenuOption = MENU_OPTION_FROM_LINK (SavedListEntry);
-
- UpdateStatusBar (INPUT_ERROR, FALSE);
-
- } else {
- //
- // Scroll to the first page.
- //
- if (TopOfScreen != gMenuOption.ForwardLink || SkipValue != 0) {
- TopOfScreen = gMenuOption.ForwardLink;
- Repaint = TRUE;
- MenuOption = NULL;
+ if (TopOfScreen != NewPos) {
+ SkipValue = DistanceValue;
+ } else {
+ SkipValue = 0;
+ }
} else {
//
- // Need to remove the current highlight menu.
- // MenuOption saved the last highlight menu info.
+ // Since we will act on this op-code in the next routine, and increment the
+ // SkipValue, set the skips to one less than what is required.
//
- MenuOption = MENU_OPTION_FROM_LINK (SavedListEntry);
+ SkipValue += Temp - BottomRow;
}
-
- SkipValue = 0;
- NewLine = TRUE;
+ Repaint = TRUE;
+ } else if (!IsSelectable (NextMenuOption)) {
//
- // Get the next highlight menu.
+ // Continue to go down until scroll to next page or the selectable option is found.
//
- NewPos = gMenuOption.ForwardLink;
- MoveToNextStatement (FALSE, &NewPos, BottomRow - TopRow);
+ ScreenOperation = UiDown;
+ ControlFlag = CfScreenOperation;
+ break;
}
+ MenuOption = MENU_OPTION_FROM_LINK (SavedListEntry);
+
+ //
+ // Check whether new highlight menu is selectable, if not, keep highlight on the old one.
+ //
+ // BottomRow - TopRow + 1 means the total rows current forms supported.
+ // Difference + NextMenuOption->Skip + 1 means the distance between last highlight menu
+ // and new top menu. New top menu will all shows in next form, but last highlight menu
+ // may only shows 1 line. + 1 at right part means at least need to keep 1 line for the
+ // last highlight menu.
+ //
+ if (!IsSelectable (NextMenuOption) && IsSelectable (MenuOption) &&
+ (BottomRow - TopRow + 1 >= Difference + NextMenuOption->Skip + 1)) {
+ NewPos = SavedListEntry;
+ }
+
+ UpdateStatusBar (INPUT_ERROR, FALSE);
+
//
// If we are at the end of the list and sitting on a Date/Time op, rewind to the head.
//
diff --git a/MdeModulePkg/Universal/DisplayEngineDxe/ProcessOptions.c b/MdeModulePkg/Universal/DisplayEngineDxe/ProcessOptions.c
index cf9f6836b..8da563ba7 100644
--- a/MdeModulePkg/Universal/DisplayEngineDxe/ProcessOptions.c
+++ b/MdeModulePkg/Universal/DisplayEngineDxe/ProcessOptions.c
@@ -55,6 +55,56 @@ NewStrCat (
}
/**
+ Get UINT64 type value.
+
+ @param Value Input Hii value.
+
+ @retval UINT64 Return the UINT64 type value.
+
+**/
+UINT64
+HiiValueToUINT64 (
+ IN EFI_HII_VALUE *Value
+ )
+{
+ UINT64 RetVal;
+
+ RetVal = 0;
+
+ switch (Value->Type) {
+ case EFI_IFR_TYPE_NUM_SIZE_8:
+ RetVal = Value->Value.u8;
+ break;
+
+ case EFI_IFR_TYPE_NUM_SIZE_16:
+ RetVal = Value->Value.u16;
+ break;
+
+ case EFI_IFR_TYPE_NUM_SIZE_32:
+ RetVal = Value->Value.u32;
+ break;
+
+ case EFI_IFR_TYPE_BOOLEAN:
+ RetVal = Value->Value.b;
+ break;
+
+ case EFI_IFR_TYPE_DATE:
+ RetVal = *(UINT64*) &Value->Value.date;
+ break;
+
+ case EFI_IFR_TYPE_TIME:
+ RetVal = (*(UINT64*) &Value->Value.time) & 0xffffff;
+ break;
+
+ default:
+ RetVal = Value->Value.u64;
+ break;
+ }
+
+ return RetVal;
+}
+
+/**
Compare two Hii value.
@param Value1 Expression value to compare on left-hand.
@@ -153,7 +203,7 @@ CompareHiiValue (
//
// Take remain types(integer, boolean, date/time) as integer
//
- Temp64 = (INT64) (Value1->Value.u64 - Value2->Value.u64);
+ Temp64 = HiiValueToUINT64(Value1) - HiiValueToUINT64(Value2);
if (Temp64 > 0) {
*Result = 1;
} else if (Temp64 < 0) {
@@ -1178,8 +1228,24 @@ ProcessOptions (
Link = GetFirstNode (&Question->OptionListHead);
Option = DISPLAY_QUESTION_OPTION_FROM_LINK (Link);
- CopyMem (&gUserInput->InputValue.Value, &Option->OptionOpCode->Value, sizeof (EFI_IFR_TYPE_VALUE));
gUserInput->InputValue.Type = Option->OptionOpCode->Type;
+ switch (gUserInput->InputValue.Type) {
+ case EFI_IFR_TYPE_NUM_SIZE_8:
+ gUserInput->InputValue.Value.u8 = Option->OptionOpCode->Value.u8;
+ break;
+ case EFI_IFR_TYPE_NUM_SIZE_16:
+ CopyMem (&gUserInput->InputValue.Value.u16, &Option->OptionOpCode->Value.u16, sizeof (UINT16));
+ break;
+ case EFI_IFR_TYPE_NUM_SIZE_32:
+ CopyMem (&gUserInput->InputValue.Value.u32, &Option->OptionOpCode->Value.u32, sizeof (UINT32));
+ break;
+ case EFI_IFR_TYPE_NUM_SIZE_64:
+ CopyMem (&gUserInput->InputValue.Value.u64, &Option->OptionOpCode->Value.u64, sizeof (UINT64));
+ break;
+ default:
+ ASSERT (FALSE);
+ break;
+ }
gUserInput->SelectedStatement = Question;
FreePool (*OptionString);
diff --git a/MdeModulePkg/Universal/HiiDatabaseDxe/ConfigRouting.c b/MdeModulePkg/Universal/HiiDatabaseDxe/ConfigRouting.c
index 2ed02cdaa..fb69b9ca1 100644
--- a/MdeModulePkg/Universal/HiiDatabaseDxe/ConfigRouting.c
+++ b/MdeModulePkg/Universal/HiiDatabaseDxe/ConfigRouting.c
@@ -355,6 +355,9 @@ OutputConfigBody (
}
Length = TmpPtr - String;
+ if (Length == 0) {
+ return EFI_NOT_FOUND;
+ }
Result = AllocateCopyPool (Length * sizeof (CHAR16), String);
if (Result == NULL) {
return EFI_OUT_OF_RESOURCES;
@@ -1281,6 +1284,13 @@ IsThisVarstore (
GuidStr = NULL;
TempStr = NULL;
+ //
+ // If ConfigHdr has name field and varstore not has name, return FALSE.
+ //
+ if (Name == NULL && StrStr (ConfigHdr, L"NAME=&") == NULL) {
+ return FALSE;
+ }
+
GenerateSubStr (L"GUID=", sizeof (EFI_GUID), (VOID *)VarstoreGuid, 1, &GuidStr);
if (Name != NULL) {
GenerateSubStr (L"NAME=", StrLen (Name) * sizeof (CHAR16), (VOID *) Name, 2, &NameStr);
@@ -1318,6 +1328,130 @@ Done:
}
/**
+ This function parses Form Package to get the efi varstore info according to the request ConfigHdr.
+
+ @param DataBaseRecord The DataBaseRecord instance contains the found Hii handle and package.
+ @param ConfigHdr Request string ConfigHdr. If it is NULL,
+ the first found varstore will be as ConfigHdr.
+ @retval TRUE This hii package is the reqeust one.
+ @retval FALSE This hii package is not the reqeust one.
+**/
+BOOLEAN
+IsThisPackageList (
+ IN HII_DATABASE_RECORD *DataBaseRecord,
+ IN EFI_STRING ConfigHdr
+ )
+{
+ EFI_STATUS Status;
+ UINTN IfrOffset;
+ UINTN PackageOffset;
+ EFI_IFR_OP_HEADER *IfrOpHdr;
+ CHAR16 *VarStoreName;
+ UINT8 *HiiFormPackage;
+ UINTN PackageSize;
+ EFI_IFR_VARSTORE_EFI *IfrEfiVarStore;
+ EFI_HII_PACKAGE_HEADER *PackageHeader;
+ EFI_IFR_VARSTORE *IfrVarStore;
+ EFI_IFR_VARSTORE_NAME_VALUE *IfrNameValueVarStore;
+ BOOLEAN FindVarstore;
+
+ HiiFormPackage = NULL;
+ VarStoreName = NULL;
+ Status = EFI_SUCCESS;
+ FindVarstore = FALSE;
+
+ Status = GetFormPackageData(DataBaseRecord, &HiiFormPackage, &PackageSize);
+ if (EFI_ERROR (Status)) {
+ return FALSE;
+ }
+
+ IfrOffset = sizeof (EFI_HII_PACKAGE_HEADER);
+ PackageOffset = IfrOffset;
+ PackageHeader = (EFI_HII_PACKAGE_HEADER *) HiiFormPackage;
+
+ while (IfrOffset < PackageSize) {
+ //
+ // More than one form packages exist.
+ //
+ if (PackageOffset >= PackageHeader->Length) {
+ //
+ // Process the new form package.
+ //
+ PackageOffset = sizeof (EFI_HII_PACKAGE_HEADER);
+ IfrOffset += PackageOffset;
+ PackageHeader = (EFI_HII_PACKAGE_HEADER *) (HiiFormPackage + IfrOffset);
+ }
+
+ IfrOpHdr = (EFI_IFR_OP_HEADER *) (HiiFormPackage + IfrOffset);
+ IfrOffset += IfrOpHdr->Length;
+ PackageOffset += IfrOpHdr->Length;
+
+ switch (IfrOpHdr->OpCode) {
+
+ case EFI_IFR_VARSTORE_OP:
+ IfrVarStore = (EFI_IFR_VARSTORE *) IfrOpHdr;
+
+ VarStoreName = AllocateZeroPool (AsciiStrSize ((CHAR8 *)IfrVarStore->Name) * sizeof (CHAR16));
+ if (VarStoreName == NULL) {
+ goto Done;
+ }
+ AsciiStrToUnicodeStr ((CHAR8 *)IfrVarStore->Name, VarStoreName);
+
+ if (IsThisVarstore((VOID *)&IfrVarStore->Guid, VarStoreName, ConfigHdr)) {
+ FindVarstore = TRUE;
+ goto Done;
+ }
+ break;
+
+ case EFI_IFR_VARSTORE_EFI_OP:
+ IfrEfiVarStore = (EFI_IFR_VARSTORE_EFI *) IfrOpHdr;
+ VarStoreName = AllocateZeroPool (AsciiStrSize ((CHAR8 *)IfrEfiVarStore->Name) * sizeof (CHAR16));
+ if (VarStoreName == NULL) {
+ goto Done;
+ }
+ AsciiStrToUnicodeStr ((CHAR8 *)IfrEfiVarStore->Name, VarStoreName);
+
+ if (IsThisVarstore (&IfrEfiVarStore->Guid, VarStoreName, ConfigHdr)) {
+ FindVarstore = TRUE;
+ goto Done;
+ }
+ break;
+
+ case EFI_IFR_VARSTORE_NAME_VALUE_OP:
+ IfrNameValueVarStore = (EFI_IFR_VARSTORE_NAME_VALUE *) IfrOpHdr;
+
+ if (IsThisVarstore (&IfrNameValueVarStore->Guid, NULL, ConfigHdr)) {
+ FindVarstore = TRUE;
+ goto Done;
+ }
+ break;
+
+ case EFI_IFR_FORM_OP:
+ case EFI_IFR_FORM_MAP_OP:
+ //
+ // No matched varstore is found and directly return.
+ //
+ goto Done;
+ break;
+
+ default:
+ break;
+ }
+ }
+
+Done:
+ if (HiiFormPackage != NULL) {
+ FreePool (HiiFormPackage);
+ }
+
+ if (VarStoreName != NULL) {
+ FreePool (VarStoreName);
+ }
+
+ return FindVarstore;
+}
+
+/**
Check whether the this op code is required.
@param RequestBlockArray The array includes all the request info or NULL.
@@ -2128,14 +2262,26 @@ ParseIfrData (
//
// End Opcode is for Var question.
//
- if (BlockData != NULL && BlockData->Scope > 0) {
- BlockData->Scope--;
+ if (BlockData != NULL) {
+ if (BlockData->Scope > 0) {
+ BlockData->Scope--;
+ }
+ if (BlockData->Scope == 0) {
+ BlockData = NULL;
+ }
}
+
break;
default:
- if (BlockData != NULL && BlockData->Scope > 0) {
- BlockData->Scope = (UINT8) (BlockData->Scope + IfrOpHdr->Scope);
+ if (BlockData != NULL) {
+ if (BlockData->Scope > 0) {
+ BlockData->Scope = (UINT8) (BlockData->Scope + IfrOpHdr->Scope);
+ }
+
+ if (BlockData->Scope == 0) {
+ BlockData = NULL;
+ }
}
break;
}
@@ -3200,10 +3346,11 @@ GetConfigRespFromEfiVarStore (
UINT8 *VarStore;
UINTN BufferSize;
- Status = EFI_SUCCESS;
- BufferSize = 0;
- VarStore = NULL;
- VarStoreName = NULL;
+ Status = EFI_SUCCESS;
+ BufferSize = 0;
+ VarStore = NULL;
+ VarStoreName = NULL;
+ *AccessProgress = Request;
VarStoreName = AllocateZeroPool (AsciiStrSize ((CHAR8 *)EfiVarStoreInfo->Name) * sizeof (CHAR16));
if (VarStoreName == NULL) {
@@ -3537,6 +3684,7 @@ HiiConfigRoutingExtractConfig (
BOOLEAN IsEfiVarStore;
EFI_IFR_VARSTORE_EFI *EfiVarStoreInfo;
EFI_STRING ErrorPtr;
+ UINTN DevicePathSize;
if (This == NULL || Progress == NULL || Results == NULL) {
return EFI_INVALID_PARAMETER;
@@ -3622,11 +3770,8 @@ HiiConfigRoutingExtractConfig (
Database = CR (Link, HII_DATABASE_RECORD, DatabaseEntry, HII_DATABASE_RECORD_SIGNATURE);
if ((DevicePathPkg = Database->PackageList->DevicePathPkg) != NULL) {
CurrentDevicePath = DevicePathPkg + sizeof (EFI_HII_PACKAGE_HEADER);
- if (CompareMem (
- DevicePath,
- CurrentDevicePath,
- GetDevicePathSize ((EFI_DEVICE_PATH_PROTOCOL *) CurrentDevicePath)
- ) == 0) {
+ DevicePathSize = GetDevicePathSize ((EFI_DEVICE_PATH_PROTOCOL *) CurrentDevicePath);
+ if ((CompareMem (DevicePath,CurrentDevicePath,DevicePathSize) == 0) && IsThisPackageList(Database, ConfigRequest)) {
DriverHandle = Database->DriverHandle;
HiiHandle = Database->Handle;
break;
@@ -4060,6 +4205,7 @@ HiiConfigRoutingRouteConfig (
EFI_STRING AccessProgress;
EFI_IFR_VARSTORE_EFI *EfiVarStoreInfo;
BOOLEAN IsEfiVarstore;
+ UINTN DevicePathSize;
if (This == NULL || Progress == NULL) {
return EFI_INVALID_PARAMETER;
@@ -4131,11 +4277,8 @@ HiiConfigRoutingRouteConfig (
if ((DevicePathPkg = Database->PackageList->DevicePathPkg) != NULL) {
CurrentDevicePath = DevicePathPkg + sizeof (EFI_HII_PACKAGE_HEADER);
- if (CompareMem (
- DevicePath,
- CurrentDevicePath,
- GetDevicePathSize ((EFI_DEVICE_PATH_PROTOCOL *) CurrentDevicePath)
- ) == 0) {
+ DevicePathSize = GetDevicePathSize ((EFI_DEVICE_PATH_PROTOCOL *) CurrentDevicePath);
+ if ((CompareMem (DevicePath,CurrentDevicePath,DevicePathSize) == 0) && IsThisPackageList(Database, ConfigResp)) {
DriverHandle = Database->DriverHandle;
break;
}
diff --git a/MdeModulePkg/Universal/HiiDatabaseDxe/Image.c b/MdeModulePkg/Universal/HiiDatabaseDxe/Image.c
index ccd197557..efa5bbb71 100644
--- a/MdeModulePkg/Universal/HiiDatabaseDxe/Image.c
+++ b/MdeModulePkg/Universal/HiiDatabaseDxe/Image.c
@@ -2,7 +2,7 @@
Implementation for EFI_HII_IMAGE_PROTOCOL.
-Copyright (c) 2007 - 2008, Intel Corporation. All rights reserved.<BR>
+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
@@ -81,7 +81,6 @@ GetImageIdOrAddress (
case EFI_HII_IIBT_EXT1:
Length8 = *(ImageBlock + sizeof (EFI_HII_IMAGE_BLOCK) + sizeof (UINT8));
ImageBlock += Length8;
- ImageIdCurrent++;
break;
case EFI_HII_IIBT_EXT2:
CopyMem (
@@ -90,7 +89,6 @@ GetImageIdOrAddress (
sizeof (UINT16)
);
ImageBlock += Length16;
- ImageIdCurrent++;
break;
case EFI_HII_IIBT_EXT4:
CopyMem (
@@ -99,7 +97,6 @@ GetImageIdOrAddress (
sizeof (UINT32)
);
ImageBlock += Length32;
- ImageIdCurrent++;
break;
case EFI_HII_IIBT_IMAGE_1BIT:
diff --git a/MdeModulePkg/Universal/Network/IScsiDxe/IScsiDriver.c b/MdeModulePkg/Universal/Network/IScsiDxe/IScsiDriver.c
index f668fe3d9..f4663d9f5 100644
--- a/MdeModulePkg/Universal/Network/IScsiDxe/IScsiDriver.c
+++ b/MdeModulePkg/Universal/Network/IScsiDxe/IScsiDriver.c
@@ -1,7 +1,7 @@
/** @file
The entry point of IScsi driver.
-Copyright (c) 2004 - 2011, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2004 - 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
@@ -24,6 +24,44 @@ EFI_DRIVER_BINDING_PROTOCOL gIScsiDriverBinding = {
};
/**
+ Tests to see if this driver supports the RemainingDevicePath.
+
+ @param[in] RemainingDevicePath A pointer to the remaining portion of a device path. This
+ parameter is ignored by device drivers, and is optional for bus
+ drivers. For bus drivers, if this parameter is not NULL, then
+ the bus driver must determine if the bus controller specified
+ by ControllerHandle and the child controller specified
+ by RemainingDevicePath are both supported by this
+ bus driver.
+
+ @retval EFI_SUCCESS The RemainingDevicePath is supported or NULL.
+ @retval EFI_UNSUPPORTED The device specified by ControllerHandle and
+ RemainingDevicePath is not supported by the driver specified by This.
+**/
+EFI_STATUS
+IScsiIsDevicePathSupported (
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL
+ )
+{
+ EFI_DEVICE_PATH_PROTOCOL *CurrentDevicePath;
+
+ CurrentDevicePath = RemainingDevicePath;
+ if (CurrentDevicePath != NULL) {
+ while (!IsDevicePathEnd (CurrentDevicePath)) {
+ if ((CurrentDevicePath->Type == MESSAGING_DEVICE_PATH) && (CurrentDevicePath->SubType == MSG_ISCSI_DP)) {
+ return EFI_SUCCESS;
+ }
+
+ CurrentDevicePath = NextDevicePathNode (CurrentDevicePath);
+ }
+
+ return EFI_UNSUPPORTED;
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
Tests to see if this driver supports a given controller. If a child device is provided,
it further tests to see if this driver supports creating a handle for the specified child device.
@@ -56,7 +94,6 @@ IScsiDriverBindingSupported (
)
{
EFI_STATUS Status;
- EFI_DEVICE_PATH_PROTOCOL *CurrentDevicePath;
Status = gBS->OpenProtocol (
ControllerHandle,
@@ -82,17 +119,23 @@ IScsiDriverBindingSupported (
return EFI_UNSUPPORTED;
}
- CurrentDevicePath = RemainingDevicePath;
- if (CurrentDevicePath != NULL) {
- while (!IsDevicePathEnd (CurrentDevicePath)) {
- if ((CurrentDevicePath->Type == MESSAGING_DEVICE_PATH) && (CurrentDevicePath->SubType == MSG_ISCSI_DP)) {
- return EFI_SUCCESS;
- }
+ Status = IScsiIsDevicePathSupported (RemainingDevicePath);
+ if (EFI_ERROR (Status)) {
+ return EFI_UNSUPPORTED;
+ }
- CurrentDevicePath = NextDevicePathNode (CurrentDevicePath);
+ if (IScsiDhcpIsConfigured (ControllerHandle)) {
+ Status = gBS->OpenProtocol (
+ ControllerHandle,
+ &gEfiDhcp4ServiceBindingProtocolGuid,
+ NULL,
+ This->DriverBindingHandle,
+ ControllerHandle,
+ EFI_OPEN_PROTOCOL_TEST_PROTOCOL
+ );
+ if (EFI_ERROR (Status)) {
+ return EFI_UNSUPPORTED;
}
-
- return EFI_UNSUPPORTED;
}
return EFI_SUCCESS;
@@ -170,7 +213,7 @@ IScsiDriverBindingStart (
goto ON_ERROR;
}
- //
+ //
// Always install private protocol no matter what happens later. We need to
// keep the relationship between ControllerHandle and ChildHandle.
//
diff --git a/MdeModulePkg/Universal/Network/IScsiDxe/IScsiMisc.c b/MdeModulePkg/Universal/Network/IScsiDxe/IScsiMisc.c
index 5341e5a01..2e43b415e 100644
--- a/MdeModulePkg/Universal/Network/IScsiDxe/IScsiMisc.c
+++ b/MdeModulePkg/Universal/Network/IScsiDxe/IScsiMisc.c
@@ -1,7 +1,7 @@
/** @file
Miscellaneous routines for iSCSI driver.
-Copyright (c) 2004 - 2011, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2004 - 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
@@ -617,6 +617,59 @@ IScsiCleanDriverData (
}
/**
+ Check wheather the Controller is configured to use DHCP protocol.
+
+ @param[in] Controller The handle of the controller.
+
+ @retval TRUE The handle of the controller need the Dhcp protocol.
+ @retval FALSE The handle of the controller does not need the Dhcp protocol.
+
+**/
+BOOLEAN
+IScsiDhcpIsConfigured (
+ IN EFI_HANDLE Controller
+ )
+{
+ EFI_STATUS Status;
+ EFI_MAC_ADDRESS MacAddress;
+ UINTN HwAddressSize;
+ UINT16 VlanId;
+ CHAR16 MacString[70];
+ ISCSI_SESSION_CONFIG_NVDATA *ConfigDataTmp;
+
+ //
+ // Get the mac string, it's the name of various variable
+ //
+ Status = NetLibGetMacAddress (Controller, &MacAddress, &HwAddressSize);
+ if (EFI_ERROR (Status)) {
+ return FALSE;
+ }
+ VlanId = NetLibGetVlanId (Controller);
+ IScsiMacAddrToStr (&MacAddress, (UINT32) HwAddressSize, VlanId, MacString);
+
+ //
+ // Get the normal configuration.
+ //
+ Status = GetVariable2 (
+ MacString,
+ &gEfiIScsiInitiatorNameProtocolGuid,
+ (VOID**)&ConfigDataTmp,
+ NULL
+ );
+ if (ConfigDataTmp == NULL || EFI_ERROR (Status)) {
+ return FALSE;
+ }
+
+ if (ConfigDataTmp->Enabled && ConfigDataTmp->InitiatorInfoFromDhcp) {
+ FreePool (ConfigDataTmp);
+ return TRUE;
+ }
+
+ FreePool (ConfigDataTmp);
+ return FALSE;
+}
+
+/**
Get the various configuration data of this iSCSI instance.
@param[in] Private The iSCSI driver data.
diff --git a/MdeModulePkg/Universal/Network/IScsiDxe/IScsiMisc.h b/MdeModulePkg/Universal/Network/IScsiDxe/IScsiMisc.h
index 512c67c38..b310c9c57 100644
--- a/MdeModulePkg/Universal/Network/IScsiDxe/IScsiMisc.h
+++ b/MdeModulePkg/Universal/Network/IScsiDxe/IScsiMisc.h
@@ -1,7 +1,7 @@
/** @file
Miscellaneous definitions for iSCSI driver.
-Copyright (c) 2004 - 2011, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2004 - 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
@@ -222,6 +222,20 @@ IScsiCleanDriverData (
);
/**
+ Check wheather the Controller is configured to use DHCP protocol.
+
+ @param[in] Controller The handle of the controller.
+
+ @retval TRUE The handle of the controller need the Dhcp protocol.
+ @retval FALSE The handle of the controller does not need the Dhcp protocol.
+
+**/
+BOOLEAN
+IScsiDhcpIsConfigured (
+ IN EFI_HANDLE Controller
+ );
+
+/**
Get the various configuration data of this iSCSI instance.
@param[in] Private The iSCSI driver data.
diff --git a/MdeModulePkg/Universal/PCD/Dxe/Pcd.c b/MdeModulePkg/Universal/PCD/Dxe/Pcd.c
index 3cd805a88..8a3e8cd50 100644
--- a/MdeModulePkg/Universal/PCD/Dxe/Pcd.c
+++ b/MdeModulePkg/Universal/PCD/Dxe/Pcd.c
@@ -3,7 +3,7 @@
produce the implementation of native PCD protocol and EFI_PCD_PROTOCOL defined in
PI 1.2 Vol3.
-Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>
+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
@@ -16,13 +16,6 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#include "Service.h"
-//
-// Just pre-allocate a memory buffer that is big enough to
-// host all distinct TokenSpace guid in both
-// PEI ExMap and DXE ExMap.
-//
-EFI_GUID *TmpTokenSpaceBuffer[PEI_EXMAPPING_TABLE_SIZE + DXE_EXMAPPING_TABLE_SIZE] = { 0 };
-
///
/// PCD database lock.
///
@@ -96,6 +89,25 @@ EFI_PCD_PROTOCOL mEfiPcdInstance = {
DxePcdGetNextTokenSpace
};
+///
+/// Instance of GET_PCD_INFO_PROTOCOL protocol is EDKII native implementation.
+/// This protocol instance support dynamic and dynamicEx type PCDs.
+///
+GET_PCD_INFO_PROTOCOL mGetPcdInfoInstance = {
+ DxeGetPcdInfoGetInfo,
+ DxeGetPcdInfoGetInfoEx,
+ DxeGetPcdInfoGetSku
+};
+
+///
+/// Instance of EFI_GET_PCD_INFO_PROTOCOL which is defined in PI 1.2.1 Vol 3.
+/// This PPI instance only support dyanmicEx type PCD.
+///
+EFI_GET_PCD_INFO_PROTOCOL mEfiGetPcdInfoInstance = {
+ DxeGetPcdInfoGetInfoEx,
+ DxeGetPcdInfoGetSku
+};
+
EFI_HANDLE mPcdHandle = NULL;
/**
@@ -136,11 +148,90 @@ PcdDxeInit (
&gEfiPcdProtocolGuid, &mEfiPcdInstance,
NULL
);
-
ASSERT_EFI_ERROR (Status);
+ //
+ // Only install PcdInfo PROTOCOL when PCD info content is present.
+ //
+ if (mPcdDatabase.DxeDb->PcdNameTableOffset != 0) {
+ //
+ // Install GET_PCD_INFO_PROTOCOL to handle dynamic type PCD
+ // Install EFI_GET_PCD_INFO_PROTOCOL to handle dynamicEx type PCD
+ //
+ Status = gBS->InstallMultipleProtocolInterfaces (
+ &mPcdHandle,
+ &gGetPcdInfoProtocolGuid, &mGetPcdInfoInstance,
+ &gEfiGetPcdInfoProtocolGuid, &mEfiGetPcdInfoInstance,
+ NULL
+ );
+ ASSERT_EFI_ERROR (Status);
+ }
+
return Status;
+}
+
+/**
+ Retrieve additional information associated with a PCD token in the default token space.
+
+ This includes information such as the type of value the TokenNumber is associated with as well as possible
+ human readable name that is associated with the token.
+
+ @param[in] TokenNumber The PCD token number.
+ @param[out] PcdInfo The returned information associated with the requested TokenNumber.
+ The caller is responsible for freeing the buffer that is allocated by callee for PcdInfo->PcdName.
+
+ @retval EFI_SUCCESS The PCD information was returned successfully.
+ @retval EFI_NOT_FOUND The PCD service could not find the requested token number.
+**/
+EFI_STATUS
+EFIAPI
+DxeGetPcdInfoGetInfo (
+ IN UINTN TokenNumber,
+ OUT EFI_PCD_INFO *PcdInfo
+ )
+{
+ return DxeGetPcdInfo (NULL, TokenNumber, PcdInfo);
+}
+
+/**
+ Retrieve additional information associated with a PCD token.
+
+ This includes information such as the type of value the TokenNumber is associated with as well as possible
+ human readable name that is associated with the token.
+
+ @param[in] Guid The 128-bit unique value that designates the namespace from which to extract the value.
+ @param[in] TokenNumber The PCD token number.
+ @param[out] PcdInfo The returned information associated with the requested TokenNumber.
+ The caller is responsible for freeing the buffer that is allocated by callee for PcdInfo->PcdName.
+
+ @retval EFI_SUCCESS The PCD information was returned successfully.
+ @retval EFI_NOT_FOUND The PCD service could not find the requested token number.
+**/
+EFI_STATUS
+EFIAPI
+DxeGetPcdInfoGetInfoEx (
+ IN CONST EFI_GUID *Guid,
+ IN UINTN TokenNumber,
+ OUT EFI_PCD_INFO *PcdInfo
+ )
+{
+ return DxeGetPcdInfo (Guid, TokenNumber, PcdInfo);
+}
+
+/**
+ Retrieve the currently set SKU Id.
+ @return The currently set SKU Id. If the platform has not set at a SKU Id, then the
+ default SKU Id value of 0 is returned. If the platform has set a SKU Id, then the currently set SKU
+ Id is returned.
+**/
+UINTN
+EFIAPI
+DxeGetPcdInfoGetSku (
+ VOID
+ )
+{
+ return mPcdDatabase.PeiDb->SystemSkuId;
}
/**
@@ -170,7 +261,7 @@ DxePcdSetSku (
IN UINTN SkuId
)
{
- mPcdDatabase->PeiDb.Init.SystemSkuId = (SKU_ID) SkuId;
+ mPcdDatabase.PeiDb->SystemSkuId = (SKU_ID) SkuId;
return;
}
@@ -336,18 +427,18 @@ DxePcdGetSize (
// EBC compiler is very choosy. It may report warning about comparison
// between UINTN and 0 . So we add 1 in each size of the
// comparison.
- ASSERT (TokenNumber + 1 < PCD_TOTAL_TOKEN_NUMBER + 1);
+ ASSERT (TokenNumber + 1 < mPcdTotalTokenCount + 1);
// EBC compiler is very choosy. It may report warning about comparison
// between UINTN and 0 . So we add 1 in each size of the
// comparison.
- IsPeiDb = (BOOLEAN) (TokenNumber + 1 < PEI_LOCAL_TOKEN_NUMBER + 1);
+ IsPeiDb = (BOOLEAN) (TokenNumber + 1 < mPeiLocalTokenCount + 1);
TokenNumber = IsPeiDb ? TokenNumber :
- (TokenNumber - PEI_LOCAL_TOKEN_NUMBER);
+ (TokenNumber - mPeiLocalTokenCount);
- LocalTokenNumberTable = IsPeiDb ? mPcdDatabase->PeiDb.Init.LocalTokenNumberTable
- : mPcdDatabase->DxeDb.Init.LocalTokenNumberTable;
+ LocalTokenNumberTable = IsPeiDb ? (UINT32 *)((UINT8 *)mPcdDatabase.PeiDb + mPcdDatabase.PeiDb->LocalTokenNumberTableOffset)
+ : (UINT32 *)((UINT8 *)mPcdDatabase.DxeDb + mPcdDatabase.DxeDb->LocalTokenNumberTableOffset);
Size = (LocalTokenNumberTable[TokenNumber] & PCD_DATUM_TYPE_ALL_SET) >> PCD_DATUM_TYPE_SHIFT;
@@ -971,10 +1062,8 @@ DxeUnRegisterCallBackOnSet (
@param[in, out] TokenNumber
A pointer to the PCD token number to use to find the subsequent token number.
- @retval EFI_SUCCESS The PCD service retrieved the next valid token number. Or the input token number
- is already the last valid token number in the PCD database.
- In the later case, *TokenNumber is updated with the value of 0.
- @retval EFI_NOT_FOUND If this input token number and token namespace does not exist on the platform.
+ @retval EFI_SUCCESS The PCD service has retrieved the next valid token number.
+ @retval EFI_NOT_FOUND The PCD service could not find data from the requested token number.
**/
EFI_STATUS
@@ -989,8 +1078,8 @@ DxePcdGetNextToken (
BOOLEAN DxeExMapTableEmpty;
Status = EFI_NOT_FOUND;
- PeiExMapTableEmpty = PEI_EXMAP_TABLE_EMPTY;
- DxeExMapTableEmpty = DXE_EXMAP_TABLE_EMPTY;
+ PeiExMapTableEmpty = mPeiExMapTableEmpty;
+ DxeExMapTableEmpty = mDxeExMapTableEmpty;
//
// Scan the local token space
@@ -999,27 +1088,32 @@ DxePcdGetNextToken (
// EBC compiler is very choosy. It may report warning about comparison
// between UINTN and 0 . So we add 1 in each size of the
// comparison.
- if (((*TokenNumber + 1 > PEI_NEX_TOKEN_NUMBER + 1) && (*TokenNumber + 1 < PEI_LOCAL_TOKEN_NUMBER + 1)) ||
- ((*TokenNumber + 1 > (PEI_LOCAL_TOKEN_NUMBER + DXE_NEX_TOKEN_NUMBER + 1)))) {
- return EFI_NOT_FOUND;
+ if (((*TokenNumber + 1 > mPeiNexTokenCount + 1) && (*TokenNumber + 1 <= mPeiLocalTokenCount + 1)) ||
+ ((*TokenNumber + 1 > (mPeiLocalTokenCount + mDxeNexTokenCount + 1)))) {
+ return EFI_NOT_FOUND;
}
(*TokenNumber)++;
- if ((*TokenNumber + 1 > PEI_NEX_TOKEN_NUMBER + 1) &&
- (*TokenNumber <= PEI_LOCAL_TOKEN_NUMBER)) {
+ if ((*TokenNumber + 1 > mPeiNexTokenCount + 1) &&
+ (*TokenNumber + 1 <= mPeiLocalTokenCount + 1)) {
//
// The first Non-Ex type Token Number for DXE PCD
- // database is PEI_LOCAL_TOKEN_NUMBER
+ // database is mPeiLocalTokenCount + 1
//
- *TokenNumber = PEI_LOCAL_TOKEN_NUMBER;
- } else if (*TokenNumber + 1 > DXE_NEX_TOKEN_NUMBER + PEI_LOCAL_TOKEN_NUMBER + 1) {
+ if (mDxeNexTokenCount > 0) {
+ *TokenNumber = mPeiLocalTokenCount + 1;
+ } else {
+ *TokenNumber = PCD_INVALID_TOKEN_NUMBER;
+ return EFI_NOT_FOUND;
+ }
+ } else if (*TokenNumber + 1 > mDxeNexTokenCount + mPeiLocalTokenCount + 1) {
*TokenNumber = PCD_INVALID_TOKEN_NUMBER;
+ return EFI_NOT_FOUND;
}
return EFI_SUCCESS;
}
if (PeiExMapTableEmpty && DxeExMapTableEmpty) {
- *TokenNumber = PCD_INVALID_TOKEN_NUMBER;
return EFI_NOT_FOUND;
}
@@ -1027,10 +1121,10 @@ DxePcdGetNextToken (
Status = ExGetNextTokeNumber (
Guid,
TokenNumber,
- mPcdDatabase->PeiDb.Init.GuidTable,
- sizeof(mPcdDatabase->PeiDb.Init.GuidTable),
- mPcdDatabase->PeiDb.Init.ExMapTable,
- sizeof(mPcdDatabase->PeiDb.Init.ExMapTable)
+ (EFI_GUID *)((UINT8 *)mPcdDatabase.PeiDb + mPcdDatabase.PeiDb->GuidTableOffset),
+ mPeiGuidTableSize,
+ (DYNAMICEX_MAPPING *)((UINT8 *) mPcdDatabase.PeiDb + mPcdDatabase.PeiDb->ExMapTableOffset),
+ mPeiExMapppingTableSize
);
}
@@ -1042,10 +1136,10 @@ DxePcdGetNextToken (
Status = ExGetNextTokeNumber (
Guid,
TokenNumber,
- mPcdDatabase->DxeDb.Init.GuidTable,
- sizeof(mPcdDatabase->DxeDb.Init.GuidTable),
- mPcdDatabase->DxeDb.Init.ExMapTable,
- sizeof(mPcdDatabase->DxeDb.Init.ExMapTable)
+ (EFI_GUID *)((UINT8 *)mPcdDatabase.DxeDb + mPcdDatabase.DxeDb->GuidTableOffset),
+ mDxeGuidTableSize,
+ (DYNAMICEX_MAPPING *)((UINT8 *) mPcdDatabase.DxeDb + mPcdDatabase.DxeDb->ExMapTableOffset),
+ mDxeExMapppingTableSize
);
}
@@ -1055,7 +1149,7 @@ DxePcdGetNextToken (
/**
Get all token space guid table which is different with given token space guid.
- @param ExMapTableSize The size of guid table
+ @param ExMapTableSize The size of ExMapTable in item
@param ExMapTable Token space guid table that want to be scaned.
@param GuidTable Guid table
@@ -1072,8 +1166,9 @@ GetDistinctTokenSpace (
EFI_GUID **DistinctTokenSpace;
UINTN OldGuidIndex;
UINTN TsIdx;
+ UINTN TempTsIdx;
UINTN Idx;
-
+ BOOLEAN Match;
DistinctTokenSpace = AllocateZeroPool (*ExMapTableSize * sizeof (EFI_GUID *));
ASSERT (DistinctTokenSpace != NULL);
@@ -1082,8 +1177,18 @@ GetDistinctTokenSpace (
OldGuidIndex = ExMapTable[0].ExGuidIndex;
DistinctTokenSpace[TsIdx] = &GuidTable[OldGuidIndex];
for (Idx = 1; Idx < *ExMapTableSize; Idx++) {
- if (ExMapTable[Idx].ExGuidIndex != OldGuidIndex) {
- OldGuidIndex = ExMapTable[Idx].ExGuidIndex;
+ Match = FALSE;
+ OldGuidIndex = ExMapTable[Idx].ExGuidIndex;
+ for (TempTsIdx = 0; TempTsIdx <= TsIdx; TempTsIdx++) {
+ if (&GuidTable[OldGuidIndex] == DistinctTokenSpace[TempTsIdx]) {
+ //
+ // Have recorded this GUID.
+ //
+ Match = TRUE;
+ break;
+ }
+ }
+ if (!Match) {
DistinctTokenSpace[++TsIdx] = &GuidTable[OldGuidIndex];
}
}
@@ -1099,16 +1204,20 @@ GetDistinctTokenSpace (
}
/**
- Get next token space in PCD database according to given token space guid.
-
- @param Guid Given token space guid. If NULL, then Guid will be set to
- the first PCD token space in PCD database, If not NULL, then
- Guid will be set to next PCD token space.
-
- @retval EFI_UNSUPPORTED
- @retval EFI_NOT_FOUND If PCD database has no token space table or can not find given
- token space in PCD database.
- @retval EFI_SUCCESS Success to get next token space guid.
+ Retrieves the next valid PCD token namespace for a given namespace.
+
+ Gets the next valid token namespace for a given namespace. This is useful to traverse the valid
+ token namespaces on a platform.
+
+ @param[in, out] Guid An indirect pointer to EFI_GUID. On input it designates a known token
+ namespace from which the search will start. On output, it designates the next valid
+ token namespace on the platform. If *Guid is NULL, then the GUID of the first token
+ space of the current platform is returned. If the search cannot locate the next valid
+ token namespace, an error is returned and the value of *Guid is undefined.
+
+ @retval EFI_SUCCESS The PCD service retrieved the value requested.
+ @retval EFI_NOT_FOUND The PCD service could not find the next valid token namespace.
+
**/
EFI_STATUS
EFIAPI
@@ -1129,35 +1238,31 @@ DxePcdGetNextTokenSpace (
ASSERT (Guid != NULL);
- PeiExMapTableEmpty = PEI_EXMAP_TABLE_EMPTY;
- DxeExMapTableEmpty = DXE_EXMAP_TABLE_EMPTY;
+ PeiExMapTableEmpty = mPeiExMapTableEmpty;
+ DxeExMapTableEmpty = mDxeExMapTableEmpty;
if (PeiExMapTableEmpty && DxeExMapTableEmpty) {
- if (*Guid != NULL) {
- return EFI_NOT_FOUND;
- } else {
- return EFI_SUCCESS;
- }
+ return EFI_NOT_FOUND;
}
-
if (TmpTokenSpaceBuffer[0] == NULL) {
PeiTokenSpaceTableSize = 0;
if (!PeiExMapTableEmpty) {
- PeiTokenSpaceTableSize = PEI_EXMAPPING_TABLE_SIZE;
+ PeiTokenSpaceTableSize = mPeiExMapppingTableSize / sizeof(DYNAMICEX_MAPPING);
PeiTokenSpaceTable = GetDistinctTokenSpace (&PeiTokenSpaceTableSize,
- mPcdDatabase->PeiDb.Init.ExMapTable,
- mPcdDatabase->PeiDb.Init.GuidTable
+ (DYNAMICEX_MAPPING *)((UINT8 *)mPcdDatabase.PeiDb + mPcdDatabase.PeiDb->ExMapTableOffset),
+ (EFI_GUID *)((UINT8 *)mPcdDatabase.PeiDb + mPcdDatabase.PeiDb->GuidTableOffset)
);
CopyMem (TmpTokenSpaceBuffer, PeiTokenSpaceTable, sizeof (EFI_GUID*) * PeiTokenSpaceTableSize);
+ FreePool (PeiTokenSpaceTable);
}
if (!DxeExMapTableEmpty) {
- DxeTokenSpaceTableSize = DXE_EXMAPPING_TABLE_SIZE;
+ DxeTokenSpaceTableSize = mDxeExMapppingTableSize / sizeof(DYNAMICEX_MAPPING);
DxeTokenSpaceTable = GetDistinctTokenSpace (&DxeTokenSpaceTableSize,
- mPcdDatabase->DxeDb.Init.ExMapTable,
- mPcdDatabase->DxeDb.Init.GuidTable
+ (DYNAMICEX_MAPPING *)((UINT8 *)mPcdDatabase.DxeDb + mPcdDatabase.DxeDb->ExMapTableOffset),
+ (EFI_GUID *)((UINT8 *)mPcdDatabase.DxeDb + mPcdDatabase.DxeDb->GuidTableOffset)
);
//
@@ -1175,6 +1280,9 @@ DxePcdGetNextTokenSpace (
TmpTokenSpaceBuffer[Idx3++] = DxeTokenSpaceTable[Idx2];
}
}
+
+ TmpTokenSpaceBufferCount = Idx3;
+ FreePool (DxeTokenSpaceTable);
}
}
@@ -1183,11 +1291,19 @@ DxePcdGetNextTokenSpace (
return EFI_SUCCESS;
}
- for (Idx = 0; Idx < (PEI_EXMAPPING_TABLE_SIZE + DXE_EXMAPPING_TABLE_SIZE); Idx++) {
- if(CompareGuid (*Guid, TmpTokenSpaceBuffer[Idx])) {
- Idx++;
- *Guid = TmpTokenSpaceBuffer[Idx];
- return EFI_SUCCESS;
+ for (Idx = 0; Idx < TmpTokenSpaceBufferCount; Idx++) {
+ if (CompareGuid (*Guid, TmpTokenSpaceBuffer[Idx])) {
+ if (Idx == TmpTokenSpaceBufferCount - 1) {
+ //
+ // It has been the last token namespace.
+ //
+ *Guid = NULL;
+ return EFI_NOT_FOUND;
+ } else {
+ Idx++;
+ *Guid = TmpTokenSpaceBuffer[Idx];
+ return EFI_SUCCESS;
+ }
}
}
diff --git a/MdeModulePkg/Universal/PCD/Dxe/Pcd.inf b/MdeModulePkg/Universal/PCD/Dxe/Pcd.inf
index 112c91e06..2b8d83c12 100644
--- a/MdeModulePkg/Universal/PCD/Dxe/Pcd.inf
+++ b/MdeModulePkg/Universal/PCD/Dxe/Pcd.inf
@@ -1,18 +1,19 @@
## @file
-# PCD DXE driver manage database contains all dynamic PCD entries initialized in
-# PEI phase, DXE phase and produce the implementation of PCD protocol.
+# PCD DXE driver manage database contains all dynamic PCD entries and produce the implementation of PCD protocol.
#
+# This version PCD DXE depends on the external PCD database binary file, not built in PCD data base.
# There are two PCD Protocols as follows:
# 1) PCD_PROTOCOL
# It is EDKII implementation which support Dynamic/DynamicEx type Pcds.
-# 2) EFI_PCD_PROTOCOL_PPI
+# 2) EFI_PCD_PROTOCOL
# It is defined by PI specification 1.2, Vol 3 which only support dynamicEx
# type Pcd.
#
-# For dynamicEx type PCD, it is compatible between PCD_PPI and EFI_PEI_PCD_PPI.
+# For dynamicEx type PCD, it is compatible between PCD_PROTOCOL and EFI_PCD_PROTOCOL.
# PCD DXE driver will produce above two protocols at same time.
#
-# PCD database structure is generated at autogen.h/autogen.c in build time.
+# PCD database is generated as the separate binary image at build time. The binary image
+# will be intergrated into Firmware volume together with PCD driver.
#
# ////////////////////////////////////////////////////////////////////////////////
# // //
@@ -63,7 +64,7 @@
# b) Variable Storage:
# - The PCD value is stored in variable area.
# - As default storage type, this type PCD could be used for PEI/DXE driver
-# communication. But beside it, this type PCD could alsp be used to store
+# communication. But beside it, this type PCD could also be used to store
# the value associate with a HII setting via variable interface.
# - In PEI phase, the PCD value could only be got but can not be set due
# to variable area is readonly.
@@ -94,12 +95,12 @@
# PCD information used in PEI phase or use in both PEI/DXE phase. And DXE PCD
# database contains all PCDs used in PEI/DXE phase in memory.
#
-# Build tool will generate PCD database into some C structure and variable for
+# Build tool will generate PCD database into the separate binary file for
# PEI/DXE PCD driver according to dynamic PCD section in platform DSC file.
#
# 3.1 PcdPeim and PcdDxe
# PEI PCD database is maintained by PcdPeim driver run from flash. PcdPeim driver
-# build guid hob in temporary memory and copy auto-generated C structure
+# build guid hob in temporary memory and copy the binary data base from flash
# to temporary memory for PEI PCD database.
# DXE PCD database is maintained by PcdDxe driver.At entry point of PcdDxe driver,
# a new PCD database is allocated in boot-time memory which including all
@@ -185,8 +186,10 @@
# Based on local token number, PCD driver could fast determine PCD type, value
# type and get PCD entry from PCD database.
#
-# 3.3 PCD Database C structure.
-# PCD Database C structure is generated by build tools in PCD driver's autogen.h/
+# 3.3 PCD Database binary file
+# PCD Database binary file will be created at build time as the standalone binary image.
+# To understand the binary image layout, PCD Database C structure is still generated
+# as comments by build tools in PCD driver's autogen.h/
# autogen.c file. In generated C structure, following information is stored:
# - ExMapTable: This table is used translate a binary dynamicex type PCD's
# "tokenguid + token" to local token number.
@@ -195,7 +198,7 @@
# token number" as array index to get PCD entry's offset fastly.
# - SizeTable: This table stores the size information for all PCD entry.
# - GuidTable: This table stores guid value for DynamicEx's token space,
-# HII type PCD's variable.
+# HII type PCD's variable GUID.
# - SkuIdTable: TBD
# - SystemSkuId: TBD
# - PCD value structure:
@@ -275,8 +278,8 @@
# GuidTable array is used to store all related GUID value in PCD database:
# - Variable GUID for HII type PCD
# - Token space GUID for dynamicex type PCD
-#
-# Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>
+#
+# 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
@@ -293,7 +296,7 @@
BASE_NAME = PcdDxe
FILE_GUID = 80CF7257-87AB-47f9-A3FE-D50B76D89541
MODULE_TYPE = DXE_DRIVER
- VERSION_STRING = 1.0
+ VERSION_STRING = 4.0
PCD_IS_DRIVER = DXE_PCD_DRIVER
ENTRY_POINT = PcdDxeInit
@@ -323,16 +326,20 @@
DebugLib
BaseLib
PcdLib
+ DxeServicesLib
[Guids]
- gPcdDataBaseHobGuid ## CONSUMES ## Hob: GUID_EXTENSION
+ gPcdDataBaseHobGuid ## SOMETIMES_CONSUMES ## HOB
+ gPcdDataBaseSignatureGuid ## CONSUMES ## UNDEFINED # PCD database signature GUID.
[Protocols]
gPcdProtocolGuid ## PRODUCES
gEfiPcdProtocolGuid ## PRODUCES
-
+ gGetPcdInfoProtocolGuid ## SOMETIMES_PRODUCES
+ gEfiGetPcdInfoProtocolGuid ## SOMETIMES_PRODUCES
+
[Pcd]
- gEfiMdeModulePkgTokenSpaceGuid.PcdVpdBaseAddress
+ gEfiMdeModulePkgTokenSpaceGuid.PcdVpdBaseAddress ## SOMETIMES_CONSUMES
[Depex]
TRUE
diff --git a/MdeModulePkg/Universal/PCD/Dxe/Service.c b/MdeModulePkg/Universal/PCD/Dxe/Service.c
index 6eaadd6cc..b082f0a6d 100644
--- a/MdeModulePkg/Universal/PCD/Dxe/Service.c
+++ b/MdeModulePkg/Universal/PCD/Dxe/Service.c
@@ -13,10 +13,336 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#include "Service.h"
+#include <Library/DxeServicesLib.h>
-PCD_DATABASE *mPcdDatabase;
+PCD_DATABASE mPcdDatabase;
+
+UINT32 mPcdTotalTokenCount;
+UINT32 mPeiLocalTokenCount;
+UINT32 mDxeLocalTokenCount;
+UINT32 mPeiNexTokenCount;
+UINT32 mDxeNexTokenCount;
+UINT32 mPeiExMapppingTableSize;
+UINT32 mDxeExMapppingTableSize;
+UINT32 mPeiGuidTableSize;
+UINT32 mDxeGuidTableSize;
+
+BOOLEAN mPeiExMapTableEmpty;
+BOOLEAN mDxeExMapTableEmpty;
+BOOLEAN mPeiDatabaseEmpty;
LIST_ENTRY *mCallbackFnTable;
+EFI_GUID **TmpTokenSpaceBuffer;
+UINTN TmpTokenSpaceBufferCount;
+
+/**
+ Get Local Token Number by Token Number.
+
+ @param[in] IsPeiDb If TRUE, the pcd entry is initialized in PEI phase,
+ If FALSE, the pcd entry is initialized in DXE phase.
+ @param[in] TokenNumber The PCD token number.
+
+ @return Local Token Number.
+**/
+UINT32
+GetLocalTokenNumber (
+ IN BOOLEAN IsPeiDb,
+ IN UINTN TokenNumber
+ )
+{
+ UINT32 *LocalTokenNumberTable;
+ UINT32 LocalTokenNumber;
+ UINTN Size;
+ UINTN MaxSize;
+
+ //
+ // TokenNumber Zero is reserved as PCD_INVALID_TOKEN_NUMBER.
+ // We have to decrement TokenNumber by 1 to make it usable
+ // as the array index.
+ //
+ TokenNumber--;
+
+ LocalTokenNumberTable = IsPeiDb ? (UINT32 *)((UINT8 *)mPcdDatabase.PeiDb + mPcdDatabase.PeiDb->LocalTokenNumberTableOffset) :
+ (UINT32 *)((UINT8 *)mPcdDatabase.DxeDb + mPcdDatabase.DxeDb->LocalTokenNumberTableOffset);
+ TokenNumber = IsPeiDb ? TokenNumber : TokenNumber - mPeiLocalTokenCount;
+
+ LocalTokenNumber = LocalTokenNumberTable[TokenNumber];
+
+ Size = (LocalTokenNumber & PCD_DATUM_TYPE_ALL_SET) >> PCD_DATUM_TYPE_SHIFT;
+
+ if ((LocalTokenNumber & PCD_TYPE_SKU_ENABLED) == PCD_TYPE_SKU_ENABLED) {
+ if (Size == 0) {
+ GetPtrTypeSize (TokenNumber, &MaxSize);
+ } else {
+ MaxSize = Size;
+ }
+ LocalTokenNumber = GetSkuEnabledTokenNumber (LocalTokenNumber & ~PCD_TYPE_SKU_ENABLED, MaxSize, IsPeiDb);
+ }
+
+ return LocalTokenNumber;
+}
+
+/**
+ Get PCD type by Local Token Number.
+
+ @param[in] LocalTokenNumber The PCD local token number.
+
+ @return PCD type.
+**/
+EFI_PCD_TYPE
+GetPcdType (
+ IN UINT32 LocalTokenNumber
+ )
+{
+ switch (LocalTokenNumber & PCD_DATUM_TYPE_ALL_SET) {
+ case PCD_DATUM_TYPE_POINTER:
+ return EFI_PCD_TYPE_PTR;
+ case PCD_DATUM_TYPE_UINT8:
+ if ((LocalTokenNumber & PCD_DATUM_TYPE_UINT8_BOOLEAN) == PCD_DATUM_TYPE_UINT8_BOOLEAN) {
+ return EFI_PCD_TYPE_BOOL;
+ } else {
+ return EFI_PCD_TYPE_8;
+ }
+ case PCD_DATUM_TYPE_UINT16:
+ return EFI_PCD_TYPE_16;
+ case PCD_DATUM_TYPE_UINT32:
+ return EFI_PCD_TYPE_32;
+ case PCD_DATUM_TYPE_UINT64:
+ return EFI_PCD_TYPE_64;
+ default:
+ ASSERT (FALSE);
+ return EFI_PCD_TYPE_8;
+ }
+}
+
+/**
+ Get PCD name.
+
+ @param[in] OnlyTokenSpaceName If TRUE, only need to get the TokenSpaceCName.
+ If FALSE, need to get the full PCD name.
+ @param[in] IsPeiDb If TRUE, the pcd entry is initialized in PEI phase,
+ If FALSE, the pcd entry is initialized in DXE phase.
+ @param[in] TokenNumber The PCD token number.
+
+ @return The TokenSpaceCName or full PCD name.
+**/
+CHAR8 *
+GetPcdName (
+ IN BOOLEAN OnlyTokenSpaceName,
+ IN BOOLEAN IsPeiDb,
+ IN UINTN TokenNumber
+ )
+{
+ PCD_DATABASE_INIT *Database;
+ UINT8 *StringTable;
+ PCD_NAME_INDEX *PcdNameIndex;
+ CHAR8 *TokenSpaceName;
+ CHAR8 *PcdName;
+ CHAR8 *Name;
+
+ //
+ // TokenNumber Zero is reserved as PCD_INVALID_TOKEN_NUMBER.
+ // We have to decrement TokenNumber by 1 to make it usable
+ // as the array index.
+ //
+ TokenNumber--;
+
+ Database = IsPeiDb ? mPcdDatabase.PeiDb: mPcdDatabase.DxeDb;
+ TokenNumber = IsPeiDb ? TokenNumber : TokenNumber - mPeiLocalTokenCount;
+
+ StringTable = (UINT8 *) Database + Database->StringTableOffset;
+
+ //
+ // Get the PCD name index.
+ //
+ PcdNameIndex = (PCD_NAME_INDEX *)((UINT8 *) Database + Database->PcdNameTableOffset) + TokenNumber;
+ TokenSpaceName = (CHAR8 *)&StringTable[PcdNameIndex->TokenSpaceCNameIndex];
+ PcdName = (CHAR8 *)&StringTable[PcdNameIndex->PcdCNameIndex];
+
+ if (OnlyTokenSpaceName) {
+ //
+ // Only need to get the TokenSpaceCName.
+ //
+ Name = AllocateCopyPool (AsciiStrSize (TokenSpaceName), TokenSpaceName);
+ } else {
+ //
+ // Need to get the full PCD name.
+ //
+ Name = AllocateZeroPool (AsciiStrSize (TokenSpaceName) + AsciiStrSize (PcdName));
+ ASSERT (Name != NULL);
+ //
+ // Catenate TokenSpaceCName and PcdCName with a '.' to form the full PCD name.
+ //
+ AsciiStrCat (Name, TokenSpaceName);
+ Name[AsciiStrSize (TokenSpaceName) - sizeof (CHAR8)] = '.';
+ AsciiStrCat (Name, PcdName);
+ }
+
+ return Name;
+}
+
+/**
+ Retrieve additional information associated with a PCD token.
+
+ This includes information such as the type of value the TokenNumber is associated with as well as possible
+ human readable name that is associated with the token.
+
+ @param[in] IsPeiDb If TRUE, the pcd entry is initialized in PEI phase,
+ If FALSE, the pcd entry is initialized in DXE phase.
+ @param[in] Guid The 128-bit unique value that designates the namespace from which to extract the value.
+ @param[in] TokenNumber The PCD token number.
+ @param[out] PcdInfo The returned information associated with the requested TokenNumber.
+ The caller is responsible for freeing the buffer that is allocated by callee for PcdInfo->PcdName.
+
+ @retval EFI_SUCCESS The PCD information was returned successfully
+ @retval EFI_NOT_FOUND The PCD service could not find the requested token number.
+**/
+EFI_STATUS
+ExGetPcdInfo (
+ IN BOOLEAN IsPeiDb,
+ IN CONST EFI_GUID *Guid,
+ IN UINTN TokenNumber,
+ OUT EFI_PCD_INFO *PcdInfo
+ )
+{
+ PCD_DATABASE_INIT *Database;
+ UINTN GuidTableIdx;
+ EFI_GUID *MatchGuid;
+ EFI_GUID *GuidTable;
+ DYNAMICEX_MAPPING *ExMapTable;
+ UINTN Index;
+ UINT32 LocalTokenNumber;
+
+ Database = IsPeiDb ? mPcdDatabase.PeiDb: mPcdDatabase.DxeDb;
+
+ GuidTable = (EFI_GUID *)((UINT8 *)Database + Database->GuidTableOffset);
+ MatchGuid = ScanGuid (GuidTable, Database->GuidTableCount * sizeof(EFI_GUID), Guid);
+
+ if (MatchGuid == NULL) {
+ return EFI_NOT_FOUND;
+ }
+
+ GuidTableIdx = MatchGuid - GuidTable;
+
+ ExMapTable = (DYNAMICEX_MAPPING *)((UINT8 *)Database + Database->ExMapTableOffset);
+
+ //
+ // Find the PCD by GuidTableIdx and ExTokenNumber in ExMapTable.
+ //
+ for (Index = 0; Index < Database->ExTokenCount; Index++) {
+ if (ExMapTable[Index].ExGuidIndex == GuidTableIdx) {
+ if (TokenNumber == PCD_INVALID_TOKEN_NUMBER) {
+ //
+ // TokenNumber is 0, follow spec to set PcdType to EFI_PCD_TYPE_8,
+ // PcdSize to 0 and PcdName to the null-terminated ASCII string
+ // associated with the token's namespace Guid.
+ //
+ PcdInfo->PcdType = EFI_PCD_TYPE_8;
+ PcdInfo->PcdSize = 0;
+ //
+ // Here use one representative in the token space to get the TokenSpaceCName.
+ //
+ PcdInfo->PcdName = GetPcdName (TRUE, IsPeiDb, ExMapTable[Index].TokenNumber);
+ return EFI_SUCCESS;
+ } else if (ExMapTable[Index].ExTokenNumber == TokenNumber) {
+ PcdInfo->PcdSize = DxePcdGetSize (ExMapTable[Index].TokenNumber);
+ LocalTokenNumber = GetLocalTokenNumber (IsPeiDb, ExMapTable[Index].TokenNumber);
+ PcdInfo->PcdType = GetPcdType (LocalTokenNumber);
+ PcdInfo->PcdName = GetPcdName (FALSE, IsPeiDb, ExMapTable[Index].TokenNumber);
+ return EFI_SUCCESS;
+ }
+ }
+ }
+
+ return EFI_NOT_FOUND;
+}
+
+/**
+ Retrieve additional information associated with a PCD token.
+
+ This includes information such as the type of value the TokenNumber is associated with as well as possible
+ human readable name that is associated with the token.
+
+ @param[in] Guid The 128-bit unique value that designates the namespace from which to extract the value.
+ @param[in] TokenNumber The PCD token number.
+ @param[out] PcdInfo The returned information associated with the requested TokenNumber.
+ The caller is responsible for freeing the buffer that is allocated by callee for PcdInfo->PcdName.
+
+ @retval EFI_SUCCESS The PCD information was returned successfully.
+ @retval EFI_NOT_FOUND The PCD service could not find the requested token number.
+**/
+EFI_STATUS
+DxeGetPcdInfo (
+ IN CONST EFI_GUID *Guid,
+ IN UINTN TokenNumber,
+ OUT EFI_PCD_INFO *PcdInfo
+ )
+{
+ EFI_STATUS Status;
+ BOOLEAN PeiExMapTableEmpty;
+ BOOLEAN DxeExMapTableEmpty;
+ UINT32 LocalTokenNumber;
+ BOOLEAN IsPeiDb;
+
+ ASSERT (PcdInfo != NULL);
+
+ Status = EFI_NOT_FOUND;
+ PeiExMapTableEmpty = mPeiExMapTableEmpty;
+ DxeExMapTableEmpty = mDxeExMapTableEmpty;
+
+ if (Guid == NULL) {
+ if (((TokenNumber + 1 > mPeiNexTokenCount + 1) && (TokenNumber + 1 <= mPeiLocalTokenCount + 1)) ||
+ ((TokenNumber + 1 > (mPeiLocalTokenCount + mDxeNexTokenCount + 1)))) {
+ return EFI_NOT_FOUND;
+ } else if (TokenNumber == PCD_INVALID_TOKEN_NUMBER) {
+ //
+ // TokenNumber is 0, follow spec to set PcdType to EFI_PCD_TYPE_8,
+ // PcdSize to 0 and PcdName to NULL for default Token Space.
+ //
+ PcdInfo->PcdType = EFI_PCD_TYPE_8;
+ PcdInfo->PcdSize = 0;
+ PcdInfo->PcdName = NULL;
+ } else {
+ PcdInfo->PcdSize = DxePcdGetSize (TokenNumber);
+ IsPeiDb = FALSE;
+ if ((TokenNumber + 1 <= mPeiNexTokenCount + 1)) {
+ IsPeiDb = TRUE;
+ }
+ LocalTokenNumber = GetLocalTokenNumber (IsPeiDb, TokenNumber);
+ PcdInfo->PcdType = GetPcdType (LocalTokenNumber);
+ PcdInfo->PcdName = GetPcdName (FALSE, IsPeiDb, TokenNumber);
+ }
+ return EFI_SUCCESS;
+ }
+
+ if (PeiExMapTableEmpty && DxeExMapTableEmpty) {
+ return EFI_NOT_FOUND;
+ }
+
+ if (!PeiExMapTableEmpty) {
+ Status = ExGetPcdInfo (
+ TRUE,
+ Guid,
+ TokenNumber,
+ PcdInfo
+ );
+ }
+
+ if (Status == EFI_SUCCESS) {
+ return Status;
+ }
+
+ if (!DxeExMapTableEmpty) {
+ Status = ExGetPcdInfo (
+ FALSE,
+ Guid,
+ TokenNumber,
+ PcdInfo
+ );
+ }
+
+ return Status;
+}
/**
Get the PCD entry pointer in PCD database.
@@ -38,7 +364,6 @@ GetWorker (
IN UINTN GetSize
)
{
- UINT32 *LocalTokenNumberTable;
EFI_GUID *GuidTable;
UINT8 *StringTable;
EFI_GUID *Guid;
@@ -49,7 +374,6 @@ GetWorker (
VPD_HEAD *VpdHead;
UINT8 *PcdDb;
VOID *RetPtr;
- UINTN MaxSize;
UINTN TmpTokenNumber;
UINTN DataSize;
EFI_STATUS Status;
@@ -64,6 +388,8 @@ GetWorker (
EfiAcquireLock (&mPcdDatabaseLock);
RetPtr = NULL;
+
+ ASSERT (TokenNumber > 0);
//
// TokenNumber Zero is reserved as PCD_INVALID_TOKEN_NUMBER.
// We have to decrement TokenNumber by 1 to make it usable
@@ -72,115 +398,81 @@ GetWorker (
TokenNumber--;
TmpTokenNumber = TokenNumber;
-
+
//
- // PCD_TOTAL_TOKEN_NUMBER is a auto-generated constant.
- // It could be zero. EBC compiler is very choosy. It may
- // report warning. So we add 1 in each size of the
+ // EBC compiler is very choosy. It may report warning about comparison
+ // between UINTN and 0 . So we add 1 in each size of the
// comparison.
//
- ASSERT (TokenNumber + 1 < PCD_TOTAL_TOKEN_NUMBER + 1);
+ ASSERT (TokenNumber + 1 < mPcdTotalTokenCount + 1);
ASSERT ((GetSize == DxePcdGetSize (TokenNumber + 1)) || (GetSize == 0));
// EBC compiler is very choosy. It may report warning about comparison
// between UINTN and 0 . So we add 1 in each size of the
// comparison.
- IsPeiDb = (BOOLEAN) ((TokenNumber + 1 < PEI_LOCAL_TOKEN_NUMBER + 1) ? TRUE : FALSE);
+ IsPeiDb = (BOOLEAN) ((TokenNumber + 1 < mPeiLocalTokenCount + 1) ? TRUE : FALSE);
- LocalTokenNumberTable = IsPeiDb ? mPcdDatabase->PeiDb.Init.LocalTokenNumberTable :
- mPcdDatabase->DxeDb.Init.LocalTokenNumberTable;
+ LocalTokenNumber = GetLocalTokenNumber (IsPeiDb, TokenNumber + 1);
- TokenNumber = IsPeiDb ? TokenNumber :
- TokenNumber - PEI_LOCAL_TOKEN_NUMBER;
-
- LocalTokenNumber = LocalTokenNumberTable[TokenNumber];
-
- if ((LocalTokenNumber & PCD_TYPE_SKU_ENABLED) == PCD_TYPE_SKU_ENABLED) {
- if (GetSize == 0) {
- GetPtrTypeSize (TmpTokenNumber, &MaxSize);
- } else {
- MaxSize = GetSize;
- }
- LocalTokenNumber = GetSkuEnabledTokenNumber (LocalTokenNumber & ~PCD_TYPE_SKU_ENABLED, MaxSize, IsPeiDb);
- }
-
- PcdDb = IsPeiDb ? ((UINT8 *) &mPcdDatabase->PeiDb) : ((UINT8 *) &mPcdDatabase->DxeDb);
+ PcdDb = IsPeiDb ? ((UINT8 *) mPcdDatabase.PeiDb) : ((UINT8 *) mPcdDatabase.DxeDb);
if (IsPeiDb) {
- StringTable = (UINT8 *) (&mPcdDatabase->PeiDb.Init.StringTable[0]);
+ StringTable = (UINT8 *) ((UINT8 *)mPcdDatabase.PeiDb + mPcdDatabase.PeiDb->StringTableOffset);
} else {
- StringTable = (UINT8 *) (&mPcdDatabase->DxeDb.Init.StringTable[0]);
+ StringTable = (UINT8 *) ((UINT8 *)mPcdDatabase.DxeDb + mPcdDatabase.DxeDb->StringTableOffset);
}
-
-
+
+
Offset = LocalTokenNumber & PCD_DATABASE_OFFSET_MASK;
-
+
switch (LocalTokenNumber & PCD_TYPE_ALL_SET) {
case PCD_TYPE_VPD:
VpdHead = (VPD_HEAD *) ((UINT8 *) PcdDb + Offset);
RetPtr = (VOID *) (UINTN) (PcdGet32 (PcdVpdBaseAddress) + VpdHead->Offset);
+
break;
-
+
case PCD_TYPE_HII|PCD_TYPE_STRING:
case PCD_TYPE_HII:
if (IsPeiDb) {
- GuidTable = (EFI_GUID *) (&mPcdDatabase->PeiDb.Init.GuidTable[0]);
+ GuidTable = (EFI_GUID *) ((UINT8 *)mPcdDatabase.PeiDb + mPcdDatabase.PeiDb->GuidTableOffset);
} else {
- GuidTable = (EFI_GUID *) (&mPcdDatabase->DxeDb.Init.GuidTable[0]);
+ GuidTable = (EFI_GUID *) ((UINT8 *)mPcdDatabase.DxeDb + mPcdDatabase.DxeDb->GuidTableOffset);
}
-
+
VariableHead = (VARIABLE_HEAD *) (PcdDb + Offset);
Guid = GuidTable + VariableHead->GuidTableIndex;
Name = (UINT16*)(StringTable + VariableHead->StringIndex);
-
+
if ((LocalTokenNumber & PCD_TYPE_ALL_SET) == (PCD_TYPE_HII|PCD_TYPE_STRING)) {
- //
- // If a HII type PCD's datum type is VOID*, the DefaultValueOffset is the index of
- // string array in string table.
- //
+ //
+ // If a HII type PCD's datum type is VOID*, the DefaultValueOffset is the index of
+ // string array in string table.
+ //
StringTableIdx = *(STRING_HEAD*)((UINT8 *) PcdDb + VariableHead->DefaultValueOffset);
VaraiableDefaultBuffer = (VOID *) (StringTable + StringTableIdx);
- Status = GetHiiVariable (Guid, Name, &Data, &DataSize);
- if (Status == EFI_SUCCESS) {
- if (GetSize == 0) {
- //
- // It is a pointer type. So get the MaxSize reserved for
- // this PCD entry.
- //
- GetPtrTypeSize (TmpTokenNumber, &GetSize);
- }
- //
- // If the operation is successful, we copy the data
- // to the default value buffer in the PCD Database.
- // So that we can free the Data allocated in GetHiiVariable.
- //
- CopyMem (VaraiableDefaultBuffer, Data + VariableHead->Offset, GetSize);
- FreePool (Data);
- }
- RetPtr = (VOID *) VaraiableDefaultBuffer;
} else {
VaraiableDefaultBuffer = (UINT8 *) PcdDb + VariableHead->DefaultValueOffset;
-
- Status = GetHiiVariable (Guid, Name, &Data, &DataSize);
- if (Status == EFI_SUCCESS) {
- if (GetSize == 0) {
- //
- // It is a pointer type. So get the MaxSize reserved for
- // this PCD entry.
- //
- GetPtrTypeSize (TmpTokenNumber, &GetSize);
- }
+ }
+ Status = GetHiiVariable (Guid, Name, &Data, &DataSize);
+ if (Status == EFI_SUCCESS) {
+ if (GetSize == 0) {
//
- // If the operation is successful, we copy the data
- // to the default value buffer in the PCD Database.
- // So that we can free the Data allocated in GetHiiVariable.
+ // It is a pointer type. So get the MaxSize reserved for
+ // this PCD entry.
//
- CopyMem (VaraiableDefaultBuffer, Data + VariableHead->Offset, GetSize);
- FreePool (Data);
+ GetPtrTypeSize (TmpTokenNumber, &GetSize);
}
- RetPtr = (VOID *) VaraiableDefaultBuffer;
+ //
+ // If the operation is successful, we copy the data
+ // to the default value buffer in the PCD Database.
+ // So that we can free the Data allocated in GetHiiVariable.
+ //
+ CopyMem (VaraiableDefaultBuffer, Data + VariableHead->Offset, GetSize);
+ FreePool (Data);
}
+ RetPtr = (VOID *) VaraiableDefaultBuffer;
break;
case PCD_TYPE_STRING:
@@ -199,9 +491,9 @@ GetWorker (
}
EfiReleaseLock (&mPcdDatabaseLock);
-
+
return RetPtr;
-
+
}
/**
@@ -359,6 +651,7 @@ ExGetNextTokeNumber (
UINTN Index;
UINTN GuidTableIdx;
BOOLEAN Found;
+ UINTN ExMapTableCount;
//
// Scan token space guid
@@ -373,7 +666,8 @@ ExGetNextTokeNumber (
//
Found = FALSE;
GuidTableIdx = MatchGuid - GuidTable;
- for (Index = 0; Index < SizeOfExMapTable; Index++) {
+ ExMapTableCount = SizeOfExMapTable / sizeof(ExMapTable[0]);
+ for (Index = 0; Index < ExMapTableCount; Index++) {
if (ExMapTable[Index].ExGuidIndex == GuidTableIdx) {
Found = TRUE;
break;
@@ -390,36 +684,71 @@ ExGetNextTokeNumber (
return EFI_SUCCESS;
}
- for ( ; Index < SizeOfExMapTable; Index++) {
+ for ( ; Index < ExMapTableCount; Index++) {
if (ExMapTable[Index].ExTokenNumber == *TokenNumber) {
- Index ++;
- if (Index == SizeOfExMapTable) {
- //
- // Exceed the length of ExMap Table
- //
- *TokenNumber = PCD_INVALID_TOKEN_NUMBER;
- return EFI_SUCCESS;
- } else if (ExMapTable[Index].ExGuidIndex == GuidTableIdx) {
- //
- // Found the next match
- //
- *TokenNumber = ExMapTable[Index].ExTokenNumber;
- return EFI_SUCCESS;
- } else {
- //
- // Guid has been changed. It is the next Token Space Guid.
- // We should flag no more TokenNumber.
- //
- *TokenNumber = PCD_INVALID_TOKEN_NUMBER;
- return EFI_SUCCESS;
- }
+ break;
+ }
+ }
+
+ while (Index < ExMapTableCount) {
+ Index++;
+ if (Index == ExMapTableCount) {
+ //
+ // Exceed the length of ExMap Table
+ //
+ *TokenNumber = PCD_INVALID_TOKEN_NUMBER;
+ return EFI_NOT_FOUND;
+ } else if (ExMapTable[Index].ExGuidIndex == GuidTableIdx) {
+ //
+ // Found the next match
+ //
+ *TokenNumber = ExMapTable[Index].ExTokenNumber;
+ return EFI_SUCCESS;
}
}
}
-
+
return EFI_NOT_FOUND;
}
+/**
+ Find the PCD database.
+
+ @retval The base address of external PCD database binary.
+ @retval NULL Return NULL if not find.
+**/
+DXE_PCD_DATABASE *
+LocateExPcdBinary (
+ VOID
+)
+{
+ DXE_PCD_DATABASE *DxePcdDbBinary;
+ UINTN DxePcdDbSize;
+ EFI_STATUS Status;
+
+ DxePcdDbBinary = NULL;
+ //
+ // Search the External Pcd database from one section of current FFS,
+ // and read it to memory
+ //
+ Status = GetSectionFromFfs (
+ EFI_SECTION_RAW,
+ 0,
+ (VOID **) &DxePcdDbBinary,
+ &DxePcdDbSize
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Check the first bytes (Header Signature Guid) and build version.
+ //
+ if (!CompareGuid ((VOID *)DxePcdDbBinary, &gPcdDataBaseSignatureGuid) ||
+ (DxePcdDbBinary->BuildVersion != PCD_SERVICE_DXE_VERSION)) {
+ ASSERT (FALSE);
+ }
+
+ return DxePcdDbBinary;
+}
/**
Initialize the PCD database in DXE phase.
@@ -436,15 +765,12 @@ BuildPcdDxeDataBase (
PEI_PCD_DATABASE *PeiDatabase;
EFI_HOB_GUID_TYPE *GuidHob;
UINTN Index;
-
- mPcdDatabase = AllocateZeroPool (sizeof(PCD_DATABASE));
- ASSERT (mPcdDatabase != NULL);
+ UINT32 PcdDxeDbLen;
+ VOID *PcdDxeDb;
GuidHob = GetFirstGuidHob (&gPcdDataBaseHobGuid);
if (GuidHob != NULL) {
- //
- // We will copy over the PEI phase's PCD Database.
//
// If no PEIMs use dynamic Pcd Entry, the Pcd Service PEIM
// should not be included at all. So the GuidHob could
@@ -454,28 +780,57 @@ BuildPcdDxeDataBase (
PeiDatabase = (PEI_PCD_DATABASE *) GET_GUID_HOB_DATA (GuidHob);
//
- // Copy PCD Entries refereneced in PEI phase to PCD DATABASE
+ // Assign PCD Entries refereneced in PEI phase to PCD DATABASE
//
- CopyMem (&mPcdDatabase->PeiDb, PeiDatabase, sizeof (PEI_PCD_DATABASE));
+ mPcdDatabase.PeiDb = PeiDatabase;
}
//
- // Copy PCD Entries with default value to PCD DATABASE
+ // Assign PCD Entries with default value to PCD DATABASE
+ //
+ mPcdDatabase.DxeDb = LocateExPcdBinary ();
+ ASSERT(mPcdDatabase.DxeDb != NULL);
+ PcdDxeDbLen = mPcdDatabase.DxeDb->Length + mPcdDatabase.DxeDb->UninitDataBaseSize;
+ PcdDxeDb = AllocateZeroPool (PcdDxeDbLen);
+ ASSERT (PcdDxeDb != NULL);
+ CopyMem (PcdDxeDb, mPcdDatabase.DxeDb, mPcdDatabase.DxeDb->Length);
+ FreePool (mPcdDatabase.DxeDb);
+ mPcdDatabase.DxeDb = PcdDxeDb;
+
+ //
+ // Initialized the external PCD database local variables
//
- CopyMem (&mPcdDatabase->DxeDb.Init, &gDXEPcdDbInit, sizeof(DXE_PCD_DATABASE_INIT));
+ mPeiLocalTokenCount = mPcdDatabase.PeiDb->LocalTokenCount;
+ mDxeLocalTokenCount = mPcdDatabase.DxeDb->LocalTokenCount;
+
+ mPeiExMapppingTableSize = mPcdDatabase.PeiDb->ExTokenCount * sizeof (DYNAMICEX_MAPPING);
+ mDxeExMapppingTableSize = mPcdDatabase.DxeDb->ExTokenCount * sizeof (DYNAMICEX_MAPPING);
+ mPeiGuidTableSize = mPcdDatabase.PeiDb->GuidTableCount * sizeof(GUID);
+ mDxeGuidTableSize = mPcdDatabase.DxeDb->GuidTableCount * sizeof (GUID);
+
+ mPcdTotalTokenCount = mPeiLocalTokenCount + mDxeLocalTokenCount;
+ mPeiNexTokenCount = mPeiLocalTokenCount - mPcdDatabase.PeiDb->ExTokenCount;
+ mDxeNexTokenCount = mDxeLocalTokenCount - mPcdDatabase.DxeDb->ExTokenCount;
+
+ mPeiExMapTableEmpty = (mPcdDatabase.PeiDb->ExTokenCount == 0) ? TRUE : FALSE;
+ mDxeExMapTableEmpty = (mPcdDatabase.DxeDb->ExTokenCount == 0) ? TRUE : FALSE;
+ mPeiDatabaseEmpty = (mPeiLocalTokenCount == 0) ? TRUE : FALSE;
+ TmpTokenSpaceBufferCount = mPcdDatabase.PeiDb->ExTokenCount + mPcdDatabase.DxeDb->ExTokenCount;
+ TmpTokenSpaceBuffer = (EFI_GUID **)AllocateZeroPool(TmpTokenSpaceBufferCount * sizeof (EFI_GUID *));
//
// Initialized the Callback Function Table
//
-
- mCallbackFnTable = AllocateZeroPool (PCD_TOTAL_TOKEN_NUMBER * sizeof (LIST_ENTRY));
+ mCallbackFnTable = AllocateZeroPool (mPcdTotalTokenCount * sizeof (LIST_ENTRY));
ASSERT(mCallbackFnTable != NULL);
-
+
+ //
// EBC compiler is very choosy. It may report warning about comparison
// between UINTN and 0 . So we add 1 in each size of the
// comparison.
- for (Index = 0; Index + 1 < PCD_TOTAL_TOKEN_NUMBER + 1; Index++) {
+ //
+ for (Index = 0; Index + 1 < mPcdTotalTokenCount + 1; Index++) {
InitializeListHead (&mCallbackFnTable[Index]);
}
}
@@ -568,29 +923,39 @@ GetSkuEnabledTokenNumber (
SKU_ID *SkuIdTable;
INTN Index;
UINT8 *Value;
- SKU_ID *PhaseSkuIdTable;
UINT8 *PcdDb;
+ BOOLEAN FoundSku;
ASSERT ((LocalTokenNumber & PCD_TYPE_SKU_ENABLED) == 0);
- PcdDb = IsPeiDb ? (UINT8 *) &mPcdDatabase->PeiDb : (UINT8 *) &mPcdDatabase->DxeDb;
+ PcdDb = IsPeiDb ? (UINT8 *) mPcdDatabase.PeiDb : (UINT8 *) mPcdDatabase.DxeDb;
SkuHead = (SKU_HEAD *) (PcdDb + (LocalTokenNumber & PCD_DATABASE_OFFSET_MASK));
Value = (UINT8 *) (PcdDb + SkuHead->SkuDataStartOffset);
- PhaseSkuIdTable = IsPeiDb ? mPcdDatabase->PeiDb.Init.SkuIdTable :
- mPcdDatabase->DxeDb.Init.SkuIdTable;
-
- SkuIdTable = &PhaseSkuIdTable[SkuHead->SkuIdTableOffset];
-
+ SkuIdTable = (SKU_ID *)(PcdDb + SkuHead->SkuIdTableOffset);
//
// Find the current system's SKU ID entry in SKU ID table.
//
+ FoundSku = FALSE;
for (Index = 0; Index < SkuIdTable[0]; Index++) {
- if (mPcdDatabase->PeiDb.Init.SystemSkuId == SkuIdTable[Index + 1]) {
+ if (mPcdDatabase.PeiDb->SystemSkuId == SkuIdTable[Index + 1]) {
+ FoundSku = TRUE;
break;
}
}
+
+ //
+ // Find the default SKU ID entry in SKU ID table.
+ //
+
+ if(!FoundSku) {
+ for (Index = 0; Index < SkuIdTable[0]; Index++) {
+ if (0 == SkuIdTable[Index + 1]) {
+ break;
+ }
+ }
+ }
ASSERT (Index < SkuIdTable[0]);
switch (LocalTokenNumber & PCD_TYPE_ALL_SET) {
@@ -602,13 +967,17 @@ GetSkuEnabledTokenNumber (
Value = (UINT8 *) &(((VARIABLE_HEAD *) Value)[Index]);
return (UINT32) ((Value - PcdDb) | PCD_TYPE_HII);
+ case PCD_TYPE_HII|PCD_TYPE_STRING:
+ Value = (UINT8 *) &(((VARIABLE_HEAD *) Value)[Index]);
+ return (UINT32) ((Value - PcdDb) | PCD_TYPE_HII | PCD_TYPE_STRING);
+
case PCD_TYPE_STRING:
Value = (UINT8 *) &(((STRING_HEAD *) Value)[Index]);
return (UINT32) ((Value - PcdDb) | PCD_TYPE_STRING);
case PCD_TYPE_DATA:
Value += Size * Index;
- return (UINT32) (Value - PcdDb);
+ return (UINT32) ((Value - PcdDb) | PCD_TYPE_DATA);
default:
ASSERT (FALSE);
@@ -714,7 +1083,6 @@ SetWorker (
IN BOOLEAN PtrType
)
{
- UINT32 *LocalTokenNumberTable;
BOOLEAN IsPeiDb;
UINT32 LocalTokenNumber;
EFI_GUID *GuidTable;
@@ -744,7 +1112,7 @@ SetWorker (
// between UINTN and 0 . So we add 1 in each size of the
// comparison.
//
- ASSERT (TokenNumber + 1 < PCD_TOTAL_TOKEN_NUMBER + 1);
+ ASSERT (TokenNumber + 1 < mPcdTotalTokenCount + 1);
if (PtrType) {
//
@@ -766,8 +1134,8 @@ SetWorker (
// between UINTN and 0 . So we add 1 in each size of the
// comparison.
//
- if ((TokenNumber + 1 < PEI_NEX_TOKEN_NUMBER + 1) ||
- (TokenNumber + 1 >= PEI_LOCAL_TOKEN_NUMBER + 1 || TokenNumber + 1 < (PEI_LOCAL_TOKEN_NUMBER + DXE_NEX_TOKEN_NUMBER + 1))) {
+ if ((TokenNumber + 1 < mPeiNexTokenCount + 1) ||
+ (TokenNumber + 1 >= mPeiLocalTokenCount + 1 && TokenNumber + 1 < (mPeiLocalTokenCount + mDxeNexTokenCount + 1))) {
InvokeCallbackOnSet (0, NULL, TokenNumber + 1, Data, *Size);
}
@@ -781,33 +1149,18 @@ SetWorker (
// between UINTN and 0 . So we add 1 in each size of the
// comparison.
//
- IsPeiDb = (BOOLEAN) ((TokenNumber + 1 < PEI_LOCAL_TOKEN_NUMBER + 1) ? TRUE : FALSE);
+ IsPeiDb = (BOOLEAN) ((TokenNumber + 1 < mPeiLocalTokenCount + 1) ? TRUE : FALSE);
- LocalTokenNumberTable = IsPeiDb ? mPcdDatabase->PeiDb.Init.LocalTokenNumberTable :
- mPcdDatabase->DxeDb.Init.LocalTokenNumberTable;
-
- TokenNumber = IsPeiDb ? TokenNumber
- : TokenNumber - PEI_LOCAL_TOKEN_NUMBER;
-
- LocalTokenNumber = LocalTokenNumberTable[TokenNumber];
-
- if ((LocalTokenNumber & PCD_TYPE_SKU_ENABLED) == PCD_TYPE_SKU_ENABLED) {
- if (PtrType) {
- GetPtrTypeSize (TmpTokenNumber, &MaxSize);
- } else {
- MaxSize = *Size;
- }
- LocalTokenNumber = GetSkuEnabledTokenNumber (LocalTokenNumber & ~PCD_TYPE_SKU_ENABLED, MaxSize, IsPeiDb);
- }
+ LocalTokenNumber = GetLocalTokenNumber (IsPeiDb, TokenNumber + 1);
Offset = LocalTokenNumber & PCD_DATABASE_OFFSET_MASK;
- PcdDb = IsPeiDb ? ((UINT8 *) &mPcdDatabase->PeiDb) : ((UINT8 *) &mPcdDatabase->DxeDb);
+ PcdDb = IsPeiDb ? ((UINT8 *) mPcdDatabase.PeiDb) : ((UINT8 *) mPcdDatabase.DxeDb);
if (IsPeiDb) {
- StringTable = (UINT8 *) (&mPcdDatabase->PeiDb.Init.StringTable[0]);
+ StringTable = (UINT8 *) ((UINT8 *)mPcdDatabase.PeiDb + mPcdDatabase.PeiDb->StringTableOffset);
} else {
- StringTable = (UINT8 *) (&mPcdDatabase->DxeDb.Init.StringTable[0]);
+ StringTable = (UINT8 *) ((UINT8 *)mPcdDatabase.DxeDb + mPcdDatabase.DxeDb->StringTableOffset);
}
@@ -836,20 +1189,20 @@ SetWorker (
break;
}
}
-
+
if (IsPeiDb) {
- GuidTable = (EFI_GUID *) (&mPcdDatabase->PeiDb.Init.GuidTable[0]);
+ GuidTable = (EFI_GUID *) ((UINT8 *)mPcdDatabase.PeiDb + mPcdDatabase.PeiDb->GuidTableOffset);
} else {
- GuidTable = (EFI_GUID *) (&mPcdDatabase->DxeDb.Init.GuidTable[0]);
+ GuidTable = (EFI_GUID *) ((UINT8 *)mPcdDatabase.DxeDb + mPcdDatabase.DxeDb->GuidTableOffset);
}
-
+
VariableHead = (VARIABLE_HEAD *) (PcdDb + Offset);
-
+
Guid = GuidTable + VariableHead->GuidTableIndex;
Name = (UINT16*) (StringTable + VariableHead->StringIndex);
VariableOffset = VariableHead->Offset;
Status = SetHiiVariable (Guid, Name, Data, *Size, VariableOffset);
-
+
if (EFI_NOT_FOUND == Status) {
if ((LocalTokenNumber & PCD_TYPE_ALL_SET) == (PCD_TYPE_HII|PCD_TYPE_STRING)) {
CopyMem (
@@ -954,7 +1307,7 @@ ExSetValueWorker (
}
/**
- Set value for a dynamic PCD entry.
+ Set value for a dynamic-ex PCD entry.
This routine find the local token number according to dynamic-ex PCD's token
space guid and token number firstly, and invoke callback function if this PCD
@@ -1100,16 +1453,16 @@ SetHiiVariable (
}
/**
- Get local token number according to dynamic-ex PCD's {token space guid:token number}
+ Get Token Number according to dynamic-ex PCD's {token space guid:token number}
A dynamic-ex type PCD, developer must provide pair of token space guid: token number
in DEC file. PCD database maintain a mapping table that translate pair of {token
- space guid: token number} to local token number.
+ space guid: token number} to Token Number.
@param Guid Token space guid for dynamic-ex PCD entry.
@param ExTokenNumber Dynamic-ex PCD token number.
- @return local token number for dynamic-ex PCD.
+ @return Token Number for dynamic-ex PCD.
**/
UINTN
@@ -1124,29 +1477,29 @@ GetExPcdTokenNumber (
EFI_GUID *MatchGuid;
UINTN MatchGuidIdx;
- if (!PEI_DATABASE_EMPTY) {
- ExMap = mPcdDatabase->PeiDb.Init.ExMapTable;
- GuidTable = mPcdDatabase->PeiDb.Init.GuidTable;
-
- MatchGuid = ScanGuid (GuidTable, sizeof(mPcdDatabase->PeiDb.Init.GuidTable), Guid);
-
+ if (!mPeiDatabaseEmpty) {
+ ExMap = (DYNAMICEX_MAPPING *)((UINT8 *)mPcdDatabase.PeiDb + mPcdDatabase.PeiDb->ExMapTableOffset);
+ GuidTable = (EFI_GUID *)((UINT8 *)mPcdDatabase.PeiDb + mPcdDatabase.PeiDb->GuidTableOffset);
+
+ MatchGuid = ScanGuid (GuidTable, mPeiGuidTableSize, Guid);
+
if (MatchGuid != NULL) {
MatchGuidIdx = MatchGuid - GuidTable;
-
- for (Index = 0; Index < PEI_EXMAPPING_TABLE_SIZE; Index++) {
+
+ for (Index = 0; Index < mPeiExMapppingTableSize; Index++) {
if ((ExTokenNumber == ExMap[Index].ExTokenNumber) &&
(MatchGuidIdx == ExMap[Index].ExGuidIndex)) {
- return ExMap[Index].LocalTokenNumber;
+ return ExMap[Index].TokenNumber;
}
}
}
}
-
- ExMap = mPcdDatabase->DxeDb.Init.ExMapTable;
- GuidTable = mPcdDatabase->DxeDb.Init.GuidTable;
- MatchGuid = ScanGuid (GuidTable, sizeof(mPcdDatabase->DxeDb.Init.GuidTable), Guid);
+ ExMap = (DYNAMICEX_MAPPING *)((UINT8 *)mPcdDatabase.DxeDb + mPcdDatabase.DxeDb->ExMapTableOffset);
+ GuidTable = (EFI_GUID *)((UINT8 *)mPcdDatabase.DxeDb + mPcdDatabase.DxeDb->GuidTableOffset);
+
+ MatchGuid = ScanGuid (GuidTable, mDxeGuidTableSize, Guid);
//
// We need to ASSERT here. If GUID can't be found in GuidTable, this is a
// error in the BUILD system.
@@ -1154,11 +1507,11 @@ GetExPcdTokenNumber (
ASSERT (MatchGuid != NULL);
MatchGuidIdx = MatchGuid - GuidTable;
-
- for (Index = 0; Index < DXE_EXMAPPING_TABLE_SIZE; Index++) {
+
+ for (Index = 0; Index < mDxeExMapppingTableSize; Index++) {
if ((ExTokenNumber == ExMap[Index].ExTokenNumber) &&
(MatchGuidIdx == ExMap[Index].ExGuidIndex)) {
- return ExMap[Index].LocalTokenNumber;
+ return ExMap[Index].TokenNumber;
}
}
@@ -1171,27 +1524,27 @@ GetExPcdTokenNumber (
Get SKU ID table from PCD database.
@param LocalTokenNumberTableIdx Index of local token number in token number table.
- @param IsPeiPcd If TRUE,
-
+ @param IsPeiDb If TRUE, the pcd entry is initialized in PEI phase,
+ If FALSE, the pcd entry is initialized in DXE phase.
@return Pointer to SKU ID array table
**/
SKU_ID *
GetSkuIdArray (
IN UINTN LocalTokenNumberTableIdx,
- IN BOOLEAN IsPeiPcd
+ IN BOOLEAN IsPeiDb
)
{
SKU_HEAD *SkuHead;
UINTN LocalTokenNumber;
UINT8 *Database;
- if (IsPeiPcd) {
- LocalTokenNumber = mPcdDatabase->PeiDb.Init.LocalTokenNumberTable[LocalTokenNumberTableIdx];
- Database = (UINT8 *) &mPcdDatabase->PeiDb;
+ if (IsPeiDb) {
+ LocalTokenNumber = *((UINT32 *)((UINT8 *)mPcdDatabase.PeiDb + mPcdDatabase.PeiDb->LocalTokenNumberTableOffset) + LocalTokenNumberTableIdx);
+ Database = (UINT8 *) mPcdDatabase.PeiDb;
} else {
- LocalTokenNumber = mPcdDatabase->DxeDb.Init.LocalTokenNumberTable[LocalTokenNumberTableIdx - PEI_LOCAL_TOKEN_NUMBER];
- Database = (UINT8 *) &mPcdDatabase->DxeDb;
+ LocalTokenNumber = *((UINT32 *)((UINT8 *)mPcdDatabase.DxeDb + mPcdDatabase.DxeDb->LocalTokenNumberTableOffset) + LocalTokenNumberTableIdx);
+ Database = (UINT8 *) mPcdDatabase.DxeDb;
}
ASSERT ((LocalTokenNumber & PCD_TYPE_SKU_ENABLED) != 0);
@@ -1224,9 +1577,9 @@ GetSizeTableIndex (
SKU_ID *SkuIdTable;
if (IsPeiDb) {
- LocalTokenNumberTable = mPcdDatabase->PeiDb.Init.LocalTokenNumberTable;
+ LocalTokenNumberTable = (UINT32 *)((UINT8 *)mPcdDatabase.PeiDb + mPcdDatabase.PeiDb->LocalTokenNumberTableOffset);
} else {
- LocalTokenNumberTable = mPcdDatabase->DxeDb.Init.LocalTokenNumberTable;
+ LocalTokenNumberTable = (UINT32 *)((UINT8 *)mPcdDatabase.DxeDb + mPcdDatabase.DxeDb->LocalTokenNumberTableOffset);
}
SizeTableIdx = 0;
@@ -1241,11 +1594,12 @@ GetSizeTableIndex (
//
if ((LocalTokenNumber & PCD_TYPE_VPD) != 0) {
//
- // We have only one entry for VPD enabled PCD entry:
+ // We have only two entry for VPD enabled PCD entry:
// 1) MAX Size.
- // We consider current size is equal to MAX size.
+ // 2) Current Size
+ // Current size is equal to MAX size.
//
- SizeTableIdx++;
+ SizeTableIdx += 2;
} else {
if ((LocalTokenNumber & PCD_TYPE_SKU_ENABLED) == 0) {
//
@@ -1297,16 +1651,16 @@ GetPtrTypeSize (
// EBC compiler is very choosy. It may report warning about comparison
// between UINTN and 0 . So we add 1 in each size of the
// comparison.
- IsPeiDb = (BOOLEAN) (LocalTokenNumberTableIdx + 1 < PEI_LOCAL_TOKEN_NUMBER + 1);
+ IsPeiDb = (BOOLEAN) (LocalTokenNumberTableIdx + 1 < mPeiLocalTokenCount + 1);
if (IsPeiDb) {
- LocalTokenNumberTable = mPcdDatabase->PeiDb.Init.LocalTokenNumberTable;
- SizeTable = mPcdDatabase->PeiDb.Init.SizeTable;
+ LocalTokenNumberTable = (UINT32 *)((UINT8 *)mPcdDatabase.PeiDb + mPcdDatabase.PeiDb->LocalTokenNumberTableOffset);
+ SizeTable = (SIZE_INFO *)((UINT8 *)mPcdDatabase.PeiDb + mPcdDatabase.PeiDb->SizeTableOffset);
} else {
- LocalTokenNumberTableIdx -= PEI_LOCAL_TOKEN_NUMBER;
- LocalTokenNumberTable = mPcdDatabase->DxeDb.Init.LocalTokenNumberTable;
- SizeTable = mPcdDatabase->DxeDb.Init.SizeTable;
+ LocalTokenNumberTableIdx -= mPeiLocalTokenCount;
+ LocalTokenNumberTable = (UINT32 *)((UINT8 *)mPcdDatabase.DxeDb + mPcdDatabase.DxeDb->LocalTokenNumberTableOffset);
+ SizeTable = (SIZE_INFO *)((UINT8 *)mPcdDatabase.DxeDb + mPcdDatabase.DxeDb->SizeTableOffset);
}
LocalTokenNumber = LocalTokenNumberTable[LocalTokenNumberTableIdx];
@@ -1322,8 +1676,9 @@ GetPtrTypeSize (
//
if ((LocalTokenNumber & PCD_TYPE_VPD) != 0) {
//
- // We have only one entry for VPD enabled PCD entry:
+ // We have only two entry for VPD enabled PCD entry:
// 1) MAX Size.
+ // 2) Current Size
// We consider current size is equal to MAX size.
//
return *MaxSize;
@@ -1343,7 +1698,7 @@ GetPtrTypeSize (
//
SkuIdTable = GetSkuIdArray (LocalTokenNumberTableIdx, IsPeiDb);
for (Index = 0; Index < SkuIdTable[0]; Index++) {
- if (SkuIdTable[1 + Index] == mPcdDatabase->PeiDb.Init.SystemSkuId) {
+ if (SkuIdTable[1 + Index] == mPcdDatabase.PeiDb->SystemSkuId) {
return SizeTable[SizeTableIdx + 1 + Index];
}
}
@@ -1382,15 +1737,15 @@ SetPtrTypeSize (
// between UINTN and 0 . So we add 1 in each size of the
// comparison.
//
- IsPeiDb = (BOOLEAN) (LocalTokenNumberTableIdx + 1 < PEI_LOCAL_TOKEN_NUMBER + 1);
+ IsPeiDb = (BOOLEAN) (LocalTokenNumberTableIdx + 1 < mPeiLocalTokenCount + 1);
if (IsPeiDb) {
- LocalTokenNumberTable = mPcdDatabase->PeiDb.Init.LocalTokenNumberTable;
- SizeTable = mPcdDatabase->PeiDb.Init.SizeTable;
+ LocalTokenNumberTable = (UINT32 *)((UINT8 *)mPcdDatabase.PeiDb + mPcdDatabase.PeiDb->LocalTokenNumberTableOffset);
+ SizeTable = (SIZE_INFO *)((UINT8 *)mPcdDatabase.PeiDb + mPcdDatabase.PeiDb->SizeTableOffset);
} else {
- LocalTokenNumberTableIdx -= PEI_LOCAL_TOKEN_NUMBER;
- LocalTokenNumberTable = mPcdDatabase->DxeDb.Init.LocalTokenNumberTable;
- SizeTable = mPcdDatabase->DxeDb.Init.SizeTable;
+ LocalTokenNumberTableIdx -= mPeiLocalTokenCount;
+ LocalTokenNumberTable = (UINT32 *)((UINT8 *)mPcdDatabase.DxeDb + mPcdDatabase.DxeDb->LocalTokenNumberTableOffset);
+ SizeTable = (SIZE_INFO *)((UINT8 *)mPcdDatabase.DxeDb + mPcdDatabase.DxeDb->SizeTableOffset);
}
LocalTokenNumber = LocalTokenNumberTable[LocalTokenNumberTableIdx];
@@ -1433,7 +1788,7 @@ SetPtrTypeSize (
//
SkuIdTable = GetSkuIdArray (LocalTokenNumberTableIdx, IsPeiDb);
for (Index = 0; Index < SkuIdTable[0]; Index++) {
- if (SkuIdTable[1 + Index] == mPcdDatabase->PeiDb.Init.SystemSkuId) {
+ if (SkuIdTable[1 + Index] == mPcdDatabase.PeiDb->SystemSkuId) {
SizeTable[SizeTableIdx + 1 + Index] = (SIZE_INFO) *CurrentSize;
return TRUE;
}
diff --git a/MdeModulePkg/Universal/PCD/Dxe/Service.h b/MdeModulePkg/Universal/PCD/Dxe/Service.h
index c15edd3e8..55717dc98 100644
--- a/MdeModulePkg/Universal/PCD/Dxe/Service.h
+++ b/MdeModulePkg/Universal/PCD/Dxe/Service.h
@@ -1,7 +1,7 @@
/** @file
Private functions used by PCD DXE driver.
-Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.<BR>
+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
@@ -17,8 +17,11 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#include <PiDxe.h>
#include <Guid/PcdDataBaseHobGuid.h>
+#include <Guid/PcdDataBaseSignatureGuid.h>
#include <Protocol/Pcd.h>
#include <Protocol/PiPcd.h>
+#include <Protocol/PcdInfo.h>
+#include <Protocol/PiPcdInfo.h>
#include <Library/BaseLib.h>
#include <Library/DebugLib.h>
#include <Library/UefiLib.h>
@@ -34,7 +37,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
// Please make sure the PCD Serivce DXE Version is consistent with
// the version of the generated DXE PCD Database by build tool.
//
-#define PCD_SERVICE_DXE_VERSION 2
+#define PCD_SERVICE_DXE_VERSION 4
//
// PCD_DXE_SERVICE_DRIVER_VERSION is defined in Autogen.h.
@@ -43,6 +46,61 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#error "Please make sure the version of PCD DXE Service and the generated PCD DXE Database match."
#endif
+/**
+ Retrieve additional information associated with a PCD token in the default token space.
+
+ This includes information such as the type of value the TokenNumber is associated with as well as possible
+ human readable name that is associated with the token.
+
+ @param[in] TokenNumber The PCD token number.
+ @param[out] PcdInfo The returned information associated with the requested TokenNumber.
+ The caller is responsible for freeing the buffer that is allocated by callee for PcdInfo->PcdName.
+
+ @retval EFI_SUCCESS The PCD information was returned successfully.
+ @retval EFI_NOT_FOUND The PCD service could not find the requested token number.
+**/
+EFI_STATUS
+EFIAPI
+DxeGetPcdInfoGetInfo (
+ IN UINTN TokenNumber,
+ OUT EFI_PCD_INFO *PcdInfo
+ );
+
+/**
+ Retrieve additional information associated with a PCD token.
+
+ This includes information such as the type of value the TokenNumber is associated with as well as possible
+ human readable name that is associated with the token.
+
+ @param[in] Guid The 128-bit unique value that designates the namespace from which to extract the value.
+ @param[in] TokenNumber The PCD token number.
+ @param[out] PcdInfo The returned information associated with the requested TokenNumber.
+ The caller is responsible for freeing the buffer that is allocated by callee for PcdInfo->PcdName.
+
+ @retval EFI_SUCCESS The PCD information was returned successfully.
+ @retval EFI_NOT_FOUND The PCD service could not find the requested token number.
+**/
+EFI_STATUS
+EFIAPI
+DxeGetPcdInfoGetInfoEx (
+ IN CONST EFI_GUID *Guid,
+ IN UINTN TokenNumber,
+ OUT EFI_PCD_INFO *PcdInfo
+ );
+
+/**
+ Retrieve the currently set SKU Id.
+
+ @return The currently set SKU Id. If the platform has not set at a SKU Id, then the
+ default SKU Id value of 0 is returned. If the platform has set a SKU Id, then the currently set SKU
+ Id is returned.
+**/
+UINTN
+EFIAPI
+DxeGetPcdInfoGetSku (
+ VOID
+ );
+
//
// Protocol Interface function declaration.
//
@@ -757,6 +815,27 @@ typedef struct {
//
/**
+ Retrieve additional information associated with a PCD token.
+
+ This includes information such as the type of value the TokenNumber is associated with as well as possible
+ human readable name that is associated with the token.
+
+ @param[in] Guid The 128-bit unique value that designates the namespace from which to extract the value.
+ @param[in] TokenNumber The PCD token number.
+ @param[out] PcdInfo The returned information associated with the requested TokenNumber.
+ The caller is responsible for freeing the buffer that is allocated by callee for PcdInfo->PcdName.
+
+ @retval EFI_SUCCESS The PCD information was returned successfully
+ @retval EFI_NOT_FOUND The PCD service could not find the requested token number.
+**/
+EFI_STATUS
+DxeGetPcdInfo (
+ IN CONST EFI_GUID *Guid,
+ IN UINTN TokenNumber,
+ OUT EFI_PCD_INFO *PcdInfo
+ );
+
+/**
Wrapper function for setting non-pointer type value for a PCD entry.
@param TokenNumber Pcd token number autogenerated by build tools.
@@ -995,16 +1074,16 @@ BuildPcdDxeDataBase (
);
/**
- Get local token number according to dynamic-ex PCD's {token space guid:token number}
+ Get Token Number according to dynamic-ex PCD's {token space guid:token number}
A dynamic-ex type PCD, developer must provide pair of token space guid: token number
in DEC file. PCD database maintain a mapping table that translate pair of {token
- space guid: token number} to local token number.
+ space guid: token number} to Token Number.
@param Guid Token space guid for dynamic-ex PCD entry.
@param ExTokenNumber Dynamic-ex PCD token number.
- @return local token number for dynamic-ex PCD.
+ @return Token Number for dynamic-ex PCD.
**/
UINTN
@@ -1079,9 +1158,24 @@ SetPtrTypeSize (
IN OUT UINTN *CurrentSize
);
-extern PCD_DATABASE * mPcdDatabase;
+extern PCD_DATABASE mPcdDatabase;
+
+extern UINT32 mPcdTotalTokenCount;
+extern UINT32 mPeiLocalTokenCount;
+extern UINT32 mDxeLocalTokenCount;
+extern UINT32 mPeiNexTokenCount;
+extern UINT32 mDxeNexTokenCount;
+extern UINT32 mPeiExMapppingTableSize;
+extern UINT32 mDxeExMapppingTableSize;
+extern UINT32 mPeiGuidTableSize;
+extern UINT32 mDxeGuidTableSize;
+
+extern BOOLEAN mPeiExMapTableEmpty;
+extern BOOLEAN mDxeExMapTableEmpty;
+extern BOOLEAN mPeiDatabaseEmpty;
-extern DXE_PCD_DATABASE_INIT gDXEPcdDbInit;
+extern EFI_GUID **TmpTokenSpaceBuffer;
+extern UINTN TmpTokenSpaceBufferCount;
extern EFI_LOCK mPcdDatabaseLock;
diff --git a/MdeModulePkg/Universal/PCD/Pei/Pcd.c b/MdeModulePkg/Universal/PCD/Pei/Pcd.c
index 5ab8e1287..91e94e263 100644
--- a/MdeModulePkg/Universal/PCD/Pei/Pcd.c
+++ b/MdeModulePkg/Universal/PCD/Pei/Pcd.c
@@ -1,7 +1,7 @@
/** @file
All Pcd Ppi services are implemented here.
-Copyright (c) 2006 - 2009, Intel Corporation. All rights reserved.<BR>
+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
@@ -83,6 +83,25 @@ EFI_PEI_PCD_PPI mEfiPcdPpiInstance = {
PeiPcdGetNextTokenSpace
};
+///
+/// Instance of GET_PCD_INFO_PPI protocol is EDKII native implementation.
+/// This protocol instance support dynamic and dynamicEx type PCDs.
+///
+GET_PCD_INFO_PPI mGetPcdInfoInstance = {
+ PeiGetPcdInfoGetInfo,
+ PeiGetPcdInfoGetInfoEx,
+ PeiGetPcdInfoGetSku
+};
+
+///
+/// Instance of EFI_GET_PCD_INFO_PPI which is defined in PI 1.2.1 Vol 3.
+/// This PPI instance only support dyanmicEx type PCD.
+///
+EFI_GET_PCD_INFO_PPI mEfiGetPcdInfoInstance = {
+ PeiGetPcdInfoGetInfoEx,
+ PeiGetPcdInfoGetSku
+};
+
EFI_PEI_PPI_DESCRIPTOR mPpiList[] = {
{
EFI_PEI_PPI_DESCRIPTOR_PPI,
@@ -96,6 +115,19 @@ EFI_PEI_PPI_DESCRIPTOR mPpiList[] = {
}
};
+EFI_PEI_PPI_DESCRIPTOR mPpiList2[] = {
+ {
+ EFI_PEI_PPI_DESCRIPTOR_PPI,
+ &gGetPcdInfoPpiGuid,
+ &mGetPcdInfoInstance
+ },
+ {
+ (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
+ &gEfiGetPcdInfoPpiGuid,
+ &mEfiGetPcdInfoInstance
+ }
+};
+
/**
Main entry for PCD PEIM driver.
@@ -114,20 +146,96 @@ PcdPeimInit (
IN CONST EFI_PEI_SERVICES **PeiServices
)
{
- EFI_STATUS Status;
-
- BuildPcdDatabase ();
+ EFI_STATUS Status;
+ PEI_PCD_DATABASE *DataBase;
+
+ DataBase = BuildPcdDatabase (FileHandle);
//
// Install PCD_PPI and EFI_PEI_PCD_PPI.
//
Status = PeiServicesInstallPpi (&mPpiList[0]);
ASSERT_EFI_ERROR (Status);
-
+
+ //
+ // Only install PcdInfo PPI when PCD info content is present.
+ //
+ if (DataBase->PcdNameTableOffset != 0) {
+ //
+ // Install GET_PCD_INFO_PPI and EFI_GET_PCD_INFO_PPI.
+ //
+ Status = PeiServicesInstallPpi (&mPpiList2[0]);
+ ASSERT_EFI_ERROR (Status);
+ }
+
return Status;
}
/**
+ Retrieve additional information associated with a PCD token in the default token space.
+
+ This includes information such as the type of value the TokenNumber is associated with as well as possible
+ human readable name that is associated with the token.
+
+ @param[in] TokenNumber The PCD token number.
+ @param[out] PcdInfo The returned information associated with the requested TokenNumber.
+ The caller is responsible for freeing the buffer that is allocated by callee for PcdInfo->PcdName.
+
+ @retval EFI_SUCCESS The PCD information was returned successfully.
+ @retval EFI_NOT_FOUND The PCD service could not find the requested token number.
+**/
+EFI_STATUS
+EFIAPI
+PeiGetPcdInfoGetInfo (
+ IN UINTN TokenNumber,
+ OUT EFI_PCD_INFO *PcdInfo
+ )
+{
+ return PeiGetPcdInfo (NULL, TokenNumber, PcdInfo);
+}
+
+/**
+ Retrieve additional information associated with a PCD token.
+
+ This includes information such as the type of value the TokenNumber is associated with as well as possible
+ human readable name that is associated with the token.
+
+ @param[in] Guid The 128-bit unique value that designates the namespace from which to extract the value.
+ @param[in] TokenNumber The PCD token number.
+ @param[out] PcdInfo The returned information associated with the requested TokenNumber.
+ The caller is responsible for freeing the buffer that is allocated by callee for PcdInfo->PcdName.
+
+ @retval EFI_SUCCESS The PCD information was returned successfully.
+ @retval EFI_NOT_FOUND The PCD service could not find the requested token number.
+**/
+EFI_STATUS
+EFIAPI
+PeiGetPcdInfoGetInfoEx (
+ IN CONST EFI_GUID *Guid,
+ IN UINTN TokenNumber,
+ OUT EFI_PCD_INFO *PcdInfo
+ )
+{
+ return PeiGetPcdInfo (Guid, TokenNumber, PcdInfo);
+}
+
+/**
+ Retrieve the currently set SKU Id.
+
+ @return The currently set SKU Id. If the platform has not set at a SKU Id, then the
+ default SKU Id value of 0 is returned. If the platform has set a SKU Id, then the currently set SKU
+ Id is returned.
+**/
+UINTN
+EFIAPI
+PeiGetPcdInfoGetSku (
+ VOID
+ )
+{
+ return GetPcdDatabase()->SystemSkuId;
+}
+
+/**
Sets the SKU value for subsequent calls to set or get PCD token values.
SetSku() sets the SKU Id to be used for subsequent calls to set or get PCD values.
@@ -155,7 +263,7 @@ PeiPcdSetSku (
)
{
- GetPcdDatabase()->Init.SystemSkuId = (SKU_ID) SkuId;
+ GetPcdDatabase()->SystemSkuId = (SKU_ID) SkuId;
return;
}
@@ -304,8 +412,10 @@ PeiPcdGetSize (
PEI_PCD_DATABASE *PeiPcdDb;
UINTN Size;
UINTN MaxSize;
+ UINT32 LocalTokenCount;
- PeiPcdDb = GetPcdDatabase ();
+ PeiPcdDb = GetPcdDatabase ();
+ LocalTokenCount = PeiPcdDb->LocalTokenCount;
//
// TokenNumber Zero is reserved as PCD_INVALID_TOKEN_NUMBER.
// We have to decrement TokenNumber by 1 to make it usable
@@ -316,9 +426,9 @@ PeiPcdGetSize (
// EBC compiler is very choosy. It may report warning about comparison
// between UINTN and 0 . So we add 1 in each size of the
// comparison.
- ASSERT (TokenNumber + 1 < PEI_LOCAL_TOKEN_NUMBER + 1);
+ ASSERT (TokenNumber + 1 < (LocalTokenCount + 1));
- Size = (PeiPcdDb->Init.LocalTokenNumberTable[TokenNumber] & PCD_DATUM_TYPE_ALL_SET) >> PCD_DATUM_TYPE_SHIFT;
+ Size = (*((UINT32 *)((UINT8 *)PeiPcdDb + PeiPcdDb->LocalTokenNumberTableOffset) + TokenNumber) & PCD_DATUM_TYPE_ALL_SET) >> PCD_DATUM_TYPE_SHIFT;
if (Size == 0) {
//
@@ -926,10 +1036,8 @@ PcdUnRegisterCallBackOnSet (
is being made to retrieve tokens from the default token space.
@param[in, out] TokenNumber A pointer to the PCD token number to use to find the subsequent token number.
- @retval EFI_SUCCESS The PCD service has retrieved the next valid token number.
- Or the input token number is already the last valid token number in the PCD database.
- In the later case, *TokenNumber is updated with the value of 0.
- @retval EFI_NOT_FOUND If this input token number and token namespace does not exist on the platform.
+ @retval EFI_SUCCESS The PCD service has retrieved the next valid token number.
+ @retval EFI_NOT_FOUND The PCD service could not find data from the requested token number.
**/
EFI_STATUS
@@ -942,55 +1050,56 @@ PeiPcdGetNextToken (
UINTN GuidTableIdx;
PEI_PCD_DATABASE *PeiPcdDb;
EFI_GUID *MatchGuid;
+ EFI_GUID *GuidTable;
DYNAMICEX_MAPPING *ExMapTable;
UINTN Index;
BOOLEAN Found;
BOOLEAN PeiExMapTableEmpty;
+ UINTN PeiNexTokenNumber;
if (!FeaturePcdGet (PcdPeiFullPcdDatabaseEnable)) {
return EFI_UNSUPPORTED;
}
- PeiExMapTableEmpty = PEI_EXMAP_TABLE_EMPTY;
+ PeiPcdDb = GetPcdDatabase ();
+ PeiNexTokenNumber = PeiPcdDb->LocalTokenCount - PeiPcdDb->ExTokenCount;
+ GuidTable = (EFI_GUID *)((UINT8 *)PeiPcdDb + PeiPcdDb->GuidTableOffset);
+ if (PeiPcdDb->ExTokenCount == 0) {
+ PeiExMapTableEmpty = TRUE;
+ } else {
+ PeiExMapTableEmpty = FALSE;
+ }
if (Guid == NULL) {
- if (*TokenNumber > PEI_NEX_TOKEN_NUMBER) {
+ if (*TokenNumber > PeiNexTokenNumber) {
return EFI_NOT_FOUND;
}
(*TokenNumber)++;
- if (*TokenNumber > PEI_NEX_TOKEN_NUMBER) {
+ if (*TokenNumber > PeiNexTokenNumber) {
*TokenNumber = PCD_INVALID_TOKEN_NUMBER;
+ return EFI_NOT_FOUND;
}
return EFI_SUCCESS;
} else {
if (PeiExMapTableEmpty) {
- *TokenNumber = PCD_INVALID_TOKEN_NUMBER;
- return EFI_SUCCESS;
+ return EFI_NOT_FOUND;
}
-
- //
- // Assume PCD Database AutoGen tool is sorting the ExMap based on the following order
- // 1) ExGuid
- // 2) ExTokenNumber
- //
- PeiPcdDb = GetPcdDatabase ();
-
- MatchGuid = ScanGuid (PeiPcdDb->Init.GuidTable, sizeof(PeiPcdDb->Init.GuidTable), Guid);
+
+ MatchGuid = ScanGuid (GuidTable, PeiPcdDb->GuidTableCount * sizeof(EFI_GUID), Guid);
if (MatchGuid == NULL) {
- *TokenNumber = PCD_INVALID_TOKEN_NUMBER;
return EFI_NOT_FOUND;
}
- GuidTableIdx = MatchGuid - PeiPcdDb->Init.GuidTable;
+ GuidTableIdx = MatchGuid - GuidTable;
- ExMapTable = PeiPcdDb->Init.ExMapTable;
+ ExMapTable = (DYNAMICEX_MAPPING *)((UINT8 *)PeiPcdDb + PeiPcdDb->ExMapTableOffset);
Found = FALSE;
//
// Locate the GUID in ExMapTable first.
//
- for (Index = 0; Index < PEI_EXMAPPING_TABLE_SIZE; Index++) {
+ for (Index = 0; Index < PeiPcdDb->ExTokenCount; Index++) {
if (ExMapTable[Index].ExGuidIndex == GuidTableIdx) {
Found = TRUE;
break;
@@ -1003,26 +1112,28 @@ PeiPcdGetNextToken (
return EFI_SUCCESS;
}
- for ( ; Index < PEI_EXMAPPING_TABLE_SIZE; Index++) {
+ for ( ; Index < PeiPcdDb->ExTokenCount; Index++) {
if (ExMapTable[Index].ExTokenNumber == *TokenNumber) {
- Index++;
- if (Index == PEI_EXMAPPING_TABLE_SIZE) {
- //
- // Exceed the length of ExMap Table
- //
- *TokenNumber = PCD_INVALID_TOKEN_NUMBER;
- return EFI_SUCCESS;
- }
- if (ExMapTable[Index].ExGuidIndex == GuidTableIdx) {
- *TokenNumber = ExMapTable[Index].ExTokenNumber;
- return EFI_SUCCESS;
- } else {
- *TokenNumber = PCD_INVALID_TOKEN_NUMBER;
- return EFI_SUCCESS;
- }
+ break;
+ }
+ }
+
+ while (Index < PeiPcdDb->ExTokenCount) {
+ Index++;
+ if (Index == PeiPcdDb->ExTokenCount) {
+ //
+ // Exceed the length of ExMap Table
+ //
+ *TokenNumber = PCD_INVALID_TOKEN_NUMBER;
+ return EFI_NOT_FOUND;
+ } else if (ExMapTable[Index].ExGuidIndex == GuidTableIdx) {
+ //
+ // Found the next match
+ //
+ *TokenNumber = ExMapTable[Index].ExTokenNumber;
+ return EFI_SUCCESS;
}
}
- return EFI_NOT_FOUND;
}
}
@@ -1032,22 +1143,17 @@ PeiPcdGetNextToken (
/**
Retrieves the next valid PCD token namespace for a given namespace.
- @param[in, out] Guid An indirect pointer to EFI_GUID. On input it designates
- a known token namespace from which the search will start. On output,
- it designates the next valid token namespace on the platform. If the input
- token namespace does not exist on the platform, an error is returned and
- the value of *Guid is undefined. If *Guid is NULL, then the GUID of the
- first token space of the current platform is assigned to *Guid the function
- return EFI_SUCCESS. If *Guid is NULL and there is no namespace exist in
- the platform other than the default (NULL) tokennamespace, *Guid is unchanged
- and the function return EFI_SUCCESS. If this input token namespace is the last
- namespace on the platform, *Guid will be assigned to NULL and the function return
- EFI_SUCCESS.
-
- @retval EFI_SUCCESS The PCD service retrieved the next valid token space Guid.
- Or the input token space Guid is already the last valid token space Guid
- in the PCD database. In the later case, *Guid is updated with the value of NULL.
- @retval EFI_NOT_FOUND If the input token namespace does not exist on the platform.
+ Gets the next valid token namespace for a given namespace. This is useful to traverse the valid
+ token namespaces on a platform.
+
+ @param[in, out] Guid An indirect pointer to EFI_GUID. On input it designates a known token
+ namespace from which the search will start. On output, it designates the next valid
+ token namespace on the platform. If *Guid is NULL, then the GUID of the first token
+ space of the current platform is returned. If the search cannot locate the next valid
+ token namespace, an error is returned and the value of *Guid is undefined.
+
+ @retval EFI_SUCCESS The PCD service retrieved the value requested.
+ @retval EFI_NOT_FOUND The PCD service could not find the next valid token namespace.
**/
EFI_STATUS
@@ -1061,8 +1167,10 @@ PeiPcdGetNextTokenSpace (
PEI_PCD_DATABASE *PeiPcdDb;
DYNAMICEX_MAPPING *ExMapTable;
UINTN Index;
+ UINTN Index2;
BOOLEAN Found;
BOOLEAN PeiExMapTableEmpty;
+ EFI_GUID *GuidTable;
if (!FeaturePcdGet (PcdPeiFullPcdDatabaseEnable)) {
return EFI_UNSUPPORTED;
@@ -1070,43 +1178,39 @@ PeiPcdGetNextTokenSpace (
ASSERT (Guid != NULL);
- PeiExMapTableEmpty = PEI_EXMAP_TABLE_EMPTY;
+ PeiPcdDb = GetPcdDatabase ();
+ if (PeiPcdDb->ExTokenCount == 0) {
+ PeiExMapTableEmpty = TRUE;
+ } else {
+ PeiExMapTableEmpty = FALSE;
+ }
+
if (PeiExMapTableEmpty) {
- if (*Guid != NULL) {
- return EFI_NOT_FOUND;
- } else {
- return EFI_SUCCESS;
- }
+ return EFI_NOT_FOUND;
}
- //
- // Assume PCD Database AutoGen tool is sorting the ExMap based on the following order
- // 1) ExGuid
- // 2) ExTokenNumber
- //
- PeiPcdDb = GetPcdDatabase ();
-
- ExMapTable = PeiPcdDb->Init.ExMapTable;
-
+ ExMapTable = (DYNAMICEX_MAPPING *)((UINT8 *)PeiPcdDb + PeiPcdDb->ExMapTableOffset);
+ GuidTable = (EFI_GUID *)((UINT8 *)PeiPcdDb + PeiPcdDb->GuidTableOffset);
+
if (*Guid == NULL) {
//
// return the first Token Space Guid.
//
- *Guid = &PeiPcdDb->Init.GuidTable[ExMapTable[0].ExGuidIndex];
+ *Guid = GuidTable + ExMapTable[0].ExGuidIndex;
return EFI_SUCCESS;
}
- MatchGuid = ScanGuid (PeiPcdDb->Init.GuidTable, sizeof(PeiPcdDb->Init.GuidTable), *Guid);
+ MatchGuid = ScanGuid (GuidTable, PeiPcdDb->GuidTableCount * sizeof(GuidTable[0]), *Guid);
if (MatchGuid == NULL) {
return EFI_NOT_FOUND;
}
- GuidTableIdx = MatchGuid - PeiPcdDb->Init.GuidTable;
+ GuidTableIdx = MatchGuid - GuidTable;
Found = FALSE;
- for (Index = 0; Index < PEI_EXMAPPING_TABLE_SIZE; Index++) {
+ for (Index = 0; Index < PeiPcdDb->ExTokenCount; Index++) {
if (ExMapTable[Index].ExGuidIndex == GuidTableIdx) {
Found = TRUE;
break;
@@ -1115,14 +1219,25 @@ PeiPcdGetNextTokenSpace (
if (Found) {
Index++;
- for ( ; Index < PEI_EXMAPPING_TABLE_SIZE; Index++ ) {
- if (ExMapTable[Index].ExGuidIndex != GuidTableIdx ) {
- *Guid = &PeiPcdDb->Init.GuidTable[ExMapTable[Index].ExGuidIndex];
- return EFI_SUCCESS;
+ for ( ; Index < PeiPcdDb->ExTokenCount; Index++ ) {
+ if (ExMapTable[Index].ExGuidIndex != GuidTableIdx) {
+ Found = FALSE;
+ for (Index2 = 0 ; Index2 < Index; Index2++) {
+ if (ExMapTable[Index2].ExGuidIndex == ExMapTable[Index].ExGuidIndex) {
+ //
+ // This token namespace should have been found and output at preceding getting.
+ //
+ Found = TRUE;
+ break;
+ }
+ }
+ if (!Found) {
+ *Guid = (EFI_GUID *)((UINT8 *)PeiPcdDb + PeiPcdDb->GuidTableOffset) + ExMapTable[Index].ExGuidIndex;
+ return EFI_SUCCESS;
+ }
}
}
*Guid = NULL;
- return EFI_SUCCESS;
}
return EFI_NOT_FOUND;
@@ -1132,7 +1247,7 @@ PeiPcdGetNextTokenSpace (
/**
Get PCD value's size for POINTER type PCD.
- The POINTER type PCD's value will be stored into a buffer in specificed size.
+ The POINTER type PCD's value will be stored into a buffer in specified size.
The max size of this PCD's value is described in PCD's definition in DEC file.
@param LocalTokenNumberTableIdx Index of PCD token number in PCD token table
@@ -1157,11 +1272,11 @@ GetPtrTypeSize (
SizeTableIdx = GetSizeTableIndex (LocalTokenNumberTableIdx, Database);
- LocalTokenNumber = Database->Init.LocalTokenNumberTable[LocalTokenNumberTableIdx];
+ LocalTokenNumber = *((UINT32 *)((UINT8 *)Database + Database->LocalTokenNumberTableOffset) + LocalTokenNumberTableIdx);
ASSERT ((LocalTokenNumber & PCD_DATUM_TYPE_ALL_SET) == PCD_DATUM_TYPE_POINTER);
- SizeTable = Database->Init.SizeTable;
+ SizeTable = (SIZE_INFO *)((UINT8 *)Database + Database->SizeTableOffset);
*MaxSize = SizeTable[SizeTableIdx];
//
@@ -1170,8 +1285,9 @@ GetPtrTypeSize (
//
if ((LocalTokenNumber & PCD_TYPE_VPD) != 0) {
//
- // We have only one entry for VPD enabled PCD entry:
+ // We have only two entry for VPD enabled PCD entry:
// 1) MAX Size.
+ // 2) Current Size
// We consider current size is equal to MAX size.
//
return *MaxSize;
@@ -1191,7 +1307,7 @@ GetPtrTypeSize (
//
SkuIdTable = GetSkuIdArray (LocalTokenNumberTableIdx, Database);
for (Index = 0; Index < SkuIdTable[0]; Index++) {
- if (SkuIdTable[1 + Index] == Database->Init.SystemSkuId) {
+ if (SkuIdTable[1 + Index] == Database->SystemSkuId) {
return SizeTable[SizeTableIdx + 1 + Index];
}
}
@@ -1203,7 +1319,7 @@ GetPtrTypeSize (
/**
Set PCD value's size for POINTER type PCD.
- The POINTER type PCD's value will be stored into a buffer in specificed size.
+ The POINTER type PCD's value will be stored into a buffer in specified size.
The max size of this PCD's value is described in PCD's definition in DEC file.
@param LocalTokenNumberTableIdx Index of PCD token number in PCD token table
@@ -1230,11 +1346,11 @@ SetPtrTypeSize (
SizeTableIdx = GetSizeTableIndex (LocalTokenNumberTableIdx, Database);
- LocalTokenNumber = Database->Init.LocalTokenNumberTable[LocalTokenNumberTableIdx];
+ LocalTokenNumber = *((UINT32 *)((UINT8 *)Database + Database->LocalTokenNumberTableOffset) + LocalTokenNumberTableIdx);
ASSERT ((LocalTokenNumber & PCD_DATUM_TYPE_ALL_SET) == PCD_DATUM_TYPE_POINTER);
-
- SizeTable = Database->Init.SizeTable;
+
+ SizeTable = (SIZE_INFO *)((UINT8 *)Database + Database->SizeTableOffset);
MaxSize = SizeTable[SizeTableIdx];
//
@@ -1270,7 +1386,7 @@ SetPtrTypeSize (
//
SkuIdTable = GetSkuIdArray (LocalTokenNumberTableIdx, Database);
for (Index = 0; Index < SkuIdTable[0]; Index++) {
- if (SkuIdTable[1 + Index] == Database->Init.SystemSkuId) {
+ if (SkuIdTable[1 + Index] == Database->SystemSkuId) {
SizeTable[SizeTableIdx + 1 + Index] = (SIZE_INFO) *CurrentSize;
return TRUE;
}
diff --git a/MdeModulePkg/Universal/PCD/Pei/Pcd.inf b/MdeModulePkg/Universal/PCD/Pei/Pcd.inf
index 20e442082..357f047ff 100644
--- a/MdeModulePkg/Universal/PCD/Pei/Pcd.inf
+++ b/MdeModulePkg/Universal/PCD/Pei/Pcd.inf
@@ -1,6 +1,7 @@
## @file
# PCD PEIM produces PCD database to manage all dynamic PCD in PEI phase and install Pcd Ppi service.
#
+# This version PCD PEIM depends on the external PCD database binary file, not built in PCD data base.
# There are two PCD PPIs as follows:
# 1) PCD_PPI
# It is EDKII implementation which support Dynamic/DynamicEx Pcds.
@@ -8,6 +9,10 @@
# It is defined by PI specification 1.2, Vol 3 which only support dynamicEx
# type Pcd.
# For dynamicEx type PCD, it is compatible between PCD_PPI and EFI_PEI_PCD_PPI.
+# PCD PEIM driver will produce above two PPIs at same time.
+#
+# PCD database is generated as the separate binary image at build time. The binary image
+# will be intergrated into Firmware volume together with PCD driver.
#
# ////////////////////////////////////////////////////////////////////////////////
# // //
@@ -58,7 +63,7 @@
# b) Variable Storage:
# - The PCD value is stored in variable area.
# - As default storage type, this type PCD could be used for PEI/DXE driver
-# communication. But beside it, this type PCD could alsp be used to store
+# communication. But beside it, this type PCD could also be used to store
# the value associate with a HII setting via variable interface.
# - In PEI phase, the PCD value could only be got but can not be set due
# to variable area is readonly.
@@ -89,12 +94,12 @@
# PCD information used in PEI phase or use in both PEI/DXE phase. And DXE PCD
# database contains all PCDs used in PEI/DXE phase in memory.
#
-# Build tool will generate PCD database into some C structure and variable for
+# Build tool will generate PCD database into the separate binary file for
# PEI/DXE PCD driver according to dynamic PCD section in platform DSC file.
#
# 3.1 PcdPeim and PcdDxe
# PEI PCD database is maintained by PcdPeim driver run from flash. PcdPeim driver
-# build guid hob in temporary memory and copy auto-generated C structure
+# build guid hob in temporary memory and copy the binary data base from flash
# to temporary memory for PEI PCD database.
# DXE PCD database is maintained by PcdDxe driver.At entry point of PcdDxe driver,
# a new PCD database is allocated in boot-time memory which including all
@@ -180,8 +185,10 @@
# Based on local token number, PCD driver could fast determine PCD type, value
# type and get PCD entry from PCD database.
#
-# 3.3 PCD Database C structure.
-# PCD Database C structure is generated by build tools in PCD driver's autogen.h/
+# 3.3 PCD Database binary file
+# PCD Database binary file will be created at build time as the standalone binary image.
+# To understand the binary image layout, PCD Database C structure is still generated
+# as comments by build tools in PCD driver's autogen.h/
# autogen.c file. In generated C structure, following information is stored:
# - ExMapTable: This table is used translate a binary dynamicex type PCD's
# "tokenguid + token" to local token number.
@@ -190,7 +197,7 @@
# token number" as array index to get PCD entry's offset fastly.
# - SizeTable: This table stores the size information for all PCD entry.
# - GuidTable: This table stores guid value for DynamicEx's token space,
-# HII type PCD's variable.
+# HII type PCD's variable GUID.
# - SkuIdTable: TBD
# - SystemSkuId: TBD
# - PCD value structure:
@@ -271,7 +278,7 @@
# - Variable GUID for HII type PCD
# - Token space GUID for dynamicex type PCD
#
-# Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>
+# 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
@@ -288,7 +295,7 @@
BASE_NAME = PcdPeim
FILE_GUID = 9B3ADA4F-AE56-4c24-8DEA-F03B7558AE50
MODULE_TYPE = PEIM
- VERSION_STRING = 1.0
+ VERSION_STRING = 4.0
PCD_IS_DRIVER = PEI_PCD_DRIVER
ENTRY_POINT = PcdPeimInit
@@ -315,22 +322,27 @@
BaseLib
PeimEntryPoint
DebugLib
+ MemoryAllocationLib
[Guids]
- gPcdDataBaseHobGuid ## PRODUCES ## Hob
- gPcdDataBaseHobGuid ## CONSUMES ## Hob
+ ## PRODUCES ## HOB
+ ## SOMETIMES_CONSUMES ## HOB
+ gPcdDataBaseHobGuid
+ gPcdDataBaseSignatureGuid ## CONSUMES ## UNDEFINED # PCD database signature GUID.
[Ppis]
- gEfiPeiReadOnlyVariable2PpiGuid ## CONSUMES
+ gEfiPeiReadOnlyVariable2PpiGuid ## SOMETIMES_CONSUMES
gPcdPpiGuid ## PRODUCES
gEfiPeiPcdPpiGuid ## PRODUCES
-
+ gGetPcdInfoPpiGuid ## SOMETIMES_PRODUCES
+ gEfiGetPcdInfoPpiGuid ## SOMETIMES_PRODUCES
+
[FeaturePcd]
- gEfiMdeModulePkgTokenSpaceGuid.PcdPeiFullPcdDatabaseEnable
+ gEfiMdeModulePkgTokenSpaceGuid.PcdPeiFullPcdDatabaseEnable ## CONSUMES
[Pcd]
- gEfiMdeModulePkgTokenSpaceGuid.PcdVpdBaseAddress
- gEfiMdeModulePkgTokenSpaceGuid.PcdMaxPeiPcdCallBackNumberPerPcdEntry || gEfiMdeModulePkgTokenSpaceGuid.PcdPeiFullPcdDatabaseEnable
+ gEfiMdeModulePkgTokenSpaceGuid.PcdVpdBaseAddress ## SOMETIMES_CONSUMES
+ gEfiMdeModulePkgTokenSpaceGuid.PcdMaxPeiPcdCallBackNumberPerPcdEntry || gEfiMdeModulePkgTokenSpaceGuid.PcdPeiFullPcdDatabaseEnable ## SOMETIMES_CONSUMES
[Depex]
TRUE
diff --git a/MdeModulePkg/Universal/PCD/Pei/Service.c b/MdeModulePkg/Universal/PCD/Pei/Service.c
index e5d5f0c20..4fb8b4a68 100644
--- a/MdeModulePkg/Universal/PCD/Pei/Service.c
+++ b/MdeModulePkg/Universal/PCD/Pei/Service.c
@@ -2,7 +2,7 @@
The driver internal functions are implmented here.
They build Pei PCD database, and provide access service to PCD database.
-Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.<BR>
+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
@@ -16,6 +16,281 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#include "Service.h"
/**
+ Get Local Token Number by Token Number.
+
+ @param[in] Database PCD database.
+ @param[in] TokenNumber The PCD token number.
+
+ @return Local Token Number.
+**/
+UINT32
+GetLocalTokenNumber (
+ IN PEI_PCD_DATABASE *Database,
+ IN UINTN TokenNumber
+ )
+{
+ UINT32 LocalTokenNumber;
+ UINTN Size;
+ UINTN MaxSize;
+
+ //
+ // TokenNumber Zero is reserved as PCD_INVALID_TOKEN_NUMBER.
+ // We have to decrement TokenNumber by 1 to make it usable
+ // as the array index.
+ //
+ TokenNumber--;
+
+ LocalTokenNumber = *((UINT32 *)((UINT8 *)Database + Database->LocalTokenNumberTableOffset) + TokenNumber);
+
+ Size = (LocalTokenNumber & PCD_DATUM_TYPE_ALL_SET) >> PCD_DATUM_TYPE_SHIFT;
+
+ if ((LocalTokenNumber & PCD_TYPE_SKU_ENABLED) == PCD_TYPE_SKU_ENABLED) {
+ if (Size == 0) {
+ GetPtrTypeSize (TokenNumber, &MaxSize, Database);
+ } else {
+ MaxSize = Size;
+ }
+ LocalTokenNumber = GetSkuEnabledTokenNumber (LocalTokenNumber & ~PCD_TYPE_SKU_ENABLED, MaxSize);
+ }
+
+ return LocalTokenNumber;
+}
+
+/**
+ Get PCD type by Local Token Number.
+
+ @param[in] LocalTokenNumber The PCD local token number.
+
+ @return PCD type.
+**/
+EFI_PCD_TYPE
+GetPcdType (
+ IN UINT32 LocalTokenNumber
+ )
+{
+ switch (LocalTokenNumber & PCD_DATUM_TYPE_ALL_SET) {
+ case PCD_DATUM_TYPE_POINTER:
+ return EFI_PCD_TYPE_PTR;
+ case PCD_DATUM_TYPE_UINT8:
+ if ((LocalTokenNumber & PCD_DATUM_TYPE_UINT8_BOOLEAN) == PCD_DATUM_TYPE_UINT8_BOOLEAN) {
+ return EFI_PCD_TYPE_BOOL;
+ } else {
+ return EFI_PCD_TYPE_8;
+ }
+ case PCD_DATUM_TYPE_UINT16:
+ return EFI_PCD_TYPE_16;
+ case PCD_DATUM_TYPE_UINT32:
+ return EFI_PCD_TYPE_32;
+ case PCD_DATUM_TYPE_UINT64:
+ return EFI_PCD_TYPE_64;
+ default:
+ ASSERT (FALSE);
+ return EFI_PCD_TYPE_8;
+ }
+}
+
+/**
+ Get PCD name.
+
+ @param[in] OnlyTokenSpaceName If TRUE, only need to get the TokenSpaceCName.
+ If FALSE, need to get the full PCD name.
+ @param[in] Database PCD database.
+ @param[in] TokenNumber The PCD token number.
+
+ @return The TokenSpaceCName or full PCD name.
+**/
+CHAR8 *
+GetPcdName (
+ IN BOOLEAN OnlyTokenSpaceName,
+ IN PEI_PCD_DATABASE *Database,
+ IN UINTN TokenNumber
+ )
+{
+ UINT8 *StringTable;
+ PCD_NAME_INDEX *PcdNameIndex;
+ CHAR8 *TokenSpaceName;
+ CHAR8 *PcdName;
+ CHAR8 *Name;
+
+ //
+ // TokenNumber Zero is reserved as PCD_INVALID_TOKEN_NUMBER.
+ // We have to decrement TokenNumber by 1 to make it usable
+ // as the array index.
+ //
+ TokenNumber--;
+
+ StringTable = (UINT8 *) Database + Database->StringTableOffset;
+
+ //
+ // Get the PCD name index.
+ //
+ PcdNameIndex = (PCD_NAME_INDEX *)((UINT8 *) Database + Database->PcdNameTableOffset) + TokenNumber;
+ TokenSpaceName = (CHAR8 *)&StringTable[PcdNameIndex->TokenSpaceCNameIndex];
+ PcdName = (CHAR8 *)&StringTable[PcdNameIndex->PcdCNameIndex];
+
+ if (OnlyTokenSpaceName) {
+ //
+ // Only need to get the TokenSpaceCName.
+ //
+ Name = AllocateCopyPool (AsciiStrSize (TokenSpaceName), TokenSpaceName);
+ } else {
+ //
+ // Need to get the full PCD name.
+ //
+ Name = AllocateZeroPool (AsciiStrSize (TokenSpaceName) + AsciiStrSize (PcdName));
+ ASSERT (Name != NULL);
+ //
+ // Catenate TokenSpaceCName and PcdCName with a '.' to form the full PCD name.
+ //
+ AsciiStrCat (Name, TokenSpaceName);
+ Name[AsciiStrSize (TokenSpaceName) - sizeof (CHAR8)] = '.';
+ AsciiStrCat (Name, PcdName);
+ }
+
+ return Name;
+}
+
+/**
+ Retrieve additional information associated with a PCD token.
+
+ This includes information such as the type of value the TokenNumber is associated with as well as possible
+ human readable name that is associated with the token.
+
+ @param[in] Database PCD database.
+ @param[in] Guid The 128-bit unique value that designates the namespace from which to extract the value.
+ @param[in] TokenNumber The PCD token number.
+ @param[out] PcdInfo The returned information associated with the requested TokenNumber.
+ The caller is responsible for freeing the buffer that is allocated by callee for PcdInfo->PcdName.
+
+ @retval EFI_SUCCESS The PCD information was returned successfully
+ @retval EFI_NOT_FOUND The PCD service could not find the requested token number.
+**/
+EFI_STATUS
+ExGetPcdInfo (
+ IN PEI_PCD_DATABASE *Database,
+ IN CONST EFI_GUID *Guid,
+ IN UINTN TokenNumber,
+ OUT EFI_PCD_INFO *PcdInfo
+ )
+{
+ UINTN GuidTableIdx;
+ EFI_GUID *MatchGuid;
+ EFI_GUID *GuidTable;
+ DYNAMICEX_MAPPING *ExMapTable;
+ UINTN Index;
+ UINT32 LocalTokenNumber;
+
+ GuidTable = (EFI_GUID *)((UINT8 *)Database + Database->GuidTableOffset);
+ MatchGuid = ScanGuid (GuidTable, Database->GuidTableCount * sizeof(EFI_GUID), Guid);
+
+ if (MatchGuid == NULL) {
+ return EFI_NOT_FOUND;
+ }
+
+ GuidTableIdx = MatchGuid - GuidTable;
+
+ ExMapTable = (DYNAMICEX_MAPPING *)((UINT8 *)Database + Database->ExMapTableOffset);
+
+ //
+ // Find the PCD by GuidTableIdx and ExTokenNumber in ExMapTable.
+ //
+ for (Index = 0; Index < Database->ExTokenCount; Index++) {
+ if (ExMapTable[Index].ExGuidIndex == GuidTableIdx) {
+ if (TokenNumber == PCD_INVALID_TOKEN_NUMBER) {
+ //
+ // TokenNumber is 0, follow spec to set PcdType to EFI_PCD_TYPE_8,
+ // PcdSize to 0 and PcdName to the null-terminated ASCII string
+ // associated with the token's namespace Guid.
+ //
+ PcdInfo->PcdType = EFI_PCD_TYPE_8;
+ PcdInfo->PcdSize = 0;
+ //
+ // Here use one representative in the token space to get the TokenSpaceCName.
+ //
+ PcdInfo->PcdName = GetPcdName (TRUE, Database, ExMapTable[Index].TokenNumber);
+ return EFI_SUCCESS;
+ } else if (ExMapTable[Index].ExTokenNumber == TokenNumber) {
+ PcdInfo->PcdSize = PeiPcdGetSize (ExMapTable[Index].TokenNumber);
+ LocalTokenNumber = GetLocalTokenNumber (Database, ExMapTable[Index].TokenNumber);
+ PcdInfo->PcdType = GetPcdType (LocalTokenNumber);
+ PcdInfo->PcdName = GetPcdName (FALSE, Database, ExMapTable[Index].TokenNumber);
+ return EFI_SUCCESS;
+ }
+ }
+ }
+
+ return EFI_NOT_FOUND;
+}
+
+/**
+ Retrieve additional information associated with a PCD token.
+
+ This includes information such as the type of value the TokenNumber is associated with as well as possible
+ human readable name that is associated with the token.
+
+ @param[in] Guid The 128-bit unique value that designates the namespace from which to extract the value.
+ @param[in] TokenNumber The PCD token number.
+ @param[out] PcdInfo The returned information associated with the requested TokenNumber.
+ The caller is responsible for freeing the buffer that is allocated by callee for PcdInfo->PcdName.
+
+ @retval EFI_SUCCESS The PCD information was returned successfully.
+ @retval EFI_NOT_FOUND The PCD service could not find the requested token number.
+**/
+EFI_STATUS
+PeiGetPcdInfo (
+ IN CONST EFI_GUID *Guid,
+ IN UINTN TokenNumber,
+ OUT EFI_PCD_INFO *PcdInfo
+ )
+{
+ PEI_PCD_DATABASE *PeiPcdDb;
+ BOOLEAN PeiExMapTableEmpty;
+ UINTN PeiNexTokenNumber;
+ UINT32 LocalTokenNumber;
+
+ ASSERT (PcdInfo != NULL);
+
+ PeiPcdDb = GetPcdDatabase ();
+ PeiNexTokenNumber = PeiPcdDb->LocalTokenCount - PeiPcdDb->ExTokenCount;
+
+ if (PeiPcdDb->ExTokenCount == 0) {
+ PeiExMapTableEmpty = TRUE;
+ } else {
+ PeiExMapTableEmpty = FALSE;
+ }
+
+ if (Guid == NULL) {
+ if (TokenNumber > PeiNexTokenNumber) {
+ return EFI_NOT_FOUND;
+ } else if (TokenNumber == PCD_INVALID_TOKEN_NUMBER) {
+ //
+ // TokenNumber is 0, follow spec to set PcdType to EFI_PCD_TYPE_8,
+ // PcdSize to 0 and PcdName to NULL for default Token Space.
+ //
+ PcdInfo->PcdType = EFI_PCD_TYPE_8;
+ PcdInfo->PcdSize = 0;
+ PcdInfo->PcdName = NULL;
+ } else {
+ PcdInfo->PcdSize = PeiPcdGetSize (TokenNumber);
+ LocalTokenNumber = GetLocalTokenNumber (PeiPcdDb, TokenNumber);
+ PcdInfo->PcdType = GetPcdType (LocalTokenNumber);
+ PcdInfo->PcdName = GetPcdName (FALSE, PeiPcdDb, TokenNumber);
+ }
+ return EFI_SUCCESS;
+ } else {
+ if (PeiExMapTableEmpty) {
+ return EFI_NOT_FOUND;
+ }
+ return ExGetPcdInfo (
+ PeiPcdDb,
+ Guid,
+ TokenNumber,
+ PcdInfo
+ );
+ }
+}
+
+/**
The function registers the CallBackOnSet fucntion
according to TokenNumber and EFI_GUID space.
@@ -43,25 +318,30 @@ PeiRegisterCallBackWorker (
PCD_PPI_CALLBACK Compare;
PCD_PPI_CALLBACK Assign;
UINT32 LocalTokenNumber;
+ UINT32 LocalTokenCount;
+ UINTN PeiNexTokenNumber;
UINTN TokenNumber;
UINTN Idx;
+ PEI_PCD_DATABASE *PeiPcdDb;
+
+ PeiPcdDb = GetPcdDatabase();
+ LocalTokenCount = PeiPcdDb->LocalTokenCount;
+ PeiNexTokenNumber = PeiPcdDb->LocalTokenCount - PeiPcdDb->ExTokenCount;
if (Guid == NULL) {
TokenNumber = ExTokenNumber;
-
//
// TokenNumber Zero is reserved as PCD_INVALID_TOKEN_NUMBER.
// We have to decrement TokenNumber by 1 to make it usable
// as the array index.
//
TokenNumber--;
- ASSERT (TokenNumber + 1 < PEI_NEX_TOKEN_NUMBER + 1);
+ ASSERT (TokenNumber + 1 < (PeiNexTokenNumber + 1));
} else {
TokenNumber = GetExPcdTokenNumber (Guid, ExTokenNumber);
if (TokenNumber == PCD_INVALID_TOKEN_NUMBER) {
return EFI_NOT_FOUND;
}
-
//
// TokenNumber Zero is reserved as PCD_INVALID_TOKEN_NUMBER.
// We have to decrement TokenNumber by 1 to make it usable
@@ -71,11 +351,11 @@ PeiRegisterCallBackWorker (
// EBC compiler is very choosy. It may report warning about comparison
// between UINTN and 0 . So we add 1 in each size of the
// comparison.
- ASSERT (TokenNumber + 1 < PEI_LOCAL_TOKEN_NUMBER + 1);
+ ASSERT ((TokenNumber + 1) < (LocalTokenCount + 1));
}
- LocalTokenNumber = GetPcdDatabase()->Init.LocalTokenNumberTable[TokenNumber];
+ LocalTokenNumber = *((UINT32 *)((UINT8 *)PeiPcdDb + PeiPcdDb->LocalTokenNumberTableOffset) + TokenNumber);
//
// We don't support SET for HII and VPD type PCD entry in PEI phase.
@@ -105,33 +385,81 @@ PeiRegisterCallBackWorker (
}
+
+/**
+ Find the Pcd database.
+
+ @param FileHandle Handle of the file the external PCD database binary located.
+
+ @retval The base address of external PCD database binary.
+ @retval NULL Return NULL if not find.
+**/
+VOID *
+LocateExPcdBinary (
+ IN EFI_PEI_FILE_HANDLE FileHandle
+ )
+{
+ EFI_STATUS Status;
+ VOID *PcdDb;
+
+ PcdDb = NULL;
+
+ ASSERT (FileHandle != NULL);
+
+ Status = PeiServicesFfsFindSectionData (EFI_SECTION_RAW, FileHandle, &PcdDb);
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Check the first bytes (Header Signature Guid) and build version.
+ //
+ if (!CompareGuid (PcdDb, &gPcdDataBaseSignatureGuid) ||
+ (((PEI_PCD_DATABASE *) PcdDb)->BuildVersion != PCD_SERVICE_PEIM_VERSION)) {
+ ASSERT (FALSE);
+ }
+ return PcdDb;
+}
+
+
/**
The function builds the PCD database.
+
+ @param FileHandle Handle of the file the external PCD database binary located.
+
+ @return Pointer to PCD database.
**/
-VOID
+PEI_PCD_DATABASE *
BuildPcdDatabase (
- VOID
+ IN EFI_PEI_FILE_HANDLE FileHandle
)
{
- PEI_PCD_DATABASE *Database;
- VOID *CallbackFnTable;
- UINTN SizeOfCallbackFnTable;
-
- Database = BuildGuidHob (&gPcdDataBaseHobGuid, sizeof (PEI_PCD_DATABASE));
+ PEI_PCD_DATABASE *Database;
+ PEI_PCD_DATABASE *PeiPcdDbBinary;
+ VOID *CallbackFnTable;
+ UINTN SizeOfCallbackFnTable;
+
+ //
+ // Locate the external PCD database binary for one section of current FFS
+ //
+ PeiPcdDbBinary = LocateExPcdBinary (FileHandle);
+
+ ASSERT(PeiPcdDbBinary != NULL);
+
+ Database = BuildGuidHob (&gPcdDataBaseHobGuid, PeiPcdDbBinary->Length + PeiPcdDbBinary->UninitDataBaseSize);
- ZeroMem (Database, sizeof (PEI_PCD_DATABASE));
+ ZeroMem (Database, PeiPcdDbBinary->Length + PeiPcdDbBinary->UninitDataBaseSize);
//
- // gPEIPcdDbInit is smaller than PEI_PCD_DATABASE
+ // PeiPcdDbBinary is smaller than Database
//
-
- CopyMem (&Database->Init, &gPEIPcdDbInit, sizeof (gPEIPcdDbInit));
+ CopyMem (Database, PeiPcdDbBinary, PeiPcdDbBinary->Length);
- SizeOfCallbackFnTable = PEI_LOCAL_TOKEN_NUMBER * sizeof (PCD_PPI_CALLBACK) * PcdGet32 (PcdMaxPeiPcdCallBackNumberPerPcdEntry);
+ SizeOfCallbackFnTable = Database->LocalTokenCount * sizeof (PCD_PPI_CALLBACK) * PcdGet32 (PcdMaxPeiPcdCallBackNumberPerPcdEntry);
CallbackFnTable = BuildGuidHob (&gEfiCallerIdGuid, SizeOfCallbackFnTable);
ZeroMem (CallbackFnTable, SizeOfCallbackFnTable);
+
+ return Database;
}
/**
@@ -215,6 +543,7 @@ GetSkuEnabledTokenNumber (
SKU_ID *SkuIdTable;
INTN Index;
UINT8 *Value;
+ BOOLEAN FoundSku;
PeiPcdDb = GetPcdDatabase ();
@@ -223,13 +552,30 @@ GetSkuEnabledTokenNumber (
SkuHead = (SKU_HEAD *) ((UINT8 *)PeiPcdDb + (LocalTokenNumber & PCD_DATABASE_OFFSET_MASK));
Value = (UINT8 *) ((UINT8 *)PeiPcdDb + (SkuHead->SkuDataStartOffset));
SkuIdTable = (SKU_ID *) ((UINT8 *)PeiPcdDb + (SkuHead->SkuIdTableOffset));
-
+
+ //
+ // Find the current system's SKU ID entry in SKU ID table.
+ //
+ FoundSku = FALSE;
for (Index = 0; Index < SkuIdTable[0]; Index++) {
- if (PeiPcdDb->Init.SystemSkuId == SkuIdTable[Index + 1]) {
+ if (PeiPcdDb->SystemSkuId == SkuIdTable[Index + 1]) {
+ FoundSku = TRUE;
break;
}
}
+ //
+ // Find the default SKU ID entry in SKU ID table.
+ //
+ if(!FoundSku) {
+ for (Index = 0; Index < SkuIdTable[0]; Index++) {
+ if (0 == SkuIdTable[Index + 1]) {
+ break;
+ }
+ }
+ }
+ ASSERT (Index < SkuIdTable[0]);
+
switch (LocalTokenNumber & PCD_TYPE_ALL_SET) {
case PCD_TYPE_VPD:
Value = (UINT8 *) &(((VPD_HEAD *) Value)[Index]);
@@ -238,14 +584,18 @@ GetSkuEnabledTokenNumber (
case PCD_TYPE_HII:
Value = (UINT8 *) &(((VARIABLE_HEAD *) Value)[Index]);
return (UINT32) ((Value - (UINT8 *) PeiPcdDb) | PCD_TYPE_HII);
-
+
+ case PCD_TYPE_HII|PCD_TYPE_STRING:
+ Value = (UINT8 *) &(((VARIABLE_HEAD *) Value)[Index]);
+ return (UINT32) ((Value - (UINT8 *) PeiPcdDb) | PCD_TYPE_HII | PCD_TYPE_STRING);
+
case PCD_TYPE_STRING:
Value = (UINT8 *) &(((STRING_HEAD *) Value)[Index]);
return (UINT32) ((Value - (UINT8 *) PeiPcdDb) | PCD_TYPE_STRING);
case PCD_TYPE_DATA:
Value += Size * Index;
- return (UINT32) (Value - (UINT8 *) PeiPcdDb);
+ return (UINT32) ((Value - (UINT8 *) PeiPcdDb) | PCD_TYPE_DATA);
default:
ASSERT (FALSE);
@@ -281,6 +631,8 @@ InvokeCallbackOnSet (
EFI_HOB_GUID_TYPE *GuidHob;
PCD_PPI_CALLBACK *CallbackTable;
UINTN Idx;
+ PEI_PCD_DATABASE *PeiPcdDb;
+ UINT32 LocalTokenCount;
//
// TokenNumber Zero is reserved as PCD_INVALID_TOKEN_NUMBER.
@@ -288,12 +640,15 @@ InvokeCallbackOnSet (
// as the array index.
//
TokenNumber--;
-
+
+ PeiPcdDb = GetPcdDatabase ();
+ LocalTokenCount = PeiPcdDb->LocalTokenCount;
+
if (Guid == NULL) {
// EBC compiler is very choosy. It may report warning about comparison
// between UINTN and 0 . So we add 1 in each size of the
// comparison.
- ASSERT (TokenNumber + 1 < PEI_LOCAL_TOKEN_NUMBER + 1);
+ ASSERT (TokenNumber + 1 < (LocalTokenCount + 1));
}
GuidHob = GetFirstGuidHob (&gEfiCallerIdGuid);
@@ -359,11 +714,13 @@ SetWorker (
)
{
UINT32 LocalTokenNumber;
+ UINTN PeiNexTokenNumber;
PEI_PCD_DATABASE *PeiPcdDb;
STRING_HEAD StringTableIdx;
UINTN Offset;
VOID *InternalData;
UINTN MaxSize;
+ UINT32 LocalTokenCount;
if (!FeaturePcdGet(PcdPeiFullPcdDatabaseEnable)) {
return EFI_UNSUPPORTED;
@@ -375,15 +732,13 @@ SetWorker (
// as the array index.
//
TokenNumber--;
+ PeiPcdDb = GetPcdDatabase ();
+ LocalTokenCount = PeiPcdDb->LocalTokenCount;
// EBC compiler is very choosy. It may report warning about comparison
// between UINTN and 0 . So we add 1 in each size of the
// comparison.
- ASSERT (TokenNumber + 1 < PEI_LOCAL_TOKEN_NUMBER + 1);
-
- PeiPcdDb = GetPcdDatabase ();
-
- LocalTokenNumber = PeiPcdDb->Init.LocalTokenNumberTable[TokenNumber];
+ ASSERT (TokenNumber + 1 < (LocalTokenCount + 1));
if (PtrType) {
//
@@ -405,18 +760,12 @@ SetWorker (
// For Dynamic EX PCD entry, we have invoked the callback function for Dynamic EX
// type PCD entry in ExSetWorker.
//
- if (TokenNumber + 1 < PEI_NEX_TOKEN_NUMBER + 1) {
+ PeiNexTokenNumber = PeiPcdDb->LocalTokenCount - PeiPcdDb->ExTokenCount;
+ if (TokenNumber + 1 < PeiNexTokenNumber + 1) {
InvokeCallbackOnSet (0, NULL, TokenNumber + 1, Data, *Size);
}
- if ((LocalTokenNumber & PCD_TYPE_SKU_ENABLED) == PCD_TYPE_SKU_ENABLED) {
- if (PtrType) {
- GetPtrTypeSize (TokenNumber, &MaxSize, PeiPcdDb);
- } else {
- MaxSize = *Size;
- }
- LocalTokenNumber = GetSkuEnabledTokenNumber (LocalTokenNumber & ~PCD_TYPE_SKU_ENABLED, MaxSize);
- }
+ LocalTokenNumber = GetLocalTokenNumber (PeiPcdDb, TokenNumber + 1);
Offset = LocalTokenNumber & PCD_DATABASE_OFFSET_MASK;
InternalData = (VOID *) ((UINT8 *) PeiPcdDb + Offset);
@@ -433,7 +782,7 @@ SetWorker (
case PCD_TYPE_STRING:
if (SetPtrTypeSize (TokenNumber, Size, PeiPcdDb)) {
StringTableIdx = *((STRING_HEAD *)InternalData);
- CopyMem (&PeiPcdDb->Init.StringTable[StringTableIdx], Data, *Size);
+ CopyMem ((UINT8 *)PeiPcdDb + PeiPcdDb->StringTableOffset + StringTableIdx, Data, *Size);
return EFI_SUCCESS;
} else {
return EFI_INVALID_PARAMETER;
@@ -503,7 +852,7 @@ ExSetValueWorker (
}
/**
- Set value for a dynamic PCD entry.
+ Set value for a dynamic-ex PCD entry.
This routine find the local token number according to dynamic-ex PCD's token
space guid and token number firstly, and invoke callback function if this PCD
@@ -597,7 +946,7 @@ GetWorker (
STRING_HEAD StringTableIdx;
PEI_PCD_DATABASE *PeiPcdDb;
UINT32 LocalTokenNumber;
- UINTN MaxSize;
+ UINT32 LocalTokenCount;
//
// TokenNumber Zero is reserved as PCD_INVALID_TOKEN_NUMBER.
@@ -606,29 +955,21 @@ GetWorker (
//
TokenNumber--;
+ PeiPcdDb = GetPcdDatabase ();
+ LocalTokenCount = PeiPcdDb->LocalTokenCount;
+
// EBC compiler is very choosy. It may report warning about comparison
// between UINTN and 0 . So we add 1 in each size of the
// comparison.
- ASSERT (TokenNumber + 1 < PEI_LOCAL_TOKEN_NUMBER + 1);
+ ASSERT (TokenNumber + 1 < (LocalTokenCount + 1));
ASSERT ((GetSize == PeiPcdGetSize(TokenNumber + 1)) || (GetSize == 0));
- PeiPcdDb = GetPcdDatabase ();
-
- LocalTokenNumber = PeiPcdDb->Init.LocalTokenNumberTable[TokenNumber];
-
- if ((LocalTokenNumber & PCD_TYPE_SKU_ENABLED) == PCD_TYPE_SKU_ENABLED) {
- if (GetSize == 0) {
- GetPtrTypeSize (TokenNumber, &MaxSize, PeiPcdDb);
- } else {
- MaxSize = GetSize;
- }
- LocalTokenNumber = GetSkuEnabledTokenNumber (LocalTokenNumber & ~PCD_TYPE_SKU_ENABLED, MaxSize);
- }
+ LocalTokenNumber = GetLocalTokenNumber (PeiPcdDb, TokenNumber + 1);
Offset = LocalTokenNumber & PCD_DATABASE_OFFSET_MASK;
- StringTable = PeiPcdDb->Init.StringTable;
-
+ StringTable = (UINT8 *)PeiPcdDb + PeiPcdDb->StringTableOffset;
+
switch (LocalTokenNumber & PCD_TYPE_ALL_SET) {
case PCD_TYPE_VPD:
{
@@ -642,7 +983,7 @@ GetWorker (
{
VariableHead = (VARIABLE_HEAD *) ((UINT8 *)PeiPcdDb + Offset);
- Guid = &(PeiPcdDb->Init.GuidTable[VariableHead->GuidTableIndex]);
+ Guid = (EFI_GUID *) ((UINT8 *)PeiPcdDb + PeiPcdDb->GuidTableOffset) + VariableHead->GuidTableIndex;
Name = (UINT16*)&StringTable[VariableHead->StringIndex];
Status = GetHiiVariable (Guid, Name, &Data, &DataSize);
@@ -681,16 +1022,16 @@ GetWorker (
}
/**
- Get local token number according to dynamic-ex PCD's {token space guid:token number}
+ Get Token Number according to dynamic-ex PCD's {token space guid:token number}
A dynamic-ex type PCD, developer must provide pair of token space guid: token number
in DEC file. PCD database maintain a mapping table that translate pair of {token
- space guid: token number} to local token number.
+ space guid: token number} to Token Number.
@param Guid Token space guid for dynamic-ex PCD entry.
- @param ExTokenNumber EDES_TODO: Add parameter description
+ @param ExTokenNumber Dynamic-ex PCD token number.
- @return local token number for dynamic-ex PCD.
+ @return Token Number for dynamic-ex PCD.
**/
UINTN
@@ -707,11 +1048,11 @@ GetExPcdTokenNumber (
PEI_PCD_DATABASE *PeiPcdDb;
PeiPcdDb = GetPcdDatabase();
-
- ExMap = PeiPcdDb->Init.ExMapTable;
- GuidTable = PeiPcdDb->Init.GuidTable;
- MatchGuid = ScanGuid (GuidTable, sizeof(PeiPcdDb->Init.GuidTable), Guid);
+ ExMap = (DYNAMICEX_MAPPING *)((UINT8 *)PeiPcdDb + PeiPcdDb->ExMapTableOffset);
+ GuidTable = (EFI_GUID *)((UINT8 *)PeiPcdDb + PeiPcdDb->GuidTableOffset);
+
+ MatchGuid = ScanGuid (GuidTable, PeiPcdDb->GuidTableCount * sizeof(EFI_GUID), Guid);
//
// We need to ASSERT here. If GUID can't be found in GuidTable, this is a
// error in the BUILD system.
@@ -720,10 +1061,10 @@ GetExPcdTokenNumber (
MatchGuidIdx = MatchGuid - GuidTable;
- for (Index = 0; Index < PEI_EXMAPPING_TABLE_SIZE; Index++) {
+ for (Index = 0; Index < PeiPcdDb->ExTokenCount; Index++) {
if ((ExTokenNumber == ExMap[Index].ExTokenNumber) &&
(MatchGuidIdx == ExMap[Index].ExGuidIndex)) {
- return ExMap[Index].LocalTokenNumber;
+ return ExMap[Index].TokenNumber;
}
}
@@ -750,7 +1091,7 @@ GetPcdDatabase (
}
/**
- Get SKU ID tabble from PCD database.
+ Get SKU ID table from PCD database.
@param LocalTokenNumberTableIdx Index of local token number in token number table.
@param Database PCD database.
@@ -767,7 +1108,7 @@ GetSkuIdArray (
SKU_HEAD *SkuHead;
UINTN LocalTokenNumber;
- LocalTokenNumber = Database->Init.LocalTokenNumberTable[LocalTokenNumberTableIdx];
+ LocalTokenNumber = *((UINT32 *)((UINT8 *)Database + Database->LocalTokenNumberTableOffset) + LocalTokenNumberTableIdx);
ASSERT ((LocalTokenNumber & PCD_TYPE_SKU_ENABLED) != 0);
@@ -793,14 +1134,14 @@ GetSizeTableIndex (
)
{
UINTN Index;
- UINTN SizeTableIdx;
+ UINTN SizeTableIdx;
UINTN LocalTokenNumber;
SKU_ID *SkuIdTable;
SizeTableIdx = 0;
- for (Index=0; Index<LocalTokenNumberTableIdx; Index++) {
- LocalTokenNumber = Database->Init.LocalTokenNumberTable[Index];
+ for (Index = 0; Index < LocalTokenNumberTableIdx; Index++) {
+ LocalTokenNumber = *((UINT32 *)((UINT8 *)Database + Database->LocalTokenNumberTableOffset) + Index);
if ((LocalTokenNumber & PCD_DATUM_TYPE_ALL_SET) == PCD_DATUM_TYPE_POINTER) {
//
@@ -809,11 +1150,12 @@ GetSizeTableIndex (
//
if ((LocalTokenNumber & PCD_TYPE_VPD) != 0) {
//
- // We have only one entry for VPD enabled PCD entry:
+ // We have only two entry for VPD enabled PCD entry:
// 1) MAX Size.
- // We consider current size is equal to MAX size.
+ // 2) Current Size
+ // Current size is equal to MAX size.
//
- SizeTableIdx++;
+ SizeTableIdx += 2;
} else {
if ((LocalTokenNumber & PCD_TYPE_SKU_ENABLED) == 0) {
//
diff --git a/MdeModulePkg/Universal/PCD/Pei/Service.h b/MdeModulePkg/Universal/PCD/Pei/Service.h
index 284768625..916e70895 100644
--- a/MdeModulePkg/Universal/PCD/Pei/Service.h
+++ b/MdeModulePkg/Universal/PCD/Pei/Service.h
@@ -1,7 +1,7 @@
/** @file
The internal header file declares the private functions used by PeiPcd driver.
-Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.<BR>
+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
@@ -19,7 +19,10 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#include <Ppi/ReadOnlyVariable2.h>
#include <Ppi/Pcd.h>
#include <Ppi/PiPcd.h>
+#include <Ppi/PcdInfo.h>
+#include <Ppi/PiPcdInfo.h>
#include <Guid/PcdDataBaseHobGuid.h>
+#include <Guid/PcdDataBaseSignatureGuid.h>
#include <Library/DebugLib.h>
#include <Library/PeimEntryPoint.h>
#include <Library/BaseLib.h>
@@ -27,13 +30,13 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#include <Library/PeiServicesLib.h>
#include <Library/PcdLib.h>
#include <Library/BaseMemoryLib.h>
-
+#include <Library/MemoryAllocationLib.h>
//
// Please make sure the PCD Serivce PEIM Version is consistent with
// the version of the generated PEIM PCD Database by build tool.
//
-#define PCD_SERVICE_PEIM_VERSION 2
+#define PCD_SERVICE_PEIM_VERSION 4
//
// PCD_PEI_SERVICE_DRIVER_VERSION is defined in Autogen.h.
@@ -42,6 +45,61 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#error "Please make sure the version of PCD PEIM Service and the generated PCD PEI Database match."
#endif
+/**
+ Retrieve additional information associated with a PCD token in the default token space.
+
+ This includes information such as the type of value the TokenNumber is associated with as well as possible
+ human readable name that is associated with the token.
+
+ @param[in] TokenNumber The PCD token number.
+ @param[out] PcdInfo The returned information associated with the requested TokenNumber.
+ The caller is responsible for freeing the buffer that is allocated by callee for PcdInfo->PcdName.
+
+ @retval EFI_SUCCESS The PCD information was returned successfully.
+ @retval EFI_NOT_FOUND The PCD service could not find the requested token number.
+**/
+EFI_STATUS
+EFIAPI
+PeiGetPcdInfoGetInfo (
+ IN UINTN TokenNumber,
+ OUT EFI_PCD_INFO *PcdInfo
+ );
+
+/**
+ Retrieve additional information associated with a PCD token.
+
+ This includes information such as the type of value the TokenNumber is associated with as well as possible
+ human readable name that is associated with the token.
+
+ @param[in] Guid The 128-bit unique value that designates the namespace from which to extract the value.
+ @param[in] TokenNumber The PCD token number.
+ @param[out] PcdInfo The returned information associated with the requested TokenNumber.
+ The caller is responsible for freeing the buffer that is allocated by callee for PcdInfo->PcdName.
+
+ @retval EFI_SUCCESS The PCD information was returned successfully.
+ @retval EFI_NOT_FOUND The PCD service could not find the requested token number.
+**/
+EFI_STATUS
+EFIAPI
+PeiGetPcdInfoGetInfoEx (
+ IN CONST EFI_GUID *Guid,
+ IN UINTN TokenNumber,
+ OUT EFI_PCD_INFO *PcdInfo
+ );
+
+/**
+ Retrieve the currently set SKU Id.
+
+ @return The currently set SKU Id. If the platform has not set at a SKU Id, then the
+ default SKU Id value of 0 is returned. If the platform has set a SKU Id, then the currently set SKU
+ Id is returned.
+**/
+UINTN
+EFIAPI
+PeiGetPcdInfoGetSku (
+ VOID
+ );
+
//
// PPI Interface Implementation Declaration.
//
@@ -752,6 +810,26 @@ PeiPcdGetNextTokenSpace (
IN OUT CONST EFI_GUID **Guid
);
+/**
+ Retrieve additional information associated with a PCD token.
+
+ This includes information such as the type of value the TokenNumber is associated with as well as possible
+ human readable name that is associated with the token.
+
+ @param[in] Guid The 128-bit unique value that designates the namespace from which to extract the value.
+ @param[in] TokenNumber The PCD token number.
+ @param[out] PcdInfo The returned information associated with the requested TokenNumber.
+ The caller is responsible for freeing the buffer that is allocated by callee for PcdInfo->PcdName.
+
+ @retval EFI_SUCCESS The PCD information was returned successfully
+ @retval EFI_NOT_FOUND The PCD service could not find the requested token number.
+**/
+EFI_STATUS
+PeiGetPcdInfo (
+ IN CONST EFI_GUID *Guid,
+ IN UINTN TokenNumber,
+ OUT EFI_PCD_INFO *PcdInfo
+ );
/* Internal Function definitions */
/**
@@ -896,16 +974,16 @@ typedef struct {
} EX_PCD_ENTRY_ATTRIBUTE;
/**
- Get local token number according to dynamic-ex PCD's {token space guid:token number}
+ Get Token Number according to dynamic-ex PCD's {token space guid:token number}
A dynamic-ex type PCD, developer must provide pair of token space guid: token number
in DEC file. PCD database maintain a mapping table that translate pair of {token
- space guid: token number} to local token number.
+ space guid: token number} to Token Number.
@param Guid Token space guid for dynamic-ex PCD entry.
@param ExTokenNumber Token number for dynamic-ex PCD.
- @return local token number for dynamic-ex PCD.
+ @return Token Number for dynamic-ex PCD.
**/
UINTN
@@ -915,6 +993,21 @@ GetExPcdTokenNumber (
);
/**
+ Find the local token number according to system SKU ID.
+
+ @param LocalTokenNumber PCD token number
+ @param Size The size of PCD entry.
+
+ @return Token number according to system SKU ID.
+
+**/
+UINT32
+GetSkuEnabledTokenNumber (
+ UINT32 LocalTokenNumber,
+ UINTN Size
+ );
+
+/**
The function registers the CallBackOnSet fucntion
according to TokenNumber and EFI_GUID space.
@@ -938,10 +1031,15 @@ PeiRegisterCallBackWorker (
/**
The function builds the PCD database.
+
+ @param FileHandle Handle of the file the external PCD database binary located.
+
+ @return Pointer to PCD database.
+
**/
-VOID
+PEI_PCD_DATABASE *
BuildPcdDatabase (
- VOID
+ IN EFI_PEI_FILE_HANDLE FileHandle
);
/**
@@ -1015,10 +1113,5 @@ SetPtrTypeSize (
IN PEI_PCD_DATABASE *Database
);
-//
-// The init Database created by PCD Database generation tool
-//
-extern PEI_PCD_DATABASE_INIT gPEIPcdDbInit;
-
#endif
diff --git a/MdeModulePkg/Universal/SetupBrowserDxe/Expression.c b/MdeModulePkg/Universal/SetupBrowserDxe/Expression.c
index 44dae1ba0..d4ab369a4 100644
--- a/MdeModulePkg/Universal/SetupBrowserDxe/Expression.c
+++ b/MdeModulePkg/Universal/SetupBrowserDxe/Expression.c
@@ -1799,6 +1799,55 @@ ExtendValueToU64 (
Value->Value.u64 = Temp;
}
+/**
+ Get UINT64 type value.
+
+ @param Value Input Hii value.
+
+ @retval UINT64 Return the UINT64 type value.
+
+**/
+UINT64
+HiiValueToUINT64 (
+ IN EFI_HII_VALUE *Value
+ )
+{
+ UINT64 RetVal;
+
+ RetVal = 0;
+
+ switch (Value->Type) {
+ case EFI_IFR_TYPE_NUM_SIZE_8:
+ RetVal = Value->Value.u8;
+ break;
+
+ case EFI_IFR_TYPE_NUM_SIZE_16:
+ RetVal = Value->Value.u16;
+ break;
+
+ case EFI_IFR_TYPE_NUM_SIZE_32:
+ RetVal = Value->Value.u32;
+ break;
+
+ case EFI_IFR_TYPE_BOOLEAN:
+ RetVal = Value->Value.b;
+ break;
+
+ case EFI_IFR_TYPE_DATE:
+ RetVal = *(UINT64*) &Value->Value.date;
+ break;
+
+ case EFI_IFR_TYPE_TIME:
+ RetVal = (*(UINT64*) &Value->Value.time) & 0xffffff;
+ break;
+
+ default:
+ RetVal = Value->Value.u64;
+ break;
+ }
+
+ return RetVal;
+}
/**
Compare two Hii value.
@@ -1899,7 +1948,7 @@ CompareHiiValue (
//
// Take remain types(integer, boolean, date/time) as integer
//
- Temp64 = (INT64) (Value1->Value.u64 - Value2->Value.u64);
+ Temp64 = HiiValueToUINT64(Value1) - HiiValueToUINT64(Value2);
if (Temp64 > 0) {
*Result = 1;
} else if (Temp64 < 0) {
@@ -2036,11 +2085,7 @@ GetQuestionValueFromForm (
)
{
EFI_STATUS Status;
- EFI_HANDLE DriverHandle;
- EFI_HANDLE Handle;
- EFI_HII_HANDLE *HiiHandles;
EFI_HII_HANDLE HiiHandle;
- UINTN Index;
FORM_BROWSER_STATEMENT *Question;
FORM_BROWSER_FORMSET *FormSet;
FORM_BROWSER_FORM *Form;
@@ -2054,7 +2099,6 @@ GetQuestionValueFromForm (
(DevicePath == NULL && InputHiiHandle != NULL) );
GetTheVal = TRUE;
- DriverHandle = NULL;
HiiHandle = NULL;
Question = NULL;
Form = NULL;
@@ -2063,38 +2107,10 @@ GetQuestionValueFromForm (
// Get HiiHandle.
//
if (DevicePath != NULL) {
- //
- // 1. Get Driver handle.
- //
- Status = gBS->LocateDevicePath (
- &gEfiDevicePathProtocolGuid,
- &DevicePath,
- &DriverHandle
- );
- if (EFI_ERROR (Status) || (DriverHandle == NULL)) {
+ HiiHandle = DevicePathToHiiHandle (DevicePath, FormSetGuid);
+ if (HiiHandle == NULL) {
return FALSE;
}
-
- //
- // 2. Get Hii handle
- //
- HiiHandles = HiiGetHiiHandles (NULL);
- if (HiiHandles == NULL) {
- return FALSE;
- }
-
- for (Index = 0; HiiHandles[Index] != NULL; Index++) {
- Status = mHiiDatabase->GetPackageListHandle (
- mHiiDatabase,
- HiiHandles[Index],
- &Handle
- );
- if (!EFI_ERROR (Status) && (Handle == DriverHandle)) {
- HiiHandle = HiiHandles[Index];
- break;
- }
- }
- FreePool (HiiHandles);
} else {
HiiHandle = InputHiiHandle;
}
diff --git a/MdeModulePkg/Universal/SetupBrowserDxe/IfrParse.c b/MdeModulePkg/Universal/SetupBrowserDxe/IfrParse.c
index 4006fcd6f..ce2ba6fab 100644
--- a/MdeModulePkg/Universal/SetupBrowserDxe/IfrParse.c
+++ b/MdeModulePkg/Universal/SetupBrowserDxe/IfrParse.c
@@ -348,9 +348,19 @@ InitializeConfigHdr (
/**
Find the global storage link base on the input storate type, name and guid.
+ For EFI_HII_VARSTORE_EFI_VARIABLE and EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER,
+ same guid + name = same storage
+
+ For EFI_HII_VARSTORE_NAME_VALUE:
+ same guid + HiiHandle = same storage
+
+ For EFI_HII_VARSTORE_BUFFER:
+ same guid + name + HiiHandle = same storage
+
@param StorageType Storage type.
@param StorageGuid Storage guid.
@param StorageName Storage Name.
+ @param HiiHandle HiiHandle for this varstore.
@return Pointer to a GLOBAL_STORAGE data structure.
@@ -359,7 +369,8 @@ BROWSER_STORAGE *
FindStorageInList (
IN UINT8 StorageType,
IN EFI_GUID *StorageGuid,
- IN CHAR16 *StorageName
+ IN CHAR16 *StorageName,
+ IN EFI_HII_HANDLE HiiHandle
)
{
LIST_ENTRY *Link;
@@ -370,12 +381,16 @@ FindStorageInList (
BrowserStorage = BROWSER_STORAGE_FROM_LINK (Link);
if ((BrowserStorage->Type == StorageType) && CompareGuid (&BrowserStorage->Guid, StorageGuid)) {
- if (StorageType == EFI_HII_VARSTORE_NAME_VALUE) {
+ if (StorageType == EFI_HII_VARSTORE_NAME_VALUE && BrowserStorage->HiiHandle == HiiHandle) {
return BrowserStorage;
}
if (StrCmp (BrowserStorage->Name, StorageName) == 0) {
- return BrowserStorage;
+ if (StorageType == EFI_HII_VARSTORE_EFI_VARIABLE || StorageType == EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER) {
+ return BrowserStorage;
+ } else if (StorageType == EFI_HII_VARSTORE_BUFFER && BrowserStorage->HiiHandle == HiiHandle) {
+ return BrowserStorage;
+ }
}
}
@@ -494,7 +509,7 @@ CreateStorage (
Storage->Signature = FORMSET_STORAGE_SIGNATURE;
InsertTailList (&FormSet->StorageListHead, &Storage->Link);
- BrowserStorage = FindStorageInList(StorageType, StorageGuid, UnicodeString);
+ BrowserStorage = FindStorageInList(StorageType, StorageGuid, UnicodeString, FormSet->HiiHandle);
if (BrowserStorage == NULL) {
BrowserStorage = AllocateZeroPool (sizeof (BROWSER_STORAGE));
ASSERT (BrowserStorage != NULL);
@@ -508,7 +523,10 @@ CreateStorage (
BrowserStorage->Name = UnicodeString;
}
+ BrowserStorage->HiiHandle = FormSet->HiiHandle;
InitializeConfigHdr (FormSet, BrowserStorage);
+
+ BrowserStorage->Initialized = FALSE;
}
Storage->BrowserStorage = BrowserStorage;
diff --git a/MdeModulePkg/Universal/SetupBrowserDxe/Presentation.c b/MdeModulePkg/Universal/SetupBrowserDxe/Presentation.c
index 8e6dff0dd..fb3ff7b26 100644
--- a/MdeModulePkg/Universal/SetupBrowserDxe/Presentation.c
+++ b/MdeModulePkg/Universal/SetupBrowserDxe/Presentation.c
@@ -1040,6 +1040,87 @@ ProcessAction (
return EFI_SUCCESS;
}
+/**
+ Check whether the formset guid is in this Hii package list.
+
+ @param HiiHandle The HiiHandle for this HII package list.
+ @param FormSetGuid The formset guid for the request formset.
+
+ @retval TRUE Find the formset guid.
+ @retval FALSE Not found the formset guid.
+
+**/
+BOOLEAN
+GetFormsetGuidFromHiiHandle (
+ IN EFI_HII_HANDLE HiiHandle,
+ IN EFI_GUID *FormSetGuid
+ )
+{
+ EFI_HII_PACKAGE_LIST_HEADER *HiiPackageList;
+ UINTN BufferSize;
+ UINT32 Offset;
+ UINT32 Offset2;
+ UINT32 PackageListLength;
+ EFI_HII_PACKAGE_HEADER PackageHeader;
+ UINT8 *Package;
+ UINT8 *OpCodeData;
+ EFI_STATUS Status;
+ BOOLEAN FindGuid;
+
+ BufferSize = 0;
+ HiiPackageList = NULL;
+ FindGuid = FALSE;
+
+ Status = mHiiDatabase->ExportPackageLists (mHiiDatabase, HiiHandle, &BufferSize, HiiPackageList);
+ if (Status == EFI_BUFFER_TOO_SMALL) {
+ HiiPackageList = AllocatePool (BufferSize);
+ ASSERT (HiiPackageList != NULL);
+
+ Status = mHiiDatabase->ExportPackageLists (mHiiDatabase, HiiHandle, &BufferSize, HiiPackageList);
+ }
+ if (EFI_ERROR (Status) || HiiPackageList == NULL) {
+ return FALSE;
+ }
+
+ //
+ // Get Form package from this HII package List
+ //
+ Offset = sizeof (EFI_HII_PACKAGE_LIST_HEADER);
+ Offset2 = 0;
+ CopyMem (&PackageListLength, &HiiPackageList->PackageLength, sizeof (UINT32));
+
+ while (Offset < PackageListLength) {
+ Package = ((UINT8 *) HiiPackageList) + Offset;
+ CopyMem (&PackageHeader, Package, sizeof (EFI_HII_PACKAGE_HEADER));
+ Offset += PackageHeader.Length;
+
+ if (PackageHeader.Type == EFI_HII_PACKAGE_FORMS) {
+ //
+ // Search FormSet in this Form Package
+ //
+ Offset2 = sizeof (EFI_HII_PACKAGE_HEADER);
+ while (Offset2 < PackageHeader.Length) {
+ OpCodeData = Package + Offset2;
+
+ if (((EFI_IFR_OP_HEADER *) OpCodeData)->OpCode == EFI_IFR_FORM_SET_OP) {
+ if (CompareGuid (FormSetGuid, (EFI_GUID *)(OpCodeData + sizeof (EFI_IFR_OP_HEADER)))){
+ FindGuid = TRUE;
+ break;
+ }
+ }
+
+ Offset2 += ((EFI_IFR_OP_HEADER *) OpCodeData)->Length;
+ }
+ }
+ if (FindGuid) {
+ break;
+ }
+ }
+
+ FreePool (HiiPackageList);
+
+ return FindGuid;
+}
/**
Find HII Handle in the HII database associated with given Device Path.
@@ -1048,6 +1129,7 @@ ProcessAction (
@param DevicePath Device Path associated with the HII package list
handle.
+ @param FormsetGuid The formset guid for this formset.
@retval Handle HII package list Handle associated with the Device
Path.
@@ -1055,15 +1137,13 @@ ProcessAction (
**/
EFI_HII_HANDLE
-EFIAPI
DevicePathToHiiHandle (
- IN EFI_DEVICE_PATH_PROTOCOL *DevicePath
+ IN EFI_DEVICE_PATH_PROTOCOL *DevicePath,
+ IN EFI_GUID *FormsetGuid
)
{
EFI_STATUS Status;
EFI_DEVICE_PATH_PROTOCOL *TmpDevicePath;
- UINTN BufferSize;
- UINTN HandleCount;
UINTN Index;
EFI_HANDLE Handle;
EFI_HANDLE DriverHandle;
@@ -1088,32 +1168,8 @@ DevicePathToHiiHandle (
//
// Retrieve all HII Handles from HII database
//
- BufferSize = 0x1000;
- HiiHandles = AllocatePool (BufferSize);
- ASSERT (HiiHandles != NULL);
- Status = mHiiDatabase->ListPackageLists (
- mHiiDatabase,
- EFI_HII_PACKAGE_TYPE_ALL,
- NULL,
- &BufferSize,
- HiiHandles
- );
- if (Status == EFI_BUFFER_TOO_SMALL) {
- FreePool (HiiHandles);
- HiiHandles = AllocatePool (BufferSize);
- ASSERT (HiiHandles != NULL);
-
- Status = mHiiDatabase->ListPackageLists (
- mHiiDatabase,
- EFI_HII_PACKAGE_TYPE_ALL,
- NULL,
- &BufferSize,
- HiiHandles
- );
- }
-
- if (EFI_ERROR (Status)) {
- FreePool (HiiHandles);
+ HiiHandles = HiiGetHiiHandles (NULL);
+ if (HiiHandles == NULL) {
return NULL;
}
@@ -1121,16 +1177,21 @@ DevicePathToHiiHandle (
// Search Hii Handle by Driver Handle
//
HiiHandle = NULL;
- HandleCount = BufferSize / sizeof (EFI_HII_HANDLE);
- for (Index = 0; Index < HandleCount; Index++) {
+ for (Index = 0; HiiHandles[Index] != NULL; Index++) {
Status = mHiiDatabase->GetPackageListHandle (
mHiiDatabase,
HiiHandles[Index],
&Handle
);
if (!EFI_ERROR (Status) && (Handle == DriverHandle)) {
- HiiHandle = HiiHandles[Index];
- break;
+ if (GetFormsetGuidFromHiiHandle(HiiHandles[Index], FormsetGuid)) {
+ HiiHandle = HiiHandles[Index];
+ break;
+ }
+
+ if (HiiHandle != NULL) {
+ break;
+ }
}
}
@@ -1157,17 +1218,8 @@ FormSetGuidToHiiHandle (
)
{
EFI_HII_HANDLE *HiiHandles;
- UINTN Index;
- EFI_HII_PACKAGE_LIST_HEADER *HiiPackageList;
- UINTN BufferSize;
- UINT32 Offset;
- UINT32 Offset2;
- UINT32 PackageListLength;
- EFI_HII_PACKAGE_HEADER PackageHeader;
- UINT8 *Package;
- UINT8 *OpCodeData;
- EFI_STATUS Status;
EFI_HII_HANDLE HiiHandle;
+ UINTN Index;
ASSERT (ComparingGuid != NULL);
@@ -1182,61 +1234,14 @@ FormSetGuidToHiiHandle (
// Search for formset of each class type
//
for (Index = 0; HiiHandles[Index] != NULL; Index++) {
- BufferSize = 0;
- HiiPackageList = NULL;
- Status = mHiiDatabase->ExportPackageLists (mHiiDatabase, HiiHandles[Index], &BufferSize, HiiPackageList);
- if (Status == EFI_BUFFER_TOO_SMALL) {
- HiiPackageList = AllocatePool (BufferSize);
- ASSERT (HiiPackageList != NULL);
-
- Status = mHiiDatabase->ExportPackageLists (mHiiDatabase, HiiHandles[Index], &BufferSize, HiiPackageList);
- }
- if (EFI_ERROR (Status) || HiiPackageList == NULL) {
- return NULL;
+ if (GetFormsetGuidFromHiiHandle(HiiHandles[Index], ComparingGuid)) {
+ HiiHandle = HiiHandles[Index];
+ break;
}
- //
- // Get Form package from this HII package List
- //
- Offset = sizeof (EFI_HII_PACKAGE_LIST_HEADER);
- Offset2 = 0;
- CopyMem (&PackageListLength, &HiiPackageList->PackageLength, sizeof (UINT32));
-
- while (Offset < PackageListLength) {
- Package = ((UINT8 *) HiiPackageList) + Offset;
- CopyMem (&PackageHeader, Package, sizeof (EFI_HII_PACKAGE_HEADER));
-
- if (PackageHeader.Type == EFI_HII_PACKAGE_FORMS) {
- //
- // Search FormSet in this Form Package
- //
- Offset2 = sizeof (EFI_HII_PACKAGE_HEADER);
- while (Offset2 < PackageHeader.Length) {
- OpCodeData = Package + Offset2;
-
- if (((EFI_IFR_OP_HEADER *) OpCodeData)->OpCode == EFI_IFR_FORM_SET_OP) {
- //
- // Try to compare against formset GUID
- //
- if (CompareGuid (ComparingGuid, (EFI_GUID *)(OpCodeData + sizeof (EFI_IFR_OP_HEADER)))) {
- HiiHandle = HiiHandles[Index];
- break;
- }
- }
-
- Offset2 += ((EFI_IFR_OP_HEADER *) OpCodeData)->Length;
- }
- }
- if (HiiHandle != NULL) {
- break;
- }
- Offset += PackageHeader.Length;
+ if (HiiHandle != NULL) {
+ break;
}
-
- FreePool (HiiPackageList);
- if (HiiHandle != NULL) {
- break;
- }
}
FreePool (HiiHandles);
@@ -1375,7 +1380,7 @@ ProcessGotoOpCode (
if (mPathFromText != NULL) {
DevicePath = mPathFromText->ConvertTextToDevicePath(StringPtr);
if (DevicePath != NULL) {
- HiiHandle = DevicePathToHiiHandle (DevicePath);
+ HiiHandle = DevicePathToHiiHandle (DevicePath, &Statement->HiiValue.Value.ref.FormSetGuid);
FreePool (DevicePath);
}
FreePool (StringPtr);
@@ -1494,7 +1499,6 @@ ProcessQuestionConfig (
EFI_STATUS Status;
CHAR16 *ConfigResp;
CHAR16 *Progress;
- EFI_HII_CONFIG_ACCESS_PROTOCOL *ConfigAccess;
if (Question->QuestionConfig == 0) {
return EFI_SUCCESS;
@@ -1511,12 +1515,8 @@ ProcessQuestionConfig (
//
// Send config to Configuration Driver
//
- ConfigAccess = Selection->FormSet->ConfigAccess;
- if (ConfigAccess == NULL) {
- return EFI_UNSUPPORTED;
- }
- Status = ConfigAccess->RouteConfig (
- ConfigAccess,
+ Status = mHiiConfigRouting->RouteConfig (
+ mHiiConfigRouting,
ConfigResp,
&Progress
);
diff --git a/MdeModulePkg/Universal/SetupBrowserDxe/Setup.c b/MdeModulePkg/Universal/SetupBrowserDxe/Setup.c
index 7975a1df1..66238e055 100644
--- a/MdeModulePkg/Universal/SetupBrowserDxe/Setup.c
+++ b/MdeModulePkg/Universal/SetupBrowserDxe/Setup.c
@@ -645,6 +645,17 @@ BrowserCallback (
}
}
+ if (Storage->Type == EFI_HII_VARSTORE_NAME_VALUE ||
+ Storage->Type == EFI_HII_VARSTORE_BUFFER) {
+ if (mSystemLevelFormSet == NULL || mSystemLevelFormSet->HiiHandle == NULL) {
+ return EFI_NOT_FOUND;
+ }
+
+ if (Storage->HiiHandle != mSystemLevelFormSet->HiiHandle) {
+ continue;
+ }
+ }
+
Status = ProcessStorage (&TotalSize, &ResultsData, RetrieveData, Storage);
if (EFI_ERROR (Status)) {
return Status;
@@ -1259,7 +1270,6 @@ GetQuestionValue (
BOOLEAN IsString;
CHAR16 TemStr[5];
UINT8 DigitUint8;
- UINT8 *TemBuffer;
Status = EFI_SUCCESS;
Value = NULL;
@@ -1476,147 +1486,118 @@ GetQuestionValue (
FreePool (Value);
}
} else {
- if (Storage->Type == EFI_HII_VARSTORE_BUFFER || Storage->Type == EFI_HII_VARSTORE_NAME_VALUE) {
- //
- // Request current settings from Configuration Driver
- //
- if (FormSet->ConfigAccess == NULL) {
- return EFI_NOT_FOUND;
- }
-
- //
- // <ConfigRequest> ::= <ConfigHdr> + <BlockName> ||
- // <ConfigHdr> + "&" + <VariableName>
- //
- if (IsBufferStorage) {
- Length = StrLen (Storage->ConfigHdr);
- Length += StrLen (Question->BlockName);
- } else {
- Length = StrLen (Storage->ConfigHdr);
- Length += StrLen (Question->VariableName) + 1;
- }
- ConfigRequest = AllocateZeroPool ((Length + 1) * sizeof (CHAR16));
- ASSERT (ConfigRequest != NULL);
+ //
+ // <ConfigRequest> ::= <ConfigHdr> + <BlockName> ||
+ // <ConfigHdr> + "&" + <VariableName>
+ //
+ if (IsBufferStorage) {
+ Length = StrLen (Storage->ConfigHdr);
+ Length += StrLen (Question->BlockName);
+ } else {
+ Length = StrLen (Storage->ConfigHdr);
+ Length += StrLen (Question->VariableName) + 1;
+ }
+ ConfigRequest = AllocateZeroPool ((Length + 1) * sizeof (CHAR16));
+ ASSERT (ConfigRequest != NULL);
- StrCpy (ConfigRequest, Storage->ConfigHdr);
- if (IsBufferStorage) {
- StrCat (ConfigRequest, Question->BlockName);
- } else {
- StrCat (ConfigRequest, L"&");
- StrCat (ConfigRequest, Question->VariableName);
- }
+ StrCpy (ConfigRequest, Storage->ConfigHdr);
+ if (IsBufferStorage) {
+ StrCat (ConfigRequest, Question->BlockName);
+ } else {
+ StrCat (ConfigRequest, L"&");
+ StrCat (ConfigRequest, Question->VariableName);
+ }
- Status = FormSet->ConfigAccess->ExtractConfig (
- FormSet->ConfigAccess,
- ConfigRequest,
- &Progress,
- &Result
- );
- FreePool (ConfigRequest);
- if (EFI_ERROR (Status)) {
- return Status;
- }
+ //
+ // Request current settings from Configuration Driver
+ //
+ Status = mHiiConfigRouting->ExtractConfig (
+ mHiiConfigRouting,
+ ConfigRequest,
+ &Progress,
+ &Result
+ );
+ FreePool (ConfigRequest);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
- //
- // Skip <ConfigRequest>
- //
- if (IsBufferStorage) {
- Value = StrStr (Result, L"&VALUE");
- if (Value == NULL) {
- FreePool (Result);
- return EFI_NOT_FOUND;
- }
- //
- // Skip "&VALUE"
- //
- Value = Value + 6;
- } else {
- Value = Result + Length;
- }
- if (*Value != '=') {
+ //
+ // Skip <ConfigRequest>
+ //
+ if (IsBufferStorage) {
+ Value = StrStr (Result, L"&VALUE");
+ if (Value == NULL) {
FreePool (Result);
return EFI_NOT_FOUND;
}
//
- // Skip '=', point to value
+ // Skip "&VALUE"
//
- Value = Value + 1;
+ Value = Value + 6;
+ } else {
+ Value = Result + Length;
+ }
+ if (*Value != '=') {
+ FreePool (Result);
+ return EFI_NOT_FOUND;
+ }
+ //
+ // Skip '=', point to value
+ //
+ Value = Value + 1;
+ //
+ // Suppress <AltResp> if any
+ //
+ StringPtr = Value;
+ while (*StringPtr != L'\0' && *StringPtr != L'&') {
+ StringPtr++;
+ }
+ *StringPtr = L'\0';
+
+ LengthStr = StrLen (Value);
+ Status = EFI_SUCCESS;
+ if (!IsBufferStorage && IsString) {
//
- // Suppress <AltResp> if any
+ // Convert Config String to Unicode String, e.g "0041004200430044" => "ABCD"
+ // Add string tail char L'\0' into Length
//
- StringPtr = Value;
- while (*StringPtr != L'\0' && *StringPtr != L'&') {
- StringPtr++;
- }
- *StringPtr = L'\0';
-
- LengthStr = StrLen (Value);
- Status = EFI_SUCCESS;
- if (!IsBufferStorage && IsString) {
+ Length = StorageWidth + sizeof (CHAR16);
+ if (Length < ((LengthStr / 4 + 1) * 2)) {
+ Status = EFI_BUFFER_TOO_SMALL;
+ } else {
+ StringPtr = (CHAR16 *) Dst;
+ ZeroMem (TemStr, sizeof (TemStr));
+ for (Index = 0; Index < LengthStr; Index += 4) {
+ StrnCpy (TemStr, Value + Index, 4);
+ StringPtr[Index/4] = (CHAR16) StrHexToUint64 (TemStr);
+ }
//
- // Convert Config String to Unicode String, e.g "0041004200430044" => "ABCD"
- // Add string tail char L'\0' into Length
+ // Add tailing L'\0' character
//
- Length = StorageWidth + sizeof (CHAR16);
- if (Length < ((LengthStr / 4 + 1) * 2)) {
- Status = EFI_BUFFER_TOO_SMALL;
- } else {
- StringPtr = (CHAR16 *) Dst;
- ZeroMem (TemStr, sizeof (TemStr));
- for (Index = 0; Index < LengthStr; Index += 4) {
- StrnCpy (TemStr, Value + Index, 4);
- StringPtr[Index/4] = (CHAR16) StrHexToUint64 (TemStr);
- }
- //
- // Add tailing L'\0' character
- //
- StringPtr[Index/4] = L'\0';
- }
+ StringPtr[Index/4] = L'\0';
+ }
+ } else {
+ if (StorageWidth < ((LengthStr + 1) / 2)) {
+ Status = EFI_BUFFER_TOO_SMALL;
} else {
- if (StorageWidth < ((LengthStr + 1) / 2)) {
- Status = EFI_BUFFER_TOO_SMALL;
- } else {
- ZeroMem (TemStr, sizeof (TemStr));
- for (Index = 0; Index < LengthStr; Index ++) {
- TemStr[0] = Value[LengthStr - Index - 1];
- DigitUint8 = (UINT8) StrHexToUint64 (TemStr);
- if ((Index & 1) == 0) {
- Dst [Index/2] = DigitUint8;
- } else {
- Dst [Index/2] = (UINT8) ((DigitUint8 << 4) + Dst [Index/2]);
- }
+ ZeroMem (TemStr, sizeof (TemStr));
+ for (Index = 0; Index < LengthStr; Index ++) {
+ TemStr[0] = Value[LengthStr - Index - 1];
+ DigitUint8 = (UINT8) StrHexToUint64 (TemStr);
+ if ((Index & 1) == 0) {
+ Dst [Index/2] = DigitUint8;
+ } else {
+ Dst [Index/2] = (UINT8) ((DigitUint8 << 4) + Dst [Index/2]);
}
}
}
+ }
- if (EFI_ERROR (Status)) {
- FreePool (Result);
- return Status;
- }
- } else if (Storage->Type == EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER) {
- TemBuffer = NULL;
- TemBuffer = AllocateZeroPool (Storage->Size);
- if (TemBuffer == NULL) {
- Status = EFI_OUT_OF_RESOURCES;
- return Status;
- }
- Length = Storage->Size;
- Status = gRT->GetVariable (
- Storage->Name,
- &Storage->Guid,
- NULL,
- &Length,
- TemBuffer
- );
- if (EFI_ERROR (Status)) {
- FreePool (TemBuffer);
- return Status;
- }
-
- CopyMem (Dst, TemBuffer + Question->VarStoreInfo.VarOffset, StorageWidth);
-
- FreePool (TemBuffer);
+ if (EFI_ERROR (Status)) {
+ FreePool (Result);
+ return Status;
}
//
@@ -1860,111 +1841,78 @@ SetQuestionValue (
}
}
} else if (SetValueTo == GetSetValueWithHiiDriver) {
- if (Storage->Type == EFI_HII_VARSTORE_BUFFER || Storage->Type == EFI_HII_VARSTORE_NAME_VALUE) {
- //
- // <ConfigResp> ::= <ConfigHdr> + <BlockName> + "&VALUE=" + "<HexCh>StorageWidth * 2" ||
- // <ConfigHdr> + "&" + <VariableName> + "=" + "<string>"
- //
- if (IsBufferStorage) {
- Length = StrLen (Question->BlockName) + 7;
- } else {
- Length = StrLen (Question->VariableName) + 2;
- }
- if (!IsBufferStorage && IsString) {
- Length += (StrLen ((CHAR16 *) Src) * 4);
- } else {
- Length += (StorageWidth * 2);
- }
- ConfigResp = AllocateZeroPool ((StrLen (Storage->ConfigHdr) + Length + 1) * sizeof (CHAR16));
- ASSERT (ConfigResp != NULL);
-
- StrCpy (ConfigResp, Storage->ConfigHdr);
- if (IsBufferStorage) {
- StrCat (ConfigResp, Question->BlockName);
- StrCat (ConfigResp, L"&VALUE=");
- } else {
- StrCat (ConfigResp, L"&");
- StrCat (ConfigResp, Question->VariableName);
- StrCat (ConfigResp, L"=");
- }
+ //
+ // <ConfigResp> ::= <ConfigHdr> + <BlockName> + "&VALUE=" + "<HexCh>StorageWidth * 2" ||
+ // <ConfigHdr> + "&" + <VariableName> + "=" + "<string>"
+ //
+ if (IsBufferStorage) {
+ Length = StrLen (Question->BlockName) + 7;
+ } else {
+ Length = StrLen (Question->VariableName) + 2;
+ }
+ if (!IsBufferStorage && IsString) {
+ Length += (StrLen ((CHAR16 *) Src) * 4);
+ } else {
+ Length += (StorageWidth * 2);
+ }
+ ConfigResp = AllocateZeroPool ((StrLen (Storage->ConfigHdr) + Length + 1) * sizeof (CHAR16));
+ ASSERT (ConfigResp != NULL);
- Value = ConfigResp + StrLen (ConfigResp);
+ StrCpy (ConfigResp, Storage->ConfigHdr);
+ if (IsBufferStorage) {
+ StrCat (ConfigResp, Question->BlockName);
+ StrCat (ConfigResp, L"&VALUE=");
+ } else {
+ StrCat (ConfigResp, L"&");
+ StrCat (ConfigResp, Question->VariableName);
+ StrCat (ConfigResp, L"=");
+ }
- if (!IsBufferStorage && IsString) {
- //
- // Convert Unicode String to Config String, e.g. "ABCD" => "0041004200430044"
- //
- TemName = (CHAR16 *) Src;
- TemString = Value;
- for (; *TemName != L'\0'; TemName++) {
- TemString += UnicodeValueToString (TemString, PREFIX_ZERO | RADIX_HEX, *TemName, 4);
- }
- } else {
- //
- // Convert Buffer to Hex String
- //
- TemBuffer = Src + StorageWidth - 1;
- TemString = Value;
- for (Index = 0; Index < StorageWidth; Index ++, TemBuffer --) {
- TemString += UnicodeValueToString (TemString, PREFIX_ZERO | RADIX_HEX, *TemBuffer, 2);
- }
- }
+ Value = ConfigResp + StrLen (ConfigResp);
+ if (!IsBufferStorage && IsString) {
//
- // Convert to lower char.
+ // Convert Unicode String to Config String, e.g. "ABCD" => "0041004200430044"
//
- for (TemString = Value; *Value != L'\0'; Value++) {
- if (*Value >= L'A' && *Value <= L'Z') {
- *Value = (CHAR16) (*Value - L'A' + L'a');
- }
+ TemName = (CHAR16 *) Src;
+ TemString = Value;
+ for (; *TemName != L'\0'; TemName++) {
+ TemString += UnicodeValueToString (TemString, PREFIX_ZERO | RADIX_HEX, *TemName, 4);
}
-
+ } else {
//
- // Submit Question Value to Configuration Driver
+ // Convert Buffer to Hex String
//
- if (FormSet->ConfigAccess != NULL) {
- Status = FormSet->ConfigAccess->RouteConfig (
- FormSet->ConfigAccess,
- ConfigResp,
- &Progress
- );
- if (EFI_ERROR (Status)) {
- FreePool (ConfigResp);
- return Status;
- }
- }
- FreePool (ConfigResp);
-
- } else if (Storage->Type == EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER) {
- TemBuffer = NULL;
- TemBuffer = AllocateZeroPool(Storage->Size);
- if (TemBuffer == NULL) {
- Status = EFI_OUT_OF_RESOURCES;
- return Status;
+ TemBuffer = Src + StorageWidth - 1;
+ TemString = Value;
+ for (Index = 0; Index < StorageWidth; Index ++, TemBuffer --) {
+ TemString += UnicodeValueToString (TemString, PREFIX_ZERO | RADIX_HEX, *TemBuffer, 2);
}
- Length = Storage->Size;
- Status = gRT->GetVariable (
- Storage->Name,
- &Storage->Guid,
- NULL,
- &Length,
- TemBuffer
- );
-
- CopyMem (TemBuffer + Question->VarStoreInfo.VarOffset, Src, StorageWidth);
-
- Status = gRT->SetVariable (
- Storage->Name,
- &Storage->Guid,
- Storage->Attributes,
- Storage->Size,
- TemBuffer
- );
- FreePool (TemBuffer);
- if (EFI_ERROR (Status)){
- return Status;
+ }
+
+ //
+ // Convert to lower char.
+ //
+ for (TemString = Value; *Value != L'\0'; Value++) {
+ if (*Value >= L'A' && *Value <= L'Z') {
+ *Value = (CHAR16) (*Value - L'A' + L'a');
}
}
+
+ //
+ // Submit Question Value to Configuration Driver
+ //
+ Status = mHiiConfigRouting->RouteConfig (
+ mHiiConfigRouting,
+ ConfigResp,
+ &Progress
+ );
+ if (EFI_ERROR (Status)) {
+ FreePool (ConfigResp);
+ return Status;
+ }
+ FreePool (ConfigResp);
+
//
// Sync storage, from editbuffer to buffer.
//
@@ -2511,8 +2459,6 @@ SubmitForm (
EFI_STRING Progress;
BROWSER_STORAGE *Storage;
FORMSET_STORAGE *FormSetStorage;
- UINTN BufferSize;
- UINT8 *TmpBuf;
FORM_BROWSER_FORMSET *LocalFormSet;
FORM_BROWSER_CONFIG_REQUEST *ConfigInfo;
@@ -2564,72 +2510,18 @@ SubmitForm (
}
//
- // 2. Set value to hii driver or efi variable.
+ // 2. Set value to hii config routine protocol.
//
- if (Storage->Type == EFI_HII_VARSTORE_BUFFER ||
- Storage->Type == EFI_HII_VARSTORE_NAME_VALUE) {
- //
- // Send <ConfigResp> to Configuration Driver
- //
- if (FormSet->ConfigAccess != NULL) {
- Status = FormSet->ConfigAccess->RouteConfig (
- FormSet->ConfigAccess,
- ConfigResp,
- &Progress
- );
- if (EFI_ERROR (Status)) {
- FreePool (ConfigResp);
- return Status;
- }
- }
- } else if (Storage->Type == EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER) {
- TmpBuf = NULL;
- TmpBuf = AllocateZeroPool(Storage->Size);
- if (TmpBuf == NULL) {
- Status = EFI_OUT_OF_RESOURCES;
- return Status;
- }
-
- BufferSize = Storage->Size;
- Status = gRT->GetVariable (
- Storage->Name,
- &Storage->Guid,
- NULL,
- &BufferSize,
- TmpBuf
- );
- if (EFI_ERROR (Status)) {
- FreePool (TmpBuf);
- FreePool (ConfigResp);
- return Status;
- }
- ASSERT (BufferSize == Storage->Size);
- Status = mHiiConfigRouting->ConfigToBlock (
- mHiiConfigRouting,
- ConfigResp,
- TmpBuf,
- &BufferSize,
- &Progress
- );
- if (EFI_ERROR (Status)) {
- FreePool (TmpBuf);
- FreePool (ConfigResp);
- return Status;
- }
-
- Status = gRT->SetVariable (
- Storage->Name,
- &Storage->Guid,
- Storage->Attributes,
- Storage->Size,
- TmpBuf
- );
- FreePool (TmpBuf);
- if (EFI_ERROR (Status)) {
- FreePool (ConfigResp);
- return Status;
- }
+ Status = mHiiConfigRouting->RouteConfig (
+ mHiiConfigRouting,
+ ConfigResp,
+ &Progress
+ );
+ if (EFI_ERROR (Status)) {
+ FreePool (ConfigResp);
+ return Status;
}
+
FreePool (ConfigResp);
//
// 3. Config success, update storage shadow Buffer, only update the data belong to this form.
@@ -2670,69 +2562,19 @@ SubmitForm (
return Status;
}
- if (Storage->Type == EFI_HII_VARSTORE_BUFFER ||
- Storage->Type == EFI_HII_VARSTORE_NAME_VALUE) {
-
- //
- // 2. Send <ConfigResp> to Configuration Driver
- //
- if (FormSet->ConfigAccess != NULL) {
- Status = FormSet->ConfigAccess->RouteConfig (
- FormSet->ConfigAccess,
- ConfigResp,
- &Progress
- );
- if (EFI_ERROR (Status)) {
- FreePool (ConfigResp);
- return Status;
- }
- }
- } else if (Storage->Type == EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER) {
- //
- // 1&2. Set the edit data to the variable.
- //
- TmpBuf = NULL;
- TmpBuf = AllocateZeroPool (Storage->Size);
- if (TmpBuf == NULL) {
- Status = EFI_OUT_OF_RESOURCES;
- return Status;
- }
- BufferSize = Storage->Size;
- Status = gRT->GetVariable (
- Storage->Name,
- &Storage->Guid,
- NULL,
- &BufferSize,
- TmpBuf
- );
- ASSERT (BufferSize == Storage->Size);
- Status = mHiiConfigRouting->ConfigToBlock (
- mHiiConfigRouting,
- ConfigResp,
- TmpBuf,
- &BufferSize,
- &Progress
- );
- if (EFI_ERROR (Status)) {
- FreePool (TmpBuf);
- FreePool (ConfigResp);
- return Status;
- }
-
- Status = gRT->SetVariable (
- Storage->Name,
- &Storage->Guid,
- Storage->Attributes,
- Storage->Size,
- TmpBuf
- );
- if (EFI_ERROR (Status)) {
- FreePool (TmpBuf);
- FreePool (ConfigResp);
- return Status;
- }
- FreePool (TmpBuf);
+ //
+ // 2. Send <ConfigResp> to Routine config Protocol.
+ //
+ Status = mHiiConfigRouting->RouteConfig (
+ mHiiConfigRouting,
+ ConfigResp,
+ &Progress
+ );
+ if (EFI_ERROR (Status)) {
+ FreePool (ConfigResp);
+ return Status;
}
+
FreePool (ConfigResp);
//
// 3. Config success, update storage shadow Buffer
@@ -2817,9 +2659,7 @@ GetDefaultValueFromAltCfg (
Value = NULL;
Storage = Question->Storage;
- if ((Storage == NULL) ||
- (Storage->Type == EFI_HII_VARSTORE_EFI_VARIABLE) ||
- (Storage->Type == EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER)) {
+ if ((Storage == NULL) || (Storage->Type == EFI_HII_VARSTORE_EFI_VARIABLE)) {
return Status;
}
@@ -2838,7 +2678,11 @@ GetDefaultValueFromAltCfg (
Dst = (UINT8 *) &Question->HiiValue.Value;
}
- IsBufferStorage = (BOOLEAN) ((Storage->Type == EFI_HII_VARSTORE_BUFFER) ? TRUE : FALSE);
+ if (Storage->Type == EFI_HII_VARSTORE_BUFFER || Storage->Type == EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER) {
+ IsBufferStorage = TRUE;
+ } else {
+ IsBufferStorage = FALSE;
+ }
IsString = (BOOLEAN) ((Question->HiiValue.Type == EFI_IFR_TYPE_STRING) ? TRUE : FALSE);
//
@@ -2863,8 +2707,8 @@ GetDefaultValueFromAltCfg (
StrCat (ConfigRequest, Question->VariableName);
}
- Status = FormSet->ConfigAccess->ExtractConfig (
- FormSet->ConfigAccess,
+ Status = mHiiConfigRouting->ExtractConfig (
+ mHiiConfigRouting,
ConfigRequest,
&Progress,
&Result
@@ -2894,6 +2738,11 @@ GetDefaultValueFromAltCfg (
goto Done;
}
+ if (ConfigResp == NULL) {
+ Status = EFI_NOT_FOUND;
+ goto Done;
+ }
+
//
// Skip <ConfigRequest>
//
@@ -3880,18 +3729,20 @@ CleanBrowserStorage (
Storage = FORMSET_STORAGE_FROM_LINK (Link);
Link = GetNextNode (&FormSet->StorageListHead, Link);
- if ((Storage->BrowserStorage->Type != EFI_HII_VARSTORE_BUFFER) &&
- (Storage->BrowserStorage->Type != EFI_HII_VARSTORE_NAME_VALUE) &&
- (Storage->BrowserStorage->Type != EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER)) {
- continue;
- }
+ if (Storage->BrowserStorage->Type == EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER) {
+ if (Storage->ConfigRequest == NULL || Storage->BrowserStorage->ConfigRequest == NULL) {
+ continue;
+ }
- if (Storage->ConfigRequest == NULL || Storage->BrowserStorage->ConfigRequest == NULL) {
- continue;
+ ConfigRequest = FormSet->QuestionInited ? Storage->ConfigRequest : Storage->ConfigElements;
+ RemoveConfigRequest (Storage->BrowserStorage, ConfigRequest);
+ } else if (Storage->BrowserStorage->Type == EFI_HII_VARSTORE_BUFFER ||
+ Storage->BrowserStorage->Type == EFI_HII_VARSTORE_NAME_VALUE) {
+ if (Storage->BrowserStorage->ConfigRequest != NULL) {
+ FreePool (Storage->BrowserStorage->ConfigRequest);
+ }
+ Storage->BrowserStorage->Initialized = FALSE;
}
-
- ConfigRequest = FormSet->QuestionInited ? Storage->ConfigRequest : Storage->ConfigElements;
- RemoveConfigRequest (Storage->BrowserStorage, ConfigRequest);
}
}
@@ -4244,86 +4095,57 @@ LoadStorage (
ConfigRequestAdjust(Storage);
return;
}
-
- Status = gRT->GetVariable (
- Storage->BrowserStorage->Name,
- &Storage->BrowserStorage->Guid,
- NULL,
- (UINTN*)&Storage->BrowserStorage->Size,
- Storage->BrowserStorage->EditBuffer
- );
- //
- // If get variable fail, extract default from IFR binary
- //
- if (EFI_ERROR (Status)) {
- ExtractDefault (FormSet, NULL, EFI_HII_DEFAULT_CLASS_STANDARD, FormSetLevel, GetDefaultForStorage, Storage->BrowserStorage, TRUE);
- }
-
- Storage->BrowserStorage->ConfigRequest = AllocateCopyPool (StrSize (Storage->ConfigRequest), Storage->ConfigRequest);
- //
- // Input NULL for ConfigRequest field means sync all fields from editbuffer to buffer.
- //
- SynchronizeStorage(FormSet, Storage->BrowserStorage, NULL, TRUE);
break;
case EFI_HII_VARSTORE_BUFFER:
case EFI_HII_VARSTORE_NAME_VALUE:
//
- // Skip if there is no RequestElement
+ // Skip if there is no RequestElement or data has initilized.
//
- if (Storage->ElementCount == 0) {
+ if (Storage->ElementCount == 0 || Storage->BrowserStorage->Initialized) {
return;
}
+ Storage->BrowserStorage->Initialized = TRUE;
+ break;
- //
- // Adjust the ConfigRequest string, only the field not saved in BrowserStorage->AllConfig
- // will used to call ExtractConfig.
- // If not elements need to udpate, return.
- //
- if (!ConfigRequestAdjust(Storage)) {
- return;
- }
- ASSERT (Storage->ConfigElements != NULL);
+ default:
+ return;
+ }
- Status = EFI_NOT_FOUND;
- if (FormSet->ConfigAccess != NULL) {
- //
- // Request current settings from Configuration Driver
- //
- Status = FormSet->ConfigAccess->ExtractConfig (
- FormSet->ConfigAccess,
- Storage->ConfigElements,
- &Progress,
- &Result
- );
-
- if (!EFI_ERROR (Status)) {
- //
- // Convert Result from <ConfigAltResp> to <ConfigResp>
- //
- StrPtr = StrStr (Result, L"&GUID=");
- if (StrPtr != NULL) {
- *StrPtr = L'\0';
- }
-
- Status = ConfigRespToStorage (Storage->BrowserStorage, Result);
- FreePool (Result);
- }
- }
+ //
+ // Request current settings from Configuration Driver
+ //
+ Status = mHiiConfigRouting->ExtractConfig (
+ mHiiConfigRouting,
+ Storage->ConfigRequest,
+ &Progress,
+ &Result
+ );
- if (EFI_ERROR (Status)) {
- //
- // Base on the configRequest string to get default value.
- //
- GetDefaultForFormset (FormSet, Storage->BrowserStorage, Storage->ConfigElements);
- }
+ //
+ // If get value fail, extract default from IFR binary
+ //
+ if (EFI_ERROR (Status)) {
+ ExtractDefault (FormSet, NULL, EFI_HII_DEFAULT_CLASS_STANDARD, FormSetLevel, GetDefaultForStorage, Storage->BrowserStorage, TRUE);
+ } else {
+ //
+ // Convert Result from <ConfigAltResp> to <ConfigResp>
+ //
+ StrPtr = StrStr (Result, L"&GUID=");
+ if (StrPtr != NULL) {
+ *StrPtr = L'\0';
+ }
+
+ Status = ConfigRespToStorage (Storage->BrowserStorage, Result);
+ FreePool (Result);
+ }
- SynchronizeStorage(FormSet, Storage->BrowserStorage, Storage->ConfigElements, TRUE);
- break;
+ Storage->BrowserStorage->ConfigRequest = AllocateCopyPool (StrSize (Storage->ConfigRequest), Storage->ConfigRequest);
- default:
- break;
- }
+ //
+ // Input NULL for ConfigRequest field means sync all fields from editbuffer to buffer.
+ //
+ SynchronizeStorage(FormSet, Storage->BrowserStorage, NULL, TRUE);
}
/**
diff --git a/MdeModulePkg/Universal/SetupBrowserDxe/Setup.h b/MdeModulePkg/Universal/SetupBrowserDxe/Setup.h
index 77a0ad1ba..9cb4653c8 100644
--- a/MdeModulePkg/Universal/SetupBrowserDxe/Setup.h
+++ b/MdeModulePkg/Universal/SetupBrowserDxe/Setup.h
@@ -136,6 +136,9 @@ typedef struct {
UINT8 Type; // Storage type
+ BOOLEAN Initialized; // Whether this varstore is initialized, efi varstore not used.
+
+ EFI_HII_HANDLE HiiHandle; // HiiHandle for this varstore, efi varstore not used.
EFI_GUID Guid;
CHAR16 *Name; // For EFI_IFR_VARSTORE
@@ -1613,5 +1616,25 @@ VOID
CleanBrowserStorage (
IN OUT FORM_BROWSER_FORMSET *FormSet
);
-
+
+/**
+ Find HII Handle in the HII database associated with given Device Path.
+
+ If DevicePath is NULL, then ASSERT.
+
+ @param DevicePath Device Path associated with the HII package list
+ handle.
+ @param FormsetGuid The formset guid for this formset.
+
+ @retval Handle HII package list Handle associated with the Device
+ Path.
+ @retval NULL Hii Package list handle is not found.
+
+**/
+EFI_HII_HANDLE
+DevicePathToHiiHandle (
+ IN EFI_DEVICE_PATH_PROTOCOL *DevicePath,
+ IN EFI_GUID *FormsetGuid
+ );
+
#endif
diff --git a/MdeModulePkg/Universal/Variable/RuntimeDxe/Reclaim.c b/MdeModulePkg/Universal/Variable/RuntimeDxe/Reclaim.c
index 11bf1a02b..1732a0cd6 100644
--- a/MdeModulePkg/Universal/Variable/RuntimeDxe/Reclaim.c
+++ b/MdeModulePkg/Universal/Variable/RuntimeDxe/Reclaim.c
@@ -3,7 +3,7 @@
Handles non-volatile variable store garbage collection, using FTW
(Fault Tolerant Write) protocol.
-Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>
+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
@@ -99,8 +99,7 @@ GetLbaAndOffsetByAddress (
VariableBase. Fault Tolerant Write protocol is used for writing.
@param VariableBase Base address of variable to write
- @param Buffer Point to the data buffer.
- @param BufferSize The number of bytes of the data Buffer.
+ @param VariableBuffer Point to the variable data buffer.
@retval EFI_SUCCESS The function completed successfully.
@retval EFI_NOT_FOUND Fail to locate Fault Tolerant Write protocol.
@@ -110,15 +109,13 @@ GetLbaAndOffsetByAddress (
EFI_STATUS
FtwVariableSpace (
IN EFI_PHYSICAL_ADDRESS VariableBase,
- IN UINT8 *Buffer,
- IN UINTN BufferSize
+ IN VARIABLE_STORE_HEADER *VariableBuffer
)
{
EFI_STATUS Status;
EFI_HANDLE FvbHandle;
EFI_LBA VarLba;
UINTN VarOffset;
- UINT8 *FtwBuffer;
UINTN FtwBufferSize;
EFI_FAULT_TOLERANT_WRITE_PROTOCOL *FtwProtocol;
@@ -143,17 +140,9 @@ FtwVariableSpace (
if (EFI_ERROR (Status)) {
return EFI_ABORTED;
}
- //
- // Prepare for the variable data.
- //
- FtwBufferSize = ((VARIABLE_STORE_HEADER *) ((UINTN) VariableBase))->Size;
- FtwBuffer = AllocatePool (FtwBufferSize);
- if (FtwBuffer == NULL) {
- return EFI_OUT_OF_RESOURCES;
- }
- SetMem (FtwBuffer, FtwBufferSize, (UINT8) 0xff);
- CopyMem (FtwBuffer, Buffer, BufferSize);
+ FtwBufferSize = ((VARIABLE_STORE_HEADER *) ((UINTN) VariableBase))->Size;
+ ASSERT (FtwBufferSize == VariableBuffer->Size);
//
// FTW write record.
@@ -165,9 +154,8 @@ FtwVariableSpace (
FtwBufferSize, // NumBytes
NULL, // PrivateData NULL
FvbHandle, // Fvb Handle
- FtwBuffer // write buffer
+ (VOID *) VariableBuffer // write buffer
);
- FreePool (FtwBuffer);
return Status;
}
diff --git a/MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.c b/MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.c
index 51dd0fd6f..c66eb8750 100644
--- a/MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.c
+++ b/MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.c
@@ -566,7 +566,8 @@ GetEndPointer (
@param IsVolatile The variable store is volatile or not;
if it is non-volatile, need FTW.
@param UpdatingPtrTrack Pointer to updating variable pointer track structure.
- @param ReclaimAnyway If TRUE, do reclaim anyway.
+ @param NewVariable Pointer to new variable.
+ @param NewVariableSize New variable size.
@return EFI_OUT_OF_RESOURCES
@return EFI_SUCCESS
@@ -579,7 +580,8 @@ Reclaim (
OUT UINTN *LastVariableOffset,
IN BOOLEAN IsVolatile,
IN OUT VARIABLE_POINTER_TRACK *UpdatingPtrTrack,
- IN BOOLEAN ReclaimAnyway
+ IN VARIABLE_HEADER *NewVariable,
+ IN UINTN NewVariableSize
)
{
VARIABLE_HEADER *Variable;
@@ -590,65 +592,72 @@ Reclaim (
UINT8 *ValidBuffer;
UINTN MaximumBufferSize;
UINTN VariableSize;
- UINTN VariableNameSize;
- UINTN UpdatingVariableNameSize;
UINTN NameSize;
UINT8 *CurrPtr;
VOID *Point0;
VOID *Point1;
BOOLEAN FoundAdded;
EFI_STATUS Status;
- CHAR16 *VariableNamePtr;
- CHAR16 *UpdatingVariableNamePtr;
UINTN CommonVariableTotalSize;
UINTN HwErrVariableTotalSize;
- BOOLEAN NeedDoReclaim;
VARIABLE_HEADER *UpdatingVariable;
+ VARIABLE_HEADER *UpdatingInDeletedTransition;
UpdatingVariable = NULL;
+ UpdatingInDeletedTransition = NULL;
if (UpdatingPtrTrack != NULL) {
UpdatingVariable = UpdatingPtrTrack->CurrPtr;
+ UpdatingInDeletedTransition = UpdatingPtrTrack->InDeletedTransitionPtr;
}
- NeedDoReclaim = FALSE;
VariableStoreHeader = (VARIABLE_STORE_HEADER *) ((UINTN) VariableBase);
CommonVariableTotalSize = 0;
HwErrVariableTotalSize = 0;
- //
- // Start Pointers for the variable.
- //
- Variable = GetStartPointer (VariableStoreHeader);
- MaximumBufferSize = sizeof (VARIABLE_STORE_HEADER);
+ if (IsVolatile) {
+ //
+ // Start Pointers for the variable.
+ //
+ Variable = GetStartPointer (VariableStoreHeader);
+ MaximumBufferSize = sizeof (VARIABLE_STORE_HEADER);
- while (IsValidVariableHeader (Variable)) {
- NextVariable = GetNextVariablePtr (Variable);
- if (Variable->State == VAR_ADDED ||
- Variable->State == (VAR_IN_DELETED_TRANSITION & VAR_ADDED)
- ) {
- VariableSize = (UINTN) NextVariable - (UINTN) Variable;
- MaximumBufferSize += VariableSize;
- } else {
- NeedDoReclaim = TRUE;
- }
+ while (IsValidVariableHeader (Variable)) {
+ NextVariable = GetNextVariablePtr (Variable);
+ if ((Variable->State == VAR_ADDED || Variable->State == (VAR_IN_DELETED_TRANSITION & VAR_ADDED)) &&
+ Variable != UpdatingVariable &&
+ Variable != UpdatingInDeletedTransition
+ ) {
+ VariableSize = (UINTN) NextVariable - (UINTN) Variable;
+ MaximumBufferSize += VariableSize;
+ }
- Variable = NextVariable;
- }
+ Variable = NextVariable;
+ }
- if (!ReclaimAnyway && !NeedDoReclaim) {
- DEBUG ((EFI_D_INFO, "Variable driver: no DELETED variable found, so no variable space could be reclaimed.\n"));
- return EFI_SUCCESS;
- }
+ if (NewVariable != NULL) {
+ //
+ // Add the new variable size.
+ //
+ MaximumBufferSize += NewVariableSize;
+ }
- //
- // Reserve the 1 Bytes with Oxff to identify the
- // end of the variable buffer.
- //
- MaximumBufferSize += 1;
- ValidBuffer = AllocatePool (MaximumBufferSize);
- if (ValidBuffer == NULL) {
- return EFI_OUT_OF_RESOURCES;
+ //
+ // Reserve the 1 Bytes with Oxff to identify the
+ // end of the variable buffer.
+ //
+ MaximumBufferSize += 1;
+ ValidBuffer = AllocatePool (MaximumBufferSize);
+ if (ValidBuffer == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+ } else {
+ //
+ // For NV variable reclaim, don't allocate pool here and just use mNvVariableCache
+ // as the buffer to reduce SMRAM consumption for SMM variable driver.
+ //
+ MaximumBufferSize = mNvVariableCache->Size;
+ ValidBuffer = (UINT8 *) mNvVariableCache;
}
SetMem (ValidBuffer, MaximumBufferSize, 0xff);
@@ -665,25 +674,7 @@ Reclaim (
Variable = GetStartPointer (VariableStoreHeader);
while (IsValidVariableHeader (Variable)) {
NextVariable = GetNextVariablePtr (Variable);
- if (Variable->State == VAR_ADDED) {
- if (UpdatingVariable != NULL) {
- if (UpdatingVariable == Variable) {
- Variable = NextVariable;
- continue;
- }
-
- VariableNameSize = NameSizeOfVariable(Variable);
- UpdatingVariableNameSize = NameSizeOfVariable(UpdatingVariable);
-
- VariableNamePtr = GetVariableNamePtr (Variable);
- UpdatingVariableNamePtr = GetVariableNamePtr (UpdatingVariable);
- if (CompareGuid (&Variable->VendorGuid, &UpdatingVariable->VendorGuid) &&
- VariableNameSize == UpdatingVariableNameSize &&
- CompareMem (VariableNamePtr, UpdatingVariableNamePtr, VariableNameSize) == 0 ) {
- Variable = NextVariable;
- continue;
- }
- }
+ if (Variable != UpdatingVariable && Variable->State == VAR_ADDED) {
VariableSize = (UINTN) NextVariable - (UINTN) Variable;
CopyMem (CurrPtr, (UINT8 *) Variable, VariableSize);
CurrPtr += VariableSize;
@@ -697,28 +688,12 @@ Reclaim (
}
//
- // Reinstall the variable being updated if it is not NULL.
- //
- if (UpdatingVariable != NULL) {
- VariableSize = (UINTN)(GetNextVariablePtr (UpdatingVariable)) - (UINTN)UpdatingVariable;
- CopyMem (CurrPtr, (UINT8 *) UpdatingVariable, VariableSize);
- UpdatingPtrTrack->CurrPtr = (VARIABLE_HEADER *)((UINTN)UpdatingPtrTrack->StartPtr + ((UINTN)CurrPtr - (UINTN)GetStartPointer ((VARIABLE_STORE_HEADER *) ValidBuffer)));
- UpdatingPtrTrack->InDeletedTransitionPtr = NULL;
- CurrPtr += VariableSize;
- if ((!IsVolatile) && ((UpdatingVariable->Attributes & EFI_VARIABLE_HARDWARE_ERROR_RECORD) == EFI_VARIABLE_HARDWARE_ERROR_RECORD)) {
- HwErrVariableTotalSize += VariableSize;
- } else if ((!IsVolatile) && ((UpdatingVariable->Attributes & EFI_VARIABLE_HARDWARE_ERROR_RECORD) != EFI_VARIABLE_HARDWARE_ERROR_RECORD)) {
- CommonVariableTotalSize += VariableSize;
- }
- }
-
- //
// Reinstall all in delete transition variables.
//
- Variable = GetStartPointer (VariableStoreHeader);
+ Variable = GetStartPointer (VariableStoreHeader);
while (IsValidVariableHeader (Variable)) {
NextVariable = GetNextVariablePtr (Variable);
- if (Variable != UpdatingVariable && Variable->State == (VAR_IN_DELETED_TRANSITION & VAR_ADDED)) {
+ if (Variable != UpdatingVariable && Variable != UpdatingInDeletedTransition && Variable->State == (VAR_IN_DELETED_TRANSITION & VAR_ADDED)) {
//
// Buffer has cached all ADDED variable.
@@ -762,12 +737,49 @@ Reclaim (
Variable = NextVariable;
}
+ //
+ // Install the new variable if it is not NULL.
+ //
+ if (NewVariable != NULL) {
+ if ((UINTN) (CurrPtr - ValidBuffer) + NewVariableSize > VariableStoreHeader->Size) {
+ //
+ // No enough space to store the new variable.
+ //
+ Status = EFI_OUT_OF_RESOURCES;
+ goto Done;
+ }
+ if (!IsVolatile) {
+ if ((NewVariable->Attributes & EFI_VARIABLE_HARDWARE_ERROR_RECORD) == EFI_VARIABLE_HARDWARE_ERROR_RECORD) {
+ HwErrVariableTotalSize += NewVariableSize;
+ } else if ((NewVariable->Attributes & EFI_VARIABLE_HARDWARE_ERROR_RECORD) != EFI_VARIABLE_HARDWARE_ERROR_RECORD) {
+ CommonVariableTotalSize += NewVariableSize;
+ }
+ if ((HwErrVariableTotalSize > PcdGet32 (PcdHwErrStorageSize)) ||
+ (CommonVariableTotalSize > VariableStoreHeader->Size - sizeof (VARIABLE_STORE_HEADER) - PcdGet32 (PcdHwErrStorageSize))) {
+ //
+ // No enough space to store the new variable by NV or NV+HR attribute.
+ //
+ Status = EFI_OUT_OF_RESOURCES;
+ goto Done;
+ }
+ }
+
+ CopyMem (CurrPtr, (UINT8 *) NewVariable, NewVariableSize);
+ ((VARIABLE_HEADER *) CurrPtr)->State = VAR_ADDED;
+ if (UpdatingVariable != NULL) {
+ UpdatingPtrTrack->CurrPtr = (VARIABLE_HEADER *)((UINTN)UpdatingPtrTrack->StartPtr + ((UINTN)CurrPtr - (UINTN)GetStartPointer ((VARIABLE_STORE_HEADER *) ValidBuffer)));
+ UpdatingPtrTrack->InDeletedTransitionPtr = NULL;
+ }
+ CurrPtr += NewVariableSize;
+ }
+
if (IsVolatile) {
//
// If volatile variable store, just copy valid buffer.
//
SetMem ((UINT8 *) (UINTN) VariableBase, VariableStoreHeader->Size, 0xff);
- CopyMem ((UINT8 *) (UINTN) VariableBase, ValidBuffer, (UINTN) (CurrPtr - (UINT8 *) ValidBuffer));
+ CopyMem ((UINT8 *) (UINTN) VariableBase, ValidBuffer, (UINTN) (CurrPtr - ValidBuffer));
+ *LastVariableOffset = (UINTN) (CurrPtr - ValidBuffer);
Status = EFI_SUCCESS;
} else {
//
@@ -775,33 +787,37 @@ Reclaim (
//
Status = FtwVariableSpace (
VariableBase,
- ValidBuffer,
- (UINTN) (CurrPtr - (UINT8 *) ValidBuffer)
+ (VARIABLE_STORE_HEADER *) ValidBuffer
);
- CopyMem (mNvVariableCache, (CHAR8 *)(UINTN)VariableBase, VariableStoreHeader->Size);
- }
- if (!EFI_ERROR (Status)) {
- *LastVariableOffset = (UINTN) (CurrPtr - (UINT8 *) ValidBuffer);
- if (!IsVolatile) {
+ if (!EFI_ERROR (Status)) {
+ *LastVariableOffset = (UINTN) (CurrPtr - ValidBuffer);
mVariableModuleGlobal->HwErrVariableTotalSize = HwErrVariableTotalSize;
mVariableModuleGlobal->CommonVariableTotalSize = CommonVariableTotalSize;
- }
- } else {
- NextVariable = GetStartPointer ((VARIABLE_STORE_HEADER *)(UINTN)VariableBase);
- while (IsValidVariableHeader (NextVariable)) {
- VariableSize = NextVariable->NameSize + NextVariable->DataSize + sizeof (VARIABLE_HEADER);
- if ((!IsVolatile) && ((Variable->Attributes & EFI_VARIABLE_HARDWARE_ERROR_RECORD) == EFI_VARIABLE_HARDWARE_ERROR_RECORD)) {
- mVariableModuleGlobal->HwErrVariableTotalSize += HEADER_ALIGN (VariableSize);
- } else if ((!IsVolatile) && ((Variable->Attributes & EFI_VARIABLE_HARDWARE_ERROR_RECORD) != EFI_VARIABLE_HARDWARE_ERROR_RECORD)) {
- mVariableModuleGlobal->CommonVariableTotalSize += HEADER_ALIGN (VariableSize);
- }
+ } else {
+ NextVariable = GetStartPointer ((VARIABLE_STORE_HEADER *)(UINTN)VariableBase);
+ while (IsValidVariableHeader (NextVariable)) {
+ VariableSize = NextVariable->NameSize + NextVariable->DataSize + sizeof (VARIABLE_HEADER);
+ if ((Variable->Attributes & EFI_VARIABLE_HARDWARE_ERROR_RECORD) == EFI_VARIABLE_HARDWARE_ERROR_RECORD) {
+ mVariableModuleGlobal->HwErrVariableTotalSize += HEADER_ALIGN (VariableSize);
+ } else if ((Variable->Attributes & EFI_VARIABLE_HARDWARE_ERROR_RECORD) != EFI_VARIABLE_HARDWARE_ERROR_RECORD) {
+ mVariableModuleGlobal->CommonVariableTotalSize += HEADER_ALIGN (VariableSize);
+ }
- NextVariable = GetNextVariablePtr (NextVariable);
+ NextVariable = GetNextVariablePtr (NextVariable);
+ }
+ *LastVariableOffset = (UINTN) NextVariable - (UINTN) VariableBase;
}
- *LastVariableOffset = (UINTN) NextVariable - (UINTN) VariableBase;
}
- FreePool (ValidBuffer);
+Done:
+ if (IsVolatile) {
+ FreePool (ValidBuffer);
+ } else {
+ //
+ // For NV variable reclaim, we use mNvVariableCache as the buffer, so copy the data back.
+ //
+ CopyMem (mNvVariableCache, (UINT8 *)(UINTN)VariableBase, VariableStoreHeader->Size);
+ }
return Status;
}
@@ -1706,27 +1722,22 @@ UpdateVariable (
goto Done;
}
//
- // Perform garbage collection & reclaim operation.
+ // Perform garbage collection & reclaim operation, and integrate the new variable at the same time.
//
Status = Reclaim (mVariableModuleGlobal->VariableGlobal.NonVolatileVariableBase,
- &mVariableModuleGlobal->NonVolatileLastVariableOffset, FALSE, Variable, FALSE);
- if (EFI_ERROR (Status)) {
- goto Done;
- }
- //
- // If still no enough space, return out of resources.
- //
- if ((((Attributes & EFI_VARIABLE_HARDWARE_ERROR_RECORD) != 0)
- && ((VarSize + mVariableModuleGlobal->HwErrVariableTotalSize) > PcdGet32 (PcdHwErrStorageSize)))
- || (((Attributes & EFI_VARIABLE_HARDWARE_ERROR_RECORD) == 0)
- && ((VarSize + mVariableModuleGlobal->CommonVariableTotalSize) > NonVolatileVarableStoreSize - sizeof (VARIABLE_STORE_HEADER) - PcdGet32 (PcdHwErrStorageSize)))) {
- Status = EFI_OUT_OF_RESOURCES;
- goto Done;
- }
- if (Variable->CurrPtr != NULL) {
- CacheVariable->CurrPtr = (VARIABLE_HEADER *)((UINTN) CacheVariable->StartPtr + ((UINTN) Variable->CurrPtr - (UINTN) Variable->StartPtr));
- CacheVariable->InDeletedTransitionPtr = NULL;
+ &mVariableModuleGlobal->NonVolatileLastVariableOffset, FALSE, Variable, NextVariable, HEADER_ALIGN (VarSize));
+ if (!EFI_ERROR (Status)) {
+ //
+ // The new variable has been integrated successfully during reclaiming.
+ //
+ if (Variable->CurrPtr != NULL) {
+ CacheVariable->CurrPtr = (VARIABLE_HEADER *)((UINTN) CacheVariable->StartPtr + ((UINTN) Variable->CurrPtr - (UINTN) Variable->StartPtr));
+ CacheVariable->InDeletedTransitionPtr = NULL;
+ }
+ UpdateVariableInfo (VariableName, VendorGuid, FALSE, FALSE, TRUE, FALSE, FALSE);
+ FlushHobVariableToFlash (VariableName, VendorGuid);
}
+ goto Done;
}
//
// Four steps
@@ -1824,26 +1835,21 @@ UpdateVariable (
if ((UINT32) (VarSize + mVariableModuleGlobal->VolatileLastVariableOffset) >
((VARIABLE_STORE_HEADER *) ((UINTN) (mVariableModuleGlobal->VariableGlobal.VolatileVariableBase)))->Size) {
//
- // Perform garbage collection & reclaim operation.
+ // Perform garbage collection & reclaim operation, and integrate the new variable at the same time.
//
Status = Reclaim (mVariableModuleGlobal->VariableGlobal.VolatileVariableBase,
- &mVariableModuleGlobal->VolatileLastVariableOffset, TRUE, Variable, FALSE);
- if (EFI_ERROR (Status)) {
- goto Done;
- }
- //
- // If still no enough space, return out of resources.
- //
- if ((UINT32) (VarSize + mVariableModuleGlobal->VolatileLastVariableOffset) >
- ((VARIABLE_STORE_HEADER *) ((UINTN) (mVariableModuleGlobal->VariableGlobal.VolatileVariableBase)))->Size
- ) {
- Status = EFI_OUT_OF_RESOURCES;
- goto Done;
- }
- if (Variable->CurrPtr != NULL) {
- CacheVariable->CurrPtr = (VARIABLE_HEADER *)((UINTN) CacheVariable->StartPtr + ((UINTN) Variable->CurrPtr - (UINTN) Variable->StartPtr));
- CacheVariable->InDeletedTransitionPtr = NULL;
+ &mVariableModuleGlobal->VolatileLastVariableOffset, TRUE, Variable, NextVariable, HEADER_ALIGN (VarSize));
+ if (!EFI_ERROR (Status)) {
+ //
+ // The new variable has been integrated successfully during reclaiming.
+ //
+ if (Variable->CurrPtr != NULL) {
+ CacheVariable->CurrPtr = (VARIABLE_HEADER *)((UINTN) CacheVariable->StartPtr + ((UINTN) Variable->CurrPtr - (UINTN) Variable->StartPtr));
+ CacheVariable->InDeletedTransitionPtr = NULL;
+ }
+ UpdateVariableInfo (VariableName, VendorGuid, TRUE, FALSE, TRUE, FALSE, FALSE);
}
+ goto Done;
}
NextVariable->State = VAR_ADDED;
@@ -2693,7 +2699,8 @@ ReclaimForOS(
&mVariableModuleGlobal->NonVolatileLastVariableOffset,
FALSE,
NULL,
- FALSE
+ NULL,
+ 0
);
ASSERT_EFI_ERROR (Status);
}
@@ -2963,7 +2970,8 @@ VariableWriteServiceInitialize (
&mVariableModuleGlobal->NonVolatileLastVariableOffset,
FALSE,
NULL,
- TRUE
+ NULL,
+ 0
);
if (EFI_ERROR (Status)) {
return Status;
diff --git a/MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.h b/MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.h
index a10ad8755..9c8626cdc 100644
--- a/MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.h
+++ b/MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.h
@@ -133,8 +133,7 @@ FlushHobVariableToFlash (
VariableBase. Fault Tolerant Write protocol is used for writing.
@param VariableBase Base address of the variable to write.
- @param Buffer Point to the data buffer.
- @param BufferSize The number of bytes of the data Buffer.
+ @param VariableBuffer Point to the variable data buffer.
@retval EFI_SUCCESS The function completed successfully.
@retval EFI_NOT_FOUND Fail to locate Fault Tolerant Write protocol.
@@ -144,8 +143,7 @@ FlushHobVariableToFlash (
EFI_STATUS
FtwVariableSpace (
IN EFI_PHYSICAL_ADDRESS VariableBase,
- IN UINT8 *Buffer,
- IN UINTN BufferSize
+ IN VARIABLE_STORE_HEADER *VariableBuffer
);
diff --git a/MdePkg/Include/Guid/VectorHandoffTable.h b/MdePkg/Include/Guid/VectorHandoffTable.h
new file mode 100644
index 000000000..a3b3a95e8
--- /dev/null
+++ b/MdePkg/Include/Guid/VectorHandoffTable.h
@@ -0,0 +1,33 @@
+/** @file
+ GUID for system configuration table entry that points to the table
+ in case an entity in DXE wishes to update/change the vector table contents.
+
+ Copyright (c) 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.
+
+ @par Revision Reference:
+ GUID defined in PI 1.2.1 spec.
+**/
+
+#ifndef __EFI_VECTOR_HANDOFF_TABLE_H__
+#define __EFI_VECTOR_HANDOFF_TABLE_H__
+
+#include <Ppi/VectorHandoffInfo.h>
+
+//
+// System configuration table entry that points to the table
+// in case an entity in DXE wishes to update/change the vector
+// table contents.
+//
+#define EFI_VECTOR_HANDOF_TABLE_GUID \
+ { 0x996ec11c, 0x5397, 0x4e73, { 0xb5, 0x8f, 0x82, 0x7e, 0x52, 0x90, 0x6d, 0xef }}
+
+extern EFI_GUID gEfiVectorHandoffTableGuid;
+
+#endif
diff --git a/MdePkg/Include/Library/PcdLib.h b/MdePkg/Include/Library/PcdLib.h
index 8deb6f758..1ea4ac7ce 100644
--- a/MdePkg/Include/Library/PcdLib.h
+++ b/MdePkg/Include/Library/PcdLib.h
@@ -14,7 +14,7 @@
There are no restrictions on the use of FeaturePcd(), FixedPcdGetXX(),
PatchPcdGetXX(), and PatchPcdSetXX().
-Copyright (c) 2006 - 2008, Intel Corporation. All rights reserved.<BR>
+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
@@ -533,6 +533,20 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
/**
+ Retrieves a token number based on a GUID and a token name.
+
+ Returns the token number for the token specified by Guid and TokenName.
+
+ @param Guid Pointer to a 128-bit unique value that designates
+ which namespace to retrieve a value from.
+ @param TokenName The name of the PCD token to retrieve a current value for.
+
+ @return Return the token number.
+
+**/
+#define PcdTokenEx(Guid,TokenName) _PCD_TOKEN_EX_##TokenName(Guid)
+
+/**
Retrieves an 8-bit PCD token value based on a GUID and a token name.
Returns the 8-bit value for the token specified by Guid and TokenName.
@@ -548,8 +562,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
@return An 8-bit PCD token value.
**/
-#define PcdGetEx8(Guid, TokenName) LibPcdGetEx8 ((Guid), _PCD_TOKEN_##TokenName)
-
+#define PcdGetEx8(Guid, TokenName) LibPcdGetEx8 ((Guid), PcdTokenEx(Guid,TokenName))
/**
Retrieves a 16-bit PCD token value based on a GUID and a token name.
@@ -567,7 +580,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
@return A 16-bit PCD token value.
**/
-#define PcdGetEx16(Guid, TokenName) LibPcdGetEx16 ((Guid), _PCD_TOKEN_##TokenName)
+#define PcdGetEx16(Guid, TokenName) LibPcdGetEx16 ((Guid), PcdTokenEx(Guid,TokenName))
/**
@@ -586,7 +599,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
@return A 32-bit PCD token value.
**/
-#define PcdGetEx32(Guid, TokenName) LibPcdGetEx32 ((Guid), _PCD_TOKEN_##TokenName)
+#define PcdGetEx32(Guid, TokenName) LibPcdGetEx32 ((Guid), PcdTokenEx(Guid,TokenName))
/**
@@ -605,7 +618,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
@return A 64-bit PCD token value.
**/
-#define PcdGetEx64(Guid, TokenName) LibPcdGetEx64 ((Guid), _PCD_TOKEN_##TokenName)
+#define PcdGetEx64(Guid, TokenName) LibPcdGetEx64 ((Guid), PcdTokenEx(Guid,TokenName))
/**
@@ -624,7 +637,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
@return A pointer to a PCD token buffer.
**/
-#define PcdGetExPtr(Guid, TokenName) LibPcdGetExPtr ((Guid), _PCD_TOKEN_##TokenName)
+#define PcdGetExPtr(Guid, TokenName) LibPcdGetExPtr ((Guid), PcdTokenEx(Guid,TokenName))
/**
@@ -643,7 +656,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
@return A Boolean PCD token value.
**/
-#define PcdGetExBool(Guid, TokenName) LibPcdGetExBool ((Guid), _PCD_TOKEN_##TokenName)
+#define PcdGetExBool(Guid, TokenName) LibPcdGetExBool ((Guid), PcdTokenEx(Guid,TokenName))
/**
@@ -663,7 +676,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
@return Return the Value that was set.
**/
-#define PcdSetEx8(Guid, TokenName, Value) LibPcdSetEx8 ((Guid), _PCD_TOKEN_##TokenName, (Value))
+#define PcdSetEx8(Guid, TokenName, Value) LibPcdSetEx8 ((Guid), PcdTokenEx(Guid,TokenName), (Value))
/**
@@ -683,7 +696,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
@return Return the Value that was set.
**/
-#define PcdSetEx16(Guid, TokenName, Value) LibPcdSetEx16 ((Guid), _PCD_TOKEN_##TokenName, (Value))
+#define PcdSetEx16(Guid, TokenName, Value) LibPcdSetEx16 ((Guid), PcdTokenEx(Guid,TokenName), (Value))
/**
@@ -703,7 +716,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
@return Return the Value that was set.
**/
-#define PcdSetEx32(Guid, TokenName, Value) LibPcdSetEx32 ((Guid), _PCD_TOKEN_##TokenName, (Value))
+#define PcdSetEx32(Guid, TokenName, Value) LibPcdSetEx32 ((Guid), PcdTokenEx(Guid,TokenName), (Value))
/**
@@ -723,7 +736,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
@return Return the Value that was set.
**/
-#define PcdSetEx64(Guid, TokenName, Value) LibPcdSetEx64 ((Guid), _PCD_TOKEN_##TokenName, (Value))
+#define PcdSetEx64(Guid, TokenName, Value) LibPcdSetEx64 ((Guid), PcdTokenEx(Guid,TokenName), (Value))
/**
@@ -752,7 +765,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#define PcdSetExPtr(Guid, TokenName, SizeOfBuffer, Buffer) \
- LibPcdSetExPtr ((Guid), _PCD_TOKEN_##TokenName, (SizeOfBuffer), (Buffer))
+ LibPcdSetExPtr ((Guid), PcdTokenEx(Guid,TokenName), (SizeOfBuffer), (Buffer))
/**
@@ -773,7 +786,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#define PcdSetExBool(Guid, TokenName, Value) \
- LibPcdSetExBool((Guid), _PCD_TOKEN_##TokenName, (Value))
+ LibPcdSetExBool((Guid), PcdTokenEx(Guid,TokenName), (Value))
/**
@@ -1503,4 +1516,89 @@ LibPatchPcdSetPtr (
IN CONST VOID *Buffer
);
+typedef enum {
+ PCD_TYPE_8,
+ PCD_TYPE_16,
+ PCD_TYPE_32,
+ PCD_TYPE_64,
+ PCD_TYPE_BOOL,
+ PCD_TYPE_PTR
+} PCD_TYPE;
+
+typedef struct {
+ ///
+ /// The returned information associated with the requested TokenNumber. If
+ /// TokenNumber is 0, then PcdType is set to PCD_TYPE_8.
+ ///
+ PCD_TYPE PcdType;
+ ///
+ /// The size of the data in bytes associated with the TokenNumber specified. If
+ /// TokenNumber is 0, then PcdSize is set 0.
+ ///
+ UINTN PcdSize;
+ ///
+ /// The null-terminated ASCII string associated with a given token. If the
+ /// TokenNumber specified was 0, then this field corresponds to the null-terminated
+ /// ASCII string associated with the token's namespace Guid. If NULL, there is no
+ /// name associated with this request.
+ ///
+ CHAR8 *PcdName;
+} PCD_INFO;
+
+
+/**
+ Retrieve additional information associated with a PCD token.
+
+ This includes information such as the type of value the TokenNumber is associated with as well as possible
+ human readable name that is associated with the token.
+
+ If TokenNumber is not in the default token space specified, then ASSERT().
+
+ @param[in] TokenNumber The PCD token number.
+ @param[out] PcdInfo The returned information associated with the requested TokenNumber.
+ The caller is responsible for freeing the buffer that is allocated by callee for PcdInfo->PcdName.
+**/
+VOID
+EFIAPI
+LibPcdGetInfo (
+ IN UINTN TokenNumber,
+ OUT PCD_INFO *PcdInfo
+ );
+
+/**
+ Retrieve additional information associated with a PCD token.
+
+ This includes information such as the type of value the TokenNumber is associated with as well as possible
+ human readable name that is associated with the token.
+
+ If TokenNumber is not in the token space specified by Guid, then ASSERT().
+
+ @param[in] Guid The 128-bit unique value that designates the namespace from which to extract the value.
+ @param[in] TokenNumber The PCD token number.
+ @param[out] PcdInfo The returned information associated with the requested TokenNumber.
+ The caller is responsible for freeing the buffer that is allocated by callee for PcdInfo->PcdName.
+**/
+VOID
+EFIAPI
+LibPcdGetInfoEx (
+ IN CONST GUID *Guid,
+ IN UINTN TokenNumber,
+ OUT PCD_INFO *PcdInfo
+ );
+
+/**
+ Retrieve the currently set SKU Id.
+
+ If the sku id got >= PCD_MAX_SKU_ID, then ASSERT().
+
+ @return The currently set SKU Id. If the platform has not set at a SKU Id, then the
+ default SKU Id value of 0 is returned. If the platform has set a SKU Id, then the currently set SKU
+ Id is returned.
+**/
+UINTN
+EFIAPI
+LibPcdGetSku (
+ VOID
+ );
+
#endif
diff --git a/MdePkg/Include/Pi/PiDxeCis.h b/MdePkg/Include/Pi/PiDxeCis.h
index caed14bd8..9bcfecc04 100644
--- a/MdePkg/Include/Pi/PiDxeCis.h
+++ b/MdePkg/Include/Pi/PiDxeCis.h
@@ -1,7 +1,7 @@
/** @file
Include file matches things in PI.
-Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>
+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 that accompanies this distribution.
The full text of the license may be found at
@@ -657,7 +657,7 @@ EFI_STATUS
//
#define DXE_SERVICES_SIGNATURE 0x565245535f455844ULL
#define DXE_SPECIFICATION_MAJOR_REVISION 1
-#define DXE_SPECIFICATION_MINOR_REVISION 20
+#define DXE_SPECIFICATION_MINOR_REVISION 30
#define DXE_SERVICES_REVISION ((DXE_SPECIFICATION_MAJOR_REVISION<<16) | (DXE_SPECIFICATION_MINOR_REVISION))
typedef struct {
diff --git a/MdePkg/Include/Pi/PiMultiPhase.h b/MdePkg/Include/Pi/PiMultiPhase.h
index 5a06966a9..2aa4c276c 100644
--- a/MdePkg/Include/Pi/PiMultiPhase.h
+++ b/MdePkg/Include/Pi/PiMultiPhase.h
@@ -1,7 +1,7 @@
/** @file
Include file matches things in PI for multiple module types.
-Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>
+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 that accompanies this distribution.
The full text of the license may be found at
@@ -133,4 +133,33 @@ typedef struct {
UINT64 RegionState;
} EFI_SMRAM_DESCRIPTOR;
+typedef enum {
+ EFI_PCD_TYPE_8,
+ EFI_PCD_TYPE_16,
+ EFI_PCD_TYPE_32,
+ EFI_PCD_TYPE_64,
+ EFI_PCD_TYPE_BOOL,
+ EFI_PCD_TYPE_PTR
+} EFI_PCD_TYPE;
+
+typedef struct {
+ ///
+ /// The returned information associated with the requested TokenNumber. If
+ /// TokenNumber is 0, then PcdType is set to EFI_PCD_TYPE_8.
+ ///
+ EFI_PCD_TYPE PcdType;
+ ///
+ /// The size of the data in bytes associated with the TokenNumber specified. If
+ /// TokenNumber is 0, then PcdSize is set 0.
+ ///
+ UINTN PcdSize;
+ ///
+ /// The null-terminated ASCII string associated with a given token. If the
+ /// TokenNumber specified was 0, then this field corresponds to the null-terminated
+ /// ASCII string associated with the token's namespace Guid. If NULL, there is no
+ /// name associated with this request.
+ ///
+ CHAR8 *PcdName;
+} EFI_PCD_INFO;
+
#endif
diff --git a/MdePkg/Include/Pi/PiPeiCis.h b/MdePkg/Include/Pi/PiPeiCis.h
index f2da20a23..75accf9f0 100644
--- a/MdePkg/Include/Pi/PiPeiCis.h
+++ b/MdePkg/Include/Pi/PiPeiCis.h
@@ -808,7 +808,7 @@ EFI_STATUS
// PEI Specification Revision information
//
#define PEI_SPECIFICATION_MAJOR_REVISION 1
-#define PEI_SPECIFICATION_MINOR_REVISION 20
+#define PEI_SPECIFICATION_MINOR_REVISION 30
///
/// Specification inconsistency here:
/// In the PI1.0 spec, PEI_SERVICES_SIGNATURE is defined as 0x5652455320494550. But
diff --git a/MdePkg/Include/Pi/PiSmmCis.h b/MdePkg/Include/Pi/PiSmmCis.h
index 29e5e9067..011127a76 100644
--- a/MdePkg/Include/Pi/PiSmmCis.h
+++ b/MdePkg/Include/Pi/PiSmmCis.h
@@ -2,7 +2,7 @@
Common definitions in the Platform Initialization Specification version 1.2
VOLUME 4 System Management Mode Core Interface version.
- Copyright (c) 2009 - 2012, Intel Corporation. All rights reserved.<BR>
+ Copyright (c) 2009 - 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
@@ -29,7 +29,7 @@ typedef struct _EFI_SMM_SYSTEM_TABLE2 EFI_SMM_SYSTEM_TABLE2;
/// The System Management System Table (SMST) revision is 1.2
///
#define SMM_SPECIFICATION_MAJOR_REVISION 1
-#define SMM_SPECIFICATION_MINOR_REVISION 20
+#define SMM_SPECIFICATION_MINOR_REVISION 30
#define EFI_SMM_SYSTEM_TABLE2_REVISION ((SMM_SPECIFICATION_MAJOR_REVISION<<16) | (SMM_SPECIFICATION_MINOR_REVISION))
/**
@@ -106,6 +106,7 @@ EFI_STATUS
The SmmRegisterProtocolNotify() function creates a registration Function that is to be
called whenever a protocol interface is installed for Protocol by
SmmInstallProtocolInterface().
+ If Function == NULL and Registration is an existing registration, then the callback is unhooked.
@param[in] Protocol The unique ID of the protocol for which the event is to be registered.
@param[in] Function Points to the notification function.
@@ -114,6 +115,7 @@ EFI_STATUS
@retval EFI_SUCCESS Successfully returned the registration record that has been added.
@retval EFI_INVALID_PARAMETER One or more of Protocol, Function and Registration is NULL.
@retval EFI_OUT_OF_RESOURCES Not enough memory resource to finish the request.
+ @retval EFI_NOT_FOUND If the registration is not found when Function == NULL.
**/
typedef
EFI_STATUS
diff --git a/MdePkg/Include/Ppi/Pcd.h b/MdePkg/Include/Ppi/Pcd.h
index da250a59e..79e9c3e97 100644
--- a/MdePkg/Include/Ppi/Pcd.h
+++ b/MdePkg/Include/Ppi/Pcd.h
@@ -6,7 +6,7 @@
The interfaces for dynamic type PCD do not require the token space guid as parameter,
but interfaces for dynamic-ex type PCD require token space guid as parameter.
-Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>
+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 that accompanies this distribution.
The full text of the license may be found at
@@ -775,10 +775,8 @@ EFI_STATUS
is being made to retrieve tokens from the default token space.
@param[in, out] TokenNumber A pointer to the PCD token number to use to find the subsequent token number.
- @retval EFI_SUCCESS The PCD service has retrieved the next valid token number.
- Or the input token number is already the last valid token number in the PCD database.
- In the later case, *TokenNumber is updated with the value of 0.
- @retval EFI_NOT_FOUND If this input token number and token namespace does not exist on the platform.
+ @retval EFI_SUCCESS The PCD service has retrieved the next valid token number.
+ @retval EFI_NOT_FOUND The PCD service could not find data from the requested token number.
**/
typedef
@@ -793,25 +791,17 @@ EFI_STATUS
/**
Retrieves the next valid PCD token namespace for a given namespace.
- If *Guid is NULL, then the GUID of the first token space of the
- current platform is assigned to *Guid the function return EFI_SUCCESS.
- If *Guid is NULL and there is no namespace exist in the platform other than the default
- (NULL) tokennamespace, *Guid is unchanged and the function return EFI_SUCCESS.
- If this input token namespace is the last namespace on the platform,
- *Guid will be assigned to NULL and the function return EFI_SUCCESS.
-
- @param[in, out] Guid An indirect pointer to EFI_GUID. On input it designates a known
- token namespace from which the search will start. On output, it designates
- the next valid token namespace on the platform. If the input token namespace
- does not exist on the platform, an error is returned, and the value of *Guid is
- undefined.
-
- @retval EFI_SUCCESS The PCD service has retrieved the next valid token namespace.
- Or the input token namespace is already the last valid token
- number in the PCD database. In the later case, *Guid is updated
- with the value of NULL. Or the input token name space is NULL and there
- is no valid token namespace other than the default namespace (NULL).
- @retval EFI_NOT_FOUND If the input token namespace does not exist on the platform.
+ Gets the next valid token namespace for a given namespace. This is useful to traverse the valid
+ token namespaces on a platform.
+
+ @param[in, out] Guid An indirect pointer to EFI_GUID. On input it designates a known token
+ namespace from which the search will start. On output, it designates the next valid
+ token namespace on the platform. If *Guid is NULL, then the GUID of the first token
+ space of the current platform is returned. If the search cannot locate the next valid
+ token namespace, an error is returned and the value of *Guid is undefined.
+
+ @retval EFI_SUCCESS The PCD service retrieved the value requested.
+ @retval EFI_NOT_FOUND The PCD service could not find the next valid token namespace.
**/
typedef
diff --git a/MdePkg/Include/Ppi/PcdInfo.h b/MdePkg/Include/Ppi/PcdInfo.h
new file mode 100644
index 000000000..731f873ed
--- /dev/null
+++ b/MdePkg/Include/Ppi/PcdInfo.h
@@ -0,0 +1,105 @@
+/** @file
+ Native Platform Configuration Database (PCD) INFO PPI
+
+ The PPI that provides additional information about items that reside in the PCD database.
+
+ Different with the EFI_GET_PCD_INFO_PPI defined in PI 1.2.1 specification,
+ the native PCD INFO PPI provide interfaces for dynamic and dynamic-ex type PCD.
+ The interfaces for dynamic type PCD do not require the token space guid as parameter,
+ but interfaces for dynamic-ex type PCD require token space guid as parameter.
+
+ Copyright (c) 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 __PCD_INFO_PPI_H__
+#define __PCD_INFO_PPI_H__
+
+extern EFI_GUID gGetPcdInfoPpiGuid;
+
+#define GET_PCD_INFO_PPI_GUID \
+ { 0x4d8b155b, 0xc059, 0x4c8f, { 0x89, 0x26, 0x6, 0xfd, 0x43, 0x31, 0xdb, 0x8a } }
+
+///
+/// The forward declaration for GET_PCD_INFO_PPI.
+///
+typedef struct _GET_PCD_INFO_PPI GET_PCD_INFO_PPI;
+
+/**
+ Retrieve additional information associated with a PCD token in the default token space.
+
+ This includes information such as the type of value the TokenNumber is associated with as well as possible
+ human readable name that is associated with the token.
+
+ @param[in] TokenNumber The PCD token number.
+ @param[out] PcdInfo The returned information associated with the requested TokenNumber.
+
+ @retval EFI_SUCCESS The PCD information was returned successfully
+ @retval EFI_NOT_FOUND The PCD service could not find the requested token number.
+**/
+typedef
+EFI_STATUS
+(EFIAPI *GET_PCD_INFO_PPI_GET_INFO) (
+ IN UINTN TokenNumber,
+ OUT EFI_PCD_INFO *PcdInfo
+);
+
+/**
+ Retrieve additional information associated with a PCD token.
+
+ This includes information such as the type of value the TokenNumber is associated with as well as possible
+ human readable name that is associated with the token.
+
+ @param[in] Guid The 128-bit unique value that designates the namespace from which to extract the value.
+ @param[in] TokenNumber The PCD token number.
+ @param[out] PcdInfo The returned information associated with the requested TokenNumber.
+
+ @retval EFI_SUCCESS The PCD information was returned successfully
+ @retval EFI_NOT_FOUND The PCD service could not find the requested token number.
+**/
+typedef
+EFI_STATUS
+(EFIAPI *GET_PCD_INFO_PPI_GET_INFO_EX) (
+ IN CONST EFI_GUID *Guid,
+ IN UINTN TokenNumber,
+ OUT EFI_PCD_INFO *PcdInfo
+);
+
+/**
+ Retrieve the currently set SKU Id.
+
+ @return The currently set SKU Id. If the platform has not set at a SKU Id, then the
+ default SKU Id value of 0 is returned. If the platform has set a SKU Id, then the currently set SKU
+ Id is returned.
+**/
+typedef
+UINTN
+(EFIAPI *GET_PCD_INFO_PPI_GET_SKU) (
+ VOID
+);
+
+///
+/// This is the PCD service to use when querying for some additional data that can be contained in the
+/// PCD database.
+///
+struct _GET_PCD_INFO_PPI {
+ ///
+ /// Retrieve additional information associated with a PCD.
+ ///
+ GET_PCD_INFO_PPI_GET_INFO GetInfo;
+ GET_PCD_INFO_PPI_GET_INFO_EX GetInfoEx;
+ ///
+ /// Retrieve the currently set SKU Id.
+ ///
+ GET_PCD_INFO_PPI_GET_SKU GetSku;
+};
+
+#endif
+
diff --git a/MdePkg/Include/Ppi/PiPcd.h b/MdePkg/Include/Ppi/PiPcd.h
index d116dc230..4698ecc3a 100644
--- a/MdePkg/Include/Ppi/PiPcd.h
+++ b/MdePkg/Include/Ppi/PiPcd.h
@@ -1,18 +1,17 @@
/** @file
- Platform Configuration Database (PCD) Protocol defined in PI 1.2 Vol3
+ Platform Configuration Database (PCD) PPI defined in PI 1.2 Vol3
A platform database that contains a variety of current platform settings or
directives that can be accessed by a driver or application.
- PI PCD protocol only provide the accessing interfaces for Dynamic-Ex type PCD.
+ PI PCD ppi only provide the accessing interfaces for Dynamic-Ex type PCD.
- Callers to this protocol must be at a TPL_APPLICATION task priority level.
This is the base PCD service API that provides an abstraction for accessing configuration content in
the platform. It a seamless mechanism for extracting information regardless of where the
information is stored (such as in Read-only data, or an EFI Variable).
This protocol allows access to data through size-granular APIs and provides a mechanism for a
firmware component to monitor specific settings and be alerted when a setting is changed.
- Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.<BR>
+ Copyright (c) 2009 - 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
@@ -73,7 +72,7 @@ UINT8
);
/**
- Retrieves the current byte-sized value for a PCD token number. If the TokenNumber is invalid,
+ Retrieves the current word-sized value for a PCD token number. If the TokenNumber is invalid,
the results are unpredictable.
@param[in] Guid The 128-bit unique value that designates which namespace to extract the value from.
@@ -375,7 +374,8 @@ EFI_STATUS
know what token numbers are valid in the database.
@param[in] Guid The 128-bit unique value that designates which namespace to extract the value from.
- @param[in] TokenNumber The PCD token number.
+ @param[in] TokenNumber A pointer to the PCD token number to use to find the subsequent token number. To
+ retrieve the "first" token, have the pointer reference a TokenNumber value of 0.
@retval EFI_SUCCESS The PCD service has retrieved the value requested.
@retval EFI_NOT_FOUND The PCD service could not find data from the requested token number.
diff --git a/MdePkg/Include/Ppi/PiPcdInfo.h b/MdePkg/Include/Ppi/PiPcdInfo.h
new file mode 100644
index 000000000..586f70756
--- /dev/null
+++ b/MdePkg/Include/Ppi/PiPcdInfo.h
@@ -0,0 +1,82 @@
+/** @file
+ Platform Configuration Database (PCD) Info Ppi defined in PI 1.2.1 Vol3.
+
+ The PPI that provides additional information about items that reside in the PCD database.
+
+ Copyright (c) 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.
+
+ @par Revision Reference:
+ PI Version 1.2.1 Vol 3.
+**/
+
+#ifndef __PI_PCD_INFO_PPI_H__
+#define __PI_PCD_INFO_PPI_H__
+
+extern EFI_GUID gEfiGetPcdInfoPpiGuid;
+
+#define EFI_GET_PCD_INFO_PPI_GUID \
+ { 0xa60c6b59, 0xe459, 0x425d, { 0x9c, 0x69, 0xb, 0xcc, 0x9c, 0xb2, 0x7d, 0x81 } }
+
+///
+/// The forward declaration for EFI_GET_PCD_INFO_PPI.
+///
+typedef struct _EFI_GET_PCD_INFO_PPI EFI_GET_PCD_INFO_PPI;
+
+/**
+ Retrieve additional information associated with a PCD token.
+
+ This includes information such as the type of value the TokenNumber is associated with as well as possible
+ human readable name that is associated with the token.
+
+ @param[in] Guid The 128-bit unique value that designates the namespace from which to extract the value.
+ @param[in] TokenNumber The PCD token number.
+ @param[out] PcdInfo The returned information associated with the requested TokenNumber.
+
+ @retval EFI_SUCCESS The PCD information was returned successfully
+ @retval EFI_NOT_FOUND The PCD service could not find the requested token number.
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_GET_PCD_INFO_PPI_GET_INFO) (
+ IN CONST EFI_GUID *Guid,
+ IN UINTN TokenNumber,
+ OUT EFI_PCD_INFO *PcdInfo
+);
+
+/**
+ Retrieve the currently set SKU Id.
+
+ @return The currently set SKU Id. If the platform has not set at a SKU Id, then the
+ default SKU Id value of 0 is returned. If the platform has set a SKU Id, then the currently set SKU
+ Id is returned.
+**/
+typedef
+UINTN
+(EFIAPI *EFI_GET_PCD_INFO_PPI_GET_SKU) (
+ VOID
+);
+
+///
+/// This is the PCD service to use when querying for some additional data that can be contained in the
+/// PCD database.
+///
+struct _EFI_GET_PCD_INFO_PPI {
+ ///
+ /// Retrieve additional information associated with a PCD.
+ ///
+ EFI_GET_PCD_INFO_PPI_GET_INFO GetInfo;
+ ///
+ /// Retrieve the currently set SKU Id.
+ ///
+ EFI_GET_PCD_INFO_PPI_GET_SKU GetSku;
+};
+
+#endif
+
diff --git a/MdePkg/Include/Ppi/TemporaryRamDone.h b/MdePkg/Include/Ppi/TemporaryRamDone.h
new file mode 100644
index 000000000..c492a86fb
--- /dev/null
+++ b/MdePkg/Include/Ppi/TemporaryRamDone.h
@@ -0,0 +1,52 @@
+/** @file
+ This file declares Temporary RAM Done PPI.
+ The PPI that provides a service to disable the use of Temporary RAM.
+
+ Copyright (c) 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.
+
+ @par Revision Reference:
+ This PPI is introduced in PI Version 1.2.1.
+
+**/
+
+#ifndef __TEMPORARY_RAM_DONE_H__
+#define __TEMPORARY_RAM_DONE_H__
+
+#define EFI_PEI_TEMPORARY_RAM_DONE_PPI_GUID \
+ { 0xceab683c, 0xec56, 0x4a2d, { 0xa9, 0x6, 0x40, 0x53, 0xfa, 0x4e, 0x9c, 0x16 } }
+
+/**
+ TemporaryRamDone() disables the use of Temporary RAM. If present, this service is invoked
+ by the PEI Foundation after the EFI_PEI_PERMANANT_MEMORY_INSTALLED_PPI is installed.
+
+ @retval EFI_SUCCESS Use of Temporary RAM was disabled.
+ @retval EFI_INVALID_PARAMETER Temporary RAM could not be disabled.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI * EFI_PEI_TEMPORARY_RAM_DONE) (
+ VOID
+ );
+
+///
+/// This is an optional PPI that may be produced by SEC or a PEIM. If present, it provide a service to
+/// disable the use of Temporary RAM. This service may only be called by the PEI Foundation after the
+/// transition from Temporary RAM to Permanent RAM is complete. This PPI provides an alternative
+/// to the Temporary RAM Migration PPI for system architectures that allow Temporary RAM and
+/// Permanent RAM to be enabled and accessed at the same time with no side effects.
+///
+typedef struct _EFI_PEI_TEMPORARY_RAM_DONE_PPI {
+ EFI_PEI_TEMPORARY_RAM_DONE TemporaryRamDone;
+} EFI_PEI_TEMPORARY_RAM_DONE_PPI;
+
+extern EFI_GUID gEfiTemporaryRamDonePpiGuid;
+
+#endif
diff --git a/MdePkg/Include/Ppi/VectorHandoffInfo.h b/MdePkg/Include/Ppi/VectorHandoffInfo.h
new file mode 100644
index 000000000..84cad7046
--- /dev/null
+++ b/MdePkg/Include/Ppi/VectorHandoffInfo.h
@@ -0,0 +1,75 @@
+/** @file
+ This file declares Vector Handoff Info PPI that describes an array of
+ interrupt and/or exception vectors that are in use and need to persist.
+
+ This is an optional PPI that may be produced by SEC. If present, it provides
+ a description of the interrupt and/or exception vectors that were established
+ in the SEC Phase and need to persist into PEI and DXE.
+
+ Copyright (c) 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.
+
+ @par Revision Reference:
+ This PPI is introduced in PI Version 1.2.1.
+
+**/
+
+#ifndef __VECTOR_HANDOFF_INFO_H__
+#define __VECTOR_HANDOFF_INFO_H__
+
+///
+/// NOTE: EFI_PEI_VECTOR_HANDOFF_INFO_PPI_GUID can also be used in the PEI Phase
+/// to build a GUIDed HOB that contains an array of EFI_VECTOR_HANDOFF_INFO.
+///
+#define EFI_PEI_VECTOR_HANDOFF_INFO_PPI_GUID \
+ { 0x3cd652b4, 0x6d33, 0x4dce, { 0x89, 0xdb, 0x83, 0xdf, 0x97, 0x66, 0xfc, 0xca }}
+
+///
+/// Vector Handoff Info Attributes
+///@{
+#define EFI_VECTOR_HANDOFF_DO_NOT_HOOK 0x00000000
+#define EFI_VECTOR_HANDOFF_HOOK_BEFORE 0x00000001
+#define EFI_VECTOR_HANDOFF_HOOK_AFTER 0x00000002
+#define EFI_VECTOR_HANDOFF_LAST_ENTRY 0x80000000
+///@}
+
+///
+/// EFI_VECTOR_HANDOFF_INFO entries that describes the interrupt and/or
+/// exception vectors in use in the PEI Phase.
+///
+typedef struct {
+ //
+ // The interrupt or exception vector that is in use and must be preserved.
+ //
+ UINT32 VectorNumber;
+ //
+ // A bitmask that describes the attributes ofthe interrupt or exception vector.
+ //
+ UINT32 Attribute;
+ //
+ // The GUID identifies the party who created the entry. For the
+ // EFI_VECTOR_HANDOFF_DO_NOT_HOOK case, this establishes the single owner.
+ //
+ EFI_GUID Owner;
+} EFI_VECTOR_HANDOFF_INFO;
+
+///
+/// Provides a description of the interrupt and/or exception vectors that
+/// were established in the SEC Phase and need to persist into PEI and DXE.
+///
+typedef struct _EFI_PEI_VECTOR_HANDOFF_INFO_PPI {
+ //
+ // Pointer to an array of interrupt and /or exception vectors.
+ //
+ EFI_VECTOR_HANDOFF_INFO *Info;
+} EFI_PEI_VECTOR_HANDOFF_INFO_PPI;
+
+extern EFI_GUID gEfiVectorHandoffInfoPpiGuid;
+
+#endif
diff --git a/MdePkg/Include/Protocol/Pcd.h b/MdePkg/Include/Protocol/Pcd.h
index 03ce981d4..03b02fd93 100644
--- a/MdePkg/Include/Protocol/Pcd.h
+++ b/MdePkg/Include/Protocol/Pcd.h
@@ -6,7 +6,7 @@
The interfaces in dynamic type PCD do not require the token space guid as parameter,
but interfaces in dynamic-ex type PCD require token space guid as parameter.
-Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>
+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 that accompanies this distribution.
The full text of the license may be found at
@@ -766,7 +766,7 @@ EFI_STATUS
Retrieves the next valid token number in a given namespace.
This is useful since the PCD infrastructure contains a sparse list of token numbers,
- and one cannot know without examination or by deduction what token numbers are valid in the database.
+ and one cannot a priori know what token numbers are valid in the database.
If TokenNumber is 0 and Guid is not NULL, then the first token from the token space specified by Guid is returned.
If TokenNumber is not 0 and Guid is not NULL, then the next token in the token space specified by Guid is returned.
@@ -784,10 +784,8 @@ EFI_STATUS
@param[in,out] TokenNumber
A pointer to the PCD token number to use to find the subsequent token number.
- @retval EFI_SUCCESS The PCD service retrieved the next valid token number. Or the input token number
- is already the last valid token number in the PCD database.
- In the later case, *TokenNumber is updated with the value of 0.
- @retval EFI_NOT_FOUND If this input token number and token namespace does not exist on the platform.
+ @retval EFI_SUCCESS The PCD service has retrieved the next valid token number.
+ @retval EFI_NOT_FOUND The PCD service could not find data from the requested token number.
**/
typedef
@@ -802,22 +800,17 @@ EFI_STATUS
/**
Retrieves the next valid PCD token namespace for a given namespace.
- @param[in, out] Guid An indirect pointer to EFI_GUID. On input it designates
- a known token namespace from which the search will start. On output,
- it designates the next valid token namespace on the platform. If the input
- token namespace does not exist on the platform, an error is returned and
- the value of *Guid is undefined. If *Guid is NULL, then the GUID of the
- first token space of the current platform is assigned to *Guid the function
- return EFI_SUCCESS. If *Guid is NULL and there is no namespace exist in
- the platform other than the default (NULL) token namespace, *Guid is unchanged
- and the function return EFI_SUCCESS. If this input token namespace is the last
- namespace on the platform, *Guid will be assigned to NULL and the function return
- EFI_SUCCESS.
-
- @retval EFI_SUCCESS The PCD service retrieved the next valid token space Guid.
- Or, the input token space Guid is already the last valid token space Guid
- in the PCD database. In the later case, *Guid is updated with the value of NULL.
- @retval EFI_NOT_FOUND If the input token namespace does not exist on the platform.
+ Gets the next valid token namespace for a given namespace. This is useful to traverse the valid
+ token namespaces on a platform.
+
+ @param[in, out] Guid An indirect pointer to EFI_GUID. On input it designates a known token namespace
+ from which the search will start. On output, it designates the next valid token
+ namespace on the platform. If *Guid is NULL, then the GUID of the first token
+ space of the current platform is returned. If the search cannot locate the next valid
+ token namespace, an error is returned and the value of *Guid is undefined.
+
+ @retval EFI_SUCCESS The PCD service retrieved the value requested.
+ @retval EFI_NOT_FOUND The PCD service could not find the next valid token namespace.
**/
typedef
diff --git a/MdePkg/Include/Protocol/PcdInfo.h b/MdePkg/Include/Protocol/PcdInfo.h
new file mode 100644
index 000000000..00edd1b50
--- /dev/null
+++ b/MdePkg/Include/Protocol/PcdInfo.h
@@ -0,0 +1,105 @@
+/** @file
+ Native Platform Configuration Database (PCD) INFO PROTOCOL.
+
+ The protocol that provides additional information about items that reside in the PCD database.
+
+ Different with the EFI_GET_PCD_INFO_PROTOCOL defined in PI 1.2.1 specification,
+ the native PCD INFO PROTOCOL provide interfaces for dynamic and dynamic-ex type PCD.
+ The interfaces for dynamic type PCD do not require the token space guid as parameter,
+ but interfaces for dynamic-ex type PCD require token space guid as parameter.
+
+ Copyright (c) 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 __PCD_INFO_H__
+#define __PCD_INFO_H__
+
+extern EFI_GUID gGetPcdInfoProtocolGuid;
+
+#define GET_PCD_INFO_PROTOCOL_GUID \
+ { 0x5be40f57, 0xfa68, 0x4610, { 0xbb, 0xbf, 0xe9, 0xc5, 0xfc, 0xda, 0xd3, 0x65 } }
+
+///
+/// The forward declaration for GET_PCD_INFO_PROTOCOL.
+///
+typedef struct _GET_PCD_INFO_PROTOCOL GET_PCD_INFO_PROTOCOL;
+
+/**
+ Retrieve additional information associated with a PCD token.
+
+ This includes information such as the type of value the TokenNumber is associated with as well as possible
+ human readable name that is associated with the token.
+
+ @param[in] TokenNumber The PCD token number.
+ @param[out] PcdInfo The returned information associated with the requested TokenNumber.
+
+ @retval EFI_SUCCESS The PCD information was returned successfully
+ @retval EFI_NOT_FOUND The PCD service could not find the requested token number.
+**/
+typedef
+EFI_STATUS
+(EFIAPI *GET_PCD_INFO_PROTOCOL_GET_INFO) (
+ IN UINTN TokenNumber,
+ OUT EFI_PCD_INFO *PcdInfo
+);
+
+/**
+ Retrieve additional information associated with a PCD token.
+
+ This includes information such as the type of value the TokenNumber is associated with as well as possible
+ human readable name that is associated with the token.
+
+ @param[in] Guid The 128-bit unique value that designates the namespace from which to extract the value.
+ @param[in] TokenNumber The PCD token number.
+ @param[out] PcdInfo The returned information associated with the requested TokenNumber.
+
+ @retval EFI_SUCCESS The PCD information was returned successfully
+ @retval EFI_NOT_FOUND The PCD service could not find the requested token number.
+**/
+typedef
+EFI_STATUS
+(EFIAPI *GET_PCD_INFO_PROTOCOL_GET_INFO_EX) (
+ IN CONST EFI_GUID *Guid,
+ IN UINTN TokenNumber,
+ OUT EFI_PCD_INFO *PcdInfo
+);
+
+/**
+ Retrieve the currently set SKU Id.
+
+ @return The currently set SKU Id. If the platform has not set at a SKU Id, then the
+ default SKU Id value of 0 is returned. If the platform has set a SKU Id, then the currently set SKU
+ Id is returned.
+**/
+typedef
+UINTN
+(EFIAPI *GET_PCD_INFO_PROTOCOL_GET_SKU) (
+ VOID
+);
+
+///
+/// This is the PCD service to use when querying for some additional data that can be contained in the
+/// PCD database.
+///
+struct _GET_PCD_INFO_PROTOCOL {
+ ///
+ /// Retrieve additional information associated with a PCD.
+ ///
+ GET_PCD_INFO_PROTOCOL_GET_INFO GetInfo;
+ GET_PCD_INFO_PROTOCOL_GET_INFO_EX GetInfoEx;
+ ///
+ /// Retrieve the currently set SKU Id.
+ ///
+ GET_PCD_INFO_PROTOCOL_GET_SKU GetSku;
+};
+
+#endif
+
diff --git a/MdePkg/Include/Protocol/PiPcdInfo.h b/MdePkg/Include/Protocol/PiPcdInfo.h
new file mode 100644
index 000000000..3c4307586
--- /dev/null
+++ b/MdePkg/Include/Protocol/PiPcdInfo.h
@@ -0,0 +1,83 @@
+/** @file
+ Platform Configuration Database (PCD) Info Protocol defined in PI 1.2.1 Vol3.
+
+ The protocol that provides additional information about items that reside in the PCD database.
+
+ Copyright (c) 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.
+
+ @par Revision Reference:
+ PI Version 1.2.1 Vol 3.
+**/
+
+#ifndef __PI_PCD_INFO_H__
+#define __PI_PCD_INFO_H__
+
+extern EFI_GUID gEfiGetPcdInfoProtocolGuid;
+
+#define EFI_GET_PCD_INFO_PROTOCOL_GUID \
+ { 0xfd0f4478, 0xefd, 0x461d, { 0xba, 0x2d, 0xe5, 0x8c, 0x45, 0xfd, 0x5f, 0x5e } }
+
+///
+/// The forward declaration for EFI_GET_PCD_INFO_PROTOCOL.
+///
+typedef struct _EFI_GET_PCD_INFO_PROTOCOL EFI_GET_PCD_INFO_PROTOCOL;
+
+/**
+ Retrieve additional information associated with a PCD token.
+
+ This includes information such as the type of value the TokenNumber is associated with as well as possible
+ human readable name that is associated with the token.
+
+ @param[in] Guid The 128-bit unique value that designates the namespace from which to extract the value.
+ @param[in] TokenNumber The PCD token number.
+ @param[out] PcdInfo The returned information associated with the requested TokenNumber.
+
+ @retval EFI_SUCCESS The PCD information was returned successfully
+ @retval EFI_NOT_FOUND The PCD service could not find the requested token number.
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_GET_PCD_INFO_PROTOCOL_GET_INFO) (
+ IN CONST EFI_GUID *Guid,
+ IN UINTN TokenNumber,
+ OUT EFI_PCD_INFO *PcdInfo
+);
+
+/**
+ Retrieve the currently set SKU Id.
+
+ @return The currently set SKU Id. If the platform has not set at a SKU Id, then the
+ default SKU Id value of 0 is returned. If the platform has set a SKU Id, then the currently set SKU
+ Id is returned.
+**/
+typedef
+UINTN
+(EFIAPI *EFI_GET_PCD_INFO_PROTOCOL_GET_SKU) (
+ VOID
+);
+
+///
+/// Callers to this protocol must be at a TPL_APPLICATION task priority level.
+/// This is the PCD service to use when querying for some additional data that can be contained in the
+/// PCD database.
+///
+struct _EFI_GET_PCD_INFO_PROTOCOL {
+ ///
+ /// Retrieve additional information associated with a PCD.
+ ///
+ EFI_GET_PCD_INFO_PROTOCOL_GET_INFO GetInfo;
+ ///
+ /// Retrieve the currently set SKU Id.
+ ///
+ EFI_GET_PCD_INFO_PROTOCOL_GET_SKU GetSku;
+};
+
+#endif
+
diff --git a/MdePkg/Include/Protocol/Rng.h b/MdePkg/Include/Protocol/Rng.h
new file mode 100644
index 000000000..5a4fe692f
--- /dev/null
+++ b/MdePkg/Include/Protocol/Rng.h
@@ -0,0 +1,156 @@
+/** @file
+ EFI_RNG_PROTOCOL as defined in UEFI 2.4.
+ The UEFI Random Number Generator Protocol is used to provide random bits for use
+ in applications, or entropy for seeding other random number generators.
+
+Copyright (c) 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 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.
+
+**/
+
+#ifndef __EFI_RNG_PROTOCOL_H__
+#define __EFI_RNG_PROTOCOL_H__
+
+///
+/// Global ID for the Random Number Generator Protocol
+///
+#define EFI_RNG_PROTOCOL_GUID \
+ { \
+ 0x3152bca5, 0xeade, 0x433d, {0x86, 0x2e, 0xc0, 0x1c, 0xdc, 0x29, 0x1f, 0x44 } \
+ }
+
+typedef struct _EFI_RNG_PROTOCOL EFI_RNG_PROTOCOL;
+
+///
+/// A selection of EFI_RNG_PROTOCOL algorithms.
+/// The algorithms listed are optional, not meant to be exhaustive and be argmented by
+/// vendors or other industry standards.
+///
+
+typedef EFI_GUID EFI_RNG_ALGORITHM;
+
+///
+/// The algorithms corresponds to SP800-90 as defined in
+/// NIST SP 800-90, "Recommendation for Random Number Generation Using Deterministic Random
+/// Bit Generators", March 2007.
+///
+#define EFI_RNG_ALGORITHM_SP800_90_HASH_256_GUID \
+ { \
+ 0xa7af67cb, 0x603b, 0x4d42, {0xba, 0x21, 0x70, 0xbf, 0xb6, 0x29, 0x3f, 0x96 } \
+ }
+#define EFI_RNG_ALGORITHM_SP800_90_HMAC_256_GUID \
+ { \
+ 0xc5149b43, 0xae85, 0x4f53, {0x99, 0x82, 0xb9, 0x43, 0x35, 0xd3, 0xa9, 0xe7 } \
+ }
+#define EFI_RNG_ALGORITHM_SP800_90_CTR_256_GUID \
+ { \
+ 0x44f0de6e, 0x4d8c, 0x4045, {0xa8, 0xc7, 0x4d, 0xd1, 0x68, 0x85, 0x6b, 0x9e } \
+ }
+///
+/// The algorithms correspond to X9.31 as defined in
+/// NIST, "Recommended Random Number Generator Based on ANSI X9.31 Appendix A.2.4 Using
+/// the 3-Key Triple DES and AES Algorithm", January 2005.
+///
+#define EFI_RNG_ALGORITHM_X9_31_3DES_GUID \
+ { \
+ 0x63c4785a, 0xca34, 0x4012, {0xa3, 0xc8, 0x0b, 0x6a, 0x32, 0x4f, 0x55, 0x46 } \
+ }
+#define EFI_RNG_ALGORITHM_X9_31_AES_GUID \
+ { \
+ 0xacd03321, 0x777e, 0x4d3d, {0xb1, 0xc8, 0x20, 0xcf, 0xd8, 0x88, 0x20, 0xc9 } \
+ }
+///
+/// The "raw" algorithm, when supported, is intended to provide entropy directly from
+/// the source, without it going through some deterministic random bit generator.
+///
+#define EFI_RNG_ALGORITHM_RAW \
+ { \
+ 0xe43176d7, 0xb6e8, 0x4827, {0xb7, 0x84, 0x7f, 0xfd, 0xc4, 0xb6, 0x85, 0x61 } \
+ }
+
+/**
+ Returns information about the random number generation implementation.
+
+ @param[in] This A pointer to the EFI_RNG_PROTOCOL instance.
+ @param[in,out] RNGAlgorithmListSize On input, the size in bytes of RNGAlgorithmList.
+ On output with a return code of EFI_SUCCESS, the size
+ in bytes of the data returned in RNGAlgorithmList. On output
+ with a return code of EFI_BUFFER_TOO_SMALL,
+ the size of RNGAlgorithmList required to obtain the list.
+ @param[out] RNGAlgorithmList A caller-allocated memory buffer filled by the driver
+ with one EFI_RNG_ALGORITHM element for each supported
+ RNG algorithm. The list must not change across multiple
+ calls to the same driver. The first algorithm in the list
+ is the default algorithm for the driver.
+
+ @retval EFI_SUCCESS The RNG algorithm list was returned successfully.
+ @retval EFI_UNSUPPORTED The services is not supported by this driver.
+ @retval EFI_DEVICE_ERROR The list of algorithms could not be retrieved due to a
+ hardware or firmware error.
+ @retval EFI_INVALID_PARAMETER One or more of the parameters are incorrect.
+ @retval EFI_BUFFER_TOO_SMALL The buffer RNGAlgorithmList is too small to hold the result.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_RNG_GET_INFO) (
+ IN EFI_RNG_PROTOCOL *This,
+ IN OUT UINTN *RNGAlgorithmListSize,
+ OUT EFI_RNG_ALGORITHM *RNGAlgorithmList
+ );
+
+/**
+ Produces and returns an RNG value using either the default or specified RNG algorithm.
+
+ @param[in] This A pointer to the EFI_RNG_PROTOCOL instance.
+ @param[in] RNGAlgorithm A pointer to the EFI_RNG_ALGORITHM that identifies the RNG
+ algorithm to use. May be NULL in which case the function will
+ use its default RNG algorithm.
+ @param[in] RNGValueLength The length in bytes of the memory buffer pointed to by
+ RNGValue. The driver shall return exactly this numbers of bytes.
+ @param[out] RNGValue A caller-allocated memory buffer filled by the driver with the
+ resulting RNG value.
+
+ @retval EFI_SUCCESS The RNG value was returned successfully.
+ @retval EFI_UNSUPPORTED The algorithm specified by RNGAlgorithm is not supported by
+ this driver.
+ @retval EFI_DEVICE_ERROR An RNG value could not be retrieved due to a hardware or
+ firmware error.
+ @retval EFI_NOT_READY There is not enough random data available to satisfy the length
+ requested by RNGValueLength.
+ @retval EFI_INVALID_PARAMETER RNGValue is NULL or RNGValueLength is zero.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_RNG_GET_RNG) (
+ IN EFI_RNG_PROTOCOL *This,
+ IN EFI_RNG_ALGORITHM *RNGAlgorithm, OPTIONAL
+ IN UINTN RNGValueLength,
+ OUT UINT8 *RNGValue
+ );
+
+///
+/// The Random Number Generator (RNG) protocol provides random bits for use in
+/// applications, or entropy for seeding other random number generators.
+///
+struct _EFI_RNG_PROTOCOL {
+ EFI_RNG_GET_INFO GetInfo;
+ EFI_RNG_GET_RNG GetRNG;
+};
+
+extern EFI_GUID gEfiRngProtocolGuid;
+extern EFI_GUID gEfiRngAlgorithmSp80090Hash256Guid;
+extern EFI_GUID gEfiRngAlgorithmSp80090Hmac256Guid;
+extern EFI_GUID gEfiRngAlgorithmSp80090Ctr256Guid;
+extern EFI_GUID gEfiRngAlgorithmX9313DesGuid;
+extern EFI_GUID gEfiRngAlgorithmX931AesGuid;
+extern EFI_GUID gEfiRngAlgorithmRaw;
+
+#endif
diff --git a/MdePkg/Include/Protocol/SimpleFileSystem.h b/MdePkg/Include/Protocol/SimpleFileSystem.h
index 7522bc8b8..bc6718cf6 100644
--- a/MdePkg/Include/Protocol/SimpleFileSystem.h
+++ b/MdePkg/Include/Protocol/SimpleFileSystem.h
@@ -7,7 +7,7 @@
UEFI 2.0 can boot from any valid EFI image contained in a SimpleFileSystem.
-Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>
+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 that accompanies this distribution.
The full text of the license may be found at
@@ -190,7 +190,7 @@ EFI_STATUS
@retval EFI_DEVICE_ERROR An attempt was made to read from a deleted file.
@retval EFI_DEVICE_ERROR On entry, the current file position is beyond the end of the file.
@retval EFI_VOLUME_CORRUPTED The file system structures are corrupted.
- @retval EFI_BUFFER_TO_SMALL The BufferSize is too small to read the current directory
+ @retval EFI_BUFFER_TOO_SMALL The BufferSize is too small to read the current directory
entry. BufferSize has been updated with the size
needed to complete the request.
@@ -363,7 +363,162 @@ EFI_STATUS
IN EFI_FILE_PROTOCOL *This
);
-#define EFI_FILE_PROTOCOL_REVISION 0x00010000
+typedef struct {
+ //
+ // If Event is NULL, then blocking I/O is performed.
+ // If Event is not NULL and non-blocking I/O is supported, then non-blocking I/O is performed,
+ // and Event will be signaled when the read request is completed.
+ // The caller must be prepared to handle the case where the callback associated with Event
+ // occurs before the original asynchronous I/O request call returns.
+ //
+ EFI_EVENT Event;
+
+ //
+ // Defines whether or not the signaled event encountered an error.
+ //
+ EFI_STATUS Status;
+
+ //
+ // For OpenEx(): Not Used, ignored.
+ // For ReadEx(): On input, the size of the Buffer. On output, the amount of data returned in Buffer.
+ // In both cases, the size is measured in bytes.
+ // For WriteEx(): On input, the size of the Buffer. On output, the amount of data actually written.
+ // In both cases, the size is measured in bytes.
+ // For FlushEx(): Not used, ignored.
+ //
+ UINTN BufferSize;
+
+ //
+ // For OpenEx(): Not Used, ignored.
+ // For ReadEx(): The buffer into which the data is read.
+ // For WriteEx(): The buffer of data to write.
+ // For FlushEx(): Not Used, ignored.
+ //
+ VOID *Buffer;
+} EFI_FILE_IO_TOKEN;
+
+/**
+ Opens a new file relative to the source directory's location.
+
+ @param This A pointer to the EFI_FILE_PROTOCOL instance that is the file
+ handle to the source location.
+ @param NewHandle A pointer to the location to return the opened handle for the new
+ file.
+ @param FileName The Null-terminated string of the name of the file to be opened.
+ The file name may contain the following path modifiers: "\", ".",
+ and "..".
+ @param OpenMode The mode to open the file. The only valid combinations that the
+ file may be opened with are: Read, Read/Write, or Create/Read/Write.
+ @param Attributes Only valid for EFI_FILE_MODE_CREATE, in which case these are the
+ attribute bits for the newly created file.
+ @param Token A pointer to the token associated with the transaction.
+
+ @retval EFI_SUCCESS If Event is NULL (blocking I/O): The data was read successfully.
+ If Event is not NULL (asynchronous I/O): The request was successfully
+ queued for processing.
+ @retval EFI_NOT_FOUND The specified file could not be found 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.
+ @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_FILE_OPEN_EX)(
+ IN EFI_FILE_PROTOCOL *This,
+ OUT EFI_FILE_PROTOCOL **NewHandle,
+ IN CHAR16 *FileName,
+ IN UINT64 OpenMode,
+ IN UINT64 Attributes,
+ IN OUT EFI_FILE_IO_TOKEN *Token
+ );
+
+
+/**
+ Reads data from a file.
+
+ @param This A pointer to the EFI_FILE_PROTOCOL instance that is the file handle to read data from.
+ @param Token A pointer to the token associated with the transaction.
+
+ @retval EFI_SUCCESS If Event is NULL (blocking I/O): The data was read successfully.
+ If Event is not NULL (asynchronous I/O): The request was successfully
+ queued for processing.
+ @retval EFI_NO_MEDIA The device has no medium.
+ @retval EFI_DEVICE_ERROR The device reported an error.
+ @retval EFI_DEVICE_ERROR An attempt was made to read from a deleted file.
+ @retval EFI_DEVICE_ERROR On entry, the current file position is beyond the end of the file.
+ @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted.
+ @retval EFI_OUT_OF_RESOURCES Unable to queue the request due to lack of resources.
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_FILE_READ_EX) (
+ IN EFI_FILE_PROTOCOL *This,
+ IN OUT EFI_FILE_IO_TOKEN *Token
+);
+
+
+/**
+ Writes data to a file.
+
+ @param This A pointer to the EFI_FILE_PROTOCOL instance that is the file handle to write data to.
+ @param Token A pointer to the token associated with the transaction.
+
+ @retval EFI_SUCCESS If Event is NULL (blocking I/O): The data was read successfully.
+ If Event is not NULL (asynchronous I/O): The request was successfully
+ queued for processing.
+ @retval EFI_UNSUPPORTED Writes to open directory files are not supported.
+ @retval EFI_NO_MEDIA The device has no medium.
+ @retval EFI_DEVICE_ERROR The device reported an error.
+ @retval EFI_DEVICE_ERROR An attempt was made to write to a deleted file.
+ @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_OUT_OF_RESOURCES Unable to queue the request due to lack of resources.
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_FILE_WRITE_EX) (
+ IN EFI_FILE_PROTOCOL *This,
+ IN OUT EFI_FILE_IO_TOKEN *Token
+);
+
+/**
+ Flushes all modified data associated with a file to a device.
+
+ @param This A pointer to the EFI_FILE_PROTOCOL instance that is the file
+ handle to flush.
+ @param Token A pointer to the token associated with the transaction.
+
+ @retval EFI_SUCCESS If Event is NULL (blocking I/O): The data was read successfully.
+ If Event is not NULL (asynchronous I/O): The request was successfully
+ queued for processing.
+ @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_OUT_OF_RESOURCES Unable to queue the request due to lack of resources.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_FILE_FLUSH_EX) (
+ IN EFI_FILE_PROTOCOL *This,
+ IN OUT EFI_FILE_IO_TOKEN *Token
+ );
+
+#define EFI_FILE_PROTOCOL_REVISION 0x00010000
+#define EFI_FILE_PROTOCOL_REVISION2 0x00020000
//
// Revision defined in EFI1.1.
//
@@ -393,6 +548,10 @@ struct _EFI_FILE_PROTOCOL {
EFI_FILE_GET_INFO GetInfo;
EFI_FILE_SET_INFO SetInfo;
EFI_FILE_FLUSH Flush;
+ EFI_FILE_OPEN_EX OpenEx;
+ EFI_FILE_READ_EX ReadEx;
+ EFI_FILE_WRITE_EX WriteEx;
+ EFI_FILE_FLUSH_EX FlushEx;
};
diff --git a/MdePkg/Include/Uefi/UefiSpec.h b/MdePkg/Include/Uefi/UefiSpec.h
index 619246b61..e6819aa28 100644
--- a/MdePkg/Include/Uefi/UefiSpec.h
+++ b/MdePkg/Include/Uefi/UefiSpec.h
@@ -1770,10 +1770,11 @@ EFI_STATUS
#define EFI_2_00_SYSTEM_TABLE_REVISION ((2 << 16) | (00))
#define EFI_1_10_SYSTEM_TABLE_REVISION ((1 << 16) | (10))
#define EFI_1_02_SYSTEM_TABLE_REVISION ((1 << 16) | (02))
-#define EFI_SYSTEM_TABLE_REVISION EFI_2_31_SYSTEM_TABLE_REVISION
+#define EFI_SYSTEM_TABLE_REVISION EFI_2_40_SYSTEM_TABLE_REVISION
+#define EFI_SPECIFICATION_VERSION EFI_SYSTEM_TABLE_REVISION
#define EFI_RUNTIME_SERVICES_SIGNATURE SIGNATURE_64 ('R','U','N','T','S','E','R','V')
-#define EFI_RUNTIME_SERVICES_REVISION EFI_2_31_SYSTEM_TABLE_REVISION
+#define EFI_RUNTIME_SERVICES_REVISION EFI_SPECIFICATION_VERSION
///
/// EFI Runtime Services Table.
@@ -1825,7 +1826,7 @@ typedef struct {
#define EFI_BOOT_SERVICES_SIGNATURE SIGNATURE_64 ('B','O','O','T','S','E','R','V')
-#define EFI_BOOT_SERVICES_REVISION EFI_2_31_SYSTEM_TABLE_REVISION
+#define EFI_BOOT_SERVICES_REVISION EFI_SPECIFICATION_VERSION
///
/// EFI Boot Services Table.
diff --git a/MdePkg/Library/BaseLib/X64/Thunk16.S b/MdePkg/Library/BaseLib/X64/Thunk16.S
index a521aff31..f592a2868 100644
--- a/MdePkg/Library/BaseLib/X64/Thunk16.S
+++ b/MdePkg/Library/BaseLib/X64/Thunk16.S
@@ -146,8 +146,8 @@ L_64Eip: .space 4
L_SavedCs: .space 2
L_64BitCode:
.byte 0x90
- .byte 0x67,0xbc # mov esp, imm32
-L_SavedSp: .space 4 # restore stack
+ .byte 0x48,0xbc # mov rsp, imm64
+L_SavedSp: .space 8 # restore stack
nop
ret
@@ -307,7 +307,7 @@ ASM_PFX(InternalAsmThunk16):
pushq %r8
movl %cs, %r8d
movw %r8w, (L_SavedCs - L_SavedCr4)(%rcx)
- movl %esp, (L_SavedSp - L_SavedCr4)(%rcx)
+ movq %rsp, (L_SavedSp - L_SavedCr4)(%rcx)
.byte 0xff, 0x69 # jmp (_EntryPoint - L_SavedCr4)(%rcx)
.set Ltemp1, _EntryPoint - L_SavedCr4
.byte Ltemp1
diff --git a/MdePkg/Library/BaseLib/X64/Thunk16.asm b/MdePkg/Library/BaseLib/X64/Thunk16.asm
index 01051341f..e01de272d 100644
--- a/MdePkg/Library/BaseLib/X64/Thunk16.asm
+++ b/MdePkg/Library/BaseLib/X64/Thunk16.asm
@@ -142,8 +142,8 @@ SavedCr0 DD ?
SavedCs DW ?
@64BitCode:
db 090h
- db 067h, 0bch ; mov esp, imm32
-SavedSp DD ? ; restore stack
+ db 048h, 0bch ; mov rsp, imm64
+SavedSp DQ ? ; restore stack
nop
ret
_BackFromUserCode ENDP
@@ -294,7 +294,7 @@ InternalAsmThunk16 PROC USES rbp rbx rsi rdi
push r8
mov r8d, cs
mov [rcx + (SavedCs - SavedCr4)], r8w
- mov [rcx + (SavedSp - SavedCr4)], esp
+ mov [rcx + (SavedSp - SavedCr4)], rsp
jmp fword ptr [rcx + (_EntryPoint - SavedCr4)]
@RetFromRealMode:
popfq
diff --git a/MdePkg/Library/BasePcdLibNull/PcdLib.c b/MdePkg/Library/BasePcdLibNull/PcdLib.c
index 4823f5ad6..8333aaa3f 100644
--- a/MdePkg/Library/BasePcdLibNull/PcdLib.c
+++ b/MdePkg/Library/BasePcdLibNull/PcdLib.c
@@ -919,3 +919,69 @@ LibPatchPcdSetPtr (
return (VOID *) Buffer;
}
+/**
+ Retrieve additional information associated with a PCD token.
+
+ This includes information such as the type of value the TokenNumber is associated with as well as possible
+ human readable name that is associated with the token.
+
+ If TokenNumber is not in the default token space specified, then ASSERT().
+
+ @param[in] TokenNumber The PCD token number.
+ @param[out] PcdInfo The returned information associated with the requested TokenNumber.
+ The caller is responsible for freeing the buffer that is allocated by callee for PcdInfo->PcdName.
+**/
+VOID
+EFIAPI
+LibPcdGetInfo (
+ IN UINTN TokenNumber,
+ OUT PCD_INFO *PcdInfo
+ )
+{
+ ASSERT (FALSE);
+}
+
+/**
+ Retrieve additional information associated with a PCD token.
+
+ This includes information such as the type of value the TokenNumber is associated with as well as possible
+ human readable name that is associated with the token.
+
+ If TokenNumber is not in the token space specified by Guid, then ASSERT().
+
+ @param[in] Guid The 128-bit unique value that designates the namespace from which to extract the value.
+ @param[in] TokenNumber The PCD token number.
+ @param[out] PcdInfo The returned information associated with the requested TokenNumber.
+ The caller is responsible for freeing the buffer that is allocated by callee for PcdInfo->PcdName.
+**/
+VOID
+EFIAPI
+LibPcdGetInfoEx (
+ IN CONST GUID *Guid,
+ IN UINTN TokenNumber,
+ OUT PCD_INFO *PcdInfo
+ )
+{
+ ASSERT (FALSE);
+}
+
+/**
+ Retrieve the currently set SKU Id.
+
+ If the sku id got >= PCD_MAX_SKU_ID, then ASSERT().
+
+ @return The currently set SKU Id. If the platform has not set at a SKU Id, then the
+ default SKU Id value of 0 is returned. If the platform has set a SKU Id, then the currently set SKU
+ Id is returned.
+**/
+UINTN
+EFIAPI
+LibPcdGetSku (
+ VOID
+ )
+{
+ ASSERT (FALSE);
+
+ return 0;
+}
+
diff --git a/MdePkg/Library/BaseSmbusLibNull/BaseSmbusLibNull.c b/MdePkg/Library/BaseSmbusLibNull/BaseSmbusLibNull.c
new file mode 100644
index 000000000..32bead9b0
--- /dev/null
+++ b/MdePkg/Library/BaseSmbusLibNull/BaseSmbusLibNull.c
@@ -0,0 +1,544 @@
+/** @file
+Null implementation of SmBusLib class library.
+
+Copyright (c) 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 <Base.h>
+#include <Library/SmbusLib.h>
+#include <Library/DebugLib.h>
+
+/**
+ Executes an SMBUS quick read command.
+
+ Executes an SMBUS quick read command on the SMBUS device specified by SmBusAddress.
+ Only the SMBUS slave address field of SmBusAddress is required.
+ If Status is not NULL, then the status of the executed command is returned in Status.
+ If PEC is set in SmBusAddress, then ASSERT().
+ If Command in SmBusAddress is not zero, then ASSERT().
+ If Length in SmBusAddress is not zero, then ASSERT().
+ If any reserved bits of SmBusAddress are set, then ASSERT().
+
+ @param SmBusAddress Address that encodes the SMBUS Slave Address,
+ SMBUS Command, SMBUS Data Length, and PEC.
+ @param Status Return status for the executed command.
+ This is an optional parameter and may be NULL.
+ RETURN_SUCCESS The SMBUS command was executed.
+ RETURN_TIMEOUT A timeout occurred while executing the SMBUS command.
+ RETURN_DEVICE_ERROR The request was not completed because a failure
+ reflected in the Host Status Register bit. Device errors are a result
+ of a transaction collision, illegal command field, unclaimed cycle
+ (host initiated), or bus errors (collisions).
+ RETURN_UNSUPPORTED The SMBus operation is not supported.
+
+**/
+VOID
+EFIAPI
+SmBusQuickRead (
+ IN UINTN SmBusAddress,
+ OUT RETURN_STATUS *Status OPTIONAL
+ )
+{
+ ASSERT (!SMBUS_LIB_PEC (SmBusAddress));
+ ASSERT (SMBUS_LIB_COMMAND (SmBusAddress) == 0);
+ ASSERT (SMBUS_LIB_LENGTH (SmBusAddress) == 0);
+ ASSERT (SMBUS_LIB_RESERVED (SmBusAddress) == 0);
+ if (Status != NULL) {
+ *Status = RETURN_UNSUPPORTED;
+ }
+}
+
+/**
+ Executes an SMBUS quick write command.
+
+ Executes an SMBUS quick write command on the SMBUS device specified by SmBusAddress.
+ Only the SMBUS slave address field of SmBusAddress is required.
+ If Status is not NULL, then the status of the executed command is returned in Status.
+ If PEC is set in SmBusAddress, then ASSERT().
+ If Command in SmBusAddress is not zero, then ASSERT().
+ If Length in SmBusAddress is not zero, then ASSERT().
+ If any reserved bits of SmBusAddress are set, then ASSERT().
+
+ @param SmBusAddress Address that encodes the SMBUS Slave Address,
+ SMBUS Command, SMBUS Data Length, and PEC.
+ @param Status Return status for the executed command.
+ This is an optional parameter and may be NULL.
+ RETURN_SUCCESS The SMBUS command was executed.
+ RETURN_TIMEOUT A timeout occurred while executing the SMBUS command.
+ RETURN_DEVICE_ERROR The request was not completed because a failure
+ reflected in the Host Status Register bit. Device errors are a result
+ of a transaction collision, illegal command field, unclaimed cycle
+ (host initiated), or bus errors (collisions).
+ RETURN_UNSUPPORTED The SMBus operation is not supported.
+
+**/
+VOID
+EFIAPI
+SmBusQuickWrite (
+ IN UINTN SmBusAddress,
+ OUT RETURN_STATUS *Status OPTIONAL
+ )
+{
+ ASSERT (!SMBUS_LIB_PEC (SmBusAddress));
+ ASSERT (SMBUS_LIB_COMMAND (SmBusAddress) == 0);
+ ASSERT (SMBUS_LIB_LENGTH (SmBusAddress) == 0);
+ ASSERT (SMBUS_LIB_RESERVED (SmBusAddress) == 0);
+ if (Status != NULL) {
+ *Status = RETURN_UNSUPPORTED;
+ }
+}
+
+/**
+ Executes an SMBUS receive byte command.
+
+ Executes an SMBUS receive byte command on the SMBUS device specified by SmBusAddress.
+ Only the SMBUS slave address field of SmBusAddress is required.
+ The byte received from the SMBUS is returned.
+ If Status is not NULL, then the status of the executed command is returned in Status.
+ If Command in SmBusAddress is not zero, then ASSERT().
+ If Length in SmBusAddress is not zero, then ASSERT().
+ If any reserved bits of SmBusAddress are set, then ASSERT().
+
+ @param SmBusAddress Address that encodes the SMBUS Slave Address,
+ SMBUS Command, SMBUS Data Length, and PEC.
+ @param Status Return status for the executed command.
+ This is an optional parameter and may be NULL.
+ RETURN_SUCCESS The SMBUS command was executed.
+ RETURN_TIMEOUT A timeout occurred while executing the SMBUS command.
+ RETURN_DEVICE_ERROR The request was not completed because a failure
+ reflected in the Host Status Register bit. Device errors are a result
+ of a transaction collision, illegal command field, unclaimed cycle
+ (host initiated), or bus errors (collisions).
+ RETURN_CRC_ERROR The checksum is not correct (PEC is incorrect)
+ RETURN_UNSUPPORTED The SMBus operation is not supported.
+
+ @return The byte received from the SMBUS.
+
+**/
+UINT8
+EFIAPI
+SmBusReceiveByte (
+ IN UINTN SmBusAddress,
+ OUT RETURN_STATUS *Status OPTIONAL
+ )
+{
+ ASSERT (SMBUS_LIB_COMMAND (SmBusAddress) == 0);
+ ASSERT (SMBUS_LIB_LENGTH (SmBusAddress) == 0);
+ ASSERT (SMBUS_LIB_RESERVED (SmBusAddress) == 0);
+ if (Status != NULL) {
+ *Status = RETURN_UNSUPPORTED;
+ }
+ return 0;
+}
+
+/**
+ Executes an SMBUS send byte command.
+
+ Executes an SMBUS send byte command on the SMBUS device specified by SmBusAddress.
+ The byte specified by Value is sent.
+ Only the SMBUS slave address field of SmBusAddress is required. Value is returned.
+ If Status is not NULL, then the status of the executed command is returned in Status.
+ If Command in SmBusAddress is not zero, then ASSERT().
+ If Length in SmBusAddress is not zero, then ASSERT().
+ If any reserved bits of SmBusAddress are set, then ASSERT().
+
+ @param SmBusAddress Address that encodes the SMBUS Slave Address,
+ SMBUS Command, SMBUS Data Length, and PEC.
+ @param Value The 8-bit value to send.
+ @param Status Return status for the executed command.
+ This is an optional parameter and may be NULL.
+ RETURN_SUCCESS The SMBUS command was executed.
+ RETURN_TIMEOUT A timeout occurred while executing the SMBUS command.
+ RETURN_DEVICE_ERROR The request was not completed because a failure
+ reflected in the Host Status Register bit. Device errors are a result
+ of a transaction collision, illegal command field, unclaimed cycle
+ (host initiated), or bus errors (collisions).
+ RETURN_CRC_ERROR The checksum is not correct (PEC is incorrect)
+ RETURN_UNSUPPORTED The SMBus operation is not supported.
+
+ @return The parameter of Value.
+
+**/
+UINT8
+EFIAPI
+SmBusSendByte (
+ IN UINTN SmBusAddress,
+ IN UINT8 Value,
+ OUT RETURN_STATUS *Status OPTIONAL
+ )
+{
+ ASSERT (SMBUS_LIB_COMMAND (SmBusAddress) == 0);
+ ASSERT (SMBUS_LIB_LENGTH (SmBusAddress) == 0);
+ ASSERT (SMBUS_LIB_RESERVED (SmBusAddress) == 0);
+ if (Status != NULL) {
+ *Status = RETURN_UNSUPPORTED;
+ }
+ return 0;
+}
+
+/**
+ Executes an SMBUS read data byte command.
+
+ Executes an SMBUS read data byte command on the SMBUS device specified by SmBusAddress.
+ Only the SMBUS slave address and SMBUS command fields of SmBusAddress are required.
+ The 8-bit value read from the SMBUS is returned.
+ If Status is not NULL, then the status of the executed command is returned in Status.
+ If Length in SmBusAddress is not zero, then ASSERT().
+ If any reserved bits of SmBusAddress are set, then ASSERT().
+
+ @param SmBusAddress Address that encodes the SMBUS Slave Address,
+ SMBUS Command, SMBUS Data Length, and PEC.
+ @param Status Return status for the executed command.
+ This is an optional parameter and may be NULL.
+ RETURN_SUCCESS The SMBUS command was executed.
+ RETURN_TIMEOUT A timeout occurred while executing the SMBUS command.
+ RETURN_DEVICE_ERROR The request was not completed because a failure
+ reflected in the Host Status Register bit. Device errors are a result
+ of a transaction collision, illegal command field, unclaimed cycle
+ (host initiated), or bus errors (collisions).
+ RETURN_CRC_ERROR The checksum is not correct (PEC is incorrect)
+ RETURN_UNSUPPORTED The SMBus operation is not supported.
+
+ @return The byte read from the SMBUS.
+
+**/
+UINT8
+EFIAPI
+SmBusReadDataByte (
+ IN UINTN SmBusAddress,
+ OUT RETURN_STATUS *Status OPTIONAL
+ )
+{
+ ASSERT (SMBUS_LIB_LENGTH (SmBusAddress) == 0);
+ ASSERT (SMBUS_LIB_RESERVED (SmBusAddress) == 0);
+ if (Status != NULL) {
+ *Status = RETURN_UNSUPPORTED;
+ }
+ return 0;
+}
+
+/**
+ Executes an SMBUS write data byte command.
+
+ Executes an SMBUS write data byte command on the SMBUS device specified by SmBusAddress.
+ The 8-bit value specified by Value is written.
+ Only the SMBUS slave address and SMBUS command fields of SmBusAddress are required.
+ Value is returned.
+ If Status is not NULL, then the status of the executed command is returned in Status.
+ If Length in SmBusAddress is not zero, then ASSERT().
+ If any reserved bits of SmBusAddress are set, then ASSERT().
+
+ @param SmBusAddress Address that encodes the SMBUS Slave Address,
+ SMBUS Command, SMBUS Data Length, and PEC.
+ @param Value The 8-bit value to write.
+ @param Status Return status for the executed command.
+ This is an optional parameter and may be NULL.
+ RETURN_SUCCESS The SMBUS command was executed.
+ RETURN_TIMEOUT A timeout occurred while executing the SMBUS command.
+ RETURN_DEVICE_ERROR The request was not completed because a failure
+ reflected in the Host Status Register bit. Device errors are a result
+ of a transaction collision, illegal command field, unclaimed cycle
+ (host initiated), or bus errors (collisions).
+ RETURN_CRC_ERROR The checksum is not correct (PEC is incorrect)
+ RETURN_UNSUPPORTED The SMBus operation is not supported.
+
+ @return The parameter of Value.
+
+**/
+UINT8
+EFIAPI
+SmBusWriteDataByte (
+ IN UINTN SmBusAddress,
+ IN UINT8 Value,
+ OUT RETURN_STATUS *Status OPTIONAL
+ )
+{
+ ASSERT (SMBUS_LIB_LENGTH (SmBusAddress) == 0);
+ ASSERT (SMBUS_LIB_RESERVED (SmBusAddress) == 0);
+ if (Status != NULL) {
+ *Status = RETURN_UNSUPPORTED;
+ }
+ return 0;
+}
+
+/**
+ Executes an SMBUS read data word command.
+
+ Executes an SMBUS read data word command on the SMBUS device specified by SmBusAddress.
+ Only the SMBUS slave address and SMBUS command fields of SmBusAddress are required.
+ The 16-bit value read from the SMBUS is returned.
+ If Status is not NULL, then the status of the executed command is returned in Status.
+ If Length in SmBusAddress is not zero, then ASSERT().
+ If any reserved bits of SmBusAddress are set, then ASSERT().
+
+ @param SmBusAddress Address that encodes the SMBUS Slave Address,
+ SMBUS Command, SMBUS Data Length, and PEC.
+ @param Status Return status for the executed command.
+ This is an optional parameter and may be NULL.
+ RETURN_SUCCESS The SMBUS command was executed.
+ RETURN_TIMEOUT A timeout occurred while executing the SMBUS command.
+ RETURN_DEVICE_ERROR The request was not completed because a failure
+ reflected in the Host Status Register bit. Device errors are a result
+ of a transaction collision, illegal command field, unclaimed cycle
+ (host initiated), or bus errors (collisions).
+ RETURN_CRC_ERROR The checksum is not correct (PEC is incorrect)
+ RETURN_UNSUPPORTED The SMBus operation is not supported.
+
+ @return The byte read from the SMBUS.
+
+**/
+UINT16
+EFIAPI
+SmBusReadDataWord (
+ IN UINTN SmBusAddress,
+ OUT RETURN_STATUS *Status OPTIONAL
+ )
+{
+ ASSERT (SMBUS_LIB_LENGTH (SmBusAddress) == 0);
+ ASSERT (SMBUS_LIB_RESERVED (SmBusAddress) == 0);
+ if (Status != NULL) {
+ *Status = RETURN_UNSUPPORTED;
+ }
+ return 0;
+}
+
+/**
+ Executes an SMBUS write data word command.
+
+ Executes an SMBUS write data word command on the SMBUS device specified by SmBusAddress.
+ The 16-bit value specified by Value is written.
+ Only the SMBUS slave address and SMBUS command fields of SmBusAddress are required.
+ Value is returned.
+ If Status is not NULL, then the status of the executed command is returned in Status.
+ If Length in SmBusAddress is not zero, then ASSERT().
+ If any reserved bits of SmBusAddress are set, then ASSERT().
+
+ @param SmBusAddress Address that encodes the SMBUS Slave Address,
+ SMBUS Command, SMBUS Data Length, and PEC.
+ @param Value The 16-bit value to write.
+ @param Status Return status for the executed command.
+ This is an optional parameter and may be NULL.
+ RETURN_SUCCESS The SMBUS command was executed.
+ RETURN_TIMEOUT A timeout occurred while executing the SMBUS command.
+ RETURN_DEVICE_ERROR The request was not completed because a failure
+ reflected in the Host Status Register bit. Device errors are a result
+ of a transaction collision, illegal command field, unclaimed cycle
+ (host initiated), or bus errors (collisions).
+ RETURN_CRC_ERROR The checksum is not correct (PEC is incorrect)
+ RETURN_UNSUPPORTED The SMBus operation is not supported.
+
+ @return The parameter of Value.
+
+**/
+UINT16
+EFIAPI
+SmBusWriteDataWord (
+ IN UINTN SmBusAddress,
+ IN UINT16 Value,
+ OUT RETURN_STATUS *Status OPTIONAL
+ )
+{
+ ASSERT (SMBUS_LIB_LENGTH (SmBusAddress) == 0);
+ ASSERT (SMBUS_LIB_RESERVED (SmBusAddress) == 0);
+ if (Status != NULL) {
+ *Status = RETURN_UNSUPPORTED;
+ }
+ return 0;
+}
+
+/**
+ Executes an SMBUS process call command.
+
+ Executes an SMBUS process call command on the SMBUS device specified by SmBusAddress.
+ The 16-bit value specified by Value is written.
+ Only the SMBUS slave address and SMBUS command fields of SmBusAddress are required.
+ The 16-bit value returned by the process call command is returned.
+ If Status is not NULL, then the status of the executed command is returned in Status.
+ If Length in SmBusAddress is not zero, then ASSERT().
+ If any reserved bits of SmBusAddress are set, then ASSERT().
+
+ @param SmBusAddress Address that encodes the SMBUS Slave Address,
+ SMBUS Command, SMBUS Data Length, and PEC.
+ @param Value The 16-bit value to write.
+ @param Status Return status for the executed command.
+ This is an optional parameter and may be NULL.
+ RETURN_SUCCESS The SMBUS command was executed.
+ RETURN_TIMEOUT A timeout occurred while executing the SMBUS command.
+ RETURN_DEVICE_ERROR The request was not completed because a failure
+ reflected in the Host Status Register bit. Device errors are a result
+ of a transaction collision, illegal command field, unclaimed cycle
+ (host initiated), or bus errors (collisions).
+ RETURN_CRC_ERROR The checksum is not correct (PEC is incorrect)
+ RETURN_UNSUPPORTED The SMBus operation is not supported.
+
+ @return The 16-bit value returned by the process call command.
+
+**/
+UINT16
+EFIAPI
+SmBusProcessCall (
+ IN UINTN SmBusAddress,
+ IN UINT16 Value,
+ OUT RETURN_STATUS *Status OPTIONAL
+ )
+{
+ ASSERT (SMBUS_LIB_LENGTH (SmBusAddress) == 0);
+ ASSERT (SMBUS_LIB_RESERVED (SmBusAddress) == 0);
+ if (Status != NULL) {
+ *Status = RETURN_UNSUPPORTED;
+ }
+ return 0;
+}
+
+/**
+ Executes an SMBUS read block command.
+
+ Executes an SMBUS read block command on the SMBUS device specified by SmBusAddress.
+ Only the SMBUS slave address and SMBUS command fields of SmBusAddress are required.
+ Bytes are read from the SMBUS and stored in Buffer.
+ The number of bytes read is returned, and will never return a value larger than 32-bytes.
+ If Status is not NULL, then the status of the executed command is returned in Status.
+ It is the caller's responsibility to make sure Buffer is large enough for the total number of bytes read.
+ SMBUS supports a maximum transfer size of 32 bytes, so Buffer does not need to be any larger than 32 bytes.
+ If Length in SmBusAddress is not zero, then ASSERT().
+ If Buffer is NULL, then ASSERT().
+ If any reserved bits of SmBusAddress are set, then ASSERT().
+
+ @param SmBusAddress Address that encodes the SMBUS Slave Address,
+ SMBUS Command, SMBUS Data Length, and PEC.
+ @param Buffer Pointer to the buffer to store the bytes read from the SMBUS.
+ @param Status Return status for the executed command.
+ This is an optional parameter and may be NULL.
+ RETURN_SUCCESS The SMBUS command was executed.
+ RETURN_TIMEOUT A timeout occurred while executing the SMBUS command.
+ RETURN_DEVICE_ERROR The request was not completed because a failure
+ reflected in the Host Status Register bit. Device errors are a result
+ of a transaction collision, illegal command field, unclaimed cycle
+ (host initiated), or bus errors (collisions).
+ RETURN_CRC_ERROR The checksum is not correct (PEC is incorrect)
+ RETURN_UNSUPPORTED The SMBus operation is not supported.
+
+ @return The number of bytes read.
+
+**/
+UINTN
+EFIAPI
+SmBusReadBlock (
+ IN UINTN SmBusAddress,
+ OUT VOID *Buffer,
+ OUT RETURN_STATUS *Status OPTIONAL
+ )
+{
+ ASSERT (Buffer != NULL);
+ ASSERT (SMBUS_LIB_LENGTH (SmBusAddress) == 0);
+ ASSERT (SMBUS_LIB_RESERVED (SmBusAddress) == 0);
+ if (Status != NULL) {
+ *Status = RETURN_UNSUPPORTED;
+ }
+ return 0;
+}
+
+/**
+ Executes an SMBUS write block command.
+
+ Executes an SMBUS write block command on the SMBUS device specified by SmBusAddress.
+ The SMBUS slave address, SMBUS command, and SMBUS length fields of SmBusAddress are required.
+ Bytes are written to the SMBUS from Buffer.
+ The number of bytes written is returned, and will never return a value larger than 32-bytes.
+ If Status is not NULL, then the status of the executed command is returned in Status.
+ If Length in SmBusAddress is zero or greater than 32, then ASSERT().
+ If Buffer is NULL, then ASSERT().
+ If any reserved bits of SmBusAddress are set, then ASSERT().
+
+ @param SmBusAddress Address that encodes the SMBUS Slave Address,
+ SMBUS Command, SMBUS Data Length, and PEC.
+ @param Buffer Pointer to the buffer to store the bytes read from the SMBUS.
+ @param Status Return status for the executed command.
+ This is an optional parameter and may be NULL.
+ RETURN_TIMEOUT A timeout occurred while executing the SMBUS command.
+ RETURN_DEVICE_ERROR The request was not completed because a failure
+ reflected in the Host Status Register bit. Device errors are a result
+ of a transaction collision, illegal command field, unclaimed cycle
+ (host initiated), or bus errors (collisions).
+ RETURN_CRC_ERROR The checksum is not correct (PEC is incorrect)
+ RETURN_UNSUPPORTED The SMBus operation is not supported.
+
+ @return The number of bytes written.
+
+**/
+UINTN
+EFIAPI
+SmBusWriteBlock (
+ IN UINTN SmBusAddress,
+ OUT VOID *Buffer,
+ OUT RETURN_STATUS *Status OPTIONAL
+ )
+{
+ ASSERT (Buffer != NULL);
+ ASSERT (SMBUS_LIB_LENGTH (SmBusAddress) >= 1);
+ ASSERT (SMBUS_LIB_LENGTH (SmBusAddress) <= 32);
+ ASSERT (SMBUS_LIB_RESERVED (SmBusAddress) == 0);
+ if (Status != NULL) {
+ *Status = RETURN_UNSUPPORTED;
+ }
+ return 0;
+}
+
+/**
+ Executes an SMBUS block process call command.
+
+ Executes an SMBUS block process call command on the SMBUS device specified by SmBusAddress.
+ The SMBUS slave address, SMBUS command, and SMBUS length fields of SmBusAddress are required.
+ Bytes are written to the SMBUS from WriteBuffer. Bytes are then read from the SMBUS into ReadBuffer.
+ If Status is not NULL, then the status of the executed command is returned in Status.
+ It is the caller's responsibility to make sure ReadBuffer is large enough for the total number of bytes read.
+ SMBUS supports a maximum transfer size of 32 bytes, so Buffer does not need to be any larger than 32 bytes.
+ If Length in SmBusAddress is zero or greater than 32, then ASSERT().
+ If WriteBuffer is NULL, then ASSERT().
+ If ReadBuffer is NULL, then ASSERT().
+ If any reserved bits of SmBusAddress are set, then ASSERT().
+
+ @param SmBusAddress Address that encodes the SMBUS Slave Address,
+ SMBUS Command, SMBUS Data Length, and PEC.
+ @param WriteBuffer Pointer to the buffer of bytes to write to the SMBUS.
+ @param ReadBuffer Pointer to the buffer of bytes to read from the SMBUS.
+ @param Status Return status for the executed command.
+ This is an optional parameter and may be NULL.
+ RETURN_TIMEOUT A timeout occurred while executing the SMBUS command.
+ RETURN_DEVICE_ERROR The request was not completed because a failure
+ reflected in the Host Status Register bit. Device errors are a result
+ of a transaction collision, illegal command field, unclaimed cycle
+ (host initiated), or bus errors (collisions).
+ RETURN_CRC_ERROR The checksum is not correct (PEC is incorrect)
+ RETURN_UNSUPPORTED The SMBus operation is not supported.
+
+ @return The number of bytes written.
+
+**/
+UINTN
+EFIAPI
+SmBusBlockProcessCall (
+ IN UINTN SmBusAddress,
+ IN VOID *WriteBuffer,
+ OUT VOID *ReadBuffer,
+ OUT RETURN_STATUS *Status OPTIONAL
+ )
+{
+ ASSERT (WriteBuffer != NULL);
+ ASSERT (ReadBuffer != NULL);
+ ASSERT (SMBUS_LIB_LENGTH (SmBusAddress) >= 1);
+ ASSERT (SMBUS_LIB_LENGTH (SmBusAddress) <= 32);
+ ASSERT (SMBUS_LIB_RESERVED (SmBusAddress) == 0);
+ if (Status != NULL) {
+ *Status = RETURN_UNSUPPORTED;
+ }
+ return 0;
+}
diff --git a/MdePkg/Library/BaseSmbusLibNull/BaseSmbusLibNull.inf b/MdePkg/Library/BaseSmbusLibNull/BaseSmbusLibNull.inf
new file mode 100644
index 000000000..c0c0f6b6d
--- /dev/null
+++ b/MdePkg/Library/BaseSmbusLibNull/BaseSmbusLibNull.inf
@@ -0,0 +1,34 @@
+## @file
+# Null implementation of the SMBUS Library.
+#
+# Copyright (c) 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.
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = BaseSmbusLibNull
+ FILE_GUID = E2ECA273-A1C0-407E-9A5C-F10C55142196
+ MODULE_TYPE = BASE
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = SmbusLib
+
+#
+# VALID_ARCHITECTURES = IA32 X64 IPF EBC
+#
+
+[Sources]
+ BaseSmbusLibNull.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+
+[LibraryClasses]
+ DebugLib
diff --git a/MdePkg/Library/DxePcdLib/DxePcdLib.c b/MdePkg/Library/DxePcdLib/DxePcdLib.c
index a7303e800..bc87c4e6a 100644
--- a/MdePkg/Library/DxePcdLib/DxePcdLib.c
+++ b/MdePkg/Library/DxePcdLib/DxePcdLib.c
@@ -1,7 +1,7 @@
/** @file
Implementation of PcdLib class library for DXE phase.
-Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>
+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
@@ -18,17 +18,23 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#include <Protocol/Pcd.h>
#include <Protocol/PiPcd.h>
+#include <Protocol/PcdInfo.h>
+#include <Protocol/PiPcdInfo.h>
#include <Library/PcdLib.h>
#include <Library/DebugLib.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Library/BaseMemoryLib.h>
-PCD_PROTOCOL *mPcd = NULL;
-EFI_PCD_PROTOCOL *mPiPcd = NULL;
+PCD_PROTOCOL *mPcd = NULL;
+EFI_PCD_PROTOCOL *mPiPcd = NULL;
+GET_PCD_INFO_PROTOCOL *mPcdInfo = NULL;
+EFI_GET_PCD_INFO_PROTOCOL *mPiPcdInfo = NULL;
/**
Retrieves the PI PCD protocol from the handle database.
+
+ @retval EFI_PCD_PROTOCOL * The pointer to the EFI_PCD_PROTOCOL.
**/
EFI_PCD_PROTOCOL *
EFIAPI
@@ -52,6 +58,8 @@ GetPiPcdProtocol (
/**
Retrieves the PCD protocol from the handle database.
+
+ @retval PCD_PROTOCOL * The pointer to the PCD_PROTOCOL.
**/
PCD_PROTOCOL *
EFIAPI
@@ -73,6 +81,45 @@ GetPcdProtocol (
return mPcd;
}
+/**
+ Retrieves the PI PCD info protocol from the handle database.
+
+ @retval EFI_GET_PCD_INFO_PROTOCOL * The pointer to the EFI_GET_PCD_INFO_PROTOCOL defined in PI 1.2.1 Vol 3.
+**/
+EFI_GET_PCD_INFO_PROTOCOL *
+GetPiPcdInfoProtocolPointer (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+
+ if (mPiPcdInfo == NULL) {
+ Status = gBS->LocateProtocol (&gEfiGetPcdInfoProtocolGuid, NULL, (VOID **)&mPiPcdInfo);
+ ASSERT_EFI_ERROR (Status);
+ ASSERT (mPiPcdInfo != NULL);
+ }
+ return mPiPcdInfo;
+}
+
+/**
+ Retrieves the PCD info protocol from the handle database.
+
+ @retval GET_PCD_INFO_PROTOCOL * The pointer to the GET_PCD_INFO_PROTOCOL.
+**/
+GET_PCD_INFO_PROTOCOL *
+GetPcdInfoProtocolPointer (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+
+ if (mPcdInfo == NULL) {
+ Status = gBS->LocateProtocol (&gGetPcdInfoProtocolGuid, NULL, (VOID **)&mPcdInfo);
+ ASSERT_EFI_ERROR (Status);
+ ASSERT (mPcdInfo != NULL);
+ }
+ return mPcdInfo;
+}
/**
This function provides a means by which SKU support can be established in the PCD infrastructure.
@@ -955,10 +1002,7 @@ LibPcdGetNextToken (
IN UINTN TokenNumber
)
{
- EFI_STATUS Status;
-
- Status = GetPiPcdProtocol()->GetNextToken (Guid, &TokenNumber);
- ASSERT_EFI_ERROR (Status);
+ GetPiPcdProtocol()->GetNextToken (Guid, &TokenNumber);
return TokenNumber;
}
@@ -984,10 +1028,7 @@ LibPcdGetNextTokenSpace (
IN CONST GUID *TokenSpaceGuid
)
{
- EFI_STATUS Status;
-
- Status = GetPiPcdProtocol()->GetNextTokenSpace (&TokenSpaceGuid);
- ASSERT_EFI_ERROR (Status);
+ GetPiPcdProtocol()->GetNextTokenSpace (&TokenSpaceGuid);
return (GUID *)TokenSpaceGuid;
}
@@ -1043,5 +1084,78 @@ LibPatchPcdSetPtr (
return (VOID *) Buffer;
}
+/**
+ Retrieve additional information associated with a PCD token.
+
+ This includes information such as the type of value the TokenNumber is associated with as well as possible
+ human readable name that is associated with the token.
+ If TokenNumber is not in the default token space specified, then ASSERT().
+
+ @param[in] TokenNumber The PCD token number.
+ @param[out] PcdInfo The returned information associated with the requested TokenNumber.
+ The caller is responsible for freeing the buffer that is allocated by callee for PcdInfo->PcdName.
+**/
+VOID
+EFIAPI
+LibPcdGetInfo (
+ IN UINTN TokenNumber,
+ OUT PCD_INFO *PcdInfo
+ )
+{
+ EFI_STATUS Status;
+
+ Status = GetPcdInfoProtocolPointer()->GetInfo (TokenNumber, (EFI_PCD_INFO *) PcdInfo);
+ ASSERT_EFI_ERROR (Status);
+}
+
+/**
+ Retrieve additional information associated with a PCD token.
+
+ This includes information such as the type of value the TokenNumber is associated with as well as possible
+ human readable name that is associated with the token.
+
+ If TokenNumber is not in the token space specified by Guid, then ASSERT().
+
+ @param[in] Guid The 128-bit unique value that designates the namespace from which to extract the value.
+ @param[in] TokenNumber The PCD token number.
+ @param[out] PcdInfo The returned information associated with the requested TokenNumber.
+ The caller is responsible for freeing the buffer that is allocated by callee for PcdInfo->PcdName.
+**/
+VOID
+EFIAPI
+LibPcdGetInfoEx (
+ IN CONST GUID *Guid,
+ IN UINTN TokenNumber,
+ OUT PCD_INFO *PcdInfo
+ )
+{
+ EFI_STATUS Status;
+
+ Status = GetPiPcdInfoProtocolPointer()->GetInfo (Guid, TokenNumber, (EFI_PCD_INFO *) PcdInfo);
+ ASSERT_EFI_ERROR (Status);
+}
+
+/**
+ Retrieve the currently set SKU Id.
+
+ If the sku id got >= PCD_MAX_SKU_ID, then ASSERT().
+
+ @return The currently set SKU Id. If the platform has not set at a SKU Id, then the
+ default SKU Id value of 0 is returned. If the platform has set a SKU Id, then the currently set SKU
+ Id is returned.
+**/
+UINTN
+EFIAPI
+LibPcdGetSku (
+ VOID
+ )
+{
+ UINTN SkuId;
+
+ SkuId = GetPiPcdInfoProtocolPointer()->GetSku ();
+ ASSERT (SkuId < PCD_MAX_SKU_ID);
+
+ return SkuId;
+}
diff --git a/MdePkg/Library/DxePcdLib/DxePcdLib.inf b/MdePkg/Library/DxePcdLib/DxePcdLib.inf
index db06967c9..a520f069b 100644
--- a/MdePkg/Library/DxePcdLib/DxePcdLib.inf
+++ b/MdePkg/Library/DxePcdLib/DxePcdLib.inf
@@ -1,7 +1,7 @@
## @file
# Instance of PCD Library using PCD Protocol.
#
-# There are two PCD PPIs as follows:
+# There are two PCD PROTOCOLs as follows:
# 1) PCD_PROTOCOL
# It is EDKII implementation which support Dynamic/DynamicEx Pcds.
# 2) EFI_PCD_PROTOCOL
@@ -13,7 +13,7 @@
# This library instance uses the PCD_PROTOCOL to handle dynamic PCD request and use
# EFI_PCD_PROTOCOL to handle dynamicEx type PCD.
#
-# Copyright (c) 2007 - 2011, Intel Corporation. All rights reserved.<BR>
+# 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
@@ -54,6 +54,8 @@
[Protocols]
gPcdProtocolGuid ## CONSUMES
gEfiPcdProtocolGuid ## CONSUMES
+ gGetPcdInfoProtocolGuid ## SOMETIMES_CONSUMES
+ gEfiGetPcdInfoProtocolGuid ## SOMETIMES_CONSUMES
[Depex.common.DXE_DRIVER, Depex.common.DXE_RUNTIME_DRIVER, Depex.common.DXE_SAL_DRIVER, Depex.common.DXE_SMM_DRIVER]
gEfiPcdProtocolGuid
diff --git a/MdePkg/Library/PeiPcdLib/PeiPcdLib.c b/MdePkg/Library/PeiPcdLib/PeiPcdLib.c
index 4d9179902..a57751f41 100644
--- a/MdePkg/Library/PeiPcdLib/PeiPcdLib.c
+++ b/MdePkg/Library/PeiPcdLib/PeiPcdLib.c
@@ -1,7 +1,7 @@
/** @file
Implementation of PcdLib class library for PEI phase.
-Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>
+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
@@ -20,6 +20,8 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#include <Ppi/Pcd.h>
#include <Ppi/PiPcd.h>
+#include <Ppi/PcdInfo.h>
+#include <Ppi/PiPcdInfo.h>
#include <Library/PeiServicesLib.h>
#include <Library/PcdLib.h>
@@ -71,7 +73,53 @@ GetPiPcdPpiPointer (
return PiPcdPpi;
}
+
+/**
+ Retrieve the GET_PCD_INFO_PPI pointer.
+
+ This function is to locate GET_PCD_INFO_PPI PPI via PeiService.
+ If fail to locate GET_PCD_INFO_PPI, then ASSERT_EFI_ERROR().
+
+ @retval GET_PCD_INFO_PPI * The pointer to the GET_PCD_INFO_PPI.
+
+**/
+GET_PCD_INFO_PPI *
+GetPcdInfoPpiPointer (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+ GET_PCD_INFO_PPI *PcdInfoPpi;
+
+ Status = PeiServicesLocatePpi (&gGetPcdInfoPpiGuid, 0, NULL, (VOID **)&PcdInfoPpi);
+ ASSERT_EFI_ERROR (Status);
+
+ return PcdInfoPpi;
+}
+
+/**
+ Retrieve the pointer of EFI_GET_PCD_INFO_PPI defined in PI 1.2.1 Vol 3.
+
+ This function is to locate EFI_GET_PCD_INFO_PPI PPI via PeiService.
+ If fail to locate EFI_GET_PCD_INFO_PPI, then ASSERT_EFI_ERROR().
+
+ @retval EFI_GET_PCD_INFO_PPI * The pointer to the EFI_GET_PCD_INFO_PPI.
+
+**/
+EFI_GET_PCD_INFO_PPI *
+GetPiPcdInfoPpiPointer (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+ EFI_GET_PCD_INFO_PPI *PiPcdInfoPpi;
+
+ Status = PeiServicesLocatePpi (&gEfiGetPcdInfoPpiGuid, 0, NULL, (VOID **)&PiPcdInfoPpi);
+ ASSERT_EFI_ERROR (Status);
+ return PiPcdInfoPpi;
+}
+
/**
This function provides a means by which SKU support can be established in the PCD infrastructure.
@@ -962,11 +1010,7 @@ LibPcdGetNextToken (
IN UINTN TokenNumber
)
{
- EFI_STATUS Status;
-
- Status = (GetPiPcdPpiPointer ())->GetNextToken (Guid, &TokenNumber);
-
- ASSERT_EFI_ERROR (Status);
+ (GetPiPcdPpiPointer ())->GetNextToken (Guid, &TokenNumber);
return TokenNumber;
}
@@ -991,11 +1035,7 @@ LibPcdGetNextTokenSpace (
IN CONST GUID *TokenSpaceGuid
)
{
- EFI_STATUS Status;
-
- Status = (GetPiPcdPpiPointer ())->GetNextTokenSpace (&TokenSpaceGuid);
-
- ASSERT_EFI_ERROR (Status);
+ (GetPiPcdPpiPointer ())->GetNextTokenSpace (&TokenSpaceGuid);
return (GUID *) TokenSpaceGuid;
}
@@ -1052,4 +1092,77 @@ LibPatchPcdSetPtr (
return (VOID *) Buffer;
}
+/**
+ Retrieve additional information associated with a PCD token.
+
+ This includes information such as the type of value the TokenNumber is associated with as well as possible
+ human readable name that is associated with the token.
+ If TokenNumber is not in the default token space specified, then ASSERT().
+
+ @param[in] TokenNumber The PCD token number.
+ @param[out] PcdInfo The returned information associated with the requested TokenNumber.
+ The caller is responsible for freeing the buffer that is allocated by callee for PcdInfo->PcdName.
+**/
+VOID
+EFIAPI
+LibPcdGetInfo (
+ IN UINTN TokenNumber,
+ OUT PCD_INFO *PcdInfo
+ )
+{
+ EFI_STATUS Status;
+
+ Status = GetPcdInfoPpiPointer()->GetInfo (TokenNumber, (EFI_PCD_INFO *) PcdInfo);
+ ASSERT_EFI_ERROR (Status);
+}
+
+/**
+ Retrieve additional information associated with a PCD token.
+
+ This includes information such as the type of value the TokenNumber is associated with as well as possible
+ human readable name that is associated with the token.
+
+ If TokenNumber is not in the token space specified by Guid, then ASSERT().
+
+ @param[in] Guid The 128-bit unique value that designates the namespace from which to extract the value.
+ @param[in] TokenNumber The PCD token number.
+ @param[out] PcdInfo The returned information associated with the requested TokenNumber.
+ The caller is responsible for freeing the buffer that is allocated by callee for PcdInfo->PcdName.
+**/
+VOID
+EFIAPI
+LibPcdGetInfoEx (
+ IN CONST GUID *Guid,
+ IN UINTN TokenNumber,
+ OUT PCD_INFO *PcdInfo
+ )
+{
+ EFI_STATUS Status;
+
+ Status = GetPiPcdInfoPpiPointer()->GetInfo (Guid, TokenNumber, (EFI_PCD_INFO *) PcdInfo);
+ ASSERT_EFI_ERROR (Status);
+}
+
+/**
+ Retrieve the currently set SKU Id.
+
+ If the sku id got >= PCD_MAX_SKU_ID, then ASSERT().
+
+ @return The currently set SKU Id. If the platform has not set at a SKU Id, then the
+ default SKU Id value of 0 is returned. If the platform has set a SKU Id, then the currently set SKU
+ Id is returned.
+**/
+UINTN
+EFIAPI
+LibPcdGetSku (
+ VOID
+ )
+{
+ UINTN SkuId;
+
+ SkuId = GetPiPcdInfoPpiPointer()->GetSku ();
+ ASSERT (SkuId < PCD_MAX_SKU_ID);
+
+ return SkuId;
+}
diff --git a/MdePkg/Library/PeiPcdLib/PeiPcdLib.inf b/MdePkg/Library/PeiPcdLib/PeiPcdLib.inf
index 814c8f6a9..b9d88eff8 100644
--- a/MdePkg/Library/PeiPcdLib/PeiPcdLib.inf
+++ b/MdePkg/Library/PeiPcdLib/PeiPcdLib.inf
@@ -15,7 +15,7 @@
#
# PCD Library that uses the PCD PPI to access Dynamic and DynamicEx PCD entries
#
-# Copyright (c) 2007 - 2011, Intel Corporation. All rights reserved.<BR>
+# 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
@@ -57,7 +57,9 @@
[Ppis]
gPcdPpiGuid ## CONSUMES
gEfiPeiPcdPpiGuid ## CONSUMES
-
+ gGetPcdInfoPpiGuid ## SOMETIMES_CONSUMES
+ gEfiGetPcdInfoPpiGuid ## SOMETIMES_CONSUMES
+
[Depex.common.PEIM]
gEfiPeiPcdPpiGuid
- \ No newline at end of file
+
diff --git a/MdePkg/Library/PeiServicesTablePointerLibIdt/PeiServicesTablePointer.c b/MdePkg/Library/PeiServicesTablePointerLibIdt/PeiServicesTablePointer.c
index c5fb8f552..4e3f013ed 100644
--- a/MdePkg/Library/PeiServicesTablePointerLibIdt/PeiServicesTablePointer.c
+++ b/MdePkg/Library/PeiServicesTablePointerLibIdt/PeiServicesTablePointer.c
@@ -4,7 +4,7 @@
According to PI specification, the peiservice pointer is stored prior at IDT
table in IA32 and x64 architecture.
- Copyright (c) 2006 - 2008, Intel Corporation. All rights reserved.<BR>
+ 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
@@ -20,6 +20,8 @@
#include <Library/BaseLib.h>
#include <Library/PeiServicesTablePointerLib.h>
#include <Library/DebugLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Ppi/TemporaryRamSupport.h>
/**
Retrieves the cached value of the PEI Services Table pointer.
@@ -67,11 +69,43 @@ SetPeiServicesTablePointer (
IN CONST EFI_PEI_SERVICES ** PeiServicesTablePointer
)
{
- IA32_DESCRIPTOR Idtr;
+ IA32_DESCRIPTOR Idtr;
+ EFI_PHYSICAL_ADDRESS IdtBase;
+ EFI_STATUS Status;
+ EFI_PEI_TEMPORARY_RAM_SUPPORT_PPI *TemporaryRamSupportPpi;
ASSERT (PeiServicesTablePointer != NULL);
AsmReadIdtr (&Idtr);
- (*(UINTN*)(Idtr.Base - sizeof (UINTN))) = (UINTN)PeiServicesTablePointer;
+ if ((*(UINTN*)(Idtr.Base - sizeof (UINTN))) != (UINTN)PeiServicesTablePointer) {
+ (*(UINTN*)(Idtr.Base - sizeof (UINTN))) = (UINTN)PeiServicesTablePointer;
+ Status = (*PeiServicesTablePointer)->LocatePpi (
+ PeiServicesTablePointer,
+ &gEfiTemporaryRamSupportPpiGuid,
+ 0,
+ NULL,
+ (VOID**)&TemporaryRamSupportPpi
+ );
+
+ if (EFI_ERROR (Status)) {
+ //
+ // If TemporaryRamSupportPpi is not found, Idt table needs to be migrated into memory.
+ //
+ Status = (*PeiServicesTablePointer)->AllocatePages (
+ PeiServicesTablePointer,
+ EfiBootServicesCode,
+ EFI_SIZE_TO_PAGES(Idtr.Limit + 1 + sizeof (UINTN)),
+ &IdtBase
+ );
+ if (!EFI_ERROR (Status)) {
+ //
+ // Migrate Idt table
+ //
+ CopyMem ((VOID *) (UINTN) IdtBase, (VOID *) (Idtr.Base - sizeof (UINTN)), Idtr.Limit + 1 + sizeof (UINTN));
+ Idtr.Base = (UINTN) IdtBase + sizeof (UINTN);
+ AsmWriteIdtr (&Idtr);
+ }
+ }
+ }
}
diff --git a/MdePkg/Library/PeiServicesTablePointerLibIdt/PeiServicesTablePointerLibIdt.inf b/MdePkg/Library/PeiServicesTablePointerLibIdt/PeiServicesTablePointerLibIdt.inf
index 1a54bd466..020a7f7e8 100644
--- a/MdePkg/Library/PeiServicesTablePointerLibIdt/PeiServicesTablePointerLibIdt.inf
+++ b/MdePkg/Library/PeiServicesTablePointerLibIdt/PeiServicesTablePointerLibIdt.inf
@@ -4,7 +4,7 @@
# PEI Services Table Pointer Library implementation that retrieves a pointer to the PEI
# Services Table from the IDT on IA-32 and x64.
#
-# Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>
+# 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
@@ -39,6 +39,7 @@
[LibraryClasses]
DebugLib
BaseLib
+ BaseMemoryLib
-
-
+[Ppis]
+ gEfiTemporaryRamSupportPpiGuid ## SOMETIMES_CONSUMES
diff --git a/MdePkg/Library/UefiDevicePathLib/DevicePathFromText.c b/MdePkg/Library/UefiDevicePathLib/DevicePathFromText.c
index 91203190e..8943191bd 100644
--- a/MdePkg/Library/UefiDevicePathLib/DevicePathFromText.c
+++ b/MdePkg/Library/UefiDevicePathLib/DevicePathFromText.c
@@ -479,7 +479,7 @@ StrToIPv4Addr (
UINTN Index;
for (Index = 0; Index < 4; Index++) {
- IPv4Addr->Addr[Index] = (UINT8) StrDecimalToUintn (SplitStr (Str, L'.'));
+ IPv4Addr->Addr[Index] = (UINT8) Strtoi (SplitStr (Str, L'.'));
}
}
@@ -1055,8 +1055,8 @@ DevPathFromTextAcpiAdr (
**/
EFI_DEVICE_PATH_PROTOCOL *
DevPathFromTextAta (
- IN CHAR16 *TextDeviceNode
- )
+IN CHAR16 *TextDeviceNode
+)
{
CHAR16 *PrimarySecondaryStr;
CHAR16 *SlaveMasterStr;
@@ -1064,18 +1064,31 @@ DevPathFromTextAta (
ATAPI_DEVICE_PATH *Atapi;
Atapi = (ATAPI_DEVICE_PATH *) CreateDeviceNode (
- MESSAGING_DEVICE_PATH,
- MSG_ATAPI_DP,
- (UINT16) sizeof (ATAPI_DEVICE_PATH)
- );
-
- PrimarySecondaryStr = GetNextParamStr (&TextDeviceNode);
- SlaveMasterStr = GetNextParamStr (&TextDeviceNode);
- LunStr = GetNextParamStr (&TextDeviceNode);
+ MESSAGING_DEVICE_PATH,
+ MSG_ATAPI_DP,
+ (UINT16) sizeof (ATAPI_DEVICE_PATH)
+ );
+
+ PrimarySecondaryStr = GetNextParamStr (&TextDeviceNode);
+ SlaveMasterStr = GetNextParamStr (&TextDeviceNode);
+ LunStr = GetNextParamStr (&TextDeviceNode);
+
+ if (StrCmp (PrimarySecondaryStr, L"Primary") == 0) {
+ Atapi->PrimarySecondary = 0;
+ } else if (StrCmp (PrimarySecondaryStr, L"Secondary") == 0) {
+ Atapi->PrimarySecondary = 1;
+ } else {
+ Atapi->PrimarySecondary = (UINT8) Strtoi (PrimarySecondaryStr);
+ }
+ if (StrCmp (SlaveMasterStr, L"Master") == 0) {
+ Atapi->SlaveMaster = 0;
+ } else if (StrCmp (SlaveMasterStr, L"Slave") == 0) {
+ Atapi->SlaveMaster = 1;
+ } else {
+ Atapi->SlaveMaster = (UINT8) Strtoi (SlaveMasterStr);
+ }
- Atapi->PrimarySecondary = (UINT8) ((StrCmp (PrimarySecondaryStr, L"Primary") == 0) ? 0 : 1);
- Atapi->SlaveMaster = (UINT8) ((StrCmp (SlaveMasterStr, L"Master") == 0) ? 0 : 1);
- Atapi->Lun = (UINT16) Strtoi (LunStr);
+ Atapi->Lun = (UINT16) Strtoi (LunStr);
return (EFI_DEVICE_PATH_PROTOCOL *) Atapi;
}
@@ -1880,8 +1893,12 @@ DevPathFromTextUart (
(UINT16) sizeof (UART_DEVICE_PATH)
);
- Uart->BaudRate = (StrCmp (BaudStr, L"DEFAULT") == 0) ? 115200 : StrDecimalToUintn (BaudStr);
- Uart->DataBits = (UINT8) ((StrCmp (DataBitsStr, L"DEFAULT") == 0) ? 8 : StrDecimalToUintn (DataBitsStr));
+ if (StrCmp (BaudStr, L"DEFAULT") == 0) {
+ Uart->BaudRate = 115200;
+ } else {
+ Strtoi64 (BaudStr, &Uart->BaudRate);
+ }
+ Uart->DataBits = (UINT8) ((StrCmp (DataBitsStr, L"DEFAULT") == 0) ? 8 : Strtoi (DataBitsStr));
switch (*ParityStr) {
case L'D':
Uart->Parity = 0;
@@ -1908,7 +1925,8 @@ DevPathFromTextUart (
break;
default:
- Uart->Parity = 0xff;
+ Uart->Parity = (UINT8) Strtoi (ParityStr);
+ break;
}
if (StrCmp (StopBitsStr, L"D") == 0) {
@@ -1920,7 +1938,7 @@ DevPathFromTextUart (
} else if (StrCmp (StopBitsStr, L"2") == 0) {
Uart->StopBits = (UINT8) 3;
} else {
- Uart->StopBits = 0xff;
+ Uart->StopBits = (UINT8) Strtoi (StopBitsStr);
}
return (EFI_DEVICE_PATH_PROTOCOL *) Uart;
@@ -2351,21 +2369,30 @@ DevPathFromTextUsbWwid (
CHAR16 *InterfaceNumStr;
CHAR16 *SerialNumberStr;
USB_WWID_DEVICE_PATH *UsbWwid;
-
- VIDStr = GetNextParamStr (&TextDeviceNode);
- PIDStr = GetNextParamStr (&TextDeviceNode);
- InterfaceNumStr = GetNextParamStr (&TextDeviceNode);
- SerialNumberStr = GetNextParamStr (&TextDeviceNode);
- UsbWwid = (USB_WWID_DEVICE_PATH *) CreateDeviceNode (
+ UINTN SerialNumberStrLen;
+
+ VIDStr = GetNextParamStr (&TextDeviceNode);
+ PIDStr = GetNextParamStr (&TextDeviceNode);
+ InterfaceNumStr = GetNextParamStr (&TextDeviceNode);
+ SerialNumberStr = GetNextParamStr (&TextDeviceNode);
+ SerialNumberStrLen = StrLen (SerialNumberStr);
+ if (SerialNumberStrLen >= 2 &&
+ SerialNumberStr[0] == L'\"' &&
+ SerialNumberStr[SerialNumberStrLen - 1] == L'\"'
+ ) {
+ SerialNumberStr[SerialNumberStrLen - 1] = L'\0';
+ SerialNumberStr++;
+ SerialNumberStrLen -= 2;
+ }
+ UsbWwid = (USB_WWID_DEVICE_PATH *) CreateDeviceNode (
MESSAGING_DEVICE_PATH,
MSG_USB_WWID_DP,
- (UINT16) (sizeof (USB_WWID_DEVICE_PATH) + StrSize (SerialNumberStr))
+ (UINT16) (sizeof (USB_WWID_DEVICE_PATH) + SerialNumberStrLen * sizeof (CHAR16))
);
-
- UsbWwid->VendorId = (UINT16) Strtoi (VIDStr);
- UsbWwid->ProductId = (UINT16) Strtoi (PIDStr);
- UsbWwid->InterfaceNumber = (UINT16) Strtoi (InterfaceNumStr);
- StrCpy ((CHAR16 *) ((UINT8 *) UsbWwid + sizeof (USB_WWID_DEVICE_PATH)), SerialNumberStr);
+ UsbWwid->VendorId = (UINT16) Strtoi (VIDStr);
+ UsbWwid->ProductId = (UINT16) Strtoi (PIDStr);
+ UsbWwid->InterfaceNumber = (UINT16) Strtoi (InterfaceNumStr);
+ StrnCpy ((CHAR16 *) ((UINT8 *) UsbWwid + sizeof (USB_WWID_DEVICE_PATH)), SerialNumberStr, SerialNumberStrLen);
return (EFI_DEVICE_PATH_PROTOCOL *) UsbWwid;
}
@@ -2526,7 +2553,7 @@ DevPathFromTextHD (
(UINT16) sizeof (HARDDRIVE_DEVICE_PATH)
);
- Hd->PartitionNumber = (UINT32) StrDecimalToUintn (PartitionStr);
+ Hd->PartitionNumber = (UINT32) Strtoi (PartitionStr);
ZeroMem (Hd->Signature, 16);
Hd->MBRType = (UINT8) 0;
@@ -2596,7 +2623,7 @@ DevPathFromTextCDROM (
**/
EFI_DEVICE_PATH_PROTOCOL *
-DevPathFromTextVenMEDIA (
+DevPathFromTextVenMedia (
IN CHAR16 *TextDeviceNode
)
{
@@ -2818,29 +2845,18 @@ DevPathFromTextSata (
CHAR16 *Param2;
CHAR16 *Param3;
- //
- // The PMPN is optional.
- //
Param1 = GetNextParamStr (&TextDeviceNode);
Param2 = GetNextParamStr (&TextDeviceNode);
- Param3 = NULL;
- if (!IS_NULL (TextDeviceNode)) {
- Param3 = GetNextParamStr (&TextDeviceNode);
- }
+ Param3 = GetNextParamStr (&TextDeviceNode);
Sata = (SATA_DEVICE_PATH *) CreateDeviceNode (
MESSAGING_DEVICE_PATH,
MSG_SATA_DP,
(UINT16) sizeof (SATA_DEVICE_PATH)
);
- Sata->HBAPortNumber = (UINT16) StrHexToUintn (Param1);
- if (Param3 != NULL) {
- Sata->PortMultiplierPortNumber = (UINT16) StrHexToUintn (Param2);
- Param2 = Param3;
- } else {
- Sata->PortMultiplierPortNumber = SATA_HBA_DIRECT_CONNECT_FLAG;
- }
- Sata->Lun = (UINT16) StrHexToUintn (Param2);
+ Sata->HBAPortNumber = (UINT16) Strtoi (Param1);
+ Sata->PortMultiplierPortNumber = (UINT16) Strtoi (Param2);
+ Sata->Lun = (UINT16) Strtoi (Param3);
return (EFI_DEVICE_PATH_PROTOCOL *) Sata;
}
@@ -2904,7 +2920,7 @@ GLOBAL_REMOVE_IF_UNREFERENCED DEVICE_PATH_FROM_TEXT_TABLE mUefiDevicePathLibDevP
{L"Vlan", DevPathFromTextVlan },
{L"HD", DevPathFromTextHD },
{L"CDROM", DevPathFromTextCDROM },
- {L"VenMEDIA", DevPathFromTextVenMEDIA },
+ {L"VenMedia", DevPathFromTextVenMedia },
{L"Media", DevPathFromTextMedia },
{L"Fv", DevPathFromTextFv },
{L"FvFile", DevPathFromTextFvFile },
diff --git a/MdePkg/Library/UefiDevicePathLib/DevicePathToText.c b/MdePkg/Library/UefiDevicePathLib/DevicePathToText.c
index 81cf84e25..eebdbf239 100644
--- a/MdePkg/Library/UefiDevicePathLib/DevicePathToText.c
+++ b/MdePkg/Library/UefiDevicePathLib/DevicePathToText.c
@@ -990,22 +990,13 @@ DevPathToTextSata (
SATA_DEVICE_PATH *Sata;
Sata = DevPath;
- if ((Sata->PortMultiplierPortNumber & SATA_HBA_DIRECT_CONNECT_FLAG) != 0) {
- UefiDevicePathLibCatPrint (
- Str,
- L"Sata(0x%x,0x%x)",
- Sata->HBAPortNumber,
- Sata->Lun
- );
- } else {
- UefiDevicePathLibCatPrint (
- Str,
- L"Sata(0x%x,0x%x,0x%x)",
- Sata->HBAPortNumber,
- Sata->PortMultiplierPortNumber,
- Sata->Lun
- );
- }
+ UefiDevicePathLibCatPrint (
+ Str,
+ L"Sata(0x%x,0x%x,0x%x)",
+ Sata->HBAPortNumber,
+ Sata->PortMultiplierPortNumber,
+ Sata->Lun
+ );
}
/**
diff --git a/MdePkg/MdePkg.dec b/MdePkg/MdePkg.dec
index 7c85b2804..9b37abdc9 100644
--- a/MdePkg/MdePkg.dec
+++ b/MdePkg/MdePkg.dec
@@ -520,6 +520,14 @@
## Include/Guid/FmpCapsule.h
gEfiFmpCapsuleGuid = { 0x6dcbd5ed, 0xe82d, 0x4c44, {0xbd, 0xa1, 0x71, 0x94, 0x19, 0x9a, 0xd9, 0x2a }}
+ ## Include/Protocol/Rng.h
+ gEfiRngAlgorithmSp80090Hash256Guid = { 0xa7af67cb, 0x603b, 0x4d42, {0xba, 0x21, 0x70, 0xbf, 0xb6, 0x29, 0x3f, 0x96 }}
+ gEfiRngAlgorithmSp80090Hmac256Guid = { 0xc5149b43, 0xae85, 0x4f53, {0x99, 0x82, 0xb9, 0x43, 0x35, 0xd3, 0xa9, 0xe7 }}
+ gEfiRngAlgorithmSp80090Ctr256Guid = { 0x44f0de6e, 0x4d8c, 0x4045, {0xa8, 0xc7, 0x4d, 0xd1, 0x68, 0x85, 0x6b, 0x9e }}
+ gEfiRngAlgorithmX9313DesGuid = { 0x63c4785a, 0xca34, 0x4012, {0xa3, 0xc8, 0x0b, 0x6a, 0x32, 0x4f, 0x55, 0x46 }}
+ gEfiRngAlgorithmX931AesGuid = { 0xacd03321, 0x777e, 0x4d3d, {0xb1, 0xc8, 0x20, 0xcf, 0xd8, 0x88, 0x20, 0xc9 }}
+ gEfiRngAlgorithmRaw = { 0xe43176d7, 0xb6e8, 0x4827, {0xb7, 0x84, 0x7f, 0xfd, 0xc4, 0xb6, 0x85, 0x61 }}
+
#
# GUID defined in PI1.0
#
@@ -599,6 +607,9 @@
## Include/Guid/FirmwareContentsSigned.h
gEfiFirmwareContentsSignedGuid = { 0xf9d89e8, 0x9259, 0x4f76, { 0xa5, 0xaf, 0xc, 0x89, 0xe3, 0x40, 0x23, 0xdf }}
+ ## Include/Guid/VectorHandoffTable.h
+ gEfiVectorHandoffTableGuid = { 0x996ec11c, 0x5397, 0x4e73, { 0xb5, 0x8f, 0x82, 0x7e, 0x52, 0x90, 0x6d, 0xef }}
+
[Guids.IA32, Guids.X64]
## Include/Guid/Cper.h
gEfiIa32X64ErrorTypeCacheCheckGuid = { 0xA55701F5, 0xE3EF, 0x43de, { 0xAC, 0x72, 0x24, 0x9B, 0x57, 0x3F, 0xAD, 0x2C }}
@@ -673,6 +684,9 @@
## Include/Ppi/Pcd.h
gPcdPpiGuid = { 0x6e81c58, 0x4ad7, 0x44bc, { 0x83, 0x90, 0xf1, 0x2, 0x65, 0xf7, 0x24, 0x80 } }
+ ## Include/Ppi/PcdInfo.h
+ gGetPcdInfoPpiGuid = { 0x4d8b155b, 0xc059, 0x4c8f, { 0x89, 0x26, 0x6, 0xfd, 0x43, 0x31, 0xdb, 0x8a } }
+
#
# PPIs defined in PI 1.2.
#
@@ -696,6 +710,19 @@
gEfiPeiPcdPpiGuid = { 0x1f34d25, 0x4de2, 0x23ad, { 0x3f, 0xf3, 0x36, 0x35, 0x3f, 0xf3, 0x23, 0xf1 } }
#
+ # PPIs defined in PI 1.2.1.
+ #
+
+ ## Include/Ppi/PiPcdInfo.h
+ gEfiGetPcdInfoPpiGuid = { 0xa60c6b59, 0xe459, 0x425d, { 0x9c, 0x69, 0xb, 0xcc, 0x9c, 0xb2, 0x7d, 0x81 } }
+
+ ## Include/Ppi/TemporaryRamDone.h
+ gEfiTemporaryRamDonePpiGuid = { 0xceab683c, 0xec56, 0x4a2d, { 0xa9, 0x6, 0x40, 0x53, 0xfa, 0x4e, 0x9c, 0x16 } }
+
+ ## Include/Ppi/VectorHandoffInfo.h
+ gEfiVectorHandoffInfoPpiGuid = { 0x3cd652b4, 0x6d33, 0x4dce, { 0x89, 0xdb, 0x83, 0xdf, 0x97, 0x66, 0xfc, 0xca }}
+
+ #
# PPIs defined in PI 1.3.
#
@@ -705,7 +732,15 @@
## Include/Ppi/FirmwareVolumeInfo2.h
gEfiPeiFirmwareVolumeInfo2PpiGuid = { 0xea7ca24b, 0xded5, 0x4dad, { 0xa3, 0x89, 0xbf, 0x82, 0x7e, 0x8f, 0x9b, 0x38 } }
+
+
[Protocols]
+ ## Include/Protocol/Pcd.h
+ gPcdProtocolGuid = { 0x11B34006, 0xD85B, 0x4D0A, { 0xA2, 0x90, 0xD5, 0xA5, 0x71, 0x31, 0x0E, 0xF7 }}
+
+ ## Include/Protocol/PcdInfo.h
+ gGetPcdInfoProtocolGuid = { 0x5be40f57, 0xfa68, 0x4610, { 0xbb, 0xbf, 0xe9, 0xc5, 0xfc, 0xda, 0xd3, 0x65 } }
+
#
# Protocols defined in PI1.0.
#
@@ -915,18 +950,18 @@
gEfiExtendedSalMcaLogServicesProtocolGuid = { 0xcb3fd86e, 0x38a3, 0x4c03, {0x9a, 0x5c, 0x90, 0xcf, 0xa3, 0xa2, 0xab, 0x7a } }
#
- # Protocols defined in PI1.2.1
+ # Protocols defined in PI 1.2.1
#
+
## Include/Protocol/Security2.h
gEfiSecurity2ArchProtocolGuid = { 0x94ab2f58, 0x1438, 0x4ef1, {0x91, 0x52, 0x18, 0x94, 0x1a, 0x3a, 0x0e, 0x68 } }
- #
- # Protocols defined in PI 1.2.1
- #
-
## Include/Protocol/SmmEndOfDxe.h
gEfiSmmEndOfDxeProtocolGuid = { 0x24e70042, 0xd5c5, 0x4260, { 0x8c, 0x39, 0xa, 0xd3, 0xaa, 0x32, 0xe9, 0x3d }}
+ ## Include/Protocol/PiPcdInfo.h
+ gEfiGetPcdInfoProtocolGuid = { 0xfd0f4478, 0xefd, 0x461d, { 0xba, 0x2d, 0xe5, 0x8c, 0x45, 0xfd, 0x5f, 0x5e } }
+
#
# Protocols defined in PI 1.3.
#
@@ -1181,9 +1216,6 @@
## Include/Protocol/Hash.h
gEfiHashProtocolGuid = { 0xC5184932, 0xDBA5, 0x46DB, { 0xA5, 0xBA, 0xCC, 0x0B, 0xDA, 0x9C, 0x14, 0x35 }}
- ## Include/Protocol/Pcd.h
- gPcdProtocolGuid = { 0x11B34006, 0xD85B, 0x4D0A, { 0xA2, 0x90, 0xD5, 0xA5, 0x71, 0x31, 0x0E, 0xF7 }}
-
## Include/Protocol/TcgService.h
gEfiTcgProtocolGuid = { 0xf541796d, 0xa62e, 0x4954, { 0xa7, 0x75, 0x95, 0x84, 0xf6, 0x1b, 0x9c, 0xdd }}
@@ -1319,6 +1351,9 @@
## Include/Protocol/Timestamp.h
gEfiTimestampProtocolGuid = { 0xafbfde41, 0x2e6e, 0x4262, {0xba, 0x65, 0x62, 0xb9, 0x23, 0x6e, 0x54, 0x95 }}
+ ## Include/Protocol/Rng.h
+ gEfiRngProtocolGuid = { 0x3152bca5, 0xeade, 0x433d, {0x86, 0x2e, 0xc0, 0x1c, 0xdc, 0x29, 0x1f, 0x44 }}
+
[PcdsFeatureFlag]
## If TRUE, the component name protocol will not be installed.
gEfiMdePkgTokenSpaceGuid.PcdComponentNameDisable|FALSE|BOOLEAN|0x0000000d
diff --git a/MdePkg/MdePkg.dsc b/MdePkg/MdePkg.dsc
index fa1e6d71c..389c4eb05 100644
--- a/MdePkg/MdePkg.dsc
+++ b/MdePkg/MdePkg.dsc
@@ -79,6 +79,7 @@
MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLib.inf
MdePkg/Library/BaseTimerLibNullTemplate/BaseTimerLibNullTemplate.inf
MdePkg/Library/BaseUefiDecompressLib/BaseUefiDecompressLib.inf
+ MdePkg/Library/BaseSmbusLibNull/BaseSmbusLibNull.inf
MdePkg/Library/DxeCoreEntryPoint/DxeCoreEntryPoint.inf
MdePkg/Library/DxeCoreHobLib/DxeCoreHobLib.inf
diff --git a/NetworkPkg/IScsiDxe/IScsiConfigNVDataStruc.h b/NetworkPkg/IScsiDxe/IScsiConfigNVDataStruc.h
index 9024b398d..56ebb503c 100644
--- a/NetworkPkg/IScsiDxe/IScsiConfigNVDataStruc.h
+++ b/NetworkPkg/IScsiDxe/IScsiConfigNVDataStruc.h
@@ -1,7 +1,7 @@
/** @file
Define NVData structures used by the iSCSI configuration component.
-Copyright (c) 2004 - 2011, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2004 - 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
@@ -68,8 +68,8 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#define LUN_MIN_SIZE 1
#define LUN_MAX_SIZE 20
-#define ISCSI_CHAP_UNI 1
-#define ISCSI_CHAP_MUTUAL 2
+#define ISCSI_CHAP_UNI 0
+#define ISCSI_CHAP_MUTUAL 1
#define TARGET_PORT_MIN_NUM 0
#define TARGET_PORT_MAX_NUM 65535
diff --git a/NetworkPkg/IScsiDxe/IScsiDriver.c b/NetworkPkg/IScsiDxe/IScsiDriver.c
index cc452e711..6d6f9a13e 100644
--- a/NetworkPkg/IScsiDxe/IScsiDriver.c
+++ b/NetworkPkg/IScsiDxe/IScsiDriver.c
@@ -112,13 +112,16 @@ IScsiSupported (
EFI_STATUS Status;
EFI_GUID *IScsiServiceBindingGuid;
EFI_GUID *TcpServiceBindingGuid;
+ EFI_GUID *DhcpServiceBindingGuid;
if (IpVersion == IP_VERSION_4) {
IScsiServiceBindingGuid = &gIScsiV4PrivateGuid;
TcpServiceBindingGuid = &gEfiTcp4ServiceBindingProtocolGuid;
+ DhcpServiceBindingGuid = &gEfiDhcp4ServiceBindingProtocolGuid;
} else {
IScsiServiceBindingGuid = &gIScsiV6PrivateGuid;
TcpServiceBindingGuid = &gEfiTcp6ServiceBindingProtocolGuid;
+ DhcpServiceBindingGuid = &gEfiDhcp6ServiceBindingProtocolGuid;
}
Status = gBS->OpenProtocol (
@@ -131,24 +134,40 @@ IScsiSupported (
);
if (!EFI_ERROR (Status)) {
return EFI_ALREADY_STARTED;
- } else {
+ }
+
+ Status = gBS->OpenProtocol (
+ ControllerHandle,
+ TcpServiceBindingGuid,
+ NULL,
+ This->DriverBindingHandle,
+ ControllerHandle,
+ EFI_OPEN_PROTOCOL_TEST_PROTOCOL
+ );
+ if (EFI_ERROR (Status)) {
+ return EFI_UNSUPPORTED;
+ }
+
+ Status = IScsiIsDevicePathSupported (RemainingDevicePath);
+ if (EFI_ERROR (Status)) {
+ return EFI_UNSUPPORTED;
+ }
+
+ if (IScsiDhcpIsConfigured (ControllerHandle, IpVersion)) {
Status = gBS->OpenProtocol (
ControllerHandle,
- TcpServiceBindingGuid,
+ DhcpServiceBindingGuid,
NULL,
This->DriverBindingHandle,
ControllerHandle,
EFI_OPEN_PROTOCOL_TEST_PROTOCOL
);
- if (!EFI_ERROR (Status)) {
- Status = IScsiIsDevicePathSupported (RemainingDevicePath);
- if (!EFI_ERROR (Status)) {
- return EFI_SUCCESS;
- }
+ if (EFI_ERROR (Status)) {
+ return EFI_UNSUPPORTED;
}
}
-
- return EFI_UNSUPPORTED;
+
+ return EFI_SUCCESS;
}
diff --git a/NetworkPkg/IScsiDxe/IScsiMisc.c b/NetworkPkg/IScsiDxe/IScsiMisc.c
index 971011eac..6ed497454 100644
--- a/NetworkPkg/IScsiDxe/IScsiMisc.c
+++ b/NetworkPkg/IScsiDxe/IScsiMisc.c
@@ -1,7 +1,7 @@
/** @file
Miscellaneous routines for iSCSI driver.
-Copyright (c) 2004 - 2012, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2004 - 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
@@ -890,6 +890,100 @@ IScsiCleanDriverData (
FreePool (Private);
}
+/**
+ Check wheather the Controller handle is configured to use DHCP protocol.
+
+ @param[in] Controller The handle of the controller.
+ @param[in] IpVersion IP_VERSION_4 or IP_VERSION_6.
+
+ @retval TRUE The handle of the controller need the Dhcp protocol.
+ @retval FALSE The handle of the controller does not need the Dhcp protocol.
+
+**/
+BOOLEAN
+IScsiDhcpIsConfigured (
+ IN EFI_HANDLE Controller,
+ IN UINT8 IpVersion
+ )
+{
+ ISCSI_ATTEMPT_CONFIG_NVDATA *AttemptTmp;
+ UINT8 *AttemptConfigOrder;
+ UINTN AttemptConfigOrderSize;
+ UINTN Index;
+ EFI_STATUS Status;
+ EFI_MAC_ADDRESS MacAddr;
+ UINTN HwAddressSize;
+ UINT16 VlanId;
+ CHAR16 MacString[ISCSI_MAX_MAC_STRING_LEN];
+ CHAR16 AttemptName[ISCSI_NAME_IFR_MAX_SIZE];
+
+ AttemptConfigOrder = IScsiGetVariableAndSize (
+ L"AttemptOrder",
+ &gIScsiConfigGuid,
+ &AttemptConfigOrderSize
+ );
+ if (AttemptConfigOrder == NULL || AttemptConfigOrderSize == 0) {
+ return FALSE;
+ }
+
+ //
+ // Get MAC address of this network device.
+ //
+ Status = NetLibGetMacAddress (Controller, &MacAddr, &HwAddressSize);
+ if(EFI_ERROR (Status)) {
+ return FALSE;
+ }
+ //
+ // Get VLAN ID of this network device.
+ //
+ VlanId = NetLibGetVlanId (Controller);
+ IScsiMacAddrToStr (&MacAddr, (UINT32) HwAddressSize, VlanId, MacString);
+
+ for (Index = 0; Index < AttemptConfigOrderSize / sizeof (UINT8); Index++) {
+ UnicodeSPrint (
+ AttemptName,
+ (UINTN) 128,
+ L"%s%d",
+ MacString,
+ (UINTN) AttemptConfigOrder[Index]
+ );
+ Status = GetVariable2 (
+ AttemptName,
+ &gEfiIScsiInitiatorNameProtocolGuid,
+ (VOID**)&AttemptTmp,
+ NULL
+ );
+ if(AttemptTmp == NULL || EFI_ERROR (Status)) {
+ continue;
+ }
+
+ ASSERT (AttemptConfigOrder[Index] == AttemptTmp->AttemptConfigIndex);
+
+ if (AttemptTmp->SessionConfigData.Enabled == ISCSI_DISABLED) {
+ FreePool (AttemptTmp);
+ continue;
+ }
+
+ if (AttemptTmp->SessionConfigData.IpMode != IP_MODE_AUTOCONFIG &&
+ AttemptTmp->SessionConfigData.IpMode != ((IpVersion == IP_VERSION_4) ? IP_MODE_IP4 : IP_MODE_IP6)) {
+ FreePool (AttemptTmp);
+ continue;
+ }
+
+ if(AttemptTmp->SessionConfigData.IpMode == IP_MODE_AUTOCONFIG ||
+ AttemptTmp->SessionConfigData.InitiatorInfoFromDhcp == TRUE ||
+ AttemptTmp->SessionConfigData.TargetInfoFromDhcp == TRUE) {
+ FreePool (AttemptTmp);
+ FreePool (AttemptConfigOrder);
+ return TRUE;
+ }
+
+ FreePool (AttemptTmp);
+ }
+
+ FreePool (AttemptConfigOrder);
+ return FALSE;
+}
/**
Get the various configuration data.
diff --git a/NetworkPkg/IScsiDxe/IScsiMisc.h b/NetworkPkg/IScsiDxe/IScsiMisc.h
index c9ff96da6..e2a27806a 100644
--- a/NetworkPkg/IScsiDxe/IScsiMisc.h
+++ b/NetworkPkg/IScsiDxe/IScsiMisc.h
@@ -1,7 +1,7 @@
/** @file
Miscellaneous definitions for iSCSI driver.
-Copyright (c) 2004 - 2012, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2004 - 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
@@ -299,6 +299,22 @@ IScsiCleanDriverData (
);
/**
+ Check wheather the Controller handle is configured to use DHCP protocol.
+
+ @param[in] Controller The handle of the controller.
+ @param[in] IpVersion IP_VERSION_4 or IP_VERSION_6.
+
+ @retval TRUE The handle of the controller need the Dhcp protocol.
+ @retval FALSE The handle of the controller does not need the Dhcp protocol.
+
+**/
+BOOLEAN
+IScsiDhcpIsConfigured (
+ IN EFI_HANDLE Controller,
+ IN UINT8 IpVersion
+ );
+
+/**
Get the various configuration data of this iSCSI instance.
@param[in] Private The iSCSI driver data.
diff --git a/NetworkPkg/IScsiDxe/IScsiProto.c b/NetworkPkg/IScsiDxe/IScsiProto.c
index 8c0bbec06..29b3c2499 100644
--- a/NetworkPkg/IScsiDxe/IScsiProto.c
+++ b/NetworkPkg/IScsiDxe/IScsiProto.c
@@ -228,7 +228,7 @@ IScsiCreateConnection (
Conn->PartialRspRcvd = FALSE;
Conn->ParamNegotiated = FALSE;
Conn->Cid = Session->NextCid++;
- Conn->Ipv6Flag = mPrivate->Ipv6Flag;
+ Conn->Ipv6Flag = NvData->IpMode == IP_MODE_IP6 || Session->ConfigData->AutoConfigureMode == IP_MODE_AUTOCONFIG_IP6;
Status = gBS->CreateEvent (
EVT_TIMER,
@@ -472,7 +472,7 @@ IScsiSessionLogin (
if (!EFI_ERROR (Status)) {
Session->State = SESSION_STATE_LOGGED_IN;
- if (!mPrivate->Ipv6Flag) {
+ if (!Conn->Ipv6Flag) {
ProtocolGuid = &gEfiTcp4ProtocolGuid;
} else {
ProtocolGuid = &gEfiTcp6ProtocolGuid;
@@ -489,7 +489,7 @@ IScsiSessionLogin (
ASSERT_EFI_ERROR (Status);
- if (mPrivate->Ipv6Flag) {
+ if (Conn->Ipv6Flag) {
Status = IScsiGetIp6NicInfo (Conn);
}
}
diff --git a/Nt32Pkg/Nt32Pkg.dsc b/Nt32Pkg/Nt32Pkg.dsc
index 59ee48741..83286b0cb 100644
--- a/Nt32Pkg/Nt32Pkg.dsc
+++ b/Nt32Pkg/Nt32Pkg.dsc
@@ -31,6 +31,12 @@
BUILD_TARGETS = DEBUG|RELEASE
SKUID_IDENTIFIER = DEFAULT
FLASH_DEFINITION = Nt32Pkg/Nt32Pkg.fdf
+ #
+ # This flag is to control tool to generate PCD info for dynamic(ex) PCD,
+ # then enable or disable PCD info feature. TRUE is enable, and FLASE is disable.
+ # If the flag is absent, it will be same as FALSE.
+ #
+ PCD_INFO_GENERATION = TRUE
#
# Defines for default states. These can be changed on the command line.
@@ -442,12 +448,11 @@
[BuildOptions]
DEBUG_*_*_DLINK_FLAGS = /EXPORT:InitializeDriver=$(IMAGE_ENTRY_POINT) /BASE:0x10000 /ALIGN:4096 /FILEALIGN:4096 /SUBSYSTEM:CONSOLE
RELEASE_*_*_DLINK_FLAGS = /ALIGN:4096 /FILEALIGN:4096
- *_*_IA32_CC_FLAGS = /D EFI_SPECIFICATION_VERSION=0x0002000A /D TIANO_RELEASE_VERSION=0x00080006
# Add override here, because default X64_CC_FLAGS add /X
- DEBUG_*_X64_CC_FLAGS == /nologo /c /WX /GS- /W4 /Gs32768 /D UNICODE /O1ib2s /GL /Gy /FIAutoGen.h /EHs-c- /GR- /GF /Zi /Gm /D EFI_SPECIFICATION_VERSION=0x0002000A /D TIANO_RELEASE_VERSION=0x00080006
-RELEASE_*_X64_CC_FLAGS == /nologo /c /WX /GS- /W4 /Gs32768 /D UNICODE /O1ib2s /GL /Gy /FIAutoGen.h /EHs-c- /GR- /GF /D EFI_SPECIFICATION_VERSION=0x0002000A /D TIANO_RELEASE_VERSION=0x00080006
-NOOPT_*_X64_CC_FLAGS == /nologo /c /WX /GS- /W4 /Gs32768 /D UNICODE /Gy /FIAutoGen.h /EHs-c- /GR- /GF /Zi /Gm /Od /D EFI_SPECIFICATION_VERSION=0x0002000A /D TIANO_RELEASE_VERSION=0x00080006
+ DEBUG_*_X64_CC_FLAGS == /nologo /c /WX /GS- /W4 /Gs32768 /D UNICODE /O1ib2s /GL /Gy /FIAutoGen.h /EHs-c- /GR- /GF /Zi /Gm
+ RELEASE_*_X64_CC_FLAGS == /nologo /c /WX /GS- /W4 /Gs32768 /D UNICODE /O1ib2s /GL /Gy /FIAutoGen.h /EHs-c- /GR- /GF
+ NOOPT_*_X64_CC_FLAGS == /nologo /c /WX /GS- /W4 /Gs32768 /D UNICODE /Gy /FIAutoGen.h /EHs-c- /GR- /GF /Zi /Gm /Od
#############################################################################################################
# NOTE:
diff --git a/OptionRomPkg/Bus/Usb/FtdiUsbSerialDxe/CompatibleDevices.txt b/OptionRomPkg/Bus/Usb/FtdiUsbSerialDxe/CompatibleDevices.txt
new file mode 100644
index 000000000..1ec1cce0d
--- /dev/null
+++ b/OptionRomPkg/Bus/Usb/FtdiUsbSerialDxe/CompatibleDevices.txt
@@ -0,0 +1,5 @@
+The following devices have been confirmed to work with the USB Serial Driver:
+
+Brand Model Name Product Name Vendor ID Device ID
+Gearmo USA_FTDI-36 USB to RS-232 0x0403 0x6001
+Sabrent CB-FTDI 0x0403 0x6001 \ No newline at end of file
diff --git a/OptionRomPkg/Bus/Usb/FtdiUsbSerialDxe/ComponentName.c b/OptionRomPkg/Bus/Usb/FtdiUsbSerialDxe/ComponentName.c
new file mode 100644
index 000000000..c200878d4
--- /dev/null
+++ b/OptionRomPkg/Bus/Usb/FtdiUsbSerialDxe/ComponentName.c
@@ -0,0 +1,224 @@
+/** @file
+ UEFI Component Name(2) protocol implementation for USB Serial driver.
+
+Copyright (c) 2004 - 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 "FtdiUsbSerialDriver.h"
+
+//
+// EFI Component Name Protocol
+//
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME_PROTOCOL gUsbSerialComponentName = {
+ (EFI_COMPONENT_NAME_GET_DRIVER_NAME) UsbSerialComponentNameGetDriverName,
+ (EFI_COMPONENT_NAME_GET_CONTROLLER_NAME) UsbSerialComponentNameGetControllerName,
+ "eng"
+};
+
+//
+// EFI Component Name 2 Protocol
+//
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME2_PROTOCOL gUsbSerialComponentName2 = {
+ UsbSerialComponentNameGetDriverName,
+ UsbSerialComponentNameGetControllerName,
+ "en"
+};
+
+//
+// Driver name string table
+//
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE mUsbSerialDriverNameTable[] = {
+ { "eng;en", L"FTDI-232 USB Serial 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 A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or
+ EFI_COMPONENT_NAME_PROTOCOL instance.
+ @param Language 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 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
+UsbSerialComponentNameGetDriverName (
+ IN EFI_COMPONENT_NAME2_PROTOCOL *This,
+ IN CHAR8 *Language,
+ OUT CHAR16 **DriverName
+ )
+{
+ return LookupUnicodeString2 (
+ Language,
+ This->SupportedLanguages,
+ mUsbSerialDriverNameTable,
+ DriverName,
+ (BOOLEAN)(This == &gUsbSerialComponentName2)
+ );
+}
+
+
+/**
+ 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 A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or
+ EFI_COMPONENT_NAME_PROTOCOL instance.
+ @param ControllerHandle 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 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 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 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 not a valid EFI_HANDLE.
+ @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
+UsbSerialComponentNameGetControllerName (
+ IN EFI_COMPONENT_NAME2_PROTOCOL *This,
+ IN EFI_HANDLE ControllerHandle,
+ IN EFI_HANDLE ChildHandle OPTIONAL,
+ IN CHAR8 *Language,
+ OUT CHAR16 **ControllerName
+ )
+{
+ EFI_STATUS Status;
+ USB_SER_DEV *UsbSerDev;
+ EFI_SERIAL_IO_PROTOCOL *SerialIo;
+ EFI_USB_IO_PROTOCOL *UsbIoProtocol;
+
+ //
+ // This is a device driver, so ChildHandle must be NULL.
+ //
+ if (ChildHandle != NULL) {
+ return EFI_UNSUPPORTED;
+ }
+
+ //
+ // Check Controller's handle
+ //
+ Status = gBS->OpenProtocol (
+ ControllerHandle,
+ &gEfiUsbIoProtocolGuid,
+ (VOID **) &UsbIoProtocol,
+ gUsbSerialDriverBinding.DriverBindingHandle,
+ ControllerHandle,
+ EFI_OPEN_PROTOCOL_BY_DRIVER
+ );
+ if (!EFI_ERROR (Status)) {
+ gBS->CloseProtocol (
+ ControllerHandle,
+ &gEfiUsbIoProtocolGuid,
+ gUsbSerialDriverBinding.DriverBindingHandle,
+ ControllerHandle
+ );
+
+ return EFI_UNSUPPORTED;
+ }
+
+ if (Status != EFI_ALREADY_STARTED) {
+ return EFI_UNSUPPORTED;
+ }
+ //
+ // Get the device context
+ //
+ Status = gBS->OpenProtocol (
+ ControllerHandle,
+ &gEfiSerialIoProtocolGuid,
+ (VOID **) &SerialIo,
+ gUsbSerialDriverBinding.DriverBindingHandle,
+ ControllerHandle,
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ UsbSerDev = USB_SER_DEV_FROM_THIS (SerialIo);
+
+ return LookupUnicodeString2 (
+ Language,
+ This->SupportedLanguages,
+ UsbSerDev->ControllerNameTable,
+ ControllerName,
+ (BOOLEAN)(This == &gUsbSerialComponentName2)
+ );
+}
diff --git a/OptionRomPkg/Bus/Usb/FtdiUsbSerialDxe/FtdiUsbSerialDriver.c b/OptionRomPkg/Bus/Usb/FtdiUsbSerialDxe/FtdiUsbSerialDriver.c
new file mode 100644
index 000000000..595ef4a3e
--- /dev/null
+++ b/OptionRomPkg/Bus/Usb/FtdiUsbSerialDxe/FtdiUsbSerialDriver.c
@@ -0,0 +1,2588 @@
+/** @file
+ USB Serial Driver that manages USB to Serial and produces Serial IO Protocol.
+
+Copyright (c) 2004 - 2013, Intel Corporation. All rights reserved.
+Portions Copyright 2012 Ashley DeSimone
+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.
+
+**/
+
+//
+
+// Tested with VEND_ID 0x0403, DEVICE_ID 0x6001
+//
+// Driver starts the device with the following values:
+// 115200, No parity, 8 data bits, 1 stop bit, No Flow control
+//
+
+#include "FtdiUsbSerialDriver.h"
+
+//
+// Table of supported devices. This is the device information that this
+// driver was developed with. Add other FTDI devices as needed.
+//
+USB_DEVICE gUSBDeviceList[] = {
+ {VID_FTDI, DID_FTDI_FT232},
+ {0,0}
+};
+
+//
+// USB Serial Driver Global Variables
+//
+EFI_DRIVER_BINDING_PROTOCOL gUsbSerialDriverBinding = {
+ UsbSerialDriverBindingSupported,
+ UsbSerialDriverBindingStart,
+ UsbSerialDriverBindingStop,
+ 0xa,
+ NULL,
+ NULL
+};
+
+//
+// Table with the nearest power of 2 for the numbers 0-15
+//
+UINT8 gRoundedPowersOf2[16] = { 0, 2, 2, 4, 4, 4, 8, 8, 8, 8, 8, 8, 16, 16, 16, 16 };
+
+/**
+ Check to see if the device path node is the Flow control node
+
+ @param[in] FlowControl The device path node to be checked
+
+ @retval TRUE It is the flow control node
+ @retval FALSE It is not the flow control node
+
+**/
+BOOLEAN
+IsUartFlowControlNode (
+ IN UART_FLOW_CONTROL_DEVICE_PATH *FlowControl
+ )
+{
+ return (BOOLEAN) (
+ (DevicePathType (FlowControl) == MESSAGING_DEVICE_PATH) &&
+ (DevicePathSubType (FlowControl) == MSG_VENDOR_DP) &&
+ (CompareGuid (&FlowControl->Guid, &gEfiUartDevicePathGuid))
+ );
+}
+
+/**
+ Checks the device path to see if it contains flow control.
+
+ @param[in] DevicePath The device path to be checked
+
+ @retval TRUE It contains flow control
+ @retval FALSE It does not contain flow control
+
+**/
+BOOLEAN
+ContainsFlowControl (
+ IN EFI_DEVICE_PATH_PROTOCOL *DevicePath
+ )
+{
+ while (!IsDevicePathEnd (DevicePath)) {
+ if (IsUartFlowControlNode ((UART_FLOW_CONTROL_DEVICE_PATH *) DevicePath)) {
+ return TRUE;
+ }
+ DevicePath = NextDevicePathNode (DevicePath);
+ }
+ return FALSE;
+}
+
+/**
+ Transfer the data between the device and host.
+
+ This function transfers the data between the device and host.
+ BOT transfer is composed of three phases: Command, Data, and Status.
+ This is the Data phase.
+
+ @param UsbBot[in] The USB BOT device
+ @param DataDir[in] The direction of the data
+ @param Data[in, out] The buffer to hold data
+ @param TransLen[in, out] The expected length of the data
+ @param Timeout[in] The time to wait the command to complete
+
+ @retval EFI_SUCCESS The data is transferred
+ @retval EFI_SUCCESS No data to transfer
+ @retval EFI_NOT_READY The device return NAK to the transfer
+ @retval Others Failed to transfer data
+
+**/
+EFI_STATUS
+UsbSerialDataTransfer (
+ IN USB_SER_DEV *UsbBot,
+ IN EFI_USB_DATA_DIRECTION DataDir,
+ IN OUT VOID *Data,
+ IN OUT UINTN *TransLen,
+ IN UINT32 Timeout
+ )
+{
+ EFI_USB_ENDPOINT_DESCRIPTOR *Endpoint;
+ EFI_STATUS Status;
+ UINT32 Result;
+
+ //
+ // If no data to transfer, just return EFI_SUCCESS.
+ //
+ if ((DataDir == EfiUsbNoData) || (*TransLen == 0)) {
+ return EFI_SUCCESS;
+ }
+
+ //
+ // Select the endpoint then issue the transfer
+ //
+ if (DataDir == EfiUsbDataIn) {
+ Endpoint = &UsbBot->InEndpointDescriptor;
+ } else {
+ Endpoint = &UsbBot->OutEndpointDescriptor;
+ }
+
+ Result = 0;
+ Status = UsbBot->UsbIo->UsbBulkTransfer (
+ UsbBot->UsbIo,
+ Endpoint->EndpointAddress,
+ Data,
+ TransLen,
+ Timeout,
+ &Result
+ );
+ if (EFI_ERROR (Status)) {
+ if (USB_IS_ERROR (Result, EFI_USB_ERR_NAK)) {
+ Status = EFI_NOT_READY;
+ } else {
+ UsbBot->Shutdown = TRUE; // Fixes infinite loop in older EFI
+ }
+ return Status;
+ }
+ return Status;
+}
+
+/**
+ Sets the status values of the Usb Serial Device.
+
+ @param UsbSerialDevice[in] Handle to the Usb Serial Device to set the status
+ for
+ @param StatusBuffer[in] Buffer holding the status values
+
+ @retval EFI_SUCCESS The status values were read and set correctly
+
+**/
+EFI_STATUS
+EFIAPI
+SetStatusInternal (
+ IN USB_SER_DEV *UsbSerialDevice,
+ IN UINT8 *StatusBuffer
+ )
+{
+ UINT8 Msr;
+
+ Msr = (StatusBuffer[0] & MSR_MASK);
+
+ //
+ // set the Status values to disabled
+ //
+ UsbSerialDevice->StatusValues.CtsState = FALSE;
+ UsbSerialDevice->StatusValues.DsrState = FALSE;
+ UsbSerialDevice->StatusValues.RiState = FALSE;
+ UsbSerialDevice->StatusValues.SdState = FALSE;
+
+ //
+ // Check the values from the status buffer and set the appropriate status
+ // values to enabled
+ //
+ if ((Msr & CTS_MASK) == CTS_MASK) {
+ UsbSerialDevice->StatusValues.CtsState = TRUE;
+ }
+ if ((Msr & DSR_MASK) == DSR_MASK) {
+ UsbSerialDevice->StatusValues.DsrState = TRUE;
+ }
+ if ((Msr & RI_MASK) == RI_MASK) {
+ UsbSerialDevice->StatusValues.RiState = TRUE;
+ }
+ if ((Msr & SD_MASK) == SD_MASK) {
+ UsbSerialDevice->StatusValues.SdState = TRUE;
+ }
+ return EFI_SUCCESS;
+}
+
+/**
+ Initiates a read operation on the Usb Serial Device.
+
+ @param UsbSerialDevice[in] Handle to the USB device to read
+ @param BufferSize[in, out] On input, the size of the Buffer. On output,
+ the amount of data returned in Buffer.
+ Setting this to zero will initiate a read
+ and store all data returned in the internal
+ buffer.
+ @param Buffer [out] The buffer to return the data into.
+
+ @retval EFI_SUCCESS The data was read.
+ @retval EFI_DEVICE_ERROR The device reported an error.
+ @retval EFI_TIMEOUT The data write was stopped due to a timeout.
+
+**/
+EFI_STATUS
+EFIAPI
+ReadDataFromUsb (
+ IN USB_SER_DEV *UsbSerialDevice,
+ IN OUT UINTN *BufferSize,
+ OUT VOID *Buffer
+ )
+{
+ EFI_STATUS Status;
+ UINTN ReadBufferSize;
+ UINT8 *ReadBuffer;
+ UINTN Index;
+ EFI_TPL Tpl;
+ UINT8 StatusBuffer[2]; // buffer to store the status bytes
+
+ ReadBufferSize = 512;
+ ReadBuffer = &(UsbSerialDevice->ReadBuffer[0]);
+
+ if (UsbSerialDevice->Shutdown) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ Tpl = gBS->RaiseTPL (TPL_NOTIFY);
+
+ Status = UsbSerialDataTransfer (
+ UsbSerialDevice,
+ EfiUsbDataIn,
+ ReadBuffer,
+ &ReadBufferSize,
+ FTDI_TIMEOUT*2 //Padded because timers won't be exactly aligned
+ );
+ if (EFI_ERROR (Status)) {
+ gBS->RestoreTPL (Tpl);
+ if (Status == EFI_TIMEOUT) {
+ return EFI_TIMEOUT;
+ } else {
+ return EFI_DEVICE_ERROR;
+ }
+ }
+
+ //
+ // Store the status bytes in the status buffer
+ //
+ for (Index = 0; Index < 2; Index++) {//only the first 2 bytes are status bytes
+ StatusBuffer[Index] = ReadBuffer[Index];
+ }
+ //
+ // update the statusvalue field of the usbserialdevice
+ //
+ Status = SetStatusInternal (UsbSerialDevice, StatusBuffer);
+ if (Status != EFI_SUCCESS) {
+ }
+
+ //
+ // Store the read data in the read buffer, start at 2 to ignore status bytes
+ //
+ for (Index = 2; Index < ReadBufferSize; Index++) {
+ if (((UsbSerialDevice->DataBufferTail + 1) % SW_FIFO_DEPTH) == UsbSerialDevice->DataBufferHead) {
+ break;
+ }
+ if (ReadBuffer[Index] == 0x00) {
+ //
+ // This is null, do not add
+ //
+ } else {
+ UsbSerialDevice->DataBuffer[UsbSerialDevice->DataBufferTail] = ReadBuffer[Index];
+ UsbSerialDevice->DataBufferTail = (UsbSerialDevice->DataBufferTail + 1) % SW_FIFO_DEPTH;
+ }
+ }
+
+ //
+ // Read characters out of the buffer to satisfy caller's request.
+ //
+ for (Index = 0; Index < *BufferSize; Index++) {
+ if (UsbSerialDevice->DataBufferHead == UsbSerialDevice->DataBufferTail) {
+ break;
+ }
+ //
+ // Still have characters in the buffer to return
+ //
+ ((UINT8 *)Buffer)[Index] = UsbSerialDevice->DataBuffer[UsbSerialDevice->DataBufferHead];
+ UsbSerialDevice->DataBufferHead = (UsbSerialDevice->DataBufferHead + 1) % SW_FIFO_DEPTH;
+ }
+ //
+ // Return actual number of bytes returned.
+ //
+ *BufferSize = Index;
+ gBS->RestoreTPL (Tpl);
+ return EFI_SUCCESS;
+}
+
+/**
+ Sets the initial status values of the Usb Serial Device by reading the status
+ bytes from the device.
+
+ @param UsbSerialDevice[in] Handle to the Usb Serial Device that needs its
+ initial status values set
+
+ @retval EFI_SUCCESS The status bytes were read successfully and the
+ initial status values were set correctly
+ @retval EFI_TIMEOUT The read of the status bytes was stopped due to a
+ timeout
+ @retval EFI_DEVICE_ERROR The device reported an error during the read of
+ the status bytes
+
+**/
+EFI_STATUS
+EFIAPI
+SetInitialStatus (
+ IN USB_SER_DEV *UsbSerialDevice
+ )
+{
+ EFI_STATUS Status;
+ UINTN BufferSize;
+ EFI_TPL Tpl;
+ UINT8 StatusBuffer[2];
+
+ Status = EFI_UNSUPPORTED;
+ BufferSize = sizeof (StatusBuffer);
+
+ if (UsbSerialDevice->Shutdown) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ Tpl = gBS->RaiseTPL (TPL_NOTIFY);
+
+ Status = UsbSerialDataTransfer (
+ UsbSerialDevice,
+ EfiUsbDataIn,
+ StatusBuffer,
+ &BufferSize,
+ 40 //Slightly more than 2x the FTDI polling frequency to make sure that data will be returned
+ );
+
+ Status = SetStatusInternal (UsbSerialDevice, StatusBuffer);
+
+ gBS->RestoreTPL (Tpl);
+
+ return Status;
+}
+
+/**
+ UsbSerialDriverCheckInput.
+ attempts to read data in from the device periodically, stores any read data
+ and updates the control attributes.
+
+ @param Event[in]
+ @param Context[in]....The current instance of the USB serial device
+
+**/
+VOID
+EFIAPI
+UsbSerialDriverCheckInput (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+{
+ UINTN BufferSize;
+ USB_SER_DEV *UsbSerialDevice;
+
+ UsbSerialDevice = (USB_SER_DEV*)Context;
+
+ if (UsbSerialDevice->DataBufferHead == UsbSerialDevice->DataBufferTail) {
+ //
+ // Data buffer is empty, try to read from device
+ //
+ BufferSize = 0;
+ ReadDataFromUsb (UsbSerialDevice, &BufferSize, NULL);
+ if (UsbSerialDevice->DataBufferHead == UsbSerialDevice->DataBufferTail) {
+ //
+ // Data buffer still has no data, set the EFI_SERIAL_INPUT_BUFFER_EMPTY
+ // flag
+ //
+ UsbSerialDevice->ControlBits |= EFI_SERIAL_INPUT_BUFFER_EMPTY;
+ } else {
+ //
+ // Read has returned some data, clear the EFI_SERIAL_INPUT_BUFFER_EMPTY
+ // flag
+ //
+ UsbSerialDevice->ControlBits &= ~(EFI_SERIAL_INPUT_BUFFER_EMPTY);
+ }
+ } else {
+ //
+ // Data buffer has data, no read attempt required
+ //
+ UsbSerialDevice->ControlBits &= ~(EFI_SERIAL_INPUT_BUFFER_EMPTY);
+ }
+}
+
+/**
+ Encodes the baud rate into the format expected by the Ftdi device.
+
+ @param BaudRate[in] The baudrate to be set on the device
+ @param EncodedBaudRate[out] The baud rate encoded in the format
+ expected by the Ftdi device
+
+ @return EFI_SUCCESS Baudrate encoding was calculated
+ successfully
+ @return EFI_INVALID_PARAMETER An invalid value of BaudRate was received
+
+**/
+EFI_STATUS
+EFIAPI
+EncodeBaudRateForFtdi (
+ IN UINT64 BaudRate,
+ OUT UINT16 *EncodedBaudRate
+ )
+{
+ UINT32 Divisor;
+ UINT32 AdjustedFrequency;
+ UINT16 Result;
+
+ //
+ // Check to make sure we won't get an integer overflow
+ //
+ if ((BaudRate < 178) || ( BaudRate > ((FTDI_UART_FREQUENCY * 100) / 97))) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // Baud Rates of 2000000 and 3000000 are special cases
+ //
+ if ((BaudRate >= FTDI_SPECIAL_CASE_300_MIN) && (BaudRate <= FTDI_SPECIAL_CASE_300_MAX)) {
+ *EncodedBaudRate = 0;
+ return EFI_SUCCESS;
+ }
+ if ((BaudRate >= FTDI_SPECIAL_CASE_200_MIN) && (BaudRate <= FTDI_SPECIAL_CASE_200_MAX)) {
+ *EncodedBaudRate = 1;
+ return EFI_SUCCESS;
+ }
+
+ //
+ // Compute divisor
+ //
+ Divisor = (FTDI_UART_FREQUENCY << 4) / (UINT32)BaudRate;
+
+ //
+ // Round the last 4 bits to the nearest power of 2
+ //
+ Divisor = (Divisor & ~(0xF)) + (gRoundedPowersOf2[Divisor & 0xF]);
+
+ //
+ // Check to make sure computed divisor is within
+ // the min and max that FTDI controller will accept
+ //
+ if (Divisor < FTDI_MIN_DIVISOR) {
+ Divisor = FTDI_MIN_DIVISOR;
+ } else if (Divisor > FTDI_MAX_DIVISOR) {
+ Divisor = FTDI_MAX_DIVISOR;
+ }
+
+ //
+ // Check to make sure the frequency that the FTDI chip will need to
+ // generate to attain the requested Baud Rate is within 3% of the
+ // 3MHz clock frequency that the FTDI chip runs at.
+ //
+ // (3MHz * 1600) / 103 = 46601941
+ // (3MHz * 1600) / 97 = 49484536
+ //
+ AdjustedFrequency = (((UINT32)BaudRate) * Divisor);
+ if ((AdjustedFrequency < FTDI_MIN_FREQUENCY) || (AdjustedFrequency > FTDI_MAX_FREQUENCY)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // Encode the Divisor into the format FTDI expects
+ //
+ Result = (UINT16)(Divisor >> 4);
+ if ((Divisor & 0x8) != 0) {
+ Result |= 0x4000;
+ } else if ((Divisor & 0x4) != 0) {
+ Result |= 0x8000;
+ } else if ((Divisor & 0x2) != 0) {
+ Result |= 0xC000;
+ }
+
+ *EncodedBaudRate = Result;
+ return EFI_SUCCESS;
+}
+
+/**
+ Uses USB I/O to check whether the device is a USB Serial device.
+
+ @param UsbIo[in] Pointer to a USB I/O protocol instance.
+
+ @retval TRUE Device is a USB Serial device.
+ @retval FALSE Device is a not USB Serial device.
+
+**/
+BOOLEAN
+IsUsbSerial (
+ IN EFI_USB_IO_PROTOCOL *UsbIo
+ )
+{
+ EFI_STATUS Status;
+ EFI_USB_DEVICE_DESCRIPTOR DeviceDescriptor;
+ CHAR16 *StrMfg;
+ BOOLEAN Found;
+ UINT32 Index;
+
+ //
+ // Get the default device descriptor
+ //
+ Status = UsbIo->UsbGetDeviceDescriptor (
+ UsbIo,
+ &DeviceDescriptor
+ );
+ if (EFI_ERROR (Status)) {
+ return FALSE;
+ }
+
+ Found = FALSE;
+ Index = 0;
+ while (gUSBDeviceList[Index].VendorId != 0 &&
+ gUSBDeviceList[Index].DeviceId != 0 &&
+ !Found ) {
+ if (DeviceDescriptor.IdProduct == gUSBDeviceList[Index].DeviceId &&
+ DeviceDescriptor.IdVendor == gUSBDeviceList[Index].VendorId ){
+ //
+ // Checks to see if a string descriptor can be pulled from the device in
+ // the selected language. If not False is returned indicating that this
+ // is not a Usb Serial Device that can be managegd by this driver
+ //
+ StrMfg = NULL;
+ Status = UsbIo->UsbGetStringDescriptor (
+ UsbIo,
+ USB_US_LANG_ID, // LANGID selector, should make this
+ // more robust to verify lang support
+ // for device
+ DeviceDescriptor.StrManufacturer,
+ &StrMfg
+ );
+ if (StrMfg != NULL) {
+ FreePool (StrMfg);
+ }
+ if (EFI_ERROR (Status)) {
+ return FALSE;
+ }
+ return TRUE;
+ }
+ Index++;
+ }
+ return FALSE;
+}
+
+/**
+ Internal function that sets the Data Bits, Stop Bits and Parity values on the
+ Usb Serial Device with a single usb control transfer.
+
+ @param UsbIo[in] Usb Io Protocol instance pointer
+ @param DataBits[in] The data bits value to be set on the Usb
+ Serial Device
+ @param Parity[in] The parity type that will be set on the Usb
+ Serial Device
+ @param StopBits[in] The stop bits type that will be set on the
+ Usb Serial Device
+ @param LastSettings[in] A pointer to the Usb Serial Device's
+ PREVIOUS_ATTRIBUTES item
+
+ @retval EFI_SUCCESS The data items were correctly set on the
+ USB Serial Device
+ @retval EFI_INVALID_PARAMETER An invalid data parameter or an invalid
+ combination or parameters was used
+ @retval EFI_DEVICE_ERROR The device is not functioning correctly and
+ the data values were unable to be set
+
+**/
+EFI_STATUS
+EFIAPI
+SetDataInternal (
+ IN EFI_USB_IO_PROTOCOL *UsbIo,
+ IN UINT8 DataBits,
+ IN EFI_PARITY_TYPE Parity,
+ IN EFI_STOP_BITS_TYPE StopBits,
+ IN PREVIOUS_ATTRIBUTES *LastSettings
+ )
+{
+ EFI_STATUS Status;
+ EFI_USB_DEVICE_REQUEST DevReq;
+ UINT32 ReturnValue;
+ UINT8 ConfigurationValue;
+
+ //
+ // Since data bits settings of 6,7,8 cannot be set with a stop bits setting of
+ // 1.5 check to see if this happens when the values of last settings are used
+ //
+ if ((DataBits == 0) && (StopBits == OneFiveStopBits)) {
+ if ((LastSettings->DataBits == 6) || (LastSettings->DataBits == 7) || (LastSettings->DataBits == 8)) {
+ return EFI_INVALID_PARAMETER;
+ }
+ } else if ((StopBits == DefaultStopBits) && ((DataBits == 6) || (DataBits == 7) || (DataBits == 8))) {
+ if (LastSettings->StopBits == OneFiveStopBits) {
+ return EFI_INVALID_PARAMETER;
+ }
+ } else if ((DataBits == 0) && (StopBits == DefaultStopBits)) {
+ if (LastSettings->StopBits == OneFiveStopBits) {
+ if ((LastSettings->DataBits == 6) || (LastSettings->DataBits == 7) || (LastSettings->DataBits == 8)) {
+ return EFI_INVALID_PARAMETER;
+ }
+ }
+ }
+
+ //
+ // set the DevReq.Value for the usb control transfer to the correct value
+ // based on the seleceted number of data bits if there is an invalid number of
+ // data bits requested return EFI_INVALID_PARAMETER
+ //
+ if (((DataBits < 5 ) || (DataBits > 8)) && (DataBits != 0)) {
+ return EFI_INVALID_PARAMETER;
+ }
+ if (DataBits == 0) {
+ //
+ // use the value of LastDataBits
+ //
+ DevReq.Value = SET_DATA_BITS (LastSettings->DataBits);
+ } else {
+ //
+ // use the value of DataBits
+ //
+ DevReq.Value = SET_DATA_BITS (DataBits);
+ }
+
+ //
+ // Set Parity
+ //
+ if (Parity == DefaultParity) {
+ Parity = LastSettings->Parity;
+ }
+
+ if (Parity == NoParity) {
+ DevReq.Value |= SET_PARITY_NONE;
+ } else if (Parity == EvenParity) {
+ DevReq.Value |= SET_PARITY_EVEN;
+ } else if (Parity == OddParity){
+ DevReq.Value |= SET_PARITY_ODD;
+ } else if (Parity == MarkParity) {
+ DevReq.Value |= SET_PARITY_MARK;
+ } else if (Parity == SpaceParity) {
+ DevReq.Value |= SET_PARITY_SPACE;
+ }
+
+ //
+ // Set Stop Bits
+ //
+ if (StopBits == DefaultStopBits) {
+ StopBits = LastSettings->StopBits;
+ }
+
+ if (StopBits == OneStopBit) {
+ DevReq.Value |= SET_STOP_BITS_1;
+ } else if (StopBits == OneFiveStopBits) {
+ DevReq.Value |= SET_STOP_BITS_15;
+ } else if (StopBits == TwoStopBits) {
+ DevReq.Value |= SET_STOP_BITS_2;
+ }
+
+ //
+ // set the rest of the DevReq parameters and perform the usb control transfer
+ // to set the data bits on the device
+ //
+ DevReq.Request = FTDI_COMMAND_SET_DATA;
+ DevReq.RequestType = USB_REQ_TYPE_VENDOR;
+ DevReq.Index = FTDI_PORT_IDENTIFIER;
+ DevReq.Length = 0; // indicates that there is no data phase in this request
+
+ Status = UsbIo->UsbControlTransfer (
+ UsbIo,
+ &DevReq,
+ EfiUsbDataOut,
+ WDR_SHORT_TIMEOUT,
+ &ConfigurationValue,
+ 1,
+ &ReturnValue
+ );
+ if (EFI_ERROR (Status)) {
+ goto StatusError;
+ }
+ return Status;
+
+StatusError:
+ if ((Status != EFI_INVALID_PARAMETER) || (Status != EFI_DEVICE_ERROR)) {
+ return EFI_DEVICE_ERROR;
+ } else {
+ return Status;
+ }
+}
+
+/**
+ Internal function that sets the baudrate on the Usb Serial Device.
+
+ @param UsbIo[in] Usb Io Protocol instance pointer
+ @param BaudRate[in] The baudrate value to be set on the device.
+ If this value is 0 the value of LastBaudRate
+ will be used instead
+ @param LastBaudRate[in] The baud rate value that was previously set
+ on the Usb Serial Device
+
+ @retval EFI_SUCCESS The baudrate was set succesfully
+ @retval EFI_INVALID_PARAMETER An invalid baudrate was used
+ @retval EFI_DEVICE_ERROR The device is not functioning correctly and
+ the baudrate was unable to be set
+
+**/
+EFI_STATUS
+EFIAPI
+SetBaudRateInternal (
+ IN EFI_USB_IO_PROTOCOL *UsbIo,
+ IN UINT64 BaudRate,
+ IN UINT64 LastBaudRate
+ )
+{
+ EFI_STATUS Status;
+ EFI_USB_DEVICE_REQUEST DevReq;
+ UINT32 ReturnValue;
+ UINT8 ConfigurationValue;
+ UINT16 EncodedBaudRate;
+ EFI_TPL Tpl;
+
+ Tpl = gBS->RaiseTPL(TPL_NOTIFY);
+
+ //
+ // set the value of DevReq.Value based on the value of BaudRate
+ // if 0 is selected as baud rate use the value of LastBaudRate
+ //
+ if (BaudRate == 0) {
+ Status = EncodeBaudRateForFtdi (LastBaudRate, &EncodedBaudRate);
+ if (EFI_ERROR (Status)) {
+ gBS->RestoreTPL (Tpl);
+ //
+ // EncodeBaudRateForFtdi returns EFI_INVALID_PARAMETER when not
+ // succesfull
+ //
+ return Status;
+ }
+ DevReq.Value = EncodedBaudRate;
+ } else {
+ Status = EncodeBaudRateForFtdi (BaudRate, &EncodedBaudRate);
+ if (EFI_ERROR (Status)) {
+ gBS->RestoreTPL (Tpl);
+ //
+ // EncodeBaudRateForFtdi returns EFI_INVALID_PARAMETER when not
+ // successfull
+ //
+ return Status;
+ }
+ DevReq.Value = EncodedBaudRate;
+ }
+
+ //
+ // set the remaining parameters of DevReq and perform the usb control transfer
+ // to set the device
+ //
+ DevReq.Request = FTDI_COMMAND_SET_BAUDRATE;
+ DevReq.RequestType = USB_REQ_TYPE_VENDOR;
+ DevReq.Index = FTDI_PORT_IDENTIFIER;
+ DevReq.Length = 0; // indicates that there is no data phase in this request
+
+ Status = UsbIo->UsbControlTransfer (
+ UsbIo,
+ &DevReq,
+ EfiUsbDataOut,
+ WDR_SHORT_TIMEOUT,
+ &ConfigurationValue,
+ 1,
+ &ReturnValue
+ );
+ if (EFI_ERROR (Status)) {
+ goto StatusError;
+ }
+ gBS->RestoreTPL (Tpl);
+ return Status;
+
+StatusError:
+ gBS->RestoreTPL (Tpl);
+ if ((Status != EFI_INVALID_PARAMETER) || (Status != EFI_DEVICE_ERROR)) {
+ return EFI_DEVICE_ERROR;
+ } else {
+ return Status;
+ }
+}
+
+/**
+ Sets the baud rate, receive FIFO depth, transmit/receice time out, parity,
+ data bits, and stop bits on a serial device.
+
+ @param UsbSerialDevice[in] Pointer to the current instance of the USB Serial
+ Device.
+ @param BaudRate[in] The requested baud rate. A BaudRate value of 0
+ will use the device's default interface speed.
+ @param ReveiveFifoDepth[in] The requested depth of the FIFO on the receive
+ side of the serial interface. A ReceiveFifoDepth
+ value of 0 will use the device's default FIFO
+ depth.
+ @param Timeout[in] The requested time out for a single character in
+ microseconds.This timeout applies to both the
+ transmit and receive side of the interface.A
+ Timeout value of 0 will use the device's default
+ time out value.
+ @param Parity[in] The type of parity to use on this serial device.
+ A Parity value of DefaultParity will use the
+ device's default parity value.
+ @param DataBits[in] The number of data bits to use on the serial
+ device. A DataBits value of 0 will use the
+ device's default data bit setting.
+ @param StopBits[in] The number of stop bits to use on this serial
+ device. A StopBits value of DefaultStopBits will
+ use the device's default number of stop bits.
+
+ @retval EFI_SUCCESS The attributes were set
+ @retval EFI_DEVICE_ERROR The attributes were not able to be set
+
+**/
+EFI_STATUS
+EFIAPI
+SetAttributesInternal (
+ IN USB_SER_DEV *UsbSerialDevice,
+ IN UINT64 BaudRate,
+ IN UINT32 ReceiveFifoDepth,
+ IN UINT32 Timeout,
+ IN EFI_PARITY_TYPE Parity,
+ IN UINT8 DataBits,
+ IN EFI_STOP_BITS_TYPE StopBits
+ )
+{
+ EFI_STATUS Status;
+ EFI_TPL Tpl;
+ UART_DEVICE_PATH *Uart;
+ EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath;
+
+ Status = EFI_UNSUPPORTED;
+ Tpl = gBS->RaiseTPL(TPL_NOTIFY);
+ Uart = NULL;
+
+ //
+ // check for invalid combinations of parameters
+ //
+ if (((DataBits >= 6) && (DataBits <= 8)) && (StopBits == OneFiveStopBits)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // set data bits, parity and stop bits
+ //
+ Status = SetDataInternal (
+ UsbSerialDevice->UsbIo,
+ DataBits,
+ Parity,
+ StopBits,
+ &(UsbSerialDevice->LastSettings)
+ );
+ if (EFI_ERROR (Status)) {
+ goto StatusError;
+ }
+ //
+ // set baudrate
+ //
+ Status = SetBaudRateInternal (
+ UsbSerialDevice->UsbIo,
+ BaudRate,
+ UsbSerialDevice->LastSettings.BaudRate
+ );
+ if (EFI_ERROR (Status)){
+ goto StatusError;
+ }
+
+ //
+ // update the values of UsbSerialDevice->LastSettings and UsbSerialDevice->SerialIo.Mode
+ //
+ if (BaudRate == 0) {
+ UsbSerialDevice->LastSettings.BaudRate = UsbSerialDevice->LastSettings.BaudRate;
+ UsbSerialDevice->SerialIo.Mode->BaudRate = UsbSerialDevice->LastSettings.BaudRate;
+ } else {
+ UsbSerialDevice->LastSettings.BaudRate = BaudRate;
+ UsbSerialDevice->SerialIo.Mode->BaudRate = BaudRate;
+ }
+
+ UsbSerialDevice->LastSettings.Timeout = FTDI_TIMEOUT;
+ UsbSerialDevice->LastSettings.ReceiveFifoDepth = FTDI_MAX_RECEIVE_FIFO_DEPTH;
+
+ if (Parity == DefaultParity) {
+ UsbSerialDevice->LastSettings.Parity = UsbSerialDevice->LastSettings.Parity;
+ UsbSerialDevice->SerialIo.Mode->Parity = UsbSerialDevice->LastSettings.Parity;
+ } else {
+ UsbSerialDevice->LastSettings.Parity = Parity;
+ UsbSerialDevice->SerialIo.Mode->Parity = Parity;
+ }
+ if (DataBits == 0) {
+ UsbSerialDevice->LastSettings.DataBits = UsbSerialDevice->LastSettings.DataBits;
+ UsbSerialDevice->SerialIo.Mode->DataBits = UsbSerialDevice->LastSettings.DataBits;
+ } else {
+ UsbSerialDevice->LastSettings.DataBits = DataBits;
+ UsbSerialDevice->SerialIo.Mode->DataBits = DataBits;
+ }
+ if (StopBits == DefaultStopBits) {
+ UsbSerialDevice->LastSettings.StopBits = UsbSerialDevice->LastSettings.StopBits;
+ UsbSerialDevice->SerialIo.Mode->StopBits = UsbSerialDevice->LastSettings.StopBits;
+ } else {
+ UsbSerialDevice->LastSettings.StopBits = StopBits;
+ UsbSerialDevice->SerialIo.Mode->StopBits = StopBits;
+ }
+
+ //
+ // See if the device path node has changed
+ //
+ if (UsbSerialDevice->UartDevicePath.BaudRate == BaudRate &&
+ UsbSerialDevice->UartDevicePath.DataBits == DataBits &&
+ UsbSerialDevice->UartDevicePath.StopBits == StopBits &&
+ UsbSerialDevice->UartDevicePath.Parity == Parity
+ ) {
+ gBS->RestoreTPL (Tpl);
+ return EFI_SUCCESS;
+ }
+
+ //
+ // Update the device path
+ //
+ UsbSerialDevice->UartDevicePath.BaudRate = BaudRate;
+ UsbSerialDevice->UartDevicePath.DataBits = DataBits;
+ UsbSerialDevice->UartDevicePath.StopBits = (UINT8) StopBits;
+ UsbSerialDevice->UartDevicePath.Parity = (UINT8) Parity;
+
+ Status = EFI_SUCCESS;
+ if (UsbSerialDevice->ControllerHandle != NULL) {
+ RemainingDevicePath = UsbSerialDevice->DevicePath;
+ while (!IsDevicePathEnd (RemainingDevicePath)) {
+ Uart = (UART_DEVICE_PATH *) NextDevicePathNode (RemainingDevicePath);
+ if (Uart->Header.Type == MESSAGING_DEVICE_PATH &&
+ Uart->Header.SubType == MSG_UART_DP &&
+ sizeof (UART_DEVICE_PATH) == DevicePathNodeLength ((EFI_DEVICE_PATH *) Uart)) {
+ Uart->BaudRate = BaudRate;
+ Uart->DataBits = DataBits;
+ Uart->StopBits = (UINT8)StopBits;
+ Uart->Parity = (UINT8) Parity;
+ break;
+ }
+ RemainingDevicePath = NextDevicePathNode (RemainingDevicePath);
+ }
+ }
+
+ gBS->RestoreTPL (Tpl);
+ return Status;
+
+StatusError:
+ gBS->RestoreTPL (Tpl);
+ if ((Status != EFI_INVALID_PARAMETER) || (Status != EFI_DEVICE_ERROR)) {
+ return EFI_DEVICE_ERROR;
+ } else {
+ return Status;
+ }
+}
+
+/**
+ Internal function that performs a Usb Control Transfer to set the flow control
+ on the Usb Serial Device.
+
+ @param UsbIo[in] Usb Io Protocol instance pointer
+ @param FlowControlEnable[in] Data on the Enable/Disable status of Flow
+ Control on the Usb Serial Device
+
+ @retval EFI_SUCCESS The flow control was set on the Usb Serial
+ device
+ @retval EFI_INVALID_PARAMETER An invalid flow control value was used
+ @retval EFI_EFI_UNSUPPORTED The operation is not supported
+ @retval EFI_DEVICE_ERROR The device is not functioning correctly
+
+**/
+EFI_STATUS
+EFIAPI
+SetFlowControlInternal (
+ IN EFI_USB_IO_PROTOCOL *UsbIo,
+ IN BOOLEAN FlowControlEnable
+ )
+{
+ EFI_STATUS Status;
+ EFI_USB_DEVICE_REQUEST DevReq;
+ UINT32 ReturnValue;
+ UINT8 ConfigurationValue;
+
+ //
+ // set DevReq.Value based on the value of FlowControlEnable
+ //
+ if (!FlowControlEnable) {
+ DevReq.Value = NO_FLOW_CTRL;
+ }
+ if (FlowControlEnable) {
+ DevReq.Value = XON_XOFF_CTRL;
+ }
+ //
+ // set the remaining DevReq parameters and perform the usb control transfer to
+ // set the flow control on the device
+ //
+ DevReq.Request = FTDI_COMMAND_SET_FLOW_CTRL;
+ DevReq.RequestType = USB_REQ_TYPE_VENDOR;
+ DevReq.Index = FTDI_PORT_IDENTIFIER;
+ DevReq.Length = 0; // indicates that this transfer has no data phase
+ Status = UsbIo->UsbControlTransfer (
+ UsbIo,
+ &DevReq,
+ EfiUsbDataOut,
+ WDR_TIMEOUT,
+ &ConfigurationValue,
+ 1,
+ &ReturnValue
+ );
+ if (EFI_ERROR (Status)) {
+ goto StatusError;
+ }
+
+ return Status;
+
+StatusError:
+ if ((Status != EFI_INVALID_PARAMETER) ||
+ (Status != EFI_DEVICE_ERROR) ||
+ (Status != EFI_UNSUPPORTED) ) {
+ return EFI_DEVICE_ERROR;
+ } else {
+ return Status;
+ }
+}
+
+/**
+ Internal function that performs a Usb Control Transfer to set the Dtr value on
+ the Usb Serial Device.
+
+ @param UsbIo[in] Usb Io Protocol instance pointer
+ @param DtrEnable[in] Data on the Enable/Disable status of the
+ Dtr for the Usb Serial Device
+
+ @retval EFI_SUCCESS The Dtr value was set on the Usb Serial
+ Device
+ @retval EFI_INVALID_PARAMETER An invalid Dtr value was used
+ @retval EFI_UNSUPPORTED The operation is not supported
+ @retval EFI_DEVICE_ERROR The device is not functioning correctly
+
+**/
+EFI_STATUS
+EFIAPI
+SetDtrInternal (
+ IN EFI_USB_IO_PROTOCOL *UsbIo,
+ IN BOOLEAN DtrEnable
+ )
+{
+ EFI_STATUS Status;
+ EFI_USB_DEVICE_REQUEST DevReq;
+ UINT32 ReturnValue;
+ UINT8 ConfigurationValue;
+
+ //
+ // set the value of DevReq.Value based on the value of DtrEnable
+ //
+ if (!DtrEnable) {
+ DevReq.Value = SET_DTR_LOW;
+ }
+ if (DtrEnable) {
+ DevReq.Value = SET_DTR_HIGH;
+ }
+ //
+ // set the remaining attributes of DevReq and perform the usb control transfer
+ // to set the device
+ //
+ DevReq.Request = FTDI_COMMAND_MODEM_CTRL;
+ DevReq.RequestType = USB_REQ_TYPE_VENDOR;
+ DevReq.Index = FTDI_PORT_IDENTIFIER;
+ DevReq.Length = 0; // indicates that there is no data phase in this transfer
+
+ Status = UsbIo->UsbControlTransfer (
+ UsbIo,
+ &DevReq,
+ EfiUsbDataOut,
+ WDR_TIMEOUT,
+ &ConfigurationValue,
+ 1,
+ &ReturnValue
+ );
+ if (EFI_ERROR (Status)) {
+ goto StatusError;
+ }
+ return Status;
+
+StatusError:
+ if ((Status != EFI_INVALID_PARAMETER) ||
+ (Status != EFI_DEVICE_ERROR) ||
+ (Status != EFI_UNSUPPORTED) ) {
+ return EFI_DEVICE_ERROR;
+ } else {
+ return Status;
+ }
+}
+
+/**
+ Internal function that performs a Usb Control Transfer to set the Dtr value on
+ the Usb Serial Device.
+
+ @param UsbIo[in] Usb Io Protocol instance pointer
+ @param RtsEnable[in] Data on the Enable/Disable status of the
+ Rts for the Usb Serial Device
+
+ @retval EFI_SUCCESS The Rts value was set on the Usb Serial
+ Device
+ @retval EFI_INVALID_PARAMETER An invalid Rts value was used
+ @retval EFI_UNSUPPORTED The operation is not supported
+ @retval EFI_DEVICE_ERROR The device is not functioning correctly
+
+**/
+EFI_STATUS
+EFIAPI
+SetRtsInternal (
+ IN EFI_USB_IO_PROTOCOL *UsbIo,
+ IN BOOLEAN RtsEnable
+ )
+{
+ EFI_STATUS Status;
+ EFI_USB_DEVICE_REQUEST DevReq;
+ UINT32 ReturnValue;
+ UINT8 ConfigurationValue;
+
+ //
+ // set DevReq.Value based on the value of RtsEnable
+ //
+ if (!RtsEnable) {
+ DevReq.Value = SET_RTS_LOW;
+ }
+ if (RtsEnable) {
+ DevReq.Value = SET_RTS_HIGH;
+ }
+
+ //
+ // set the remaining parameters of DevReq and perform the usb control transfer
+ // to set the values on the device
+ //
+ DevReq.Request = FTDI_COMMAND_MODEM_CTRL;
+ DevReq.RequestType = USB_REQ_TYPE_VENDOR;
+ DevReq.Index = FTDI_PORT_IDENTIFIER;
+ DevReq.Length = 0; // indicates that there is no data phase in this request
+
+ Status = UsbIo->UsbControlTransfer (
+ UsbIo,
+ &DevReq,
+ EfiUsbDataOut,
+ WDR_TIMEOUT,
+ &ConfigurationValue,
+ 1,
+ &ReturnValue
+ );
+ if (EFI_ERROR (Status)) {
+ goto StatusError;
+ }
+
+ return Status;
+
+StatusError:
+ if ((Status != EFI_INVALID_PARAMETER) ||
+ (Status != EFI_DEVICE_ERROR) ||
+ (Status != EFI_UNSUPPORTED) ) {
+ return EFI_DEVICE_ERROR;
+ } else {
+ return Status;
+ }
+}
+
+/**
+ Internal function that checks for valid control values and sets the control
+ bits on the Usb Serial Device.
+
+ @param UsbSerialDevice[in] Handle to the Usb Serial Device whose
+ control bits are being set
+ @param Control[in] The control value passed to the function
+ that contains the values of the control
+ bits that are being set
+
+ @retval EFI_SUCCESS The control bits were set on the Usb Serial
+ Device
+ @retval EFI_INVALID_PARAMETER An invalid control value was encountered
+ @retval EFI_EFI_UNSUPPORTED The operation is not supported
+ @retval EFI_DEVICE_ERROR The device is not functioning correctly
+
+**/
+EFI_STATUS
+EFIAPI
+SetControlBitsInternal (
+ IN USB_SER_DEV *UsbSerialDevice,
+ IN CONTROL_BITS *Control
+ )
+{
+ EFI_STATUS Status;
+ UART_FLOW_CONTROL_DEVICE_PATH *FlowControl;
+ EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath;
+
+ //
+ // check for invalid control parameters hardware and software loopback enabled
+ // must always be set to FALSE
+ //
+ Control->HardwareLoopBack = FALSE;
+ Control->SoftwareLoopBack = FALSE;
+
+ //
+ // set hardware flow control
+ //
+ Status = SetFlowControlInternal (
+ UsbSerialDevice->UsbIo,
+ Control->HardwareFlowControl
+ );
+ if (EFI_ERROR (Status)) {
+ goto StatusError;
+ }
+
+ //
+ // set Dtr state
+ //
+ Status = SetDtrInternal (UsbSerialDevice->UsbIo, Control->DtrState);
+ if (EFI_ERROR (Status)) {
+ goto StatusError;
+ }
+
+ //
+ // set Rts state
+ //
+ Status = SetRtsInternal (UsbSerialDevice->UsbIo, Control->RtsState);
+ if (EFI_ERROR (Status)){
+ goto StatusError;
+ }
+
+ //
+ // update the remaining control values for UsbSerialDevice->ControlValues
+ //
+ UsbSerialDevice->ControlValues.DtrState = Control->DtrState;
+ UsbSerialDevice->ControlValues.RtsState = Control->RtsState;
+ UsbSerialDevice->ControlValues.HardwareFlowControl = Control->HardwareFlowControl;
+ UsbSerialDevice->ControlValues.HardwareLoopBack = FALSE;
+ UsbSerialDevice->ControlValues.SoftwareLoopBack = FALSE;
+
+ Status = EFI_SUCCESS;
+ //
+ // Update the device path to have the correct flow control values
+ //
+ if (UsbSerialDevice->ControllerHandle != NULL) {
+ RemainingDevicePath = UsbSerialDevice->DevicePath;
+ while (!IsDevicePathEnd (RemainingDevicePath)) {
+ FlowControl = (UART_FLOW_CONTROL_DEVICE_PATH *) NextDevicePathNode (RemainingDevicePath);
+ if (FlowControl->Header.Type == MESSAGING_DEVICE_PATH &&
+ FlowControl->Header.SubType == MSG_VENDOR_DP &&
+ sizeof (UART_FLOW_CONTROL_DEVICE_PATH) == DevicePathNodeLength ((EFI_DEVICE_PATH *) FlowControl)){
+ if (UsbSerialDevice->ControlValues.HardwareFlowControl == TRUE) {
+ FlowControl->FlowControlMap = UART_FLOW_CONTROL_HARDWARE;
+ } else if (UsbSerialDevice->ControlValues.HardwareFlowControl == FALSE) {
+ FlowControl->FlowControlMap = 0;
+ }
+ break;
+ }
+ RemainingDevicePath = NextDevicePathNode (RemainingDevicePath);
+ }
+ }
+
+ return Status;
+
+StatusError:
+ if ((Status != EFI_INVALID_PARAMETER) ||
+ (Status != EFI_DEVICE_ERROR) ||
+ (Status != EFI_UNSUPPORTED) ) {
+ return EFI_DEVICE_ERROR;
+ } else {
+ return Status;
+ }
+}
+
+/**
+ Internal function that calculates the Control value used by GetControlBits()
+ based on the status and control values of the Usb Serial Device.
+
+ @param UsbSerialDevice[in] Handle to the Usb Serial Devie whose status
+ and control values are being used to set
+ Control
+ @param Control[out] On output the formated value of Control
+ that has been calculated based on the
+ control and status values of the Usb Serial
+ Device
+
+ @retval EFI_SUCCESS The value of Control was successfully
+ calculated
+
+**/
+EFI_STATUS
+EFIAPI
+GetControlBitsInternal (
+ IN USB_SER_DEV *UsbSerialDevice,
+ OUT UINT32 *Control
+ )
+{
+ *Control = 0;
+
+ //
+ // Check the values of UsbSerialDevice->Status Values and modify control
+ // accordingly these values correspond to the modem status register
+ //
+ if (UsbSerialDevice->StatusValues.CtsState) {
+ *Control |= EFI_SERIAL_CLEAR_TO_SEND;
+ }
+ if (UsbSerialDevice->StatusValues.DsrState) {
+ *Control |= EFI_SERIAL_DATA_SET_READY;
+ }
+ if (UsbSerialDevice->StatusValues.RiState) {
+ *Control |= EFI_SERIAL_RING_INDICATE;
+ }
+ if (UsbSerialDevice->StatusValues.SdState) {
+ *Control |= EFI_SERIAL_CARRIER_DETECT;
+ }
+
+ //
+ // check the values of UsbSerialDevice->ControlValues and modify control
+ // accordingly these values correspond to the values of the Modem Control
+ // Register
+ //
+ if (UsbSerialDevice->ControlValues.DtrState) {
+ *Control |= EFI_SERIAL_DATA_TERMINAL_READY;
+ }
+ if (UsbSerialDevice->ControlValues.RtsState) {
+ *Control |= EFI_SERIAL_REQUEST_TO_SEND;
+ }
+ if (UsbSerialDevice->ControlValues.HardwareLoopBack) {
+ *Control |= EFI_SERIAL_HARDWARE_LOOPBACK_ENABLE;
+ }
+ if (UsbSerialDevice->ControlValues.HardwareFlowControl) {
+ *Control |= EFI_SERIAL_HARDWARE_FLOW_CONTROL_ENABLE;
+ }
+ //
+ // check if the buffer is empty since only one is being used if it is empty
+ // set both the receive and transmit buffers to empty
+ //
+ if (UsbSerialDevice->DataBufferHead == UsbSerialDevice->DataBufferTail) {
+ *Control |= EFI_SERIAL_OUTPUT_BUFFER_EMPTY;
+ *Control |= EFI_SERIAL_INPUT_BUFFER_EMPTY;
+ }
+ //
+ // check for software loopback enable in UsbSerialDevice->ControlValues
+ //
+ if (UsbSerialDevice->ControlValues.SoftwareLoopBack) {
+ *Control |= EFI_SERIAL_SOFTWARE_LOOPBACK_ENABLE;
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Resets the USB Serial Device
+
+ This function is the internal method for reseting the device and is called by
+ SerialReset()
+
+ @param UsbSerialDevice[in] A pointer to the USB Serial device
+
+ @retval EFI_SUCCESS The device was reset
+ @retval EFI_DEVICE_ERROR The device could not be reset
+
+**/
+EFI_STATUS
+EFIAPI
+ResetInternal (
+ IN USB_SER_DEV *UsbSerialDevice
+ )
+{
+ EFI_STATUS Status;
+ EFI_USB_DEVICE_REQUEST DevReq;
+ UINT8 ConfigurationValue;
+ UINT32 ReturnValue;
+
+ DevReq.Request = FTDI_COMMAND_RESET_PORT;
+ DevReq.RequestType = USB_REQ_TYPE_VENDOR;
+ DevReq.Value = RESET_PORT_PURGE_RX;
+ DevReq.Index = FTDI_PORT_IDENTIFIER;
+ DevReq.Length = 0; //indicates that there is not data phase in this request
+
+ Status = UsbSerialDevice->UsbIo->UsbControlTransfer (
+ UsbSerialDevice->UsbIo,
+ &DevReq,
+ EfiUsbDataIn,
+ WDR_TIMEOUT,
+ &ConfigurationValue,
+ 1,
+ &ReturnValue
+ );
+ if (EFI_ERROR (Status)) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ DevReq.Request = FTDI_COMMAND_RESET_PORT;
+ DevReq.RequestType = USB_REQ_TYPE_VENDOR;
+ DevReq.Value = RESET_PORT_PURGE_TX;
+ DevReq.Index = FTDI_PORT_IDENTIFIER;
+ DevReq.Length = 0; //indicates that there is no data phase in this request
+
+ Status = UsbSerialDevice->UsbIo->UsbControlTransfer (
+ UsbSerialDevice->UsbIo,
+ &DevReq,
+ EfiUsbDataIn,
+ WDR_TIMEOUT,
+ &ConfigurationValue,
+ 1,
+ &ReturnValue
+ );
+ if (EFI_ERROR (Status)) {
+ return EFI_DEVICE_ERROR;
+ }
+ return Status;
+}
+
+/**
+ Entrypoint of USB Serial Driver.
+
+ This function is the entrypoint of USB Serial Driver. It installs
+ Driver Binding Protocols together with Component Name Protocols.
+
+ @param ImageHandle[in] The firmware allocated handle for the EFI image.
+ @param SystemTable[in] A pointer to the EFI System Table.
+
+ @retval EFI_SUCCESS The entry point is executed successfully.
+
+**/
+EFI_STATUS
+EFIAPI
+FtdiUsbSerialEntryPoint (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+
+ Status = EfiLibInstallDriverBindingComponentName2 (
+ ImageHandle,
+ SystemTable,
+ &gUsbSerialDriverBinding,
+ ImageHandle,
+ &gUsbSerialComponentName,
+ &gUsbSerialComponentName2
+ );
+ ASSERT_EFI_ERROR (Status);
+ return EFI_SUCCESS;
+}
+
+/**
+ Unload function for the Usb Serial Driver.
+
+ @param ImageHandle[in] The allocated handle for the EFI image
+
+ @retval EFI_SUCCESS The driver was unloaded successfully
+**/
+EFI_STATUS
+EFIAPI
+FtdiUsbSerialUnload (
+ IN EFI_HANDLE ImageHandle
+ )
+{
+ EFI_STATUS Status;
+ EFI_HANDLE *HandleBuffer;
+ UINTN HandleCount;
+ UINTN Index;
+
+ //
+ // Retrieve all handles in the handle database
+ //
+ Status = gBS->LocateHandleBuffer (
+ AllHandles,
+ NULL,
+ NULL,
+ &HandleCount,
+ &HandleBuffer
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Disconnect the driver from the handles in the handle database
+ //
+ for (Index = 0; Index < HandleCount; Index++) {
+ Status = gBS->DisconnectController (
+ HandleBuffer[Index],
+ gImageHandle,
+ NULL
+ );
+ }
+
+ //
+ // Free the handle array
+ //
+ FreePool (HandleBuffer);
+
+ //
+ // Uninstall protocols installed by the driver in its entrypoint
+ //
+ Status = gBS->UninstallMultipleProtocolInterfaces (
+ ImageHandle,
+ &gEfiDriverBindingProtocolGuid,
+ &gUsbSerialDriverBinding,
+ &gEfiComponentNameProtocolGuid,
+ &gUsbSerialComponentName,
+ &gEfiComponentName2ProtocolGuid,
+ &gUsbSerialComponentName2,
+ NULL
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Check whether USB Serial driver supports this device.
+
+ @param This[in] The USB Serial driver binding protocol.
+ @param Controller[in] The controller handle to check.
+ @param RemainingDevicePath[in] The remaining device path.
+
+ @retval EFI_SUCCESS The driver supports this controller.
+ @retval other This device isn't supported.
+
+**/
+EFI_STATUS
+EFIAPI
+UsbSerialDriverBindingSupported (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Controller,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
+ )
+{
+ EFI_STATUS Status;
+ EFI_USB_IO_PROTOCOL *UsbIo;
+ UART_DEVICE_PATH *UartNode;
+ UART_FLOW_CONTROL_DEVICE_PATH *FlowControlNode;
+ UINTN Index;
+ UINTN EntryCount;
+ EFI_OPEN_PROTOCOL_INFORMATION_ENTRY *OpenInfoBuffer;
+ BOOLEAN HasFlowControl;
+ EFI_DEVICE_PATH_PROTOCOL *DevicePath;
+ EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath;
+
+ if (RemainingDevicePath != NULL) {
+ if (!IsDevicePathEnd (RemainingDevicePath)) {
+ Status = EFI_UNSUPPORTED;
+ UartNode = (UART_DEVICE_PATH *) NextDevicePathNode (RemainingDevicePath);
+ if (UartNode->Header.Type != MESSAGING_DEVICE_PATH ||
+ UartNode->Header.SubType != MSG_UART_DP ||
+ sizeof (UART_DEVICE_PATH) != DevicePathNodeLength ((EFI_DEVICE_PATH *) UartNode)) {
+ goto Error;
+ }
+ FlowControlNode = (UART_FLOW_CONTROL_DEVICE_PATH *) NextDevicePathNode (UartNode);
+ if ((ReadUnaligned32 (&FlowControlNode->FlowControlMap) & ~UART_FLOW_CONTROL_HARDWARE) != 0) {
+ goto Error;
+ }
+ }
+ }
+
+ //
+ // Check if USB I/O Protocol is attached on the controller handle.
+ //
+ Status = gBS->OpenProtocol (
+ Controller,
+ &gEfiUsbIoProtocolGuid,
+ (VOID **) &UsbIo,
+ This->DriverBindingHandle,
+ Controller,
+ EFI_OPEN_PROTOCOL_BY_DRIVER
+ );
+ if (Status == EFI_ALREADY_STARTED) {
+ if (RemainingDevicePath == NULL || IsDevicePathEnd (RemainingDevicePath)) {
+ return EFI_SUCCESS;
+ }
+ Status = gBS->OpenProtocolInformation (
+ Controller,
+ &gEfiUsbIoProtocolGuid,
+ &OpenInfoBuffer,
+ &EntryCount
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ for (Index = 0; Index < EntryCount; Index++) {
+ if ((OpenInfoBuffer[Index].Attributes & EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) != 0) {
+ Status = gBS->OpenProtocol (
+ OpenInfoBuffer[Index].ControllerHandle,
+ &gEfiDevicePathProtocolGuid,
+ (VOID **) &DevicePath,
+ This->DriverBindingHandle,
+ Controller,
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL
+ );
+ if (!EFI_ERROR (Status)) {
+ HasFlowControl = ContainsFlowControl (RemainingDevicePath);
+ if (HasFlowControl ^ ContainsFlowControl (DevicePath)) {
+ Status = EFI_UNSUPPORTED;
+ }
+ }
+ break;
+ }
+ }
+ FreePool (OpenInfoBuffer);
+ return Status;
+ }
+
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ gBS->CloseProtocol (
+ Controller,
+ &gEfiUsbIoProtocolGuid,
+ This->DriverBindingHandle,
+ Controller
+ );
+
+ Status = gBS->OpenProtocol (
+ Controller,
+ &gEfiDevicePathProtocolGuid,
+ (VOID **) &ParentDevicePath,
+ This->DriverBindingHandle,
+ Controller,
+ EFI_OPEN_PROTOCOL_BY_DRIVER
+ );
+ if (Status == EFI_ALREADY_STARTED) {
+ return EFI_SUCCESS;
+ }
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Use the USB I/O Protocol interface to check whether Controller is
+ // a USB Serial device that can be managed by this driver.
+ //
+ Status = EFI_SUCCESS;
+
+ if (!IsUsbSerial (UsbIo)) {
+ Status = EFI_UNSUPPORTED;
+ goto Error;
+ }
+
+Error:
+ gBS->CloseProtocol (
+ Controller,
+ &gEfiDevicePathProtocolGuid,
+ This->DriverBindingHandle,
+ Controller
+ );
+ return Status;
+}
+
+/**
+ Starts the USB Serial device with this driver.
+
+ This function produces initializes the USB Serial device and
+ produces the Serial IO Protocol.
+
+ @param This[in] The USB Serial driver binding instance.
+ @param Controller[in] Handle of device to bind driver to.
+ @param RemainingDevicePath[in] Optional parameter use to pick a specific
+ child device to start.
+
+ @retval EFI_SUCCESS The controller is controlled by the usb USB
+ Serial driver.
+ @retval EFI_UNSUPPORTED No interrupt endpoint can be found.
+ @retval Other This controller cannot be started.
+
+**/
+EFI_STATUS
+EFIAPI
+UsbSerialDriverBindingStart (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Controller,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
+ )
+{
+ EFI_STATUS Status;
+ EFI_USB_IO_PROTOCOL *UsbIo;
+ USB_SER_DEV *UsbSerialDevice;
+ UINT8 EndpointNumber;
+ EFI_USB_ENDPOINT_DESCRIPTOR EndpointDescriptor;
+ UINT8 Index;
+ BOOLEAN FoundIn;
+ BOOLEAN FoundOut;
+ EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath;
+ EFI_OPEN_PROTOCOL_INFORMATION_ENTRY *OpenInfoBuffer;
+ UINTN EntryCount;
+ EFI_SERIAL_IO_PROTOCOL *SerialIo;
+ UART_DEVICE_PATH *Uart;
+ UART_FLOW_CONTROL_DEVICE_PATH *FlowControl;
+ UINT32 FlowControlMap;
+ UINT32 Control;
+ EFI_DEVICE_PATH_PROTOCOL *TempDevicePath;
+
+ UsbSerialDevice = AllocateZeroPool (sizeof (USB_SER_DEV));
+ ASSERT (UsbSerialDevice != NULL);
+
+ //
+ // Get the Parent Device path
+ //
+ Status = gBS->OpenProtocol (
+ Controller,
+ &gEfiDevicePathProtocolGuid,
+ (VOID **) &ParentDevicePath,
+ This->DriverBindingHandle,
+ Controller,
+ EFI_OPEN_PROTOCOL_BY_DRIVER
+ );
+ if (EFI_ERROR (Status) && Status != EFI_ALREADY_STARTED) {
+ goto ErrorExit1;
+ }
+
+ //
+ // Open USB I/O Protocol
+ //
+ Status = gBS->OpenProtocol (
+ Controller,
+ &gEfiUsbIoProtocolGuid,
+ (VOID **) &UsbIo,
+ This->DriverBindingHandle,
+ Controller,
+ EFI_OPEN_PROTOCOL_BY_DRIVER
+ );
+ if (EFI_ERROR (Status) && Status != EFI_ALREADY_STARTED) {
+ goto ErrorExit1;
+ }
+
+ if (Status == EFI_ALREADY_STARTED) {
+ if (RemainingDevicePath == NULL || IsDevicePathEnd (RemainingDevicePath)) {
+ FreePool (UsbSerialDevice);
+ return EFI_SUCCESS;
+ }
+
+ //
+ // Check to see if a child handle exists
+ //
+ Status = gBS->OpenProtocolInformation (
+ Controller,
+ &gEfiSerialIoProtocolGuid,
+ &OpenInfoBuffer,
+ &EntryCount
+ );
+ if (EFI_ERROR (Status)) {
+ goto ErrorExit1;
+ }
+
+ Status = EFI_ALREADY_STARTED;
+ for (Index = 0; Index < EntryCount; Index++) {
+ if ((OpenInfoBuffer[Index].Attributes & EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) != 0) {
+ Status = gBS->OpenProtocol (
+ OpenInfoBuffer[Index].ControllerHandle,
+ &gEfiSerialIoProtocolGuid,
+ (VOID **) &SerialIo,
+ This->DriverBindingHandle,
+ Controller,
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL
+ );
+ if (EFI_ERROR (Status)) {
+ }
+ if (!EFI_ERROR (Status)) {
+ Uart = (UART_DEVICE_PATH *) RemainingDevicePath;
+ Status = SerialIo->SetAttributes (
+ SerialIo,
+ Uart->BaudRate,
+ SerialIo->Mode->ReceiveFifoDepth,
+ SerialIo->Mode->Timeout,
+ (EFI_PARITY_TYPE) Uart->Parity,
+ Uart->DataBits,
+ (EFI_STOP_BITS_TYPE) Uart->StopBits
+ );
+ FlowControl = (UART_FLOW_CONTROL_DEVICE_PATH *) NextDevicePathNode (Uart);
+ if (!EFI_ERROR (Status) && IsUartFlowControlNode (FlowControl)) {
+ Status = SerialIo->GetControl (
+ SerialIo,
+ &Control
+ );
+ if (!EFI_ERROR (Status)) {
+ if (ReadUnaligned32 (&FlowControl->FlowControlMap) == UART_FLOW_CONTROL_HARDWARE) {
+ Control |= EFI_SERIAL_HARDWARE_FLOW_CONTROL_ENABLE;
+ } else {
+ Control &= ~EFI_SERIAL_HARDWARE_FLOW_CONTROL_ENABLE;
+ }
+ //
+ // Clear bits that are not allowed to be passed to SetControl
+ //
+ Control &= (EFI_SERIAL_REQUEST_TO_SEND |
+ EFI_SERIAL_DATA_TERMINAL_READY |
+ EFI_SERIAL_HARDWARE_LOOPBACK_ENABLE |
+ EFI_SERIAL_SOFTWARE_LOOPBACK_ENABLE |
+ EFI_SERIAL_HARDWARE_FLOW_CONTROL_ENABLE);
+ Status = SerialIo->SetControl (SerialIo, Control);
+ }
+ }
+ }
+ break;
+ }
+ }
+ FreePool (OpenInfoBuffer);
+ return Status;
+ }
+
+ if (RemainingDevicePath != NULL) {
+ if (IsDevicePathEnd (RemainingDevicePath)) {
+ return EFI_SUCCESS;
+ }
+ }
+
+ UsbSerialDevice->UsbIo = UsbIo;
+
+ //
+ // Get interface & endpoint descriptor
+ //
+ UsbIo->UsbGetInterfaceDescriptor (
+ UsbIo,
+ &UsbSerialDevice->InterfaceDescriptor
+ );
+
+ EndpointNumber = UsbSerialDevice->InterfaceDescriptor.NumEndpoints;
+
+ //
+ // Traverse endpoints to find the IN and OUT endpoints that will send and
+ // receive data.
+ //
+ FoundIn = FALSE;
+ FoundOut = FALSE;
+ for (Index = 0; Index < EndpointNumber; Index++) {
+
+ Status = UsbIo->UsbGetEndpointDescriptor (
+ UsbIo,
+ Index,
+ &EndpointDescriptor
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ if (EndpointDescriptor.EndpointAddress == FTDI_ENDPOINT_ADDRESS_OUT) {
+ //
+ // Set the Out endpoint device
+ //
+ CopyMem (
+ &UsbSerialDevice->OutEndpointDescriptor,
+ &EndpointDescriptor,
+ sizeof(EndpointDescriptor)
+ );
+ FoundOut = TRUE;
+ }
+
+ if (EndpointDescriptor.EndpointAddress == FTDI_ENDPOINT_ADDRESS_IN) {
+ //
+ // Set the In endpoint device
+ //
+ CopyMem (
+ &UsbSerialDevice->InEndpointDescriptor,
+ &EndpointDescriptor,
+ sizeof(EndpointDescriptor)
+ );
+ FoundIn = TRUE;
+ }
+ }
+
+ if (!FoundIn || !FoundOut) {
+ //
+ // No interrupt endpoint found, then return unsupported.
+ //
+ Status = EFI_UNSUPPORTED;
+ goto ErrorExit;
+ }
+ //
+ // set the initial values of UsbSerialDevice->LastSettings to the default
+ // values
+ //
+ UsbSerialDevice->LastSettings.BaudRate = 115200;
+ UsbSerialDevice->LastSettings.DataBits = 8;
+ UsbSerialDevice->LastSettings.Parity = NoParity;
+ UsbSerialDevice->LastSettings.ReceiveFifoDepth = FTDI_MAX_RECEIVE_FIFO_DEPTH;
+ UsbSerialDevice->LastSettings.StopBits = OneStopBit;
+ UsbSerialDevice->LastSettings.Timeout = FTDI_TIMEOUT;
+
+ //
+ // set the initial values of UsbSerialDevice->ControlValues
+ //
+ UsbSerialDevice->ControlValues.DtrState = FALSE;
+ UsbSerialDevice->ControlValues.RtsState = FALSE;
+ UsbSerialDevice->ControlValues.HardwareFlowControl = FALSE;
+ UsbSerialDevice->ControlValues.HardwareLoopBack = FALSE;
+ UsbSerialDevice->ControlValues.SoftwareLoopBack = FALSE;
+
+ //
+ // set the values of UsbSerialDevice->UartDevicePath
+ //
+ UsbSerialDevice->UartDevicePath.Header.Type = MESSAGING_DEVICE_PATH;
+ UsbSerialDevice->UartDevicePath.Header.SubType = MSG_UART_DP;
+ UsbSerialDevice->UartDevicePath.Header.Length[0] = (UINT8) (sizeof (UART_DEVICE_PATH));
+ UsbSerialDevice->UartDevicePath.Header.Length[1] = (UINT8) ((sizeof (UART_DEVICE_PATH)) >> 8);
+
+ //
+ // set the values of UsbSerialDevice->FlowControlDevicePath
+ UsbSerialDevice->FlowControlDevicePath.Header.Type = MESSAGING_DEVICE_PATH;
+ UsbSerialDevice->FlowControlDevicePath.Header.SubType = MSG_VENDOR_DP;
+ UsbSerialDevice->FlowControlDevicePath.Header.Length[0] = (UINT8) (sizeof (UART_FLOW_CONTROL_DEVICE_PATH));
+ UsbSerialDevice->FlowControlDevicePath.Header.Length[1] = (UINT8) ((sizeof (UART_FLOW_CONTROL_DEVICE_PATH)) >> 8);
+ UsbSerialDevice->FlowControlDevicePath.FlowControlMap = 0;
+
+ Status = SetAttributesInternal (
+ UsbSerialDevice,
+ UsbSerialDevice->LastSettings.BaudRate,
+ UsbSerialDevice->LastSettings.ReceiveFifoDepth,
+ UsbSerialDevice->LastSettings.Timeout,
+ UsbSerialDevice->LastSettings.Parity,
+ UsbSerialDevice->LastSettings.DataBits,
+ UsbSerialDevice->LastSettings.StopBits
+ );
+
+ ASSERT_EFI_ERROR (Status);
+
+ Status = SetControlBitsInternal (
+ UsbSerialDevice,
+ &(UsbSerialDevice->ControlValues)
+ );
+
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Publish Serial GUID and protocol
+ //
+
+ UsbSerialDevice->Signature = USB_SER_DEV_SIGNATURE;
+ UsbSerialDevice->SerialIo.Reset = SerialReset;
+ UsbSerialDevice->SerialIo.SetControl = SetControlBits;
+ UsbSerialDevice->SerialIo.SetAttributes = SetAttributes;
+ UsbSerialDevice->SerialIo.GetControl = GetControlBits;
+ UsbSerialDevice->SerialIo.Read = ReadSerialIo;
+ UsbSerialDevice->SerialIo.Write = WriteSerialIo;
+
+ //
+ // Set the static Serial IO modes that will display when running
+ // "sermode" within the UEFI shell.
+ //
+
+ UsbSerialDevice->SerialIo.Mode->Timeout = 0;
+ UsbSerialDevice->SerialIo.Mode->BaudRate = 115200;
+ UsbSerialDevice->SerialIo.Mode->DataBits = 8;
+ UsbSerialDevice->SerialIo.Mode->Parity = 1;
+ UsbSerialDevice->SerialIo.Mode->StopBits = 1;
+
+ UsbSerialDevice->ParentDevicePath = ParentDevicePath;
+ UsbSerialDevice->ControllerHandle = NULL;
+ FlowControl = NULL;
+ FlowControlMap = 0;
+
+ //
+ // Allocate space for the receive buffer
+ //
+ UsbSerialDevice->DataBuffer = AllocateZeroPool (SW_FIFO_DEPTH);
+
+ //
+ // Initialize data buffer pointers.
+ // Head==Tail = true means buffer is empty.
+ //
+ UsbSerialDevice->DataBufferHead = 0;
+ UsbSerialDevice->DataBufferTail = 0;
+
+ UsbSerialDevice->ControllerNameTable = NULL;
+ AddUnicodeString2 (
+ "eng",
+ gUsbSerialComponentName.SupportedLanguages,
+ &UsbSerialDevice->ControllerNameTable,
+ L"FTDI USB Serial Adapter",
+ TRUE
+ );
+ AddUnicodeString2 (
+ "en",
+ gUsbSerialComponentName2.SupportedLanguages,
+ &UsbSerialDevice->ControllerNameTable,
+ L"FTDI USB Serial Adapter",
+ FALSE
+ );
+
+ Status = SetInitialStatus (UsbSerialDevice);
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Create a polling loop to check for input
+ //
+
+ gBS->CreateEvent (
+ EVT_TIMER | EVT_NOTIFY_SIGNAL,
+ TPL_CALLBACK,
+ UsbSerialDriverCheckInput,
+ UsbSerialDevice,
+ &(UsbSerialDevice->PollingLoop)
+ );
+ //
+ // add code to set trigger time based on baud rate
+ // setting to 0.5s for now
+ //
+ gBS->SetTimer (
+ UsbSerialDevice->PollingLoop,
+ TimerPeriodic,
+ EFI_TIMER_PERIOD_MILLISECONDS (500)
+ );
+
+ //
+ // Check if the remaining device path is null. If it is not null change the settings
+ // of the device to match those on the device path
+ //
+ if (RemainingDevicePath != NULL) {
+ CopyMem (
+ &UsbSerialDevice->UartDevicePath,
+ RemainingDevicePath,
+ sizeof (UART_DEVICE_PATH)
+ );
+ FlowControl = (UART_FLOW_CONTROL_DEVICE_PATH *) NextDevicePathNode (RemainingDevicePath);
+ if (IsUartFlowControlNode (FlowControl)) {
+ UsbSerialDevice->FlowControlDevicePath.FlowControlMap = ReadUnaligned32 (&FlowControl->FlowControlMap);
+ } else {
+ FlowControl = NULL;
+ }
+ }
+
+ //
+ // Build the device path by appending the UART node to the parent device path
+ //
+ UsbSerialDevice->DevicePath = AppendDevicePathNode (
+ ParentDevicePath,
+ (EFI_DEVICE_PATH_PROTOCOL *) &UsbSerialDevice->UartDevicePath
+ );
+ //
+ // Continue building the device path by appending the flow control node
+ //
+ TempDevicePath = UsbSerialDevice->DevicePath;
+ UsbSerialDevice->DevicePath = AppendDevicePathNode (
+ TempDevicePath,
+ (EFI_DEVICE_PATH_PROTOCOL *) &UsbSerialDevice->FlowControlDevicePath
+ );
+ FreePool (TempDevicePath);
+
+ if (UsbSerialDevice->DevicePath == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto ErrorExit;
+ }
+
+ //
+ // Install protocol interfaces for the device
+ //
+ Status = gBS->InstallMultipleProtocolInterfaces (
+ &UsbSerialDevice->ControllerHandle,
+ &gEfiDevicePathProtocolGuid,
+ UsbSerialDevice->DevicePath,
+ &gEfiSerialIoProtocolGuid,
+ &UsbSerialDevice->SerialIo,
+ NULL
+ );
+ if (EFI_ERROR (Status)){
+ goto ErrorExit;
+ }
+
+ //
+ // Open for child device
+ //
+ Status = gBS->OpenProtocol (
+ Controller,
+ &gEfiUsbIoProtocolGuid,
+ (VOID **) &UsbIo,
+ This->DriverBindingHandle,
+ UsbSerialDevice->ControllerHandle,
+ EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
+ );
+
+ UsbSerialDevice->Shutdown = FALSE;
+
+ return EFI_SUCCESS;
+
+ErrorExit:
+ //
+ // Error handler
+ //
+
+ Status = gBS->UninstallMultipleProtocolInterfaces (
+ Controller,
+ &gEfiSerialIoProtocolGuid,
+ &UsbSerialDevice->SerialIo,
+ NULL
+ );
+ if (EFI_ERROR (Status)) {
+ goto ErrorExit1;
+ }
+
+ FreePool (UsbSerialDevice->DataBuffer);
+ FreePool (UsbSerialDevice);
+
+ UsbSerialDevice = NULL;
+ gBS->CloseProtocol (
+ Controller,
+ &gEfiUsbIoProtocolGuid,
+ This->DriverBindingHandle,
+ Controller
+ );
+
+ErrorExit1:
+ return Status;
+}
+
+/**
+ Stop the USB Serial device handled by this driver.
+
+ @param This[in] The USB Serial driver binding protocol.
+ @param Controller[in] The controller to release.
+ @param NumberOfChildren[in] The number of handles in ChildHandleBuffer.
+ @param ChildHandleBuffer[in] The array of child handle.
+
+ @retval EFI_SUCCESS The device was stopped.
+ @retval EFI_UNSUPPORTED Serial IO Protocol is not installed on
+ Controller.
+ @retval EFI_DEVICE_ERROR The device could not be stopped due to a
+ device error.
+ @retval Others Fail to uninstall protocols attached on the
+ device.
+
+**/
+EFI_STATUS
+EFIAPI
+UsbSerialDriverBindingStop (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Controller,
+ IN UINTN NumberOfChildren,
+ IN EFI_HANDLE *ChildHandleBuffer
+ )
+{
+ EFI_STATUS Status;
+ EFI_SERIAL_IO_PROTOCOL *SerialIo;
+ EFI_USB_IO_PROTOCOL *UsbIo;
+ USB_SER_DEV *UsbSerialDevice;
+ UINTN Index;
+ BOOLEAN AllChildrenStopped;
+
+ Status = EFI_SUCCESS;
+ UsbSerialDevice = NULL;
+
+ if (NumberOfChildren == 0) {
+ //
+ // Close the driver
+ //
+ Status = gBS->CloseProtocol (
+ Controller,
+ &gEfiUsbIoProtocolGuid,
+ This->DriverBindingHandle,
+ Controller
+ );
+ Status = gBS->CloseProtocol (
+ Controller,
+ &gEfiDevicePathProtocolGuid,
+ This->DriverBindingHandle,
+ Controller
+ );
+ return Status;
+ }
+
+ AllChildrenStopped = TRUE;
+
+ for (Index = 0; Index < NumberOfChildren ;Index++) {
+ Status = gBS->OpenProtocol (
+ ChildHandleBuffer[Index],
+ &gEfiSerialIoProtocolGuid,
+ (VOID **) &SerialIo,
+ This->DriverBindingHandle,
+ Controller,
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL
+ );
+ if (Status == EFI_SUCCESS) {//!EFI_ERROR (Status)) {
+ UsbSerialDevice = USB_SER_DEV_FROM_THIS (SerialIo);
+ Status = gBS->CloseProtocol (
+ Controller,
+ &gEfiUsbIoProtocolGuid,
+ This->DriverBindingHandle,
+ ChildHandleBuffer[Index]
+ );
+ Status = gBS->UninstallMultipleProtocolInterfaces (
+ ChildHandleBuffer[Index],
+ &gEfiDevicePathProtocolGuid,
+ UsbSerialDevice->DevicePath,
+ &gEfiSerialIoProtocolGuid,
+ &UsbSerialDevice->SerialIo,
+ NULL
+ );
+
+ if (EFI_ERROR (Status)) {
+ gBS->OpenProtocol (
+ Controller,
+ &gEfiUsbIoProtocolGuid,
+ (VOID **) &UsbIo,
+ This->DriverBindingHandle,
+ ChildHandleBuffer[Index],
+ EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
+ );
+ } else {
+ if (UsbSerialDevice->DevicePath != NULL) {
+ gBS->FreePool (UsbSerialDevice->DevicePath);
+ }
+ gBS->SetTimer (
+ UsbSerialDevice->PollingLoop,
+ TimerCancel,
+ 0
+ );
+ gBS->CloseEvent (UsbSerialDevice->PollingLoop);
+ UsbSerialDevice->Shutdown = TRUE;
+ FreeUnicodeStringTable (UsbSerialDevice->ControllerNameTable);
+ FreePool (UsbSerialDevice->DataBuffer);
+ FreePool (UsbSerialDevice);
+ }
+ }
+ if (EFI_ERROR (Status)) {
+ AllChildrenStopped = FALSE;
+ }
+ }
+
+ if (!AllChildrenStopped) {
+ return EFI_DEVICE_ERROR;
+ }
+ return EFI_SUCCESS;
+}
+
+//
+// Serial IO Member Functions
+//
+
+/**
+ Reset the serial device.
+
+ @param This[in] Protocol instance pointer.
+
+ @retval EFI_SUCCESS The device was reset.
+ @retval EFI_DEVICE_ERROR The serial device could not be reset.
+
+**/
+EFI_STATUS
+EFIAPI
+SerialReset (
+ IN EFI_SERIAL_IO_PROTOCOL *This
+ )
+{
+ EFI_STATUS Status;
+ USB_SER_DEV *UsbSerialDevice;
+
+ UsbSerialDevice = USB_SER_DEV_FROM_THIS (This);
+ Status = ResetInternal (UsbSerialDevice);
+ if (EFI_ERROR (Status)){
+ return EFI_DEVICE_ERROR;
+ }
+ return Status;
+}
+
+/**
+ Set the control bits on a serial device.
+
+ @param This[in] Protocol instance pointer.
+ @param Control[in] Set the bits of Control that are settable.
+
+ @retval EFI_SUCCESS The new control bits were set on the serial device.
+ @retval EFI_UNSUPPORTED The serial device does not support this operation.
+ @retval EFI_DEVICE_ERROR The serial device is not functioning correctly.
+
+**/
+EFI_STATUS
+EFIAPI
+SetControlBits (
+ IN EFI_SERIAL_IO_PROTOCOL *This,
+ IN UINT32 Control
+ )
+{
+ EFI_STATUS Status;
+ USB_SER_DEV *UsbSerialDevice;
+ CONTROL_BITS ControlBits;
+
+ UsbSerialDevice = USB_SER_DEV_FROM_THIS (This);
+
+ //
+ // check for invalid control parameters
+ //
+ if ((Control & (~(EFI_SERIAL_REQUEST_TO_SEND |
+ EFI_SERIAL_DATA_TERMINAL_READY |
+ EFI_SERIAL_HARDWARE_LOOPBACK_ENABLE |
+ EFI_SERIAL_SOFTWARE_LOOPBACK_ENABLE |
+ EFI_SERIAL_HARDWARE_FLOW_CONTROL_ENABLE))) != 0 ) {
+ return EFI_UNSUPPORTED;
+ }
+
+ //
+ // check the control parameters and set the correct setting for
+ // the paramerts of ControlBits
+ // both loopback enables are always set to FALSE
+ //
+ ControlBits.HardwareLoopBack = FALSE;
+ ControlBits.SoftwareLoopBack = FALSE;
+ //
+ // check for hardware flow control
+ //
+ if ((Control & EFI_SERIAL_HARDWARE_FLOW_CONTROL_ENABLE) == EFI_SERIAL_HARDWARE_FLOW_CONTROL_ENABLE) {
+ ControlBits.HardwareFlowControl = TRUE;
+ } else {
+ ControlBits.HardwareFlowControl = FALSE;
+ }
+ //
+ // check for DTR enabled
+ //
+ if ((Control & EFI_SERIAL_DATA_TERMINAL_READY) == EFI_SERIAL_DATA_TERMINAL_READY) {
+ ControlBits.DtrState = TRUE;
+ } else {
+ ControlBits.DtrState = FALSE;
+ }
+ //
+ // check for RTS enabled
+ //
+ if ((Control & EFI_SERIAL_REQUEST_TO_SEND) == EFI_SERIAL_REQUEST_TO_SEND) {
+ ControlBits.RtsState = TRUE;
+ } else {
+ ControlBits.RtsState = FALSE;
+ }
+
+ //
+ // set the control values with a call to SetControlBitsInternal()
+ //
+ Status = SetControlBitsInternal (UsbSerialDevice, &ControlBits);
+
+ return Status;
+}
+
+/**
+ calls SetAttributesInternal() to set the baud rate, receive FIFO depth,
+ transmit/receive time out, parity, data buts, and stop bits on a serial
+ device.
+
+ @param This[in] Protocol instance pointer.
+ @param BaudRate[in] The requested baud rate. A BaudRate value of 0
+ will use the device's default interface speed.
+ @param ReveiveFifoDepth[in] The requested depth of the FIFO on the receive
+ side of the serial interface. A ReceiveFifoDepth
+ value of 0 will use the device's default FIFO
+ depth.
+ @param Timeout[in] The requested time out for a single character in
+ microseconds.This timeout applies to both the
+ transmit and receive side of the interface. A
+ Timeout value of 0 will use the device's default
+ time out value.
+ @param Parity[in] The type of parity to use on this serial device.
+ A Parity value of DefaultParity will use the
+ device's default parity value.
+ @param DataBits[in] The number of data bits to use on the serial
+ device. A DataBit vaule of 0 will use the
+ device's default data bit setting.
+ @param StopBits[in] The number of stop bits to use on this serial
+ device. A StopBits value of DefaultStopBits will
+ use the device's default number of stop bits.
+
+ @retval EFI_SUCCESS The attributes were set
+ @retval EFI_DEVICE_ERROR The attributes were not able to be
+
+**/
+EFI_STATUS
+EFIAPI
+SetAttributes (
+ IN EFI_SERIAL_IO_PROTOCOL *This,
+ IN UINT64 BaudRate,
+ IN UINT32 ReceiveFifoDepth,
+ IN UINT32 Timeout,
+ IN EFI_PARITY_TYPE Parity,
+ IN UINT8 DataBits,
+ IN EFI_STOP_BITS_TYPE StopBits
+ )
+{
+
+ EFI_STATUS Status;
+ USB_SER_DEV *UsbSerialDevice;
+
+ UsbSerialDevice = USB_SER_DEV_FROM_THIS (This);
+
+ Status = SetAttributesInternal (
+ UsbSerialDevice,
+ BaudRate,
+ ReceiveFifoDepth,
+ Timeout,
+ Parity,
+ DataBits,
+ StopBits
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ return Status;
+}
+
+
+/**
+ Retrieves the status of the control bits on a serial device.
+
+ @param This[in] Protocol instance pointer.
+ @param Control[out] A pointer to return the current Control signals
+ from the serial device.
+
+ @retval EFI_SUCCESS The control bits were read from the serial
+ device.
+ @retval EFI_DEVICE_ERROR The serial device is not functioning correctly.
+
+**/
+EFI_STATUS
+EFIAPI
+GetControlBits (
+ IN EFI_SERIAL_IO_PROTOCOL *This,
+ OUT UINT32 *Control
+ )
+{
+ USB_SER_DEV *UsbSerialDevice;
+ EFI_STATUS Status;
+
+ UsbSerialDevice = USB_SER_DEV_FROM_THIS (This);
+
+ *Control = 0;
+
+ Status = GetControlBitsInternal (UsbSerialDevice, Control);
+
+ if (EFI_ERROR (Status)) {
+ return EFI_DEVICE_ERROR;
+ }
+ return Status;
+}
+
+/**
+ Reads data from a serial device.
+
+ @param This[in] Protocol instance pointer.
+ @param BufferSize[in, out] On input, the size of the Buffer. On output,
+ the amount of data returned in Buffer.
+ @param Buffer[out] The buffer to return the data into.
+
+ @retval EFI_SUCCESS The data was read.
+ @retval EFI_DEVICE_ERROR The device reported an error.
+ @retval EFI_TIMEOUT The data write was stopped due to a timeout.
+
+**/
+EFI_STATUS
+EFIAPI
+ReadSerialIo (
+ IN EFI_SERIAL_IO_PROTOCOL *This,
+ IN OUT UINTN *BufferSize,
+ OUT VOID *Buffer
+ )
+{
+ UINTN Index;
+ UINTN RemainingCallerBufferSize;
+ USB_SER_DEV *UsbSerialDevice;
+ EFI_STATUS Status;
+
+
+ if (*BufferSize == 0) {
+ return EFI_SUCCESS;
+ }
+
+ if (Buffer == NULL) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ Status = EFI_SUCCESS;
+ UsbSerialDevice = USB_SER_DEV_FROM_THIS (This);
+
+ //
+ // Clear out any data that we already have in our internal buffer
+ //
+ for (Index = 0; Index < *BufferSize; Index++) {
+ if (UsbSerialDevice->DataBufferHead == UsbSerialDevice->DataBufferTail) {
+ break;
+ }
+
+ //
+ // Still have characters in the buffer to return
+ //
+ ((UINT8 *)Buffer)[Index] = UsbSerialDevice->DataBuffer[UsbSerialDevice->DataBufferHead];
+ UsbSerialDevice->DataBufferHead = (UsbSerialDevice->DataBufferHead + 1) % SW_FIFO_DEPTH;
+ }
+
+ //
+ // If we haven't filled the caller's buffer using data that we already had on
+ // hand We need to generate an additional USB request to try and fill the
+ // caller's buffer
+ //
+ if (Index != *BufferSize) {
+ RemainingCallerBufferSize = *BufferSize - Index;
+ Status = ReadDataFromUsb (
+ UsbSerialDevice,
+ &RemainingCallerBufferSize,
+ (VOID *)(((CHAR8 *)Buffer) + Index)
+ );
+ if (!EFI_ERROR (Status)) {
+ *BufferSize = RemainingCallerBufferSize + Index;
+ } else {
+ *BufferSize = Index;
+ }
+ }
+
+ if (UsbSerialDevice->DataBufferHead == UsbSerialDevice->DataBufferTail) {
+ //
+ // Data buffer has no data, set the EFI_SERIAL_INPUT_BUFFER_EMPTY flag
+ //
+ UsbSerialDevice->ControlBits |= EFI_SERIAL_INPUT_BUFFER_EMPTY;
+ } else {
+ //
+ // There is some leftover data, clear EFI_SERIAL_INPUT_BUFFER_EMPTY flag
+ //
+ UsbSerialDevice->ControlBits &= ~(EFI_SERIAL_INPUT_BUFFER_EMPTY);
+ }
+ return Status;
+}
+
+/**
+ Writes data to a serial device.
+
+ @param This[in] Protocol instance pointer.
+ @param BufferSize[in, out] On input, the size of the Buffer. On output,
+ the amount of data actually written.
+ @param Buffer[in] The buffer of data to write
+
+ @retval EFI_SUCCESS The data was written.
+ @retval EFI_DEVICE_ERROR The device reported an error.
+ @retval EFI_TIMEOUT The data write was stopped due to a timeout.
+
+**/
+EFI_STATUS
+EFIAPI
+WriteSerialIo (
+ IN EFI_SERIAL_IO_PROTOCOL *This,
+ IN OUT UINTN *BufferSize,
+ IN VOID *Buffer
+ )
+{
+ EFI_STATUS Status;
+ USB_SER_DEV *UsbSerialDevice;
+ EFI_TPL Tpl;
+
+ UsbSerialDevice = USB_SER_DEV_FROM_THIS (This);
+
+ if (UsbSerialDevice->Shutdown) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ Tpl = gBS->RaiseTPL (TPL_NOTIFY);
+
+ Status = UsbSerialDataTransfer (
+ UsbSerialDevice,
+ EfiUsbDataOut,
+ Buffer,
+ BufferSize,
+ FTDI_TIMEOUT
+ );
+
+ gBS->RestoreTPL (Tpl);
+ if (EFI_ERROR (Status)) {
+ if (Status == EFI_TIMEOUT){
+ return Status;
+ } else {
+ return EFI_DEVICE_ERROR;
+ }
+ }
+
+ return EFI_SUCCESS;
+}
diff --git a/OptionRomPkg/Bus/Usb/FtdiUsbSerialDxe/FtdiUsbSerialDriver.h b/OptionRomPkg/Bus/Usb/FtdiUsbSerialDxe/FtdiUsbSerialDriver.h
new file mode 100644
index 000000000..07f4133cc
--- /dev/null
+++ b/OptionRomPkg/Bus/Usb/FtdiUsbSerialDxe/FtdiUsbSerialDriver.h
@@ -0,0 +1,595 @@
+/** @file
+ Header file for USB Serial Driver's Data Structures.
+
+Copyright (c) 2004 - 2013, Intel Corporation. All rights reserved.
+Portions Copyright 2012 Ashley DeSimone
+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 _FTDI_USB_SERIAL_DRIVER_H_
+#define _FTDI_USB_SERIAL_DRIVER_H_
+
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiLib.h>
+#include <Library/DevicePathLib.h>
+
+#include <Protocol/DevicePath.h>
+#include <Protocol/UsbIo.h>
+#include <Protocol/SerialIo.h>
+
+//
+// US English LangID
+//
+#define USB_US_LANG_ID 0x0409
+
+//
+// Supported Vendor Ids
+//
+#define VID_FTDI 0x0403
+
+//
+// Supported product ids
+//
+#define DID_FTDI_FT232 0x6001
+
+//
+// FTDI Commands
+//
+#define FTDI_COMMAND_RESET_PORT 0
+#define FTDI_COMMAND_MODEM_CTRL 1
+#define FTDI_COMMAND_SET_FLOW_CTRL 2
+#define FTDI_COMMAND_SET_BAUDRATE 3
+#define FTDI_COMMAND_SET_DATA 4
+#define FTDI_COMMAND_GET_MODEM_STATUS 5
+#define FTDI_COMMAND_SET_EVENT_CHAR 6
+#define FTDI_COMMAND_SET_ERROR_CHAR 7
+#define FTDI_COMMAND_SET_LATENCY_TIMER 9
+#define FTDI_COMMAND_GET_LATENCY_TIMER 10
+
+//
+// FTDI_PORT_IDENTIFIER
+// Used in the usb control transfers that issue FTDI commands as the index value.
+//
+#define FTDI_PORT_IDENTIFIER 0x1 // For FTDI USB serial adapter the port
+ // identifier is always 1.
+
+//
+// RESET_PORT
+//
+#define RESET_PORT_RESET 0x0 // Purges RX and TX, clears DTR and RTS sets
+ // flow control to none, disables event
+ // trigger, sets the event char to 0x0d and
+ // does nothing to baudrate or data settings
+#define RESET_PORT_PURGE_RX 0x1
+#define RESET_PORT_PURGE_TX 0x2
+
+//
+// SET_FLOW_CONTROL
+//
+#define NO_FLOW_CTRL 0x0
+#define XON_XOFF_CTRL 0x4
+
+//
+// SET_BAUD_RATE
+// To set baud rate, one must calculate an encoding of the baud rate from
+// UINT32 to UINT16.See EncodeBaudRateForFtdi() for details
+//
+#define FTDI_UART_FREQUENCY 3000000
+#define FTDI_MIN_DIVISOR 0x20
+#define FTDI_MAX_DIVISOR 0x3FFF8
+//
+// Special case baudrate values
+// 300,000 and 200,000 are special cases for calculating the encoded baudrate
+//
+#define FTDI_SPECIAL_CASE_300_MIN (3000000 * 100) / 103 // minimum adjusted
+ // value for 300,000
+#define FTDI_SPECIAL_CASE_300_MAX (3000000 * 100) / 97 // maximum adjusted
+ // value for 300,000
+#define FTDI_SPECIAL_CASE_200_MIN (2000000 * 100) / 103 // minimum adjusted
+ // value for 200,000
+#define FTDI_SPECIAL_CASE_200_MAX (2000000 * 100) / 97 // maximum adjusted
+ // value for 200,000
+//
+// Min and max frequency values that the FTDI chip can attain
+//.all generated frequencies must be between these values
+//
+#define FTDI_MIN_FREQUENCY 46601941 // (3MHz * 1600) / 103 = 46601941
+#define FTDI_MAX_FREQUENCY 49484536 // (3MHz * 1600) / 97 = 49484536
+
+//
+// SET_DATA_BITS
+//
+#define SET_DATA_BITS(n) (n)
+
+//
+// SET_PARITY
+//
+#define SET_PARITY_NONE 0x0
+#define SET_PARITY_ODD BIT8 // (0x1 << 8)
+#define SET_PARITY_EVEN BIT9 // (0x2 << 8)
+#define SET_PARITY_MARK BIT9 | BIT8 // (0x3 << 8)
+#define SET_PARITY_SPACE BIT10 // (0x4 << 8)
+
+//
+// SET_STOP_BITS
+//
+#define SET_STOP_BITS_1 0x0
+#define SET_STOP_BITS_15 BIT11 // (0x1 << 11)
+#define SET_STOP_BITS_2 BIT12 // (0x2 << 11)
+
+//
+// SET_MODEM_CTRL
+// SET_DTR_HIGH = (1 | (1 << 8)), SET_DTR_LOW = (0 | (1 << 8)
+// SET_RTS_HIGH = (2 | (2 << 8)), SET_RTS_LOW = (0 | (2 << 8)
+//
+#define SET_DTR_HIGH (BIT8 | BIT0)
+#define SET_DTR_LOW (BIT8)
+#define SET_RTS_HIGH (BIT9 | BIT1)
+#define SET_RTS_LOW (BIT9)
+
+//
+// MODEM_STATUS
+//
+#define CTS_MASK BIT4
+#define DSR_MASK BIT5
+#define RI_MASK BIT6
+#define SD_MASK BIT7
+#define MSR_MASK (CTS_MASK | DSR_MASK | RI_MASK | SD_MASK)
+
+//
+// Macro used to check for USB transfer errors
+//
+#define USB_IS_ERROR(Result, Error) (((Result) & (Error)) != 0)
+
+//
+// USB request timeouts
+//
+#define WDR_TIMEOUT 5000 // default urb timeout in ms
+#define WDR_SHORT_TIMEOUT 1000 // shorter urb timeout in ms
+
+//
+// FTDI timeout
+//
+#define FTDI_TIMEOUT 16
+
+//
+// FTDI FIFO depth
+//
+#define FTDI_MAX_RECEIVE_FIFO_DEPTH 384
+
+//
+// FTDI Endpoint Descriptors
+//
+#define FTDI_ENDPOINT_ADDRESS_IN 0x81 //the endpoint address for the in enpoint generated by the device
+#define FTDI_ENDPOINT_ADDRESS_OUT 0x02 //the endpoint address for the out endpoint generated by the device
+
+//
+// Max buffer size for USB transfers
+//
+#define SW_FIFO_DEPTH 1024
+
+//
+// struct to define a usb device as a vendor and product id pair
+//
+typedef struct {
+ UINTN VendorId;
+ UINTN DeviceId;
+} USB_DEVICE;
+
+//
+//struct to describe the control bits of the device
+//true indicates enabled
+//false indicates disabled
+//
+typedef struct {
+ BOOLEAN HardwareFlowControl;
+ BOOLEAN DtrState;
+ BOOLEAN RtsState;
+ BOOLEAN HardwareLoopBack;
+ BOOLEAN SoftwareLoopBack;
+} CONTROL_BITS;
+
+//
+//struct to describe the status bits of the device
+//true indicates enabled
+//false indicated disabled
+//
+typedef struct {
+ BOOLEAN CtsState;
+ BOOLEAN DsrState;
+ BOOLEAN RiState;
+ BOOLEAN SdState;
+} STATUS_BITS;
+
+//
+// Structure to describe the last attributes of the Usb Serial device
+//
+typedef struct {
+ UINT64 BaudRate;
+ UINT32 ReceiveFifoDepth;
+ UINT32 Timeout;
+ EFI_PARITY_TYPE Parity;
+ UINT8 DataBits;
+ EFI_STOP_BITS_TYPE StopBits;
+} PREVIOUS_ATTRIBUTES;
+
+//
+// Structure to describe USB serial device
+//
+#define USB_SER_DEV_SIGNATURE SIGNATURE_32 ('u', 's', 'b', 's')
+
+typedef struct {
+ UINTN Signature;
+ EFI_HANDLE ControllerHandle;
+ EFI_DEVICE_PATH_PROTOCOL *DevicePath;
+ EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath;
+ UART_DEVICE_PATH UartDevicePath;
+ UART_FLOW_CONTROL_DEVICE_PATH FlowControlDevicePath;
+ EFI_USB_IO_PROTOCOL *UsbIo;
+ EFI_USB_INTERFACE_DESCRIPTOR InterfaceDescriptor;
+ EFI_USB_ENDPOINT_DESCRIPTOR InEndpointDescriptor;
+ EFI_USB_ENDPOINT_DESCRIPTOR OutEndpointDescriptor;
+ EFI_UNICODE_STRING_TABLE *ControllerNameTable;
+ UINT32 DataBufferHead;
+ UINT32 DataBufferTail;
+ UINT8 *DataBuffer;
+ EFI_SERIAL_IO_PROTOCOL SerialIo;
+ BOOLEAN Shutdown;
+ EFI_EVENT PollingLoop;
+ UINT32 ControlBits;
+ PREVIOUS_ATTRIBUTES LastSettings;
+ CONTROL_BITS ControlValues;
+ STATUS_BITS StatusValues;
+ UINT8 ReadBuffer[512];
+} USB_SER_DEV;
+
+#define USB_SER_DEV_FROM_THIS(a) \
+ CR(a, USB_SER_DEV, SerialIo, USB_SER_DEV_SIGNATURE)
+
+//
+// Global Variables
+//
+extern EFI_DRIVER_BINDING_PROTOCOL gUsbSerialDriverBinding;
+extern EFI_COMPONENT_NAME_PROTOCOL gUsbSerialComponentName;
+extern EFI_COMPONENT_NAME2_PROTOCOL gUsbSerialComponentName2;
+
+//
+// Functions of Driver Binding Protocol
+//
+/**
+ Check whether USB Serial driver supports this device.
+
+ @param This[in] The USB Serial driver binding protocol.
+ @param Controller[in] The controller handle to check.
+ @param RemainingDevicePath[in] The remaining device path.
+
+ @retval EFI_SUCCESS The driver supports this controller.
+ @retval other This device isn't supported.
+
+**/
+EFI_STATUS
+EFIAPI
+UsbSerialDriverBindingSupported (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Controller,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
+ );
+
+/**
+ Starts the Serial device with this driver.
+
+ This function produces Serial IO Protocol and initializes the USB
+ Serial device to manage this USB Serial device.
+
+ @param This[in] The USB Serial driver binding instance.
+ @param Controller[in] Handle of device to bind driver to.
+ @param RemainingDevicePath[in] Optional parameter use to pick a specific
+ child device to start.
+
+ @retval EFI_SUCCESS The controller is controlled by the USB
+ Serial driver.
+ @retval EFI_UNSUPPORTED No interrupt endpoint can be found.
+ @retval Other This controller cannot be started.
+
+**/
+EFI_STATUS
+EFIAPI
+UsbSerialDriverBindingStart (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Controller,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
+ );
+
+/**
+ Stop the USB Serial device handled by this driver.
+
+ @param This[in] The USB Serial driver binding protocol.
+ @param Controller[in] The controller to release.
+ @param NumberOfChildren[in] The number of handles in ChildHandleBuffer.
+ @param ChildHandleBuffer[in] The array of child handle.
+
+ @retval EFI_SUCCESS The device was stopped.
+ @retval EFI_UNSUPPORTED Simple Text In Protocol or Simple Text In Ex
+ Protocol is not installed on Controller.
+ @retval EFI_DEVICE_ERROR The device could not be stopped due to a
+ device error.
+ @retval Others Fail to uninstall protocols attached on the
+ device.
+
+**/
+EFI_STATUS
+EFIAPI
+UsbSerialDriverBindingStop (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Controller,
+ IN UINTN NumberOfChildren,
+ IN EFI_HANDLE *ChildHandleBuffer
+ );
+
+//
+// Serial IO Member Functions
+//
+
+/**
+ Writes data to a serial device.
+
+ @param This[in] Protocol instance pointer.
+ @param BufferSize[in, out] On input, the size of the Buffer. On output,
+ the amount of data actually written.
+ @param Buffer[in] The buffer of data to write
+
+ @retval EFI_SUCCESS The data was written.
+ @retval EFI_DEVICE_ERROR The device reported an error.
+ @retval EFI_TIMEOUT The data write was stopped due to a timeout.
+
+**/
+EFI_STATUS
+EFIAPI
+WriteSerialIo (
+ IN EFI_SERIAL_IO_PROTOCOL *This,
+ IN OUT UINTN *BufferSize,
+ IN VOID *Buffer
+ );
+
+/**
+ Reads data from a serial device.
+
+ @param This[in] Protocol instance pointer.
+ @param BufferSize[in, out] On input, the size of the Buffer. On output,
+ the amount of data returned in Buffer.
+ @param Buffer[out] The buffer to return the data into.
+
+ @retval EFI_SUCCESS The data was read.
+ @retval EFI_DEVICE_ERROR The device reported an error.
+ @retval EFI_TIMEOUT The data write was stopped due to a timeout.
+
+**/
+EFI_STATUS
+EFIAPI
+ReadSerialIo (
+ IN EFI_SERIAL_IO_PROTOCOL *This,
+ IN OUT UINTN *BufferSize,
+ OUT VOID *Buffer
+ );
+
+/**
+ Retrieves the status of the control bits on a serial device.
+
+ @param This[in] Protocol instance pointer.
+ @param Control[out] A pointer to return the current Control signals
+ from the serial device.
+
+ @retval EFI_SUCCESS The control bits were read from the serial
+ device.
+ @retval EFI_DEVICE_ERROR The serial device is not functioning correctly.
+
+**/
+EFI_STATUS
+EFIAPI
+GetControlBits (
+ IN EFI_SERIAL_IO_PROTOCOL *This,
+ OUT UINT32 *Control
+ );
+
+/**
+ Set the control bits on a serial device.
+
+ @param This[in] Protocol instance pointer.
+ @param Control[in] Set the bits of Control that are settable.
+
+ @retval EFI_SUCCESS The new control bits were set on the serial device.
+ @retval EFI_UNSUPPORTED The serial device does not support this operation.
+ @retval EFI_DEVICE_ERROR The serial device is not functioning correctly.
+
+**/
+EFI_STATUS
+EFIAPI
+SetControlBits (
+ IN EFI_SERIAL_IO_PROTOCOL *This,
+ IN UINT32 Control
+ );
+
+/**
+ Calls SetAttributesInternal() to set the baud rate, receive FIFO depth,
+ transmit/receice time out, parity, data buts, and stop bits on a serial device.
+
+ @param This[in] Protocol instance pointer.
+ @param BaudRate[in] The requested baud rate. A BaudRate value of 0
+ will use the device's default interface speed.
+ @param ReveiveFifoDepth[in] The requested depth of the FIFO on the receive
+ side of the serial interface. A ReceiveFifoDepth
+ value of 0 will use the device's default FIFO
+ depth.
+ @param Timeout[in] The requested time out for a single character in
+ microseconds.This timeout applies to both the
+ transmit and receive side of the interface.A
+ Timeout value of 0 will use the device's default
+ time out value.
+ @param Parity[in] The type of parity to use on this serial device.A
+ Parity value of DefaultParity will use the
+ device's default parity value.
+ @param DataBits[in] The number of data bits to use on the serial
+ device. A DataBits value of 0 will use the
+ device's default data bit setting.
+ @param StopBits[in] The number of stop bits to use on this serial
+ device. A StopBits value of DefaultStopBits will
+ use the device's default number of stop bits.
+
+ @retval EFI_SUCCESS The attributes were set
+ @retval EFI_DEVICE_ERROR The attributes were not able to be
+
+**/
+EFI_STATUS
+EFIAPI
+SetAttributes (
+ IN EFI_SERIAL_IO_PROTOCOL *This,
+ IN UINT64 BaudRate,
+ IN UINT32 ReceiveFifoDepth,
+ IN UINT32 Timeout,
+ IN EFI_PARITY_TYPE Parity,
+ IN UINT8 DataBits,
+ IN EFI_STOP_BITS_TYPE StopBits
+ );
+
+/**
+ Reset the serial device.
+
+ @param This Protocol instance pointer.
+
+ @retval EFI_SUCCESS The device was reset.
+ @retval EFI_DEVICE_ERROR The serial device could not be reset.
+
+**/
+EFI_STATUS
+EFIAPI
+SerialReset (
+ IN EFI_SERIAL_IO_PROTOCOL *This
+ );
+
+//
+// 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
+UsbSerialComponentNameGetDriverName (
+ IN EFI_COMPONENT_NAME2_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 not a valid EFI_HANDLE.
+ @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
+UsbSerialComponentNameGetControllerName (
+ IN EFI_COMPONENT_NAME2_PROTOCOL *This,
+ IN EFI_HANDLE ControllerHandle,
+ IN EFI_HANDLE ChildHandle OPTIONAL,
+ IN CHAR8 *Language,
+ OUT CHAR16 **ControllerName
+ );
+
+#endif
diff --git a/OptionRomPkg/Bus/Usb/FtdiUsbSerialDxe/FtdiUsbSerialDxe.inf b/OptionRomPkg/Bus/Usb/FtdiUsbSerialDxe/FtdiUsbSerialDxe.inf
new file mode 100644
index 000000000..e0381b1c4
--- /dev/null
+++ b/OptionRomPkg/Bus/Usb/FtdiUsbSerialDxe/FtdiUsbSerialDxe.inf
@@ -0,0 +1,61 @@
+## @file
+# USB Serial Driver that manages USB Serial device and produces Serial IO
+# Protocol.
+#
+# USB Serial Driver consumes USB I/O Protocol and Device Path Protocol, and
+# produces Serial IO Protocol on USB Serial devices.
+# It manages the USB Serial device via USB Bulk Transfer of USB I/O Protocol.
+# This module refers to following specifications:
+# 1. UEFI Specification, v2.1
+#
+# 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.
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = FtdiUsbSerialDxe
+ FILE_GUID = A8154B55-2021-4D40-AE81-2E23A02dCC46
+ MODULE_TYPE = UEFI_DRIVER
+ VERSION_STRING = 1.0
+ ENTRY_POINT = FtdiUsbSerialEntryPoint
+ UNLOAD_IMAGE = FtdiUsbSerialUnload
+
+#
+# VALID_ARCHITECTURES = IA32 X64 IPF EBC
+#
+
+[Sources]
+ FtdiUsbSerialDriver.c
+ FtdiUsbSerialDriver.h
+ ComponentName.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+
+[LibraryClasses]
+ UefiDriverEntryPoint
+ BaseMemoryLib
+ DebugLib
+ MemoryAllocationLib
+ UefiBootServicesTableLib
+ UefiLib
+ DevicePathLib
+
+[Guids]
+ gEfiUartDevicePathGuid
+
+[Protocols]
+ ## TO_START
+ ## BY_START
+ gEfiDevicePathProtocolGuid
+ gEfiUsbIoProtocolGuid ## TO_START
+ gEfiSerialIoProtocolGuid ## BY_START
diff --git a/OptionRomPkg/Bus/Usb/FtdiUsbSerialDxe/ReadMe.txt b/OptionRomPkg/Bus/Usb/FtdiUsbSerialDxe/ReadMe.txt
new file mode 100644
index 000000000..d8ca227a4
--- /dev/null
+++ b/OptionRomPkg/Bus/Usb/FtdiUsbSerialDxe/ReadMe.txt
@@ -0,0 +1,32 @@
+
+=== FTDI USB SERIAL OVERVIEW ===
+
+This is a bus driver that enables the EfiSerialIoProtocol interface
+for FTDI8U232AM based USB-to-Serial adapters.
+
+=== STATUS ===
+
+Serial Input: Functional on real hardware.
+Serial Output: Functional on real hardware.
+
+Operating Modes: Currently the user is able to change all operating modes
+except timeout and FIFO depth.
+The default operating mode is:
+ Baudrate: 115200
+ Parity: None
+ Flow Control: None
+ Data Bits: 8
+ Stop Bits: 1
+Notes:
+ Data Bits setting of 6,7,8 can not be combined with a Stop Bits setting of 1.5
+
+ At baudrates less than 9600 some of the characters may be transmitted incorrectly.
+
+=== COMPATIBILITY ===
+
+Tested with:
+An FTDI8U232AM based USB-To-Serial adapter, the UEFI Shell, and the SerialTest application
+using a PuTTY Terminal
+
+See CompatibleDevices.txt for a list of devices which have been confirmed to work with this
+driver. \ No newline at end of file
diff --git a/OptionRomPkg/OptionRomPkg.dsc b/OptionRomPkg/OptionRomPkg.dsc
index 4fdcf6d9b..03592f8a3 100644
--- a/OptionRomPkg/OptionRomPkg.dsc
+++ b/OptionRomPkg/OptionRomPkg.dsc
@@ -104,6 +104,7 @@
OptionRomPkg/AtapiPassThruDxe/AtapiPassThruDxe.inf
OptionRomPkg/CirrusLogic5430Dxe/CirrusLogic5430Dxe.inf
OptionRomPkg/UndiRuntimeDxe/UndiRuntimeDxe.inf
+ OptionRomPkg/Bus/Usb/FtdiUsbSerialDxe/FtdiUsbSerialDxe.inf
[Components.IA32, Components.X64, Components.IPF]
OptionRomPkg/Application/BltLibSample/BltLibSample.inf
diff --git a/OvmfPkg/AcpiPlatformDxe/AcpiPlatformDxe.inf b/OvmfPkg/AcpiPlatformDxe/AcpiPlatformDxe.inf
index acc224728..90178e0f5 100644
--- a/OvmfPkg/AcpiPlatformDxe/AcpiPlatformDxe.inf
+++ b/OvmfPkg/AcpiPlatformDxe/AcpiPlatformDxe.inf
@@ -62,6 +62,7 @@
gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiTableStorageFile
gUefiCpuPkgTokenSpaceGuid.PcdCpuLocalApicBaseAddress
gPcAtChipsetPkgTokenSpaceGuid.Pcd8259LegacyModeEdgeLevel
+ gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFdBaseAddress
[Depex]
gEfiAcpiTableProtocolGuid
diff --git a/OvmfPkg/AcpiPlatformDxe/Qemu.c b/OvmfPkg/AcpiPlatformDxe/Qemu.c
index 8a6ecf75b..06bd46370 100644
--- a/OvmfPkg/AcpiPlatformDxe/Qemu.c
+++ b/OvmfPkg/AcpiPlatformDxe/Qemu.c
@@ -250,7 +250,7 @@ PopulateFwData(
Desc = &AllDesc[CurDesc];
ExclTop = Desc->BaseAddress + Desc->Length;
- if (ExclTop <= BASE_4GB) {
+ if (ExclTop <= (UINT64) PcdGet32 (PcdOvmfFdBaseAddress)) {
switch (Desc->GcdMemoryType) {
case EfiGcdMemoryTypeNonExistent:
break;
diff --git a/OvmfPkg/EmuVariableFvbRuntimeDxe/Fvb.c b/OvmfPkg/EmuVariableFvbRuntimeDxe/Fvb.c
index c7c3fcb36..7a8beb335 100644
--- a/OvmfPkg/EmuVariableFvbRuntimeDxe/Fvb.c
+++ b/OvmfPkg/EmuVariableFvbRuntimeDxe/Fvb.c
@@ -819,6 +819,12 @@ FvbInitialize (
return EFI_INVALID_PARAMETER;
}
+ if (PcdGet64 (PcdFlashNvStorageVariableBase64) != 0) {
+ DEBUG ((EFI_D_INFO, "Disabling EMU Variable FVB since "
+ "flash variables appear to be supported.\n"));
+ return EFI_ABORTED;
+ }
+
//
// By default we will initialize the FV contents. But, if
// PcdEmuVariableNvStoreReserved is non-zero, then we will
diff --git a/OvmfPkg/Include/IndustryStandard/Virtio.h b/OvmfPkg/Include/IndustryStandard/Virtio.h
index 75c5a9c85..fcf7b6743 100644
--- a/OvmfPkg/Include/IndustryStandard/Virtio.h
+++ b/OvmfPkg/Include/IndustryStandard/Virtio.h
@@ -4,7 +4,7 @@
specification.
Copyright (C) 2012, Red Hat, Inc.
- Portion of Copyright (C) 2013, ARM Ltd.
+ Portion of Copyright (C) 2013, ARM Ltd.
This program and the accompanying materials are licensed and made available
under the terms and conditions of the BSD License which accompanies this
@@ -36,53 +36,54 @@
#define VIRTIO_SUBSYSTEM_MAC80211_WLAN 10
//
-// Virtio IDs
-//
-#define VIRTIO_VENDOR_ID 0x1AF4
-#define VIRTIO_MMIO_MAGIC 0x74726976 // "virt"
-
-
-//
-// VirtIo Device Specific Configuration Offsets
-//
-#define VIRTIO_DEVICE_SPECIFIC_CONFIGURATION_OFFSET_PCI 20
-#define VIRTIO_DEVICE_SPECIFIC_CONFIGURATION_OFFSET_PCI_WITH_MSI_X 24
-#define VIRTIO_DEVICE_SPECIFIC_CONFIGURATION_OFFSET_MMIO 0x100
-
-// PCI VirtIo Header Offsets
-//
-#define VIRTIO_PCI_OFFSET_DEVICE_FEATURES 0x00
-#define VIRTIO_PCI_OFFSET_GUEST_FEATURES 0x04
-#define VIRTIO_PCI_OFFSET_QUEUE_ADDRESS 0x08
-#define VIRTIO_PCI_OFFSET_QUEUE_SIZE 0x0C
-#define VIRTIO_PCI_OFFSET_QUEUE_SELECT 0x0E
-#define VIRTIO_PCI_OFFSET_QUEUE_NOTIFY 0x10
-#define VIRTIO_PCI_OFFSET_QUEUE_DEVICE_STATUS 0x12
-#define VIRTIO_PCI_OFFSET_QUEUE_DEVICE_ISR 0x13
-
-//
-// MMIO VirtIo Header Offsets
-//
-#define VIRTIO_MMIO_OFFSET_MAGIC 0x00
-#define VIRTIO_MMIO_OFFSET_VERSION 0x04
-#define VIRTIO_MMIO_OFFSET_DEVICE_ID 0x08
-#define VIRTIO_MMIO_OFFSET_VENDOR_ID 0x0C
-#define VIRTIO_MMIO_OFFSET_HOST_FEATURES 0x10
-#define VIRTIO_MMIO_OFFSET_HOST_FEATURES_SEL 0x14
-#define VIRTIO_MMIO_OFFSET_GUEST_FEATURES 0x20
-#define VIRTIO_MMIO_OFFSET_GUEST_FEATURES_SEL 0x24
-#define VIRTIO_MMIO_OFFSET_GUEST_PAGE_SIZE 0x28
-#define VIRTIO_MMIO_OFFSET_QUEUE_SEL 0x30
-#define VIRTIO_MMIO_OFFSET_QUEUE_NUM_MAX 0x34
-#define VIRTIO_MMIO_OFFSET_QUEUE_NUM 0x38
-#define VIRTIO_MMIO_OFFSET_QUEUE_ALIGN 0x3C
-#define VIRTIO_MMIO_OFFSET_QUEUE_PFN 0x40
-#define VIRTIO_MMIO_OFFSET_QUEUE_NOTIFY 0x50
-#define VIRTIO_MMIO_OFFSET_INTERRUPT_STATUS 0x60
-#define VIRTIO_MMIO_OFFSET_INTERRUPT_ACK 0x64
-#define VIRTIO_MMIO_OFFSET_STATUS 0x70
-
-//
+// Virtio IDs
+//
+#define VIRTIO_VENDOR_ID 0x1AF4
+#define VIRTIO_MMIO_MAGIC 0x74726976 // "virt"
+
+
+//
+// VirtIo Device Specific Configuration Offsets
+//
+#define VIRTIO_DEVICE_SPECIFIC_CONFIGURATION_OFFSET_PCI 20
+#define VIRTIO_DEVICE_SPECIFIC_CONFIGURATION_OFFSET_PCI_WITH_MSI_X 24
+#define VIRTIO_DEVICE_SPECIFIC_CONFIGURATION_OFFSET_MMIO 0x100
+
+//
+// PCI VirtIo Header Offsets
+//
+#define VIRTIO_PCI_OFFSET_DEVICE_FEATURES 0x00
+#define VIRTIO_PCI_OFFSET_GUEST_FEATURES 0x04
+#define VIRTIO_PCI_OFFSET_QUEUE_ADDRESS 0x08
+#define VIRTIO_PCI_OFFSET_QUEUE_SIZE 0x0C
+#define VIRTIO_PCI_OFFSET_QUEUE_SELECT 0x0E
+#define VIRTIO_PCI_OFFSET_QUEUE_NOTIFY 0x10
+#define VIRTIO_PCI_OFFSET_QUEUE_DEVICE_STATUS 0x12
+#define VIRTIO_PCI_OFFSET_QUEUE_DEVICE_ISR 0x13
+
+//
+// MMIO VirtIo Header Offsets
+//
+#define VIRTIO_MMIO_OFFSET_MAGIC 0x00
+#define VIRTIO_MMIO_OFFSET_VERSION 0x04
+#define VIRTIO_MMIO_OFFSET_DEVICE_ID 0x08
+#define VIRTIO_MMIO_OFFSET_VENDOR_ID 0x0C
+#define VIRTIO_MMIO_OFFSET_HOST_FEATURES 0x10
+#define VIRTIO_MMIO_OFFSET_HOST_FEATURES_SEL 0x14
+#define VIRTIO_MMIO_OFFSET_GUEST_FEATURES 0x20
+#define VIRTIO_MMIO_OFFSET_GUEST_FEATURES_SEL 0x24
+#define VIRTIO_MMIO_OFFSET_GUEST_PAGE_SIZE 0x28
+#define VIRTIO_MMIO_OFFSET_QUEUE_SEL 0x30
+#define VIRTIO_MMIO_OFFSET_QUEUE_NUM_MAX 0x34
+#define VIRTIO_MMIO_OFFSET_QUEUE_NUM 0x38
+#define VIRTIO_MMIO_OFFSET_QUEUE_ALIGN 0x3C
+#define VIRTIO_MMIO_OFFSET_QUEUE_PFN 0x40
+#define VIRTIO_MMIO_OFFSET_QUEUE_NOTIFY 0x50
+#define VIRTIO_MMIO_OFFSET_INTERRUPT_STATUS 0x60
+#define VIRTIO_MMIO_OFFSET_INTERRUPT_ACK 0x64
+#define VIRTIO_MMIO_OFFSET_STATUS 0x70
+
+//
// Data in the communication area is defined as packed and accessed as
// volatile.
//
diff --git a/OvmfPkg/Library/PlatformBdsLib/BdsPlatform.c b/OvmfPkg/Library/PlatformBdsLib/BdsPlatform.c
index ba6af2cae..ab9c93eaf 100644
--- a/OvmfPkg/Library/PlatformBdsLib/BdsPlatform.c
+++ b/OvmfPkg/Library/PlatformBdsLib/BdsPlatform.c
@@ -1073,11 +1073,16 @@ Returns:
ConnectRootBridge ();
- //
- // Try to restore variables from the hard disk early so
- // they can be used for the other BDS connect operations.
- //
- PlatformBdsRestoreNvVarsFromHardDisk ();
+ 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 ();
+ }
//
// Init the time out value
diff --git a/OvmfPkg/Library/PlatformBdsLib/PlatformBdsLib.inf b/OvmfPkg/Library/PlatformBdsLib/PlatformBdsLib.inf
index 7f7f47379..a2b72bad3 100644
--- a/OvmfPkg/Library/PlatformBdsLib/PlatformBdsLib.inf
+++ b/OvmfPkg/Library/PlatformBdsLib/PlatformBdsLib.inf
@@ -57,6 +57,7 @@
gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdPlatformBootTimeOut
gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdLogoFile
gUefiOvmfPkgTokenSpaceGuid.PcdEmuVariableEvent
+ gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFlashVariablesEnable
[Pcd.IA32, Pcd.X64]
gEfiMdePkgTokenSpaceGuid.PcdFSBClock
diff --git a/OvmfPkg/OvmfPkg.dec b/OvmfPkg/OvmfPkg.dec
index 11c44534a..3d4e7bcd9 100644
--- a/OvmfPkg/OvmfPkg.dec
+++ b/OvmfPkg/OvmfPkg.dec
@@ -1,7 +1,7 @@
## @file
# EFI/Framework Open Virtual Machine Firmware (OVMF) platform
#
-# Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.<BR>
+# 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
@@ -69,8 +69,19 @@
gUefiOvmfPkgTokenSpaceGuid.PcdVirtioScsiMaxTargetLimit|31|UINT16|6
gUefiOvmfPkgTokenSpaceGuid.PcdVirtioScsiMaxLunLimit|7|UINT32|7
+[PcdsFixedAtBuild]
+ gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFlashNvStorageEventLogBase|0x0|UINT32|0x8
+ gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFlashNvStorageEventLogSize|0x0|UINT32|0x9
+ gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFirmwareFdSize|0x0|UINT32|0xa
+ gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFirmwareBlockSize|0|UINT32|0xb
+ gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFlashNvStorageVariableBase|0x0|UINT32|0xc
+ gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFlashNvStorageFtwSpareBase|0x0|UINT32|0xd
+ gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFlashNvStorageFtwWorkingBase|0x0|UINT32|0xe
+ gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFdBaseAddress|0x0|UINT32|0xf
+
[PcdsDynamic, PcdsDynamicEx]
gUefiOvmfPkgTokenSpaceGuid.PcdEmuVariableEvent|0|UINT64|2
+ gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFlashVariablesEnable|FALSE|BOOLEAN|0x10
[PcdsFeatureFlag]
gUefiOvmfPkgTokenSpaceGuid.PcdSecureBootEnable|FALSE|BOOLEAN|3
diff --git a/OvmfPkg/OvmfPkgIa32.dsc b/OvmfPkg/OvmfPkgIa32.dsc
index c57822bdd..860a73e96 100644
--- a/OvmfPkg/OvmfPkgIa32.dsc
+++ b/OvmfPkg/OvmfPkgIa32.dsc
@@ -113,7 +113,6 @@
ResetSystemLib|OvmfPkg/Library/ResetSystemLib/ResetSystemLib.inf
LocalApicLib|UefiCpuPkg/Library/BaseXApicLib/BaseXApicLib.inf
DebugPrintErrorLevelLib|MdePkg/Library/BaseDebugPrintErrorLevelLib/BaseDebugPrintErrorLevelLib.inf
- CpuExceptionHandlerLib|MdeModulePkg/Library/CpuExceptionHandlerLibNull/CpuExceptionHandlerLibNull.inf
!if $(SECURE_BOOT_ENABLE) == TRUE
PlatformSecureLib|OvmfPkg/Library/PlatformSecureLib/PlatformSecureLib.inf
@@ -142,6 +141,7 @@
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
@@ -195,6 +195,7 @@
!ifdef $(SOURCE_DEBUG_ENABLE)
DebugAgentLib|SourceLevelDebugPkg/Library/DebugAgent/DxeDebugAgentLib.inf
!endif
+ CpuExceptionHandlerLib|UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeCpuExceptionHandlerLib.inf
[LibraryClasses.common.DXE_RUNTIME_DRIVER]
HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf
@@ -241,6 +242,7 @@
UdpIoLib|MdeModulePkg/Library/DxeUdpIoLib/DxeUdpIoLib.inf
DpcLib|MdeModulePkg/Library/DxeDpcLib/DxeDpcLib.inf
PlatformBdsLib|OvmfPkg/Library/PlatformBdsLib/PlatformBdsLib.inf
+ CpuExceptionHandlerLib|UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeCpuExceptionHandlerLib.inf
[LibraryClasses.common.UEFI_APPLICATION]
HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf
@@ -279,10 +281,7 @@
gEfiMdeModulePkgTokenSpaceGuid.PcdMaxVariableSize|0x400
!endif
gEfiMdeModulePkgTokenSpaceGuid.PcdMaxHardwareErrorVariableSize|0x8000
- gEfiMdeModulePkgTokenSpaceGuid.PcdVariableStoreSize|0xc000
- gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize|0xc000
- gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingSize|0x2000
- gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize|0x10000
+ gEfiMdeModulePkgTokenSpaceGuid.PcdVariableStoreSize|0xe000
gEfiMdeModulePkgTokenSpaceGuid.PcdVpdBaseAddress|0x0
@@ -411,6 +410,7 @@
OvmfPkg/VirtioPciDeviceDxe/VirtioPciDeviceDxe.inf
OvmfPkg/VirtioBlkDxe/VirtioBlk.inf
OvmfPkg/VirtioScsiDxe/VirtioScsi.inf
+ OvmfPkg/QemuFlashFvbServicesRuntimeDxe/FvbServicesRuntimeDxe.inf
OvmfPkg/EmuVariableFvbRuntimeDxe/Fvb.inf {
<LibraryClasses>
PlatformFvbLib|OvmfPkg/Library/EmuVariableFvbLib/EmuVariableFvbLib.inf
diff --git a/OvmfPkg/OvmfPkgIa32.fdf b/OvmfPkg/OvmfPkgIa32.fdf
index b13cf0589..af3890c0e 100644
--- a/OvmfPkg/OvmfPkgIa32.fdf
+++ b/OvmfPkg/OvmfPkgIa32.fdf
@@ -14,28 +14,112 @@
##
################################################################################
+
+#
+# Default flash size for DEBUG build is 2MB. For RELEASE it is 1MB.
+#
+# Defining FD_SIZE_1MB or FD_SIZE_2MB on the build command line can
+# override this.
+#
+[Defines]
+!if $(TARGET) == RELEASE
!ifndef $(FD_SIZE_2MB)
+DEFINE FD_SIZE_1MB=
+!endif
+!endif
+
+!ifdef $(FD_SIZE_1MB)
[FD.OVMF]
-BaseAddress = 0xFFF00000
-Size = 0x00100000
+BaseAddress = 0xFFF00000|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFdBaseAddress
+Size = 0x00100000|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFirmwareFdSize
ErasePolarity = 1
-BlockSize = 0x1000
+BlockSize = 0x1000|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFirmwareBlockSize
NumBlocks = 0x100
+!else
+[FD.OVMF]
+BaseAddress = 0xFFE00000|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFdBaseAddress
+Size = 0x00200000|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFirmwareFdSize
+ErasePolarity = 1
+BlockSize = 0x1000|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFirmwareBlockSize
+NumBlocks = 0x200
+!endif
-0x00000000|0x000EC000
+0x00000000|0x0000e000
+gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFlashNvStorageVariableBase|gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize
+#NV_VARIABLE_STORE
+DATA = {
+ ## This is the EFI_FIRMWARE_VOLUME_HEADER
+ # ZeroVector []
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ # FileSystemGuid: gEfiSystemNvDataFvGuid =
+ # { 0xFFF12B8D, 0x7696, 0x4C8B,
+ # { 0xA9, 0x85, 0x27, 0x47, 0x07, 0x5B, 0x4F, 0x50 }}
+ 0x8D, 0x2B, 0xF1, 0xFF, 0x96, 0x76, 0x8B, 0x4C,
+ 0xA9, 0x85, 0x27, 0x47, 0x07, 0x5B, 0x4F, 0x50,
+ # FvLength: 0x20000
+ 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
+ # Signature "_FVH" # Attributes
+ 0x5f, 0x46, 0x56, 0x48, 0xff, 0xfe, 0x04, 0x00,
+ # HeaderLength # CheckSum # ExtHeaderOffset #Reserved #Revision
+ 0x48, 0x00, 0x19, 0xF9, 0x00, 0x00, 0x00, 0x02,
+ # Blockmap[0]: 0x20 Blocks * 0x1000 Bytes / Block
+ 0x20, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00,
+ # Blockmap[1]: End
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ ## This is the VARIABLE_STORE_HEADER
+!if $(SECURE_BOOT_ENABLE) == TRUE
+ # Signature: gEfiAuthenticatedVariableGuid =
+ # { 0xaaf32c78, 0x947b, 0x439a,
+ # { 0xa1, 0x80, 0x2e, 0x14, 0x4e, 0xc3, 0x77, 0x92 }}
+ 0x78, 0x2c, 0xf3, 0xaa, 0x7b, 0x94, 0x9a, 0x43,
+ 0xa1, 0x80, 0x2e, 0x14, 0x4e, 0xc3, 0x77, 0x92,
+!else
+ # Signature: gEfiVariableGuid =
+ # { 0xddcf3616, 0x3275, 0x4164,
+ # { 0x98, 0xb6, 0xfe, 0x85, 0x70, 0x7f, 0xfe, 0x7d }}
+ 0x16, 0x36, 0xcf, 0xdd, 0x75, 0x32, 0x64, 0x41,
+ 0x98, 0xb6, 0xfe, 0x85, 0x70, 0x7f, 0xfe, 0x7d,
+!endif
+ # Size: 0xe000 (gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize) -
+ # 0x48 (size of EFI_FIRMWARE_VOLUME_HEADER) = 0xdfb8
+ # This can speed up the Variable Dispatch a bit.
+ 0xB8, 0xDF, 0x00, 0x00,
+ # FORMATTED: 0x5A #HEALTHY: 0xFE #Reserved: UINT16 #Reserved1: UINT32
+ 0x5A, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+}
+
+0x0000e000|0x00001000
+#NV_EVENT_LOG
+gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFlashNvStorageEventLogBase|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFlashNvStorageEventLogSize
+
+0x0000f000|0x00001000
+gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFlashNvStorageFtwWorkingBase|gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingSize
+#NV_FTW_WORKING
+DATA = {
+ # EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER->Signature = gEdkiiWorkingBlockSignatureGuid =
+ # { 0x9e58292b, 0x7c68, 0x497d, { 0xa0, 0xce, 0x65, 0x0, 0xfd, 0x9f, 0x1b, 0x95 }}
+ 0x2b, 0x29, 0x58, 0x9e, 0x68, 0x7c, 0x7d, 0x49,
+ 0xa0, 0xce, 0x65, 0x0, 0xfd, 0x9f, 0x1b, 0x95,
+ # Crc:UINT32 #WorkingBlockValid:1, WorkingBlockInvalid:1, Reserved
+ 0x2c, 0xaf, 0x2c, 0x64, 0xFE, 0xFF, 0xFF, 0xFF,
+ # WriteQueueSize: UINT64
+ 0xE0, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+}
+
+0x00010000|0x00010000
+#NV_FTW_SPARE
+gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFlashNvStorageFtwSpareBase|gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize
+
+!ifdef $(FD_SIZE_1MB)
+0x00020000|0x000CC000
FV = FVMAIN_COMPACT
0x000EC000|0x14000
FV = SECFV
-!else
-[FD.OVMF]
-BaseAddress = 0xFFE00000
-Size = 0x00200000
-ErasePolarity = 1
-BlockSize = 0x1000
-NumBlocks = 0x200
-0x00000000|0x001CC000
+!else
+0x00020000|0x001AC000
FV = FVMAIN_COMPACT
0x001CC000|0x34000
@@ -157,6 +241,7 @@ READ_LOCK_STATUS = TRUE
APRIORI DXE {
INF MdeModulePkg/Universal/DevicePathDxe/DevicePathDxe.inf
INF MdeModulePkg/Universal/PCD/Dxe/Pcd.inf
+ INF OvmfPkg/QemuFlashFvbServicesRuntimeDxe/FvbServicesRuntimeDxe.inf
}
#
@@ -184,6 +269,7 @@ INF OvmfPkg/BlockMmioToBlockIoDxe/BlockIo.inf
INF OvmfPkg/VirtioPciDeviceDxe/VirtioPciDeviceDxe.inf
INF OvmfPkg/VirtioBlkDxe/VirtioBlk.inf
INF OvmfPkg/VirtioScsiDxe/VirtioScsi.inf
+INF OvmfPkg/QemuFlashFvbServicesRuntimeDxe/FvbServicesRuntimeDxe.inf
INF OvmfPkg/EmuVariableFvbRuntimeDxe/Fvb.inf
INF MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteDxe.inf
diff --git a/OvmfPkg/OvmfPkgIa32X64.dsc b/OvmfPkg/OvmfPkgIa32X64.dsc
index 171cbe2b7..829341ca8 100644
--- a/OvmfPkg/OvmfPkgIa32X64.dsc
+++ b/OvmfPkg/OvmfPkgIa32X64.dsc
@@ -118,7 +118,6 @@
ResetSystemLib|OvmfPkg/Library/ResetSystemLib/ResetSystemLib.inf
LocalApicLib|UefiCpuPkg/Library/BaseXApicLib/BaseXApicLib.inf
DebugPrintErrorLevelLib|MdePkg/Library/BaseDebugPrintErrorLevelLib/BaseDebugPrintErrorLevelLib.inf
- CpuExceptionHandlerLib|MdeModulePkg/Library/CpuExceptionHandlerLibNull/CpuExceptionHandlerLibNull.inf
!if $(SECURE_BOOT_ENABLE) == TRUE
PlatformSecureLib|OvmfPkg/Library/PlatformSecureLib/PlatformSecureLib.inf
@@ -147,6 +146,7 @@
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
@@ -200,6 +200,7 @@
!ifdef $(SOURCE_DEBUG_ENABLE)
DebugAgentLib|SourceLevelDebugPkg/Library/DebugAgent/DxeDebugAgentLib.inf
!endif
+ CpuExceptionHandlerLib|UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeCpuExceptionHandlerLib.inf
[LibraryClasses.common.DXE_RUNTIME_DRIVER]
HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf
@@ -246,6 +247,7 @@
UdpIoLib|MdeModulePkg/Library/DxeUdpIoLib/DxeUdpIoLib.inf
DpcLib|MdeModulePkg/Library/DxeDpcLib/DxeDpcLib.inf
PlatformBdsLib|OvmfPkg/Library/PlatformBdsLib/PlatformBdsLib.inf
+ CpuExceptionHandlerLib|UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeCpuExceptionHandlerLib.inf
[LibraryClasses.common.UEFI_APPLICATION]
HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf
@@ -284,10 +286,7 @@
gEfiMdeModulePkgTokenSpaceGuid.PcdMaxVariableSize|0x400
!endif
gEfiMdeModulePkgTokenSpaceGuid.PcdMaxHardwareErrorVariableSize|0x8000
- gEfiMdeModulePkgTokenSpaceGuid.PcdVariableStoreSize|0xc000
- gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize|0xc000
- gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingSize|0x2000
- gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize|0x10000
+ gEfiMdeModulePkgTokenSpaceGuid.PcdVariableStoreSize|0xe000
gEfiMdeModulePkgTokenSpaceGuid.PcdVpdBaseAddress|0x0
@@ -418,6 +417,7 @@
OvmfPkg/VirtioPciDeviceDxe/VirtioPciDeviceDxe.inf
OvmfPkg/VirtioBlkDxe/VirtioBlk.inf
OvmfPkg/VirtioScsiDxe/VirtioScsi.inf
+ OvmfPkg/QemuFlashFvbServicesRuntimeDxe/FvbServicesRuntimeDxe.inf
OvmfPkg/EmuVariableFvbRuntimeDxe/Fvb.inf {
<LibraryClasses>
PlatformFvbLib|OvmfPkg/Library/EmuVariableFvbLib/EmuVariableFvbLib.inf
diff --git a/OvmfPkg/OvmfPkgIa32X64.fdf b/OvmfPkg/OvmfPkgIa32X64.fdf
index 9965c3cf5..9aa47740b 100644
--- a/OvmfPkg/OvmfPkgIa32X64.fdf
+++ b/OvmfPkg/OvmfPkgIa32X64.fdf
@@ -14,28 +14,112 @@
##
################################################################################
+
+#
+# Default flash size for DEBUG build is 2MB. For RELEASE it is 1MB.
+#
+# Defining FD_SIZE_1MB or FD_SIZE_2MB on the build command line can
+# override this.
+#
+[Defines]
+!if $(TARGET) == RELEASE
!ifndef $(FD_SIZE_2MB)
+DEFINE FD_SIZE_1MB=
+!endif
+!endif
+
+!ifdef $(FD_SIZE_1MB)
[FD.OVMF]
-BaseAddress = 0xFFF00000
-Size = 0x00100000
+BaseAddress = 0xFFF00000|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFdBaseAddress
+Size = 0x00100000|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFirmwareFdSize
ErasePolarity = 1
-BlockSize = 0x1000
+BlockSize = 0x1000|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFirmwareBlockSize
NumBlocks = 0x100
+!else
+[FD.OVMF]
+BaseAddress = 0xFFE00000|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFdBaseAddress
+Size = 0x00200000|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFirmwareFdSize
+ErasePolarity = 1
+BlockSize = 0x1000|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFirmwareBlockSize
+NumBlocks = 0x200
+!endif
-0x00000000|0x000EC000
+0x00000000|0x0000e000
+gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFlashNvStorageVariableBase|gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize
+#NV_VARIABLE_STORE
+DATA = {
+ ## This is the EFI_FIRMWARE_VOLUME_HEADER
+ # ZeroVector []
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ # FileSystemGuid: gEfiSystemNvDataFvGuid =
+ # { 0xFFF12B8D, 0x7696, 0x4C8B,
+ # { 0xA9, 0x85, 0x27, 0x47, 0x07, 0x5B, 0x4F, 0x50 }}
+ 0x8D, 0x2B, 0xF1, 0xFF, 0x96, 0x76, 0x8B, 0x4C,
+ 0xA9, 0x85, 0x27, 0x47, 0x07, 0x5B, 0x4F, 0x50,
+ # FvLength: 0x20000
+ 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
+ # Signature "_FVH" # Attributes
+ 0x5f, 0x46, 0x56, 0x48, 0xff, 0xfe, 0x04, 0x00,
+ # HeaderLength # CheckSum # ExtHeaderOffset #Reserved #Revision
+ 0x48, 0x00, 0x19, 0xF9, 0x00, 0x00, 0x00, 0x02,
+ # Blockmap[0]: 0x20 Blocks * 0x1000 Bytes / Block
+ 0x20, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00,
+ # Blockmap[1]: End
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ ## This is the VARIABLE_STORE_HEADER
+!if $(SECURE_BOOT_ENABLE) == TRUE
+ # Signature: gEfiAuthenticatedVariableGuid =
+ # { 0xaaf32c78, 0x947b, 0x439a,
+ # { 0xa1, 0x80, 0x2e, 0x14, 0x4e, 0xc3, 0x77, 0x92 }}
+ 0x78, 0x2c, 0xf3, 0xaa, 0x7b, 0x94, 0x9a, 0x43,
+ 0xa1, 0x80, 0x2e, 0x14, 0x4e, 0xc3, 0x77, 0x92,
+!else
+ # Signature: gEfiVariableGuid =
+ # { 0xddcf3616, 0x3275, 0x4164,
+ # { 0x98, 0xb6, 0xfe, 0x85, 0x70, 0x7f, 0xfe, 0x7d }}
+ 0x16, 0x36, 0xcf, 0xdd, 0x75, 0x32, 0x64, 0x41,
+ 0x98, 0xb6, 0xfe, 0x85, 0x70, 0x7f, 0xfe, 0x7d,
+!endif
+ # Size: 0xe000 (gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize) -
+ # 0x48 (size of EFI_FIRMWARE_VOLUME_HEADER) = 0xdfb8
+ # This can speed up the Variable Dispatch a bit.
+ 0xB8, 0xDF, 0x00, 0x00,
+ # FORMATTED: 0x5A #HEALTHY: 0xFE #Reserved: UINT16 #Reserved1: UINT32
+ 0x5A, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+}
+
+0x0000e000|0x00001000
+#NV_EVENT_LOG
+gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFlashNvStorageEventLogBase|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFlashNvStorageEventLogSize
+
+0x0000f000|0x00001000
+gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFlashNvStorageFtwWorkingBase|gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingSize
+#NV_FTW_WORKING
+DATA = {
+ # EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER->Signature = gEdkiiWorkingBlockSignatureGuid =
+ # { 0x9e58292b, 0x7c68, 0x497d, { 0xa0, 0xce, 0x65, 0x0, 0xfd, 0x9f, 0x1b, 0x95 }}
+ 0x2b, 0x29, 0x58, 0x9e, 0x68, 0x7c, 0x7d, 0x49,
+ 0xa0, 0xce, 0x65, 0x0, 0xfd, 0x9f, 0x1b, 0x95,
+ # Crc:UINT32 #WorkingBlockValid:1, WorkingBlockInvalid:1, Reserved
+ 0x2c, 0xaf, 0x2c, 0x64, 0xFE, 0xFF, 0xFF, 0xFF,
+ # WriteQueueSize: UINT64
+ 0xE0, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+}
+
+0x00010000|0x00010000
+#NV_FTW_SPARE
+gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFlashNvStorageFtwSpareBase|gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize
+
+!ifdef $(FD_SIZE_1MB)
+0x00020000|0x000CC000
FV = FVMAIN_COMPACT
0x000EC000|0x14000
FV = SECFV
-!else
-[FD.OVMF]
-BaseAddress = 0xFFE00000
-Size = 0x00200000
-ErasePolarity = 1
-BlockSize = 0x1000
-NumBlocks = 0x200
-0x00000000|0x001CC000
+!else
+0x00020000|0x001AC000
FV = FVMAIN_COMPACT
0x001CC000|0x34000
@@ -157,6 +241,7 @@ READ_LOCK_STATUS = TRUE
APRIORI DXE {
INF MdeModulePkg/Universal/DevicePathDxe/DevicePathDxe.inf
INF MdeModulePkg/Universal/PCD/Dxe/Pcd.inf
+ INF OvmfPkg/QemuFlashFvbServicesRuntimeDxe/FvbServicesRuntimeDxe.inf
}
#
@@ -184,6 +269,7 @@ INF OvmfPkg/BlockMmioToBlockIoDxe/BlockIo.inf
INF OvmfPkg/VirtioPciDeviceDxe/VirtioPciDeviceDxe.inf
INF OvmfPkg/VirtioBlkDxe/VirtioBlk.inf
INF OvmfPkg/VirtioScsiDxe/VirtioScsi.inf
+INF OvmfPkg/QemuFlashFvbServicesRuntimeDxe/FvbServicesRuntimeDxe.inf
INF OvmfPkg/EmuVariableFvbRuntimeDxe/Fvb.inf
INF MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteDxe.inf
diff --git a/OvmfPkg/OvmfPkgX64.dsc b/OvmfPkg/OvmfPkgX64.dsc
index 08c81e4a5..96067f3e3 100644
--- a/OvmfPkg/OvmfPkgX64.dsc
+++ b/OvmfPkg/OvmfPkgX64.dsc
@@ -118,7 +118,6 @@
ResetSystemLib|OvmfPkg/Library/ResetSystemLib/ResetSystemLib.inf
LocalApicLib|UefiCpuPkg/Library/BaseXApicLib/BaseXApicLib.inf
DebugPrintErrorLevelLib|MdePkg/Library/BaseDebugPrintErrorLevelLib/BaseDebugPrintErrorLevelLib.inf
- CpuExceptionHandlerLib|MdeModulePkg/Library/CpuExceptionHandlerLibNull/CpuExceptionHandlerLibNull.inf
!if $(SECURE_BOOT_ENABLE) == TRUE
PlatformSecureLib|OvmfPkg/Library/PlatformSecureLib/PlatformSecureLib.inf
@@ -147,6 +146,7 @@
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
@@ -200,6 +200,7 @@
!ifdef $(SOURCE_DEBUG_ENABLE)
DebugAgentLib|SourceLevelDebugPkg/Library/DebugAgent/DxeDebugAgentLib.inf
!endif
+ CpuExceptionHandlerLib|UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeCpuExceptionHandlerLib.inf
[LibraryClasses.common.DXE_RUNTIME_DRIVER]
HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf
@@ -246,6 +247,7 @@
UdpIoLib|MdeModulePkg/Library/DxeUdpIoLib/DxeUdpIoLib.inf
DpcLib|MdeModulePkg/Library/DxeDpcLib/DxeDpcLib.inf
PlatformBdsLib|OvmfPkg/Library/PlatformBdsLib/PlatformBdsLib.inf
+ CpuExceptionHandlerLib|UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeCpuExceptionHandlerLib.inf
[LibraryClasses.common.UEFI_APPLICATION]
HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf
@@ -284,10 +286,7 @@
gEfiMdeModulePkgTokenSpaceGuid.PcdMaxVariableSize|0x400
!endif
gEfiMdeModulePkgTokenSpaceGuid.PcdMaxHardwareErrorVariableSize|0x8000
- gEfiMdeModulePkgTokenSpaceGuid.PcdVariableStoreSize|0xc000
- gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize|0xc000
- gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingSize|0x2000
- gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize|0x10000
+ gEfiMdeModulePkgTokenSpaceGuid.PcdVariableStoreSize|0xe000
gEfiMdeModulePkgTokenSpaceGuid.PcdVpdBaseAddress|0x0
@@ -416,6 +415,7 @@
OvmfPkg/VirtioPciDeviceDxe/VirtioPciDeviceDxe.inf
OvmfPkg/VirtioBlkDxe/VirtioBlk.inf
OvmfPkg/VirtioScsiDxe/VirtioScsi.inf
+ OvmfPkg/QemuFlashFvbServicesRuntimeDxe/FvbServicesRuntimeDxe.inf
OvmfPkg/EmuVariableFvbRuntimeDxe/Fvb.inf {
<LibraryClasses>
PlatformFvbLib|OvmfPkg/Library/EmuVariableFvbLib/EmuVariableFvbLib.inf
diff --git a/OvmfPkg/OvmfPkgX64.fdf b/OvmfPkg/OvmfPkgX64.fdf
index e2420c5cf..d7221950b 100644
--- a/OvmfPkg/OvmfPkgX64.fdf
+++ b/OvmfPkg/OvmfPkgX64.fdf
@@ -14,28 +14,112 @@
##
################################################################################
+
+#
+# Default flash size for DEBUG build is 2MB. For RELEASE it is 1MB.
+#
+# Defining FD_SIZE_1MB or FD_SIZE_2MB on the build command line can
+# override this.
+#
+[Defines]
+!if $(TARGET) == RELEASE
!ifndef $(FD_SIZE_2MB)
+DEFINE FD_SIZE_1MB=
+!endif
+!endif
+
+!ifdef $(FD_SIZE_1MB)
[FD.OVMF]
-BaseAddress = 0xFFF00000
-Size = 0x00100000
+BaseAddress = 0xFFF00000|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFdBaseAddress
+Size = 0x00100000|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFirmwareFdSize
ErasePolarity = 1
-BlockSize = 0x1000
+BlockSize = 0x1000|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFirmwareBlockSize
NumBlocks = 0x100
+!else
+[FD.OVMF]
+BaseAddress = 0xFFE00000|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFdBaseAddress
+Size = 0x00200000|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFirmwareFdSize
+ErasePolarity = 1
+BlockSize = 0x1000|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFirmwareBlockSize
+NumBlocks = 0x200
+!endif
-0x00000000|0x000EC000
+0x00000000|0x0000e000
+gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFlashNvStorageVariableBase|gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize
+#NV_VARIABLE_STORE
+DATA = {
+ ## This is the EFI_FIRMWARE_VOLUME_HEADER
+ # ZeroVector []
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ # FileSystemGuid: gEfiSystemNvDataFvGuid =
+ # { 0xFFF12B8D, 0x7696, 0x4C8B,
+ # { 0xA9, 0x85, 0x27, 0x47, 0x07, 0x5B, 0x4F, 0x50 }}
+ 0x8D, 0x2B, 0xF1, 0xFF, 0x96, 0x76, 0x8B, 0x4C,
+ 0xA9, 0x85, 0x27, 0x47, 0x07, 0x5B, 0x4F, 0x50,
+ # FvLength: 0x20000
+ 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
+ # Signature "_FVH" # Attributes
+ 0x5f, 0x46, 0x56, 0x48, 0xff, 0xfe, 0x04, 0x00,
+ # HeaderLength # CheckSum # ExtHeaderOffset #Reserved #Revision
+ 0x48, 0x00, 0x19, 0xF9, 0x00, 0x00, 0x00, 0x02,
+ # Blockmap[0]: 0x20 Blocks * 0x1000 Bytes / Block
+ 0x20, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00,
+ # Blockmap[1]: End
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ ## This is the VARIABLE_STORE_HEADER
+!if $(SECURE_BOOT_ENABLE) == TRUE
+ # Signature: gEfiAuthenticatedVariableGuid =
+ # { 0xaaf32c78, 0x947b, 0x439a,
+ # { 0xa1, 0x80, 0x2e, 0x14, 0x4e, 0xc3, 0x77, 0x92 }}
+ 0x78, 0x2c, 0xf3, 0xaa, 0x7b, 0x94, 0x9a, 0x43,
+ 0xa1, 0x80, 0x2e, 0x14, 0x4e, 0xc3, 0x77, 0x92,
+!else
+ # Signature: gEfiVariableGuid =
+ # { 0xddcf3616, 0x3275, 0x4164,
+ # { 0x98, 0xb6, 0xfe, 0x85, 0x70, 0x7f, 0xfe, 0x7d }}
+ 0x16, 0x36, 0xcf, 0xdd, 0x75, 0x32, 0x64, 0x41,
+ 0x98, 0xb6, 0xfe, 0x85, 0x70, 0x7f, 0xfe, 0x7d,
+!endif
+ # Size: 0xe000 (gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize) -
+ # 0x48 (size of EFI_FIRMWARE_VOLUME_HEADER) = 0xdfb8
+ # This can speed up the Variable Dispatch a bit.
+ 0xB8, 0xDF, 0x00, 0x00,
+ # FORMATTED: 0x5A #HEALTHY: 0xFE #Reserved: UINT16 #Reserved1: UINT32
+ 0x5A, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+}
+
+0x0000e000|0x00001000
+#NV_EVENT_LOG
+gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFlashNvStorageEventLogBase|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFlashNvStorageEventLogSize
+
+0x0000f000|0x00001000
+gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFlashNvStorageFtwWorkingBase|gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingSize
+#NV_FTW_WORKING
+DATA = {
+ # EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER->Signature = gEdkiiWorkingBlockSignatureGuid =
+ # { 0x9e58292b, 0x7c68, 0x497d, { 0xa0, 0xce, 0x65, 0x0, 0xfd, 0x9f, 0x1b, 0x95 }}
+ 0x2b, 0x29, 0x58, 0x9e, 0x68, 0x7c, 0x7d, 0x49,
+ 0xa0, 0xce, 0x65, 0x0, 0xfd, 0x9f, 0x1b, 0x95,
+ # Crc:UINT32 #WorkingBlockValid:1, WorkingBlockInvalid:1, Reserved
+ 0x2c, 0xaf, 0x2c, 0x64, 0xFE, 0xFF, 0xFF, 0xFF,
+ # WriteQueueSize: UINT64
+ 0xE0, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+}
+
+0x00010000|0x00010000
+#NV_FTW_SPARE
+gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFlashNvStorageFtwSpareBase|gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize
+
+!ifdef $(FD_SIZE_1MB)
+0x00020000|0x000CC000
FV = FVMAIN_COMPACT
0x000EC000|0x14000
FV = SECFV
-!else
-[FD.OVMF]
-BaseAddress = 0xFFE00000
-Size = 0x00200000
-ErasePolarity = 1
-BlockSize = 0x1000
-NumBlocks = 0x200
-0x00000000|0x001CC000
+!else
+0x00020000|0x001AC000
FV = FVMAIN_COMPACT
0x001CC000|0x34000
@@ -157,6 +241,7 @@ READ_LOCK_STATUS = TRUE
APRIORI DXE {
INF MdeModulePkg/Universal/DevicePathDxe/DevicePathDxe.inf
INF MdeModulePkg/Universal/PCD/Dxe/Pcd.inf
+ INF OvmfPkg/QemuFlashFvbServicesRuntimeDxe/FvbServicesRuntimeDxe.inf
}
#
@@ -184,6 +269,7 @@ INF OvmfPkg/BlockMmioToBlockIoDxe/BlockIo.inf
INF OvmfPkg/VirtioPciDeviceDxe/VirtioPciDeviceDxe.inf
INF OvmfPkg/VirtioBlkDxe/VirtioBlk.inf
INF OvmfPkg/VirtioScsiDxe/VirtioScsi.inf
+INF OvmfPkg/QemuFlashFvbServicesRuntimeDxe/FvbServicesRuntimeDxe.inf
INF OvmfPkg/EmuVariableFvbRuntimeDxe/Fvb.inf
INF MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteDxe.inf
diff --git a/OvmfPkg/PlatformPei/Platform.c b/OvmfPkg/PlatformPei/Platform.c
index 1d9e93ff4..fb56e999e 100644
--- a/OvmfPkg/PlatformPei/Platform.c
+++ b/OvmfPkg/PlatformPei/Platform.c
@@ -287,7 +287,7 @@ ReserveEmuVariableNvStore (
//
VariableStore =
(EFI_PHYSICAL_ADDRESS)(UINTN)
- AllocateAlignedPages (
+ AllocateAlignedRuntimePages (
EFI_SIZE_TO_PAGES (2 * PcdGet32 (PcdFlashNvStorageFtwSpareSize)),
PcdGet32 (PcdFlashNvStorageFtwSpareSize)
);
diff --git a/OvmfPkg/QemuFlashFvbServicesRuntimeDxe/FvbInfo.c b/OvmfPkg/QemuFlashFvbServicesRuntimeDxe/FvbInfo.c
new file mode 100644
index 000000000..72845f955
--- /dev/null
+++ b/OvmfPkg/QemuFlashFvbServicesRuntimeDxe/FvbInfo.c
@@ -0,0 +1,137 @@
+/**@file
+
+Copyright (c) 2006, 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.
+
+Module Name:
+
+ FvbInfo.c
+
+Abstract:
+
+ Defines data structure that is the volume header found.These data is intent
+ to decouple FVB driver with FV header.
+
+**/
+
+//
+// The package level header files this module uses
+//
+#include <PiDxe.h>
+//
+// The protocols, PPI and GUID defintions for this module
+//
+#include <Guid/EventGroup.h>
+#include <Guid/FirmwareFileSystem2.h>
+#include <Guid/SystemNvDataGuid.h>
+#include <Protocol/FirmwareVolumeBlock.h>
+#include <Protocol/DevicePath.h>
+//
+// The Library classes this module consumes
+//
+#include <Library/UefiLib.h>
+#include <Library/UefiDriverEntryPoint.h>
+#include <Library/BaseLib.h>
+#include <Library/DxeServicesTableLib.h>
+#include <Library/UefiRuntimeLib.h>
+#include <Library/DebugLib.h>
+#include <Library/HobLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/PcdLib.h>
+
+typedef struct {
+ UINT64 FvLength;
+ EFI_FIRMWARE_VOLUME_HEADER FvbInfo;
+ //
+ // EFI_FV_BLOCK_MAP_ENTRY ExtraBlockMap[n];//n=0
+ //
+ EFI_FV_BLOCK_MAP_ENTRY End[1];
+} EFI_FVB_MEDIA_INFO;
+
+EFI_FVB_MEDIA_INFO mPlatformFvbMediaInfo[] = {
+ //
+ // Systen NvStorage FVB
+ //
+ {
+ FixedPcdGet32 (PcdFlashNvStorageVariableSize) +
+ FixedPcdGet32 (PcdFlashNvStorageFtwWorkingSize) +
+ FixedPcdGet32 (PcdFlashNvStorageFtwSpareSize) +
+ FixedPcdGet32 (PcdOvmfFlashNvStorageEventLogSize),
+ {
+ {
+ 0,
+ }, // ZeroVector[16]
+ EFI_SYSTEM_NV_DATA_FV_GUID,
+ FixedPcdGet32 (PcdFlashNvStorageVariableSize) +
+ FixedPcdGet32 (PcdFlashNvStorageFtwWorkingSize) +
+ FixedPcdGet32 (PcdFlashNvStorageFtwSpareSize) +
+ FixedPcdGet32 (PcdOvmfFlashNvStorageEventLogSize),
+ EFI_FVH_SIGNATURE,
+ EFI_FVB2_MEMORY_MAPPED |
+ EFI_FVB2_READ_ENABLED_CAP |
+ EFI_FVB2_READ_STATUS |
+ EFI_FVB2_WRITE_ENABLED_CAP |
+ EFI_FVB2_WRITE_STATUS |
+ EFI_FVB2_ERASE_POLARITY |
+ EFI_FVB2_ALIGNMENT_16,
+ sizeof (EFI_FIRMWARE_VOLUME_HEADER) + sizeof (EFI_FV_BLOCK_MAP_ENTRY),
+ 0, // CheckSum
+ 0, // ExtHeaderOffset
+ {
+ 0,
+ }, // Reserved[1]
+ 2, // Revision
+ {
+ (FixedPcdGet32 (PcdFlashNvStorageVariableSize) +
+ FixedPcdGet32 (PcdFlashNvStorageFtwWorkingSize) +
+ FixedPcdGet32 (PcdFlashNvStorageFtwSpareSize) +
+ FixedPcdGet32 (PcdOvmfFlashNvStorageEventLogSize)) / FixedPcdGet32 (PcdOvmfFirmwareBlockSize),
+ FixedPcdGet32 (PcdOvmfFirmwareBlockSize),
+ }
+ },
+ {
+ 0,
+ 0
+ }
+ }
+};
+
+EFI_STATUS
+GetFvbInfo (
+ IN UINT64 FvLength,
+ OUT EFI_FIRMWARE_VOLUME_HEADER **FvbInfo
+ )
+{
+ STATIC BOOLEAN Checksummed = FALSE;
+ UINTN Index;
+
+ if (!Checksummed) {
+ for (Index = 0; Index < sizeof (mPlatformFvbMediaInfo) / sizeof (EFI_FVB_MEDIA_INFO); Index += 1) {
+ UINT16 Checksum;
+ mPlatformFvbMediaInfo[Index].FvbInfo.Checksum = 0;
+ Checksum = CalculateCheckSum16 (
+ (UINT16*) &mPlatformFvbMediaInfo[Index].FvbInfo,
+ mPlatformFvbMediaInfo[Index].FvbInfo.HeaderLength
+ );
+ mPlatformFvbMediaInfo[Index].FvbInfo.Checksum = Checksum;
+ }
+ Checksummed = TRUE;
+ }
+
+ for (Index = 0; Index < sizeof (mPlatformFvbMediaInfo) / sizeof (EFI_FVB_MEDIA_INFO); Index += 1) {
+ if (mPlatformFvbMediaInfo[Index].FvLength == FvLength) {
+ *FvbInfo = &mPlatformFvbMediaInfo[Index].FvbInfo;
+ return EFI_SUCCESS;
+ }
+ }
+
+ return EFI_NOT_FOUND;
+}
diff --git a/OvmfPkg/QemuFlashFvbServicesRuntimeDxe/FvbServicesRuntimeDxe.inf b/OvmfPkg/QemuFlashFvbServicesRuntimeDxe/FvbServicesRuntimeDxe.inf
new file mode 100644
index 000000000..e3e7176a4
--- /dev/null
+++ b/OvmfPkg/QemuFlashFvbServicesRuntimeDxe/FvbServicesRuntimeDxe.inf
@@ -0,0 +1,84 @@
+## @file
+# Component description file for QEMU Flash Fimware Volume Block DXE driver module.
+#
+# This DXE runtime driver implements and produces the Fimware Volue Block Protocol
+# for a QEMU flash device.
+#
+# 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.
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = FvbServicesRuntimeDxe
+ FILE_GUID = 733cbac2-b23f-4b92-bc8e-fb01ce5907b7
+ MODULE_TYPE = DXE_RUNTIME_DRIVER
+ VERSION_STRING = 1.0
+ ENTRY_POINT = FvbInitialize
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32
+#
+
+[Sources]
+ FvbInfo.c
+ FwBlockService.c
+ QemuFlash.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ OvmfPkg/OvmfPkg.dec
+
+[LibraryClasses]
+ UefiBootServicesTableLib
+ MemoryAllocationLib
+ BaseMemoryLib
+ HobLib
+ DebugLib
+ UefiRuntimeLib
+ DxeServicesTableLib
+ BaseLib
+ UefiDriverEntryPoint
+ UefiLib
+ PcdLib
+
+[Guids]
+ gEfiEventVirtualAddressChangeGuid # ALWAYS_CONSUMED Create Event: EVENT_GROUP_GUID
+
+[Protocols]
+ gEfiFirmwareVolumeBlockProtocolGuid # PROTOCOL SOMETIMES_PRODUCED
+ gEfiDevicePathProtocolGuid # PROTOCOL SOMETIMES_PRODUCED
+
+[FixedPcd]
+ gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize
+ gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingSize
+ gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize
+ gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFlashNvStorageVariableBase
+ gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFlashNvStorageFtwWorkingBase
+ gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFlashNvStorageFtwSpareBase
+ gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFlashNvStorageEventLogSize
+ gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFdBaseAddress
+ gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFirmwareFdSize
+ gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFirmwareBlockSize
+
+[Pcd]
+ gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingBase
+ gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareBase
+ gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase
+ gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFlashNvStorageEventLogBase
+ gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase64
+ gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFlashVariablesEnable
+
+
+[Depex]
+ TRUE
diff --git a/OvmfPkg/QemuFlashFvbServicesRuntimeDxe/FwBlockService.c b/OvmfPkg/QemuFlashFvbServicesRuntimeDxe/FwBlockService.c
new file mode 100644
index 000000000..7d26c41cc
--- /dev/null
+++ b/OvmfPkg/QemuFlashFvbServicesRuntimeDxe/FwBlockService.c
@@ -0,0 +1,1227 @@
+/**@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.
+
+Module Name:
+
+ FWBlockService.c
+
+Abstract:
+
+Revision History
+
+**/
+
+//
+// The package level header files this module uses
+//
+#include <PiDxe.h>
+
+//
+// The protocols, PPI and GUID defintions for this module
+//
+#include <Guid/EventGroup.h>
+#include <Protocol/FirmwareVolumeBlock.h>
+#include <Protocol/DevicePath.h>
+
+//
+// The Library classes this module consumes
+//
+#include <Library/UefiLib.h>
+#include <Library/UefiDriverEntryPoint.h>
+#include <Library/BaseLib.h>
+#include <Library/DxeServicesTableLib.h>
+#include <Library/UefiRuntimeLib.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/DevicePathLib.h>
+
+#include "FwBlockService.h"
+#include "QemuFlash.h"
+
+#define EFI_FVB2_STATUS (EFI_FVB2_READ_STATUS | EFI_FVB2_WRITE_STATUS | EFI_FVB2_LOCK_STATUS)
+
+ESAL_FWB_GLOBAL *mFvbModuleGlobal;
+
+FV_MEMMAP_DEVICE_PATH mFvMemmapDevicePathTemplate = {
+ {
+ {
+ HARDWARE_DEVICE_PATH,
+ HW_MEMMAP_DP,
+ {
+ (UINT8)(sizeof (MEMMAP_DEVICE_PATH)),
+ (UINT8)(sizeof (MEMMAP_DEVICE_PATH) >> 8)
+ }
+ },
+ EfiMemoryMappedIO,
+ (EFI_PHYSICAL_ADDRESS) 0,
+ (EFI_PHYSICAL_ADDRESS) 0,
+ },
+ {
+ END_DEVICE_PATH_TYPE,
+ END_ENTIRE_DEVICE_PATH_SUBTYPE,
+ {
+ END_DEVICE_PATH_LENGTH,
+ 0
+ }
+ }
+};
+
+FV_PIWG_DEVICE_PATH mFvPIWGDevicePathTemplate = {
+ {
+ {
+ MEDIA_DEVICE_PATH,
+ MEDIA_PIWG_FW_VOL_DP,
+ {
+ (UINT8)(sizeof (MEDIA_FW_VOL_DEVICE_PATH)),
+ (UINT8)(sizeof (MEDIA_FW_VOL_DEVICE_PATH) >> 8)
+ }
+ },
+ { 0 }
+ },
+ {
+ END_DEVICE_PATH_TYPE,
+ END_ENTIRE_DEVICE_PATH_SUBTYPE,
+ {
+ END_DEVICE_PATH_LENGTH,
+ 0
+ }
+ }
+};
+
+EFI_FW_VOL_BLOCK_DEVICE mFvbDeviceTemplate = {
+ FVB_DEVICE_SIGNATURE,
+ NULL,
+ 0,
+ {
+ FvbProtocolGetAttributes,
+ FvbProtocolSetAttributes,
+ FvbProtocolGetPhysicalAddress,
+ FvbProtocolGetBlockSize,
+ FvbProtocolRead,
+ FvbProtocolWrite,
+ FvbProtocolEraseBlocks,
+ NULL
+ }
+};
+
+
+
+VOID
+EFIAPI
+FvbVirtualddressChangeEvent (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+/*++
+
+Routine Description:
+
+ Fixup internal data so that EFI and SAL can be call in virtual mode.
+ Call the passed in Child Notify event and convert the mFvbModuleGlobal
+ date items to there virtual address.
+
+ mFvbModuleGlobal->FvInstance[FVB_PHYSICAL] - Physical copy of instance data
+ mFvbModuleGlobal->FvInstance[FVB_VIRTUAL] - Virtual pointer to common
+ instance data.
+
+Arguments:
+
+ (Standard EFI notify event - EFI_EVENT_NOTIFY)
+
+Returns:
+
+ None
+
+--*/
+{
+ EFI_FW_VOL_INSTANCE *FwhInstance;
+ UINTN Index;
+
+ EfiConvertPointer (0x0, (VOID **) &mFvbModuleGlobal->FvInstance[FVB_VIRTUAL]);
+
+ //
+ // Convert the base address of all the instances
+ //
+ Index = 0;
+ FwhInstance = mFvbModuleGlobal->FvInstance[FVB_PHYSICAL];
+ while (Index < mFvbModuleGlobal->NumFv) {
+ EfiConvertPointer (0x0, (VOID **) &FwhInstance->FvBase[FVB_VIRTUAL]);
+ FwhInstance = (EFI_FW_VOL_INSTANCE *)
+ (
+ (UINTN) ((UINT8 *) FwhInstance) + FwhInstance->VolumeHeader.HeaderLength +
+ (sizeof (EFI_FW_VOL_INSTANCE) - sizeof (EFI_FIRMWARE_VOLUME_HEADER))
+ );
+ Index++;
+ }
+
+ EfiConvertPointer (0x0, (VOID **) &mFvbModuleGlobal->FvbScratchSpace[FVB_VIRTUAL]);
+ EfiConvertPointer (0x0, (VOID **) &mFvbModuleGlobal);
+ QemuFlashConvertPointers ();
+}
+
+EFI_STATUS
+GetFvbInstance (
+ IN UINTN Instance,
+ IN ESAL_FWB_GLOBAL *Global,
+ OUT EFI_FW_VOL_INSTANCE **FwhInstance,
+ IN BOOLEAN Virtual
+ )
+/*++
+
+Routine Description:
+ Retrieves the physical address of a memory mapped FV
+
+Arguments:
+ Instance - The FV instance whose base address is going to be
+ returned
+ Global - Pointer to ESAL_FWB_GLOBAL that contains all
+ instance data
+ FwhInstance - The EFI_FW_VOL_INSTANCE fimrware instance structure
+ Virtual - Whether CPU is in virtual or physical mode
+
+Returns:
+ EFI_SUCCESS - Successfully returns
+ EFI_INVALID_PARAMETER - Instance not found
+
+--*/
+{
+ EFI_FW_VOL_INSTANCE *FwhRecord;
+
+ if (Instance >= Global->NumFv) {
+ return EFI_INVALID_PARAMETER;
+ }
+ //
+ // Find the right instance of the FVB private data
+ //
+ FwhRecord = Global->FvInstance[Virtual];
+ while (Instance > 0) {
+ FwhRecord = (EFI_FW_VOL_INSTANCE *)
+ (
+ (UINTN) ((UINT8 *) FwhRecord) + FwhRecord->VolumeHeader.HeaderLength +
+ (sizeof (EFI_FW_VOL_INSTANCE) - sizeof (EFI_FIRMWARE_VOLUME_HEADER))
+ );
+ Instance--;
+ }
+
+ *FwhInstance = FwhRecord;
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+FvbGetPhysicalAddress (
+ IN UINTN Instance,
+ OUT EFI_PHYSICAL_ADDRESS *Address,
+ IN ESAL_FWB_GLOBAL *Global,
+ IN BOOLEAN Virtual
+ )
+/*++
+
+Routine Description:
+ Retrieves the physical address of a memory mapped FV
+
+Arguments:
+ Instance - The FV instance whose base address is going to be
+ returned
+ Address - Pointer to a caller allocated EFI_PHYSICAL_ADDRESS
+ that on successful return, contains the base address
+ of the firmware volume.
+ Global - Pointer to ESAL_FWB_GLOBAL that contains all
+ instance data
+ Virtual - Whether CPU is in virtual or physical mode
+
+Returns:
+ EFI_SUCCESS - Successfully returns
+ EFI_INVALID_PARAMETER - Instance not found
+
+--*/
+{
+ EFI_FW_VOL_INSTANCE *FwhInstance;
+ EFI_STATUS Status;
+
+ //
+ // Find the right instance of the FVB private data
+ //
+ Status = GetFvbInstance (Instance, Global, &FwhInstance, Virtual);
+ ASSERT_EFI_ERROR (Status);
+ *Address = FwhInstance->FvBase[Virtual];
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+FvbGetVolumeAttributes (
+ IN UINTN Instance,
+ OUT EFI_FVB_ATTRIBUTES_2 *Attributes,
+ IN ESAL_FWB_GLOBAL *Global,
+ IN BOOLEAN Virtual
+ )
+/*++
+
+Routine Description:
+ Retrieves attributes, insures positive polarity of attribute bits, returns
+ resulting attributes in output parameter
+
+Arguments:
+ Instance - The FV instance whose attributes is going to be
+ returned
+ Attributes - Output buffer which contains attributes
+ Global - Pointer to ESAL_FWB_GLOBAL that contains all
+ instance data
+ Virtual - Whether CPU is in virtual or physical mode
+
+Returns:
+ EFI_SUCCESS - Successfully returns
+ EFI_INVALID_PARAMETER - Instance not found
+
+--*/
+{
+ EFI_FW_VOL_INSTANCE *FwhInstance;
+ EFI_STATUS Status;
+
+ //
+ // Find the right instance of the FVB private data
+ //
+ Status = GetFvbInstance (Instance, Global, &FwhInstance, Virtual);
+ ASSERT_EFI_ERROR (Status);
+ *Attributes = FwhInstance->VolumeHeader.Attributes;
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+FvbGetLbaAddress (
+ IN UINTN Instance,
+ IN EFI_LBA Lba,
+ OUT UINTN *LbaAddress,
+ OUT UINTN *LbaLength,
+ OUT UINTN *NumOfBlocks,
+ IN ESAL_FWB_GLOBAL *Global,
+ IN BOOLEAN Virtual
+ )
+/*++
+
+Routine Description:
+ Retrieves the starting address of an LBA in an FV
+
+Arguments:
+ Instance - The FV instance which the Lba belongs to
+ Lba - The logical block address
+ LbaAddress - On output, contains the physical starting address
+ of the Lba
+ LbaLength - On output, contains the length of the block
+ NumOfBlocks - A pointer to a caller allocated UINTN in which the
+ number of consecutive blocks starting with Lba is
+ returned. All blocks in this range have a size of
+ BlockSize
+ Global - Pointer to ESAL_FWB_GLOBAL that contains all
+ instance data
+ Virtual - Whether CPU is in virtual or physical mode
+
+Returns:
+ EFI_SUCCESS - Successfully returns
+ EFI_INVALID_PARAMETER - Instance not found
+
+--*/
+{
+ UINT32 NumBlocks;
+ UINT32 BlockLength;
+ UINTN Offset;
+ EFI_LBA StartLba;
+ EFI_LBA NextLba;
+ EFI_FW_VOL_INSTANCE *FwhInstance;
+ EFI_FV_BLOCK_MAP_ENTRY *BlockMap;
+ EFI_STATUS Status;
+
+ //
+ // Find the right instance of the FVB private data
+ //
+ Status = GetFvbInstance (Instance, Global, &FwhInstance, Virtual);
+ ASSERT_EFI_ERROR (Status);
+
+ StartLba = 0;
+ Offset = 0;
+ BlockMap = &(FwhInstance->VolumeHeader.BlockMap[0]);
+
+ //
+ // Parse the blockmap of the FV to find which map entry the Lba belongs to
+ //
+ while (TRUE) {
+ NumBlocks = BlockMap->NumBlocks;
+ BlockLength = BlockMap->Length;
+
+ if (NumBlocks == 0 || BlockLength == 0) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ NextLba = StartLba + NumBlocks;
+
+ //
+ // The map entry found
+ //
+ if (Lba >= StartLba && Lba < NextLba) {
+ Offset = Offset + (UINTN) MultU64x32 ((Lba - StartLba), BlockLength);
+ if (LbaAddress != NULL) {
+ *LbaAddress = FwhInstance->FvBase[Virtual] + Offset;
+ }
+
+ if (LbaLength != NULL) {
+ *LbaLength = BlockLength;
+ }
+
+ if (NumOfBlocks != NULL) {
+ *NumOfBlocks = (UINTN) (NextLba - Lba);
+ }
+
+ return EFI_SUCCESS;
+ }
+
+ StartLba = NextLba;
+ Offset = Offset + NumBlocks * BlockLength;
+ BlockMap++;
+ }
+}
+
+EFI_STATUS
+FvbSetVolumeAttributes (
+ IN UINTN Instance,
+ IN OUT EFI_FVB_ATTRIBUTES_2 *Attributes,
+ IN ESAL_FWB_GLOBAL *Global,
+ IN BOOLEAN Virtual
+ )
+/*++
+
+Routine Description:
+ Modifies the current settings of the firmware volume according to the
+ input parameter, and returns the new setting of the volume
+
+Arguments:
+ Instance - The FV instance whose attributes is going to be
+ modified
+ Attributes - On input, it is a pointer to EFI_FVB_ATTRIBUTES_2
+ containing the desired firmware volume settings.
+ On successful return, it contains the new settings
+ of the firmware volume
+ Global - Pointer to ESAL_FWB_GLOBAL that contains all
+ instance data
+ Virtual - Whether CPU is in virtual or physical mode
+
+Returns:
+ EFI_SUCCESS - Successfully returns
+ EFI_ACCESS_DENIED - The volume setting is locked and cannot be modified
+ EFI_INVALID_PARAMETER - Instance not found, or The attributes requested are
+ in conflict with the capabilities as declared in the
+ firmware volume header
+
+--*/
+{
+ EFI_FW_VOL_INSTANCE *FwhInstance;
+ EFI_FVB_ATTRIBUTES_2 OldAttributes;
+ EFI_FVB_ATTRIBUTES_2 *AttribPtr;
+ UINT32 Capabilities;
+ UINT32 OldStatus;
+ UINT32 NewStatus;
+ EFI_STATUS Status;
+ EFI_FVB_ATTRIBUTES_2 UnchangedAttributes;
+
+ //
+ // Find the right instance of the FVB private data
+ //
+ Status = GetFvbInstance (Instance, Global, &FwhInstance, Virtual);
+ ASSERT_EFI_ERROR (Status);
+
+ AttribPtr = (EFI_FVB_ATTRIBUTES_2 *) &(FwhInstance->VolumeHeader.Attributes);
+ OldAttributes = *AttribPtr;
+ Capabilities = OldAttributes & (EFI_FVB2_READ_DISABLED_CAP | \
+ EFI_FVB2_READ_ENABLED_CAP | \
+ EFI_FVB2_WRITE_DISABLED_CAP | \
+ EFI_FVB2_WRITE_ENABLED_CAP | \
+ EFI_FVB2_LOCK_CAP \
+ );
+ OldStatus = OldAttributes & EFI_FVB2_STATUS;
+ NewStatus = *Attributes & EFI_FVB2_STATUS;
+
+ UnchangedAttributes = EFI_FVB2_READ_DISABLED_CAP | \
+ EFI_FVB2_READ_ENABLED_CAP | \
+ EFI_FVB2_WRITE_DISABLED_CAP | \
+ EFI_FVB2_WRITE_ENABLED_CAP | \
+ EFI_FVB2_LOCK_CAP | \
+ EFI_FVB2_STICKY_WRITE | \
+ EFI_FVB2_MEMORY_MAPPED | \
+ EFI_FVB2_ERASE_POLARITY | \
+ EFI_FVB2_READ_LOCK_CAP | \
+ EFI_FVB2_WRITE_LOCK_CAP | \
+ EFI_FVB2_ALIGNMENT;
+
+ //
+ // Some attributes of FV is read only can *not* be set
+ //
+ if ((OldAttributes & UnchangedAttributes) ^ (*Attributes & UnchangedAttributes)) {
+ return EFI_INVALID_PARAMETER;
+ }
+ //
+ // If firmware volume is locked, no status bit can be updated
+ //
+ if (OldAttributes & EFI_FVB2_LOCK_STATUS) {
+ if (OldStatus ^ NewStatus) {
+ return EFI_ACCESS_DENIED;
+ }
+ }
+ //
+ // Test read disable
+ //
+ if ((Capabilities & EFI_FVB2_READ_DISABLED_CAP) == 0) {
+ if ((NewStatus & EFI_FVB2_READ_STATUS) == 0) {
+ return EFI_INVALID_PARAMETER;
+ }
+ }
+ //
+ // Test read enable
+ //
+ if ((Capabilities & EFI_FVB2_READ_ENABLED_CAP) == 0) {
+ if (NewStatus & EFI_FVB2_READ_STATUS) {
+ return EFI_INVALID_PARAMETER;
+ }
+ }
+ //
+ // Test write disable
+ //
+ if ((Capabilities & EFI_FVB2_WRITE_DISABLED_CAP) == 0) {
+ if ((NewStatus & EFI_FVB2_WRITE_STATUS) == 0) {
+ return EFI_INVALID_PARAMETER;
+ }
+ }
+ //
+ // Test write enable
+ //
+ if ((Capabilities & EFI_FVB2_WRITE_ENABLED_CAP) == 0) {
+ if (NewStatus & EFI_FVB2_WRITE_STATUS) {
+ return EFI_INVALID_PARAMETER;
+ }
+ }
+ //
+ // Test lock
+ //
+ if ((Capabilities & EFI_FVB2_LOCK_CAP) == 0) {
+ if (NewStatus & EFI_FVB2_LOCK_STATUS) {
+ return EFI_INVALID_PARAMETER;
+ }
+ }
+
+ *AttribPtr = (*AttribPtr) & (0xFFFFFFFF & (~EFI_FVB2_STATUS));
+ *AttribPtr = (*AttribPtr) | NewStatus;
+ *Attributes = *AttribPtr;
+
+ return EFI_SUCCESS;
+}
+
+//
+// FVB protocol APIs
+//
+EFI_STATUS
+EFIAPI
+FvbProtocolGetPhysicalAddress (
+ IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This,
+ OUT EFI_PHYSICAL_ADDRESS *Address
+ )
+/*++
+
+Routine Description:
+
+ Retrieves the physical address of the device.
+
+Arguments:
+
+ This - Calling context
+ Address - Output buffer containing the address.
+
+Returns:
+
+Returns:
+ EFI_SUCCESS - Successfully returns
+
+--*/
+{
+ EFI_FW_VOL_BLOCK_DEVICE *FvbDevice;
+
+ FvbDevice = FVB_DEVICE_FROM_THIS (This);
+
+ return FvbGetPhysicalAddress (FvbDevice->Instance, Address, mFvbModuleGlobal, EfiGoneVirtual ());
+}
+
+EFI_STATUS
+EFIAPI
+FvbProtocolGetBlockSize (
+ IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This,
+ IN CONST EFI_LBA Lba,
+ OUT UINTN *BlockSize,
+ OUT UINTN *NumOfBlocks
+ )
+/*++
+
+Routine Description:
+ Retrieve the size of a logical block
+
+Arguments:
+ This - Calling context
+ Lba - Indicates which block to return the size for.
+ BlockSize - A pointer to a caller allocated UINTN in which
+ the size of the block is returned
+ NumOfBlocks - a pointer to a caller allocated UINTN in which the
+ number of consecutive blocks starting with Lba is
+ returned. All blocks in this range have a size of
+ BlockSize
+
+Returns:
+ EFI_SUCCESS - The firmware volume was read successfully and
+ contents are in Buffer
+
+--*/
+{
+ EFI_FW_VOL_BLOCK_DEVICE *FvbDevice;
+
+ FvbDevice = FVB_DEVICE_FROM_THIS (This);
+
+ return FvbGetLbaAddress (
+ FvbDevice->Instance,
+ Lba,
+ NULL,
+ BlockSize,
+ NumOfBlocks,
+ mFvbModuleGlobal,
+ EfiGoneVirtual ()
+ );
+}
+
+EFI_STATUS
+EFIAPI
+FvbProtocolGetAttributes (
+ IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This,
+ OUT EFI_FVB_ATTRIBUTES_2 *Attributes
+ )
+/*++
+
+Routine Description:
+ Retrieves Volume attributes. No polarity translations are done.
+
+Arguments:
+ This - Calling context
+ Attributes - output buffer which contains attributes
+
+Returns:
+ EFI_SUCCESS - Successfully returns
+
+--*/
+{
+ EFI_FW_VOL_BLOCK_DEVICE *FvbDevice;
+
+ FvbDevice = FVB_DEVICE_FROM_THIS (This);
+
+ return FvbGetVolumeAttributes (FvbDevice->Instance, Attributes, mFvbModuleGlobal, EfiGoneVirtual ());
+}
+
+EFI_STATUS
+EFIAPI
+FvbProtocolSetAttributes (
+ IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This,
+ IN OUT EFI_FVB_ATTRIBUTES_2 *Attributes
+ )
+/*++
+
+Routine Description:
+ Sets Volume attributes. No polarity translations are done.
+
+Arguments:
+ This - Calling context
+ Attributes - output buffer which contains attributes
+
+Returns:
+ EFI_SUCCESS - Successfully returns
+
+--*/
+{
+ EFI_FW_VOL_BLOCK_DEVICE *FvbDevice;
+
+ FvbDevice = FVB_DEVICE_FROM_THIS (This);
+
+ return FvbSetVolumeAttributes (FvbDevice->Instance, Attributes, mFvbModuleGlobal, EfiGoneVirtual ());
+}
+
+EFI_STATUS
+EFIAPI
+FvbProtocolEraseBlocks (
+ IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This,
+ ...
+ )
+/*++
+
+Routine Description:
+
+ The EraseBlock() function erases one or more blocks as denoted by the
+ variable argument list. The entire parameter list of blocks must be verified
+ prior to erasing any blocks. If a block is requested that does not exist
+ within the associated firmware volume (it has a larger index than the last
+ block of the firmware volume), the EraseBlock() function must return
+ EFI_INVALID_PARAMETER without modifying the contents of the firmware volume.
+
+Arguments:
+ This - Calling context
+ ... - Starting LBA followed by Number of Lba to erase.
+ a -1 to terminate the list.
+
+Returns:
+ EFI_SUCCESS - The erase request was successfully completed
+ EFI_ACCESS_DENIED - The firmware volume is in the WriteDisabled state
+ EFI_DEVICE_ERROR - The block device is not functioning correctly and
+ could not be written. Firmware device may have been
+ partially erased
+
+--*/
+{
+ EFI_FW_VOL_BLOCK_DEVICE *FvbDevice;
+ EFI_FW_VOL_INSTANCE *FwhInstance;
+ UINTN NumOfBlocks;
+ VA_LIST args;
+ EFI_LBA StartingLba;
+ UINTN NumOfLba;
+ EFI_STATUS Status;
+
+ FvbDevice = FVB_DEVICE_FROM_THIS (This);
+
+ Status = GetFvbInstance (FvbDevice->Instance, mFvbModuleGlobal, &FwhInstance, EfiGoneVirtual ());
+ ASSERT_EFI_ERROR (Status);
+
+ NumOfBlocks = FwhInstance->NumOfBlocks;
+
+ VA_START (args, This);
+
+ do {
+ StartingLba = VA_ARG (args, EFI_LBA);
+ if (StartingLba == EFI_LBA_LIST_TERMINATOR) {
+ break;
+ }
+
+ NumOfLba = VA_ARG (args, UINT32);
+
+ //
+ // Check input parameters
+ //
+ if ((NumOfLba == 0) || ((StartingLba + NumOfLba) > NumOfBlocks)) {
+ VA_END (args);
+ return EFI_INVALID_PARAMETER;
+ }
+ } while (1);
+
+ VA_END (args);
+
+ VA_START (args, This);
+ do {
+ StartingLba = VA_ARG (args, EFI_LBA);
+ if (StartingLba == EFI_LBA_LIST_TERMINATOR) {
+ break;
+ }
+
+ NumOfLba = VA_ARG (args, UINT32);
+
+ while (NumOfLba > 0) {
+ Status = QemuFlashEraseBlock (StartingLba);
+ if (EFI_ERROR (Status)) {
+ VA_END (args);
+ return Status;
+ }
+
+ StartingLba++;
+ NumOfLba--;
+ }
+
+ } while (1);
+
+ VA_END (args);
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+FvbProtocolWrite (
+ IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This,
+ IN EFI_LBA Lba,
+ IN UINTN Offset,
+ IN OUT UINTN *NumBytes,
+ IN UINT8 *Buffer
+ )
+/*++
+
+Routine Description:
+
+ Writes data beginning at Lba:Offset from FV. The write terminates either
+ when *NumBytes of data have been written, or when a block boundary is
+ reached. *NumBytes is updated to reflect the actual number of bytes
+ written. The write opertion does not include erase. This routine will
+ attempt to write only the specified bytes. If the writes do not stick,
+ it will return an error.
+
+Arguments:
+ This - Calling context
+ Lba - Block in which to begin write
+ Offset - Offset in the block at which to begin write
+ NumBytes - On input, indicates the requested write size. On
+ output, indicates the actual number of bytes written
+ Buffer - Buffer containing source data for the write.
+
+Returns:
+ EFI_SUCCESS - The firmware volume was written successfully
+ EFI_BAD_BUFFER_SIZE - Write attempted across a LBA boundary. On output,
+ NumBytes contains the total number of bytes
+ actually written
+ EFI_ACCESS_DENIED - The firmware volume is in the WriteDisabled state
+ EFI_DEVICE_ERROR - The block device is not functioning correctly and
+ could not be written
+ EFI_INVALID_PARAMETER - NumBytes or Buffer are NULL
+
+--*/
+{
+ return QemuFlashWrite ((EFI_LBA)Lba, (UINTN)Offset, NumBytes, (UINT8 *)Buffer);
+}
+
+EFI_STATUS
+EFIAPI
+FvbProtocolRead (
+ IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This,
+ IN CONST EFI_LBA Lba,
+ IN CONST UINTN Offset,
+ IN OUT UINTN *NumBytes,
+ IN UINT8 *Buffer
+ )
+/*++
+
+Routine Description:
+
+ Reads data beginning at Lba:Offset from FV. The Read terminates either
+ when *NumBytes of data have been read, or when a block boundary is
+ reached. *NumBytes is updated to reflect the actual number of bytes
+ written. The write opertion does not include erase. This routine will
+ attempt to write only the specified bytes. If the writes do not stick,
+ it will return an error.
+
+Arguments:
+ This - Calling context
+ Lba - Block in which to begin Read
+ Offset - Offset in the block at which to begin Read
+ NumBytes - On input, indicates the requested write size. On
+ output, indicates the actual number of bytes Read
+ Buffer - Buffer containing source data for the Read.
+
+Returns:
+ EFI_SUCCESS - The firmware volume was read successfully and
+ contents are in Buffer
+ EFI_BAD_BUFFER_SIZE - Read attempted across a LBA boundary. On output,
+ NumBytes contains the total number of bytes returned
+ in Buffer
+ EFI_ACCESS_DENIED - The firmware volume is in the ReadDisabled state
+ EFI_DEVICE_ERROR - The block device is not functioning correctly and
+ could not be read
+ EFI_INVALID_PARAMETER - NumBytes or Buffer are NULL
+
+--*/
+{
+ return QemuFlashRead ((EFI_LBA)Lba, (UINTN)Offset, NumBytes, (UINT8 *)Buffer);
+}
+
+EFI_STATUS
+ValidateFvHeader (
+ EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader
+ )
+/*++
+
+Routine Description:
+ Check the integrity of firmware volume header
+
+Arguments:
+ FwVolHeader - A pointer to a firmware volume header
+
+Returns:
+ EFI_SUCCESS - The firmware volume is consistent
+ EFI_NOT_FOUND - The firmware volume has corrupted. So it is not an FV
+
+--*/
+{
+ UINT16 Checksum;
+
+ //
+ // Verify the header revision, header signature, length
+ // Length of FvBlock cannot be 2**64-1
+ // HeaderLength cannot be an odd number
+ //
+ if ((FwVolHeader->Revision != EFI_FVH_REVISION) ||
+ (FwVolHeader->Signature != EFI_FVH_SIGNATURE) ||
+ (FwVolHeader->FvLength == ((UINTN) -1)) ||
+ ((FwVolHeader->HeaderLength & 0x01) != 0)
+ ) {
+ return EFI_NOT_FOUND;
+ }
+
+ //
+ // Verify the header checksum
+ //
+
+ Checksum = CalculateSum16 ((UINT16 *) FwVolHeader, FwVolHeader->HeaderLength);
+ if (Checksum != 0) {
+ UINT16 Expected;
+
+ Expected = ((UINTN) FwVolHeader->Checksum + 0x10000 - Checksum) & 0xffff;
+
+ DEBUG ((EFI_D_INFO, "FV@%p Checksum is 0x%x, expected 0x%x\n",
+ FwVolHeader, FwVolHeader->Checksum, Expected));
+ return EFI_NOT_FOUND;
+ }
+
+ return EFI_SUCCESS;
+}
+
+STATIC
+EFI_STATUS
+MarkMemoryRangeForRuntimeAccess (
+ EFI_PHYSICAL_ADDRESS BaseAddress,
+ UINT64 Length
+ )
+{
+ EFI_STATUS Status;
+
+ //
+ // Mark flash region as runtime memory
+ //
+ Status = gDS->RemoveMemorySpace (
+ BaseAddress,
+ Length
+ );
+
+ Status = gDS->AddMemorySpace (
+ EfiGcdMemoryTypeSystemMemory,
+ BaseAddress,
+ Length,
+ EFI_MEMORY_UC | EFI_MEMORY_RUNTIME
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ Status = gBS->AllocatePages (
+ AllocateAddress,
+ EfiRuntimeServicesData,
+ (UINTN) EFI_SIZE_TO_PAGES (Length),
+ &BaseAddress
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ return Status;
+}
+
+STATIC
+EFI_STATUS
+InitializeVariableFvHeader (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+ EFI_FIRMWARE_VOLUME_HEADER *GoodFwVolHeader;
+ EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader;
+ UINTN Length;
+ UINTN WriteLength;
+ UINTN BlockSize;
+
+ FwVolHeader =
+ (EFI_FIRMWARE_VOLUME_HEADER *) (UINTN)
+ PcdGet32 (PcdOvmfFlashNvStorageVariableBase);
+
+ Length =
+ (FixedPcdGet32 (PcdFlashNvStorageVariableSize) +
+ FixedPcdGet32 (PcdFlashNvStorageFtwWorkingSize) +
+ FixedPcdGet32 (PcdFlashNvStorageFtwSpareSize) +
+ FixedPcdGet32 (PcdOvmfFlashNvStorageEventLogSize));
+
+ BlockSize = PcdGet32 (PcdOvmfFirmwareBlockSize);
+
+ Status = ValidateFvHeader (FwVolHeader);
+ if (!EFI_ERROR (Status)) {
+ if (FwVolHeader->FvLength != Length ||
+ FwVolHeader->BlockMap[0].Length != BlockSize) {
+ Status = EFI_VOLUME_CORRUPTED;
+ }
+ }
+ if (EFI_ERROR (Status)) {
+ UINTN Offset;
+ UINTN Start;
+
+ DEBUG ((EFI_D_INFO, "Variable FV header is not valid. It will be reinitialized.\n"));
+
+ //
+ // Get FvbInfo to provide in FwhInstance.
+ //
+ Status = GetFvbInfo (Length, &GoodFwVolHeader);
+ ASSERT (!EFI_ERROR (Status));
+
+ Start = (UINTN)(UINT8*) FwVolHeader - PcdGet32 (PcdOvmfFdBaseAddress);
+ ASSERT (Start % BlockSize == 0 && Length % BlockSize == 0);
+ ASSERT (GoodFwVolHeader->HeaderLength <= BlockSize);
+
+ //
+ // Erase all the blocks
+ //
+ for (Offset = Start; Offset < Start + Length; Offset += BlockSize) {
+ Status = QemuFlashEraseBlock ((EFI_LBA) Offset / BlockSize);
+ ASSERT_EFI_ERROR (Status);
+ }
+
+ //
+ // Write good FV header
+ //
+ WriteLength = GoodFwVolHeader->HeaderLength;
+ Status = QemuFlashWrite (
+ (EFI_LBA) Start / BlockSize,
+ 0,
+ &WriteLength,
+ (UINT8 *) GoodFwVolHeader);
+ ASSERT_EFI_ERROR (Status);
+ ASSERT (WriteLength == GoodFwVolHeader->HeaderLength);
+ }
+
+ return Status;
+}
+
+EFI_STATUS
+EFIAPI
+FvbInitialize (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+/*++
+
+Routine Description:
+ This function does common initialization for FVB services
+
+Arguments:
+
+Returns:
+
+--*/
+{
+ EFI_STATUS Status;
+ EFI_FW_VOL_INSTANCE *FwhInstance;
+ EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader;
+ UINT32 BufferSize;
+ EFI_FV_BLOCK_MAP_ENTRY *PtrBlockMapEntry;
+ EFI_HANDLE FwbHandle;
+ EFI_FW_VOL_BLOCK_DEVICE *FvbDevice;
+ EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *OldFwbInterface;
+ UINT32 MaxLbaSize;
+ EFI_PHYSICAL_ADDRESS BaseAddress;
+ UINT64 Length;
+ UINTN NumOfBlocks;
+ EFI_EVENT VirtualAddressChangeEvent;
+
+ if (EFI_ERROR (QemuFlashInitialize ())) {
+ //
+ // Return an error so image will be unloaded
+ //
+ DEBUG ((EFI_D_INFO, "QEMU flash was not detected. Writable FVB is not being installed.\n"));
+ return EFI_WRITE_PROTECTED;
+ }
+
+ //
+ // Allocate runtime services data for global variable, which contains
+ // the private data of all firmware volume block instances
+ //
+ mFvbModuleGlobal = AllocateRuntimePool (sizeof (ESAL_FWB_GLOBAL));
+ ASSERT (mFvbModuleGlobal != NULL);
+
+ BaseAddress = (UINTN) PcdGet32 (PcdOvmfFdBaseAddress);
+ Length = PcdGet32 (PcdOvmfFirmwareFdSize);
+
+ Status = InitializeVariableFvHeader ();
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_INFO, "QEMU Flash: Unable to initialize variable FV header\n"));
+ return EFI_WRITE_PROTECTED;
+ }
+
+ FwVolHeader = (EFI_FIRMWARE_VOLUME_HEADER *) (UINTN) BaseAddress;
+ Status = ValidateFvHeader (FwVolHeader);
+ if (EFI_ERROR (Status)) {
+ //
+ // Get FvbInfo
+ //
+ Status = GetFvbInfo (Length, &FwVolHeader);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_INFO, "EFI_ERROR (GetFvbInfo (Length, &FwVolHeader))\n"));
+ return EFI_WRITE_PROTECTED;
+ }
+ }
+
+ BufferSize = (sizeof (EFI_FW_VOL_INSTANCE) + FwVolHeader->HeaderLength - sizeof (EFI_FIRMWARE_VOLUME_HEADER));
+
+ //
+ // Only need to allocate once. There is only one copy of physical memory for
+ // the private data of each FV instance. But in virtual mode or in physical
+ // mode, the address of the the physical memory may be different.
+ //
+ mFvbModuleGlobal->FvInstance[FVB_PHYSICAL] = AllocateRuntimePool (BufferSize);
+ ASSERT (mFvbModuleGlobal->FvInstance[FVB_PHYSICAL] != NULL);
+
+ //
+ // Make a virtual copy of the FvInstance pointer.
+ //
+ FwhInstance = mFvbModuleGlobal->FvInstance[FVB_PHYSICAL];
+ mFvbModuleGlobal->FvInstance[FVB_VIRTUAL] = FwhInstance;
+
+ mFvbModuleGlobal->NumFv = 0;
+ MaxLbaSize = 0;
+
+ FwVolHeader =
+ (EFI_FIRMWARE_VOLUME_HEADER *) (UINTN)
+ PcdGet32 (PcdOvmfFlashNvStorageVariableBase);
+
+ FwhInstance->FvBase[FVB_PHYSICAL] = (UINTN) BaseAddress;
+ FwhInstance->FvBase[FVB_VIRTUAL] = (UINTN) BaseAddress;
+
+ CopyMem ((UINTN *) &(FwhInstance->VolumeHeader), (UINTN *) FwVolHeader, FwVolHeader->HeaderLength);
+ FwVolHeader = &(FwhInstance->VolumeHeader);
+ EfiInitializeLock (&(FwhInstance->FvbDevLock), TPL_HIGH_LEVEL);
+
+ NumOfBlocks = 0;
+
+ for (PtrBlockMapEntry = FwVolHeader->BlockMap; PtrBlockMapEntry->NumBlocks != 0; PtrBlockMapEntry++) {
+ //
+ // Get the maximum size of a block.
+ //
+ if (MaxLbaSize < PtrBlockMapEntry->Length) {
+ MaxLbaSize = PtrBlockMapEntry->Length;
+ }
+
+ NumOfBlocks = NumOfBlocks + PtrBlockMapEntry->NumBlocks;
+ }
+
+ //
+ // The total number of blocks in the FV.
+ //
+ FwhInstance->NumOfBlocks = NumOfBlocks;
+
+ //
+ // Add a FVB Protocol Instance
+ //
+ FvbDevice = AllocateRuntimePool (sizeof (EFI_FW_VOL_BLOCK_DEVICE));
+ ASSERT (FvbDevice != NULL);
+
+ CopyMem (FvbDevice, &mFvbDeviceTemplate, sizeof (EFI_FW_VOL_BLOCK_DEVICE));
+
+ FvbDevice->Instance = mFvbModuleGlobal->NumFv;
+ mFvbModuleGlobal->NumFv++;
+
+ //
+ // Set up the devicepath
+ //
+ if (FwVolHeader->ExtHeaderOffset == 0) {
+ //
+ // FV does not contains extension header, then produce MEMMAP_DEVICE_PATH
+ //
+ FvbDevice->DevicePath = (EFI_DEVICE_PATH_PROTOCOL *) AllocateCopyPool (sizeof (FV_MEMMAP_DEVICE_PATH), &mFvMemmapDevicePathTemplate);
+ ((FV_MEMMAP_DEVICE_PATH *) FvbDevice->DevicePath)->MemMapDevPath.StartingAddress = BaseAddress;
+ ((FV_MEMMAP_DEVICE_PATH *) FvbDevice->DevicePath)->MemMapDevPath.EndingAddress = BaseAddress + FwVolHeader->FvLength - 1;
+ } else {
+ FvbDevice->DevicePath = (EFI_DEVICE_PATH_PROTOCOL *) AllocateCopyPool (sizeof (FV_PIWG_DEVICE_PATH), &mFvPIWGDevicePathTemplate);
+ CopyGuid (
+ &((FV_PIWG_DEVICE_PATH *)FvbDevice->DevicePath)->FvDevPath.FvName,
+ (GUID *)(UINTN)(BaseAddress + FwVolHeader->ExtHeaderOffset)
+ );
+ }
+
+ //
+ // Find a handle with a matching device path that has supports FW Block protocol
+ //
+ Status = gBS->LocateDevicePath (&gEfiFirmwareVolumeBlockProtocolGuid, &FvbDevice->DevicePath, &FwbHandle);
+ if (EFI_ERROR (Status)) {
+ //
+ // LocateDevicePath fails so install a new interface and device path
+ //
+ FwbHandle = NULL;
+ DEBUG ((EFI_D_INFO, "Installing QEMU flash FVB\n"));
+ Status = gBS->InstallMultipleProtocolInterfaces (
+ &FwbHandle,
+ &gEfiFirmwareVolumeBlockProtocolGuid,
+ &FvbDevice->FwVolBlockInstance,
+ &gEfiDevicePathProtocolGuid,
+ FvbDevice->DevicePath,
+ NULL
+ );
+ ASSERT_EFI_ERROR (Status);
+ } else if (IsDevicePathEnd (FvbDevice->DevicePath)) {
+ //
+ // Device already exists, so reinstall the FVB protocol
+ //
+ Status = gBS->HandleProtocol (
+ FwbHandle,
+ &gEfiFirmwareVolumeBlockProtocolGuid,
+ (VOID**)&OldFwbInterface
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ DEBUG ((EFI_D_INFO, "Reinstalling FVB for QEMU flash region\n"));
+ Status = gBS->ReinstallProtocolInterface (
+ FwbHandle,
+ &gEfiFirmwareVolumeBlockProtocolGuid,
+ OldFwbInterface,
+ &FvbDevice->FwVolBlockInstance
+ );
+ ASSERT_EFI_ERROR (Status);
+ } else {
+ //
+ // There was a FVB protocol on an End Device Path node
+ //
+ ASSERT (FALSE);
+ }
+
+ MarkMemoryRangeForRuntimeAccess (BaseAddress, Length);
+
+ //
+ // Set several PCD values to point to flash
+ //
+ PcdSet64 (
+ PcdFlashNvStorageVariableBase64,
+ (UINTN) PcdGet32 (PcdOvmfFlashNvStorageVariableBase)
+ );
+ PcdSet32 (
+ PcdFlashNvStorageFtwWorkingBase,
+ PcdGet32 (PcdOvmfFlashNvStorageFtwWorkingBase)
+ );
+ PcdSet32 (
+ PcdFlashNvStorageFtwSpareBase,
+ PcdGet32 (PcdOvmfFlashNvStorageFtwSpareBase)
+ );
+
+ FwhInstance = (EFI_FW_VOL_INSTANCE *)
+ (
+ (UINTN) ((UINT8 *) FwhInstance) + FwVolHeader->HeaderLength +
+ (sizeof (EFI_FW_VOL_INSTANCE) - sizeof (EFI_FIRMWARE_VOLUME_HEADER))
+ );
+
+ VirtualAddressChangeEvent = NULL;
+ Status = gBS->CreateEventEx (
+ EVT_NOTIFY_SIGNAL,
+ TPL_NOTIFY,
+ FvbVirtualddressChangeEvent,
+ NULL,
+ &gEfiEventVirtualAddressChangeGuid,
+ &VirtualAddressChangeEvent
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ PcdSetBool (PcdOvmfFlashVariablesEnable, TRUE);
+ return EFI_SUCCESS;
+}
diff --git a/OvmfPkg/QemuFlashFvbServicesRuntimeDxe/FwBlockService.h b/OvmfPkg/QemuFlashFvbServicesRuntimeDxe/FwBlockService.h
new file mode 100644
index 000000000..06a092d90
--- /dev/null
+++ b/OvmfPkg/QemuFlashFvbServicesRuntimeDxe/FwBlockService.h
@@ -0,0 +1,184 @@
+/**@file
+
+Copyright (c) 2006, 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.
+
+Module Name:
+
+ FwBlockService.h
+
+Abstract:
+
+ Firmware volume block driver for Intel Firmware Hub (FWH) device
+
+**/
+
+#ifndef _FW_BLOCK_SERVICE_H
+#define _FW_BLOCK_SERVICE_H
+
+//
+// BugBug: Add documentation here for data structure!!!!
+//
+#define FVB_PHYSICAL 0
+#define FVB_VIRTUAL 1
+
+typedef struct {
+ EFI_LOCK FvbDevLock;
+ UINTN FvBase[2];
+ UINTN NumOfBlocks;
+ EFI_FIRMWARE_VOLUME_HEADER VolumeHeader;
+} EFI_FW_VOL_INSTANCE;
+
+typedef struct {
+ UINT32 NumFv;
+ EFI_FW_VOL_INSTANCE *FvInstance[2];
+ UINT8 *FvbScratchSpace[2];
+} ESAL_FWB_GLOBAL;
+
+//
+// Fvb Protocol instance data
+//
+#define FVB_DEVICE_FROM_THIS(a) CR (a, EFI_FW_VOL_BLOCK_DEVICE, FwVolBlockInstance, FVB_DEVICE_SIGNATURE)
+#define FVB_EXTEND_DEVICE_FROM_THIS(a) CR (a, EFI_FW_VOL_BLOCK_DEVICE, FvbExtension, FVB_DEVICE_SIGNATURE)
+#define FVB_DEVICE_SIGNATURE SIGNATURE_32 ('F', 'V', 'B', 'N')
+
+typedef struct {
+ MEDIA_FW_VOL_DEVICE_PATH FvDevPath;
+ EFI_DEVICE_PATH_PROTOCOL EndDevPath;
+} FV_PIWG_DEVICE_PATH;
+
+typedef struct {
+ MEMMAP_DEVICE_PATH MemMapDevPath;
+ EFI_DEVICE_PATH_PROTOCOL EndDevPath;
+} FV_MEMMAP_DEVICE_PATH;
+
+typedef struct {
+ UINTN Signature;
+ EFI_DEVICE_PATH_PROTOCOL *DevicePath;
+ UINTN Instance;
+ EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL FwVolBlockInstance;
+} EFI_FW_VOL_BLOCK_DEVICE;
+
+EFI_STATUS
+GetFvbInfo (
+ IN UINT64 FvLength,
+ OUT EFI_FIRMWARE_VOLUME_HEADER **FvbInfo
+ );
+
+EFI_STATUS
+FvbSetVolumeAttributes (
+ IN UINTN Instance,
+ IN OUT EFI_FVB_ATTRIBUTES_2 *Attributes,
+ IN ESAL_FWB_GLOBAL *Global,
+ IN BOOLEAN Virtual
+ );
+
+EFI_STATUS
+FvbGetVolumeAttributes (
+ IN UINTN Instance,
+ OUT EFI_FVB_ATTRIBUTES_2 *Attributes,
+ IN ESAL_FWB_GLOBAL *Global,
+ IN BOOLEAN Virtual
+ );
+
+EFI_STATUS
+FvbGetPhysicalAddress (
+ IN UINTN Instance,
+ OUT EFI_PHYSICAL_ADDRESS *Address,
+ IN ESAL_FWB_GLOBAL *Global,
+ IN BOOLEAN Virtual
+ );
+
+EFI_STATUS
+EFIAPI
+FvbInitialize (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ );
+
+
+VOID
+EFIAPI
+FvbClassAddressChangeEvent (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ );
+
+EFI_STATUS
+FvbGetLbaAddress (
+ IN UINTN Instance,
+ IN EFI_LBA Lba,
+ OUT UINTN *LbaAddress,
+ OUT UINTN *LbaLength,
+ OUT UINTN *NumOfBlocks,
+ IN ESAL_FWB_GLOBAL *Global,
+ IN BOOLEAN Virtual
+ );
+
+//
+// Protocol APIs
+//
+EFI_STATUS
+EFIAPI
+FvbProtocolGetAttributes (
+ IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This,
+ OUT EFI_FVB_ATTRIBUTES_2 *Attributes
+ );
+
+EFI_STATUS
+EFIAPI
+FvbProtocolSetAttributes (
+ IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This,
+ IN OUT EFI_FVB_ATTRIBUTES_2 *Attributes
+ );
+
+EFI_STATUS
+EFIAPI
+FvbProtocolGetPhysicalAddress (
+ IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This,
+ OUT EFI_PHYSICAL_ADDRESS *Address
+ );
+
+EFI_STATUS
+EFIAPI
+FvbProtocolGetBlockSize (
+ IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This,
+ IN CONST EFI_LBA Lba,
+ OUT UINTN *BlockSize,
+ OUT UINTN *NumOfBlocks
+ );
+
+EFI_STATUS
+EFIAPI
+FvbProtocolRead (
+ IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This,
+ IN CONST EFI_LBA Lba,
+ IN CONST UINTN Offset,
+ IN OUT UINTN *NumBytes,
+ IN UINT8 *Buffer
+ );
+
+EFI_STATUS
+EFIAPI
+FvbProtocolWrite (
+ IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This,
+ IN EFI_LBA Lba,
+ IN UINTN Offset,
+ IN OUT UINTN *NumBytes,
+ IN UINT8 *Buffer
+ );
+
+EFI_STATUS
+EFIAPI
+FvbProtocolEraseBlocks (
+ IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This,
+ ...
+ );
+
+#endif
diff --git a/OvmfPkg/QemuFlashFvbServicesRuntimeDxe/QemuFlash.c b/OvmfPkg/QemuFlashFvbServicesRuntimeDxe/QemuFlash.c
new file mode 100644
index 000000000..a3fe7d874
--- /dev/null
+++ b/OvmfPkg/QemuFlashFvbServicesRuntimeDxe/QemuFlash.c
@@ -0,0 +1,265 @@
+/** @file
+ OVMF support for QEMU system firmware flash device
+
+ Copyright (c) 2009 - 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 "PiDxe.h"
+#include <Library/DebugLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/PcdLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiRuntimeLib.h>
+#include <Guid/EventGroup.h>
+
+#include "QemuFlash.h"
+
+#define WRITE_BYTE_CMD 0x10
+#define BLOCK_ERASE_CMD 0x20
+#define CLEAR_STATUS_CMD 0x50
+#define READ_STATUS_CMD 0x70
+#define READ_DEVID_CMD 0x90
+#define BLOCK_ERASE_CONFIRM_CMD 0xd0
+#define READ_ARRAY_CMD 0xff
+
+#define CLEARED_ARRAY_STATUS 0x00
+
+
+STATIC UINT8 *mFlashBase = NULL;
+STATIC UINTN mFdBlockSize = 0;
+STATIC UINTN mFdBlockCount = 0;
+
+
+VOID
+QemuFlashConvertPointers (
+ VOID
+ )
+{
+ EfiConvertPointer (0x0, (VOID **) &mFlashBase);
+}
+
+
+STATIC
+volatile UINT8*
+QemuFlashPtr (
+ IN EFI_LBA Lba,
+ IN UINTN Offset
+ )
+{
+ return mFlashBase + (Lba * mFdBlockSize) + Offset;
+}
+
+
+/**
+ Determines if the QEMU flash memory device is present.
+
+ @retval FALSE The QEMU flash device is not present.
+ @retval TRUE The QEMU flash device is present.
+
+**/
+STATIC
+BOOLEAN
+QemuFlashDetected (
+ VOID
+ )
+{
+ BOOLEAN FlashDetected;
+ volatile UINT8 *Ptr;
+
+ UINTN Offset;
+ UINT8 OriginalUint8;
+ UINT8 ProbeUint8;
+
+ FlashDetected = FALSE;
+ Ptr = QemuFlashPtr (0, 0);
+
+ for (Offset = 0; Offset < mFdBlockSize; Offset++) {
+ Ptr = QemuFlashPtr (0, Offset);
+ ProbeUint8 = *Ptr;
+ if (ProbeUint8 != CLEAR_STATUS_CMD &&
+ ProbeUint8 != READ_STATUS_CMD &&
+ ProbeUint8 != CLEARED_ARRAY_STATUS) {
+ break;
+ }
+ }
+
+ if (Offset >= mFdBlockSize) {
+ DEBUG ((EFI_D_INFO, "QEMU Flash: Failed to find probe location\n"));
+ return FALSE;
+ }
+
+ DEBUG ((EFI_D_INFO, "QEMU Flash: Attempting flash detection at %p\n", Ptr));
+
+ OriginalUint8 = *Ptr;
+ *Ptr = CLEAR_STATUS_CMD;
+ ProbeUint8 = *Ptr;
+ if (OriginalUint8 != CLEAR_STATUS_CMD &&
+ ProbeUint8 == CLEAR_STATUS_CMD) {
+ DEBUG ((EFI_D_INFO, "QemuFlashDetected => FD behaves as RAM\n"));
+ *Ptr = OriginalUint8;
+ } else {
+ *Ptr = READ_STATUS_CMD;
+ ProbeUint8 = *Ptr;
+ if (ProbeUint8 == OriginalUint8) {
+ DEBUG ((EFI_D_INFO, "QemuFlashDetected => FD behaves as ROM\n"));
+ } else if (ProbeUint8 == READ_STATUS_CMD) {
+ DEBUG ((EFI_D_INFO, "QemuFlashDetected => FD behaves as RAM\n"));
+ *Ptr = OriginalUint8;
+ } else if (ProbeUint8 == CLEARED_ARRAY_STATUS) {
+ DEBUG ((EFI_D_INFO, "QemuFlashDetected => FD behaves as FLASH\n"));
+ FlashDetected = TRUE;
+ *Ptr = READ_ARRAY_CMD;
+ }
+ }
+
+ DEBUG ((EFI_D_INFO, "QemuFlashDetected => %a\n",
+ FlashDetected ? "Yes" : "No"));
+ return FlashDetected;
+}
+
+
+/**
+ Read from QEMU Flash
+
+ @param[in] Lba The starting logical block index to read from.
+ @param[in] Offset Offset into the block at which to begin reading.
+ @param[in] NumBytes On input, indicates the requested read size. On
+ output, indicates the actual number of bytes read
+ @param[in] Buffer Pointer to the buffer to read into.
+
+**/
+EFI_STATUS
+QemuFlashRead (
+ IN EFI_LBA Lba,
+ IN UINTN Offset,
+ IN UINTN *NumBytes,
+ IN UINT8 *Buffer
+ )
+{
+ UINT8 *Ptr;
+
+ //
+ // Only write to the first 64k. We don't bother saving the FTW Spare
+ // block into the flash memory.
+ //
+ if (Lba >= mFdBlockCount) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // Get flash address
+ //
+ Ptr = (UINT8*) QemuFlashPtr (Lba, Offset);
+
+ CopyMem (Buffer, Ptr, *NumBytes);
+
+ return EFI_SUCCESS;
+}
+
+
+/**
+ Write to QEMU Flash
+
+ @param[in] Lba The starting logical block index to write to.
+ @param[in] Offset Offset into the block at which to begin writing.
+ @param[in] NumBytes On input, indicates the requested write size. On
+ output, indicates the actual number of bytes written
+ @param[in] Buffer Pointer to the data to write.
+
+**/
+EFI_STATUS
+QemuFlashWrite (
+ IN EFI_LBA Lba,
+ IN UINTN Offset,
+ IN UINTN *NumBytes,
+ IN UINT8 *Buffer
+ )
+{
+ volatile UINT8 *Ptr;
+ UINTN Loop;
+
+ //
+ // Only write to the first 64k. We don't bother saving the FTW Spare
+ // block into the flash memory.
+ //
+ if (Lba >= mFdBlockCount) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // Program flash
+ //
+ Ptr = QemuFlashPtr (Lba, Offset);
+ for (Loop = 0; Loop < *NumBytes; Loop++) {
+ *Ptr = WRITE_BYTE_CMD;
+ *Ptr = Buffer[Loop];
+ Ptr++;
+ }
+
+ //
+ // Restore flash to read mode
+ //
+ if (*NumBytes > 0) {
+ *Ptr = READ_ARRAY_CMD;
+ }
+
+ return EFI_SUCCESS;
+}
+
+
+/**
+ Erase a QEMU Flash block
+
+ @param Lba The logical block index to erase.
+
+**/
+EFI_STATUS
+QemuFlashEraseBlock (
+ IN EFI_LBA Lba
+ )
+{
+ volatile UINT8 *Ptr;
+
+ if (Lba >= mFdBlockCount) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Ptr = QemuFlashPtr (Lba, 0);
+ *Ptr = BLOCK_ERASE_CMD;
+ *Ptr = BLOCK_ERASE_CONFIRM_CMD;
+ return EFI_SUCCESS;
+}
+
+
+/**
+ Initializes QEMU flash memory support
+
+ @retval EFI_WRITE_PROTECTED The QEMU flash device is not present.
+ @retval EFI_SUCCESS The QEMU flash device is supported.
+
+**/
+EFI_STATUS
+QemuFlashInitialize (
+ VOID
+ )
+{
+ mFlashBase = (UINT8*)(UINTN) PcdGet32 (PcdOvmfFdBaseAddress);
+ mFdBlockSize = PcdGet32 (PcdOvmfFirmwareBlockSize);
+ ASSERT(PcdGet32 (PcdOvmfFirmwareFdSize) % mFdBlockSize == 0);
+ mFdBlockCount = PcdGet32 (PcdOvmfFirmwareFdSize) / mFdBlockSize;
+
+ if (!QemuFlashDetected ()) {
+ return EFI_WRITE_PROTECTED;
+ }
+
+ return EFI_SUCCESS;
+}
+
diff --git a/OvmfPkg/QemuFlashFvbServicesRuntimeDxe/QemuFlash.h b/OvmfPkg/QemuFlashFvbServicesRuntimeDxe/QemuFlash.h
new file mode 100644
index 000000000..f77e88078
--- /dev/null
+++ b/OvmfPkg/QemuFlashFvbServicesRuntimeDxe/QemuFlash.h
@@ -0,0 +1,89 @@
+/** @file
+ OVMF support for QEMU system firmware flash device
+
+ Copyright (c) 2009 - 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 __QEMU_FLASH_H__
+#define __QEMU_FLASH_H__
+
+#include <Protocol/FirmwareVolumeBlock.h>
+
+/**
+ Read from QEMU Flash
+
+ @param[in] Lba The starting logical block index to read from.
+ @param[in] Offset Offset into the block at which to begin reading.
+ @param[in] NumBytes On input, indicates the requested read size. On
+ output, indicates the actual number of bytes read
+ @param[in] Buffer Pointer to the buffer to read into.
+
+**/
+EFI_STATUS
+QemuFlashRead (
+ IN EFI_LBA Lba,
+ IN UINTN Offset,
+ IN UINTN *NumBytes,
+ IN UINT8 *Buffer
+ );
+
+
+/**
+ Write to QEMU Flash
+
+ @param[in] Lba The starting logical block index to write to.
+ @param[in] Offset Offset into the block at which to begin writing.
+ @param[in] NumBytes On input, indicates the requested write size. On
+ output, indicates the actual number of bytes written
+ @param[in] Buffer Pointer to the data to write.
+
+**/
+EFI_STATUS
+QemuFlashWrite (
+ IN EFI_LBA Lba,
+ IN UINTN Offset,
+ IN UINTN *NumBytes,
+ IN UINT8 *Buffer
+ );
+
+
+/**
+ Erase a QEMU Flash block
+
+ @param Lba The logical block index to erase.
+
+**/
+EFI_STATUS
+QemuFlashEraseBlock (
+ IN EFI_LBA Lba
+ );
+
+
+/**
+ Initializes QEMU flash memory support
+
+ @retval EFI_WRITE_PROTECTED The QEMU flash device is not present.
+ @retval EFI_SUCCESS The QEMU flash device is supported.
+
+**/
+EFI_STATUS
+QemuFlashInitialize (
+ VOID
+ );
+
+
+VOID
+QemuFlashConvertPointers (
+ VOID
+ );
+
+#endif
+
diff --git a/OvmfPkg/QemuVideoDxe/Driver.c b/OvmfPkg/QemuVideoDxe/Driver.c
index 1dd8899fc..53718e1ae 100644
--- a/OvmfPkg/QemuVideoDxe/Driver.c
+++ b/OvmfPkg/QemuVideoDxe/Driver.c
@@ -305,6 +305,10 @@ QemuVideoControllerDriverStart (
DEBUG ((EFI_D_INFO, "QemuVideo: Using mmio bar @ 0x%lx\n",
MmioDesc->AddrRangeMin));
}
+
+ if (!EFI_ERROR (Status)) {
+ FreePool (MmioDesc);
+ }
}
//
diff --git a/OvmfPkg/QemuVideoDxe/Gop.c b/OvmfPkg/QemuVideoDxe/Gop.c
index 1d2402cde..30aac7f95 100644
--- a/OvmfPkg/QemuVideoDxe/Gop.c
+++ b/OvmfPkg/QemuVideoDxe/Gop.c
@@ -72,6 +72,7 @@ QemuVideoCompleteModeData (
Mode->FrameBufferSize = Mode->FrameBufferSize * ((ModeData->ColorDepth + 7) / 8);
DEBUG ((EFI_D_INFO, "FrameBufferBase: 0x%x, FrameBufferSize: 0x%x\n", Mode->FrameBufferBase, Mode->FrameBufferSize));
+ FreePool (FrameBufDesc);
return EFI_SUCCESS;
}
diff --git a/OvmfPkg/README b/OvmfPkg/README
index 213d8648d..f2c2fc799 100644
--- a/OvmfPkg/README
+++ b/OvmfPkg/README
@@ -179,6 +179,43 @@ longer.)
VirtioNetDxe | x
Intel PROEFI | x
+=== OVMF Flash Layout ===
+
+Like all current IA32/X64 system designs, OVMF's firmware
+device (rom/flash) appears in QEMU's physical address space
+just below 4GB (0x100000000).
+
+The layout of the firmware device in memory looks like:
+
++--------------------------------------- 4GB (0x100000000)
+| VTF0 (16-bit reset code) and OVMF SEC
+| (SECFV)
++--------------------------------------- varies based on flash size
+|
+| Compressed main firmware image
+| (FVMAIN_COMPACT)
+|
++--------------------------------------- base + 0x20000
+| Fault-tolerant write (FTW)
+| Spare blocks (64KB/0x10000)
++--------------------------------------- base + 0x10000
+| FTW Work block (4KB/0x1000)
++--------------------------------------- base + 0x0f000
+| Event log area (4KB/0x1000)
++--------------------------------------- base + 0x0e000
+| Non-volatile variable storage
+| area (56KB/0xe000)
++--------------------------------------- base address
+
+OVMF supports building a 1MB or a 2MB flash image. The base address for
+a 1MB image in QEMU physical memory is 0xfff00000. The base address for
+a 2MB image is 0xffe00000.
+
+The code in SECFV locates FVMAIN_COMPACT, and decompresses the
+main firmware (MAINFV) into RAM memory at address 0x800000. The
+remaining OVMF firmware then uses this decompressed firmware
+volume image.
+
=== UNIXGCC Debug ===
If you build with the UNIXGCC toolchain, then debugging will be disabled
diff --git a/OvmfPkg/build.sh b/OvmfPkg/build.sh
index f64ea9159..f3eb97c1d 100755
--- a/OvmfPkg/build.sh
+++ b/OvmfPkg/build.sh
@@ -48,6 +48,7 @@ PLATFORMFILE=
THREADNUMBER=1
LAST_ARG=
RUN_QEMU=no
+ENABLE_FLASH=no
#
# Pick a default tool type for a given OS
@@ -106,6 +107,9 @@ do
shift
break
;;
+ --enable-flash)
+ ENABLE_FLASH=yes
+ ;;
*)
BUILD_OPTIONS="$BUILD_OPTIONS $arg"
;;
@@ -139,7 +143,12 @@ done
case $PROCESSOR in
IA32)
Processor=Ia32
- if [ -x `which qemu-system-i386` ]; then
+ if [ -n "$QEMU_COMMAND" ]; then
+ #
+ # The user set the QEMU_COMMAND variable. We'll use it to run QEMU.
+ #
+ :
+ elif [ -x `which qemu-system-i386` ]; then
QEMU_COMMAND=qemu-system-i386
elif [ -x `which qemu-system-x86_64` ]; then
QEMU_COMMAND=qemu-system-x86_64
@@ -152,7 +161,12 @@ case $PROCESSOR in
;;
X64)
Processor=X64
- QEMU_COMMAND=qemu-system-x86_64
+ if [ -z "$QEMU_COMMAND" ]; then
+ #
+ # The user didn't set the QEMU_COMMAND variable.
+ #
+ QEMU_COMMAND=qemu-system-x86_64
+ fi
;;
*)
echo Unsupported processor architecture: $PROCESSOR
@@ -165,16 +179,25 @@ if [ -z "$PLATFORMFILE" ]; then
PLATFORMFILE=$WORKSPACE/OvmfPkg/OvmfPkg$Processor.dsc
fi
-ADD_QEMU_HDA=yes
-for arg in "$@"
-do
- case $arg in
- -hd[a-d]|-fd[ab]|-cdrom)
- ADD_QEMU_HDA=no
- break
+if [[ "$RUN_QEMU" == "yes" ]]; then
+ qemu_version=$($QEMU_COMMAND -version 2>&1 | tail -1 | awk '{print $4}')
+ case $qemu_version in
+ 1.[6-9].*|1.[1-9][0-9].*|2.*.*)
+ ENABLE_FLASH=yes
;;
esac
-done
+
+ ADD_QEMU_HDA=yes
+ for arg in "$@"
+ do
+ case $arg in
+ -hd[a-d]|-fd[ab]|-cdrom)
+ ADD_QEMU_HDA=no
+ break
+ ;;
+ esac
+ done
+fi
#
# Uncomment this block for parameter parsing debug
@@ -212,12 +235,15 @@ if [[ "$RUN_QEMU" == "yes" ]]; then
mkdir $QEMU_FIRMWARE_DIR
fi
ln -sf $FV_DIR/OVMF.fd $QEMU_FIRMWARE_DIR/bios.bin
- if [[ "$ADD_QEMU_HDA" == "yes" ]]; then
- AUTO_QEMU_HDA="-hda fat:$BUILD_ROOT_ARCH"
+ if [[ "$ENABLE_FLASH" == "yes" ]]; then
+ QEMU_COMMAND="$QEMU_COMMAND -pflash $QEMU_FIRMWARE_DIR/bios.bin"
else
- AUTO_QEMU_HDA=
+ QEMU_COMMAND="$QEMU_COMMAND -L $QEMU_FIRMWARE_DIR"
+ fi
+ if [[ "$ADD_QEMU_HDA" == "yes" ]]; then
+ QEMU_COMMAND="$QEMU_COMMAND -hda fat:$BUILD_ROOT_ARCH"
fi
- QEMU_COMMAND="$QEMU_COMMAND -L $QEMU_FIRMWARE_DIR $AUTO_QEMU_HDA $*"
+ QEMU_COMMAND="$QEMU_COMMAND $*"
echo Running: $QEMU_COMMAND
$QEMU_COMMAND
exit $?
diff --git a/SecurityPkg/Application/RngTest/RngTest.c b/SecurityPkg/Application/RngTest/RngTest.c
new file mode 100644
index 000000000..f501f806e
--- /dev/null
+++ b/SecurityPkg/Application/RngTest/RngTest.c
@@ -0,0 +1,234 @@
+/** @file
+ UEFI RNG (Random Number Generator) Protocol test application.
+
+Copyright (c) 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 <Uefi.h>
+#include <Library/UefiLib.h>
+#include <Library/UefiApplicationEntryPoint.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/DebugLib.h>
+#include <Protocol/Rng.h>
+
+/**
+ The user Entry Point for Application. The user code starts with this function
+ as the real entry point for the application.
+
+ @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
+UefiMain (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+ EFI_RNG_PROTOCOL *Rng;
+ UINTN RngAlgListSize;
+ EFI_RNG_ALGORITHM RngAlgList[10];
+ EFI_RNG_ALGORITHM *PtrRngAlg;
+ UINTN RngAlgCount;
+ UINT8 *Rand;
+ UINTN RandSize;
+ UINTN Index;
+ UINTN Index2;
+
+ Status = EFI_SUCCESS;
+ PtrRngAlg = NULL;
+ Rand = NULL;
+
+ Print (L"UEFI RNG Protocol Testing :\n");
+ Print (L"----------------------------\n");
+
+ //-----------------------------------------
+ // Basic UEFI RNG Protocol Test
+ //-----------------------------------------
+ Print (L" -- Locate UEFI RNG Protocol : ");
+ Status = gBS->LocateProtocol (&gEfiRngProtocolGuid, NULL, (VOID **)&Rng);
+ if (EFI_ERROR (Status)) {
+ Print (L"[Fail - Status = %r]\n", Status);
+ goto Exit;
+ } else {
+ Print (L"[Pass]\n");
+ }
+
+ //-----------------------------------------
+ // Rng->GetInfo() interface test.
+ //-----------------------------------------
+
+ Print (L" -- Call RNG->GetInfo() interface : ");
+ RngAlgListSize = 0;
+ Status = Rng->GetInfo (Rng, &RngAlgListSize, NULL);
+ if (Status != EFI_BUFFER_TOO_SMALL) {
+ Print (L"[Fail - Status = %r]\n", Status);
+ }
+ //
+ // Print out the supported RNG algorithm GUIDs
+ //
+ RngAlgCount = RngAlgListSize / sizeof (EFI_RNG_ALGORITHM);
+ Print (L"\n >> Supported RNG Algorithm (Count = %d) : ", RngAlgCount);
+ Status = Rng->GetInfo (Rng, &RngAlgListSize, RngAlgList);
+ for (Index = 0; Index < RngAlgCount; Index++) {
+ PtrRngAlg = (EFI_RNG_ALGORITHM *)(&RngAlgList[Index]);
+ Print (L"\n %d) ", Index);
+ Print (L"%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x", PtrRngAlg->Data1,
+ PtrRngAlg->Data2, PtrRngAlg->Data3, PtrRngAlg->Data4[0], PtrRngAlg->Data4[1],
+ PtrRngAlg->Data4[2], PtrRngAlg->Data4[3], PtrRngAlg->Data4[4],
+ PtrRngAlg->Data4[5], PtrRngAlg->Data4[6], PtrRngAlg->Data4[7]);
+ }
+
+ //-----------------------------------------
+ // Rng->GetRNG() interface test.
+ //-----------------------------------------
+ Print (L"\n -- Call RNG->GetRNG() interface : ");
+
+ //
+ // Allocate one buffer to store random data.
+ //
+ RandSize = 32;
+ Rand = AllocatePool (RandSize);
+ if (Rand == NULL) {
+ goto Exit;
+ }
+
+ //
+ // RNG with default algorithm
+ //
+ Print (L"\n >> RNG with default algorithm : ");
+ Status = Rng->GetRNG (Rng, NULL, RandSize, Rand);
+ if (EFI_ERROR (Status)) {
+ Print (L"[Fail - Status = %r]", Status);
+ } else {
+ Print (L"[Pass]");
+ }
+
+ //
+ // RNG with SP800-90-HMAC-256
+ //
+ Print (L"\n >> RNG with SP800-90-HMAC-256 : ");
+ Status = Rng->GetRNG (Rng, &gEfiRngAlgorithmSp80090Hmac256Guid, RandSize, Rand);
+ if (EFI_ERROR (Status)) {
+ Print (L"[Fail - Status = %r]", Status);
+ } else {
+ Print (L"[Pass]");
+ }
+
+ //
+ // RNG with SP800-90-HASH-256
+ //
+ Print (L"\n >> RNG with SP800-90-Hash-256 : ");
+ Status = Rng->GetRNG (Rng, &gEfiRngAlgorithmSp80090Hash256Guid, RandSize, Rand);
+ if (EFI_ERROR (Status)) {
+ Print (L"[Fail - Status = %r]", Status);
+ } else {
+ Print (L"[Pass]");
+ }
+
+ //
+ // RNG with SP800-90-CTR-256
+ //
+ Print (L"\n >> RNG with SP800-90-CTR-256 : ");
+ Status = Rng->GetRNG (Rng, &gEfiRngAlgorithmSp80090Ctr256Guid, RandSize, Rand);
+ if (EFI_ERROR (Status)) {
+ Print (L"[Fail - Status = %r]", Status);
+ } else {
+ Print (L"[Pass]");
+ }
+
+ //
+ // RNG with X9.31-3DES
+ //
+ Print (L"\n >> RNG with X9.31-3DES : ");
+ Status = Rng->GetRNG (Rng, &gEfiRngAlgorithmX9313DesGuid, RandSize, Rand);
+ if (EFI_ERROR (Status)) {
+ Print (L"[Fail - Status = %r]", Status);
+ } else {
+ Print (L"[Pass]");
+ }
+
+ //
+ // RNG with X9.31-AES
+ //
+ Print (L"\n >> RNG with X9.31-AES : ");
+ Status = Rng->GetRNG (Rng, &gEfiRngAlgorithmX931AesGuid, RandSize, Rand);
+ if (EFI_ERROR (Status)) {
+ Print (L"[Fail - Status = %r]", Status);
+ } else {
+ Print (L"[Pass]");
+ }
+
+ //
+ // RNG with RAW Entropy
+ //
+ Print (L"\n >> RNG with RAW Entropy : ");
+ Status = Rng->GetRNG (Rng, &gEfiRngAlgorithmRaw, RandSize, Rand);
+ if (EFI_ERROR (Status)) {
+ Print (L"[Fail - Status = %r]", Status);
+ } else {
+ Print (L"[Pass]");
+ }
+
+ //-----------------------------------------
+ // Random Number Generator test.
+ //-----------------------------------------
+ Print (L"\n -- Random Number Generation Test with default RNG Algorithm (20 Rounds): ");
+
+ RandSize = 1;
+ for (Index = 0; Index < 20; Index++) {
+ Status = Rng->GetRNG (Rng, NULL, RandSize, Rand);
+ if (EFI_ERROR (Status)) {
+ Print (L"[Fail - Status = %r]", Status);
+ break;
+ } else {
+ Print (L"\n %02d) - ", Index + 1);
+ for (Index2 = 0; Index2 < RandSize; Index2++) {
+ Print (L"%02x", Rand[Index2]);
+ }
+ }
+
+ RandSize +=1;
+ }
+
+ //-----------------------------------------
+ // Random Number Generator test.
+ //-----------------------------------------
+ Print (L"\n -- RAW Entropy Generation Test (20 Rounds) : ");
+
+ RandSize = 32;
+ for (Index = 0; Index < 20; Index++) {
+ Status = Rng->GetRNG (Rng, &gEfiRngAlgorithmRaw, RandSize, Rand);
+ if (EFI_ERROR (Status)) {
+ Print (L"[Fail - Status = %r]", Status);
+ break;
+ } else {
+ Print (L"\n %02d) - ", Index + 1);
+ for (Index2 = 0; Index2 < RandSize; Index2++) {
+ Print (L"%02x", Rand[Index2]);
+ }
+ }
+ }
+
+ Print (L"\n -- Exit UEFI RNG Protocol Test (Status = %r).\n", Status);
+
+Exit:
+ if (Rand != NULL) {
+ FreePool (Rand);
+ }
+ return Status;
+}
diff --git a/SecurityPkg/Application/RngTest/RngTest.inf b/SecurityPkg/Application/RngTest/RngTest.inf
new file mode 100644
index 000000000..bec78a4c9
--- /dev/null
+++ b/SecurityPkg/Application/RngTest/RngTest.inf
@@ -0,0 +1,50 @@
+## @file
+# UEFI RNG (Random Number Generator) Protocol test application.
+#
+# Copyright (c) 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.
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = RngTest
+ FILE_GUID = B8AC7FB2-4211-4c2b-B62F-504421666C87
+ MODULE_TYPE = UEFI_APPLICATION
+ VERSION_STRING = 1.0
+ ENTRY_POINT = UefiMain
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64
+#
+
+[Sources]
+ RngTest.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ SecurityPkg/SecurityPkg.dec
+
+[LibraryClasses]
+ UefiApplicationEntryPoint
+ UefiLib
+
+[Protocols]
+ gEfiRngProtocolGuid
+
+[Guids]
+ gEfiRngAlgorithmSp80090Hash256Guid
+ gEfiRngAlgorithmSp80090Hmac256Guid
+ gEfiRngAlgorithmSp80090Ctr256Guid
+ gEfiRngAlgorithmX9313DesGuid
+ gEfiRngAlgorithmX931AesGuid
+ gEfiRngAlgorithmRaw \ No newline at end of file
diff --git a/SecurityPkg/Library/DxeDeferImageLoadLib/DxeDeferImageLoadLib.c b/SecurityPkg/Library/DxeDeferImageLoadLib/DxeDeferImageLoadLib.c
index fd18d2f7e..3cbd09836 100644
--- a/SecurityPkg/Library/DxeDeferImageLoadLib/DxeDeferImageLoadLib.c
+++ b/SecurityPkg/Library/DxeDeferImageLoadLib/DxeDeferImageLoadLib.c
@@ -1,7 +1,7 @@
/** @file
Implement defer image load services for user identification in UEFI2.2.
-Copyright (c) 2009 - 2012, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2009 - 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
@@ -263,57 +263,107 @@ GetAccessControl (
return EFI_NOT_FOUND;
}
-
/**
- Convert the '/' to '\' in the specified string.
+ Get file name from device path.
- @param[in, out] Str Points to the string to convert.
+ The file name may contain one or more device path node. Save the file name in a
+ buffer if file name is found. The caller is responsible to free the buffer.
+
+ @param[in] DevicePath A pointer to a device path.
+ @param[out] FileName The callee allocated buffer to save the file name if file name is found.
+ @param[out] FileNameOffset The offset of file name in device path if file name is found.
+
+ @retval UINTN The file name length. 0 means file name is not found.
**/
-VOID
-ConvertDPStr (
- IN OUT EFI_STRING Str
+UINTN
+GetFileName (
+ IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath,
+ OUT UINT8 **FileName,
+ OUT UINTN *FileNameOffset
)
{
- INTN Count;
- INTN Index;
-
- Count = StrSize(Str) / 2 - 1;
+ UINTN Length;
+ EFI_DEVICE_PATH_PROTOCOL *TmpDevicePath;
+ EFI_DEVICE_PATH_PROTOCOL *RootDevicePath;
+ CHAR8 *NodeStr;
+ UINTN NodeStrLength;
+ CHAR16 LastNodeChar;
+ CHAR16 FirstNodeChar;
- if (Count < 4) {
- return;
+ //
+ // Get the length of DevicePath before file name.
+ //
+ Length = 0;
+ RootDevicePath = (EFI_DEVICE_PATH_PROTOCOL *)DevicePath;
+ while (!IsDevicePathEnd (RootDevicePath)) {
+ if ((DevicePathType(RootDevicePath) == MEDIA_DEVICE_PATH) && (DevicePathSubType(RootDevicePath) == MEDIA_FILEPATH_DP)) {
+ break;
+ }
+ Length += DevicePathNodeLength (RootDevicePath);
+ RootDevicePath = NextDevicePathNode (RootDevicePath);
}
-
+
+ *FileNameOffset = Length;
+ if (Length == 0) {
+ return 0;
+ }
+
//
- // Convert device path string.
+ // Get the file name length.
//
- Index = Count - 1;
- while (Index > 0) {
- //
- // Find the last '/'.
- //
- for (Index = Count - 1; Index > 0; Index--) {
- if (Str[Index] == L'/')
- break;
+ Length = 0;
+ TmpDevicePath = RootDevicePath;
+ while (!IsDevicePathEnd (TmpDevicePath)) {
+ if ((DevicePathType(TmpDevicePath) != MEDIA_DEVICE_PATH) || (DevicePathSubType(TmpDevicePath) != MEDIA_FILEPATH_DP)) {
+ break;
}
+ Length += DevicePathNodeLength (TmpDevicePath) - sizeof (EFI_DEVICE_PATH_PROTOCOL);
+ TmpDevicePath = NextDevicePathNode (TmpDevicePath);
+ }
+ if (Length == 0) {
+ return 0;
+ }
- //
- // Check next char.
- //
- if (Str[Index + 1] == L'\\')
- return;
+ *FileName = AllocateZeroPool (Length);
+ ASSERT (*FileName != NULL);
+
+ //
+ // Copy the file name to the buffer.
+ //
+ Length = 0;
+ LastNodeChar = '\\';
+ TmpDevicePath = RootDevicePath;
+ while (!IsDevicePathEnd (TmpDevicePath)) {
+ if ((DevicePathType(TmpDevicePath) != MEDIA_DEVICE_PATH) || (DevicePathSubType(TmpDevicePath) != MEDIA_FILEPATH_DP)) {
+ break;
+ }
+
+ FirstNodeChar = (CHAR16) ReadUnaligned16 ((UINT16 *)((UINT8 *)TmpDevicePath + sizeof (EFI_DEVICE_PATH_PROTOCOL)));
+ NodeStr = (CHAR8 *)TmpDevicePath + sizeof (EFI_DEVICE_PATH_PROTOCOL);
+ NodeStrLength = DevicePathNodeLength (TmpDevicePath) - sizeof (EFI_DEVICE_PATH_PROTOCOL) - sizeof(CHAR16);
- Str[Index] = L'\\';
+ if ((FirstNodeChar == '\\') && (LastNodeChar == '\\')) {
+ //
+ // Skip separator "\" when there are two separators.
+ //
+ NodeStr += sizeof (CHAR16);
+ NodeStrLength -= sizeof (CHAR16);
+ } else if ((FirstNodeChar != '\\') && (LastNodeChar != '\\')) {
+ //
+ // Add separator "\" when there is no separator.
+ //
+ WriteUnaligned16 ((UINT16 *)(*FileName + Length), '\\');
+ Length += sizeof (CHAR16);
+ }
+ CopyMem (*FileName + Length, NodeStr, NodeStrLength);
+ Length += NodeStrLength;
- //
- // Check previous char.
- //
- if ((Index > 0) && (Str[Index - 1] == L'\\')) {
- CopyMem (&Str[Index - 1], &Str[Index], (UINTN) ((Count - Index + 1) * sizeof (CHAR16)));
- return;
- }
- Index--;
- }
+ LastNodeChar = (CHAR16) ReadUnaligned16 ((UINT16 *) (NodeStr + NodeStrLength - sizeof(CHAR16)));
+ TmpDevicePath = NextDevicePathNode (TmpDevicePath);
+ }
+
+ return Length;
}
@@ -342,54 +392,72 @@ CheckDevicePath (
IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath2
)
{
- EFI_STATUS Status;
- EFI_STRING DevicePathStr1;
- EFI_STRING DevicePathStr2;
- UINTN StrLen1;
- UINTN StrLen2;
- EFI_DEVICE_PATH_TO_TEXT_PROTOCOL *DevicePathText;
- BOOLEAN DevicePathEqual;
+ UINTN DevicePathSize;
+ UINTN FileNameSize1;
+ UINTN FileNameSize2;
+ UINT8 *FileName1;
+ UINT8 *FileName2;
+ UINTN FileNameOffset1;
+ UINTN FileNameOffset2;
+ BOOLEAN DevicePathEqual;
+
+ FileName1 = NULL;
+ FileName2 = NULL;
+ DevicePathEqual = TRUE;
ASSERT (DevicePath1 != NULL);
ASSERT (DevicePath2 != NULL);
+ if (IsDevicePathEnd (DevicePath1)) {
+ return FALSE;
+ }
- DevicePathEqual = FALSE;
- DevicePathText = NULL;
- Status = gBS->LocateProtocol (
- &gEfiDevicePathToTextProtocolGuid,
- NULL,
- (VOID **) &DevicePathText
- );
- ASSERT (Status == EFI_SUCCESS);
-
- //
- // Get first device path string.
//
- DevicePathStr1 = DevicePathText->ConvertDevicePathToText (DevicePath1, TRUE, TRUE);
- ConvertDPStr (DevicePathStr1);
+ // The file name may contain one or more device path node.
+ // To compare the file name, copy file name to a buffer and compare the buffer.
//
- // Get second device path string.
- //
- DevicePathStr2 = DevicePathText->ConvertDevicePathToText (DevicePath2, TRUE, TRUE);
- ConvertDPStr (DevicePathStr2);
-
+ FileNameSize1 = GetFileName (DevicePath1, &FileName1, &FileNameOffset1);
+ if (FileNameSize1 != 0) {
+ FileNameSize2 = GetFileName (DevicePath2, &FileName2, &FileNameOffset2);
+ if (FileNameOffset1 != FileNameOffset2) {
+ DevicePathEqual = FALSE;
+ goto Done;
+ }
+ if (CompareMem (DevicePath1, DevicePath2, FileNameOffset1) != 0) {
+ DevicePathEqual = FALSE;
+ goto Done;
+ }
+ if (FileNameSize1 > FileNameSize2) {
+ DevicePathEqual = FALSE;
+ goto Done;
+ }
+ if (CompareMem (FileName1, FileName2, FileNameSize1) != 0) {
+ DevicePathEqual = FALSE;
+ goto Done;
+ }
+ DevicePathEqual = TRUE;
+ goto Done;
+ }
+
+ DevicePathSize = GetDevicePathSize (DevicePath1);
+ if (DevicePathSize > GetDevicePathSize (DevicePath2)) {
+ return FALSE;
+ }
+
//
- // Compare device path string.
+ // Exclude the end of device path node.
//
- StrLen1 = StrSize (DevicePathStr1);
- StrLen2 = StrSize (DevicePathStr2);
- if (StrLen1 > StrLen2) {
+ DevicePathSize -= sizeof (EFI_DEVICE_PATH_PROTOCOL);
+ if (CompareMem (DevicePath1, DevicePath2, DevicePathSize) != 0) {
DevicePathEqual = FALSE;
- goto Done;
- }
+ }
- if (CompareMem (DevicePathStr1, DevicePathStr2, StrLen1) == 0) {
- DevicePathEqual = TRUE;
+Done:
+ if (FileName1 != NULL) {
+ FreePool (FileName1);
+ }
+ if (FileName2 != NULL) {
+ FreePool (FileName2);
}
-
-Done:
- FreePool (DevicePathStr1);
- FreePool (DevicePathStr2);
return DevicePathEqual;
}
diff --git a/SecurityPkg/Library/DxeDeferImageLoadLib/DxeDeferImageLoadLib.h b/SecurityPkg/Library/DxeDeferImageLoadLib/DxeDeferImageLoadLib.h
index 52eb81b79..fd750be51 100644
--- a/SecurityPkg/Library/DxeDeferImageLoadLib/DxeDeferImageLoadLib.h
+++ b/SecurityPkg/Library/DxeDeferImageLoadLib/DxeDeferImageLoadLib.h
@@ -2,7 +2,7 @@
The internal header file includes the common header files, defines
internal structure and functions used by DeferImageLoadLib.
-Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2009 - 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
@@ -34,7 +34,6 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#include <Protocol/DeferredImageLoad.h>
#include <Protocol/UserCredential.h>
#include <Protocol/UserManager.h>
-#include <Protocol/DevicePathToText.h>
#include <Guid/GlobalVariable.h>
diff --git a/SecurityPkg/Library/DxeDeferImageLoadLib/DxeDeferImageLoadLib.inf b/SecurityPkg/Library/DxeDeferImageLoadLib/DxeDeferImageLoadLib.inf
index e16fe8dc0..dcd5c6128 100644
--- a/SecurityPkg/Library/DxeDeferImageLoadLib/DxeDeferImageLoadLib.inf
+++ b/SecurityPkg/Library/DxeDeferImageLoadLib/DxeDeferImageLoadLib.inf
@@ -1,7 +1,7 @@
## @file
# The library instance provides security service of deferring image load.
#
-# Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.<BR>
+# Copyright (c) 2009 - 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
@@ -53,7 +53,6 @@
gEfiSimpleFileSystemProtocolGuid
gEfiUserManagerProtocolGuid
gEfiDeferredImageLoadProtocolGuid
- gEfiDevicePathToTextProtocolGuid
[Guids]
gEfiGlobalVariableGuid
diff --git a/SecurityPkg/Library/DxeImageVerificationLib/DxeImageVerificationLib.c b/SecurityPkg/Library/DxeImageVerificationLib/DxeImageVerificationLib.c
index 8860daeaf..2210c95f5 100644
--- a/SecurityPkg/Library/DxeImageVerificationLib/DxeImageVerificationLib.c
+++ b/SecurityPkg/Library/DxeImageVerificationLib/DxeImageVerificationLib.c
@@ -1108,10 +1108,11 @@ DxeImageVerificationHandler (
}
//
- // The policy QUERY_USER_ON_SECURITY_VIOLATION violates the UEFI spec and has been removed.
+ // The policy QUERY_USER_ON_SECURITY_VIOLATION and ALLOW_EXECUTE_ON_SECURITY_VIOLATION
+ // violates the UEFI spec and has been removed.
//
- ASSERT (Policy != QUERY_USER_ON_SECURITY_VIOLATION);
- if (Policy == QUERY_USER_ON_SECURITY_VIOLATION) {
+ ASSERT (Policy != QUERY_USER_ON_SECURITY_VIOLATION && Policy != ALLOW_EXECUTE_ON_SECURITY_VIOLATION);
+ if (Policy == QUERY_USER_ON_SECURITY_VIOLATION || Policy == ALLOW_EXECUTE_ON_SECURITY_VIOLATION) {
CpuDeadLoop ();
}
diff --git a/SecurityPkg/RandomNumberGenerator/RngDxe/AesCore.c b/SecurityPkg/RandomNumberGenerator/RngDxe/AesCore.c
new file mode 100644
index 000000000..13b424dc2
--- /dev/null
+++ b/SecurityPkg/RandomNumberGenerator/RngDxe/AesCore.c
@@ -0,0 +1,304 @@
+/** @file
+ Core Primitive Implementation of the Advanced Encryption Standard (AES) algorithm.
+ Refer to FIPS PUB 197 ("Advanced Encryption Standard (AES)") for detailed algorithm
+ description of AES.
+
+Copyright (c) 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 "AesCore.h"
+
+//
+// Number of columns (32-bit words) comprising the State.
+// AES_NB is a constant (value = 4) for NIST FIPS-197.
+//
+#define AES_NB 4
+
+//
+// Pre-computed AES Forward Table: AesForwardTable[t] = AES_SBOX[t].[02, 01, 01, 03]
+// AES_SBOX (AES S-box) is defined in sec 5.1.1 of FIPS PUB 197.
+// This is to speed up execution of the cipher by combining SubBytes and
+// ShiftRows with MixColumns steps and transforming them into table lookups.
+//
+GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT32 AesForwardTable[] = {
+ 0xc66363a5, 0xf87c7c84, 0xee777799, 0xf67b7b8d, 0xfff2f20d, 0xd66b6bbd,
+ 0xde6f6fb1, 0x91c5c554, 0x60303050, 0x02010103, 0xce6767a9, 0x562b2b7d,
+ 0xe7fefe19, 0xb5d7d762, 0x4dababe6, 0xec76769a, 0x8fcaca45, 0x1f82829d,
+ 0x89c9c940, 0xfa7d7d87, 0xeffafa15, 0xb25959eb, 0x8e4747c9, 0xfbf0f00b,
+ 0x41adadec, 0xb3d4d467, 0x5fa2a2fd, 0x45afafea, 0x239c9cbf, 0x53a4a4f7,
+ 0xe4727296, 0x9bc0c05b, 0x75b7b7c2, 0xe1fdfd1c, 0x3d9393ae, 0x4c26266a,
+ 0x6c36365a, 0x7e3f3f41, 0xf5f7f702, 0x83cccc4f, 0x6834345c, 0x51a5a5f4,
+ 0xd1e5e534, 0xf9f1f108, 0xe2717193, 0xabd8d873, 0x62313153, 0x2a15153f,
+ 0x0804040c, 0x95c7c752, 0x46232365, 0x9dc3c35e, 0x30181828, 0x379696a1,
+ 0x0a05050f, 0x2f9a9ab5, 0x0e070709, 0x24121236, 0x1b80809b, 0xdfe2e23d,
+ 0xcdebeb26, 0x4e272769, 0x7fb2b2cd, 0xea75759f, 0x1209091b, 0x1d83839e,
+ 0x582c2c74, 0x341a1a2e, 0x361b1b2d, 0xdc6e6eb2, 0xb45a5aee, 0x5ba0a0fb,
+ 0xa45252f6, 0x763b3b4d, 0xb7d6d661, 0x7db3b3ce, 0x5229297b, 0xdde3e33e,
+ 0x5e2f2f71, 0x13848497, 0xa65353f5, 0xb9d1d168, 0x00000000, 0xc1eded2c,
+ 0x40202060, 0xe3fcfc1f, 0x79b1b1c8, 0xb65b5bed, 0xd46a6abe, 0x8dcbcb46,
+ 0x67bebed9, 0x7239394b, 0x944a4ade, 0x984c4cd4, 0xb05858e8, 0x85cfcf4a,
+ 0xbbd0d06b, 0xc5efef2a, 0x4faaaae5, 0xedfbfb16, 0x864343c5, 0x9a4d4dd7,
+ 0x66333355, 0x11858594, 0x8a4545cf, 0xe9f9f910, 0x04020206, 0xfe7f7f81,
+ 0xa05050f0, 0x783c3c44, 0x259f9fba, 0x4ba8a8e3, 0xa25151f3, 0x5da3a3fe,
+ 0x804040c0, 0x058f8f8a, 0x3f9292ad, 0x219d9dbc, 0x70383848, 0xf1f5f504,
+ 0x63bcbcdf, 0x77b6b6c1, 0xafdada75, 0x42212163, 0x20101030, 0xe5ffff1a,
+ 0xfdf3f30e, 0xbfd2d26d, 0x81cdcd4c, 0x180c0c14, 0x26131335, 0xc3ecec2f,
+ 0xbe5f5fe1, 0x359797a2, 0x884444cc, 0x2e171739, 0x93c4c457, 0x55a7a7f2,
+ 0xfc7e7e82, 0x7a3d3d47, 0xc86464ac, 0xba5d5de7, 0x3219192b, 0xe6737395,
+ 0xc06060a0, 0x19818198, 0x9e4f4fd1, 0xa3dcdc7f, 0x44222266, 0x542a2a7e,
+ 0x3b9090ab, 0x0b888883, 0x8c4646ca, 0xc7eeee29, 0x6bb8b8d3, 0x2814143c,
+ 0xa7dede79, 0xbc5e5ee2, 0x160b0b1d, 0xaddbdb76, 0xdbe0e03b, 0x64323256,
+ 0x743a3a4e, 0x140a0a1e, 0x924949db, 0x0c06060a, 0x4824246c, 0xb85c5ce4,
+ 0x9fc2c25d, 0xbdd3d36e, 0x43acacef, 0xc46262a6, 0x399191a8, 0x319595a4,
+ 0xd3e4e437, 0xf279798b, 0xd5e7e732, 0x8bc8c843, 0x6e373759, 0xda6d6db7,
+ 0x018d8d8c, 0xb1d5d564, 0x9c4e4ed2, 0x49a9a9e0, 0xd86c6cb4, 0xac5656fa,
+ 0xf3f4f407, 0xcfeaea25, 0xca6565af, 0xf47a7a8e, 0x47aeaee9, 0x10080818,
+ 0x6fbabad5, 0xf0787888, 0x4a25256f, 0x5c2e2e72, 0x381c1c24, 0x57a6a6f1,
+ 0x73b4b4c7, 0x97c6c651, 0xcbe8e823, 0xa1dddd7c, 0xe874749c, 0x3e1f1f21,
+ 0x964b4bdd, 0x61bdbddc, 0x0d8b8b86, 0x0f8a8a85, 0xe0707090, 0x7c3e3e42,
+ 0x71b5b5c4, 0xcc6666aa, 0x904848d8, 0x06030305, 0xf7f6f601, 0x1c0e0e12,
+ 0xc26161a3, 0x6a35355f, 0xae5757f9, 0x69b9b9d0, 0x17868691, 0x99c1c158,
+ 0x3a1d1d27, 0x279e9eb9, 0xd9e1e138, 0xebf8f813, 0x2b9898b3, 0x22111133,
+ 0xd26969bb, 0xa9d9d970, 0x078e8e89, 0x339494a7, 0x2d9b9bb6, 0x3c1e1e22,
+ 0x15878792, 0xc9e9e920, 0x87cece49, 0xaa5555ff, 0x50282878, 0xa5dfdf7a,
+ 0x038c8c8f, 0x59a1a1f8, 0x09898980, 0x1a0d0d17, 0x65bfbfda, 0xd7e6e631,
+ 0x844242c6, 0xd06868b8, 0x824141c3, 0x299999b0, 0x5a2d2d77, 0x1e0f0f11,
+ 0x7bb0b0cb, 0xa85454fc, 0x6dbbbbd6, 0x2c16163a
+};
+
+//
+// Round constant word array used in AES key expansion.
+//
+GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT32 Rcon[] = {
+ 0x01000000, 0x02000000, 0x04000000, 0x08000000, 0x10000000,
+ 0x20000000, 0x40000000, 0x80000000, 0x1B000000, 0x36000000
+};
+
+//
+// Rotates x right n bits (circular right shift operation)
+//
+#define ROTATE_RIGHT32(x, n) (((x) >> (n)) | ((x) << (32-(n))))
+
+//
+// Loading & Storing 32-bit words in big-endian format: y[3..0] --> x; x --> y[3..0];
+//
+#define LOAD32H(x, y) { x = ((UINT32)((y)[0] & 0xFF) << 24) | ((UINT32)((y)[1] & 0xFF) << 16) | \
+ ((UINT32)((y)[2] & 0xFF) << 8) | ((UINT32)((y)[3] & 0xFF)); }
+#define STORE32H(x, y) { (y)[0] = (UINT8)(((x) >> 24) & 0xFF); (y)[1] = (UINT8)(((x) >> 16) & 0xFF); \
+ (y)[2] = (UINT8)(((x) >> 8) & 0xFF); (y)[3] = (UINT8)((x) & 0xFF); }
+
+//
+// Wrap macros for AES forward tables lookups
+//
+#define AES_FT0(x) AesForwardTable[x]
+#define AES_FT1(x) ROTATE_RIGHT32(AesForwardTable[x], 8)
+#define AES_FT2(x) ROTATE_RIGHT32(AesForwardTable[x], 16)
+#define AES_FT3(x) ROTATE_RIGHT32(AesForwardTable[x], 24)
+
+///
+/// AES Key Schedule which is expanded from symmetric key [Size 60 = 4 * ((Max AES Round, 14) + 1)].
+///
+typedef struct {
+ UINTN Nk; // Number of Cipher Key (in 32-bit words);
+ UINT32 EncKey[60]; // Expanded AES encryption key
+ UINT32 DecKey[60]; // Expanded AES decryption key (Not used here)
+} AES_KEY;
+
+/**
+ AES Key Expansion.
+ This function expands the cipher key into encryption schedule.
+
+ @param[in] Key AES symmetric key buffer.
+ @param[in] KeyLenInBits Key length in bits (128, 192, or 256).
+ @param[out] AesKey Expanded AES Key schedule for encryption.
+
+ @retval EFI_SUCCESS AES key expansion succeeded.
+ @retval EFI_INVALID_PARAMETER Unsupported key length.
+
+**/
+EFI_STATUS
+EFIAPI
+AesExpandKey (
+ IN UINT8 *Key,
+ IN UINTN KeyLenInBits,
+ OUT AES_KEY *AesKey
+ )
+{
+ UINTN Nk;
+ UINTN Nr;
+ UINTN Nw;
+ UINTN Index1;
+ UINTN Index2;
+ UINTN Index3;
+ UINT32 *Ek;
+ UINT32 Temp;
+
+ //
+ // Nk - Number of 32-bit words comprising the cipher key. (Nk = 4, 6 or 8)
+ // Nr - Number of rounds. (Nr = 10, 12, or 14), which is dependent on the key size.
+ //
+ Nk = KeyLenInBits >> 5;
+ if (Nk != 4 && Nk != 6 && Nk != 8) {
+ return EFI_INVALID_PARAMETER;
+ }
+ Nr = Nk + 6;
+ Nw = AES_NB * (Nr + 1); // Key Expansion generates a total of Nb * (Nr + 1) words
+ AesKey->Nk = Nk;
+
+ //
+ // Load initial symmetric AES key;
+ // Note that AES was designed on big-endian systems.
+ //
+ Ek = AesKey->EncKey;
+ for (Index1 = Index2 = 0; Index1 < Nk; Index1++, Index2 += 4) {
+ LOAD32H (Ek[Index1], Key + Index2);
+ }
+
+ //
+ // Initialize the encryption key scheduler
+ //
+ for (Index2 = Nk, Index3 = 0; Index2 < Nw; Index2 += Nk, Index3++) {
+ Temp = Ek[Index2 - 1];
+ Ek[Index2] = Ek[Index2 - Nk] ^ (AES_FT2((Temp >> 16) & 0xFF) & 0xFF000000) ^
+ (AES_FT3((Temp >> 8) & 0xFF) & 0x00FF0000) ^
+ (AES_FT0((Temp) & 0xFF) & 0x0000FF00) ^
+ (AES_FT1((Temp >> 24) & 0xFF) & 0x000000FF) ^
+ Rcon[Index3];
+ if (Nk <= 6) {
+ //
+ // If AES Cipher Key is 128 or 192 bits
+ //
+ for (Index1 = 1; Index1 < Nk && (Index1 + Index2) < Nw; Index1++) {
+ Ek [Index1 + Index2] = Ek [Index1 + Index2 - Nk] ^ Ek[Index1 + Index2 - 1];
+ }
+ } else {
+ //
+ // Different routine for key expansion If Cipher Key is 256 bits,
+ //
+ for (Index1 = 1; Index1 < 4 && (Index1 + Index2) < Nw; Index1++) {
+ Ek [Index1 + Index2] = Ek[Index1 + Index2 - Nk] ^ Ek[Index1 + Index2 - 1];
+ }
+ if (Index2 + 4 < Nw) {
+ Temp = Ek[Index2 + 3];
+ Ek[Index2 + 4] = Ek[Index2 + 4 - Nk] ^ (AES_FT2((Temp >> 24) & 0xFF) & 0xFF000000) ^
+ (AES_FT3((Temp >> 16) & 0xFF) & 0x00FF0000) ^
+ (AES_FT0((Temp >> 8) & 0xFF) & 0x0000FF00) ^
+ (AES_FT1((Temp) & 0xFF) & 0x000000FF);
+ }
+
+ for (Index1 = 5; Index1 < Nk && (Index1 + Index2) < Nw; Index1++) {
+ Ek[Index1 + Index2] = Ek[Index1 + Index2 - Nk] ^ Ek[Index1 + Index2 - 1];
+ }
+ }
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Encrypts one single block data (128 bits) with AES algorithm.
+
+ @param[in] Key AES symmetric key buffer.
+ @param[in] InData One block of input plaintext to be encrypted.
+ @param[out] OutData Encrypted output ciphertext.
+
+ @retval EFI_SUCCESS AES Block Encryption succeeded.
+ @retval EFI_INVALID_PARAMETER One or more parameters are invalid.
+
+**/
+EFI_STATUS
+EFIAPI
+AesEncrypt (
+ IN UINT8 *Key,
+ IN UINT8 *InData,
+ OUT UINT8 *OutData
+ )
+{
+ AES_KEY AesKey;
+ UINTN Nr;
+ UINT32 *Ek;
+ UINT32 State[4];
+ UINT32 TempState[4];
+ UINT32 *StateX;
+ UINT32 *StateY;
+ UINT32 *Temp;
+ UINTN Index;
+ UINTN NbIndex;
+ UINTN Round;
+
+ if ((Key == NULL) || (InData == NULL) || (OutData == NULL)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // Expands AES Key for encryption.
+ //
+ AesExpandKey (Key, 128, &AesKey);
+
+ Nr = AesKey.Nk + 6;
+ Ek = AesKey.EncKey;
+
+ //
+ // Initialize the cipher State array with the initial round key
+ //
+ for (Index = 0; Index < AES_NB; Index++) {
+ LOAD32H (State[Index], InData + 4 * Index);
+ State[Index] ^= Ek[Index];
+ }
+
+ NbIndex = AES_NB;
+ StateX = State;
+ StateY = TempState;
+
+ //
+ // AES Cipher transformation rounds (Nr - 1 rounds), in which SubBytes(),
+ // ShiftRows() and MixColumns() operations were combined by a sequence of
+ // table lookups to speed up the execution.
+ //
+ for (Round = 1; Round < Nr; Round++) {
+ StateY[0] = AES_FT0 ((StateX[0] >> 24) ) ^ AES_FT1 ((StateX[1] >> 16) & 0xFF) ^
+ AES_FT2 ((StateX[2] >> 8) & 0xFF) ^ AES_FT3 ((StateX[3] ) & 0xFF) ^ Ek[NbIndex];
+ StateY[1] = AES_FT0 ((StateX[1] >> 24) ) ^ AES_FT1 ((StateX[2] >> 16) & 0xFF) ^
+ AES_FT2 ((StateX[3] >> 8) & 0xFF) ^ AES_FT3 ((StateX[0] ) & 0xFF) ^ Ek[NbIndex + 1];
+ StateY[2] = AES_FT0 ((StateX[2] >> 24) ) ^ AES_FT1 ((StateX[3] >> 16) & 0xFF) ^
+ AES_FT2 ((StateX[0] >> 8) & 0xFF) ^ AES_FT3 ((StateX[1] ) & 0xFF) ^ Ek[NbIndex + 2];
+ StateY[3] = AES_FT0 ((StateX[3] >> 24) ) ^ AES_FT1 ((StateX[0] >> 16) & 0xFF) ^
+ AES_FT2 ((StateX[1] >> 8) & 0xFF) ^ AES_FT3 ((StateX[2] ) & 0xFF) ^ Ek[NbIndex + 3];
+
+ NbIndex += 4;
+ Temp = StateX; StateX = StateY; StateY = Temp;
+ }
+
+ //
+ // Apply the final round, which does not include MixColumns() transformation
+ //
+ StateY[0] = (AES_FT2 ((StateX[0] >> 24) ) & 0xFF000000) ^ (AES_FT3 ((StateX[1] >> 16) & 0xFF) & 0x00FF0000) ^
+ (AES_FT0 ((StateX[2] >> 8) & 0xFF) & 0x0000FF00) ^ (AES_FT1 ((StateX[3] ) & 0xFF) & 0x000000FF) ^
+ Ek[NbIndex];
+ StateY[1] = (AES_FT2 ((StateX[1] >> 24) ) & 0xFF000000) ^ (AES_FT3 ((StateX[2] >> 16) & 0xFF) & 0x00FF0000) ^
+ (AES_FT0 ((StateX[3] >> 8) & 0xFF) & 0x0000FF00) ^ (AES_FT1 ((StateX[0] ) & 0xFF) & 0x000000FF) ^
+ Ek[NbIndex + 1];
+ StateY[2] = (AES_FT2 ((StateX[2] >> 24) ) & 0xFF000000) ^ (AES_FT3 ((StateX[3] >> 16) & 0xFF) & 0x00FF0000) ^
+ (AES_FT0 ((StateX[0] >> 8) & 0xFF) & 0x0000FF00) ^ (AES_FT1 ((StateX[1] ) & 0xFF) & 0x000000FF) ^
+ Ek[NbIndex + 2];
+ StateY[3] = (AES_FT2 ((StateX[3] >> 24) ) & 0xFF000000) ^ (AES_FT3 ((StateX[0] >> 16) & 0xFF) & 0x00FF0000) ^
+ (AES_FT0 ((StateX[1] >> 8) & 0xFF) & 0x0000FF00) ^ (AES_FT1 ((StateX[2] ) & 0xFF) & 0x000000FF) ^
+ Ek[NbIndex + 3];
+
+ //
+ // Output the transformed result;
+ //
+ for (Index = 0; Index < AES_NB; Index++) {
+ STORE32H (StateY[Index], OutData + 4 * Index);
+ }
+
+ return EFI_SUCCESS;
+} \ No newline at end of file
diff --git a/SecurityPkg/RandomNumberGenerator/RngDxe/AesCore.h b/SecurityPkg/RandomNumberGenerator/RngDxe/AesCore.h
new file mode 100644
index 000000000..8279c6116
--- /dev/null
+++ b/SecurityPkg/RandomNumberGenerator/RngDxe/AesCore.h
@@ -0,0 +1,37 @@
+/** @file
+ Function prototype for AES Block Cipher support.
+
+Copyright (c) 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 __AES_CORE_H__
+#define __AES_CORE_H__
+
+/**
+ Encrypts one single block data (128 bits) with AES algorithm.
+
+ @param[in] Key AES symmetric key buffer.
+ @param[in] InData One block of input plaintext to be encrypted.
+ @param[out] OutData Encrypted output ciphertext.
+
+ @retval EFI_SUCCESS AES Block Encryption succeeded.
+ @retval EFI_INVALID_PARAMETER One or more parameters are invalid.
+
+**/
+EFI_STATUS
+EFIAPI
+AesEncrypt (
+ IN UINT8 *Key,
+ IN UINT8 *InData,
+ OUT UINT8 *OutData
+ );
+
+#endif // __AES_CORE_H__
diff --git a/SecurityPkg/RandomNumberGenerator/RngDxe/IA32/AsmRdRand.asm b/SecurityPkg/RandomNumberGenerator/RngDxe/IA32/AsmRdRand.asm
new file mode 100644
index 000000000..37b38307e
--- /dev/null
+++ b/SecurityPkg/RandomNumberGenerator/RngDxe/IA32/AsmRdRand.asm
@@ -0,0 +1,67 @@
+;------------------------------------------------------------------------------
+;
+; Copyright (c) 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.
+;
+; Module Name:
+;
+; AsmRdRand.Asm
+;
+; Abstract:
+;
+; Implementation for 16-, and 32- invocations of RDRAND instruction under 32bit platform.
+;
+; Notes:
+;
+; Visual Studio coding practices do not use inline asm since multiple compilers and
+; architectures are supported assembler not recognizing rdrand instruction so using DB's.
+;
+;------------------------------------------------------------------------------
+
+ .586P
+ .model flat, C
+ .code
+
+;------------------------------------------------------------------------------
+; Generate a 16 bit random number
+; Return TRUE if Rand generated successfully, or FALSE if not
+;
+; BOOLEAN EFIAPI RdRand16Step (UINT16 *Rand); ECX
+;------------------------------------------------------------------------------
+RdRand16Step PROC
+ ; rdrand ax ; generate a 16 bit RN into ax, CF=1 if RN generated ok, otherwise CF=0
+ db 0fh, 0c7h, 0f0h ; rdrand r16: "0f c7 /6 ModRM:r/m(w)"
+ jb rn16_ok ; jmp if CF=1
+ xor eax, eax ; reg=0 if CF=0
+ ret ; return with failure status
+rn16_ok:
+ mov [ecx], ax
+ mov eax, 1
+ ret
+RdRand16Step ENDP
+
+;------------------------------------------------------------------------------
+; Generate a 32 bit random number
+; Return TRUE if Rand generated successfully, or FALSE if not
+;
+; BOOLEAN EFIAPI RdRand32Step (UINT32 *Rand); ECX
+;------------------------------------------------------------------------------
+RdRand32Step PROC
+ ; rdrand eax ; generate a 32 bit RN into eax, CF=1 if RN generated ok, otherwise CF=0
+ db 0fh, 0c7h, 0f0h ; rdrand r32: "0f c7 /6 ModRM:r/m(w)"
+ jb rn32_ok ; jmp if CF=1
+ xor eax, eax ; reg=0 if CF=0
+ ret ; return with failure status
+rn32_ok:
+ mov [ecx], eax
+ mov eax, 1
+ ret
+RdRand32Step ENDP
+
+ END
diff --git a/SecurityPkg/RandomNumberGenerator/RngDxe/IA32/GccRdRand.c b/SecurityPkg/RandomNumberGenerator/RngDxe/IA32/GccRdRand.c
new file mode 100644
index 000000000..f42302afe
--- /dev/null
+++ b/SecurityPkg/RandomNumberGenerator/RngDxe/IA32/GccRdRand.c
@@ -0,0 +1,69 @@
+/** @file
+ RDRAND Support Routines for GCC environment.
+
+Copyright (c) 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.
+
+**/
+
+/**
+ Generates a 16-bit random number through RDRAND instruction.
+
+ @param[out] Rand Buffer pointer to store the random result.
+
+ @retval TRUE RDRAND call was successful.
+ @retval FALSE Failed attempts to call RDRAND.
+
+**/
+BOOLEAN
+EFIAPI
+RdRand16Step (
+ OUT UINT16 *Rand
+ )
+{
+ UINT8 Carry;
+
+ //
+ // Uses byte code for RDRAND instruction,
+ // in case that GCC version has no direct support on RDRAND assembly.
+ //
+ __asm__ __volatile__ (
+ ".byte 0x66; .byte 0x0f; .byte 0xc7; .byte 0xf0; setc %1"
+ :"=a" (*Rand),
+ "=qm" (Carry)
+ );
+
+ return (BOOLEAN) Carry;
+}
+
+/**
+ Generates a 32-bit random number through RDRAND instruction.
+
+ @param[out] Rand Buffer pointer to store the random result.
+
+ @retval TRUE RDRAND call was successful.
+ @retval FALSE Failed attempts to call RDRAND.
+
+**/
+BOOLEAN
+EFIAPI
+RdRand32Step (
+ OUT UINT32 *Rand
+ )
+{
+ UINT8 Carry;
+
+ __asm__ __volatile__ (
+ ".byte 0x0f; .byte 0xc7; .byte 0xf0; setc %1"
+ :"=a" (*Rand),
+ "=qm" (Carry)
+ );
+
+ return (BOOLEAN) Carry;
+} \ No newline at end of file
diff --git a/SecurityPkg/RandomNumberGenerator/RngDxe/IA32/RdRandWord.c b/SecurityPkg/RandomNumberGenerator/RngDxe/IA32/RdRandWord.c
new file mode 100644
index 000000000..125c53b3d
--- /dev/null
+++ b/SecurityPkg/RandomNumberGenerator/RngDxe/IA32/RdRandWord.c
@@ -0,0 +1,104 @@
+/** @file
+ RDRAND Support Routines.
+
+Copyright (c) 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 "RdRand.h"
+
+/**
+ Generates a 64-bit random number through RDRAND instruction.
+
+ @param[out] Rand Buffer pointer to store the random result.
+
+ @retval TRUE RDRAND call was successful.
+ @retval FALSE Failed attempts to call RDRAND.
+
+**/
+BOOLEAN
+EFIAPI
+RdRand64Step (
+ OUT UINT64 *Rand
+ )
+{
+ UINT32 RandLow;
+ UINT32 RandHigh;
+
+ //
+ // Generating a 64-bit rand on a 32-bit system by
+ // mapping two 32-bit RDRAND instructions.
+ //
+ if (!RdRand32Step (&RandLow)) {
+ return FALSE;
+ }
+ if (!RdRand32Step (&RandHigh)) {
+ return FALSE;
+ }
+
+ *Rand = (UINT64) RandLow | LShiftU64 ((UINT64)RandHigh, 32);
+
+ return TRUE;
+}
+
+/**
+ Calls RDRAND to request a word-length random number.
+
+ @param[out] Rand Buffer pointer to store the random number.
+ @param[in] NeedRetry Determine whether or not to loop retry.
+
+ @retval EFI_SUCCESS Random word generation succeeded.
+ @retval EFI_NOT_READY Failed to request random word.
+
+**/
+EFI_STATUS
+EFIAPI
+RdRandWord (
+ OUT UINTN *Rand,
+ IN BOOLEAN NeedRetry
+ )
+{
+ return RdRand32 (Rand, NeedRetry);
+}
+
+/**
+ Calls RDRAND to request multiple word-length random numbers.
+
+ @param[in] Length Size of the buffer, in words, to fill with.
+ @param[out] RandBuffer Pointer to the buffer to store the random result.
+
+ @retval EFI_SUCCESS Random words generation succeeded.
+ @retval EFI_NOT_READY Failed to request random words.
+
+**/
+EFI_STATUS
+EFIAPI
+RdRandGetWords (
+ IN UINTN Length,
+ OUT UINTN *RandBuffer
+ )
+{
+ EFI_STATUS Status;
+ UINT32 Index;
+
+ for (Index = 0; Index < Length; Index++) {
+ //
+ // Obtain one word-length (32-bit) Random Number with possible retry-loop.
+ //
+ Status = RdRand32 (RandBuffer, TRUE);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ RandBuffer++;
+ }
+
+ return EFI_SUCCESS;
+}
diff --git a/SecurityPkg/RandomNumberGenerator/RngDxe/RdRand.c b/SecurityPkg/RandomNumberGenerator/RngDxe/RdRand.c
new file mode 100644
index 000000000..7e618dc91
--- /dev/null
+++ b/SecurityPkg/RandomNumberGenerator/RngDxe/RdRand.c
@@ -0,0 +1,395 @@
+/** @file
+ Support routines for RDRAND instruction access.
+
+Copyright (c) 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 "RdRand.h"
+#include "AesCore.h"
+
+//
+// Bit mask used to determine if RdRand instruction is supported.
+//
+#define RDRAND_MASK 0x40000000
+
+/**
+ Determines whether or not RDRAND instruction is supported by the host hardware.
+
+ @retval EFI_SUCCESS RDRAND instruction supported.
+ @retval EFI_UNSUPPORTED RDRAND instruction not supported.
+
+**/
+EFI_STATUS
+EFIAPI
+IsRdRandSupported (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+ UINT32 RegEax;
+ UINT32 RegEbx;
+ UINT32 RegEcx;
+ UINT32 RegEdx;
+ BOOLEAN IsIntelCpu;
+
+ Status = EFI_UNSUPPORTED;
+ IsIntelCpu = FALSE;
+
+ //
+ // Checks whether the current processor is an Intel product by CPUID.
+ //
+ AsmCpuid (0, &RegEax, &RegEbx, &RegEcx, &RegEdx);
+ if ((CompareMem ((CHAR8 *)(&RegEbx), "Genu", 4) == 0) &&
+ (CompareMem ((CHAR8 *)(&RegEdx), "ineI", 4) == 0) &&
+ (CompareMem ((CHAR8 *)(&RegEcx), "ntel", 4) == 0)) {
+ IsIntelCpu = TRUE;
+ }
+
+ if (IsIntelCpu) {
+ //
+ // Determine RDRAND support by examining bit 30 of the ECX register returned by CPUID.
+ // A value of 1 indicates that processor supports RDRAND instruction.
+ //
+ AsmCpuid (1, 0, 0, &RegEcx, 0);
+
+ if ((RegEcx & RDRAND_MASK) == RDRAND_MASK) {
+ Status = EFI_SUCCESS;
+ }
+ }
+
+ return Status;
+}
+
+/**
+ Calls RDRAND to obtain a 16-bit random number.
+
+ @param[out] Rand Buffer pointer to store the random result.
+ @param[in] NeedRetry Determine whether or not to loop retry.
+
+ @retval EFI_SUCCESS RDRAND call was successful.
+ @retval EFI_NOT_READY Failed attempts to call RDRAND.
+
+**/
+EFI_STATUS
+EFIAPI
+RdRand16 (
+ OUT UINT16 *Rand,
+ IN BOOLEAN NeedRetry
+ )
+{
+ UINT32 Index;
+ UINT32 RetryCount;
+
+ if (NeedRetry) {
+ RetryCount = RETRY_LIMIT;
+ } else {
+ RetryCount = 1;
+ }
+
+ //
+ // Perform a single call to RDRAND, or enter a loop call until RDRAND succeeds.
+ //
+ for (Index = 0; Index < RetryCount; Index++) {
+ if (RdRand16Step (Rand)) {
+ return EFI_SUCCESS;
+ }
+ }
+
+ return EFI_NOT_READY;
+}
+
+/**
+ Calls RDRAND to obtain a 32-bit random number.
+
+ @param[out] Rand Buffer pointer to store the random result.
+ @param[in] NeedRetry Determine whether or not to loop retry.
+
+ @retval EFI_SUCCESS RDRAND call was successful.
+ @retval EFI_NOT_READY Failed attempts to call RDRAND.
+
+**/
+EFI_STATUS
+EFIAPI
+RdRand32 (
+ OUT UINT32 *Rand,
+ IN BOOLEAN NeedRetry
+ )
+{
+ UINT32 Index;
+ UINT32 RetryCount;
+
+ if (NeedRetry) {
+ RetryCount = RETRY_LIMIT;
+ } else {
+ RetryCount = 1;
+ }
+
+ //
+ // Perform a single call to RDRAND, or enter a loop call until RDRAND succeeds.
+ //
+ for (Index = 0; Index < RetryCount; Index++) {
+ if (RdRand32Step (Rand)) {
+ return EFI_SUCCESS;
+ }
+ }
+
+ return EFI_NOT_READY;
+}
+
+/**
+ Calls RDRAND to obtain a 64-bit random number.
+
+ @param[out] Rand Buffer pointer to store the random result.
+ @param[in] NeedRetry Determine whether or not to loop retry.
+
+ @retval EFI_SUCCESS RDRAND call was successful.
+ @retval EFI_NOT_READY Failed attempts to call RDRAND.
+
+**/
+EFI_STATUS
+EFIAPI
+RdRand64 (
+ OUT UINT64 *Rand,
+ IN BOOLEAN NeedRetry
+ )
+{
+ UINT32 Index;
+ UINT32 RetryCount;
+
+ if (NeedRetry) {
+ RetryCount = RETRY_LIMIT;
+ } else {
+ RetryCount = 1;
+ }
+
+ //
+ // Perform a single call to RDRAND, or enter a loop call until RDRAND succeeds.
+ //
+ for (Index = 0; Index < RetryCount; Index++) {
+ if (RdRand64Step (Rand)) {
+ return EFI_SUCCESS;
+ }
+ }
+
+ return EFI_NOT_READY;
+}
+
+/**
+ Calls RDRAND to fill a buffer of arbitrary size with random bytes.
+
+ @param[in] Length Size of the buffer, in bytes, to fill with.
+ @param[out] RandBuffer Pointer to the buffer to store the random result.
+
+ @retval EFI_SUCCESS Random bytes generation succeeded.
+ @retval EFI_NOT_READY Failed to request random bytes.
+
+**/
+EFI_STATUS
+EFIAPI
+RdRandGetBytes (
+ IN UINTN Length,
+ OUT UINT8 *RandBuffer
+ )
+{
+ EFI_STATUS Status;
+ UINT8 *Start;
+ UINT8 *ResidualStart;
+ UINTN *BlockStart;
+ UINTN TempRand;
+ UINTN Count;
+ UINTN Residual;
+ UINTN StartLen;
+ UINTN BlockNum;
+ UINTN Index;
+
+ ResidualStart = NULL;
+ TempRand = 0;
+
+ //
+ // Compute the address of the first word aligned (32/64-bit) block in the
+ // destination buffer, depending on whether we are in 32- or 64-bit mode.
+ //
+ Start = RandBuffer;
+ if (((UINT32)(UINTN)Start % (UINT32)sizeof(UINTN)) == 0) {
+ BlockStart = (UINTN *)Start;
+ Count = Length;
+ StartLen = 0;
+ } else {
+ BlockStart = (UINTN *)(((UINTN)Start & ~(UINTN)(sizeof(UINTN) - 1)) + (UINTN)sizeof(UINTN));
+ Count = Length - (sizeof (UINTN) - (UINT32)((UINTN)Start % sizeof (UINTN)));
+ StartLen = (UINT32)((UINTN)BlockStart - (UINTN)Start);
+ }
+
+ //
+ // Compute the number of word blocks and the remaining number of bytes.
+ //
+ Residual = Count % sizeof (UINTN);
+ BlockNum = Count / sizeof (UINTN);
+ if (Residual != 0) {
+ ResidualStart = (UINT8 *) (BlockStart + BlockNum);
+ }
+
+ //
+ // Obtain a temporary random number for use in the residuals. Failout if retry fails.
+ //
+ if (StartLen > 0) {
+ Status = RdRandWord ((UINTN *) &TempRand, TRUE);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ }
+
+ //
+ // Populate the starting mis-aligned block.
+ //
+ for (Index = 0; Index < StartLen; Index++) {
+ Start[Index] = (UINT8)(TempRand & 0xff);
+ TempRand = TempRand >> 8;
+ }
+
+ //
+ // Populate the central aligned block. Fail out if retry fails.
+ //
+ Status = RdRandGetWords (BlockNum, (UINTN *)(BlockStart));
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ //
+ // Populate the final mis-aligned block.
+ //
+ if (Residual > 0) {
+ Status = RdRandWord ((UINTN *)&TempRand, TRUE);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ for (Index = 0; Index < Residual; Index++) {
+ ResidualStart[Index] = (UINT8)(TempRand & 0xff);
+ TempRand = TempRand >> 8;
+ }
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Creates a 128bit random value that is fully forward and backward prediction resistant,
+ suitable for seeding a NIST SP800-90 Compliant, FIPS 1402-2 certifiable SW DRBG.
+ This function takes multiple random numbers through RDRAND without intervening
+ delays to ensure reseeding and performs AES-CBC-MAC over the data to compute the
+ seed value.
+
+ @param[out] SeedBuffer Pointer to a 128bit buffer to store the random seed.
+
+ @retval EFI_SUCCESS Random seed generation succeeded.
+ @retval EFI_NOT_READY Failed to request random bytes.
+
+**/
+EFI_STATUS
+EFIAPI
+RdRandGetSeed128 (
+ OUT UINT8 *SeedBuffer
+ )
+{
+ EFI_STATUS Status;
+ UINT8 RandByte[16];
+ UINT8 Key[16];
+ UINT8 Ffv[16];
+ UINT8 Xored[16];
+ UINT32 Index;
+ UINT32 Index2;
+
+ //
+ // Chose an arbitary key and zero the feed_forward_value (FFV)
+ //
+ for (Index = 0; Index < 16; Index++) {
+ Key[Index] = (UINT8) Index;
+ Ffv[Index] = 0;
+ }
+
+ //
+ // Perform CBC_MAC over 32 * 128 bit values, with 10us gaps between 128 bit value
+ // The 10us gaps will ensure multiple reseeds within the HW RNG with a large design margin.
+ //
+ for (Index = 0; Index < 32; Index++) {
+ MicroSecondDelay (10);
+ Status = RdRandGetBytes (16, RandByte);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Perform XOR operations on two 128-bit value.
+ //
+ for (Index2 = 0; Index2 < 16; Index2++) {
+ Xored[Index2] = RandByte[Index2] ^ Ffv[Index2];
+ }
+
+ AesEncrypt (Key, Xored, Ffv);
+ }
+
+ for (Index = 0; Index < 16; Index++) {
+ SeedBuffer[Index] = Ffv[Index];
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Generate high-quality entropy source through RDRAND.
+
+ @param[in] Length Size of the buffer, in bytes, to fill with.
+ @param[out] Entropy Pointer to the buffer to store the entropy data.
+
+ @retval EFI_SUCCESS Entropy generation succeeded.
+ @retval EFI_NOT_READY Failed to request random data.
+
+**/
+EFI_STATUS
+EFIAPI
+RdRandGenerateEntropy (
+ IN UINTN Length,
+ OUT UINT8 *Entropy
+ )
+{
+ EFI_STATUS Status;
+ UINTN BlockCount;
+ UINT8 Seed[16];
+ UINT8 *Ptr;
+
+ Status = EFI_NOT_READY;
+ BlockCount = Length / 16;
+ Ptr = (UINT8 *)Entropy;
+
+ //
+ // Generate high-quality seed for DRBG Entropy
+ //
+ while (BlockCount > 0) {
+ Status = RdRandGetSeed128 (Seed);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ CopyMem (Ptr, Seed, 16);
+
+ BlockCount--;
+ Ptr = Ptr + 16;
+ }
+
+ //
+ // Populate the remained data as request.
+ //
+ Status = RdRandGetSeed128 (Seed);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ CopyMem (Ptr, Seed, (Length % 16));
+
+ return Status;
+}
diff --git a/SecurityPkg/RandomNumberGenerator/RngDxe/RdRand.h b/SecurityPkg/RandomNumberGenerator/RngDxe/RdRand.h
new file mode 100644
index 000000000..20fd9fbd3
--- /dev/null
+++ b/SecurityPkg/RandomNumberGenerator/RngDxe/RdRand.h
@@ -0,0 +1,213 @@
+/** @file
+ Header for the RDRAND APIs used by RNG DXE driver.
+
+ Support API definitions for RDRAND instruction access, which will leverage
+ Intel Secure Key technology to provide high-quality random numbers for use
+ in applications, or entropy for seeding other random number generators.
+ Refer to http://software.intel.com/en-us/articles/intel-digital-random-number
+ -generator-drng-software-implementation-guide/ for more information about Intel
+ Secure Key technology.
+
+Copyright (c) 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 __RD_RAND_H__
+#define __RD_RAND_H__
+
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/TimerLib.h>
+#include <Protocol/Rng.h>
+
+//
+// The maximun number of retries to obtain one available random number.
+//
+#define RETRY_LIMIT 10
+
+/**
+ Determines whether or not RDRAND instruction is supported by the host hardware.
+
+ @retval EFI_SUCCESS RDRAND instruction supported.
+ @retval EFI_UNSUPPORTED RDRAND instruction not supported.
+
+**/
+EFI_STATUS
+EFIAPI
+IsRdRandSupported (
+ VOID
+ );
+
+/**
+ Generates a 16-bit random number through RDRAND instruction.
+
+ @param[out] Rand Buffer pointer to store the random result.
+
+ @retval TRUE RDRAND call was successful.
+ @retval FALSE Failed attempts to call RDRAND.
+
+**/
+BOOLEAN
+EFIAPI
+RdRand16Step (
+ OUT UINT16 *Rand
+ );
+
+/**
+ Generates a 32-bit random number through RDRAND instruction.
+
+ @param[out] Rand Buffer pointer to store the random result.
+
+ @retval TRUE RDRAND call was successful.
+ @retval FALSE Failed attempts to call RDRAND.
+
+**/
+BOOLEAN
+EFIAPI
+RdRand32Step (
+ OUT UINT32 *Rand
+ );
+
+/**
+ Generates a 64-bit random number through RDRAND instruction.
+
+ @param[out] Rand Buffer pointer to store the random result.
+
+ @retval TRUE RDRAND call was successful.
+ @retval FALSE Failed attempts to call RDRAND.
+
+**/
+BOOLEAN
+EFIAPI
+RdRand64Step (
+ OUT UINT64 *Rand
+ );
+
+/**
+ Calls RDRAND to obtain a 16-bit random number.
+
+ @param[out] Rand Buffer pointer to store the random result.
+ @param[in] NeedRetry Determine whether or not to loop retry.
+
+ @retval EFI_SUCCESS RDRAND call was successful.
+ @retval EFI_NOT_READY Failed attempts to call RDRAND.
+
+**/
+EFI_STATUS
+EFIAPI
+RdRand16 (
+ OUT UINT16 *Rand,
+ IN BOOLEAN NeedRetry
+ );
+
+/**
+ Calls RDRAND to obtain a 32-bit random number.
+
+ @param[out] Rand Buffer pointer to store the random result.
+ @param[in] NeedRetry Determine whether or not to loop retry.
+
+ @retval EFI_SUCCESS RDRAND call was successful.
+ @retval EFI_NOT_READY Failed attempts to call RDRAND.
+
+**/
+EFI_STATUS
+EFIAPI
+RdRand32 (
+ OUT UINT32 *Rand,
+ IN BOOLEAN NeedRetry
+ );
+
+/**
+ Calls RDRAND to obtain a 64-bit random number.
+
+ @param[out] Rand Buffer pointer to store the random result.
+ @param[in] NeedRetry Determine whether or not to loop retry.
+
+ @retval EFI_SUCCESS RDRAND call was successful.
+ @retval EFI_NOT_READY Failed attempts to call RDRAND.
+
+**/
+EFI_STATUS
+EFIAPI
+RdRand64 (
+ OUT UINT64 *Rand,
+ IN BOOLEAN NeedRetry
+ );
+
+/**
+ Calls RDRAND to request a word-length random number.
+
+ @param[out] Rand Buffer pointer to store the random number.
+ @param[in] NeedRetry Determine whether or not to loop retry.
+
+ @retval EFI_SUCCESS Random word generation succeeded.
+ @retval EFI_NOT_READY Failed to request random word.
+
+**/
+EFI_STATUS
+EFIAPI
+RdRandWord (
+ OUT UINTN *Rand,
+ IN BOOLEAN NeedRetry
+ );
+
+/**
+ Calls RDRAND to request multiple word-length random numbers.
+
+ @param[in] Length Size of the buffer, in words, to fill with.
+ @param[out] RandBuffer Pointer to the buffer to store the random result.
+
+ @retval EFI_SUCCESS Random words generation succeeded.
+ @retval EFI_NOT_READY Failed to request random words.
+
+**/
+EFI_STATUS
+EFIAPI
+RdRandGetWords (
+ IN UINTN Length,
+ OUT UINTN *RandBuffer
+ );
+
+/**
+ Calls RDRAND to fill a buffer of arbitrary size with random bytes.
+
+ @param[in] Length Size of the buffer, in bytes, to fill with.
+ @param[out] RandBuffer Pointer to the buffer to store the random result.
+
+ @retval EFI_SUCCESS Random bytes generation succeeded.
+ @retval EFI_NOT_READY Failed to request random bytes.
+
+**/
+EFI_STATUS
+EFIAPI
+RdRandGetBytes (
+ IN UINTN Length,
+ OUT UINT8 *RandBuffer
+ );
+
+/**
+ Generate high-quality entropy source through RDRAND.
+
+ @param[in] Length Size of the buffer, in bytes, to fill with.
+ @param[out] Entropy Pointer to the buffer to store the entropy data.
+
+ @retval EFI_SUCCESS Entropy generation succeeded.
+ @retval EFI_NOT_READY Failed to request random data.
+
+**/
+EFI_STATUS
+EFIAPI
+RdRandGenerateEntropy (
+ IN UINTN Length,
+ OUT UINT8 *Entropy
+ );
+
+#endif // __RD_RAND_H__ \ No newline at end of file
diff --git a/SecurityPkg/RandomNumberGenerator/RngDxe/RngDxe.c b/SecurityPkg/RandomNumberGenerator/RngDxe/RngDxe.c
new file mode 100644
index 000000000..98ef3b357
--- /dev/null
+++ b/SecurityPkg/RandomNumberGenerator/RngDxe/RngDxe.c
@@ -0,0 +1,219 @@
+/** @file
+ RNG Driver to produce the UEFI Random Number Generator protocol.
+
+ The driver will use the new RDRAND instruction to produce high-quality, high-performance
+ entropy and random number.
+
+ RNG Algoritnms defined in UEFI 2.4:
+ - EFI_RNG_ALGORITHM_SP800_90_CTR_256_GUID - Supported
+ (RDRAND implements a hardware NIST SP800-90 AES-CTR-256 based DRBG)
+ - EFI_RNG_ALGORITHM_RAW - Supported
+ (Structuring RDRAND invocation can be guaranteed as high-quality entropy source)
+ - EFI_RNG_ALGORITHM_SP800_90_HMAC_256_GUID - Unsupported
+ - EFI_RNG_ALGORITHM_SP800_90_HASH_256_GUID - Unsupported
+ - EFI_RNG_ALGORITHM_X9_31_3DES_GUID - Unsupported
+ - EFI_RNG_ALGORITHM_X9_31_AES_GUID - Unsupported
+
+Copyright (c) 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 "RdRand.h"
+
+//
+// Supported RNG Algorithms list by this driver.
+//
+EFI_RNG_ALGORITHM mSupportedRngAlgorithms[] = {
+ EFI_RNG_ALGORITHM_SP800_90_CTR_256_GUID,
+ EFI_RNG_ALGORITHM_RAW
+};
+
+/**
+ Returns information about the random number generation implementation.
+
+ @param[in] This A pointer to the EFI_RNG_PROTOCOL instance.
+ @param[in,out] RNGAlgorithmListSize On input, the size in bytes of RNGAlgorithmList.
+ On output with a return code of EFI_SUCCESS, the size
+ in bytes of the data returned in RNGAlgorithmList. On output
+ with a return code of EFI_BUFFER_TOO_SMALL,
+ the size of RNGAlgorithmList required to obtain the list.
+ @param[out] RNGAlgorithmList A caller-allocated memory buffer filled by the driver
+ with one EFI_RNG_ALGORITHM element for each supported
+ RNG algorithm. The list must not change across multiple
+ calls to the same driver. The first algorithm in the list
+ is the default algorithm for the driver.
+
+ @retval EFI_SUCCESS The RNG algorithm list was returned successfully.
+ @retval EFI_UNSUPPORTED The services is not supported by this driver.
+ @retval EFI_DEVICE_ERROR The list of algorithms could not be retrieved due to a
+ hardware or firmware error.
+ @retval EFI_INVALID_PARAMETER One or more of the parameters are incorrect.
+ @retval EFI_BUFFER_TOO_SMALL The buffer RNGAlgorithmList is too small to hold the result.
+
+**/
+EFI_STATUS
+EFIAPI
+RngGetInfo (
+ IN EFI_RNG_PROTOCOL *This,
+ IN OUT UINTN *RNGAlgorithmListSize,
+ OUT EFI_RNG_ALGORITHM *RNGAlgorithmList
+ )
+{
+ EFI_STATUS Status;
+ UINTN RequiredSize;
+
+ if ((This == NULL) || (RNGAlgorithmListSize == NULL)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ RequiredSize = sizeof (mSupportedRngAlgorithms);
+ if (*RNGAlgorithmListSize < RequiredSize) {
+ Status = EFI_BUFFER_TOO_SMALL;
+ } else {
+ //
+ // Return algorithm list supported by driver.
+ //
+ if (RNGAlgorithmList != NULL) {
+ CopyMem (RNGAlgorithmList, mSupportedRngAlgorithms, RequiredSize);
+ Status = EFI_SUCCESS;
+ } else {
+ Status = EFI_INVALID_PARAMETER;
+ }
+ }
+ *RNGAlgorithmListSize = RequiredSize;
+
+ return Status;
+}
+
+/**
+ Produces and returns an RNG value using either the default or specified RNG algorithm.
+
+ @param[in] This A pointer to the EFI_RNG_PROTOCOL instance.
+ @param[in] RNGAlgorithm A pointer to the EFI_RNG_ALGORITHM that identifies the RNG
+ algorithm to use. May be NULL in which case the function will
+ use its default RNG algorithm.
+ @param[in] RNGValueLength The length in bytes of the memory buffer pointed to by
+ RNGValue. The driver shall return exactly this numbers of bytes.
+ @param[out] RNGValue A caller-allocated memory buffer filled by the driver with the
+ resulting RNG value.
+
+ @retval EFI_SUCCESS The RNG value was returned successfully.
+ @retval EFI_UNSUPPORTED The algorithm specified by RNGAlgorithm is not supported by
+ this driver.
+ @retval EFI_DEVICE_ERROR An RNG value could not be retrieved due to a hardware or
+ firmware error.
+ @retval EFI_NOT_READY There is not enough random data available to satisfy the length
+ requested by RNGValueLength.
+ @retval EFI_INVALID_PARAMETER RNGValue is NULL or RNGValueLength is zero.
+
+**/
+EFI_STATUS
+EFIAPI
+RngGetRNG (
+ IN EFI_RNG_PROTOCOL *This,
+ IN EFI_RNG_ALGORITHM *RNGAlgorithm, OPTIONAL
+ IN UINTN RNGValueLength,
+ OUT UINT8 *RNGValue
+ )
+{
+ EFI_STATUS Status;
+
+ if ((RNGValueLength == 0) || (RNGValue == NULL)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Status = EFI_UNSUPPORTED;
+ if (RNGAlgorithm == NULL) {
+ //
+ // Use the default RNG algorithm if RNGAlgorithm is NULL.
+ //
+ RNGAlgorithm = &gEfiRngAlgorithmSp80090Ctr256Guid;
+ }
+
+ //
+ // NIST SP800-90-AES-CTR-256 supported by RDRAND
+ //
+ if (CompareGuid (RNGAlgorithm, &gEfiRngAlgorithmSp80090Ctr256Guid)) {
+ Status = RdRandGetBytes (RNGValueLength, RNGValue);
+ return Status;
+ }
+
+ //
+ // The "raw" algorithm is intended to provide entropy directly
+ //
+ if (CompareGuid (RNGAlgorithm, &gEfiRngAlgorithmRaw)) {
+ //
+ // When a DRBG is used on the output of a entropy source,
+ // its security level must be at least 256 bits according to UEFI Spec.
+ //
+ if (RNGValueLength < 32) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Status = RdRandGenerateEntropy (RNGValueLength, RNGValue);
+ return Status;
+ }
+
+ //
+ // Other algorithms were unsupported by this driver.
+ //
+ return Status;
+}
+
+//
+// The Random Number Generator (RNG) protocol
+//
+EFI_RNG_PROTOCOL mRngRdRand = {
+ RngGetInfo,
+ RngGetRNG
+};
+
+/**
+ The user Entry Point for the Random Number Generator (RNG) driver.
+
+ @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 EFI_NOT_SUPPORTED Platform does not support RNG.
+ @retval Other Some error occurs when executing this entry point.
+
+**/
+EFI_STATUS
+EFIAPI
+RngDriverEntry (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+ EFI_HANDLE Handle;
+
+ //
+ // Verify RdRand support on Platform.
+ //
+ Status = IsRdRandSupported ();
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Install UEFI RNG (Random Number Generator) Protocol
+ //
+ Handle = NULL;
+ Status = gBS->InstallMultipleProtocolInterfaces (
+ &Handle,
+ &gEfiRngProtocolGuid,
+ &mRngRdRand,
+ NULL
+ );
+
+ return Status;
+}
diff --git a/SecurityPkg/RandomNumberGenerator/RngDxe/RngDxe.inf b/SecurityPkg/RandomNumberGenerator/RngDxe/RngDxe.inf
new file mode 100644
index 000000000..12cb2fc3e
--- /dev/null
+++ b/SecurityPkg/RandomNumberGenerator/RngDxe/RngDxe.inf
@@ -0,0 +1,77 @@
+## @file
+# Module that produces the UEFI Random Number Generator protocol.
+#
+# This module will leverage Intel Secure Key technology to produce the Random
+# Number Generator protocol, which is used to provide high-quality random numbers
+# for use in applications, or entropy for seeding other random number generators.
+# Refer to http://software.intel.com/en-us/articles/intel-digital-random-number
+# -generator-drng-software-implementation-guide/ for more information about Intel
+# Secure Key technology.
+#
+# Copyright (c) 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.
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = RngDxe
+ FILE_GUID = B981A835-6EE8-4f4c-AE0B-210AA0BFBF01
+ MODULE_TYPE = DXE_DRIVER
+ VERSION_STRING = 1.0
+ ENTRY_POINT = RngDriverEntry
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64
+#
+
+[Sources.common]
+ RngDxe.c
+ RdRand.c
+ RdRand.h
+ AesCore.c
+ AesCore.h
+
+[Sources.IA32]
+ IA32/RdRandWord.c
+ IA32/AsmRdRand.asm | MSFT
+ IA32/GccRdRand.c | GCC
+
+[Sources.X64]
+ X64/RdRandWord.c
+ X64/AsmRdRand.asm | MSFT
+ X64/GccRdRand.c | GCC
+
+[Packages]
+ MdePkg/MdePkg.dec
+ SecurityPkg/SecurityPkg.dec
+
+[LibraryClasses]
+ UefiLib
+ UefiBootServicesTableLib
+ BaseLib
+ DebugLib
+ UefiDriverEntryPoint
+ TimerLib
+
+[Guids]
+ gEfiRngAlgorithmSp80090Hash256Guid
+ gEfiRngAlgorithmSp80090Hmac256Guid
+ gEfiRngAlgorithmSp80090Ctr256Guid
+ gEfiRngAlgorithmX9313DesGuid
+ gEfiRngAlgorithmX931AesGuid
+ gEfiRngAlgorithmRaw
+
+[Protocols]
+ gEfiRngProtocolGuid ## PRODUCES
+
+[Depex]
+ TRUE
diff --git a/SecurityPkg/RandomNumberGenerator/RngDxe/X64/AsmRdRand.asm b/SecurityPkg/RandomNumberGenerator/RngDxe/X64/AsmRdRand.asm
new file mode 100644
index 000000000..8a4fe65d0
--- /dev/null
+++ b/SecurityPkg/RandomNumberGenerator/RngDxe/X64/AsmRdRand.asm
@@ -0,0 +1,83 @@
+;------------------------------------------------------------------------------
+;
+; Copyright (c) 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.
+;
+; Module Name:
+;
+; AsmRdRand.Asm
+;
+; Abstract:
+;
+; Implementation for 16-, 32-, and 64-bit invocations of RDRAND instruction under 64bit platform.
+;
+; Notes:
+;
+; Visual Studio coding practices do not use inline asm since multiple compilers and
+; architectures are supported assembler not recognizing rdrand instruction so using DB's.
+;
+;------------------------------------------------------------------------------
+
+ .code
+
+;------------------------------------------------------------------------------
+; Generate a 16 bit random number
+; Return TRUE if Rand generated successfully, or FALSE if not
+;
+; BOOLEAN EFIAPI RdRand16Step (UINT16 *Rand); RCX
+;------------------------------------------------------------------------------
+RdRand16Step PROC
+ ; rdrand ax ; generate a 16 bit RN into ax, CF=1 if RN generated ok, otherwise CF=0
+ db 0fh, 0c7h, 0f0h ; rdrand r16: "0f c7 /6 ModRM:r/m(w)"
+ jb rn16_ok ; jmp if CF=1
+ xor rax, rax ; reg=0 if CF=0
+ ret ; return with failure status
+rn16_ok:
+ mov [rcx], ax
+ mov rax, 1
+ ret
+RdRand16Step ENDP
+
+;------------------------------------------------------------------------------
+; Generate a 32 bit random number
+; Return TRUE if Rand generated successfully, or FALSE if not
+;
+; BOOLEAN EFIAPI RdRand32Step (UINT32 *Rand); RCX
+;------------------------------------------------------------------------------
+RdRand32Step PROC
+ ; rdrand eax ; generate a 32 bit RN into eax, CF=1 if RN generated ok, otherwise CF=0
+ db 0fh, 0c7h, 0f0h ; rdrand r32: "0f c7 /6 ModRM:r/m(w)"
+ jb rn32_ok ; jmp if CF=1
+ xor rax, rax ; reg=0 if CF=0
+ ret ; return with failure status
+rn32_ok:
+ mov [rcx], eax
+ mov rax, 1
+ ret
+RdRand32Step ENDP
+
+;------------------------------------------------------------------------------
+; Generate a 64 bit random number
+; Return TRUE if RN generated successfully, or FALSE if not
+;
+; BOOLEAN EFIAPI RdRand64Step (UINT64 *Random); RCX
+;------------------------------------------------------------------------------
+RdRand64Step PROC
+ ; rdrand rax ; generate a 64 bit RN into rax, CF=1 if RN generated ok, otherwise CF=0
+ db 048h, 0fh, 0c7h, 0f0h ; rdrand r64: "REX.W + 0F C7 /6 ModRM:r/m(w)"
+ jb rn64_ok ; jmp if CF=1
+ xor rax, rax ; reg=0 if CF=0
+ ret ; return with failure status
+rn64_ok:
+ mov [rcx], rax
+ mov rax, 1
+ ret
+RdRand64Step ENDP
+
+ END
diff --git a/SecurityPkg/RandomNumberGenerator/RngDxe/X64/GccRdRand.c b/SecurityPkg/RandomNumberGenerator/RngDxe/X64/GccRdRand.c
new file mode 100644
index 000000000..d28336de4
--- /dev/null
+++ b/SecurityPkg/RandomNumberGenerator/RngDxe/X64/GccRdRand.c
@@ -0,0 +1,95 @@
+/** @file
+ RDRAND Support Routines for GCC environment.
+
+Copyright (c) 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.
+
+**/
+
+/**
+ Generates a 16-bit random number through RDRAND instruction.
+
+ @param[out] Rand Buffer pointer to store the random result.
+
+ @retval TRUE RDRAND call was successful.
+ @retval FALSE Failed attempts to call RDRAND.
+
+**/
+BOOLEAN
+EFIAPI
+RdRand16Step (
+ OUT UINT16 *Rand
+ )
+{
+ UINT8 Carry;
+
+ //
+ // Uses byte code for RDRAND instruction,
+ // in case that GCC version has no direct support on RDRAND assembly.
+ //
+ __asm__ __volatile__ (
+ ".byte 0x66; .byte 0x0f; .byte 0xc7; .byte 0xf0; setc %1"
+ :"=a" (*Rand),
+ "=qm" (Carry)
+ );
+
+ return (BOOLEAN) Carry;
+}
+
+/**
+ Generates a 32-bit random number through RDRAND instruction.
+
+ @param[out] Rand Buffer pointer to store the random result.
+
+ @retval TRUE RDRAND call was successful.
+ @retval FALSE Failed attempts to call RDRAND.
+
+**/
+BOOLEAN
+EFIAPI
+RdRand32Step (
+ OUT UINT32 *Rand
+ )
+{
+ UINT8 Carry;
+
+ __asm__ __volatile__ (
+ ".byte 0x0f; .byte 0xc7; .byte 0xf0; setc %1"
+ :"=a" (*Rand),
+ "=qm" (Carry)
+ );
+
+ return (BOOLEAN) Carry;
+}
+
+/**
+ Generates a 64-bit random number through RDRAND instruction.
+
+ @param[out] Rand Buffer pointer to store the random result.
+
+ @retval TRUE RDRAND call was successful.
+ @retval FALSE Failed attempts to call RDRAND.
+
+**/
+BOOLEAN
+EFIAPI
+RdRand64Step (
+ OUT UINT64 *Rand
+ )
+{
+ UINT8 Carry;
+
+ __asm__ __volatile__ (
+ ".byte 0x48; .byte 0x0f; .byte 0xc7; .byte 0xf0; setc %1"
+ :"=a" (*Rand),
+ "=qm" (Carry)
+ );
+
+ return (BOOLEAN) Carry;
+}
diff --git a/SecurityPkg/RandomNumberGenerator/RngDxe/X64/RdRandWord.c b/SecurityPkg/RandomNumberGenerator/RngDxe/X64/RdRandWord.c
new file mode 100644
index 000000000..946e5baba
--- /dev/null
+++ b/SecurityPkg/RandomNumberGenerator/RngDxe/X64/RdRandWord.c
@@ -0,0 +1,70 @@
+/** @file
+ RDRAND Support Routines.
+
+Copyright (c) 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 "RdRand.h"
+
+/**
+ Calls RDRAND to request a word-length random number.
+
+ @param[out] Rand Buffer pointer to store the random number.
+ @param[in] NeedRetry Determine whether or not to loop retry.
+
+ @retval EFI_SUCCESS Random word generation succeeded.
+ @retval EFI_NOT_READY Failed to request random word.
+
+**/
+EFI_STATUS
+EFIAPI
+RdRandWord (
+ OUT UINTN *Rand,
+ IN BOOLEAN NeedRetry
+ )
+{
+ return RdRand64 (Rand, NeedRetry);
+}
+
+/**
+ Calls RDRAND to request multiple word-length random numbers.
+
+ @param[in] Length Size of the buffer, in words, to fill with.
+ @param[out] RandBuffer Pointer to the buffer to store the random result.
+
+ @retval EFI_SUCCESS Random words generation succeeded.
+ @retval EFI_NOT_READY Failed to request random words.
+
+**/
+EFI_STATUS
+EFIAPI
+RdRandGetWords (
+ IN UINTN Length,
+ OUT UINTN *RandBuffer
+ )
+{
+ EFI_STATUS Status;
+ UINT32 Index;
+
+ for (Index = 0; Index < Length; Index++) {
+ //
+ // Obtain one word-length (64-bit) Random Number with possible retry-loop.
+ //
+ Status = RdRand64 (RandBuffer, TRUE);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ RandBuffer++;
+ }
+
+ return EFI_SUCCESS;
+} \ No newline at end of file
diff --git a/SecurityPkg/SecurityPkg.dec b/SecurityPkg/SecurityPkg.dec
index c07435e4b..8cf9b39f7 100644
--- a/SecurityPkg/SecurityPkg.dec
+++ b/SecurityPkg/SecurityPkg.dec
@@ -114,7 +114,8 @@
# DEFER_EXECUTE_ON_SECURITY_VIOLATION 0x00000003
# DENY_EXECUTE_ON_SECURITY_VIOLATION 0x00000004
# QUERY_USER_ON_SECURITY_VIOLATION 0x00000005
- # NOTE: Do NOT use QUERY_USER_ON_SECURITY_VIOLATION since it violates the UEFI specification and has been removed.
+ # NOTE: Do NOT use QUERY_USER_ON_SECURITY_VIOLATION and ALLOW_EXECUTE_ON_SECURITY_VIOLATION since
+ # it violates the UEFI specification and has been removed.
gEfiSecurityPkgTokenSpaceGuid.PcdOptionRomImageVerificationPolicy|0x04|UINT32|0x00000001
## Pcd for removable media.
@@ -126,7 +127,8 @@
# DEFER_EXECUTE_ON_SECURITY_VIOLATION 0x00000003
# DENY_EXECUTE_ON_SECURITY_VIOLATION 0x00000004
# QUERY_USER_ON_SECURITY_VIOLATION 0x00000005
- # NOTE: Do NOT use QUERY_USER_ON_SECURITY_VIOLATION since it violates the UEFI specification and has been removed.
+ # NOTE: Do NOT use QUERY_USER_ON_SECURITY_VIOLATION and ALLOW_EXECUTE_ON_SECURITY_VIOLATION since
+ # it violates the UEFI specification and has been removed.
gEfiSecurityPkgTokenSpaceGuid.PcdRemovableMediaImageVerificationPolicy|0x04|UINT32|0x00000002
## Pcd for fixed media.
@@ -138,7 +140,8 @@
# DEFER_EXECUTE_ON_SECURITY_VIOLATION 0x00000003
# DENY_EXECUTE_ON_SECURITY_VIOLATION 0x00000004
# QUERY_USER_ON_SECURITY_VIOLATION 0x00000005
- # NOTE: Do NOT use QUERY_USER_ON_SECURITY_VIOLATION since it violates the UEFI specification and has been removed.
+ # NOTE: Do NOT use QUERY_USER_ON_SECURITY_VIOLATION and ALLOW_EXECUTE_ON_SECURITY_VIOLATION since
+ # it violates the UEFI specification and has been removed.
gEfiSecurityPkgTokenSpaceGuid.PcdFixedMediaImageVerificationPolicy|0x04|UINT32|0x00000003
## Defer Image Load policy settings.
diff --git a/SecurityPkg/SecurityPkg.dsc b/SecurityPkg/SecurityPkg.dsc
index ebe65b8d0..0dba0f121 100644
--- a/SecurityPkg/SecurityPkg.dsc
+++ b/SecurityPkg/SecurityPkg.dsc
@@ -129,6 +129,7 @@
# Application
#
SecurityPkg/Application/VariableInfo/VariableInfo.inf
+ SecurityPkg/Application/RngTest/RngTest.inf
#
# TPM
@@ -214,6 +215,10 @@
SecurityPkg/VariableAuthenticated/RuntimeDxe/VariableSmmRuntimeDxe.inf
SecurityPkg/Tcg/TcgSmm/TcgSmm.inf
SecurityPkg/Tcg/TrEESmm/TrEESmm.inf
+ #
+ # Random Number Generator
+ #
+ SecurityPkg/RandomNumberGenerator/RngDxe/RngDxe.inf
[Components.IPF]
SecurityPkg/VariableAuthenticated/EsalVariableDxeSal/EsalVariableDxeSal.inf
diff --git a/SecurityPkg/Tcg/TcgSmm/Tpm.asl b/SecurityPkg/Tcg/TcgSmm/Tpm.asl
index b90288f4a..448ffeccc 100644
--- a/SecurityPkg/Tcg/TcgSmm/Tpm.asl
+++ b/SecurityPkg/Tcg/TcgSmm/Tpm.asl
@@ -16,7 +16,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
DefinitionBlock (
"Tpm.aml",
"SSDT",
- 1,
+ 2,
"INTEL ",
"TcgTable",
0x1000
diff --git a/SecurityPkg/Tcg/TrEESmm/Tpm.asl b/SecurityPkg/Tcg/TrEESmm/Tpm.asl
index 507f99902..8f300fa04 100644
--- a/SecurityPkg/Tcg/TrEESmm/Tpm.asl
+++ b/SecurityPkg/Tcg/TrEESmm/Tpm.asl
@@ -16,7 +16,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
DefinitionBlock (
"Tpm.aml",
"SSDT",
- 1,
+ 2,
"INTEL ",
"Tpm2Tabl",
0x1000
diff --git a/SecurityPkg/VariableAuthenticated/RuntimeDxe/AuthService.c b/SecurityPkg/VariableAuthenticated/RuntimeDxe/AuthService.c
index 8e9135709..ee45ec977 100644
--- a/SecurityPkg/VariableAuthenticated/RuntimeDxe/AuthService.c
+++ b/SecurityPkg/VariableAuthenticated/RuntimeDxe/AuthService.c
@@ -49,14 +49,6 @@ CONST UINT8 mRsaE[] = { 0x01, 0x00, 0x01 };
VOID *mHashCtx = NULL;
//
-// Pointer to runtime buffer.
-// For "Append" operation to an existing variable, a read/modify/write operation
-// is supported by firmware internally. Reserve runtime buffer to cache previous
-// variable data in runtime phase because memory allocation is forbidden in virtual mode.
-//
-VOID *mStorageArea = NULL;
-
-//
// The serialization of the values of the VariableName, VendorGuid and Attributes
// parameters of the SetVariable() call and the TimeStamp component of the
// EFI_VARIABLE_AUTHENTICATION_2 descriptor followed by the variable's new value
@@ -192,14 +184,6 @@ AutenticatedVariableServiceInitialize (
}
//
- // Reserved runtime buffer for "Append" operation in virtual mode.
- //
- mStorageArea = AllocateRuntimePool (MAX (PcdGet32 (PcdMaxVariableSize), PcdGet32 (PcdMaxHardwareErrorVariableSize)));
- if (mStorageArea == NULL) {
- return EFI_OUT_OF_RESOURCES;
- }
-
- //
// Prepare runtime buffer for serialized data of time-based authenticated
// Variable, i.e. (VariableName, VendorGuid, Attributes, TimeStamp, Data).
//
@@ -531,7 +515,8 @@ AddPubKeyInStore (
&mVariableModuleGlobal->NonVolatileLastVariableOffset,
FALSE,
NULL,
- TRUE,
+ NULL,
+ 0,
TRUE
);
if (EFI_ERROR (Status)) {
diff --git a/SecurityPkg/VariableAuthenticated/RuntimeDxe/AuthService.h b/SecurityPkg/VariableAuthenticated/RuntimeDxe/AuthService.h
index 1fd687b03..745e3c7d8 100644
--- a/SecurityPkg/VariableAuthenticated/RuntimeDxe/AuthService.h
+++ b/SecurityPkg/VariableAuthenticated/RuntimeDxe/AuthService.h
@@ -329,7 +329,6 @@ VerifyTimeBasedPayload (
extern UINT8 mPubKeyStore[MAX_KEYDB_SIZE];
extern UINT32 mPubKeyNumber;
extern VOID *mHashCtx;
-extern VOID *mStorageArea;
extern UINT8 *mSerializationRuntimeBuffer;
#endif
diff --git a/SecurityPkg/VariableAuthenticated/RuntimeDxe/Reclaim.c b/SecurityPkg/VariableAuthenticated/RuntimeDxe/Reclaim.c
index 4f7a41cd0..b20facd9d 100644
--- a/SecurityPkg/VariableAuthenticated/RuntimeDxe/Reclaim.c
+++ b/SecurityPkg/VariableAuthenticated/RuntimeDxe/Reclaim.c
@@ -2,7 +2,7 @@
Handles non-volatile variable store garbage collection, using FTW
(Fault Tolerant Write) protocol.
-Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2009 - 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
@@ -98,8 +98,7 @@ GetLbaAndOffsetByAddress (
VariableBase. Fault Tolerant Write protocol is used for writing.
@param VariableBase Base address of variable to write
- @param Buffer Point to the data buffer.
- @param BufferSize The number of bytes of the data Buffer.
+ @param VariableBuffer Point to the variable data buffer.
@retval EFI_SUCCESS The function completed successfully.
@retval EFI_NOT_FOUND Fail to locate Fault Tolerant Write protocol.
@@ -109,15 +108,13 @@ GetLbaAndOffsetByAddress (
EFI_STATUS
FtwVariableSpace (
IN EFI_PHYSICAL_ADDRESS VariableBase,
- IN UINT8 *Buffer,
- IN UINTN BufferSize
+ IN VARIABLE_STORE_HEADER *VariableBuffer
)
{
EFI_STATUS Status;
EFI_HANDLE FvbHandle;
EFI_LBA VarLba;
UINTN VarOffset;
- UINT8 *FtwBuffer;
UINTN FtwBufferSize;
EFI_FAULT_TOLERANT_WRITE_PROTOCOL *FtwProtocol;
@@ -142,17 +139,9 @@ FtwVariableSpace (
if (EFI_ERROR (Status)) {
return EFI_ABORTED;
}
- //
- // Prepare for the variable data.
- //
- FtwBufferSize = ((VARIABLE_STORE_HEADER *) ((UINTN) VariableBase))->Size;
- FtwBuffer = AllocatePool (FtwBufferSize);
- if (FtwBuffer == NULL) {
- return EFI_OUT_OF_RESOURCES;
- }
- SetMem (FtwBuffer, FtwBufferSize, (UINT8) 0xff);
- CopyMem (FtwBuffer, Buffer, BufferSize);
+ FtwBufferSize = ((VARIABLE_STORE_HEADER *) ((UINTN) VariableBase))->Size;
+ ASSERT (FtwBufferSize == VariableBuffer->Size);
//
// FTW write record.
@@ -164,9 +153,8 @@ FtwVariableSpace (
FtwBufferSize, // NumBytes
NULL, // PrivateData NULL
FvbHandle, // Fvb Handle
- FtwBuffer // write buffer
+ (VOID *) VariableBuffer // write buffer
);
- FreePool (FtwBuffer);
return Status;
}
diff --git a/SecurityPkg/VariableAuthenticated/RuntimeDxe/Variable.c b/SecurityPkg/VariableAuthenticated/RuntimeDxe/Variable.c
index a0419f080..28d026a0a 100644
--- a/SecurityPkg/VariableAuthenticated/RuntimeDxe/Variable.c
+++ b/SecurityPkg/VariableAuthenticated/RuntimeDxe/Variable.c
@@ -701,6 +701,7 @@ PubKeyStoreFilter (
*NewPubKeyIndex = AllocateZeroPool ((PubKeyNumber + 1) * sizeof (UINT32));
if (*NewPubKeyIndex == NULL) {
FreePool (*NewPubKeyStore);
+ *NewPubKeyStore = NULL;
return EFI_OUT_OF_RESOURCES;
}
@@ -731,11 +732,12 @@ PubKeyStoreFilter (
@param[in] IsVolatile The variable store is volatile or not;
if it is non-volatile, need FTW.
@param[in, out] UpdatingPtrTrack Pointer to updating variable pointer track structure.
+ @param[in] NewVariable Pointer to new variable.
+ @param[in] NewVariableSize New variable size.
@param[in] ReclaimPubKeyStore Reclaim for public key database or not.
- @param[in] ReclaimAnyway If TRUE, do reclaim anyway.
@return EFI_SUCCESS Reclaim operation has finished successfully.
- @return EFI_OUT_OF_RESOURCES No enough memory resources.
+ @return EFI_OUT_OF_RESOURCES No enough memory resources or variable space.
@return EFI_DEVICE_ERROR The public key database doesn't exist.
@return Others Unexpect error happened during reclaim operation.
@@ -746,8 +748,9 @@ Reclaim (
OUT UINTN *LastVariableOffset,
IN BOOLEAN IsVolatile,
IN OUT VARIABLE_POINTER_TRACK *UpdatingPtrTrack,
- IN BOOLEAN ReclaimPubKeyStore,
- IN BOOLEAN ReclaimAnyway
+ IN VARIABLE_HEADER *NewVariable,
+ IN UINTN NewVariableSize,
+ IN BOOLEAN ReclaimPubKeyStore
)
{
VARIABLE_HEADER *Variable;
@@ -758,31 +761,28 @@ Reclaim (
UINT8 *ValidBuffer;
UINTN MaximumBufferSize;
UINTN VariableSize;
- UINTN VariableNameSize;
- UINTN UpdatingVariableNameSize;
UINTN NameSize;
UINT8 *CurrPtr;
VOID *Point0;
VOID *Point1;
BOOLEAN FoundAdded;
EFI_STATUS Status;
- CHAR16 *VariableNamePtr;
- CHAR16 *UpdatingVariableNamePtr;
UINTN CommonVariableTotalSize;
UINTN HwErrVariableTotalSize;
UINT32 *NewPubKeyIndex;
UINT8 *NewPubKeyStore;
UINT32 NewPubKeySize;
VARIABLE_HEADER *PubKeyHeader;
- BOOLEAN NeedDoReclaim;
VARIABLE_HEADER *UpdatingVariable;
+ VARIABLE_HEADER *UpdatingInDeletedTransition;
UpdatingVariable = NULL;
+ UpdatingInDeletedTransition = NULL;
if (UpdatingPtrTrack != NULL) {
UpdatingVariable = UpdatingPtrTrack->CurrPtr;
+ UpdatingInDeletedTransition = UpdatingPtrTrack->InDeletedTransitionPtr;
}
- NeedDoReclaim = FALSE;
VariableStoreHeader = (VARIABLE_STORE_HEADER *) ((UINTN) VariableBase);
CommonVariableTotalSize = 0;
@@ -791,40 +791,50 @@ Reclaim (
NewPubKeyStore = NULL;
NewPubKeySize = 0;
PubKeyHeader = NULL;
-
- //
- // Start Pointers for the variable.
- //
- Variable = GetStartPointer (VariableStoreHeader);
- MaximumBufferSize = sizeof (VARIABLE_STORE_HEADER);
- while (IsValidVariableHeader (Variable)) {
- NextVariable = GetNextVariablePtr (Variable);
- if (Variable->State == VAR_ADDED ||
- Variable->State == (VAR_IN_DELETED_TRANSITION & VAR_ADDED)
- ) {
- VariableSize = (UINTN) NextVariable - (UINTN) Variable;
- MaximumBufferSize += VariableSize;
- } else {
- NeedDoReclaim = TRUE;
- }
+ if (IsVolatile) {
+ //
+ // Start Pointers for the variable.
+ //
+ Variable = GetStartPointer (VariableStoreHeader);
+ MaximumBufferSize = sizeof (VARIABLE_STORE_HEADER);
- Variable = NextVariable;
- }
+ while (IsValidVariableHeader (Variable)) {
+ NextVariable = GetNextVariablePtr (Variable);
+ if ((Variable->State == VAR_ADDED || Variable->State == (VAR_IN_DELETED_TRANSITION & VAR_ADDED)) &&
+ Variable != UpdatingVariable &&
+ Variable != UpdatingInDeletedTransition
+ ) {
+ VariableSize = (UINTN) NextVariable - (UINTN) Variable;
+ MaximumBufferSize += VariableSize;
+ }
- if (!ReclaimAnyway && !NeedDoReclaim) {
- DEBUG ((EFI_D_INFO, "Variable driver: no DELETED variable found, so no variable space could be reclaimed.\n"));
- return EFI_SUCCESS;
- }
+ Variable = NextVariable;
+ }
- //
- // Reserve the 1 Bytes with Oxff to identify the
- // end of the variable buffer.
- //
- MaximumBufferSize += 1;
- ValidBuffer = AllocatePool (MaximumBufferSize);
- if (ValidBuffer == NULL) {
- return EFI_OUT_OF_RESOURCES;
+ if (NewVariable != NULL) {
+ //
+ // Add the new variable size.
+ //
+ MaximumBufferSize += NewVariableSize;
+ }
+
+ //
+ // Reserve the 1 Bytes with Oxff to identify the
+ // end of the variable buffer.
+ //
+ MaximumBufferSize += 1;
+ ValidBuffer = AllocatePool (MaximumBufferSize);
+ if (ValidBuffer == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+ } else {
+ //
+ // For NV variable reclaim, don't allocate pool here and just use mNvVariableCache
+ // as the buffer to reduce SMRAM consumption for SMM variable driver.
+ //
+ MaximumBufferSize = mNvVariableCache->Size;
+ ValidBuffer = (UINT8 *) mNvVariableCache;
}
SetMem (ValidBuffer, MaximumBufferSize, 0xff);
@@ -836,6 +846,7 @@ Reclaim (
CurrPtr = (UINT8 *) GetStartPointer ((VARIABLE_STORE_HEADER *) ValidBuffer);
if (ReclaimPubKeyStore) {
+ ASSERT (IsVolatile == FALSE);
//
// Trim the PubKeyStore and get new PubKeyIndex.
//
@@ -847,14 +858,13 @@ Reclaim (
&NewPubKeySize
);
if (EFI_ERROR (Status)) {
- FreePool (ValidBuffer);
- return Status;
+ goto Done;
}
//
// Refresh the PubKeyIndex for all valid variables (ADDED and IN_DELETED_TRANSITION).
//
- Variable = GetStartPointer (mNvVariableCache);
+ Variable = GetStartPointer (VariableStoreHeader);
while (IsValidVariableHeader (Variable)) {
NextVariable = GetNextVariablePtr (Variable);
if (Variable->State == VAR_ADDED || Variable->State == (VAR_IN_DELETED_TRANSITION & VAR_ADDED)) {
@@ -872,9 +882,9 @@ Reclaim (
CopyMem (CurrPtr, (UINT8 *) Variable, VariableSize);
((VARIABLE_HEADER*) CurrPtr)->PubKeyIndex = NewPubKeyIndex[Variable->PubKeyIndex];
CurrPtr += VariableSize;
- if ((!IsVolatile) && ((Variable->Attributes & EFI_VARIABLE_HARDWARE_ERROR_RECORD) == EFI_VARIABLE_HARDWARE_ERROR_RECORD)) {
+ if ((Variable->Attributes & EFI_VARIABLE_HARDWARE_ERROR_RECORD) == EFI_VARIABLE_HARDWARE_ERROR_RECORD) {
HwErrVariableTotalSize += VariableSize;
- } else if ((!IsVolatile) && ((Variable->Attributes & EFI_VARIABLE_HARDWARE_ERROR_RECORD) != EFI_VARIABLE_HARDWARE_ERROR_RECORD)) {
+ } else if ((Variable->Attributes & EFI_VARIABLE_HARDWARE_ERROR_RECORD) != EFI_VARIABLE_HARDWARE_ERROR_RECORD) {
CommonVariableTotalSize += VariableSize;
}
}
@@ -886,10 +896,8 @@ Reclaim (
//
ASSERT (PubKeyHeader != NULL);
if (PubKeyHeader == NULL) {
- FreePool (ValidBuffer);
- FreePool (NewPubKeyIndex);
- FreePool (NewPubKeyStore);
- return EFI_DEVICE_ERROR;
+ Status = EFI_DEVICE_ERROR;
+ goto Done;
}
CopyMem (CurrPtr, (UINT8*) PubKeyHeader, sizeof (VARIABLE_HEADER));
Variable = (VARIABLE_HEADER*) CurrPtr;
@@ -905,25 +913,7 @@ Reclaim (
Variable = GetStartPointer (VariableStoreHeader);
while (IsValidVariableHeader (Variable)) {
NextVariable = GetNextVariablePtr (Variable);
- if (Variable->State == VAR_ADDED) {
- if (UpdatingVariable != NULL) {
- if (UpdatingVariable == Variable) {
- Variable = NextVariable;
- continue;
- }
-
- VariableNameSize = NameSizeOfVariable(Variable);
- UpdatingVariableNameSize = NameSizeOfVariable(UpdatingVariable);
-
- VariableNamePtr = GetVariableNamePtr (Variable);
- UpdatingVariableNamePtr = GetVariableNamePtr (UpdatingVariable);
- if (CompareGuid (&Variable->VendorGuid, &UpdatingVariable->VendorGuid) &&
- VariableNameSize == UpdatingVariableNameSize &&
- CompareMem (VariableNamePtr, UpdatingVariableNamePtr, VariableNameSize) == 0 ) {
- Variable = NextVariable;
- continue;
- }
- }
+ if (Variable != UpdatingVariable && Variable->State == VAR_ADDED) {
VariableSize = (UINTN) NextVariable - (UINTN) Variable;
CopyMem (CurrPtr, (UINT8 *) Variable, VariableSize);
CurrPtr += VariableSize;
@@ -937,28 +927,12 @@ Reclaim (
}
//
- // Reinstall the variable being updated if it is not NULL.
- //
- if (UpdatingVariable != NULL) {
- VariableSize = (UINTN)(GetNextVariablePtr (UpdatingVariable)) - (UINTN)UpdatingVariable;
- CopyMem (CurrPtr, (UINT8 *) UpdatingVariable, VariableSize);
- UpdatingPtrTrack->CurrPtr = (VARIABLE_HEADER *)((UINTN)UpdatingPtrTrack->StartPtr + ((UINTN)CurrPtr - (UINTN)GetStartPointer ((VARIABLE_STORE_HEADER *) ValidBuffer)));
- UpdatingPtrTrack->InDeletedTransitionPtr = NULL;
- CurrPtr += VariableSize;
- if ((!IsVolatile) && ((UpdatingVariable->Attributes & EFI_VARIABLE_HARDWARE_ERROR_RECORD) == EFI_VARIABLE_HARDWARE_ERROR_RECORD)) {
- HwErrVariableTotalSize += VariableSize;
- } else if ((!IsVolatile) && ((UpdatingVariable->Attributes & EFI_VARIABLE_HARDWARE_ERROR_RECORD) != EFI_VARIABLE_HARDWARE_ERROR_RECORD)) {
- CommonVariableTotalSize += VariableSize;
- }
- }
-
- //
// Reinstall all in delete transition variables.
//
- Variable = GetStartPointer (VariableStoreHeader);
+ Variable = GetStartPointer (VariableStoreHeader);
while (IsValidVariableHeader (Variable)) {
NextVariable = GetNextVariablePtr (Variable);
- if (Variable != UpdatingVariable && Variable->State == (VAR_IN_DELETED_TRANSITION & VAR_ADDED)) {
+ if (Variable != UpdatingVariable && Variable != UpdatingInDeletedTransition && Variable->State == (VAR_IN_DELETED_TRANSITION & VAR_ADDED)) {
//
// Buffer has cached all ADDED variable.
@@ -1001,6 +975,42 @@ Reclaim (
Variable = NextVariable;
}
+
+ //
+ // Install the new variable if it is not NULL.
+ //
+ if (NewVariable != NULL) {
+ if ((UINTN) (CurrPtr - ValidBuffer) + NewVariableSize > VariableStoreHeader->Size) {
+ //
+ // No enough space to store the new variable.
+ //
+ Status = EFI_OUT_OF_RESOURCES;
+ goto Done;
+ }
+ if (!IsVolatile) {
+ if ((NewVariable->Attributes & EFI_VARIABLE_HARDWARE_ERROR_RECORD) == EFI_VARIABLE_HARDWARE_ERROR_RECORD) {
+ HwErrVariableTotalSize += NewVariableSize;
+ } else if ((NewVariable->Attributes & EFI_VARIABLE_HARDWARE_ERROR_RECORD) != EFI_VARIABLE_HARDWARE_ERROR_RECORD) {
+ CommonVariableTotalSize += NewVariableSize;
+ }
+ if ((HwErrVariableTotalSize > PcdGet32 (PcdHwErrStorageSize)) ||
+ (CommonVariableTotalSize > VariableStoreHeader->Size - sizeof (VARIABLE_STORE_HEADER) - PcdGet32 (PcdHwErrStorageSize))) {
+ //
+ // No enough space to store the new variable by NV or NV+HR attribute.
+ //
+ Status = EFI_OUT_OF_RESOURCES;
+ goto Done;
+ }
+ }
+
+ CopyMem (CurrPtr, (UINT8 *) NewVariable, NewVariableSize);
+ ((VARIABLE_HEADER *) CurrPtr)->State = VAR_ADDED;
+ if (UpdatingVariable != NULL) {
+ UpdatingPtrTrack->CurrPtr = (VARIABLE_HEADER *)((UINTN)UpdatingPtrTrack->StartPtr + ((UINTN)CurrPtr - (UINTN)GetStartPointer ((VARIABLE_STORE_HEADER *) ValidBuffer)));
+ UpdatingPtrTrack->InDeletedTransitionPtr = NULL;
+ }
+ CurrPtr += NewVariableSize;
+ }
}
if (IsVolatile) {
@@ -1008,7 +1018,8 @@ Reclaim (
// If volatile variable store, just copy valid buffer.
//
SetMem ((UINT8 *) (UINTN) VariableBase, VariableStoreHeader->Size, 0xff);
- CopyMem ((UINT8 *) (UINTN) VariableBase, ValidBuffer, (UINTN) (CurrPtr - (UINT8 *) ValidBuffer));
+ CopyMem ((UINT8 *) (UINTN) VariableBase, ValidBuffer, (UINTN) (CurrPtr - ValidBuffer));
+ *LastVariableOffset = (UINTN) (CurrPtr - ValidBuffer);
Status = EFI_SUCCESS;
} else {
//
@@ -1016,41 +1027,45 @@ Reclaim (
//
Status = FtwVariableSpace (
VariableBase,
- ValidBuffer,
- (UINTN) (CurrPtr - (UINT8 *) ValidBuffer)
+ (VARIABLE_STORE_HEADER *) ValidBuffer
);
- CopyMem (mNvVariableCache, (CHAR8 *)(UINTN)VariableBase, VariableStoreHeader->Size);
- }
- if (!EFI_ERROR (Status)) {
- *LastVariableOffset = (UINTN) (CurrPtr - (UINT8 *) ValidBuffer);
- if (!IsVolatile) {
+ if (!EFI_ERROR (Status)) {
+ *LastVariableOffset = (UINTN) (CurrPtr - ValidBuffer);
mVariableModuleGlobal->HwErrVariableTotalSize = HwErrVariableTotalSize;
mVariableModuleGlobal->CommonVariableTotalSize = CommonVariableTotalSize;
- }
- } else {
- NextVariable = GetStartPointer ((VARIABLE_STORE_HEADER *)(UINTN)VariableBase);
- while (IsValidVariableHeader (NextVariable)) {
- VariableSize = NextVariable->NameSize + NextVariable->DataSize + sizeof (VARIABLE_HEADER);
- if ((!IsVolatile) && ((Variable->Attributes & EFI_VARIABLE_HARDWARE_ERROR_RECORD) == EFI_VARIABLE_HARDWARE_ERROR_RECORD)) {
- mVariableModuleGlobal->HwErrVariableTotalSize += HEADER_ALIGN (VariableSize);
- } else if ((!IsVolatile) && ((Variable->Attributes & EFI_VARIABLE_HARDWARE_ERROR_RECORD) != EFI_VARIABLE_HARDWARE_ERROR_RECORD)) {
- mVariableModuleGlobal->CommonVariableTotalSize += HEADER_ALIGN (VariableSize);
- }
+ } else {
+ NextVariable = GetStartPointer ((VARIABLE_STORE_HEADER *)(UINTN)VariableBase);
+ while (IsValidVariableHeader (NextVariable)) {
+ VariableSize = NextVariable->NameSize + NextVariable->DataSize + sizeof (VARIABLE_HEADER);
+ if ((Variable->Attributes & EFI_VARIABLE_HARDWARE_ERROR_RECORD) == EFI_VARIABLE_HARDWARE_ERROR_RECORD) {
+ mVariableModuleGlobal->HwErrVariableTotalSize += HEADER_ALIGN (VariableSize);
+ } else if ((Variable->Attributes & EFI_VARIABLE_HARDWARE_ERROR_RECORD) != EFI_VARIABLE_HARDWARE_ERROR_RECORD) {
+ mVariableModuleGlobal->CommonVariableTotalSize += HEADER_ALIGN (VariableSize);
+ }
- NextVariable = GetNextVariablePtr (NextVariable);
+ NextVariable = GetNextVariablePtr (NextVariable);
+ }
+ *LastVariableOffset = (UINTN) NextVariable - (UINTN) VariableBase;
}
- *LastVariableOffset = (UINTN) NextVariable - (UINTN) VariableBase;
}
- if (NewPubKeyStore != NULL) {
- FreePool (NewPubKeyStore);
- }
+Done:
+ if (IsVolatile) {
+ FreePool (ValidBuffer);
+ } else {
+ //
+ // For NV variable reclaim, we use mNvVariableCache as the buffer, so copy the data back.
+ //
+ CopyMem (mNvVariableCache, (UINT8 *)(UINTN)VariableBase, VariableStoreHeader->Size);
- if (NewPubKeyIndex != NULL) {
- FreePool (NewPubKeyIndex);
+ if (NewPubKeyStore != NULL) {
+ FreePool (NewPubKeyStore);
+ }
+
+ if (NewPubKeyIndex != NULL) {
+ FreePool (NewPubKeyIndex);
+ }
}
-
- FreePool (ValidBuffer);
return Status;
}
@@ -1737,7 +1752,9 @@ UpdateVariable (
VARIABLE_POINTER_TRACK NvVariable;
VARIABLE_STORE_HEADER *VariableStoreHeader;
UINTN CacheOffset;
- UINTN BufSize;
+ UINT8 *BufferForMerge;
+ UINTN MergedBufSize;
+ BOOLEAN DataReady;
UINTN DataOffset;
if (mVariableModuleGlobal->FvbInstance == NULL) {
@@ -1787,7 +1804,8 @@ UpdateVariable (
//
NextVariable = GetEndPointer ((VARIABLE_STORE_HEADER *) ((UINTN) mVariableModuleGlobal->VariableGlobal.VolatileVariableBase));
ScratchSize = MAX (PcdGet32 (PcdMaxVariableSize), PcdGet32 (PcdMaxHardwareErrorVariableSize));
-
+ SetMem (NextVariable, ScratchSize, 0xff);
+ DataReady = FALSE;
if (Variable->CurrPtr != NULL) {
//
@@ -1879,7 +1897,7 @@ UpdateVariable (
// then return to the caller immediately.
//
if (DataSizeOfVariable (Variable->CurrPtr) == DataSize &&
- (CompareMem (Data, GetVariableDataPtr (Variable->CurrPtr), DataSize) == 0) &&
+ (CompareMem (Data, GetVariableDataPtr (Variable->CurrPtr), DataSize) == 0) &&
((Attributes & EFI_VARIABLE_APPEND_WRITE) == 0) &&
(TimeStamp == NULL)) {
//
@@ -1896,42 +1914,42 @@ UpdateVariable (
//
if ((Attributes & EFI_VARIABLE_APPEND_WRITE) != 0) {
//
- // Cache the previous variable data into StorageArea.
+ // NOTE: From 0 to DataOffset of NextVariable is reserved for Variable Header and Name.
+ // From DataOffset of NextVariable is to save the existing variable data.
//
DataOffset = sizeof (VARIABLE_HEADER) + Variable->CurrPtr->NameSize + GET_PAD_SIZE (Variable->CurrPtr->NameSize);
- CopyMem (mStorageArea, (UINT8*)((UINTN) Variable->CurrPtr + DataOffset), Variable->CurrPtr->DataSize);
+ BufferForMerge = (UINT8 *) ((UINTN) NextVariable + DataOffset);
+ CopyMem (BufferForMerge, (UINT8 *) ((UINTN) Variable->CurrPtr + DataOffset), Variable->CurrPtr->DataSize);
//
// Set Max Common Variable Data Size as default MaxDataSize
//
- MaxDataSize = PcdGet32 (PcdMaxVariableSize) - sizeof (VARIABLE_HEADER) - StrSize (VariableName) - GET_PAD_SIZE (StrSize (VariableName));
-
+ MaxDataSize = PcdGet32 (PcdMaxVariableSize) - DataOffset;
if ((CompareGuid (VendorGuid, &gEfiImageSecurityDatabaseGuid) &&
((StrCmp (VariableName, EFI_IMAGE_SECURITY_DATABASE) == 0) || (StrCmp (VariableName, EFI_IMAGE_SECURITY_DATABASE1) == 0))) ||
(CompareGuid (VendorGuid, &gEfiGlobalVariableGuid) && (StrCmp (VariableName, EFI_KEY_EXCHANGE_KEY_NAME) == 0))) {
-
//
// For variables with formatted as EFI_SIGNATURE_LIST, the driver shall not perform an append of
// EFI_SIGNATURE_DATA values that are already part of the existing variable value.
//
Status = AppendSignatureList (
- mStorageArea,
+ BufferForMerge,
Variable->CurrPtr->DataSize,
MaxDataSize - Variable->CurrPtr->DataSize,
- Data,
- DataSize,
- &BufSize
+ Data,
+ DataSize,
+ &MergedBufSize
);
if (Status == EFI_BUFFER_TOO_SMALL) {
//
- // Signture List is too long, Failed to Append
+ // Signature List is too long, Failed to Append.
//
Status = EFI_INVALID_PARAMETER;
goto Done;
}
- if (BufSize == Variable->CurrPtr->DataSize) {
+ if (MergedBufSize == Variable->CurrPtr->DataSize) {
if ((TimeStamp == NULL) || CompareTimeStamp (TimeStamp, &Variable->CurrPtr->TimeStamp)) {
//
// New EFI_SIGNATURE_DATA is not found and timestamp is not later
@@ -1944,29 +1962,30 @@ UpdateVariable (
}
} else {
//
- // For other Variables, append the new data to the end of previous data.
+ // For other Variables, append the new data to the end of existing data.
// Max Harware error record variable data size is different from common variable
//
if ((Attributes & EFI_VARIABLE_HARDWARE_ERROR_RECORD) == EFI_VARIABLE_HARDWARE_ERROR_RECORD) {
- MaxDataSize = PcdGet32 (PcdMaxHardwareErrorVariableSize) - sizeof (VARIABLE_HEADER) - StrSize (VariableName) - GET_PAD_SIZE (StrSize (VariableName));
+ MaxDataSize = PcdGet32 (PcdMaxHardwareErrorVariableSize) - DataOffset;
}
if (Variable->CurrPtr->DataSize + DataSize > MaxDataSize) {
//
- // Exsiting data + Appended data exceed maximum variable size limitation
+ // Existing data size + new data size exceed maximum variable size limitation.
//
Status = EFI_INVALID_PARAMETER;
goto Done;
}
- CopyMem ((UINT8*)((UINTN) mStorageArea + Variable->CurrPtr->DataSize), Data, DataSize);
- BufSize = Variable->CurrPtr->DataSize + DataSize;
+ CopyMem ((UINT8*) ((UINTN) BufferForMerge + Variable->CurrPtr->DataSize), Data, DataSize);
+ MergedBufSize = Variable->CurrPtr->DataSize + DataSize;
}
//
- // Override Data and DataSize which are used for combined data area including previous and new data.
+ // BufferForMerge(from DataOffset of NextVariable) has included the merged existing and new data.
//
- Data = mStorageArea;
- DataSize = BufSize;
+ Data = BufferForMerge;
+ DataSize = MergedBufSize;
+ DataReady = TRUE;
}
//
@@ -2023,9 +2042,7 @@ UpdateVariable (
//
// Function part - create a new variable and copy the data.
// Both update a variable and create a variable will come here.
-
- SetMem (NextVariable, ScratchSize, 0xff);
-
+ //
NextVariable->StartId = VARIABLE_DATA;
//
// NextVariable->State = VAR_ADDED;
@@ -2067,11 +2084,19 @@ UpdateVariable (
VarNameSize
);
VarDataOffset = VarNameOffset + VarNameSize + GET_PAD_SIZE (VarNameSize);
- CopyMem (
- (UINT8 *) ((UINTN) NextVariable + VarDataOffset),
- Data,
- DataSize
- );
+
+ //
+ // If DataReady is TRUE, it means the variable data has been saved into
+ // NextVariable during EFI_VARIABLE_APPEND_WRITE operation preparation.
+ //
+ if (!DataReady) {
+ CopyMem (
+ (UINT8 *) ((UINTN) NextVariable + VarDataOffset),
+ Data,
+ DataSize
+ );
+ }
+
CopyMem (&NextVariable->VendorGuid, VendorGuid, sizeof (EFI_GUID));
//
// There will be pad bytes after Data, the NextVariable->NameSize and
@@ -2101,33 +2126,29 @@ UpdateVariable (
goto Done;
}
//
- // Perform garbage collection & reclaim operation.
+ // Perform garbage collection & reclaim operation, and integrate the new variable at the same time.
//
Status = Reclaim (
mVariableModuleGlobal->VariableGlobal.NonVolatileVariableBase,
&mVariableModuleGlobal->NonVolatileLastVariableOffset,
FALSE,
Variable,
- FALSE,
+ NextVariable,
+ HEADER_ALIGN (VarSize),
FALSE
);
- if (EFI_ERROR (Status)) {
- goto Done;
- }
- //
- // If still no enough space, return out of resources.
- //
- if ((((Attributes & EFI_VARIABLE_HARDWARE_ERROR_RECORD) != 0)
- && ((VarSize + mVariableModuleGlobal->HwErrVariableTotalSize) > PcdGet32 (PcdHwErrStorageSize)))
- || (((Attributes & EFI_VARIABLE_HARDWARE_ERROR_RECORD) == 0)
- && ((VarSize + mVariableModuleGlobal->CommonVariableTotalSize) > NonVolatileVarableStoreSize - sizeof (VARIABLE_STORE_HEADER) - PcdGet32 (PcdHwErrStorageSize)))) {
- Status = EFI_OUT_OF_RESOURCES;
- goto Done;
- }
- if (Variable->CurrPtr != NULL) {
- CacheVariable->CurrPtr = (VARIABLE_HEADER *)((UINTN) CacheVariable->StartPtr + ((UINTN) Variable->CurrPtr - (UINTN) Variable->StartPtr));
- CacheVariable->InDeletedTransitionPtr = NULL;
+ if (!EFI_ERROR (Status)) {
+ //
+ // The new variable has been integrated successfully during reclaiming.
+ //
+ if (Variable->CurrPtr != NULL) {
+ CacheVariable->CurrPtr = (VARIABLE_HEADER *)((UINTN) CacheVariable->StartPtr + ((UINTN) Variable->CurrPtr - (UINTN) Variable->StartPtr));
+ CacheVariable->InDeletedTransitionPtr = NULL;
+ }
+ UpdateVariableInfo (VariableName, VendorGuid, FALSE, FALSE, TRUE, FALSE, FALSE);
+ FlushHobVariableToFlash (VariableName, VendorGuid);
}
+ goto Done;
}
//
// Four steps
@@ -2225,32 +2246,28 @@ UpdateVariable (
if ((UINT32) (VarSize + mVariableModuleGlobal->VolatileLastVariableOffset) >
((VARIABLE_STORE_HEADER *) ((UINTN) (mVariableModuleGlobal->VariableGlobal.VolatileVariableBase)))->Size) {
//
- // Perform garbage collection & reclaim operation.
+ // Perform garbage collection & reclaim operation, and integrate the new variable at the same time.
//
Status = Reclaim (
mVariableModuleGlobal->VariableGlobal.VolatileVariableBase,
&mVariableModuleGlobal->VolatileLastVariableOffset,
TRUE,
Variable,
- FALSE,
+ NextVariable,
+ HEADER_ALIGN (VarSize),
FALSE
);
- if (EFI_ERROR (Status)) {
- goto Done;
- }
- //
- // If still no enough space, return out of resources.
- //
- if ((UINT32) (VarSize + mVariableModuleGlobal->VolatileLastVariableOffset) >
- ((VARIABLE_STORE_HEADER *) ((UINTN) (mVariableModuleGlobal->VariableGlobal.VolatileVariableBase)))->Size
- ) {
- Status = EFI_OUT_OF_RESOURCES;
- goto Done;
- }
- if (Variable->CurrPtr != NULL) {
- CacheVariable->CurrPtr = (VARIABLE_HEADER *)((UINTN) CacheVariable->StartPtr + ((UINTN) Variable->CurrPtr - (UINTN) Variable->StartPtr));
- CacheVariable->InDeletedTransitionPtr = NULL;
+ if (!EFI_ERROR (Status)) {
+ //
+ // The new variable has been integrated successfully during reclaiming.
+ //
+ if (Variable->CurrPtr != NULL) {
+ CacheVariable->CurrPtr = (VARIABLE_HEADER *)((UINTN) CacheVariable->StartPtr + ((UINTN) Variable->CurrPtr - (UINTN) Variable->StartPtr));
+ CacheVariable->InDeletedTransitionPtr = NULL;
+ }
+ UpdateVariableInfo (VariableName, VendorGuid, TRUE, FALSE, TRUE, FALSE, FALSE);
}
+ goto Done;
}
NextVariable->State = VAR_ADDED;
@@ -3207,7 +3224,8 @@ ReclaimForOS(
&mVariableModuleGlobal->NonVolatileLastVariableOffset,
FALSE,
NULL,
- FALSE,
+ NULL,
+ 0,
FALSE
);
ASSERT_EFI_ERROR (Status);
@@ -3478,8 +3496,9 @@ VariableWriteServiceInitialize (
&mVariableModuleGlobal->NonVolatileLastVariableOffset,
FALSE,
NULL,
- FALSE,
- TRUE
+ NULL,
+ 0,
+ FALSE
);
if (EFI_ERROR (Status)) {
return Status;
diff --git a/SecurityPkg/VariableAuthenticated/RuntimeDxe/Variable.h b/SecurityPkg/VariableAuthenticated/RuntimeDxe/Variable.h
index 9991dfe32..b4512d2cc 100644
--- a/SecurityPkg/VariableAuthenticated/RuntimeDxe/Variable.h
+++ b/SecurityPkg/VariableAuthenticated/RuntimeDxe/Variable.h
@@ -143,8 +143,7 @@ FlushHobVariableToFlash (
VariableBase. Fault Tolerant Write protocol is used for writing.
@param VariableBase Base address of the variable to write.
- @param Buffer Point to the data buffer.
- @param BufferSize The number of bytes of the data Buffer.
+ @param VariableBuffer Point to the variable data buffer.
@retval EFI_SUCCESS The function completed successfully.
@retval EFI_NOT_FOUND Fail to locate Fault Tolerant Write protocol.
@@ -154,8 +153,7 @@ FlushHobVariableToFlash (
EFI_STATUS
FtwVariableSpace (
IN EFI_PHYSICAL_ADDRESS VariableBase,
- IN UINT8 *Buffer,
- IN UINTN BufferSize
+ IN VARIABLE_STORE_HEADER *VariableBuffer
);
/**
@@ -402,11 +400,12 @@ VariableCommonInitialize (
@param[in] IsVolatile The variable store is volatile or not;
if it is non-volatile, need FTW.
@param[in, out] UpdatingPtrTrack Pointer to updating variable pointer track structure.
+ @param[in] NewVariable Pointer to new variable.
+ @param[in] NewVariableSize New variable size.
@param[in] ReclaimPubKeyStore Reclaim for public key database or not.
- @param[in] ReclaimAnyway If TRUE, do reclaim anyway.
@return EFI_SUCCESS Reclaim operation has finished successfully.
- @return EFI_OUT_OF_RESOURCES No enough memory resources.
+ @return EFI_OUT_OF_RESOURCES No enough memory resources or variable space.
@return EFI_DEVICE_ERROR The public key database doesn't exist.
@return Others Unexpect error happened during reclaim operation.
@@ -417,8 +416,9 @@ Reclaim (
OUT UINTN *LastVariableOffset,
IN BOOLEAN IsVolatile,
IN OUT VARIABLE_POINTER_TRACK *UpdatingPtrTrack,
- IN BOOLEAN ReclaimPubKeyStore,
- IN BOOLEAN ReclaimAnyway
+ IN VARIABLE_HEADER *NewVariable,
+ IN UINTN NewVariableSize,
+ IN BOOLEAN ReclaimPubKeyStore
);
/**
diff --git a/SecurityPkg/VariableAuthenticated/RuntimeDxe/VariableDxe.c b/SecurityPkg/VariableAuthenticated/RuntimeDxe/VariableDxe.c
index f1ba9c18f..1d71e4f80 100644
--- a/SecurityPkg/VariableAuthenticated/RuntimeDxe/VariableDxe.c
+++ b/SecurityPkg/VariableAuthenticated/RuntimeDxe/VariableDxe.c
@@ -241,7 +241,6 @@ VariableClassAddressChangeEvent (
EfiConvertPointer (0x0, (VOID **) &mVariableModuleGlobal->VariableGlobal.VolatileVariableBase);
EfiConvertPointer (0x0, (VOID **) &mVariableModuleGlobal);
EfiConvertPointer (0x0, (VOID **) &mHashCtx);
- EfiConvertPointer (0x0, (VOID **) &mStorageArea);
EfiConvertPointer (0x0, (VOID **) &mSerializationRuntimeBuffer);
EfiConvertPointer (0x0, (VOID **) &mNvVariableCache);
diff --git a/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigImpl.c b/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigImpl.c
index e8af62de4..091163094 100644
--- a/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigImpl.c
+++ b/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigImpl.c
@@ -2537,7 +2537,7 @@ SecureBootCallback (
Status = EFI_SUCCESS;
- HiiGetBrowserData (NULL, NULL, BufferSize, (UINT8 *) IfrNvData);
+ HiiGetBrowserData (&gSecureBootConfigFormSetGuid, mSecureBootStorageName, BufferSize, (UINT8 *) IfrNvData);
if (Action == EFI_BROWSER_ACTION_CHANGING) {
@@ -2850,7 +2850,7 @@ SecureBootCallback (
if (!EFI_ERROR (Status)) {
BufferSize = sizeof (SECUREBOOT_CONFIGURATION);
- HiiSetBrowserData (NULL, NULL, BufferSize, (UINT8*) IfrNvData, NULL);
+ HiiSetBrowserData (&gSecureBootConfigFormSetGuid, mSecureBootStorageName, BufferSize, (UINT8*) IfrNvData, NULL);
}
FreePool (IfrNvData);
diff --git a/ShellPkg/Application/Shell/ConsoleLogger.c b/ShellPkg/Application/Shell/ConsoleLogger.c
index 0a2b1fa5e..c3729f16c 100644
--- a/ShellPkg/Application/Shell/ConsoleLogger.c
+++ b/ShellPkg/Application/Shell/ConsoleLogger.c
@@ -1,6 +1,7 @@
/** @file
Provides interface to shell console logger.
+ Copyright (c) 2013 Hewlett-Packard Development Company, L.P.
Copyright (c) 2009 - 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
@@ -640,6 +641,10 @@ ConsoleLoggerDoPageBreak(
} else if (*Resp == ShellPromptResponseQuit) {
FreePool(Resp);
ShellInfoObject.ConsoleInfo->Enabled = FALSE;
+ //
+ // When user wants to quit, the shell should stop running the command.
+ //
+ gBS->SignalEvent (ShellInfoObject.NewEfiShellProtocol->ExecutionBreak);
return (EFI_DEVICE_ERROR);
} else {
ASSERT(FALSE);
diff --git a/ShellPkg/Application/Shell/ConsoleWrappers.c b/ShellPkg/Application/Shell/ConsoleWrappers.c
index d85d1acf4..38491216f 100644
--- a/ShellPkg/Application/Shell/ConsoleWrappers.c
+++ b/ShellPkg/Application/Shell/ConsoleWrappers.c
@@ -1,6 +1,7 @@
/** @file
Function definitions for shell simple text in and out on top of file handles.
+ Copyright (c) 2013 Hewlett-Packard Development Company, L.P.
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
@@ -24,6 +25,7 @@ typedef struct {
EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL SimpleTextOut;
SHELL_FILE_HANDLE FileHandle;
EFI_HANDLE TheHandle;
+ EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *OriginalSimpleTextOut;
} SHELL_EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL;
/**
@@ -253,7 +255,14 @@ FileBasedSimpleTextOutQueryMode (
OUT UINTN *Rows
)
{
- return (EFI_UNSUPPORTED);
+ EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *PassThruProtocol = ((SHELL_EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *)This)->OriginalSimpleTextOut;
+
+ // Pass the QueryMode call thru to the original SimpleTextOutProtocol
+ return (PassThruProtocol->QueryMode(
+ PassThruProtocol,
+ ModeNumber,
+ Columns,
+ Rows));
}
/**
@@ -386,8 +395,9 @@ FileBasedSimpleTextOutOutputString (
Function to create a EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL on top of a
SHELL_FILE_HANDLE to support redirecting output from a file.
- @param[in] FileHandleToUse The pointer to the SHELL_FILE_HANDLE to use.
- @param[in] HandleLocation The pointer of a location to copy handle with protocol to.
+ @param[in] FileHandleToUse The pointer to the SHELL_FILE_HANDLE to use.
+ @param[in] HandleLocation The pointer of a location to copy handle with protocol to.
+ @param[in] OriginalProtocol The pointer to the original output protocol for pass thru of functions.
@retval NULL There was insufficient memory available.
@return A pointer to the allocated protocol structure;
@@ -395,8 +405,9 @@ FileBasedSimpleTextOutOutputString (
EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL*
EFIAPI
CreateSimpleTextOutOnFile(
- IN SHELL_FILE_HANDLE FileHandleToUse,
- IN EFI_HANDLE *HandleLocation
+ IN SHELL_FILE_HANDLE FileHandleToUse,
+ IN EFI_HANDLE *HandleLocation,
+ IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *OriginalProtocol
)
{
SHELL_EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *ProtocolToReturn;
@@ -411,6 +422,7 @@ CreateSimpleTextOutOnFile(
return (NULL);
}
ProtocolToReturn->FileHandle = FileHandleToUse;
+ ProtocolToReturn->OriginalSimpleTextOut = OriginalProtocol;
ProtocolToReturn->SimpleTextOut.Reset = FileBasedSimpleTextOutReset;
ProtocolToReturn->SimpleTextOut.TestString = FileBasedSimpleTextOutTestString;
ProtocolToReturn->SimpleTextOut.QueryMode = FileBasedSimpleTextOutQueryMode;
@@ -425,12 +437,12 @@ CreateSimpleTextOutOnFile(
FreePool(ProtocolToReturn);
return (NULL);
}
- ProtocolToReturn->SimpleTextOut.Mode->MaxMode = 0;
- ProtocolToReturn->SimpleTextOut.Mode->Mode = 0;
- ProtocolToReturn->SimpleTextOut.Mode->Attribute = 0;
- ProtocolToReturn->SimpleTextOut.Mode->CursorColumn = 0;
- ProtocolToReturn->SimpleTextOut.Mode->CursorRow = 0;
- ProtocolToReturn->SimpleTextOut.Mode->CursorVisible = FALSE;
+ ProtocolToReturn->SimpleTextOut.Mode->MaxMode = OriginalProtocol->Mode->MaxMode;
+ ProtocolToReturn->SimpleTextOut.Mode->Mode = OriginalProtocol->Mode->Mode;
+ ProtocolToReturn->SimpleTextOut.Mode->Attribute = OriginalProtocol->Mode->Attribute;
+ ProtocolToReturn->SimpleTextOut.Mode->CursorColumn = OriginalProtocol->Mode->CursorColumn;
+ ProtocolToReturn->SimpleTextOut.Mode->CursorRow = OriginalProtocol->Mode->CursorRow;
+ ProtocolToReturn->SimpleTextOut.Mode->CursorVisible = OriginalProtocol->Mode->CursorVisible;
Status = gBS->InstallProtocolInterface(
&(ProtocolToReturn->TheHandle),
diff --git a/ShellPkg/Application/Shell/ConsoleWrappers.h b/ShellPkg/Application/Shell/ConsoleWrappers.h
index 572113d39..13d12e8f4 100644
--- a/ShellPkg/Application/Shell/ConsoleWrappers.h
+++ b/ShellPkg/Application/Shell/ConsoleWrappers.h
@@ -1,6 +1,7 @@
/** @file
Function definitions for shell simple text in and out on top of file handles.
+ Copyright (c) 2013 Hewlett-Packard Development Company, L.P.
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
@@ -50,8 +51,9 @@ CloseSimpleTextInOnFile(
Function to create a EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL on top of a
SHELL_FILE_HANDLE to support redirecting output from a file.
- @param[in] FileHandleToUse The pointer to the SHELL_FILE_HANDLE to use.
- @param[in] HandleLocation The pointer of a location to copy handle with protocol to.
+ @param[in] FileHandleToUse The pointer to the SHELL_FILE_HANDLE to use.
+ @param[in] HandleLocation The pointer of a location to copy handle with protocol to.
+ @param[in] OriginalProtocol The pointer to the original output protocol for pass thru of functions.
@retval NULL There was insufficient memory available.
@return A pointer to the allocated protocol structure;
@@ -59,8 +61,9 @@ CloseSimpleTextInOnFile(
EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL*
EFIAPI
CreateSimpleTextOutOnFile(
- IN SHELL_FILE_HANDLE FileHandleToUse,
- IN EFI_HANDLE *HandleLocation
+ IN SHELL_FILE_HANDLE FileHandleToUse,
+ IN EFI_HANDLE *HandleLocation,
+ IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *OriginalProtocol
);
/**
diff --git a/ShellPkg/Application/Shell/FileHandleWrappers.c b/ShellPkg/Application/Shell/FileHandleWrappers.c
index 2ca13cb3f..ef8293c1d 100644
--- a/ShellPkg/Application/Shell/FileHandleWrappers.c
+++ b/ShellPkg/Application/Shell/FileHandleWrappers.c
@@ -3,6 +3,7 @@
StdIn, StdOut, StdErr, etc...).
Copyright (c) 2009 - 2011, Intel Corporation. All rights reserved.<BR>
+ Copyright (c) 2013, Hewlett-Packard Development Company, L.P.
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
@@ -950,8 +951,48 @@ FileInterfaceEnvClose(
IN EFI_FILE_PROTOCOL *This
)
{
+ VOID* NewBuffer;
+ UINTN NewSize;
+ EFI_STATUS Status;
+
+ //
+ // Most if not all UEFI commands will have an '\r\n' at the end of any output.
+ // Since the output was redirected to a variable, it does not make sense to
+ // keep this. So, before closing, strip the trailing '\r\n' from the variable
+ // if it exists.
+ //
+ NewBuffer = NULL;
+ NewSize = 0;
+
+ Status = SHELL_GET_ENVIRONMENT_VARIABLE(((EFI_FILE_PROTOCOL_ENVIRONMENT*)This)->Name, &NewSize, NewBuffer);
+ if (Status == EFI_BUFFER_TOO_SMALL) {
+ NewBuffer = AllocateZeroPool(NewSize + sizeof(CHAR16));
+ if (NewBuffer == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+ Status = SHELL_GET_ENVIRONMENT_VARIABLE(((EFI_FILE_PROTOCOL_ENVIRONMENT*)This)->Name, &NewSize, NewBuffer);
+ }
+
+ if (!EFI_ERROR(Status)) {
+
+ if (StrSize(NewBuffer) > 6)
+ {
+ if ((((CHAR16*)NewBuffer)[(StrSize(NewBuffer)/2) - 2] == CHAR_LINEFEED)
+ && (((CHAR16*)NewBuffer)[(StrSize(NewBuffer)/2) - 3] == CHAR_CARRIAGE_RETURN)) {
+ ((CHAR16*)NewBuffer)[(StrSize(NewBuffer)/2) - 3] = CHAR_NULL;
+ }
+
+ if (IsVolatileEnv(((EFI_FILE_PROTOCOL_ENVIRONMENT*)This)->Name)) {
+ Status = SHELL_SET_ENVIRONMENT_VARIABLE_V(((EFI_FILE_PROTOCOL_ENVIRONMENT*)This)->Name, StrSize(NewBuffer), NewBuffer);
+ } else {
+ Status = SHELL_SET_ENVIRONMENT_VARIABLE_NV(((EFI_FILE_PROTOCOL_ENVIRONMENT*)This)->Name, StrSize(NewBuffer), NewBuffer);
+ }
+ }
+ }
+
+ SHELL_FREE_NON_NULL(NewBuffer);
FreePool((EFI_FILE_PROTOCOL_ENVIRONMENT*)This);
- return (EFI_SUCCESS);
+ return (Status);
}
/**
diff --git a/ShellPkg/Application/Shell/Shell.c b/ShellPkg/Application/Shell/Shell.c
index e5a648833..1b52692ec 100644
--- a/ShellPkg/Application/Shell/Shell.c
+++ b/ShellPkg/Application/Shell/Shell.c
@@ -1415,9 +1415,9 @@ RunCommand(
}
//
- // Remove any spaces at the beginning of the string.
+ // Remove any spaces and tabs at the beginning of the string.
//
- while (CleanOriginal[0] == L' ') {
+ while ((CleanOriginal[0] == L' ') || (CleanOriginal[0] == L'\t')) {
CopyMem(CleanOriginal, CleanOriginal+1, StrSize(CleanOriginal) - sizeof(CleanOriginal[0]));
}
@@ -1593,10 +1593,15 @@ RunCommand(
if (!EFI_ERROR(Status)) {
Status = ShellCommandRunCommandHandler(ShellInfoObject.NewShellParametersProtocol->Argv[0], &ShellStatus, &LastError);
ASSERT_EFI_ERROR(Status);
- UnicodeSPrint(LeString, sizeof(LeString), L"0x%08Lx", ShellStatus);
- DEBUG_CODE(InternalEfiShellSetEnv(L"DebugLasterror", LeString, TRUE););
+
+ if (sizeof(EFI_STATUS) == sizeof(UINT64)) {
+ UnicodeSPrint(LeString, sizeof(LeString), L"0x%Lx", ShellStatus);
+ } else {
+ UnicodeSPrint(LeString, sizeof(LeString), L"0x%x", ShellStatus);
+ }
+ DEBUG_CODE(InternalEfiShellSetEnv(L"debuglasterror", LeString, TRUE););
if (LastError) {
- InternalEfiShellSetEnv(L"Lasterror", LeString, TRUE);
+ InternalEfiShellSetEnv(L"lasterror", LeString, TRUE);
}
//
// Pass thru the exitcode from the app.
@@ -1622,6 +1627,14 @@ RunCommand(
}
if (CommandWithPath == NULL || ShellIsDirectory(CommandWithPath) == EFI_SUCCESS) {
ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SHELL_NOT_FOUND), ShellInfoObject.HiiHandle, ShellInfoObject.NewShellParametersProtocol->Argv[0]);
+
+ if (sizeof(EFI_STATUS) == sizeof(UINT64)) {
+ UnicodeSPrint(LeString, sizeof(LeString), L"0x%Lx", EFI_NOT_FOUND);
+ } else {
+ UnicodeSPrint(LeString, sizeof(LeString), L"0x%x", EFI_NOT_FOUND);
+ }
+ DEBUG_CODE(InternalEfiShellSetEnv(L"debuglasterror", LeString, TRUE););
+ InternalEfiShellSetEnv(L"lasterror", LeString, TRUE);
} else {
//
// Check if it's a NSH (script) file.
@@ -1642,11 +1655,15 @@ RunCommand(
);
//
- // Updatet last error status.
+ // Update last error status.
//
- UnicodeSPrint(LeString, sizeof(LeString), L"0x%08Lx", StatusCode);
- DEBUG_CODE(InternalEfiShellSetEnv(L"DebugLasterror", LeString, TRUE););
- InternalEfiShellSetEnv(L"Lasterror", LeString, TRUE);
+ if (sizeof(EFI_STATUS) == sizeof(UINT64)) {
+ UnicodeSPrint(LeString, sizeof(LeString), L"0x%Lx", StatusCode);
+ } else {
+ UnicodeSPrint(LeString, sizeof(LeString), L"0x%x", StatusCode);
+ }
+ DEBUG_CODE(InternalEfiShellSetEnv(L"debuglasterror", LeString, TRUE););
+ InternalEfiShellSetEnv(L"lasterror", LeString, TRUE);
}
}
}
@@ -1952,9 +1969,12 @@ RunScriptFileHandle (
}
if (ShellCommandGetScriptExit()) {
+ //
+ // ShellCommandGetExitCode() always returns a UINT64
+ //
UnicodeSPrint(LeString, sizeof(LeString), L"0x%Lx", ShellCommandGetExitCode());
- DEBUG_CODE(InternalEfiShellSetEnv(L"DebugLasterror", LeString, TRUE););
- InternalEfiShellSetEnv(L"Lasterror", LeString, TRUE);
+ DEBUG_CODE(InternalEfiShellSetEnv(L"debuglasterror", LeString, TRUE););
+ InternalEfiShellSetEnv(L"lasterror", LeString, TRUE);
ShellCommandRegisterExit(FALSE, 0);
Status = EFI_SUCCESS;
diff --git a/ShellPkg/Application/Shell/ShellManParser.c b/ShellPkg/Application/Shell/ShellManParser.c
index 470f51a8e..8196a6ac9 100644
--- a/ShellPkg/Application/Shell/ShellManParser.c
+++ b/ShellPkg/Application/Shell/ShellManParser.c
@@ -1,7 +1,7 @@
/** @file
Provides interface to shell MAN file parser.
- Copyright (c) 2009 - 2011, Intel Corporation. All rights reserved.<BR>
+ Copyright (c) 2009 - 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
@@ -491,6 +491,20 @@ ManFileFindTitleSection(
}
StrCpy(TitleString, L".TH ");
StrCat(TitleString, Command);
+
+ //
+ // If the "name" ends with .efi we can safely chop that off since "help foo.efi" and "help foo"
+ // should produce the same results.
+ //
+ if ((StrLen(Command)> 4)
+ && (TitleString[StrLen(TitleString)-1] == L'i' || TitleString[StrLen(TitleString)-1] == L'I')
+ && (TitleString[StrLen(TitleString)-2] == L'f' || TitleString[StrLen(TitleString)-2] == L'F')
+ && (TitleString[StrLen(TitleString)-3] == L'e' || TitleString[StrLen(TitleString)-2] == L'E')
+ && (TitleString[StrLen(TitleString)-4] == L'.')
+ ) {
+ TitleString[StrLen(TitleString)-4] = CHAR_NULL;
+ }
+
TitleLen = StrLen(TitleString);
for (;!ShellFileHandleEof(Handle);Size = 1024) {
Status = ShellFileHandleReadLine(Handle, ReadLine, &Size, TRUE, Ascii);
diff --git a/ShellPkg/Application/Shell/ShellParametersProtocol.c b/ShellPkg/Application/Shell/ShellParametersProtocol.c
index 2f8c626b0..b6598c0cf 100644
--- a/ShellPkg/Application/Shell/ShellParametersProtocol.c
+++ b/ShellPkg/Application/Shell/ShellParametersProtocol.c
@@ -2,6 +2,7 @@
Member functions of EFI_SHELL_PARAMETERS_PROTOCOL and functions for creation,
manipulation, and initialization of EFI_SHELL_PARAMETERS_PROTOCOL.
+ Copyright (c) 2013 Hewlett-Packard Development Company, L.P.
Copyright (c) 2009 - 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
@@ -538,6 +539,35 @@ FixFileName (
}
/**
+ Fix a string to only have the environment variable name, removing starting at the first space of whatever is quoted and removing the leading and trailing %.
+
+ @param[in] FileName The filename to start with.
+
+ @retval NULL FileName was invalid.
+ @return The modified FileName.
+**/
+CHAR16*
+EFIAPI
+FixVarName (
+ IN CHAR16 *FileName
+ )
+{
+ CHAR16 *Copy;
+ CHAR16 *TempLocation;
+
+ Copy = FileName;
+
+ if (FileName[0] == L'%') {
+ Copy = FileName+1;
+ if ((TempLocation = StrStr(Copy , L"%")) != NULL) {
+ TempLocation[0] = CHAR_NULL;
+ }
+ }
+
+ return (FixFileName(Copy));
+}
+
+/**
Funcion will replace the current StdIn and StdOut in the ShellParameters protocol
structure by parsing NewCommandLine. The current values are returned to the
user.
@@ -913,17 +943,17 @@ UpdateStdInStdOutStdErr(
}
}
if (StdErrVarName != NULL) {
- if ((StdErrVarName = FixFileName(StdErrVarName)) == NULL) {
+ if ((StdErrVarName = FixVarName(StdErrVarName)) == NULL) {
Status = EFI_INVALID_PARAMETER;
}
}
if (StdOutVarName != NULL) {
- if ((StdOutVarName = FixFileName(StdOutVarName)) == NULL) {
+ if ((StdOutVarName = FixVarName(StdOutVarName)) == NULL) {
Status = EFI_INVALID_PARAMETER;
}
}
if (StdInVarName != NULL) {
- if ((StdInVarName = FixFileName(StdInVarName)) == NULL) {
+ if ((StdInVarName = FixVarName(StdInVarName)) == NULL) {
Status = EFI_INVALID_PARAMETER;
}
}
@@ -1008,7 +1038,7 @@ UpdateStdInStdOutStdErr(
}
if (!EFI_ERROR(Status)) {
ShellParameters->StdErr = TempHandle;
- gST->StdErr = CreateSimpleTextOutOnFile(TempHandle, &gST->StandardErrorHandle);
+ gST->StdErr = CreateSimpleTextOutOnFile(TempHandle, &gST->StandardErrorHandle, gST->StdErr);
}
}
@@ -1051,7 +1081,7 @@ UpdateStdInStdOutStdErr(
}
if (!EFI_ERROR(Status)) {
ShellParameters->StdOut = TempHandle;
- gST->ConOut = CreateSimpleTextOutOnFile(TempHandle, &gST->ConsoleOutHandle);
+ gST->ConOut = CreateSimpleTextOutOnFile(TempHandle, &gST->ConsoleOutHandle, gST->ConOut);
}
}
}
@@ -1069,7 +1099,7 @@ UpdateStdInStdOutStdErr(
TempHandle = CreateFileInterfaceEnv(StdOutVarName);
ASSERT(TempHandle != NULL);
ShellParameters->StdOut = TempHandle;
- gST->ConOut = CreateSimpleTextOutOnFile(TempHandle, &gST->ConsoleOutHandle);
+ gST->ConOut = CreateSimpleTextOutOnFile(TempHandle, &gST->ConsoleOutHandle, gST->ConOut);
}
//
@@ -1085,7 +1115,7 @@ UpdateStdInStdOutStdErr(
TempHandle = CreateFileInterfaceEnv(StdErrVarName);
ASSERT(TempHandle != NULL);
ShellParameters->StdErr = TempHandle;
- gST->StdErr = CreateSimpleTextOutOnFile(TempHandle, &gST->StandardErrorHandle);
+ gST->StdErr = CreateSimpleTextOutOnFile(TempHandle, &gST->StandardErrorHandle, gST->StdErr);
}
//
diff --git a/ShellPkg/Include/Library/ShellLib.h b/ShellPkg/Include/Library/ShellLib.h
index eefa030ad..4a79acdd5 100644
--- a/ShellPkg/Include/Library/ShellLib.h
+++ b/ShellPkg/Include/Library/ShellLib.h
@@ -1008,6 +1008,23 @@ ShellStrToUintn(
);
/**
+ Function return the number converted from a hex representation of a number.
+
+ Note: this function cannot be used when (UINTN)(-1), (0xFFFFFFFF) may be a valid
+ result. Use ShellConvertStringToUint64 instead.
+
+ @param[in] String String representation of a number.
+
+ @return The unsigned integer result of the conversion.
+ @retval (UINTN)(-1) An error occured.
+**/
+UINTN
+EFIAPI
+ShellHexStrToUintn(
+ IN CONST CHAR16 *String
+ );
+
+/**
Safely append with automatic string resizing given length of Destination and
desired length of copy from Source.
diff --git a/ShellPkg/Library/UefiHandleParsingLib/UefiHandleParsingLib.c b/ShellPkg/Library/UefiHandleParsingLib/UefiHandleParsingLib.c
index 515fab329..7c2e9c735 100644
--- a/ShellPkg/Library/UefiHandleParsingLib/UefiHandleParsingLib.c
+++ b/ShellPkg/Library/UefiHandleParsingLib/UefiHandleParsingLib.c
@@ -1,6 +1,7 @@
/** @file
Provides interface to advanced shell functionality for parsing both handle and protocol database.
+ Copyright (c) 2013 Hewlett-Packard Development Company, L.P.
Copyright (c) 2010 - 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
@@ -618,7 +619,17 @@ STATIC CONST GUID_INFO_BLOCK mGuidStringList[] = {
{STRING_TOKEN(STR_KMS), &gEfiKmsProtocolGuid, NULL},
{STRING_TOKEN(STR_BLK_IO2), &gEfiBlockIo2ProtocolGuid, NULL},
{STRING_TOKEN(STR_SSC), &gEfiStorageSecurityCommandProtocolGuid, NULL},
- {STRING_TOKEN(STR_UC2), &gEfiUserCredential2ProtocolGuid, NULL},
+ {STRING_TOKEN(STR_UCRED2), &gEfiUserCredential2ProtocolGuid, NULL},
+
+//
+// UEFI 2.4
+//
+ {STRING_TOKEN(STR_DISK_IO2), &gEfiDiskIo2ProtocolGuid, NULL},
+
+//
+// PI Spec ones
+//
+ {STRING_TOKEN(STR_IDE_CONT_INIT), &gEfiIdeControllerInitProtocolGuid, NULL},
//
// terminator
@@ -753,7 +764,7 @@ GetGuidFromStringName(
if (PcdGetBool(PcdShellIncludeNtGuids)) {
for (ListWalker = mGuidStringListNT ; ListWalker != NULL && ListWalker->GuidId != NULL ; ListWalker++) {
String = HiiGetString(mHandleParsingHiiHandle, ListWalker->StringId, Lang);
- if (Name != NULL && String != NULL && StrCmp(Name, String)==0) {
+ if (Name != NULL && String != NULL && StringNoCaseCompare (&Name, &String) == 0) {
*Guid = ListWalker->GuidId;
}
SHELL_FREE_NON_NULL(String);
@@ -764,7 +775,7 @@ GetGuidFromStringName(
}
for (ListWalker = mGuidStringList ; ListWalker != NULL && ListWalker->GuidId != NULL ; ListWalker++) {
String = HiiGetString(mHandleParsingHiiHandle, ListWalker->StringId, Lang);
- if (Name != NULL && String != NULL && StrCmp(Name, String)==0) {
+ if (Name != NULL && String != NULL && StringNoCaseCompare (&Name, &String) == 0) {
*Guid = ListWalker->GuidId;
}
SHELL_FREE_NON_NULL(String);
diff --git a/ShellPkg/Library/UefiHandleParsingLib/UefiHandleParsingLib.h b/ShellPkg/Library/UefiHandleParsingLib/UefiHandleParsingLib.h
index 3b1ad2bac..37c05d04b 100644
--- a/ShellPkg/Library/UefiHandleParsingLib/UefiHandleParsingLib.h
+++ b/ShellPkg/Library/UefiHandleParsingLib/UefiHandleParsingLib.h
@@ -1,7 +1,8 @@
/** @file
Provides interface to advanced shell functionality for parsing both handle and protocol database.
- Copyright (c) 2011 - 2012, Intel Corporation. All rights reserved.<BR>
+ Copyright (c) 2013 Hewlett-Packard Development Company, L.P.
+ Copyright (c) 2011 - 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
@@ -130,6 +131,8 @@
#include <Protocol/BlockIo2.h>
#include <Protocol/StorageSecurityCommand.h>
#include <Protocol/UserCredential2.h>
+#include <Protocol/IdeControllerInit.h>
+#include <Protocol/DiskIo2.h>
#include <Library/HandleParsingLib.h>
#include <Library/UefiBootServicesTableLib.h>
@@ -143,6 +146,7 @@
#include <Library/UefiLib.h>
#include <Library/HiiLib.h>
#include <Library/ShellLib.h>
+#include <Library/SortLib.h>
typedef struct {
LIST_ENTRY Link;
diff --git a/ShellPkg/Library/UefiHandleParsingLib/UefiHandleParsingLib.inf b/ShellPkg/Library/UefiHandleParsingLib/UefiHandleParsingLib.inf
index 15226a0b2..e1d5d8c80 100644
--- a/ShellPkg/Library/UefiHandleParsingLib/UefiHandleParsingLib.inf
+++ b/ShellPkg/Library/UefiHandleParsingLib/UefiHandleParsingLib.inf
@@ -1,6 +1,7 @@
## @file
# Provides interface to advanced shell functionality for parsing both handle and protocol database.
-# Copyright (c) 2010 - 2012, Intel Corporation. All rights reserved. <BR>
+# Copyright (c) 2013 Hewlett-Packard Development Company, L.P.
+# Copyright (c) 2010 - 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
@@ -47,6 +48,7 @@
PrintLib
UefiLib
HiiLib
+ SortLib
[Protocols]
gEfiSimpleFileSystemProtocolGuid ##CONSUMES
@@ -167,6 +169,8 @@
gEfiTcgProtocolGuid ##UNDEFINED
gEfiHiiPackageListProtocolGuid ##UNDEFINED
gEfiDriverFamilyOverrideProtocolGuid ##UNDEFINED
+ gEfiIdeControllerInitProtocolGuid ##UNDEFINED
+ gEfiDiskIo2ProtocolGuid ##UNDEFINED
[Guids]
gEfiFileInfoGuid ##CONSUMES
diff --git a/ShellPkg/Library/UefiHandleParsingLib/UefiHandleParsingLib.uni b/ShellPkg/Library/UefiHandleParsingLib/UefiHandleParsingLib.uni
index 6a9074eaf..998a386fa 100644
--- a/ShellPkg/Library/UefiHandleParsingLib/UefiHandleParsingLib.uni
+++ b/ShellPkg/Library/UefiHandleParsingLib/UefiHandleParsingLib.uni
Binary files differ
diff --git a/ShellPkg/Library/UefiShellDebug1CommandsLib/Mm.c b/ShellPkg/Library/UefiShellDebug1CommandsLib/Mm.c
index 5bb3cff2d..636acb21d 100644
--- a/ShellPkg/Library/UefiShellDebug1CommandsLib/Mm.c
+++ b/ShellPkg/Library/UefiShellDebug1CommandsLib/Mm.c
@@ -1,7 +1,7 @@
/** @file
Main file for Mm shell Debug1 function.
- Copyright (c) 2005 - 2011, Intel Corporation. All rights reserved.<BR>
+ Copyright (c) 2005 - 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
@@ -315,7 +315,10 @@ ShellCommandRunMm (
}
}
- if (ShellCommandLineGetFlag (Package, L"-n")) {
+ //
+ // Non interactive for a script file or for the specific parameter
+ //
+ if (gEfiShellProtocol->BatchIsActive() || ShellCommandLineGetFlag (Package, L"-n")) {
Interactive = FALSE;
}
@@ -360,6 +363,11 @@ ShellCommandRunMm (
Temp = ShellCommandLineGetRawValue(Package, 2);
if (Temp != NULL) {
+ //
+ // Per spec if value is specified, then -n is assumed.
+ //
+ Interactive = FALSE;
+
if (!ShellIsHexOrDecimalNumber(Temp, TRUE, FALSE) || EFI_ERROR(ShellConvertStringToUint64(Temp, &Value, TRUE, FALSE))) {
ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellDebug1HiiHandle, Temp);
ShellStatus = SHELL_INVALID_PARAMETER;
@@ -489,23 +497,34 @@ ShellCommandRunMm (
if (!Interactive) {
Buffer = 0;
if (AccessType == EFIMemoryMappedIo) {
- ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_MM_MMIO), gShellDebug1HiiHandle);
+ if (!gEfiShellProtocol->BatchIsActive()) {
+ ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_MM_MMIO), gShellDebug1HiiHandle);
+ }
IoDev->Mem.Read (IoDev, Width, Address, 1, &Buffer);
} else if (AccessType == EfiIo) {
- ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_MM_IO), gShellDebug1HiiHandle);
+ if (!gEfiShellProtocol->BatchIsActive()) {
+ ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_MM_IO), gShellDebug1HiiHandle);
+ }
IoDev->Io.Read (IoDev, Width, Address, 1, &Buffer);
} else if (AccessType == EfiPciConfig) {
- ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_MM_PCI), gShellDebug1HiiHandle);
+ if (!gEfiShellProtocol->BatchIsActive()) {
+ ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_MM_PCI), gShellDebug1HiiHandle);
+ }
IoDev->Pci.Read (IoDev, Width, Address, 1, &Buffer);
} else if (AccessType == EfiPciEConfig) {
- ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_MM_PCIE), gShellDebug1HiiHandle);
+ if (!gEfiShellProtocol->BatchIsActive()) {
+ ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_MM_PCIE), gShellDebug1HiiHandle);
+ }
IoDev->Pci.Read (IoDev, Width, PciEAddress, 1, &Buffer);
} else {
- ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_MM_MEM), gShellDebug1HiiHandle);
+ if (!gEfiShellProtocol->BatchIsActive()) {
+ ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_MM_MEM), gShellDebug1HiiHandle);
+ }
ReadMem (Width, Address, 1, &Buffer);
}
-
- ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_MM_ADDRESS), gShellDebug1HiiHandle, Address);
+ if (!gEfiShellProtocol->BatchIsActive()) {
+ ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_MM_ADDRESS), gShellDebug1HiiHandle, Address);
+ }
if (Size == 1) {
ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_MM_BUF2), gShellDebug1HiiHandle, (UINTN)Buffer);
} else if (Size == 2) {
diff --git a/ShellPkg/Library/UefiShellDebug1CommandsLib/Pci.c b/ShellPkg/Library/UefiShellDebug1CommandsLib/Pci.c
index 4ca1fd1bd..e67c93f95 100644
--- a/ShellPkg/Library/UefiShellDebug1CommandsLib/Pci.c
+++ b/ShellPkg/Library/UefiShellDebug1CommandsLib/Pci.c
@@ -1,6 +1,7 @@
/** @file
Main file for Pci shell Debug1 function.
+ Copyright (c) 2013 Hewlett-Packard Development Company, L.P.
Copyright (c) 2005 - 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
@@ -1388,7 +1389,6 @@ PciPrintClassCode (
{
UINT32 ClassCode;
PCI_CLASS_STRINGS ClassStrings;
- CHAR16 OutputString[PCI_CLASS_STRING_LIMIT + 1];
ClassCode = 0;
ClassCode |= ClassCodePtr[0];
@@ -1402,9 +1402,9 @@ PciPrintClassCode (
if (IncludePIF) {
//
- // Only print base class and sub class name
+ // Print base class, sub class, and programming inferface name
//
- ShellPrintEx(-1,-1, L"%s - %s - %s",
+ ShellPrintEx (-1, -1, L"%s - %s - %s",
ClassStrings.BaseClass,
ClassStrings.SubClass,
ClassStrings.PIFClass
@@ -1412,18 +1412,12 @@ PciPrintClassCode (
} else {
//
- // Print base class, sub class, and programming inferface name
+ // Only print base class and sub class name
//
- UnicodeSPrint (
- OutputString,
- PCI_CLASS_STRING_LIMIT * sizeof (CHAR16),
- L"%s - %s",
+ ShellPrintEx (-1, -1, L"%s - %s",
ClassStrings.BaseClass,
ClassStrings.SubClass
- );
-
- OutputString[PCI_CLASS_STRING_LIMIT] = 0;
- ShellPrintEx(-1,-1, L"%s", OutputString);
+ );
}
}
@@ -2359,7 +2353,6 @@ ShellCommandRunPci (
if (EFI_ERROR (Status)) {
ShellPrintHiiEx(
-1, -1, NULL, STRING_TOKEN (STR_PCI_NO_FIND), gShellDebug1HiiHandle,
- gShellDebug1HiiHandle,
Segment,
Bus
);
@@ -2632,7 +2625,7 @@ PciExplainData (
Common = &(ConfigSpace->Common);
- Print (L"\n");
+ ShellPrintEx (-1, -1, L"\r\n");
//
// Print Vendor Id and Device Id
@@ -2657,7 +2650,7 @@ PciExplainData (
//
// Print register Revision ID
//
- ShellPrintEx(-1, -1, L"/r/n");
+ ShellPrintEx(-1, -1, L"\r\n");
ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_PCI_LINE_RID), gShellDebug1HiiHandle,
INDEX_OF (&(Common->RevisionId)),
Common->RevisionId
@@ -2733,7 +2726,7 @@ PciExplainData (
//
ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_CLASS), gShellDebug1HiiHandle);
PciPrintClassCode ((UINT8 *) Common->ClassCode, TRUE);
- Print (L"\n");
+ ShellPrintEx (-1, -1, L"\r\n");
if (ShellGetExecutionBreakFlag()) {
return EFI_SUCCESS;
@@ -2824,7 +2817,7 @@ PciExplainDeviceData (
if (!BarExist) {
BarExist = TRUE;
ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_START_TYPE), gShellDebug1HiiHandle);
- Print (L" --------------------------------------------------------------------------");
+ ShellPrintEx (-1, -1, L" --------------------------------------------------------------------------");
}
Status = PciExplainBar (
@@ -2844,7 +2837,7 @@ PciExplainDeviceData (
ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_NONE), gShellDebug1HiiHandle);
} else {
- Print (L"\n --------------------------------------------------------------------------");
+ ShellPrintEx (-1, -1, L"\r\n --------------------------------------------------------------------------");
}
//
@@ -2975,7 +2968,7 @@ PciExplainBridgeData (
if (!BarExist) {
BarExist = TRUE;
ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_START_TYPE_2), gShellDebug1HiiHandle);
- Print (L" --------------------------------------------------------------------------");
+ ShellPrintEx (-1, -1, L" --------------------------------------------------------------------------");
}
Status = PciExplainBar (
@@ -2994,7 +2987,7 @@ PciExplainBridgeData (
if (!BarExist) {
ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_NONE), gShellDebug1HiiHandle);
} else {
- Print (L"\n --------------------------------------------------------------------------");
+ ShellPrintEx (-1, -1, L"\r\n --------------------------------------------------------------------------");
}
//
@@ -3022,7 +3015,7 @@ PciExplainBridgeData (
INDEX_OF (&(Bridge->SubordinateBus))
);
- Print (L" ------------------------------------------------------\n");
+ ShellPrintEx (-1, -1, L" ------------------------------------------------------\r\n");
ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_BRIDGE), gShellDebug1HiiHandle, Bridge->PrimaryBus);
ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_BRIDGE), gShellDebug1HiiHandle, Bridge->SecondaryBus);
@@ -3049,7 +3042,7 @@ PciExplainBridgeData (
// base and limit address are listed.
//
ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_RESOURCE_TYPE), gShellDebug1HiiHandle);
- Print (L"----------------------------------------------------------------------\n");
+ ShellPrintEx (-1, -1, L"----------------------------------------------------------------------\r\n");
//
// IO Base & Limit
@@ -3218,7 +3211,7 @@ PciExplainBar (
//
IsMem = FALSE;
ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_ONE_VAR_4), gShellDebug1HiiHandle, *Bar & 0xfffffffc);
- Print (L"I/O ");
+ ShellPrintEx (-1, -1, L"I/O ");
}
//
@@ -3292,7 +3285,7 @@ PciExplainBar (
} else {
ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_RSHIFT), gShellDebug1HiiHandle, (UINT32) RShiftU64 (NewBar64, 32));
ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_RSHIFT), gShellDebug1HiiHandle, (UINT32) NewBar64);
- Print (L" ");
+ ShellPrintEx (-1, -1, L" ");
ShellPrintHiiEx(-1, -1, NULL,
STRING_TOKEN (STR_PCI2_RSHIFT),
gShellDebug1HiiHandle,
@@ -3352,7 +3345,7 @@ PciExplainCardBusData (
INDEX_OF (&(CardBus->SubordinateBusNumber))
);
- Print (L" ------------------------------------------------------\n");
+ ShellPrintEx (-1, -1, L" ------------------------------------------------------\r\n");
ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_CARDBUS), gShellDebug1HiiHandle, CardBus->PciBusNumber);
ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_CARDBUS_2), gShellDebug1HiiHandle, CardBus->CardBusBusNumber);
@@ -3372,7 +3365,7 @@ PciExplainCardBusData (
// Print Memory/Io ranges this cardbus bridge forwards
//
ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_PCI2_RESOURCE_TYPE_2), gShellDebug1HiiHandle);
- Print (L"----------------------------------------------------------------------\n");
+ ShellPrintEx (-1, -1, L"----------------------------------------------------------------------\r\n");
ShellPrintHiiEx(-1, -1, NULL,
STRING_TOKEN (STR_PCI2_MEM_3),
@@ -3805,8 +3798,8 @@ ExplainPcieCapReg (
CHAR16 *DevicePortType;
PcieCapReg = PciExpressCap->PcieCapReg;
- Print (
- L" Capability Version(3:0): %E0x%04x%N\n",
+ ShellPrintEx (-1, -1,
+ L" Capability Version(3:0): %E0x%04x%N\r\n",
PCIE_CAP_VERSION (PcieCapReg)
);
if ((UINT8) PCIE_CAP_DEVICEPORT_TYPE (PcieCapReg) < PCIE_DEVICE_PORT_TYPE_MAX) {
@@ -3814,8 +3807,8 @@ ExplainPcieCapReg (
} else {
DevicePortType = L"Unknown Type";
}
- Print (
- L" Device/PortType(7:4): %E%s%N\n",
+ ShellPrintEx (-1, -1,
+ L" Device/PortType(7:4): %E%s%N\r\n",
DevicePortType
);
//
@@ -3825,13 +3818,13 @@ ExplainPcieCapReg (
//
if (PCIE_CAP_DEVICEPORT_TYPE (PcieCapReg) == PCIE_ROOT_COMPLEX_ROOT_PORT ||
PCIE_CAP_DEVICEPORT_TYPE (PcieCapReg) == PCIE_SWITCH_DOWNSTREAM_PORT) {
- Print (
- L" Slot Implemented(8): %E%d%N\n",
+ ShellPrintEx (-1, -1,
+ L" Slot Implemented(8): %E%d%N\r\n",
PCIE_CAP_SLOT_IMPLEMENTED (PcieCapReg)
);
}
- Print (
- L" Interrupt Message Number(13:9): %E0x%05x%N\n",
+ ShellPrintEx (-1, -1,
+ L" Interrupt Message Number(13:9): %E0x%05x%N\r\n",
PCIE_CAP_INT_MSG_NUM (PcieCapReg)
);
return EFI_SUCCESS;
@@ -3858,18 +3851,18 @@ ExplainPcieDeviceCap (
PcieCapReg = PciExpressCap->PcieCapReg;
PcieDeviceCap = PciExpressCap->PcieDeviceCap;
DevicePortType = (UINT8) PCIE_CAP_DEVICEPORT_TYPE (PcieCapReg);
- Print (L" Max_Payload_Size Supported(2:0): ");
+ ShellPrintEx (-1, -1, L" Max_Payload_Size Supported(2:0): ");
if (PCIE_CAP_MAX_PAYLOAD (PcieDeviceCap) < 6) {
- Print (L"%E%d bytes%N\n", 1 << (PCIE_CAP_MAX_PAYLOAD (PcieDeviceCap) + 7));
+ ShellPrintEx (-1, -1, L"%E%d bytes%N\r\n", 1 << (PCIE_CAP_MAX_PAYLOAD (PcieDeviceCap) + 7));
} else {
- Print (L"%EUnknown%N\n");
+ ShellPrintEx (-1, -1, L"%EUnknown%N\r\n");
}
- Print (
- L" Phantom Functions Supported(4:3): %E%d%N\n",
+ ShellPrintEx (-1, -1,
+ L" Phantom Functions Supported(4:3): %E%d%N\r\n",
PCIE_CAP_PHANTOM_FUNC (PcieDeviceCap)
);
- Print (
- L" Extended Tag Field Supported(5): %E%d-bit Tag field supported%N\n",
+ ShellPrintEx (-1, -1,
+ L" Extended Tag Field Supported(5): %E%d-bit Tag field supported%N\r\n",
PCIE_CAP_EXTENDED_TAG (PcieDeviceCap) ? 8 : 5
);
//
@@ -3878,25 +3871,25 @@ ExplainPcieDeviceCap (
if (IS_PCIE_ENDPOINT (DevicePortType)) {
L0sLatency = (UINT8) PCIE_CAP_L0SLATENCY (PcieDeviceCap);
L1Latency = (UINT8) PCIE_CAP_L1LATENCY (PcieDeviceCap);
- Print (L" Endpoint L0s Acceptable Latency(8:6): ");
+ ShellPrintEx (-1, -1, L" Endpoint L0s Acceptable Latency(8:6): ");
if (L0sLatency < 4) {
- Print (L"%EMaximum of %d ns%N\n", 1 << (L0sLatency + 6));
+ ShellPrintEx (-1, -1, L"%EMaximum of %d ns%N\r\n", 1 << (L0sLatency + 6));
} else {
if (L0sLatency < 7) {
- Print (L"%EMaximum of %d us%N\n", 1 << (L0sLatency - 3));
+ ShellPrintEx (-1, -1, L"%EMaximum of %d us%N\r\n", 1 << (L0sLatency - 3));
} else {
- Print (L"%ENo limit%N\n");
+ ShellPrintEx (-1, -1, L"%ENo limit%N\r\n");
}
}
- Print (L" Endpoint L1 Acceptable Latency(11:9): ");
+ ShellPrintEx (-1, -1, L" Endpoint L1 Acceptable Latency(11:9): ");
if (L1Latency < 7) {
- Print (L"%EMaximum of %d us%N\n", 1 << (L1Latency + 1));
+ ShellPrintEx (-1, -1, L"%EMaximum of %d us%N\r\n", 1 << (L1Latency + 1));
} else {
- Print (L"%ENo limit%N\n");
+ ShellPrintEx (-1, -1, L"%ENo limit%N\r\n");
}
}
- Print (
- L" Role-based Error Reporting(15): %E%d%N\n",
+ ShellPrintEx (-1, -1,
+ L" Role-based Error Reporting(15): %E%d%N\r\n",
PCIE_CAP_ERR_REPORTING (PcieDeviceCap)
);
//
@@ -3905,12 +3898,12 @@ ExplainPcieDeviceCap (
// b) Captured Slot Power Scale
//
if (DevicePortType == PCIE_SWITCH_UPSTREAM_PORT) {
- Print (
- L" Captured Slot Power Limit Value(25:18): %E0x%02x%N\n",
+ ShellPrintEx (-1, -1,
+ L" Captured Slot Power Limit Value(25:18): %E0x%02x%N\r\n",
PCIE_CAP_SLOT_POWER_VALUE (PcieDeviceCap)
);
- Print (
- L" Captured Slot Power Limit Scale(27:26): %E%s%N\n",
+ ShellPrintEx (-1, -1,
+ L" Captured Slot Power Limit Scale(27:26): %E%s%N\r\n",
SlotPwrLmtScaleTable[PCIE_CAP_SLOT_POWER_SCALE (PcieDeviceCap)]
);
}
@@ -3918,8 +3911,8 @@ ExplainPcieDeviceCap (
// Function Level Reset Capability is only valid for Endpoint
//
if (IS_PCIE_ENDPOINT (DevicePortType)) {
- Print (
- L" Function Level Reset Capability(28): %E%d%N\n",
+ ShellPrintEx (-1, -1,
+ L" Function Level Reset Capability(28): %E%d%N\r\n",
PCIE_CAP_FUNC_LEVEL_RESET (PcieDeviceCap)
);
}
@@ -3943,60 +3936,60 @@ ExplainPcieDeviceControl (
PcieCapReg = PciExpressCap->PcieCapReg;
PcieDeviceControl = PciExpressCap->DeviceControl;
- Print (
- L" Correctable Error Reporting Enable(0): %E%d%N\n",
+ ShellPrintEx (-1, -1,
+ L" Correctable Error Reporting Enable(0): %E%d%N\r\n",
PCIE_CAP_COR_ERR_REPORTING_ENABLE (PcieDeviceControl)
);
- Print (
- L" Non-Fatal Error Reporting Enable(1): %E%d%N\n",
+ ShellPrintEx (-1, -1,
+ L" Non-Fatal Error Reporting Enable(1): %E%d%N\r\n",
PCIE_CAP_NONFAT_ERR_REPORTING_ENABLE (PcieDeviceControl)
);
- Print (
- L" Fatal Error Reporting Enable(2): %E%d%N\n",
+ ShellPrintEx (-1, -1,
+ L" Fatal Error Reporting Enable(2): %E%d%N\r\n",
PCIE_CAP_FATAL_ERR_REPORTING_ENABLE (PcieDeviceControl)
);
- Print (
- L" Unsupported Request Reporting Enable(3): %E%d%N\n",
+ ShellPrintEx (-1, -1,
+ L" Unsupported Request Reporting Enable(3): %E%d%N\r\n",
PCIE_CAP_UNSUP_REQ_REPORTING_ENABLE (PcieDeviceControl)
);
- Print (
- L" Enable Relaxed Ordering(4): %E%d%N\n",
+ ShellPrintEx (-1, -1,
+ L" Enable Relaxed Ordering(4): %E%d%N\r\n",
PCIE_CAP_RELAXED_ORDERING_ENABLE (PcieDeviceControl)
);
- Print (L" Max_Payload_Size(7:5): ");
+ ShellPrintEx (-1, -1, L" Max_Payload_Size(7:5): ");
if (PCIE_CAP_MAX_PAYLOAD_SIZE (PcieDeviceControl) < 6) {
- Print (L"%E%d bytes%N\n", 1 << (PCIE_CAP_MAX_PAYLOAD_SIZE (PcieDeviceControl) + 7));
+ ShellPrintEx (-1, -1, L"%E%d bytes%N\r\n", 1 << (PCIE_CAP_MAX_PAYLOAD_SIZE (PcieDeviceControl) + 7));
} else {
- Print (L"%EUnknown%N\n");
+ ShellPrintEx (-1, -1, L"%EUnknown%N\r\n");
}
- Print (
- L" Extended Tag Field Enable(8): %E%d%N\n",
+ ShellPrintEx (-1, -1,
+ L" Extended Tag Field Enable(8): %E%d%N\r\n",
PCIE_CAP_EXTENDED_TAG_ENABLE (PcieDeviceControl)
);
- Print (
- L" Phantom Functions Enable(9): %E%d%N\n",
+ ShellPrintEx (-1, -1,
+ L" Phantom Functions Enable(9): %E%d%N\r\n",
PCIE_CAP_PHANTOM_FUNC_ENABLE (PcieDeviceControl)
);
- Print (
- L" Auxiliary (AUX) Power PM Enable(10): %E%d%N\n",
+ ShellPrintEx (-1, -1,
+ L" Auxiliary (AUX) Power PM Enable(10): %E%d%N\r\n",
PCIE_CAP_AUX_PM_ENABLE (PcieDeviceControl)
);
- Print (
- L" Enable No Snoop(11): %E%d%N\n",
+ ShellPrintEx (-1, -1,
+ L" Enable No Snoop(11): %E%d%N\r\n",
PCIE_CAP_NO_SNOOP_ENABLE (PcieDeviceControl)
);
- Print (L" Max_Read_Request_Size(14:12): ");
+ ShellPrintEx (-1, -1, L" Max_Read_Request_Size(14:12): ");
if (PCIE_CAP_MAX_READ_REQ_SIZE (PcieDeviceControl) < 6) {
- Print (L"%E%d bytes%N\n", 1 << (PCIE_CAP_MAX_READ_REQ_SIZE (PcieDeviceControl) + 7));
+ ShellPrintEx (-1, -1, L"%E%d bytes%N\r\n", 1 << (PCIE_CAP_MAX_READ_REQ_SIZE (PcieDeviceControl) + 7));
} else {
- Print (L"%EUnknown%N\n");
+ ShellPrintEx (-1, -1, L"%EUnknown%N\r\n");
}
//
// Read operation is only valid for PCI Express to PCI/PCI-X Bridges
//
if (PCIE_CAP_DEVICEPORT_TYPE (PcieCapReg) == PCIE_PCIE_TO_PCIX_BRIDGE) {
- Print (
- L" Bridge Configuration Retry Enable(15): %E%d%N\n",
+ ShellPrintEx (-1, -1,
+ L" Bridge Configuration Retry Enable(15): %E%d%N\r\n",
PCIE_CAP_BRG_CONF_RETRY (PcieDeviceControl)
);
}
@@ -4018,28 +4011,28 @@ ExplainPcieDeviceStatus (
UINT16 PcieDeviceStatus;
PcieDeviceStatus = PciExpressCap->DeviceStatus;
- Print (
- L" Correctable Error Detected(0): %E%d%N\n",
+ ShellPrintEx (-1, -1,
+ L" Correctable Error Detected(0): %E%d%N\r\n",
PCIE_CAP_COR_ERR_DETECTED (PcieDeviceStatus)
);
- Print (
- L" Non-Fatal Error Detected(1): %E%d%N\n",
+ ShellPrintEx (-1, -1,
+ L" Non-Fatal Error Detected(1): %E%d%N\r\n",
PCIE_CAP_NONFAT_ERR_DETECTED (PcieDeviceStatus)
);
- Print (
- L" Fatal Error Detected(2): %E%d%N\n",
+ ShellPrintEx (-1, -1,
+ L" Fatal Error Detected(2): %E%d%N\r\n",
PCIE_CAP_FATAL_ERR_DETECTED (PcieDeviceStatus)
);
- Print (
- L" Unsupported Request Detected(3): %E%d%N\n",
+ ShellPrintEx (-1, -1,
+ L" Unsupported Request Detected(3): %E%d%N\r\n",
PCIE_CAP_UNSUP_REQ_DETECTED (PcieDeviceStatus)
);
- Print (
- L" AUX Power Detected(4): %E%d%N\n",
+ ShellPrintEx (-1, -1,
+ L" AUX Power Detected(4): %E%d%N\r\n",
PCIE_CAP_AUX_POWER_DETECTED (PcieDeviceStatus)
);
- Print (
- L" Transactions Pending(5): %E%d%N\n",
+ ShellPrintEx (-1, -1,
+ L" Transactions Pending(5): %E%d%N\r\n",
PCIE_CAP_TRANSACTION_PENDING (PcieDeviceStatus)
);
return EFI_SUCCESS;
@@ -4058,32 +4051,41 @@ ExplainPcieLinkCap (
)
{
UINT32 PcieLinkCap;
- CHAR16 *SupLinkSpeeds;
+ CHAR16 *MaxLinkSpeed;
CHAR16 *AspmValue;
PcieLinkCap = PciExpressCap->LinkCap;
- switch (PCIE_CAP_SUP_LINK_SPEEDS (PcieLinkCap)) {
+ switch (PCIE_CAP_MAX_LINK_SPEED (PcieLinkCap)) {
case 1:
- SupLinkSpeeds = L"2.5 GT/s";
+ MaxLinkSpeed = L"2.5 GT/s";
break;
case 2:
- SupLinkSpeeds = L"5.0 GT/s and 2.5 GT/s";
+ MaxLinkSpeed = L"5.0 GT/s";
+ break;
+ case 3:
+ MaxLinkSpeed = L"8.0 GT/s";
break;
default:
- SupLinkSpeeds = L"Unknown";
+ MaxLinkSpeed = L"Unknown";
break;
}
- Print (
- L" Supported Link Speeds(3:0): %E%s supported%N\n",
- SupLinkSpeeds
+ ShellPrintEx (-1, -1,
+ L" Maximum Link Speed(3:0): %E%s%N\r\n",
+ MaxLinkSpeed
);
- Print (
- L" Maximum Link Width(9:4): %Ex%d%N\n",
+ ShellPrintEx (-1, -1,
+ L" Maximum Link Width(9:4): %Ex%d%N\r\n",
PCIE_CAP_MAX_LINK_WIDTH (PcieLinkCap)
);
switch (PCIE_CAP_ASPM_SUPPORT (PcieLinkCap)) {
+ case 0:
+ AspmValue = L"Not";
+ break;
case 1:
- AspmValue = L"L0s Entry";
+ AspmValue = L"L0s";
+ break;
+ case 2:
+ AspmValue = L"L1";
break;
case 3:
AspmValue = L"L0s and L1";
@@ -4092,36 +4094,36 @@ ExplainPcieLinkCap (
AspmValue = L"Reserved";
break;
}
- Print (
- L" Active State Power Management Support(11:10): %E%s Supported%N\n",
+ ShellPrintEx (-1, -1,
+ L" Active State Power Management Support(11:10): %E%s Supported%N\r\n",
AspmValue
);
- Print (
- L" L0s Exit Latency(14:12): %E%s%N\n",
+ ShellPrintEx (-1, -1,
+ L" L0s Exit Latency(14:12): %E%s%N\r\n",
L0sLatencyStrTable[PCIE_CAP_L0S_LATENCY (PcieLinkCap)]
);
- Print (
- L" L1 Exit Latency(17:15): %E%s%N\n",
+ ShellPrintEx (-1, -1,
+ L" L1 Exit Latency(17:15): %E%s%N\r\n",
L1LatencyStrTable[PCIE_CAP_L0S_LATENCY (PcieLinkCap)]
);
- Print (
- L" Clock Power Management(18): %E%d%N\n",
+ ShellPrintEx (-1, -1,
+ L" Clock Power Management(18): %E%d%N\r\n",
PCIE_CAP_CLOCK_PM (PcieLinkCap)
);
- Print (
- L" Surprise Down Error Reporting Capable(19): %E%d%N\n",
+ ShellPrintEx (-1, -1,
+ L" Surprise Down Error Reporting Capable(19): %E%d%N\r\n",
PCIE_CAP_SUP_DOWN_ERR_REPORTING (PcieLinkCap)
);
- Print (
- L" Data Link Layer Link Active Reporting Capable(20): %E%d%N\n",
+ ShellPrintEx (-1, -1,
+ L" Data Link Layer Link Active Reporting Capable(20): %E%d%N\r\n",
PCIE_CAP_LINK_ACTIVE_REPORTING (PcieLinkCap)
);
- Print (
- L" Link Bandwidth Notification Capability(21): %E%d%N\n",
+ ShellPrintEx (-1, -1,
+ L" Link Bandwidth Notification Capability(21): %E%d%N\r\n",
PCIE_CAP_LINK_BWD_NOTIF_CAP (PcieLinkCap)
);
- Print (
- L" Port Number(31:24): %E0x%02x%N\n",
+ ShellPrintEx (-1, -1,
+ L" Port Number(31:24): %E0x%02x%N\r\n",
PCIE_CAP_PORT_NUMBER (PcieLinkCap)
);
return EFI_SUCCESS;
@@ -4144,16 +4146,16 @@ ExplainPcieLinkControl (
PcieLinkControl = PciExpressCap->LinkControl;
DevicePortType = (UINT8) PCIE_CAP_DEVICEPORT_TYPE (PciExpressCap->PcieCapReg);
- Print (
- L" Active State Power Management Control(1:0): %E%s%N\n",
+ ShellPrintEx (-1, -1,
+ L" Active State Power Management Control(1:0): %E%s%N\r\n",
ASPMCtrlStrTable[PCIE_CAP_ASPM_CONTROL (PcieLinkControl)]
);
//
// RCB is not applicable to switches
//
if (!IS_PCIE_SWITCH(DevicePortType)) {
- Print (
- L" Read Completion Boundary (RCB)(3): %E%d byte%N\n",
+ ShellPrintEx (-1, -1,
+ L" Read Completion Boundary (RCB)(3): %E%d byte%N\r\n",
1 << (PCIE_CAP_RCB (PcieLinkControl) + 6)
);
}
@@ -4166,33 +4168,33 @@ ExplainPcieLinkControl (
if (!IS_PCIE_ENDPOINT (DevicePortType) &&
DevicePortType != PCIE_SWITCH_UPSTREAM_PORT &&
DevicePortType != PCIE_PCIE_TO_PCIX_BRIDGE) {
- Print (
- L" Link Disable(4): %E%d%N\n",
+ ShellPrintEx (-1, -1,
+ L" Link Disable(4): %E%d%N\r\n",
PCIE_CAP_LINK_DISABLE (PcieLinkControl)
);
}
- Print (
- L" Common Clock Configuration(6): %E%d%N\n",
+ ShellPrintEx (-1, -1,
+ L" Common Clock Configuration(6): %E%d%N\r\n",
PCIE_CAP_COMMON_CLK_CONF (PcieLinkControl)
);
- Print (
- L" Extended Synch(7): %E%d%N\n",
+ ShellPrintEx (-1, -1,
+ L" Extended Synch(7): %E%d%N\r\n",
PCIE_CAP_EXT_SYNC (PcieLinkControl)
);
- Print (
- L" Enable Clock Power Management(8): %E%d%N\n",
+ ShellPrintEx (-1, -1,
+ L" Enable Clock Power Management(8): %E%d%N\r\n",
PCIE_CAP_CLK_PWR_MNG (PcieLinkControl)
);
- Print (
- L" Hardware Autonomous Width Disable(9): %E%d%N\n",
+ ShellPrintEx (-1, -1,
+ L" Hardware Autonomous Width Disable(9): %E%d%N\r\n",
PCIE_CAP_HW_AUTO_WIDTH_DISABLE (PcieLinkControl)
);
- Print (
- L" Link Bandwidth Management Interrupt Enable(10): %E%d%N\n",
+ ShellPrintEx (-1, -1,
+ L" Link Bandwidth Management Interrupt Enable(10): %E%d%N\r\n",
PCIE_CAP_LINK_BDW_MNG_INT_EN (PcieLinkControl)
);
- Print (
- L" Link Autonomous Bandwidth Interrupt Enable(11): %E%d%N\n",
+ ShellPrintEx (-1, -1,
+ L" Link Autonomous Bandwidth Interrupt Enable(11): %E%d%N\r\n",
PCIE_CAP_LINK_AUTO_BDW_INT_EN (PcieLinkControl)
);
return EFI_SUCCESS;
@@ -4211,46 +4213,49 @@ ExplainPcieLinkStatus (
)
{
UINT16 PcieLinkStatus;
- CHAR16 *SupLinkSpeeds;
+ CHAR16 *CurLinkSpeed;
PcieLinkStatus = PciExpressCap->LinkStatus;
switch (PCIE_CAP_CUR_LINK_SPEED (PcieLinkStatus)) {
case 1:
- SupLinkSpeeds = L"2.5 GT/s";
+ CurLinkSpeed = L"2.5 GT/s";
break;
case 2:
- SupLinkSpeeds = L"5.0 GT/s";
+ CurLinkSpeed = L"5.0 GT/s";
+ break;
+ case 3:
+ CurLinkSpeed = L"8.0 GT/s";
break;
default:
- SupLinkSpeeds = L"Reserved";
+ CurLinkSpeed = L"Reserved";
break;
}
- Print (
- L" Current Link Speed(3:0): %E%s%N\n",
- SupLinkSpeeds
+ ShellPrintEx (-1, -1,
+ L" Current Link Speed(3:0): %E%s%N\r\n",
+ CurLinkSpeed
);
- Print (
- L" Negotiated Link Width(9:4): %Ex%d%N\n",
+ ShellPrintEx (-1, -1,
+ L" Negotiated Link Width(9:4): %Ex%d%N\r\n",
PCIE_CAP_NEGO_LINK_WIDTH (PcieLinkStatus)
);
- Print (
- L" Link Training(11): %E%d%N\n",
+ ShellPrintEx (-1, -1,
+ L" Link Training(11): %E%d%N\r\n",
PCIE_CAP_LINK_TRAINING (PcieLinkStatus)
);
- Print (
- L" Slot Clock Configuration(12): %E%d%N\n",
+ ShellPrintEx (-1, -1,
+ L" Slot Clock Configuration(12): %E%d%N\r\n",
PCIE_CAP_SLOT_CLK_CONF (PcieLinkStatus)
);
- Print (
- L" Data Link Layer Link Active(13): %E%d%N\n",
+ ShellPrintEx (-1, -1,
+ L" Data Link Layer Link Active(13): %E%d%N\r\n",
PCIE_CAP_DATA_LINK_ACTIVE (PcieLinkStatus)
);
- Print (
- L" Link Bandwidth Management Status(14): %E%d%N\n",
+ ShellPrintEx (-1, -1,
+ L" Link Bandwidth Management Status(14): %E%d%N\r\n",
PCIE_CAP_LINK_BDW_MNG_STAT (PcieLinkStatus)
);
- Print (
- L" Link Autonomous Bandwidth Status(15): %E%d%N\n",
+ ShellPrintEx (-1, -1,
+ L" Link Autonomous Bandwidth Status(15): %E%d%N\r\n",
PCIE_CAP_LINK_AUTO_BDW_STAT (PcieLinkStatus)
);
return EFI_SUCCESS;
@@ -4272,52 +4277,52 @@ ExplainPcieSlotCap (
PcieSlotCap = PciExpressCap->SlotCap;
- Print (
- L" Attention Button Present(0): %E%d%N\n",
+ ShellPrintEx (-1, -1,
+ L" Attention Button Present(0): %E%d%N\r\n",
PCIE_CAP_ATT_BUT_PRESENT (PcieSlotCap)
);
- Print (
- L" Power Controller Present(1): %E%d%N\n",
+ ShellPrintEx (-1, -1,
+ L" Power Controller Present(1): %E%d%N\r\n",
PCIE_CAP_PWR_CTRLLER_PRESENT (PcieSlotCap)
);
- Print (
- L" MRL Sensor Present(2): %E%d%N\n",
+ ShellPrintEx (-1, -1,
+ L" MRL Sensor Present(2): %E%d%N\r\n",
PCIE_CAP_MRL_SENSOR_PRESENT (PcieSlotCap)
);
- Print (
- L" Attention Indicator Present(3): %E%d%N\n",
+ ShellPrintEx (-1, -1,
+ L" Attention Indicator Present(3): %E%d%N\r\n",
PCIE_CAP_ATT_IND_PRESENT (PcieSlotCap)
);
- Print (
- L" Power Indicator Present(4): %E%d%N\n",
+ ShellPrintEx (-1, -1,
+ L" Power Indicator Present(4): %E%d%N\r\n",
PCIE_CAP_PWD_IND_PRESENT (PcieSlotCap)
);
- Print (
- L" Hot-Plug Surprise(5): %E%d%N\n",
+ ShellPrintEx (-1, -1,
+ L" Hot-Plug Surprise(5): %E%d%N\r\n",
PCIE_CAP_HOTPLUG_SUPPRISE (PcieSlotCap)
);
- Print (
- L" Hot-Plug Capable(6): %E%d%N\n",
+ ShellPrintEx (-1, -1,
+ L" Hot-Plug Capable(6): %E%d%N\r\n",
PCIE_CAP_HOTPLUG_CAPABLE (PcieSlotCap)
);
- Print (
- L" Slot Power Limit Value(14:7): %E0x%02x%N\n",
+ ShellPrintEx (-1, -1,
+ L" Slot Power Limit Value(14:7): %E0x%02x%N\r\n",
PCIE_CAP_SLOT_PWR_LIMIT_VALUE (PcieSlotCap)
);
- Print (
- L" Slot Power Limit Scale(16:15): %E%s%N\n",
+ ShellPrintEx (-1, -1,
+ L" Slot Power Limit Scale(16:15): %E%s%N\r\n",
SlotPwrLmtScaleTable[PCIE_CAP_SLOT_PWR_LIMIT_SCALE (PcieSlotCap)]
);
- Print (
- L" Electromechanical Interlock Present(17): %E%d%N\n",
+ ShellPrintEx (-1, -1,
+ L" Electromechanical Interlock Present(17): %E%d%N\r\n",
PCIE_CAP_ELEC_INTERLOCK_PRESENT (PcieSlotCap)
);
- Print (
- L" No Command Completed Support(18): %E%d%N\n",
+ ShellPrintEx (-1, -1,
+ L" No Command Completed Support(18): %E%d%N\r\n",
PCIE_CAP_NO_COMM_COMPLETED_SUP (PcieSlotCap)
);
- Print (
- L" Physical Slot Number(31:19): %E%d%N\n",
+ ShellPrintEx (-1, -1,
+ L" Physical Slot Number(31:19): %E%d%N\r\n",
PCIE_CAP_PHY_SLOT_NUM (PcieSlotCap)
);
@@ -4339,50 +4344,50 @@ ExplainPcieSlotControl (
UINT16 PcieSlotControl;
PcieSlotControl = PciExpressCap->SlotControl;
- Print (
- L" Attention Button Pressed Enable(0): %E%d%N\n",
+ ShellPrintEx (-1, -1,
+ L" Attention Button Pressed Enable(0): %E%d%N\r\n",
PCIE_CAP_ATT_BUT_ENABLE (PcieSlotControl)
);
- Print (
- L" Power Fault Detected Enable(1): %E%d%N\n",
+ ShellPrintEx (-1, -1,
+ L" Power Fault Detected Enable(1): %E%d%N\r\n",
PCIE_CAP_PWR_FLT_DETECT_ENABLE (PcieSlotControl)
);
- Print (
- L" MRL Sensor Changed Enable(2): %E%d%N\n",
+ ShellPrintEx (-1, -1,
+ L" MRL Sensor Changed Enable(2): %E%d%N\r\n",
PCIE_CAP_MRL_SENSOR_CHANGE_ENABLE (PcieSlotControl)
);
- Print (
- L" Presence Detect Changed Enable(3): %E%d%N\n",
+ ShellPrintEx (-1, -1,
+ L" Presence Detect Changed Enable(3): %E%d%N\r\n",
PCIE_CAP_PRES_DETECT_CHANGE_ENABLE (PcieSlotControl)
);
- Print (
- L" Command Completed Interrupt Enable(4): %E%d%N\n",
+ ShellPrintEx (-1, -1,
+ L" Command Completed Interrupt Enable(4): %E%d%N\r\n",
PCIE_CAP_COMM_CMPL_INT_ENABLE (PcieSlotControl)
);
- Print (
- L" Hot-Plug Interrupt Enable(5): %E%d%N\n",
+ ShellPrintEx (-1, -1,
+ L" Hot-Plug Interrupt Enable(5): %E%d%N\r\n",
PCIE_CAP_HOTPLUG_INT_ENABLE (PcieSlotControl)
);
- Print (
- L" Attention Indicator Control(7:6): %E%s%N\n",
+ ShellPrintEx (-1, -1,
+ L" Attention Indicator Control(7:6): %E%s%N\r\n",
IndicatorTable[PCIE_CAP_ATT_IND_CTRL (PcieSlotControl)]
);
- Print (
- L" Power Indicator Control(9:8): %E%s%N\n",
+ ShellPrintEx (-1, -1,
+ L" Power Indicator Control(9:8): %E%s%N\r\n",
IndicatorTable[PCIE_CAP_PWR_IND_CTRL (PcieSlotControl)]
);
- Print (L" Power Controller Control(10): %EPower ");
+ ShellPrintEx (-1, -1, L" Power Controller Control(10): %EPower ");
if (PCIE_CAP_PWR_CTRLLER_CTRL (PcieSlotControl)) {
- Print (L"Off%N\n");
+ ShellPrintEx (-1, -1, L"Off%N\r\n");
} else {
- Print (L"On%N\n");
+ ShellPrintEx (-1, -1, L"On%N\r\n");
}
- Print (
- L" Electromechanical Interlock Control(11): %E%d%N\n",
+ ShellPrintEx (-1, -1,
+ L" Electromechanical Interlock Control(11): %E%d%N\r\n",
PCIE_CAP_ELEC_INTERLOCK_CTRL (PcieSlotControl)
);
- Print (
- L" Data Link Layer State Changed Enable(12): %E%d%N\n",
+ ShellPrintEx (-1, -1,
+ L" Data Link Layer State Changed Enable(12): %E%d%N\r\n",
PCIE_CAP_DLINK_STAT_CHANGE_ENABLE (PcieSlotControl)
);
return EFI_SUCCESS;
@@ -4404,46 +4409,46 @@ ExplainPcieSlotStatus (
PcieSlotStatus = PciExpressCap->SlotStatus;
- Print (
- L" Attention Button Pressed(0): %E%d%N\n",
+ ShellPrintEx (-1, -1,
+ L" Attention Button Pressed(0): %E%d%N\r\n",
PCIE_CAP_ATT_BUT_PRESSED (PcieSlotStatus)
);
- Print (
- L" Power Fault Detected(1): %E%d%N\n",
+ ShellPrintEx (-1, -1,
+ L" Power Fault Detected(1): %E%d%N\r\n",
PCIE_CAP_PWR_FLT_DETECTED (PcieSlotStatus)
);
- Print (
- L" MRL Sensor Changed(2): %E%d%N\n",
+ ShellPrintEx (-1, -1,
+ L" MRL Sensor Changed(2): %E%d%N\r\n",
PCIE_CAP_MRL_SENSOR_CHANGED (PcieSlotStatus)
);
- Print (
- L" Presence Detect Changed(3): %E%d%N\n",
+ ShellPrintEx (-1, -1,
+ L" Presence Detect Changed(3): %E%d%N\r\n",
PCIE_CAP_PRES_DETECT_CHANGED (PcieSlotStatus)
);
- Print (
- L" Command Completed(4): %E%d%N\n",
+ ShellPrintEx (-1, -1,
+ L" Command Completed(4): %E%d%N\r\n",
PCIE_CAP_COMM_COMPLETED (PcieSlotStatus)
);
- Print (L" MRL Sensor State(5): %EMRL ");
+ ShellPrintEx (-1, -1, L" MRL Sensor State(5): %EMRL ");
if (PCIE_CAP_MRL_SENSOR_STATE (PcieSlotStatus)) {
- Print (L" Opened%N\n");
+ ShellPrintEx (-1, -1, L" Opened%N\r\n");
} else {
- Print (L" Closed%N\n");
+ ShellPrintEx (-1, -1, L" Closed%N\r\n");
}
- Print (L" Presence Detect State(6): ");
+ ShellPrintEx (-1, -1, L" Presence Detect State(6): ");
if (PCIE_CAP_PRES_DETECT_STATE (PcieSlotStatus)) {
- Print (L"%ECard Present in slot%N\n");
+ ShellPrintEx (-1, -1, L"%ECard Present in slot%N\r\n");
} else {
- Print (L"%ESlot Empty%N\n");
+ ShellPrintEx (-1, -1, L"%ESlot Empty%N\r\n");
}
- Print (L" Electromechanical Interlock Status(7): %EElectromechanical Interlock ");
+ ShellPrintEx (-1, -1, L" Electromechanical Interlock Status(7): %EElectromechanical Interlock ");
if (PCIE_CAP_ELEC_INTERLOCK_STATE (PcieSlotStatus)) {
- Print (L"Engaged%N\n");
+ ShellPrintEx (-1, -1, L"Engaged%N\r\n");
} else {
- Print (L"Disengaged%N\n");
+ ShellPrintEx (-1, -1, L"Disengaged%N\r\n");
}
- Print (
- L" Data Link Layer State Changed(8): %E%d%N\n",
+ ShellPrintEx (-1, -1,
+ L" Data Link Layer State Changed(8): %E%d%N\r\n",
PCIE_CAP_DLINK_STAT_CHANGED (PcieSlotStatus)
);
return EFI_SUCCESS;
@@ -4465,24 +4470,24 @@ ExplainPcieRootControl (
PcieRootControl = PciExpressCap->RootControl;
- Print (
- L" System Error on Correctable Error Enable(0): %E%d%N\n",
+ ShellPrintEx (-1, -1,
+ L" System Error on Correctable Error Enable(0): %E%d%N\r\n",
PCIE_CAP_SYSERR_ON_CORERR_EN (PcieRootControl)
);
- Print (
- L" System Error on Non-Fatal Error Enable(1): %E%d%N\n",
+ ShellPrintEx (-1, -1,
+ L" System Error on Non-Fatal Error Enable(1): %E%d%N\r\n",
PCIE_CAP_SYSERR_ON_NONFATERR_EN (PcieRootControl)
);
- Print (
- L" System Error on Fatal Error Enable(2): %E%d%N\n",
+ ShellPrintEx (-1, -1,
+ L" System Error on Fatal Error Enable(2): %E%d%N\r\n",
PCIE_CAP_SYSERR_ON_FATERR_EN (PcieRootControl)
);
- Print (
- L" PME Interrupt Enable(3): %E%d%N\n",
+ ShellPrintEx (-1, -1,
+ L" PME Interrupt Enable(3): %E%d%N\r\n",
PCIE_CAP_PME_INT_ENABLE (PcieRootControl)
);
- Print (
- L" CRS Software Visibility Enable(4): %E%d%N\n",
+ ShellPrintEx (-1, -1,
+ L" CRS Software Visibility Enable(4): %E%d%N\r\n",
PCIE_CAP_CRS_SW_VIS_ENABLE (PcieRootControl)
);
@@ -4505,8 +4510,8 @@ ExplainPcieRootCap (
PcieRootCap = PciExpressCap->RsvdP;
- Print (
- L" CRS Software Visibility(0): %E%d%N\n",
+ ShellPrintEx (-1, -1,
+ L" CRS Software Visibility(0): %E%d%N\r\n",
PCIE_CAP_CRS_SW_VIS (PcieRootCap)
);
@@ -4529,16 +4534,16 @@ ExplainPcieRootStatus (
PcieRootStatus = PciExpressCap->RootStatus;
- Print (
- L" PME Requester ID(15:0): %E0x%04x%N\n",
+ ShellPrintEx (-1, -1,
+ L" PME Requester ID(15:0): %E0x%04x%N\r\n",
PCIE_CAP_PME_REQ_ID (PcieRootStatus)
);
- Print (
- L" PME Status(16): %E%d%N\n",
+ ShellPrintEx (-1, -1,
+ L" PME Status(16): %E%d%N\r\n",
PCIE_CAP_PME_STATUS (PcieRootStatus)
);
- Print (
- L" PME Pending(17): %E%d%N\n",
+ ShellPrintEx (-1, -1,
+ L" PME Pending(17): %E%d%N\r\n",
PCIE_CAP_PME_PENDING (PcieRootStatus)
);
return EFI_SUCCESS;
@@ -4584,7 +4589,7 @@ PciExplainPciExpress (
DevicePortType = (UINT8) PCIE_CAP_DEVICEPORT_TYPE (PciExpressCap.PcieCapReg);
- Print (L"\nPci Express device capability structure:\n");
+ ShellPrintEx (-1, -1, L"\r\nPci Express device capability structure:\r\n");
for (Index = 0; PcieExplainList[Index].Type < PcieExplainTypeMax; Index++) {
if (ShellGetExecutionBreakFlag()) {
@@ -4682,7 +4687,7 @@ PciExplainPciExpress (
//
// Start outputing PciEx extend space( 0xFF-0xFFF)
//
- Print (L"\n%HStart dumping PCIex extended configuration space (0x100 - 0xFFF).%N\n\n");
+ ShellPrintEx (-1, -1, L"\r\n%HStart dumping PCIex extended configuration space (0x100 - 0xFFF).%N\r\n\r\n");
if (ExRegBuffer != NULL) {
DumpHex (
diff --git a/ShellPkg/Library/UefiShellDebug1CommandsLib/Pci.h b/ShellPkg/Library/UefiShellDebug1CommandsLib/Pci.h
index 04a22da52..8a053ab98 100644
--- a/ShellPkg/Library/UefiShellDebug1CommandsLib/Pci.h
+++ b/ShellPkg/Library/UefiShellDebug1CommandsLib/Pci.h
@@ -1,6 +1,7 @@
/** @file
Header file for Pci shell Debug1 function.
+ Copyright (c) 2013 Hewlett-Packard Development Company, L.P.
Copyright (c) 2005 - 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
@@ -157,7 +158,7 @@ typedef enum {
//
// Link Capabilities Register
//
-#define PCIE_CAP_SUP_LINK_SPEEDS(PcieLinkCap) \
+#define PCIE_CAP_MAX_LINK_SPEED(PcieLinkCap) \
((PcieLinkCap) & 0x0f)
#define PCIE_CAP_MAX_LINK_WIDTH(PcieLinkCap) \
(((PcieLinkCap) >> 4) & 0x3f)
diff --git a/ShellPkg/Library/UefiShellLevel1CommandsLib/For.c b/ShellPkg/Library/UefiShellLevel1CommandsLib/For.c
index b01c69d3d..f0c4a23b2 100644
--- a/ShellPkg/Library/UefiShellLevel1CommandsLib/For.c
+++ b/ShellPkg/Library/UefiShellLevel1CommandsLib/For.c
@@ -254,6 +254,29 @@ InternalRemoveAliasFromList(
}
/**
+ Function to determine whether a string is decimal or hex representation of a number
+ and return the number converted from the string.
+
+ @param[in] String String representation of a number
+
+ @return the number
+ @retval (UINTN)(-1) An error ocurred.
+**/
+UINTN
+EFIAPI
+ReturnUintn(
+ IN CONST CHAR16 *String
+ )
+{
+ UINT64 RetVal;
+
+ if (!EFI_ERROR(ShellConvertStringToUint64(String, &RetVal, FALSE, FALSE))) {
+ return ((UINTN)RetVal);
+ }
+ return ((UINTN)(-1));
+}
+
+/**
Function for 'for' command.
@param[in] ImageHandle Handle to the Image (NULL if Internal).
@@ -486,9 +509,9 @@ ShellCommandRunFor (
ShellStatus = SHELL_INVALID_PARAMETER;
} else {
if (ArgSetWalker[0] == L'-') {
- Info->Current = 0 - (INTN)ShellStrToUintn(ArgSetWalker+1);
+ Info->Current = 0 - (INTN)ReturnUintn(ArgSetWalker+1);
} else {
- Info->Current = (INTN)ShellStrToUintn(ArgSetWalker);
+ Info->Current = (INTN)ReturnUintn(ArgSetWalker);
}
ArgSetWalker = StrStr(ArgSetWalker, L" ");
while (ArgSetWalker != NULL && ArgSetWalker[0] == L' ') {
@@ -508,9 +531,9 @@ ShellCommandRunFor (
ShellStatus = SHELL_INVALID_PARAMETER;
} else {
if (ArgSetWalker[0] == L'-') {
- Info->End = 0 - (INTN)ShellStrToUintn(ArgSetWalker+1);
+ Info->End = 0 - (INTN)ReturnUintn(ArgSetWalker+1);
} else {
- Info->End = (INTN)ShellStrToUintn(ArgSetWalker);
+ Info->End = (INTN)ReturnUintn(ArgSetWalker);
}
if (Info->Current < Info->End) {
Info->Step = 1;
@@ -540,9 +563,9 @@ ShellCommandRunFor (
ASSERT(Info->Step == 1 || Info->Step == -1);
} else {
if (ArgSetWalker[0] == L'-') {
- Info->Step = 0 - (INTN)ShellStrToUintn(ArgSetWalker+1);
+ Info->Step = 0 - (INTN)ReturnUintn(ArgSetWalker+1);
} else {
- Info->Step = (INTN)ShellStrToUintn(ArgSetWalker);
+ Info->Step = (INTN)ReturnUintn(ArgSetWalker);
}
if (StrStr(ArgSetWalker, L" ") != NULL) {
diff --git a/ShellPkg/Library/UefiShellLevel1CommandsLib/If.c b/ShellPkg/Library/UefiShellLevel1CommandsLib/If.c
index f5bc12638..791b1aed8 100644
--- a/ShellPkg/Library/UefiShellLevel1CommandsLib/If.c
+++ b/ShellPkg/Library/UefiShellLevel1CommandsLib/If.c
@@ -1,6 +1,7 @@
/** @file
Main file for If and else shell level 1 function.
+ Copyright (c) 2013, Hewlett-Packard Development Company, L.P.
Copyright (c) 2009 - 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
@@ -734,7 +735,11 @@ MoveToTagSpecial (
continue;
}
CommandWalker = CommandName;
- while (CommandWalker[0] == L' ') {
+
+ //
+ // Skip leading spaces and tabs.
+ //
+ while ((CommandWalker[0] == L' ') || (CommandWalker[0] == L'\t')) {
CommandWalker++;
}
TempLocation = StrStr(CommandWalker, L" ");
@@ -847,7 +852,7 @@ ShellCommandRunIf (
NULL,
STRING_TOKEN (STR_SYNTAX_NO_MATCHING),
gShellLevel1HiiHandle,
- L"EnfIf",
+ L"EndIf",
L"If",
CurrentScriptFile!=NULL
&& CurrentScriptFile->CurrentCommand!=NULL
diff --git a/ShellPkg/Library/UefiShellLevel1CommandsLib/UefiShellLevel1CommandsLib.c b/ShellPkg/Library/UefiShellLevel1CommandsLib/UefiShellLevel1CommandsLib.c
index 6f67f49ae..5dca0629d 100644
--- a/ShellPkg/Library/UefiShellLevel1CommandsLib/UefiShellLevel1CommandsLib.c
+++ b/ShellPkg/Library/UefiShellLevel1CommandsLib/UefiShellLevel1CommandsLib.c
@@ -1,6 +1,7 @@
/** @file
Main file for NULL named library for level 1 shell command functions.
+ Copyright (c) 2013, Hewlett-Packard Development Company, L.P.
Copyright (c) 2009 - 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
@@ -150,7 +151,11 @@ TestNodeForMove (
}
CommandNameWalker = CommandName;
- while(CommandNameWalker[0] == L' ') {
+
+ //
+ // Skip leading spaces and tabs.
+ //
+ while ((CommandNameWalker[0] == L' ') || (CommandNameWalker[0] == L'\t')) {
CommandNameWalker++;
}
TempLocation = StrStr(CommandNameWalker, L" ");
diff --git a/ShellPkg/Library/UefiShellLevel2CommandsLib/Map.c b/ShellPkg/Library/UefiShellLevel2CommandsLib/Map.c
index bd004beaa..590dbf79e 100644
--- a/ShellPkg/Library/UefiShellLevel2CommandsLib/Map.c
+++ b/ShellPkg/Library/UefiShellLevel2CommandsLib/Map.c
@@ -397,10 +397,14 @@ PerformSingleMappingDisplay(
CHAR16 *MediaType;
CHAR16 *DevPathString;
CHAR16 *TempSpot;
+ CHAR16 *Alias;
UINTN TempLen;
BOOLEAN Removable;
CONST CHAR16 *TempSpot2;
+ Alias = NULL;
+ TempSpot2 = NULL;
+ CurrentName = NULL;
DevPath = DevicePathFromHandle(Handle);
DevPathCopy = DevPath;
MapList = gEfiShellProtocol->GetMapFromDevicePath(&DevPathCopy);
@@ -412,14 +416,74 @@ PerformSingleMappingDisplay(
return EFI_NOT_FOUND;
}
- CurrentName = NULL;
- CurrentName = StrnCatGrow(&CurrentName, 0, MapList, 0);
- if (CurrentName == NULL) {
- return (EFI_OUT_OF_RESOURCES);
- }
- TempSpot = StrStr(CurrentName, L";");
- if (TempSpot != NULL) {
- *TempSpot = CHAR_NULL;
+ if (Normal) {
+ //
+ // Allocate a name
+ //
+ CurrentName = NULL;
+ CurrentName = StrnCatGrow(&CurrentName, 0, MapList, 0);
+ if (CurrentName == NULL) {
+ return (EFI_OUT_OF_RESOURCES);
+ }
+
+ //
+ // Chop off the other names that become "Alias(s)"
+ // leaving just the normal name
+ //
+ TempSpot = StrStr(CurrentName, L";");
+ if (TempSpot != NULL) {
+ *TempSpot = CHAR_NULL;
+ }
+ } else if (Consist) {
+ CurrentName = NULL;
+
+ //
+ // Skip the first name. This is the standard name.
+ //
+ TempSpot = StrStr(MapList, L";");
+ if (TempSpot != NULL) {
+ TempSpot++;
+ }
+ SearchList(TempSpot, L"HD*", &CurrentName, TRUE, FALSE, L";");
+ if (CurrentName == NULL) {
+ SearchList(TempSpot, L"CD*", &CurrentName, TRUE, FALSE, L";");
+ }
+ if (CurrentName == NULL) {
+ SearchList(TempSpot, L"FP*", &CurrentName, TRUE, FALSE, L";");
+ }
+ if (CurrentName == NULL) {
+ SearchList(TempSpot, L"F*", &CurrentName, TRUE, FALSE, L";");
+ }
+ if (CurrentName == NULL) {
+ //
+ // We didnt find anything, so just the first one in the list...
+ //
+ CurrentName = StrnCatGrow(&CurrentName, 0, MapList, 0);
+ if (CurrentName == NULL) {
+ return (EFI_OUT_OF_RESOURCES);
+ }
+ TempSpot = StrStr(CurrentName, L";");
+ if (TempSpot != NULL) {
+ *TempSpot = CHAR_NULL;
+ }
+ } else {
+ Alias = StrnCatGrow(&Alias, 0, MapList, 0);
+ TempSpot = StrStr(Alias, CurrentName);
+ if (TempSpot != NULL) {
+ TempSpot2 = StrStr(TempSpot, L";");
+ if (TempSpot2 != NULL) {
+ TempSpot2++; // Move past ";" from CurrentName
+ CopyMem(TempSpot, TempSpot2, StrSize(TempSpot2));
+ } else {
+ *TempSpot = CHAR_NULL;
+ }
+ }
+ if (Alias[StrLen(Alias)-1] == L';') {
+ Alias[StrLen(Alias)-1] = CHAR_NULL;
+ }
+ }
+ } else {
+ CurrentName = NULL;
}
DevPathString = ConvertDevicePathToText(DevPath, TRUE, FALSE);
if (!SFO) {
@@ -431,7 +495,7 @@ PerformSingleMappingDisplay(
STRING_TOKEN (STR_MAP_ENTRY),
gShellLevel2HiiHandle,
CurrentName,
- TempLen < StrLen(MapList)?MapList + TempLen+1:L"",
+ Alias!=NULL?Alias:(TempLen < StrLen(MapList)?MapList + TempLen+1:L""),
DevPathString
);
if (Verbose) {
@@ -454,7 +518,7 @@ PerformSingleMappingDisplay(
TempSpot2
);
}
- FreePool(MediaType);
+ SHELL_FREE_NON_NULL(MediaType);
}
} else {
TempLen = StrLen(CurrentName);
@@ -466,11 +530,12 @@ PerformSingleMappingDisplay(
gShellLevel2HiiHandle,
CurrentName,
DevPathString,
- TempLen < StrLen(MapList)?MapList + TempLen+1:L""
+ Consist?L"":(TempLen < StrLen(MapList)?MapList + TempLen+1:L"")
);
}
- FreePool(DevPathString);
- FreePool(CurrentName);
+ SHELL_FREE_NON_NULL(DevPathString);
+ SHELL_FREE_NON_NULL(CurrentName);
+ SHELL_FREE_NON_NULL(Alias);
return EFI_SUCCESS;
}
diff --git a/ShellPkg/Library/UefiShellLib/UefiShellLib.c b/ShellPkg/Library/UefiShellLib/UefiShellLib.c
index 6b985ed64..40b87fec3 100644
--- a/ShellPkg/Library/UefiShellLib/UefiShellLib.c
+++ b/ShellPkg/Library/UefiShellLib/UefiShellLib.c
@@ -3057,8 +3057,34 @@ ShellIsFileInPath(
}
/**
+ Function return the number converted from a hex representation of a number.
+
+ Note: this function cannot be used when (UINTN)(-1), (0xFFFFFFFF) may be a valid
+ result. Use ShellConvertStringToUint64 instead.
+
+ @param[in] String String representation of a number.
+
+ @return The unsigned integer result of the conversion.
+ @retval (UINTN)(-1) An error occured.
+**/
+UINTN
+EFIAPI
+ShellHexStrToUintn(
+ IN CONST CHAR16 *String
+ )
+{
+ UINT64 RetVal;
+
+ if (!EFI_ERROR(ShellConvertStringToUint64(String, &RetVal, TRUE, TRUE))) {
+ return ((UINTN)RetVal);
+ }
+
+ return ((UINTN)(-1));
+}
+
+/**
Function to determine whether a string is decimal or hex representation of a number
- and return the number converted from the string.
+ and return the number converted from the string. Spaces are always skipped.
@param[in] String String representation of a number
diff --git a/SourceLevelDebugPkg/Library/DebugAgent/DebugAgentCommon/DebugAgent.c b/SourceLevelDebugPkg/Library/DebugAgent/DebugAgentCommon/DebugAgent.c
index 01711ff08..239cf63f6 100644
--- a/SourceLevelDebugPkg/Library/DebugAgent/DebugAgentCommon/DebugAgent.c
+++ b/SourceLevelDebugPkg/Library/DebugAgent/DebugAgentCommon/DebugAgent.c
@@ -24,6 +24,114 @@ CHAR8 mErrorMsgConnectOK[] = "HOST connection is successful!\r\n";
CHAR8 mErrorMsgConnectFail[] = "HOST connection is failed!\r\n";
CHAR8 mWarningMsgIngoreBreakpoint[] = "Ignore break point in SMM for SMI issued during DXE debugging!\r\n";
+//
+// Vector Handoff Info list used by Debug Agent for persist
+//
+EFI_VECTOR_HANDOFF_INFO mVectorHandoffInfoDebugAgent[] = {
+ {
+ DEBUG_EXCEPT_DIVIDE_ERROR, // Vector 0
+ EFI_VECTOR_HANDOFF_HOOK_BEFORE,
+ EFI_DEBUG_AGENT_GUID
+ },
+ {
+ DEBUG_EXCEPT_DEBUG, // Vector 1
+ EFI_VECTOR_HANDOFF_DO_NOT_HOOK,
+ EFI_DEBUG_AGENT_GUID
+ },
+ {
+ DEBUG_EXCEPT_NMI, // Vector 2
+ EFI_VECTOR_HANDOFF_HOOK_BEFORE,
+ EFI_DEBUG_AGENT_GUID
+ },
+ {
+ DEBUG_EXCEPT_BREAKPOINT, // Vector 3
+ EFI_VECTOR_HANDOFF_DO_NOT_HOOK,
+ EFI_DEBUG_AGENT_GUID
+ },
+ {
+ DEBUG_EXCEPT_OVERFLOW, // Vector 4
+ EFI_VECTOR_HANDOFF_HOOK_BEFORE,
+ EFI_DEBUG_AGENT_GUID
+ },
+ {
+ DEBUG_EXCEPT_BOUND, // Vector 5
+ EFI_VECTOR_HANDOFF_HOOK_BEFORE,
+ EFI_DEBUG_AGENT_GUID
+ },
+ {
+ DEBUG_EXCEPT_INVALID_OPCODE, // Vector 6
+ EFI_VECTOR_HANDOFF_HOOK_BEFORE,
+ EFI_DEBUG_AGENT_GUID
+ },
+ {
+ DEBUG_EXCEPT_DOUBLE_FAULT, // Vector 8
+ EFI_VECTOR_HANDOFF_HOOK_BEFORE,
+ EFI_DEBUG_AGENT_GUID
+ },
+ {
+ DEBUG_EXCEPT_INVALID_TSS, // Vector 10
+ EFI_VECTOR_HANDOFF_HOOK_BEFORE,
+ EFI_DEBUG_AGENT_GUID
+ },
+ {
+ DEBUG_EXCEPT_SEG_NOT_PRESENT, // Vector 11
+ EFI_VECTOR_HANDOFF_HOOK_BEFORE,
+ EFI_DEBUG_AGENT_GUID
+ },
+ {
+ DEBUG_EXCEPT_STACK_FAULT, // Vector 12
+ EFI_VECTOR_HANDOFF_HOOK_BEFORE,
+ EFI_DEBUG_AGENT_GUID
+ },
+ {
+ DEBUG_EXCEPT_GP_FAULT, // Vector 13
+ EFI_VECTOR_HANDOFF_HOOK_BEFORE,
+ EFI_DEBUG_AGENT_GUID
+ },
+ {
+ DEBUG_EXCEPT_PAGE_FAULT, // Vector 14
+ EFI_VECTOR_HANDOFF_HOOK_BEFORE,
+ EFI_DEBUG_AGENT_GUID
+ },
+ {
+ DEBUG_EXCEPT_FP_ERROR, // Vector 16
+ EFI_VECTOR_HANDOFF_HOOK_BEFORE,
+ EFI_DEBUG_AGENT_GUID
+ },
+ {
+ DEBUG_EXCEPT_ALIGNMENT_CHECK, // Vector 17
+ EFI_VECTOR_HANDOFF_HOOK_BEFORE,
+ EFI_DEBUG_AGENT_GUID
+ },
+ {
+ DEBUG_EXCEPT_MACHINE_CHECK, // Vector 18
+ EFI_VECTOR_HANDOFF_HOOK_BEFORE,
+ EFI_DEBUG_AGENT_GUID
+ },
+ {
+ DEBUG_EXCEPT_SIMD, // Vector 19
+ EFI_VECTOR_HANDOFF_HOOK_BEFORE,
+ EFI_DEBUG_AGENT_GUID
+ },
+ {
+ DEBUG_TIMER_VECTOR, // Vector 32
+ EFI_VECTOR_HANDOFF_DO_NOT_HOOK,
+ EFI_DEBUG_AGENT_GUID
+ },
+ {
+ DEBUG_MAILBOX_VECTOR, // Vector 33
+ EFI_VECTOR_HANDOFF_DO_NOT_HOOK,
+ EFI_DEBUG_AGENT_GUID
+ },
+ {
+ 0,
+ EFI_VECTOR_HANDOFF_LAST_ENTRY,
+ { 0 }
+ }
+};
+
+UINTN mVectorHandoffInfoCount = sizeof (mVectorHandoffInfoDebugAgent) / sizeof (EFI_VECTOR_HANDOFF_INFO);
+
/**
Calculate CRC16 for target data.
diff --git a/SourceLevelDebugPkg/Library/DebugAgent/DebugAgentCommon/DebugAgent.h b/SourceLevelDebugPkg/Library/DebugAgent/DebugAgentCommon/DebugAgent.h
index 748d562a5..deed55eaf 100644
--- a/SourceLevelDebugPkg/Library/DebugAgent/DebugAgentCommon/DebugAgent.h
+++ b/SourceLevelDebugPkg/Library/DebugAgent/DebugAgentCommon/DebugAgent.h
@@ -16,9 +16,9 @@
#define _DEBUG_AGENT_H_
#include <Register/LocalApic.h>
-
#include <Guid/DebugAgentGuid.h>
-
+#include <Guid/VectorHandoffTable.h>
+#include <Ppi/VectorHandoffInfo.h>
#include <Library/BaseLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/ResetSystemLib.h>
@@ -41,6 +41,7 @@
#include "DebugMp.h"
#include "DebugTimer.h"
#include "ArchDebugSupport.h"
+#include "DebugException.h"
//
// These macros may be already defined in DebugAgentLib.h
@@ -50,8 +51,8 @@
#define DEBUG_AGENT_INIT_DXE_UNLOAD 11
#define DEBUG_AGENT_INIT_THUNK_PEI_IA32TOX64 12
-#define DEBUG_INT1_VECTOR 1
-#define DEBUG_INT3_VECTOR 3
+#define DEBUG_INT1_VECTOR DEBUG_EXCEPT_DEBUG
+#define DEBUG_INT3_VECTOR DEBUG_EXCEPT_BREAKPOINT
#define DEBUG_TIMER_VECTOR 32
#define DEBUG_MAILBOX_VECTOR 33
@@ -67,8 +68,9 @@
extern UINTN Exception0Handle;
extern UINTN TimerInterruptHandle;
extern UINT16 ExceptionStubHeaderSize;
-
extern BOOLEAN mSkipBreakpoint;
+extern EFI_VECTOR_HANDOFF_INFO mVectorHandoffInfoDebugAgent[];
+extern UINTN mVectorHandoffInfoCount;
//
// CPU exception information issued by debug agent
diff --git a/SourceLevelDebugPkg/Library/DebugAgent/DebugAgentCommon/Ia32/AsmFuncs.S b/SourceLevelDebugPkg/Library/DebugAgent/DebugAgentCommon/Ia32/AsmFuncs.S
index e05317aaf..284939126 100644
--- a/SourceLevelDebugPkg/Library/DebugAgent/DebugAgentCommon/Ia32/AsmFuncs.S
+++ b/SourceLevelDebugPkg/Library/DebugAgent/DebugAgentCommon/Ia32/AsmFuncs.S
@@ -27,114 +27,137 @@ ASM_GLOBAL ASM_PFX(ExceptionStubHeaderSize)
ASM_GLOBAL ASM_PFX(TimerInterruptHandle)
ASM_GLOBAL ASM_PFX(CommonEntry)
+.macro AGENT_HANDLER_SIGNATURE
+ .byte 0x41, 0x47, 0x54, 0x48 # AGENT_HANDLER_SIGNATURE SIGNATURE_32('A','G','T','H')
+.endm
+
.data
ASM_PFX(ExceptionStubHeaderSize): .word ASM_PFX(Exception1Handle) - ASM_PFX(Exception0Handle)
.text
-.byte 0x41, 0x47, 0x54, 0x48 # AGENT_HANDLER_SIGNATURE SIGNATURE_32('A','G','T','H')
+AGENT_HANDLER_SIGNATURE
ASM_PFX(Exception0Handle):
cli
pushl %eax
mov $0, %eax
jmp ASM_PFX(CommonEntry)
+AGENT_HANDLER_SIGNATURE
ASM_PFX(Exception1Handle):
cli
pushl %eax
mov $1, %eax
jmp ASM_PFX(CommonEntry)
+AGENT_HANDLER_SIGNATURE
ASM_PFX(Exception2Handle):
cli
pushl %eax
mov $2, %eax
jmp ASM_PFX(CommonEntry)
+AGENT_HANDLER_SIGNATURE
ASM_PFX(Exception3Handle):
cli
pushl %eax
mov $3, %eax
jmp ASM_PFX(CommonEntry)
+AGENT_HANDLER_SIGNATURE
ASM_PFX(Exception4Handle):
cli
pushl %eax
mov $4, %eax
jmp ASM_PFX(CommonEntry)
+AGENT_HANDLER_SIGNATURE
ASM_PFX(Exception5Handle):
cli
pushl %eax
mov $5, %eax
jmp ASM_PFX(CommonEntry)
+AGENT_HANDLER_SIGNATURE
ASM_PFX(Exception6Handle):
cli
pushl %eax
mov $6, %eax
jmp ASM_PFX(CommonEntry)
+AGENT_HANDLER_SIGNATURE
ASM_PFX(Exception7Handle):
cli
pushl %eax
mov $7, %eax
jmp ASM_PFX(CommonEntry)
+AGENT_HANDLER_SIGNATURE
ASM_PFX(Exception8Handle):
cli
pushl %eax
mov $8, %eax
jmp ASM_PFX(CommonEntry)
+AGENT_HANDLER_SIGNATURE
ASM_PFX(Exception9Handle):
cli
pushl %eax
mov $9, %eax
jmp ASM_PFX(CommonEntry)
+AGENT_HANDLER_SIGNATURE
ASM_PFX(Exception10Handle):
cli
pushl %eax
mov $10, %eax
jmp ASM_PFX(CommonEntry)
+AGENT_HANDLER_SIGNATURE
ASM_PFX(Exception11Handle):
cli
pushl %eax
mov $11, %eax
jmp ASM_PFX(CommonEntry)
+AGENT_HANDLER_SIGNATURE
ASM_PFX(Exception12Handle):
cli
pushl %eax
mov $12, %eax
jmp ASM_PFX(CommonEntry)
+AGENT_HANDLER_SIGNATURE
ASM_PFX(Exception13Handle):
cli
pushl %eax
mov $13, %eax
jmp ASM_PFX(CommonEntry)
+AGENT_HANDLER_SIGNATURE
ASM_PFX(Exception14Handle):
cli
pushl %eax
mov $14, %eax
jmp ASM_PFX(CommonEntry)
+AGENT_HANDLER_SIGNATURE
ASM_PFX(Exception15Handle):
cli
pushl %eax
mov $15, %eax
jmp ASM_PFX(CommonEntry)
+AGENT_HANDLER_SIGNATURE
ASM_PFX(Exception16Handle):
cli
pushl %eax
mov $16, %eax
jmp ASM_PFX(CommonEntry)
+AGENT_HANDLER_SIGNATURE
ASM_PFX(Exception17Handle):
cli
pushl %eax
mov $17, %eax
jmp ASM_PFX(CommonEntry)
+AGENT_HANDLER_SIGNATURE
ASM_PFX(Exception18Handle):
cli
pushl %eax
mov $18, %eax
jmp ASM_PFX(CommonEntry)
+AGENT_HANDLER_SIGNATURE
ASM_PFX(Exception19Handle):
cli
pushl %eax
mov $19, %eax
jmp ASM_PFX(CommonEntry)
-
+AGENT_HANDLER_SIGNATURE
ASM_PFX(TimerInterruptHandle):
cli
pushl %eax
diff --git a/SourceLevelDebugPkg/Library/DebugAgent/DebugAgentCommon/Ia32/AsmFuncs.asm b/SourceLevelDebugPkg/Library/DebugAgent/DebugAgentCommon/Ia32/AsmFuncs.asm
index c80a33ba6..9b219fc07 100644
--- a/SourceLevelDebugPkg/Library/DebugAgent/DebugAgentCommon/Ia32/AsmFuncs.asm
+++ b/SourceLevelDebugPkg/Library/DebugAgent/DebugAgentCommon/Ia32/AsmFuncs.asm
@@ -32,6 +32,10 @@ InterruptProcess PROTO C
public Exception0Handle, TimerInterruptHandle, ExceptionStubHeaderSize
+AGENT_HANDLER_SIGNATURE MACRO
+ db 41h, 47h, 54h, 48h ; SIGNATURE_32('A','G','T','H')
+ENDM
+
.data
ExceptionStubHeaderSize DW Exception1Handle - Exception0Handle
@@ -39,108 +43,127 @@ CommonEntryAddr DD CommonEntry
.code
-db 41h, 47h, 54h, 48h ; AGENT_HANDLER_SIGNATURE SIGNATURE_32('A','G','T','H')
+AGENT_HANDLER_SIGNATURE
Exception0Handle:
cli
push eax
mov eax, 0
jmp dword ptr [CommonEntryAddr]
+AGENT_HANDLER_SIGNATURE
Exception1Handle:
cli
push eax
mov eax, 1
jmp dword ptr [CommonEntryAddr]
+AGENT_HANDLER_SIGNATURE
Exception2Handle:
cli
push eax
mov eax, 2
jmp dword ptr [CommonEntryAddr]
+AGENT_HANDLER_SIGNATURE
Exception3Handle:
cli
push eax
mov eax, 3
jmp dword ptr [CommonEntryAddr]
+AGENT_HANDLER_SIGNATURE
Exception4Handle:
cli
push eax
mov eax, 4
jmp dword ptr [CommonEntryAddr]
+AGENT_HANDLER_SIGNATURE
Exception5Handle:
cli
push eax
mov eax, 5
jmp dword ptr [CommonEntryAddr]
+AGENT_HANDLER_SIGNATURE
Exception6Handle:
cli
push eax
mov eax, 6
jmp dword ptr [CommonEntryAddr]
+AGENT_HANDLER_SIGNATURE
Exception7Handle:
cli
push eax
mov eax, 7
jmp dword ptr [CommonEntryAddr]
+AGENT_HANDLER_SIGNATURE
Exception8Handle:
cli
push eax
mov eax, 8
jmp dword ptr [CommonEntryAddr]
+AGENT_HANDLER_SIGNATURE
Exception9Handle:
cli
push eax
mov eax, 9
jmp dword ptr [CommonEntryAddr]
+AGENT_HANDLER_SIGNATURE
Exception10Handle:
cli
push eax
mov eax, 10
jmp dword ptr [CommonEntryAddr]
+AGENT_HANDLER_SIGNATURE
Exception11Handle:
cli
push eax
mov eax, 11
jmp dword ptr [CommonEntryAddr]
+AGENT_HANDLER_SIGNATURE
Exception12Handle:
cli
push eax
mov eax, 12
jmp dword ptr [CommonEntryAddr]
+AGENT_HANDLER_SIGNATURE
Exception13Handle:
cli
push eax
mov eax, 13
jmp dword ptr [CommonEntryAddr]
+AGENT_HANDLER_SIGNATURE
Exception14Handle:
cli
push eax
mov eax, 14
jmp dword ptr [CommonEntryAddr]
+AGENT_HANDLER_SIGNATURE
Exception15Handle:
cli
push eax
mov eax, 15
jmp dword ptr [CommonEntryAddr]
+AGENT_HANDLER_SIGNATURE
Exception16Handle:
cli
push eax
mov eax, 16
jmp dword ptr [CommonEntryAddr]
+AGENT_HANDLER_SIGNATURE
Exception17Handle:
cli
push eax
mov eax, 17
jmp dword ptr [CommonEntryAddr]
+AGENT_HANDLER_SIGNATURE
Exception18Handle:
cli
push eax
mov eax, 18
jmp dword ptr [CommonEntryAddr]
+AGENT_HANDLER_SIGNATURE
Exception19Handle:
cli
push eax
mov eax, 19
jmp dword ptr [CommonEntryAddr]
-
+AGENT_HANDLER_SIGNATURE
TimerInterruptHandle:
cli
push eax
diff --git a/SourceLevelDebugPkg/Library/DebugAgent/DebugAgentCommon/X64/AsmFuncs.S b/SourceLevelDebugPkg/Library/DebugAgent/DebugAgentCommon/X64/AsmFuncs.S
index e7c3ed746..b742b67db 100644
--- a/SourceLevelDebugPkg/Library/DebugAgent/DebugAgentCommon/X64/AsmFuncs.S
+++ b/SourceLevelDebugPkg/Library/DebugAgent/DebugAgentCommon/X64/AsmFuncs.S
@@ -28,6 +28,10 @@ ASM_GLOBAL ASM_PFX(ExceptionStubHeaderSize)
ASM_GLOBAL ASM_PFX(TimerInterruptHandle)
ASM_GLOBAL ASM_PFX(CommonEntry)
+.macro AGENT_HANDLER_SIGNATURE
+ .byte 0x41, 0x47, 0x54, 0x48 # AGENT_HANDLER_SIGNATURE SIGNATURE_32('A','G','T','H')
+.endm
+
.data
ASM_PFX(ExceptionStubHeaderSize): .word ASM_PFX(Exception1Handle) - ASM_PFX(Exception0Handle)
@@ -35,108 +39,127 @@ ASM_PFX(ExceptionStubHeaderSize): .word ASM_PFX(Exception1Handle) - ASM_PFX
.text
-.byte 0x41, 0x47, 0x54, 0x48 # AGENT_HANDLER_SIGNATURE SIGNATURE_32('A','G','T','H')
+AGENT_HANDLER_SIGNATURE
ASM_PFX(Exception0Handle):
cli
pushq %rcx
mov $0, %rcx
jmp ASM_PFX(CommonEntry)
+AGENT_HANDLER_SIGNATURE
ASM_PFX(Exception1Handle):
cli
pushq %rcx
mov $1, %rcx
jmp ASM_PFX(CommonEntry)
+AGENT_HANDLER_SIGNATURE
ASM_PFX(Exception2Handle):
cli
pushq %rcx
mov $2, %rcx
jmp ASM_PFX(CommonEntry)
+AGENT_HANDLER_SIGNATURE
ASM_PFX(Exception3Handle):
cli
pushq %rcx
mov $3, %rcx
jmp ASM_PFX(CommonEntry)
+AGENT_HANDLER_SIGNATURE
ASM_PFX(Exception4Handle):
cli
pushq %rcx
mov $4, %rcx
jmp ASM_PFX(CommonEntry)
+AGENT_HANDLER_SIGNATURE
ASM_PFX(Exception5Handle):
cli
pushq %rcx
mov $5, %rcx
jmp ASM_PFX(CommonEntry)
+AGENT_HANDLER_SIGNATURE
ASM_PFX(Exception6Handle):
cli
pushq %rcx
mov $6, %rcx
jmp ASM_PFX(CommonEntry)
+AGENT_HANDLER_SIGNATURE
ASM_PFX(Exception7Handle):
cli
pushq %rcx
mov $7, %rcx
jmp ASM_PFX(CommonEntry)
+AGENT_HANDLER_SIGNATURE
ASM_PFX(Exception8Handle):
cli
pushq %rcx
mov $8, %rcx
jmp ASM_PFX(CommonEntry)
+AGENT_HANDLER_SIGNATURE
ASM_PFX(Exception9Handle):
cli
pushq %rcx
mov $9, %rcx
jmp ASM_PFX(CommonEntry)
+AGENT_HANDLER_SIGNATURE
ASM_PFX(Exception10Handle):
cli
pushq %rcx
mov $10, %rcx
jmp ASM_PFX(CommonEntry)
+AGENT_HANDLER_SIGNATURE
ASM_PFX(Exception11Handle):
cli
pushq %rcx
mov $11, %rcx
jmp ASM_PFX(CommonEntry)
+AGENT_HANDLER_SIGNATURE
ASM_PFX(Exception12Handle):
cli
pushq %rcx
mov $12, %rcx
jmp ASM_PFX(CommonEntry)
+AGENT_HANDLER_SIGNATURE
ASM_PFX(Exception13Handle):
cli
pushq %rcx
mov $13, %rcx
jmp ASM_PFX(CommonEntry)
+AGENT_HANDLER_SIGNATURE
ASM_PFX(Exception14Handle):
cli
pushq %rcx
mov $14, %rcx
jmp ASM_PFX(CommonEntry)
+AGENT_HANDLER_SIGNATURE
ASM_PFX(Exception15Handle):
cli
pushq %rcx
mov $15, %rcx
jmp ASM_PFX(CommonEntry)
+AGENT_HANDLER_SIGNATURE
ASM_PFX(Exception16Handle):
cli
pushq %rcx
mov $16, %rcx
jmp ASM_PFX(CommonEntry)
+AGENT_HANDLER_SIGNATURE
ASM_PFX(Exception17Handle):
cli
pushq %rcx
mov $17, %rcx
jmp ASM_PFX(CommonEntry)
+AGENT_HANDLER_SIGNATURE
ASM_PFX(Exception18Handle):
cli
pushq %rcx
mov $18, %rcx
jmp ASM_PFX(CommonEntry)
+AGENT_HANDLER_SIGNATURE
ASM_PFX(Exception19Handle):
cli
pushq %rcx
mov $19, %rcx
jmp ASM_PFX(CommonEntry)
-
+AGENT_HANDLER_SIGNATURE
ASM_PFX(TimerInterruptHandle):
cli
pushq %rcx
diff --git a/SourceLevelDebugPkg/Library/DebugAgent/DebugAgentCommon/X64/AsmFuncs.asm b/SourceLevelDebugPkg/Library/DebugAgent/DebugAgentCommon/X64/AsmFuncs.asm
index 23abcc762..cf8c5f019 100644
--- a/SourceLevelDebugPkg/Library/DebugAgent/DebugAgentCommon/X64/AsmFuncs.asm
+++ b/SourceLevelDebugPkg/Library/DebugAgent/DebugAgentCommon/X64/AsmFuncs.asm
@@ -28,113 +28,136 @@ data SEGMENT
public Exception0Handle, TimerInterruptHandle, ExceptionStubHeaderSize
+AGENT_HANDLER_SIGNATURE MACRO
+ db 41h, 47h, 54h, 48h ; SIGNATURE_32('A','G','T','H')
+ENDM
+
ExceptionStubHeaderSize dw Exception1Handle - Exception0Handle ;
CommonEntryAddr dq CommonEntry ;
.code
-db 41h, 47h, 54h, 48h ; AGENT_HANDLER_SIGNATURE SIGNATURE_32('A','G','T','H')
+AGENT_HANDLER_SIGNATURE
Exception0Handle:
cli
push rcx
mov rcx, 0
jmp qword ptr [CommonEntryAddr]
+AGENT_HANDLER_SIGNATURE
Exception1Handle:
cli
push rcx
mov rcx, 1
jmp qword ptr [CommonEntryAddr]
+AGENT_HANDLER_SIGNATURE
Exception2Handle:
cli
push rcx
mov rcx, 2
jmp qword ptr [CommonEntryAddr]
+AGENT_HANDLER_SIGNATURE
Exception3Handle:
cli
push rcx
mov rcx, 3
jmp qword ptr [CommonEntryAddr]
+AGENT_HANDLER_SIGNATURE
Exception4Handle:
cli
push rcx
mov rcx, 4
jmp qword ptr [CommonEntryAddr]
+AGENT_HANDLER_SIGNATURE
Exception5Handle:
cli
push rcx
mov rcx, 5
jmp qword ptr [CommonEntryAddr]
+AGENT_HANDLER_SIGNATURE
Exception6Handle:
cli
push rcx
mov rcx, 6
jmp qword ptr [CommonEntryAddr]
+AGENT_HANDLER_SIGNATURE
Exception7Handle:
cli
push rcx
mov rcx, 7
jmp qword ptr [CommonEntryAddr]
+AGENT_HANDLER_SIGNATURE
Exception8Handle:
cli
push rcx
mov rcx, 8
jmp qword ptr [CommonEntryAddr]
+AGENT_HANDLER_SIGNATURE
Exception9Handle:
cli
push rcx
mov rcx, 9
jmp qword ptr [CommonEntryAddr]
+AGENT_HANDLER_SIGNATURE
Exception10Handle:
cli
push rcx
mov rcx, 10
jmp qword ptr [CommonEntryAddr]
+AGENT_HANDLER_SIGNATURE
Exception11Handle:
cli
push rcx
mov rcx, 11
jmp qword ptr [CommonEntryAddr]
+AGENT_HANDLER_SIGNATURE
Exception12Handle:
cli
push rcx
mov rcx, 12
jmp qword ptr [CommonEntryAddr]
+AGENT_HANDLER_SIGNATURE
Exception13Handle:
cli
push rcx
mov rcx, 13
jmp qword ptr [CommonEntryAddr]
+AGENT_HANDLER_SIGNATURE
Exception14Handle:
cli
push rcx
mov rcx, 14
jmp qword ptr [CommonEntryAddr]
+AGENT_HANDLER_SIGNATURE
Exception15Handle:
cli
push rcx
mov rcx, 15
jmp qword ptr [CommonEntryAddr]
+AGENT_HANDLER_SIGNATURE
Exception16Handle:
cli
push rcx
mov rcx, 16
jmp qword ptr [CommonEntryAddr]
+AGENT_HANDLER_SIGNATURE
Exception17Handle:
cli
push rcx
mov rcx, 17
jmp qword ptr [CommonEntryAddr]
+AGENT_HANDLER_SIGNATURE
Exception18Handle:
cli
push rcx
mov rcx, 18
jmp qword ptr [CommonEntryAddr]
+AGENT_HANDLER_SIGNATURE
Exception19Handle:
cli
push rcx
mov rcx, 19
jmp qword ptr [CommonEntryAddr]
-
+AGENT_HANDLER_SIGNATURE
TimerInterruptHandle:
cli
push rcx
diff --git a/SourceLevelDebugPkg/Library/DebugAgent/DxeDebugAgent/DxeDebugAgentLib.c b/SourceLevelDebugPkg/Library/DebugAgent/DxeDebugAgent/DxeDebugAgentLib.c
index d560b5235..71130d8aa 100644
--- a/SourceLevelDebugPkg/Library/DebugAgent/DxeDebugAgent/DxeDebugAgentLib.c
+++ b/SourceLevelDebugPkg/Library/DebugAgent/DxeDebugAgent/DxeDebugAgentLib.c
@@ -57,6 +57,32 @@ InternalConstructorWorker (
BOOLEAN DebugTimerInterruptState;
DEBUG_AGENT_MAILBOX *Mailbox;
DEBUG_AGENT_MAILBOX *NewMailbox;
+ EFI_HOB_GUID_TYPE *GuidHob;
+ EFI_VECTOR_HANDOFF_INFO *VectorHandoffInfo;
+
+ //
+ // Check persisted vector handoff info
+ //
+ Status = EFI_SUCCESS;
+ GuidHob = GetFirstGuidHob (&gEfiVectorHandoffInfoPpiGuid);
+ if (GuidHob != NULL && !mDxeCoreFlag) {
+ //
+ // Check if configuration table is installed or not if GUIDed HOB existed,
+ // only when Debug Agent is not linked by DXE Core
+ //
+ Status = EfiGetSystemConfigurationTable (&gEfiVectorHandoffTableGuid, (VOID **) &VectorHandoffInfo);
+ }
+ if (GuidHob == NULL || Status != EFI_SUCCESS) {
+ //
+ // Install configuration table for persisted vector handoff info if GUIDed HOB cannot be found or
+ // configuration table does not exist
+ //
+ Status = gBS->InstallConfigurationTable (&gEfiVectorHandoffTableGuid, (VOID *) &mVectorHandoffInfoDebugAgent[0]);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR, "DebugAgent: Cannot install configuration table for persisted vector handoff info!\n"));
+ CpuDeadLoop ();
+ }
+ }
//
// Install EFI Serial IO protocol on debug port
@@ -70,7 +96,10 @@ InternalConstructorWorker (
EFI_SIZE_TO_PAGES (sizeof(DEBUG_AGENT_MAILBOX) + PcdGet16(PcdDebugPortHandleBufferSize)),
&Address
);
- ASSERT_EFI_ERROR (Status);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR, "DebugAgent: Cannot install configuration table for mailbox!\n"));
+ CpuDeadLoop ();
+ }
DebugTimerInterruptState = SaveAndSetDebugTimerInterrupt (FALSE);
@@ -91,7 +120,10 @@ InternalConstructorWorker (
DebugTimerInterruptState = SaveAndSetDebugTimerInterrupt (DebugTimerInterruptState);
Status = gBS->InstallConfigurationTable (&gEfiDebugAgentGuid, (VOID *) mMailboxPointer);
- ASSERT_EFI_ERROR (Status);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR, "DebugAgent: Failed to install configuration for mailbox!\n"));
+ CpuDeadLoop ();
+ }
}
/**
@@ -233,9 +265,16 @@ SetupDebugAgentEnviroment (
AsmReadIdtr ((IA32_DESCRIPTOR *) &Idtr);
IdtEntryCount = (UINT16) ((Idtr.Limit + 1) / sizeof (IA32_IDT_GATE_DESCRIPTOR));
if (IdtEntryCount < 33) {
+ ZeroMem (&mIdtEntryTable, sizeof (IA32_IDT_GATE_DESCRIPTOR) * 33);
+ //
+ // Copy original IDT table into new one
+ //
+ CopyMem (&mIdtEntryTable, (VOID *) Idtr.Base, Idtr.Limit + 1);
+ //
+ // Load new IDT table
+ //
Idtr.Limit = (UINT16) (sizeof (IA32_IDT_GATE_DESCRIPTOR) * 33 - 1);
Idtr.Base = (UINTN) &mIdtEntryTable;
- ZeroMem (&mIdtEntryTable, Idtr.Limit + 1);
AsmWriteIdtr ((IA32_DESCRIPTOR *) &Idtr);
}
diff --git a/SourceLevelDebugPkg/Library/DebugAgent/DxeDebugAgentLib.inf b/SourceLevelDebugPkg/Library/DebugAgent/DxeDebugAgentLib.inf
index cc9b48191..e5a510d4b 100644
--- a/SourceLevelDebugPkg/Library/DebugAgent/DxeDebugAgentLib.inf
+++ b/SourceLevelDebugPkg/Library/DebugAgent/DxeDebugAgentLib.inf
@@ -82,7 +82,11 @@
[Guids]
gEfiDebugAgentGuid ## PRODUCES ## Configuration Table
gEfiDebugAgentGuid ## CONSUMES ## HOB
-
+ gEfiVectorHandoffTableGuid ## SOMETIMES_PRODUCES ## Configuration Table
+
+[Ppis]
+ gEfiVectorHandoffInfoPpiGuid ## UNDEFINED
+
[Protocols]
gEfiSerialIoProtocolGuid ## PRODUCES
gEfiDevicePathProtocolGuid ## PRODUCES
diff --git a/SourceLevelDebugPkg/Library/DebugAgent/SecPeiDebugAgent/SecPeiDebugAgentLib.c b/SourceLevelDebugPkg/Library/DebugAgent/SecPeiDebugAgent/SecPeiDebugAgentLib.c
index c253fa59a..038880769 100644
--- a/SourceLevelDebugPkg/Library/DebugAgent/SecPeiDebugAgent/SecPeiDebugAgentLib.c
+++ b/SourceLevelDebugPkg/Library/DebugAgent/SecPeiDebugAgent/SecPeiDebugAgentLib.c
@@ -16,6 +16,22 @@
BOOLEAN mSkipBreakpoint = FALSE;
+
+EFI_PEI_VECTOR_HANDOFF_INFO_PPI mVectorHandoffInfoPpi = {
+ &mVectorHandoffInfoDebugAgent[0]
+};
+
+//
+// Ppis to be installed
+//
+EFI_PEI_PPI_DESCRIPTOR mVectorHandoffInfoPpiList[] = {
+ {
+ (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
+ &gEfiVectorHandoffInfoPpiGuid,
+ &mVectorHandoffInfoPpi
+ }
+};
+
EFI_PEI_NOTIFY_DESCRIPTOR mMemoryDiscoveredNotifyList[1] = {
{
(EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
@@ -348,6 +364,7 @@ InitializeDebugAgent (
)
{
DEBUG_AGENT_MAILBOX *Mailbox;
+ DEBUG_AGENT_MAILBOX *NewMailbox;
DEBUG_AGENT_MAILBOX MailboxInStack;
DEBUG_AGENT_PHASE2_CONTEXT Phase2Context;
DEBUG_AGENT_CONTEXT_POSTMEM_SEC *DebugAgentContext;
@@ -357,6 +374,7 @@ InitializeDebugAgent (
UINT64 DebugPortHandle;
UINT64 MailboxLocation;
UINT64 *MailboxLocationPointer;
+ EFI_PHYSICAL_ADDRESS Address;
DisableInterrupts ();
@@ -406,24 +424,65 @@ InitializeDebugAgent (
//
TriggerSoftInterrupt (MEMORY_READY_SIGNATURE);
}
-
//
- // Fix up Debug Port handle address and mailbox address
+ // Install Vector Handoff Info PPI to persist vectors used by Debug Agent
//
- DebugAgentContext = (DEBUG_AGENT_CONTEXT_POSTMEM_SEC *) Context;
- DebugPortHandle = (UINT64)(UINT32)(Mailbox->DebugPortHandle + DebugAgentContext->StackMigrateOffset);
- UpdateMailboxContent (Mailbox, DEBUG_MAILBOX_DEBUG_PORT_HANDLE_INDEX, DebugPortHandle);
- Mailbox = (DEBUG_AGENT_MAILBOX *) ((UINTN) Mailbox + DebugAgentContext->StackMigrateOffset);
- MailboxLocation = (UINT64)(UINTN)Mailbox;
+ Status = PeiServicesInstallPpi (&mVectorHandoffInfoPpiList[0]);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR, "DebugAgent: Failed to install Vector Handoff Info PPI!\n"));
+ CpuDeadLoop ();
+ }
//
- // Build mailbox location in HOB and fix-up its address
+ // Fix up Debug Port handle address and mailbox address
//
- MailboxLocationPointer = BuildGuidDataHob (
- &gEfiDebugAgentGuid,
- &MailboxLocation,
- sizeof (UINT64)
- );
- MailboxLocationPointer = (UINT64 *) ((UINTN) MailboxLocationPointer + DebugAgentContext->HeapMigrateOffset);
+ DebugAgentContext = (DEBUG_AGENT_CONTEXT_POSTMEM_SEC *) Context;
+ if (DebugAgentContext != NULL) {
+ DebugPortHandle = (UINT64)(UINT32)(Mailbox->DebugPortHandle + DebugAgentContext->StackMigrateOffset);
+ UpdateMailboxContent (Mailbox, DEBUG_MAILBOX_DEBUG_PORT_HANDLE_INDEX, DebugPortHandle);
+ Mailbox = (DEBUG_AGENT_MAILBOX *) ((UINTN) Mailbox + DebugAgentContext->StackMigrateOffset);
+ MailboxLocation = (UINT64)(UINTN)Mailbox;
+ //
+ // Build mailbox location in HOB and fix-up its address
+ //
+ MailboxLocationPointer = BuildGuidDataHob (
+ &gEfiDebugAgentGuid,
+ &MailboxLocation,
+ sizeof (UINT64)
+ );
+ MailboxLocationPointer = (UINT64 *) ((UINTN) MailboxLocationPointer + DebugAgentContext->HeapMigrateOffset);
+ } else {
+ //
+ // DebugAgentContext is NULL. Then, Mailbox can directly be copied into memory.
+ // Allocate ACPI NVS memory for new Mailbox and Debug Port Handle buffer
+ //
+ Status = PeiServicesAllocatePages (
+ EfiACPIMemoryNVS,
+ EFI_SIZE_TO_PAGES (sizeof(DEBUG_AGENT_MAILBOX) + PcdGet16(PcdDebugPortHandleBufferSize)),
+ &Address
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR, "DebugAgent: Failed to allocate pages!\n"));
+ CpuDeadLoop ();
+ }
+ NewMailbox = (DEBUG_AGENT_MAILBOX *) (UINTN) Address;
+ //
+ // Copy Mailbox and Debug Port Handle buffer to new location in ACPI NVS memory, because original Mailbox
+ // and Debug Port Handle buffer in the allocated pool that may be marked as free by DXE Core after DXE Core
+ // reallocates the HOB.
+ //
+ CopyMem (NewMailbox, Mailbox, sizeof (DEBUG_AGENT_MAILBOX));
+ CopyMem (NewMailbox + 1, (VOID *)(UINTN)Mailbox->DebugPortHandle, PcdGet16(PcdDebugPortHandleBufferSize));
+ UpdateMailboxContent (NewMailbox, DEBUG_MAILBOX_DEBUG_PORT_HANDLE_INDEX, (UINT64)(UINTN)(NewMailbox + 1));
+ MailboxLocation = (UINT64)(UINTN)NewMailbox;
+ //
+ // Build mailbox location in HOB
+ //
+ MailboxLocationPointer = BuildGuidDataHob (
+ &gEfiDebugAgentGuid,
+ &MailboxLocation,
+ sizeof (UINT64)
+ );
+ }
//
// Update IDT entry to save the location saved mailbox pointer
//
@@ -444,6 +503,14 @@ InitializeDebugAgent (
break;
}
//
+ // Install Vector Handoff Info PPI to persist vectors used by Debug Agent
+ //
+ Status = PeiServicesInstallPpi (&mVectorHandoffInfoPpiList[0]);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR, "DebugAgent: Failed to install Vector Handoff Info PPI!\n"));
+ CpuDeadLoop ();
+ }
+ //
// Set up IDT entries
//
InitializeDebugIdt ();
@@ -472,7 +539,10 @@ InitializeDebugAgent (
// If memery has been ready, the callback funtion will be invoked immediately
//
Status = PeiServicesNotifyPpi (&mMemoryDiscoveredNotifyList[0]);
- ASSERT_EFI_ERROR (Status);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR, "DebugAgent: Failed to register memory discovered callback function!\n"));
+ CpuDeadLoop ();
+ }
//
// Set HOB check flag if memory has not been ready yet
//
diff --git a/SourceLevelDebugPkg/Library/DebugAgent/SecPeiDebugAgentLib.inf b/SourceLevelDebugPkg/Library/DebugAgent/SecPeiDebugAgentLib.inf
index b81fc16d1..5204abca5 100644
--- a/SourceLevelDebugPkg/Library/DebugAgent/SecPeiDebugAgentLib.inf
+++ b/SourceLevelDebugPkg/Library/DebugAgent/SecPeiDebugAgentLib.inf
@@ -77,6 +77,7 @@
[Ppis]
gEfiPeiMemoryDiscoveredPpiGuid
+ gEfiVectorHandoffInfoPpiGuid ## PRODUCES
[Guids]
gEfiDebugAgentGuid ## PRODUCES ## HOB
diff --git a/SourceLevelDebugPkg/Library/DebugAgent/SmmDebugAgent/SmmDebugAgentLib.c b/SourceLevelDebugPkg/Library/DebugAgent/SmmDebugAgent/SmmDebugAgentLib.c
index 145fee0fa..651737e5e 100644
--- a/SourceLevelDebugPkg/Library/DebugAgent/SmmDebugAgent/SmmDebugAgentLib.c
+++ b/SourceLevelDebugPkg/Library/DebugAgent/SmmDebugAgent/SmmDebugAgentLib.c
@@ -193,6 +193,19 @@ InitializeDebugAgent (
switch (InitFlag) {
case DEBUG_AGENT_INIT_SMM:
//
+ // Install configuration table for persisted vector handoff info
+ //
+ Status = gSmst->SmmInstallConfigurationTable (
+ gSmst,
+ &gEfiVectorHandoffTableGuid,
+ (VOID *) &mVectorHandoffInfoDebugAgent[0],
+ sizeof (EFI_VECTOR_HANDOFF_INFO) * mVectorHandoffInfoCount
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR, "DebugAgent: Cannot install configuration table for persisted vector handoff info!\n"));
+ CpuDeadLoop ();
+ }
+ //
// Check if Debug Agent initialized in DXE phase
//
Status = EfiGetSystemConfigurationTable (&gEfiDebugAgentGuid, (VOID **) &Mailbox);
@@ -210,7 +223,7 @@ InitializeDebugAgent (
break;
}
//
- // Debug Agent was not initialized before, uset the local mailbox.
+ // Debug Agent was not initialized before, use the local mailbox.
//
ZeroMem (&mLocalMailbox, sizeof (DEBUG_AGENT_MAILBOX));
Mailbox = &mLocalMailbox;
diff --git a/SourceLevelDebugPkg/Library/DebugAgent/SmmDebugAgent/SmmDebugAgentLib.h b/SourceLevelDebugPkg/Library/DebugAgent/SmmDebugAgent/SmmDebugAgentLib.h
index ccb55f830..f30a892e2 100644
--- a/SourceLevelDebugPkg/Library/DebugAgent/SmmDebugAgent/SmmDebugAgentLib.h
+++ b/SourceLevelDebugPkg/Library/DebugAgent/SmmDebugAgent/SmmDebugAgentLib.h
@@ -1,7 +1,7 @@
/** @file
Header file for Smm Debug Agent Library instance.
- Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>
+ Copyright (c) 2010 - 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
@@ -18,6 +18,7 @@
#include <PiDxe.h>
#include <Library/UefiLib.h>
+#include <Library/SmmServicesTableLib.h>
#include "DebugAgent.h"
diff --git a/SourceLevelDebugPkg/Library/DebugAgent/SmmDebugAgentLib.inf b/SourceLevelDebugPkg/Library/DebugAgent/SmmDebugAgentLib.inf
index 9ed314d40..2878c3189 100644
--- a/SourceLevelDebugPkg/Library/DebugAgent/SmmDebugAgentLib.inf
+++ b/SourceLevelDebugPkg/Library/DebugAgent/SmmDebugAgentLib.inf
@@ -71,9 +71,11 @@
PrintLib
PeCoffExtraActionLib
PeCoffGetEntryPointLib
+ SmmServicesTableLib
[Guids]
gEfiDebugAgentGuid ## CONSUMES ## Configuration Table
+ gEfiVectorHandoffTableGuid ## SOMETIMES_PRODUCES ## Configuration Table
[Pcd]
gEfiMdePkgTokenSpaceGuid.PcdFSBClock ## CONSUMES
diff --git a/SourceLevelDebugPkg/Library/PeCoffExtraActionLibDebug/Ia32/IntHandlerFuncs.c b/SourceLevelDebugPkg/Library/PeCoffExtraActionLibDebug/Ia32/IntHandlerFuncs.c
index b2d4c37a9..ccf3fb184 100644
--- a/SourceLevelDebugPkg/Library/PeCoffExtraActionLibDebug/Ia32/IntHandlerFuncs.c
+++ b/SourceLevelDebugPkg/Library/PeCoffExtraActionLibDebug/Ia32/IntHandlerFuncs.c
@@ -18,6 +18,7 @@
Read IDT entry to check if IDT entries are setup by Debug Agent.
@param[in] IdtDescriptor Pointer to IDT Descriptor.
+ @param[in] InterruptType Interrupt type.
@retval TRUE IDT entries were setup by Debug Agent.
@retval FALSE IDT entries were not setuo by Debug Agent.
@@ -25,7 +26,8 @@
**/
BOOLEAN
CheckDebugAgentHandler (
- IN IA32_DESCRIPTOR *IdtDescriptor
+ IN IA32_DESCRIPTOR *IdtDescriptor,
+ IN UINTN InterruptType
)
{
IA32_IDT_GATE_DESCRIPTOR *IdtEntry;
@@ -36,8 +38,9 @@ CheckDebugAgentHandler (
return FALSE;
}
- InterruptHandler = IdtEntry[0].Bits.OffsetLow + (IdtEntry[0].Bits.OffsetHigh << 16);
- if (InterruptHandler >= 4 && *(UINT32 *)(InterruptHandler - 4) == AGENT_HANDLER_SIGNATURE) {
+ InterruptHandler = IdtEntry[InterruptType].Bits.OffsetLow +
+ (IdtEntry[InterruptType].Bits.OffsetHigh << 16);
+ if (InterruptHandler >= sizeof (UINT32) && *(UINT32 *)(InterruptHandler - sizeof (UINT32)) == AGENT_HANDLER_SIGNATURE) {
return TRUE;
} else {
return FALSE;
diff --git a/SourceLevelDebugPkg/Library/PeCoffExtraActionLibDebug/PeCoffExtraActionLib.c b/SourceLevelDebugPkg/Library/PeCoffExtraActionLibDebug/PeCoffExtraActionLib.c
index c28d7930a..9bf76bfb2 100644
--- a/SourceLevelDebugPkg/Library/PeCoffExtraActionLibDebug/PeCoffExtraActionLib.c
+++ b/SourceLevelDebugPkg/Library/PeCoffExtraActionLibDebug/PeCoffExtraActionLib.c
@@ -80,18 +80,21 @@ PeCoffLoaderExtraActionCommon (
IdtEntryHooked = FALSE;
LoadImageMethod = PcdGet8 (PcdDebugLoadImageMethod);
AsmReadIdtr (&IdtDescriptor);
- if (!CheckDebugAgentHandler (&IdtDescriptor)) {
- if (LoadImageMethod == DEBUG_LOAD_IMAGE_METHOD_SOFT_INT3) {
+ if (LoadImageMethod == DEBUG_LOAD_IMAGE_METHOD_SOFT_INT3) {
+ if (!CheckDebugAgentHandler (&IdtDescriptor, SOFT_INT_VECTOR_NUM)) {
//
// Do not trigger INT3 if Debug Agent did not setup IDT entries.
//
return;
}
- //
- // Save and update IDT entry for INT1
- //
- SaveAndUpdateIdtEntry1 (&IdtDescriptor, &OriginalIdtEntry);
- IdtEntryHooked = TRUE;
+ } else {
+ if (!CheckDebugAgentHandler (&IdtDescriptor, IO_HW_BREAKPOINT_VECTOR_NUM)) {
+ //
+ // Save and update IDT entry for INT1
+ //
+ SaveAndUpdateIdtEntry1 (&IdtDescriptor, &OriginalIdtEntry);
+ IdtEntryHooked = TRUE;
+ }
}
//
diff --git a/SourceLevelDebugPkg/Library/PeCoffExtraActionLibDebug/PeCoffExtraActionLib.h b/SourceLevelDebugPkg/Library/PeCoffExtraActionLibDebug/PeCoffExtraActionLib.h
index 36aebf16d..3f919287e 100644
--- a/SourceLevelDebugPkg/Library/PeCoffExtraActionLibDebug/PeCoffExtraActionLib.h
+++ b/SourceLevelDebugPkg/Library/PeCoffExtraActionLibDebug/PeCoffExtraActionLib.h
@@ -28,12 +28,16 @@
#define DEBUG_LOAD_IMAGE_METHOD_IO_HW_BREAKPOINT 1
#define DEBUG_LOAD_IMAGE_METHOD_SOFT_INT3 2
+#define IO_HW_BREAKPOINT_VECTOR_NUM 1
+#define SOFT_INT_VECTOR_NUM 3
+
extern UINTN AsmInterruptHandle;
/**
Read IDT entry to check if IDT entries are setup by Debug Agent.
@param[in] IdtDescriptor Pointer to IDT Descriptor.
+ @param[in] InterruptType Interrupt type.
@retval TRUE IDT entries were setup by Debug Agent.
@retval FALSE IDT entries were not setuo by Debug Agent.
@@ -41,7 +45,8 @@ extern UINTN AsmInterruptHandle;
**/
BOOLEAN
CheckDebugAgentHandler (
- IN IA32_DESCRIPTOR *IdtDescriptor
+ IN IA32_DESCRIPTOR *IdtDescriptor,
+ IN UINTN InterruptType
);
/**
diff --git a/SourceLevelDebugPkg/Library/PeCoffExtraActionLibDebug/X64/IntHandlerFuncs.c b/SourceLevelDebugPkg/Library/PeCoffExtraActionLibDebug/X64/IntHandlerFuncs.c
index c9041de76..5431187d0 100644
--- a/SourceLevelDebugPkg/Library/PeCoffExtraActionLibDebug/X64/IntHandlerFuncs.c
+++ b/SourceLevelDebugPkg/Library/PeCoffExtraActionLibDebug/X64/IntHandlerFuncs.c
@@ -18,6 +18,7 @@
Read IDT entry to check if IDT entries are setup by Debug Agent.
@param[in] IdtDescriptor Pointer to IDT Descriptor.
+ @param[in] InterruptType Interrupt type.
@retval TRUE IDT entries were setup by Debug Agent.
@retval FALSE IDT entries were not setuo by Debug Agent.
@@ -25,7 +26,8 @@
**/
BOOLEAN
CheckDebugAgentHandler (
- IN IA32_DESCRIPTOR *IdtDescriptor
+ IN IA32_DESCRIPTOR *IdtDescriptor,
+ IN UINTN InterruptType
)
{
IA32_IDT_GATE_DESCRIPTOR *IdtEntry;
@@ -36,9 +38,10 @@ CheckDebugAgentHandler (
return FALSE;
}
- InterruptHandler = IdtEntry[0].Bits.OffsetLow + (((UINTN)IdtEntry[0].Bits.OffsetHigh) << 16) +
- (((UINTN)IdtEntry[0].Bits.OffsetUpper) << 32);
- if (InterruptHandler >= 4 && *(UINT32 *)(InterruptHandler - 4) == AGENT_HANDLER_SIGNATURE) {
+ InterruptHandler = IdtEntry[InterruptType].Bits.OffsetLow +
+ (((UINTN)IdtEntry[InterruptType].Bits.OffsetHigh) << 16) +
+ (((UINTN)IdtEntry[InterruptType].Bits.OffsetUpper) << 32);
+ if (InterruptHandler >= sizeof (UINT32) && *(UINT32 *)(InterruptHandler - sizeof (UINT32)) == AGENT_HANDLER_SIGNATURE) {
return TRUE;
} else {
return FALSE;
diff --git a/StdLib/EfiSocketLib/EfiSocketLib.inf b/StdLib/EfiSocketLib/EfiSocketLib.inf
index 5e6ff595a..a68e241b7 100644
--- a/StdLib/EfiSocketLib/EfiSocketLib.inf
+++ b/StdLib/EfiSocketLib/EfiSocketLib.inf
@@ -52,6 +52,8 @@
UefiLib
[Protocols]
+ gEfiIp4ConfigProtocolGuid
+ gEfiIp6ConfigProtocolGuid
gEfiIp4ProtocolGuid
gEfiIp4ServiceBindingProtocolGuid
gEfiIp6ProtocolGuid
diff --git a/StdLib/EfiSocketLib/Ip4.c b/StdLib/EfiSocketLib/Ip4.c
index 2e832c7ac..ed7119416 100644
--- a/StdLib/EfiSocketLib/Ip4.c
+++ b/StdLib/EfiSocketLib/Ip4.c
@@ -1067,71 +1067,64 @@ EslIp4TxBuffer (
RAISE_TPL ( TplPrevious, TPL_SOCKETS );
//
- // Stop transmission after an error
+ // Display the request
//
- if ( !EFI_ERROR ( pSocket->TxError )) {
- //
- // Display the request
- //
- DEBUG (( DEBUG_TX,
- "Send %d bytes from 0x%08x, %d.%d.%d.%d --> %d.%d.%d.%d\r\n",
- BufferLength,
- pBuffer,
- pIp4->ModeData.ConfigData.StationAddress.Addr[0],
- pIp4->ModeData.ConfigData.StationAddress.Addr[1],
- pIp4->ModeData.ConfigData.StationAddress.Addr[2],
- pIp4->ModeData.ConfigData.StationAddress.Addr[3],
- pTxData->TxData.DestinationAddress.Addr[0],
- pTxData->TxData.DestinationAddress.Addr[1],
- pTxData->TxData.DestinationAddress.Addr[2],
- pTxData->TxData.DestinationAddress.Addr[3]));
-
- //
- // Queue the data for transmission
- //
- pPacket->pNext = NULL;
- pPreviousPacket = pSocket->pTxPacketListTail;
- if ( NULL == pPreviousPacket ) {
- pSocket->pTxPacketListHead = pPacket;
- }
- else {
- pPreviousPacket->pNext = pPacket;
- }
- pSocket->pTxPacketListTail = pPacket;
- DEBUG (( DEBUG_TX,
- "0x%08x: Packet on transmit list\r\n",
- pPacket ));
-
- //
- // Account for the buffered data
- //
- *pTxBytes += BufferLength;
- *pDataLength = BufferLength;
+ DEBUG (( DEBUG_TX,
+ "Send %d bytes from 0x%08x, %d.%d.%d.%d --> %d.%d.%d.%d\r\n",
+ BufferLength,
+ pBuffer,
+ pIp4->ModeData.ConfigData.StationAddress.Addr[0],
+ pIp4->ModeData.ConfigData.StationAddress.Addr[1],
+ pIp4->ModeData.ConfigData.StationAddress.Addr[2],
+ pIp4->ModeData.ConfigData.StationAddress.Addr[3],
+ pTxData->TxData.DestinationAddress.Addr[0],
+ pTxData->TxData.DestinationAddress.Addr[1],
+ pTxData->TxData.DestinationAddress.Addr[2],
+ pTxData->TxData.DestinationAddress.Addr[3]));
- //
- // Start the transmit engine if it is idle
- //
- if ( NULL != pPort->pTxFree ) {
- EslSocketTxStart ( pPort,
- &pSocket->pTxPacketListHead,
- &pSocket->pTxPacketListTail,
- &pPort->pTxActive,
- &pPort->pTxFree );
- }
+ //
+ // Queue the data for transmission
+ //
+ pPacket->pNext = NULL;
+ pPreviousPacket = pSocket->pTxPacketListTail;
+ if ( NULL == pPreviousPacket ) {
+ pSocket->pTxPacketListHead = pPacket;
}
else {
- //
- // Previous transmit error
- // Stop transmission
- //
- Status = pSocket->TxError;
- pSocket->errno = EIO;
+ pPreviousPacket->pNext = pPacket;
+ }
+ pSocket->pTxPacketListTail = pPacket;
+ DEBUG (( DEBUG_TX,
+ "0x%08x: Packet on transmit list\r\n",
+ pPacket ));
+
+ //
+ // Account for the buffered data
+ //
+ *pTxBytes += BufferLength;
+ *pDataLength = BufferLength;
+
+ //
+ // Start the transmit engine if it is idle
+ //
+ if ( NULL != pPort->pTxFree ) {
+ EslSocketTxStart ( pPort,
+ &pSocket->pTxPacketListHead,
+ &pSocket->pTxPacketListTail,
+ &pPort->pTxActive,
+ &pPort->pTxFree );
//
- // Free the packet
+ // Ignore any transmit error
//
- EslSocketPacketFree ( pPacket, DEBUG_TX );
- break;
+ if ( EFI_ERROR ( pSocket->TxError )) {
+ DEBUG (( DEBUG_TX,
+ "0x%08x: Transmit error, Packet: 0x%08x, Status: %r\r\n",
+ pPort,
+ pPacket,
+ pSocket->TxError ));
+ }
+ pSocket->TxError = EFI_SUCCESS;
}
//
@@ -1213,6 +1206,18 @@ EslIp4TxComplete (
Status = pIo->Token.Ip4Tx.Status;
//
+ // Ignore the transmit error
+ //
+ if ( EFI_ERROR ( Status )) {
+ DEBUG (( DEBUG_TX,
+ "0x%08x: Transmit completion error, Packet: 0x%08x, Status: %r\r\n",
+ pPort,
+ pPacket,
+ Status ));
+ Status = EFI_SUCCESS;
+ }
+
+ //
// Complete the transmit operation
//
EslSocketTxComplete ( pIo,
@@ -1228,6 +1233,157 @@ EslIp4TxComplete (
/**
+ Verify the adapter's IP address
+
+ This support routine is called by EslSocketBindTest.
+
+ @param [in] pPort Address of an ::ESL_PORT structure.
+ @param [in] pConfigData Address of the configuration data
+
+ @retval EFI_SUCCESS - The IP address is valid
+ @retval EFI_NOT_STARTED - The IP address is invalid
+
+ **/
+EFI_STATUS
+EslIp4VerifyLocalIpAddress (
+ IN ESL_PORT * pPort,
+ IN EFI_IP4_CONFIG_DATA * pConfigData
+ )
+{
+ UINTN DataSize;
+ EFI_IP4_IPCONFIG_DATA * pIpConfigData;
+ EFI_IP4_CONFIG_PROTOCOL * pIpConfigProtocol;
+ ESL_SERVICE * pService;
+ EFI_STATUS Status;
+
+ DBG_ENTER ( );
+
+ //
+ // Use break instead of goto
+ //
+ pIpConfigData = NULL;
+ for ( ; ; ) {
+ //
+ // Determine if the IP address is specified
+ //
+ DEBUG (( DEBUG_BIND,
+ "UseDefaultAddress: %s\r\n",
+ pConfigData->UseDefaultAddress ? L"TRUE" : L"FALSE" ));
+ DEBUG (( DEBUG_BIND,
+ "Requested IP address: %d.%d.%d.%d\r\n",
+ pConfigData->StationAddress.Addr [ 0 ],
+ pConfigData->StationAddress.Addr [ 1 ],
+ pConfigData->StationAddress.Addr [ 2 ],
+ pConfigData->StationAddress.Addr [ 3 ]));
+ if ( pConfigData->UseDefaultAddress
+ || (( 0 == pConfigData->StationAddress.Addr [ 0 ])
+ && ( 0 == pConfigData->StationAddress.Addr [ 1 ])
+ && ( 0 == pConfigData->StationAddress.Addr [ 2 ])
+ && ( 0 == pConfigData->StationAddress.Addr [ 3 ])))
+ {
+ Status = EFI_SUCCESS;
+ break;
+ }
+
+ //
+ // Open the configuration protocol
+ //
+ pService = pPort->pService;
+ Status = gBS->OpenProtocol ( pService->Controller,
+ &gEfiIp4ConfigProtocolGuid,
+ (VOID **)&pIpConfigProtocol,
+ NULL,
+ NULL,
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL );
+ if ( EFI_ERROR ( Status )) {
+ DEBUG (( DEBUG_ERROR,
+ "ERROR - IP Configuration Protocol not available, Status: %r\r\n",
+ Status ));
+ break;
+ }
+
+ //
+ // Get the IP configuration data size
+ //
+ DataSize = 0;
+ Status = pIpConfigProtocol->GetData ( pIpConfigProtocol,
+ &DataSize,
+ NULL );
+ if ( EFI_BUFFER_TOO_SMALL != Status ) {
+ DEBUG (( DEBUG_ERROR,
+ "ERROR - Failed to get IP Configuration data size, Status: %r\r\n",
+ Status ));
+ break;
+ }
+
+ //
+ // Allocate the configuration data buffer
+ //
+ pIpConfigData = AllocatePool ( DataSize );
+ if ( NULL == pIpConfigData ) {
+ DEBUG (( DEBUG_ERROR,
+ "ERROR - Not enough memory to allocate IP Configuration data!\r\n" ));
+ Status = EFI_OUT_OF_RESOURCES;
+ break;
+ }
+
+ //
+ // Get the IP configuration
+ //
+ Status = pIpConfigProtocol->GetData ( pIpConfigProtocol,
+ &DataSize,
+ pIpConfigData );
+ if ( EFI_ERROR ( Status )) {
+ DEBUG (( DEBUG_ERROR,
+ "ERROR - Failed to return IP Configuration data, Status: %r\r\n",
+ Status ));
+ break;
+ }
+
+ //
+ // Display the current configuration
+ //
+ DEBUG (( DEBUG_BIND,
+ "Actual adapter IP address: %d.%d.%d.%d\r\n",
+ pIpConfigData->StationAddress.Addr [ 0 ],
+ pIpConfigData->StationAddress.Addr [ 1 ],
+ pIpConfigData->StationAddress.Addr [ 2 ],
+ pIpConfigData->StationAddress.Addr [ 3 ]));
+
+ //
+ // Assume the port is not configured
+ //
+ Status = EFI_SUCCESS;
+ if (( pConfigData->StationAddress.Addr [ 0 ] == pIpConfigData->StationAddress.Addr [ 0 ])
+ && ( pConfigData->StationAddress.Addr [ 1 ] == pIpConfigData->StationAddress.Addr [ 1 ])
+ && ( pConfigData->StationAddress.Addr [ 2 ] == pIpConfigData->StationAddress.Addr [ 2 ])
+ && ( pConfigData->StationAddress.Addr [ 3 ] == pIpConfigData->StationAddress.Addr [ 3 ])) {
+ break;
+ }
+
+ //
+ // The IP address did not match
+ //
+ Status = EFI_NOT_STARTED;
+ break;
+ }
+
+ //
+ // Free the buffer if necessary
+ //
+ if ( NULL != pIpConfigData ) {
+ FreePool ( pIpConfigData );
+ }
+
+ //
+ // Return the IP address status
+ //
+ DBG_EXIT_STATUS ( Status );
+ return Status;
+}
+
+
+/**
Interface between the socket layer and the network specific
code that supports SOCK_RAW sockets over IPv4.
**/
@@ -1265,5 +1421,6 @@ CONST ESL_PROTOCOL_API cEslIp4Api = {
NULL, // RxStart
EslIp4TxBuffer,
EslIp4TxComplete,
- NULL // TxOobComplete
+ NULL, // TxOobComplete
+ (PFN_API_VERIFY_LOCAL_IP_ADDRESS)EslIp4VerifyLocalIpAddress
};
diff --git a/StdLib/EfiSocketLib/Socket.c b/StdLib/EfiSocketLib/Socket.c
index a74dcd07f..b8011951b 100644
--- a/StdLib/EfiSocketLib/Socket.c
+++ b/StdLib/EfiSocketLib/Socket.c
@@ -1336,27 +1336,40 @@ EslSocketBindTest (
pConfigData = (VOID *)pBuffer;
//
- // Attempt to use this configuration
+ // Validate that the port is connected
//
- Status = pPort->pfnConfigure ( pPort->pProtocol.v, pConfigData );
+ Status = pPort->pSocket->pApi->pfnVerifyLocalIpAddress ( pPort, pBuffer );
if ( EFI_ERROR ( Status )) {
DEBUG (( DEBUG_WARN | DEBUG_BIND,
- "WARNING - Port 0x%08x failed configuration, Status: %r\r\n",
+ "WARNING - Port 0x%08x invalid IP address: %r\r\n",
pPort,
Status ));
pPort->pSocket->errno = ErrnoValue;
}
else {
//
- // Reset the port
+ // Attempt to use this configuration
//
- Status = pPort->pfnConfigure ( pPort->pProtocol.v, NULL );
+ Status = pPort->pfnConfigure ( pPort->pProtocol.v, pConfigData );
if ( EFI_ERROR ( Status )) {
- DEBUG (( DEBUG_ERROR | DEBUG_BIND,
- "ERROR - Port 0x%08x failed configuration reset, Status: %r\r\n",
+ DEBUG (( DEBUG_WARN | DEBUG_BIND,
+ "WARNING - Port 0x%08x failed configuration, Status: %r\r\n",
pPort,
Status ));
- ASSERT ( EFI_SUCCESS == Status );
+ pPort->pSocket->errno = ErrnoValue;
+ }
+ else {
+ //
+ // Reset the port
+ //
+ Status = pPort->pfnConfigure ( pPort->pProtocol.v, NULL );
+ if ( EFI_ERROR ( Status )) {
+ DEBUG (( DEBUG_ERROR | DEBUG_BIND,
+ "ERROR - Port 0x%08x failed configuration reset, Status: %r\r\n",
+ pPort,
+ Status ));
+ ASSERT ( EFI_SUCCESS == Status );
+ }
}
}
@@ -5924,11 +5937,25 @@ EslSocketTxStart (
*ppActive = pIo;
}
else {
+ //
+ // Display the transmit error
+ //
+ DEBUG (( DEBUG_TX | DEBUG_INFO,
+ "0x%08x, 0x%08x: pIo, pPacket transmit failure: %r\r\n",
+ pIo,
+ pPacket,
+ Status ));
if ( EFI_SUCCESS == pSocket->TxError ) {
pSocket->TxError = Status;
}
//
+ // Free the IO structure
+ //
+ pIo->pNext = *ppFree;
+ *ppFree = pIo;
+
+ //
// Discard the transmit buffer
//
EslSocketPacketFree ( pPacket, DEBUG_TX );
diff --git a/StdLib/EfiSocketLib/Socket.h b/StdLib/EfiSocketLib/Socket.h
index b38bec6bd..583be1ffd 100644
--- a/StdLib/EfiSocketLib/Socket.h
+++ b/StdLib/EfiSocketLib/Socket.h
@@ -921,6 +921,25 @@ VOID
);
/**
+ Verify the adapter's IP address
+
+ This support routine is called by EslSocketBindTest.
+
+ @param [in] pPort Address of an ::ESL_PORT structure.
+ @param [in] pConfigData Address of the configuration data
+
+ @retval EFI_SUCCESS - The IP address is valid
+ @retval EFI_NOT_STARTED - The IP address is invalid
+
+ **/
+typedef
+EFI_STATUS
+(* PFN_API_VERIFY_LOCAL_IP_ADDRESS) (
+ IN ESL_PORT * pPort,
+ IN VOID * pConfigData
+ );
+
+/**
Socket type control structure
This driver uses this structure to define the API for the socket type.
@@ -960,6 +979,7 @@ typedef struct {
PFN_API_TRANSMIT pfnTransmit; ///< Attempt to buffer a packet for transmit
PFN_API_TX_COMPLETE pfnTxComplete; ///< TX completion for normal data
PFN_API_TX_COMPLETE pfnTxOobComplete; ///< TX completion for urgent data
+ PFN_API_VERIFY_LOCAL_IP_ADDRESS pfnVerifyLocalIpAddress; ///< Verify the local IP address
} ESL_PROTOCOL_API;
diff --git a/StdLib/EfiSocketLib/Tcp4.c b/StdLib/EfiSocketLib/Tcp4.c
index 34e60e2a7..4ef46283b 100644
--- a/StdLib/EfiSocketLib/Tcp4.c
+++ b/StdLib/EfiSocketLib/Tcp4.c
@@ -2226,6 +2226,159 @@ EslTcp4TxOobComplete (
/**
+ Verify the adapter's IP address
+
+ This support routine is called by EslSocketBindTest.
+
+ @param [in] pPort Address of an ::ESL_PORT structure.
+ @param [in] pConfigData Address of the configuration data
+
+ @retval EFI_SUCCESS - The IP address is valid
+ @retval EFI_NOT_STARTED - The IP address is invalid
+
+ **/
+EFI_STATUS
+EslTcp4VerifyLocalIpAddress (
+ IN ESL_PORT * pPort,
+ IN EFI_TCP4_CONFIG_DATA * pConfigData
+ )
+{
+ UINTN DataSize;
+ EFI_TCP4_ACCESS_POINT * pAccess;
+ EFI_IP4_IPCONFIG_DATA * pIpConfigData;
+ EFI_IP4_CONFIG_PROTOCOL * pIpConfigProtocol;
+ ESL_SERVICE * pService;
+ EFI_STATUS Status;
+
+ DBG_ENTER ( );
+
+ //
+ // Use break instead of goto
+ //
+ pIpConfigData = NULL;
+ for ( ; ; ) {
+ //
+ // Determine if the IP address is specified
+ //
+ pAccess = &pConfigData->AccessPoint;
+ DEBUG (( DEBUG_BIND,
+ "UseDefaultAddress: %s\r\n",
+ pAccess->UseDefaultAddress ? L"TRUE" : L"FALSE" ));
+ DEBUG (( DEBUG_BIND,
+ "Requested IP address: %d.%d.%d.%d\r\n",
+ pAccess->StationAddress.Addr [ 0 ],
+ pAccess->StationAddress.Addr [ 1 ],
+ pAccess->StationAddress.Addr [ 2 ],
+ pAccess->StationAddress.Addr [ 3 ]));
+ if ( pAccess->UseDefaultAddress
+ || (( 0 == pAccess->StationAddress.Addr [ 0 ])
+ && ( 0 == pAccess->StationAddress.Addr [ 1 ])
+ && ( 0 == pAccess->StationAddress.Addr [ 2 ])
+ && ( 0 == pAccess->StationAddress.Addr [ 3 ])))
+ {
+ Status = EFI_SUCCESS;
+ break;
+ }
+
+ //
+ // Open the configuration protocol
+ //
+ pService = pPort->pService;
+ Status = gBS->OpenProtocol ( pService->Controller,
+ &gEfiIp4ConfigProtocolGuid,
+ (VOID **)&pIpConfigProtocol,
+ NULL,
+ NULL,
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL );
+ if ( EFI_ERROR ( Status )) {
+ DEBUG (( DEBUG_ERROR,
+ "ERROR - IP Configuration Protocol not available, Status: %r\r\n",
+ Status ));
+ break;
+ }
+
+ //
+ // Get the IP configuration data size
+ //
+ DataSize = 0;
+ Status = pIpConfigProtocol->GetData ( pIpConfigProtocol,
+ &DataSize,
+ NULL );
+ if ( EFI_BUFFER_TOO_SMALL != Status ) {
+ DEBUG (( DEBUG_ERROR,
+ "ERROR - Failed to get IP Configuration data size, Status: %r\r\n",
+ Status ));
+ break;
+ }
+
+ //
+ // Allocate the configuration data buffer
+ //
+ pIpConfigData = AllocatePool ( DataSize );
+ if ( NULL == pIpConfigData ) {
+ DEBUG (( DEBUG_ERROR,
+ "ERROR - Not enough memory to allocate IP Configuration data!\r\n" ));
+ Status = EFI_OUT_OF_RESOURCES;
+ break;
+ }
+
+ //
+ // Get the IP configuration
+ //
+ Status = pIpConfigProtocol->GetData ( pIpConfigProtocol,
+ &DataSize,
+ pIpConfigData );
+ if ( EFI_ERROR ( Status )) {
+ DEBUG (( DEBUG_ERROR,
+ "ERROR - Failed to return IP Configuration data, Status: %r\r\n",
+ Status ));
+ break;
+ }
+
+ //
+ // Display the current configuration
+ //
+ DEBUG (( DEBUG_BIND,
+ "Actual adapter IP address: %d.%d.%d.%d\r\n",
+ pIpConfigData->StationAddress.Addr [ 0 ],
+ pIpConfigData->StationAddress.Addr [ 1 ],
+ pIpConfigData->StationAddress.Addr [ 2 ],
+ pIpConfigData->StationAddress.Addr [ 3 ]));
+
+ //
+ // Assume the port is not configured
+ //
+ Status = EFI_SUCCESS;
+ if (( pAccess->StationAddress.Addr [ 0 ] == pIpConfigData->StationAddress.Addr [ 0 ])
+ && ( pAccess->StationAddress.Addr [ 1 ] == pIpConfigData->StationAddress.Addr [ 1 ])
+ && ( pAccess->StationAddress.Addr [ 2 ] == pIpConfigData->StationAddress.Addr [ 2 ])
+ && ( pAccess->StationAddress.Addr [ 3 ] == pIpConfigData->StationAddress.Addr [ 3 ])) {
+ break;
+ }
+
+ //
+ // The IP address did not match
+ //
+ Status = EFI_NOT_STARTED;
+ break;
+ }
+
+ //
+ // Free the buffer if necessary
+ //
+ if ( NULL != pIpConfigData ) {
+ FreePool ( pIpConfigData );
+ }
+
+ //
+ // Return the IP address status
+ //
+ DBG_EXIT_STATUS ( Status );
+ return Status;
+}
+
+
+/**
Interface between the socket layer and the network specific
code that supports SOCK_STREAM and SOCK_SEQPACKET sockets
over TCPv4.
@@ -2264,5 +2417,6 @@ CONST ESL_PROTOCOL_API cEslTcp4Api = {
EslTcp4RxStart,
EslTcp4TxBuffer,
EslTcp4TxComplete,
- EslTcp4TxOobComplete
+ EslTcp4TxOobComplete,
+ (PFN_API_VERIFY_LOCAL_IP_ADDRESS)EslTcp4VerifyLocalIpAddress
};
diff --git a/StdLib/EfiSocketLib/Tcp6.c b/StdLib/EfiSocketLib/Tcp6.c
index df70a94f4..b2e5538da 100644
--- a/StdLib/EfiSocketLib/Tcp6.c
+++ b/StdLib/EfiSocketLib/Tcp6.c
@@ -2295,6 +2295,262 @@ EslTcp6TxOobComplete (
/**
+ Verify the adapter's IP address
+
+ This support routine is called by EslSocketBindTest.
+
+ @param [in] pPort Address of an ::ESL_PORT structure.
+ @param [in] pConfigData Address of the configuration data
+
+ @retval EFI_SUCCESS - The IP address is valid
+ @retval EFI_NOT_STARTED - The IP address is invalid
+
+ **/
+EFI_STATUS
+EslTcp6VerifyLocalIpAddress (
+ IN ESL_PORT * pPort,
+ IN EFI_TCP6_CONFIG_DATA * pConfigData
+ )
+{
+ UINTN AddressCount;
+ EFI_IP6_ADDRESS_INFO * pAddressInfo;
+ UINTN DataSize;
+ EFI_TCP6_ACCESS_POINT * pAccess;
+ EFI_IP6_CONFIG_INTERFACE_INFO * pIpConfigData;
+ EFI_IP6_CONFIG_PROTOCOL * pIpConfigProtocol;
+ ESL_SERVICE * pService;
+ EFI_STATUS Status;
+
+ DBG_ENTER ( );
+
+ //
+ // Use break instead of goto
+ //
+ pIpConfigData = NULL;
+ for ( ; ; ) {
+ //
+ // Determine if the IP address is specified
+ //
+ pAccess = &pConfigData->AccessPoint;
+ DEBUG (( DEBUG_BIND,
+ "Requested IP address: %02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x\r\n",
+ pAccess->StationAddress.Addr[0],
+ pAccess->StationAddress.Addr[1],
+ pAccess->StationAddress.Addr[2],
+ pAccess->StationAddress.Addr[3],
+ pAccess->StationAddress.Addr[4],
+ pAccess->StationAddress.Addr[5],
+ pAccess->StationAddress.Addr[6],
+ pAccess->StationAddress.Addr[7],
+ pAccess->StationAddress.Addr[8],
+ pAccess->StationAddress.Addr[9],
+ pAccess->StationAddress.Addr[10],
+ pAccess->StationAddress.Addr[11],
+ pAccess->StationAddress.Addr[12],
+ pAccess->StationAddress.Addr[13],
+ pAccess->StationAddress.Addr[14],
+ pAccess->StationAddress.Addr[15]));
+ if (( 0 == pAccess->StationAddress.Addr [ 0 ])
+ && ( 0 == pAccess->StationAddress.Addr [ 1 ])
+ && ( 0 == pAccess->StationAddress.Addr [ 2 ])
+ && ( 0 == pAccess->StationAddress.Addr [ 3 ])
+ && ( 0 == pAccess->StationAddress.Addr [ 4 ])
+ && ( 0 == pAccess->StationAddress.Addr [ 5 ])
+ && ( 0 == pAccess->StationAddress.Addr [ 6 ])
+ && ( 0 == pAccess->StationAddress.Addr [ 7 ])
+ && ( 0 == pAccess->StationAddress.Addr [ 8 ])
+ && ( 0 == pAccess->StationAddress.Addr [ 9 ])
+ && ( 0 == pAccess->StationAddress.Addr [ 10 ])
+ && ( 0 == pAccess->StationAddress.Addr [ 11 ])
+ && ( 0 == pAccess->StationAddress.Addr [ 12 ])
+ && ( 0 == pAccess->StationAddress.Addr [ 13 ])
+ && ( 0 == pAccess->StationAddress.Addr [ 14 ])
+ && ( 0 == pAccess->StationAddress.Addr [ 15 ]))
+ {
+ Status = EFI_SUCCESS;
+ break;
+ }
+
+ //
+ // Open the configuration protocol
+ //
+ pService = pPort->pService;
+ Status = gBS->OpenProtocol ( pService->Controller,
+ &gEfiIp6ConfigProtocolGuid,
+ (VOID **)&pIpConfigProtocol,
+ NULL,
+ NULL,
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL );
+ if ( EFI_ERROR ( Status )) {
+ DEBUG (( DEBUG_ERROR,
+ "ERROR - IP Configuration Protocol not available, Status: %r\r\n",
+ Status ));
+ break;
+ }
+
+ //
+ // Get the IP configuration data size
+ //
+ DataSize = 0;
+ Status = pIpConfigProtocol->GetData ( pIpConfigProtocol,
+ Ip6ConfigDataTypeInterfaceInfo,
+ &DataSize,
+ NULL );
+ if ( EFI_BUFFER_TOO_SMALL != Status ) {
+ DEBUG (( DEBUG_ERROR,
+ "ERROR - Failed to get IP Configuration data size, Status: %r\r\n",
+ Status ));
+ break;
+ }
+
+ //
+ // Allocate the configuration data buffer
+ //
+ pIpConfigData = AllocatePool ( DataSize );
+ if ( NULL == pIpConfigData ) {
+ DEBUG (( DEBUG_ERROR,
+ "ERROR - Not enough memory to allocate IP Configuration data!\r\n" ));
+ Status = EFI_OUT_OF_RESOURCES;
+ break;
+ }
+
+ //
+ // Get the IP configuration
+ //
+ Status = pIpConfigProtocol->GetData ( pIpConfigProtocol,
+ Ip6ConfigDataTypeInterfaceInfo,
+ &DataSize,
+ pIpConfigData );
+ if ( EFI_ERROR ( Status )) {
+ DEBUG (( DEBUG_ERROR,
+ "ERROR - Failed to return IP Configuration data, Status: %r\r\n",
+ Status ));
+ break;
+ }
+
+ //
+ // Display the current configuration
+ //
+ DEBUG (( DEBUG_BIND,
+ "Actual adapter IP address: %02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x\r\n",
+ pIpConfigData->HwAddress.Addr [ 0 ],
+ pIpConfigData->HwAddress.Addr [ 1 ],
+ pIpConfigData->HwAddress.Addr [ 2 ],
+ pIpConfigData->HwAddress.Addr [ 3 ],
+ pIpConfigData->HwAddress.Addr [ 4 ],
+ pIpConfigData->HwAddress.Addr [ 5 ],
+ pIpConfigData->HwAddress.Addr [ 6 ],
+ pIpConfigData->HwAddress.Addr [ 7 ],
+ pIpConfigData->HwAddress.Addr [ 8 ],
+ pIpConfigData->HwAddress.Addr [ 9 ],
+ pIpConfigData->HwAddress.Addr [ 10 ],
+ pIpConfigData->HwAddress.Addr [ 11 ],
+ pIpConfigData->HwAddress.Addr [ 12 ],
+ pIpConfigData->HwAddress.Addr [ 13 ],
+ pIpConfigData->HwAddress.Addr [ 14 ],
+ pIpConfigData->HwAddress.Addr [ 15 ]));
+
+ //
+ // Validate the hardware address
+ //
+ Status = EFI_SUCCESS;
+ if (( 16 == pIpConfigData->HwAddressSize )
+ && ( pAccess->StationAddress.Addr [ 0 ] == pIpConfigData->HwAddress.Addr [ 0 ])
+ && ( pAccess->StationAddress.Addr [ 1 ] == pIpConfigData->HwAddress.Addr [ 1 ])
+ && ( pAccess->StationAddress.Addr [ 2 ] == pIpConfigData->HwAddress.Addr [ 2 ])
+ && ( pAccess->StationAddress.Addr [ 3 ] == pIpConfigData->HwAddress.Addr [ 3 ])
+ && ( pAccess->StationAddress.Addr [ 4 ] == pIpConfigData->HwAddress.Addr [ 4 ])
+ && ( pAccess->StationAddress.Addr [ 5 ] == pIpConfigData->HwAddress.Addr [ 5 ])
+ && ( pAccess->StationAddress.Addr [ 6 ] == pIpConfigData->HwAddress.Addr [ 6 ])
+ && ( pAccess->StationAddress.Addr [ 7 ] == pIpConfigData->HwAddress.Addr [ 7 ])
+ && ( pAccess->StationAddress.Addr [ 8 ] == pIpConfigData->HwAddress.Addr [ 8 ])
+ && ( pAccess->StationAddress.Addr [ 9 ] == pIpConfigData->HwAddress.Addr [ 9 ])
+ && ( pAccess->StationAddress.Addr [ 10 ] == pIpConfigData->HwAddress.Addr [ 10 ])
+ && ( pAccess->StationAddress.Addr [ 11 ] == pIpConfigData->HwAddress.Addr [ 11 ])
+ && ( pAccess->StationAddress.Addr [ 12 ] == pIpConfigData->HwAddress.Addr [ 12 ])
+ && ( pAccess->StationAddress.Addr [ 13 ] == pIpConfigData->HwAddress.Addr [ 13 ])
+ && ( pAccess->StationAddress.Addr [ 14 ] == pIpConfigData->HwAddress.Addr [ 14 ])
+ && ( pAccess->StationAddress.Addr [ 15 ] == pIpConfigData->HwAddress.Addr [ 15 ])) {
+ break;
+ }
+
+ //
+ // Walk the list of other IP addresses assigned to this adapter
+ //
+ for ( AddressCount = 0; pIpConfigData->AddressInfoCount > AddressCount; AddressCount += 1 ) {
+ pAddressInfo = &pIpConfigData->AddressInfo [ AddressCount ];
+
+ //
+ // Display the IP address
+ //
+ DEBUG (( DEBUG_BIND,
+ "Actual adapter IP address: %02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x\r\n",
+ pAddressInfo->Address.Addr [ 0 ],
+ pAddressInfo->Address.Addr [ 1 ],
+ pAddressInfo->Address.Addr [ 2 ],
+ pAddressInfo->Address.Addr [ 3 ],
+ pAddressInfo->Address.Addr [ 4 ],
+ pAddressInfo->Address.Addr [ 5 ],
+ pAddressInfo->Address.Addr [ 6 ],
+ pAddressInfo->Address.Addr [ 7 ],
+ pAddressInfo->Address.Addr [ 8 ],
+ pAddressInfo->Address.Addr [ 9 ],
+ pAddressInfo->Address.Addr [ 10 ],
+ pAddressInfo->Address.Addr [ 11 ],
+ pAddressInfo->Address.Addr [ 12 ],
+ pAddressInfo->Address.Addr [ 13 ],
+ pAddressInfo->Address.Addr [ 14 ],
+ pAddressInfo->Address.Addr [ 15 ]));
+
+ //
+ // Validate the IP address
+ //
+ if (( pAccess->StationAddress.Addr [ 0 ] == pAddressInfo->Address.Addr [ 0 ])
+ && ( pAccess->StationAddress.Addr [ 1 ] == pAddressInfo->Address.Addr [ 1 ])
+ && ( pAccess->StationAddress.Addr [ 2 ] == pAddressInfo->Address.Addr [ 2 ])
+ && ( pAccess->StationAddress.Addr [ 3 ] == pAddressInfo->Address.Addr [ 3 ])
+ && ( pAccess->StationAddress.Addr [ 4 ] == pAddressInfo->Address.Addr [ 4 ])
+ && ( pAccess->StationAddress.Addr [ 5 ] == pAddressInfo->Address.Addr [ 5 ])
+ && ( pAccess->StationAddress.Addr [ 6 ] == pAddressInfo->Address.Addr [ 6 ])
+ && ( pAccess->StationAddress.Addr [ 7 ] == pAddressInfo->Address.Addr [ 7 ])
+ && ( pAccess->StationAddress.Addr [ 8 ] == pAddressInfo->Address.Addr [ 8 ])
+ && ( pAccess->StationAddress.Addr [ 9 ] == pAddressInfo->Address.Addr [ 9 ])
+ && ( pAccess->StationAddress.Addr [ 10 ] == pAddressInfo->Address.Addr [ 10 ])
+ && ( pAccess->StationAddress.Addr [ 11 ] == pAddressInfo->Address.Addr [ 11 ])
+ && ( pAccess->StationAddress.Addr [ 12 ] == pAddressInfo->Address.Addr [ 12 ])
+ && ( pAccess->StationAddress.Addr [ 13 ] == pAddressInfo->Address.Addr [ 13 ])
+ && ( pAccess->StationAddress.Addr [ 14 ] == pAddressInfo->Address.Addr [ 14 ])
+ && ( pAccess->StationAddress.Addr [ 15 ] == pAddressInfo->Address.Addr [ 15 ])) {
+ break;
+ }
+ }
+ if ( pIpConfigData->AddressInfoCount > AddressCount ) {
+ break;
+ }
+
+ //
+ // The IP address did not match
+ //
+ Status = EFI_NOT_STARTED;
+ break;
+ }
+
+ //
+ // Free the buffer if necessary
+ //
+ if ( NULL != pIpConfigData ) {
+ FreePool ( pIpConfigData );
+ }
+
+ //
+ // Return the IP address status
+ //
+ DBG_EXIT_STATUS ( Status );
+ return Status;
+}
+
+
+/**
Interface between the socket layer and the network specific
code that supports SOCK_STREAM and SOCK_SEQPACKET sockets
over TCPv6.
@@ -2333,5 +2589,6 @@ CONST ESL_PROTOCOL_API cEslTcp6Api = {
EslTcp6RxStart,
EslTcp6TxBuffer,
EslTcp6TxComplete,
- EslTcp6TxOobComplete
+ EslTcp6TxOobComplete,
+ (PFN_API_VERIFY_LOCAL_IP_ADDRESS)EslTcp6VerifyLocalIpAddress
};
diff --git a/StdLib/EfiSocketLib/Udp4.c b/StdLib/EfiSocketLib/Udp4.c
index 11b7db761..7fece7509 100644
--- a/StdLib/EfiSocketLib/Udp4.c
+++ b/StdLib/EfiSocketLib/Udp4.c
@@ -867,63 +867,62 @@ EslUdp4TxBuffer (
RAISE_TPL ( TplPrevious, TPL_SOCKETS );
//
- // Stop transmission after an error
+ // Display the request
//
- if ( !EFI_ERROR ( pSocket->TxError )) {
- //
- // Display the request
- //
- DEBUG (( DEBUG_TX,
- "Send %d %s bytes from 0x%08x\r\n",
- BufferLength,
- pBuffer ));
-
- //
- // Queue the data for transmission
- //
- pPacket->pNext = NULL;
- pPreviousPacket = pSocket->pTxPacketListTail;
- if ( NULL == pPreviousPacket ) {
- pSocket->pTxPacketListHead = pPacket;
- }
- else {
- pPreviousPacket->pNext = pPacket;
- }
- pSocket->pTxPacketListTail = pPacket;
- DEBUG (( DEBUG_TX,
- "0x%08x: Packet on transmit list\r\n",
- pPacket ));
-
- //
- // Account for the buffered data
- //
- *pTxBytes += BufferLength;
- *pDataLength = BufferLength;
+ DEBUG (( DEBUG_TX,
+ "Send %d bytes from 0x%08x to %d.%d.%d.%d:%d\r\n",
+ BufferLength,
+ pBuffer,
+ pTxData->Session.DestinationAddress.Addr[0],
+ pTxData->Session.DestinationAddress.Addr[1],
+ pTxData->Session.DestinationAddress.Addr[2],
+ pTxData->Session.DestinationAddress.Addr[3],
+ pTxData->Session.DestinationPort ));
- //
- // Start the transmit engine if it is idle
- //
- if ( NULL != pPort->pTxFree ) {
- EslSocketTxStart ( pPort,
- &pSocket->pTxPacketListHead,
- &pSocket->pTxPacketListTail,
- &pPort->pTxActive,
- &pPort->pTxFree );
- }
+ //
+ // Queue the data for transmission
+ //
+ pPacket->pNext = NULL;
+ pPreviousPacket = pSocket->pTxPacketListTail;
+ if ( NULL == pPreviousPacket ) {
+ pSocket->pTxPacketListHead = pPacket;
}
else {
- //
- // Previous transmit error
- // Stop transmission
- //
- Status = pSocket->TxError;
- pSocket->errno = EIO;
+ pPreviousPacket->pNext = pPacket;
+ }
+ pSocket->pTxPacketListTail = pPacket;
+ DEBUG (( DEBUG_TX,
+ "0x%08x: Packet on transmit list\r\n",
+ pPacket ));
+
+ //
+ // Account for the buffered data
+ //
+ *pTxBytes += BufferLength;
+ *pDataLength = BufferLength;
+
+ //
+ // Start the transmit engine if it is idle
+ //
+ if ( NULL != pPort->pTxFree ) {
+ pPacket = pSocket->pTxPacketListHead;
+ EslSocketTxStart ( pPort,
+ &pSocket->pTxPacketListHead,
+ &pSocket->pTxPacketListTail,
+ &pPort->pTxActive,
+ &pPort->pTxFree );
//
- // Free the packet
+ // Ignore any transmit error
//
- EslSocketPacketFree ( pPacket, DEBUG_TX );
- break;
+ if ( EFI_ERROR ( pSocket->TxError )) {
+ DEBUG (( DEBUG_TX,
+ "0x%08x: Transmit error, Packet: 0x%08x, Status: %r\r\n",
+ pPort,
+ pPacket,
+ pSocket->TxError ));
+ }
+ pSocket->TxError = EFI_SUCCESS;
}
//
@@ -1005,6 +1004,18 @@ EslUdp4TxComplete (
Status = pIo->Token.Udp4Tx.Status;
//
+ // Ignore the transmit error
+ //
+ if ( EFI_ERROR ( Status )) {
+ DEBUG (( DEBUG_TX,
+ "0x%08x: Transmit completion error, Packet: 0x%08x, Status: %r\r\n",
+ pPort,
+ pPacket,
+ Status ));
+ Status = EFI_SUCCESS;
+ }
+
+ //
// Complete the transmit operation
//
EslSocketTxComplete ( pIo,
@@ -1020,6 +1031,157 @@ EslUdp4TxComplete (
/**
+ Verify the adapter's IP address
+
+ This support routine is called by EslSocketBindTest.
+
+ @param [in] pPort Address of an ::ESL_PORT structure.
+ @param [in] pConfigData Address of the configuration data
+
+ @retval EFI_SUCCESS - The IP address is valid
+ @retval EFI_NOT_STARTED - The IP address is invalid
+
+ **/
+EFI_STATUS
+EslUdp4VerifyLocalIpAddress (
+ IN ESL_PORT * pPort,
+ IN EFI_UDP4_CONFIG_DATA * pConfigData
+ )
+{
+ UINTN DataSize;
+ EFI_IP4_IPCONFIG_DATA * pIpConfigData;
+ EFI_IP4_CONFIG_PROTOCOL * pIpConfigProtocol;
+ ESL_SERVICE * pService;
+ EFI_STATUS Status;
+
+ DBG_ENTER ( );
+
+ //
+ // Use break instead of goto
+ //
+ pIpConfigData = NULL;
+ for ( ; ; ) {
+ //
+ // Determine if the IP address is specified
+ //
+ DEBUG (( DEBUG_BIND,
+ "UseDefaultAddress: %s\r\n",
+ pConfigData->UseDefaultAddress ? L"TRUE" : L"FALSE" ));
+ DEBUG (( DEBUG_BIND,
+ "Requested IP address: %d.%d.%d.%d\r\n",
+ pConfigData->StationAddress.Addr [ 0 ],
+ pConfigData->StationAddress.Addr [ 1 ],
+ pConfigData->StationAddress.Addr [ 2 ],
+ pConfigData->StationAddress.Addr [ 3 ]));
+ if ( pConfigData->UseDefaultAddress
+ || (( 0 == pConfigData->StationAddress.Addr [ 0 ])
+ && ( 0 == pConfigData->StationAddress.Addr [ 1 ])
+ && ( 0 == pConfigData->StationAddress.Addr [ 2 ])
+ && ( 0 == pConfigData->StationAddress.Addr [ 3 ])))
+ {
+ Status = EFI_SUCCESS;
+ break;
+ }
+
+ //
+ // Open the configuration protocol
+ //
+ pService = pPort->pService;
+ Status = gBS->OpenProtocol ( pService->Controller,
+ &gEfiIp4ConfigProtocolGuid,
+ (VOID **)&pIpConfigProtocol,
+ NULL,
+ NULL,
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL );
+ if ( EFI_ERROR ( Status )) {
+ DEBUG (( DEBUG_ERROR,
+ "ERROR - IP Configuration Protocol not available, Status: %r\r\n",
+ Status ));
+ break;
+ }
+
+ //
+ // Get the IP configuration data size
+ //
+ DataSize = 0;
+ Status = pIpConfigProtocol->GetData ( pIpConfigProtocol,
+ &DataSize,
+ NULL );
+ if ( EFI_BUFFER_TOO_SMALL != Status ) {
+ DEBUG (( DEBUG_ERROR,
+ "ERROR - Failed to get IP Configuration data size, Status: %r\r\n",
+ Status ));
+ break;
+ }
+
+ //
+ // Allocate the configuration data buffer
+ //
+ pIpConfigData = AllocatePool ( DataSize );
+ if ( NULL == pIpConfigData ) {
+ DEBUG (( DEBUG_ERROR,
+ "ERROR - Not enough memory to allocate IP Configuration data!\r\n" ));
+ Status = EFI_OUT_OF_RESOURCES;
+ break;
+ }
+
+ //
+ // Get the IP configuration
+ //
+ Status = pIpConfigProtocol->GetData ( pIpConfigProtocol,
+ &DataSize,
+ pIpConfigData );
+ if ( EFI_ERROR ( Status )) {
+ DEBUG (( DEBUG_ERROR,
+ "ERROR - Failed to return IP Configuration data, Status: %r\r\n",
+ Status ));
+ break;
+ }
+
+ //
+ // Display the current configuration
+ //
+ DEBUG (( DEBUG_BIND,
+ "Actual adapter IP address: %d.%d.%d.%d\r\n",
+ pIpConfigData->StationAddress.Addr [ 0 ],
+ pIpConfigData->StationAddress.Addr [ 1 ],
+ pIpConfigData->StationAddress.Addr [ 2 ],
+ pIpConfigData->StationAddress.Addr [ 3 ]));
+
+ //
+ // Assume the port is not configured
+ //
+ Status = EFI_SUCCESS;
+ if (( pConfigData->StationAddress.Addr [ 0 ] == pIpConfigData->StationAddress.Addr [ 0 ])
+ && ( pConfigData->StationAddress.Addr [ 1 ] == pIpConfigData->StationAddress.Addr [ 1 ])
+ && ( pConfigData->StationAddress.Addr [ 2 ] == pIpConfigData->StationAddress.Addr [ 2 ])
+ && ( pConfigData->StationAddress.Addr [ 3 ] == pIpConfigData->StationAddress.Addr [ 3 ])) {
+ break;
+ }
+
+ //
+ // The IP address did not match
+ //
+ Status = EFI_NOT_STARTED;
+ break;
+ }
+
+ //
+ // Free the buffer if necessary
+ //
+ if ( NULL != pIpConfigData ) {
+ FreePool ( pIpConfigData );
+ }
+
+ //
+ // Return the IP address status
+ //
+ DBG_EXIT_STATUS ( Status );
+ return Status;
+}
+
+
+/**
Interface between the socket layer and the network specific
code that supports SOCK_DGRAM sockets over UDPv4.
**/
@@ -1057,5 +1219,6 @@ CONST ESL_PROTOCOL_API cEslUdp4Api = {
NULL, // RxStart
EslUdp4TxBuffer,
EslUdp4TxComplete,
- NULL // TxOobComplete
+ NULL, // TxOobComplete
+ (PFN_API_VERIFY_LOCAL_IP_ADDRESS)EslUdp4VerifyLocalIpAddress
};
diff --git a/StdLib/EfiSocketLib/Udp6.c b/StdLib/EfiSocketLib/Udp6.c
index 7de500509..34df06494 100644
--- a/StdLib/EfiSocketLib/Udp6.c
+++ b/StdLib/EfiSocketLib/Udp6.c
@@ -609,7 +609,7 @@ EslUdp6RxComplete (
pUdp6Protocol = pPort->pProtocol.UDPv6;
pConfigData = &pUdp6->ConfigData;
DEBUG (( DEBUG_TX,
- "0x%08x: pPort Configuring for [%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x]:%d --> [%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x]:%d\r\n",
+ "0x%08x: pPort Configuring for [%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x]:%d --> ",
pPort,
pConfigData->StationAddress.Addr[0],
pConfigData->StationAddress.Addr[1],
@@ -627,7 +627,9 @@ EslUdp6RxComplete (
pConfigData->StationAddress.Addr[13],
pConfigData->StationAddress.Addr[14],
pConfigData->StationAddress.Addr[15],
- pConfigData->StationPort,
+ pConfigData->StationPort ));
+ DEBUG (( DEBUG_TX,
+ "[%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x]:%d\r\n",
pConfigData->RemoteAddress.Addr[0],
pConfigData->RemoteAddress.Addr[1],
pConfigData->RemoteAddress.Addr[2],
@@ -692,7 +694,7 @@ EslUdp6RxComplete (
}
else {
DEBUG (( DEBUG_TX,
- "0x%08x: pPort Configured for [%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x]:%d --> [%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x]:%d\r\n",
+ "0x%08x: pPort Configured for [%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x]:%d --> ",
pPort,
pConfigData->StationAddress.Addr[0],
pConfigData->StationAddress.Addr[1],
@@ -710,7 +712,9 @@ EslUdp6RxComplete (
pConfigData->StationAddress.Addr[13],
pConfigData->StationAddress.Addr[14],
pConfigData->StationAddress.Addr[15],
- pConfigData->StationPort,
+ pConfigData->StationPort ));
+ DEBUG (( DEBUG_TX,
+ "[%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x]:%d\r\n",
pConfigData->RemoteAddress.Addr[0],
pConfigData->RemoteAddress.Addr[1],
pConfigData->RemoteAddress.Addr[2],
@@ -904,63 +908,73 @@ EslUdp6TxBuffer (
RAISE_TPL ( TplPrevious, TPL_SOCKETS );
//
- // Stop transmission after an error
+ // Display the request
//
- if ( !EFI_ERROR ( pSocket->TxError )) {
- //
- // Display the request
- //
- DEBUG (( DEBUG_TX,
- "Send %d %s bytes from 0x%08x\r\n",
- BufferLength,
- pBuffer ));
-
- //
- // Queue the data for transmission
- //
- pPacket->pNext = NULL;
- pPreviousPacket = pSocket->pTxPacketListTail;
- if ( NULL == pPreviousPacket ) {
- pSocket->pTxPacketListHead = pPacket;
- }
- else {
- pPreviousPacket->pNext = pPacket;
- }
- pSocket->pTxPacketListTail = pPacket;
- DEBUG (( DEBUG_TX,
- "0x%08x: Packet on transmit list\r\n",
- pPacket ));
-
- //
- // Account for the buffered data
- //
- *pTxBytes += BufferLength;
- *pDataLength = BufferLength;
+ DEBUG (( DEBUG_TX,
+ "Send %d bytes from 0x%08x to [%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x]:%d\r\n",
+ BufferLength,
+ pBuffer,
+ pTxData->Session.DestinationAddress.Addr[0],
+ pTxData->Session.DestinationAddress.Addr[1],
+ pTxData->Session.DestinationAddress.Addr[2],
+ pTxData->Session.DestinationAddress.Addr[3],
+ pTxData->Session.DestinationAddress.Addr[4],
+ pTxData->Session.DestinationAddress.Addr[5],
+ pTxData->Session.DestinationAddress.Addr[6],
+ pTxData->Session.DestinationAddress.Addr[7],
+ pTxData->Session.DestinationAddress.Addr[8],
+ pTxData->Session.DestinationAddress.Addr[9],
+ pTxData->Session.DestinationAddress.Addr[10],
+ pTxData->Session.DestinationAddress.Addr[11],
+ pTxData->Session.DestinationAddress.Addr[12],
+ pTxData->Session.DestinationAddress.Addr[13],
+ pTxData->Session.DestinationAddress.Addr[14],
+ pTxData->Session.DestinationAddress.Addr[15],
+ pTxData->Session.DestinationPort ));
- //
- // Start the transmit engine if it is idle
- //
- if ( NULL != pPort->pTxFree ) {
- EslSocketTxStart ( pPort,
- &pSocket->pTxPacketListHead,
- &pSocket->pTxPacketListTail,
- &pPort->pTxActive,
- &pPort->pTxFree );
- }
+ //
+ // Queue the data for transmission
+ //
+ pPacket->pNext = NULL;
+ pPreviousPacket = pSocket->pTxPacketListTail;
+ if ( NULL == pPreviousPacket ) {
+ pSocket->pTxPacketListHead = pPacket;
}
else {
- //
- // Previous transmit error
- // Stop transmission
- //
- Status = pSocket->TxError;
- pSocket->errno = EIO;
+ pPreviousPacket->pNext = pPacket;
+ }
+ pSocket->pTxPacketListTail = pPacket;
+ DEBUG (( DEBUG_TX,
+ "0x%08x: Packet on transmit list\r\n",
+ pPacket ));
+
+ //
+ // Account for the buffered data
+ //
+ *pTxBytes += BufferLength;
+ *pDataLength = BufferLength;
+
+ //
+ // Start the transmit engine if it is idle
+ //
+ if ( NULL != pPort->pTxFree ) {
+ EslSocketTxStart ( pPort,
+ &pSocket->pTxPacketListHead,
+ &pSocket->pTxPacketListTail,
+ &pPort->pTxActive,
+ &pPort->pTxFree );
//
- // Free the packet
+ // Ignore any transmit error
//
- EslSocketPacketFree ( pPacket, DEBUG_TX );
- break;
+ if ( EFI_ERROR ( pSocket->TxError )) {
+ DEBUG (( DEBUG_TX,
+ "0x%08x: Transmit error, Packet: 0x%08x, Status: %r\r\n",
+ pPort,
+ pPacket,
+ pSocket->TxError ));
+ }
+ pSocket->TxError = EFI_SUCCESS;
}
//
@@ -1042,6 +1056,18 @@ EslUdp6TxComplete (
Status = pIo->Token.Udp6Tx.Status;
//
+ // Ignore the transmit error
+ //
+ if ( EFI_ERROR ( Status )) {
+ DEBUG (( DEBUG_TX,
+ "0x%08x: Transmit completion error, Packet: 0x%08x, Status: %r\r\n",
+ pPort,
+ pPacket,
+ Status ));
+ Status = EFI_SUCCESS;
+ }
+
+ //
// Complete the transmit operation
//
EslSocketTxComplete ( pIo,
@@ -1057,6 +1083,260 @@ EslUdp6TxComplete (
/**
+ Verify the adapter's IP address
+
+ This support routine is called by EslSocketBindTest.
+
+ @param [in] pPort Address of an ::ESL_PORT structure.
+ @param [in] pConfigData Address of the configuration data
+
+ @retval EFI_SUCCESS - The IP address is valid
+ @retval EFI_NOT_STARTED - The IP address is invalid
+
+ **/
+EFI_STATUS
+EslUdp6VerifyLocalIpAddress (
+ IN ESL_PORT * pPort,
+ IN EFI_UDP6_CONFIG_DATA * pConfigData
+ )
+{
+ UINTN AddressCount;
+ EFI_IP6_ADDRESS_INFO * pAddressInfo;
+ UINTN DataSize;
+ EFI_IP6_CONFIG_INTERFACE_INFO * pIpConfigData;
+ EFI_IP6_CONFIG_PROTOCOL * pIpConfigProtocol;
+ ESL_SERVICE * pService;
+ EFI_STATUS Status;
+
+ DBG_ENTER ( );
+
+ //
+ // Use break instead of goto
+ //
+ pIpConfigData = NULL;
+ for ( ; ; ) {
+ //
+ // Determine if the IP address is specified
+ //
+ DEBUG (( DEBUG_BIND,
+ "Requested IP address: %02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x\r\n",
+ pConfigData->StationAddress.Addr[0],
+ pConfigData->StationAddress.Addr[1],
+ pConfigData->StationAddress.Addr[2],
+ pConfigData->StationAddress.Addr[3],
+ pConfigData->StationAddress.Addr[4],
+ pConfigData->StationAddress.Addr[5],
+ pConfigData->StationAddress.Addr[6],
+ pConfigData->StationAddress.Addr[7],
+ pConfigData->StationAddress.Addr[8],
+ pConfigData->StationAddress.Addr[9],
+ pConfigData->StationAddress.Addr[10],
+ pConfigData->StationAddress.Addr[11],
+ pConfigData->StationAddress.Addr[12],
+ pConfigData->StationAddress.Addr[13],
+ pConfigData->StationAddress.Addr[14],
+ pConfigData->StationAddress.Addr[15]));
+ if (( 0 == pConfigData->StationAddress.Addr [ 0 ])
+ && ( 0 == pConfigData->StationAddress.Addr [ 1 ])
+ && ( 0 == pConfigData->StationAddress.Addr [ 2 ])
+ && ( 0 == pConfigData->StationAddress.Addr [ 3 ])
+ && ( 0 == pConfigData->StationAddress.Addr [ 4 ])
+ && ( 0 == pConfigData->StationAddress.Addr [ 5 ])
+ && ( 0 == pConfigData->StationAddress.Addr [ 6 ])
+ && ( 0 == pConfigData->StationAddress.Addr [ 7 ])
+ && ( 0 == pConfigData->StationAddress.Addr [ 8 ])
+ && ( 0 == pConfigData->StationAddress.Addr [ 9 ])
+ && ( 0 == pConfigData->StationAddress.Addr [ 10 ])
+ && ( 0 == pConfigData->StationAddress.Addr [ 11 ])
+ && ( 0 == pConfigData->StationAddress.Addr [ 12 ])
+ && ( 0 == pConfigData->StationAddress.Addr [ 13 ])
+ && ( 0 == pConfigData->StationAddress.Addr [ 14 ])
+ && ( 0 == pConfigData->StationAddress.Addr [ 15 ]))
+ {
+ Status = EFI_SUCCESS;
+ break;
+ }
+
+ //
+ // Open the configuration protocol
+ //
+ pService = pPort->pService;
+ Status = gBS->OpenProtocol ( pService->Controller,
+ &gEfiIp6ConfigProtocolGuid,
+ (VOID **)&pIpConfigProtocol,
+ NULL,
+ NULL,
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL );
+ if ( EFI_ERROR ( Status )) {
+ DEBUG (( DEBUG_ERROR,
+ "ERROR - IP Configuration Protocol not available, Status: %r\r\n",
+ Status ));
+ break;
+ }
+
+ //
+ // Get the IP configuration data size
+ //
+ DataSize = 0;
+ Status = pIpConfigProtocol->GetData ( pIpConfigProtocol,
+ Ip6ConfigDataTypeInterfaceInfo,
+ &DataSize,
+ NULL );
+ if ( EFI_BUFFER_TOO_SMALL != Status ) {
+ DEBUG (( DEBUG_ERROR,
+ "ERROR - Failed to get IP Configuration data size, Status: %r\r\n",
+ Status ));
+ break;
+ }
+
+ //
+ // Allocate the configuration data buffer
+ //
+ pIpConfigData = AllocatePool ( DataSize );
+ if ( NULL == pIpConfigData ) {
+ DEBUG (( DEBUG_ERROR,
+ "ERROR - Not enough memory to allocate IP Configuration data!\r\n" ));
+ Status = EFI_OUT_OF_RESOURCES;
+ break;
+ }
+
+ //
+ // Get the IP configuration
+ //
+ Status = pIpConfigProtocol->GetData ( pIpConfigProtocol,
+ Ip6ConfigDataTypeInterfaceInfo,
+ &DataSize,
+ pIpConfigData );
+ if ( EFI_ERROR ( Status )) {
+ DEBUG (( DEBUG_ERROR,
+ "ERROR - Failed to return IP Configuration data, Status: %r\r\n",
+ Status ));
+ break;
+ }
+
+ //
+ // Display the current configuration
+ //
+ DEBUG (( DEBUG_BIND,
+ "Actual adapter IP address: %02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x\r\n",
+ pIpConfigData->HwAddress.Addr [ 0 ],
+ pIpConfigData->HwAddress.Addr [ 1 ],
+ pIpConfigData->HwAddress.Addr [ 2 ],
+ pIpConfigData->HwAddress.Addr [ 3 ],
+ pIpConfigData->HwAddress.Addr [ 4 ],
+ pIpConfigData->HwAddress.Addr [ 5 ],
+ pIpConfigData->HwAddress.Addr [ 6 ],
+ pIpConfigData->HwAddress.Addr [ 7 ],
+ pIpConfigData->HwAddress.Addr [ 8 ],
+ pIpConfigData->HwAddress.Addr [ 9 ],
+ pIpConfigData->HwAddress.Addr [ 10 ],
+ pIpConfigData->HwAddress.Addr [ 11 ],
+ pIpConfigData->HwAddress.Addr [ 12 ],
+ pIpConfigData->HwAddress.Addr [ 13 ],
+ pIpConfigData->HwAddress.Addr [ 14 ],
+ pIpConfigData->HwAddress.Addr [ 15 ]));
+
+ //
+ // Validate the hardware address
+ //
+ Status = EFI_SUCCESS;
+ if (( 16 == pIpConfigData->HwAddressSize )
+ && ( pConfigData->StationAddress.Addr [ 0 ] == pIpConfigData->HwAddress.Addr [ 0 ])
+ && ( pConfigData->StationAddress.Addr [ 1 ] == pIpConfigData->HwAddress.Addr [ 1 ])
+ && ( pConfigData->StationAddress.Addr [ 2 ] == pIpConfigData->HwAddress.Addr [ 2 ])
+ && ( pConfigData->StationAddress.Addr [ 3 ] == pIpConfigData->HwAddress.Addr [ 3 ])
+ && ( pConfigData->StationAddress.Addr [ 4 ] == pIpConfigData->HwAddress.Addr [ 4 ])
+ && ( pConfigData->StationAddress.Addr [ 5 ] == pIpConfigData->HwAddress.Addr [ 5 ])
+ && ( pConfigData->StationAddress.Addr [ 6 ] == pIpConfigData->HwAddress.Addr [ 6 ])
+ && ( pConfigData->StationAddress.Addr [ 7 ] == pIpConfigData->HwAddress.Addr [ 7 ])
+ && ( pConfigData->StationAddress.Addr [ 8 ] == pIpConfigData->HwAddress.Addr [ 8 ])
+ && ( pConfigData->StationAddress.Addr [ 9 ] == pIpConfigData->HwAddress.Addr [ 9 ])
+ && ( pConfigData->StationAddress.Addr [ 10 ] == pIpConfigData->HwAddress.Addr [ 10 ])
+ && ( pConfigData->StationAddress.Addr [ 11 ] == pIpConfigData->HwAddress.Addr [ 11 ])
+ && ( pConfigData->StationAddress.Addr [ 12 ] == pIpConfigData->HwAddress.Addr [ 12 ])
+ && ( pConfigData->StationAddress.Addr [ 13 ] == pIpConfigData->HwAddress.Addr [ 13 ])
+ && ( pConfigData->StationAddress.Addr [ 14 ] == pIpConfigData->HwAddress.Addr [ 14 ])
+ && ( pConfigData->StationAddress.Addr [ 15 ] == pIpConfigData->HwAddress.Addr [ 15 ])) {
+ break;
+ }
+
+ //
+ // Walk the list of other IP addresses assigned to this adapter
+ //
+ for ( AddressCount = 0; pIpConfigData->AddressInfoCount > AddressCount; AddressCount += 1 ) {
+ pAddressInfo = &pIpConfigData->AddressInfo [ AddressCount ];
+
+ //
+ // Display the IP address
+ //
+ DEBUG (( DEBUG_BIND,
+ "Actual adapter IP address: %02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x\r\n",
+ pAddressInfo->Address.Addr [ 0 ],
+ pAddressInfo->Address.Addr [ 1 ],
+ pAddressInfo->Address.Addr [ 2 ],
+ pAddressInfo->Address.Addr [ 3 ],
+ pAddressInfo->Address.Addr [ 4 ],
+ pAddressInfo->Address.Addr [ 5 ],
+ pAddressInfo->Address.Addr [ 6 ],
+ pAddressInfo->Address.Addr [ 7 ],
+ pAddressInfo->Address.Addr [ 8 ],
+ pAddressInfo->Address.Addr [ 9 ],
+ pAddressInfo->Address.Addr [ 10 ],
+ pAddressInfo->Address.Addr [ 11 ],
+ pAddressInfo->Address.Addr [ 12 ],
+ pAddressInfo->Address.Addr [ 13 ],
+ pAddressInfo->Address.Addr [ 14 ],
+ pAddressInfo->Address.Addr [ 15 ]));
+
+ //
+ // Validate the IP address
+ //
+ if (( pConfigData->StationAddress.Addr [ 0 ] == pAddressInfo->Address.Addr [ 0 ])
+ && ( pConfigData->StationAddress.Addr [ 1 ] == pAddressInfo->Address.Addr [ 1 ])
+ && ( pConfigData->StationAddress.Addr [ 2 ] == pAddressInfo->Address.Addr [ 2 ])
+ && ( pConfigData->StationAddress.Addr [ 3 ] == pAddressInfo->Address.Addr [ 3 ])
+ && ( pConfigData->StationAddress.Addr [ 4 ] == pAddressInfo->Address.Addr [ 4 ])
+ && ( pConfigData->StationAddress.Addr [ 5 ] == pAddressInfo->Address.Addr [ 5 ])
+ && ( pConfigData->StationAddress.Addr [ 6 ] == pAddressInfo->Address.Addr [ 6 ])
+ && ( pConfigData->StationAddress.Addr [ 7 ] == pAddressInfo->Address.Addr [ 7 ])
+ && ( pConfigData->StationAddress.Addr [ 8 ] == pAddressInfo->Address.Addr [ 8 ])
+ && ( pConfigData->StationAddress.Addr [ 9 ] == pAddressInfo->Address.Addr [ 9 ])
+ && ( pConfigData->StationAddress.Addr [ 10 ] == pAddressInfo->Address.Addr [ 10 ])
+ && ( pConfigData->StationAddress.Addr [ 11 ] == pAddressInfo->Address.Addr [ 11 ])
+ && ( pConfigData->StationAddress.Addr [ 12 ] == pAddressInfo->Address.Addr [ 12 ])
+ && ( pConfigData->StationAddress.Addr [ 13 ] == pAddressInfo->Address.Addr [ 13 ])
+ && ( pConfigData->StationAddress.Addr [ 14 ] == pAddressInfo->Address.Addr [ 14 ])
+ && ( pConfigData->StationAddress.Addr [ 15 ] == pAddressInfo->Address.Addr [ 15 ])) {
+ break;
+ }
+ }
+ if ( pIpConfigData->AddressInfoCount > AddressCount ) {
+ break;
+ }
+
+ //
+ // The IP address did not match
+ //
+ Status = EFI_NOT_STARTED;
+ break;
+ }
+
+ //
+ // Free the buffer if necessary
+ //
+ if ( NULL != pIpConfigData ) {
+ FreePool ( pIpConfigData );
+ }
+
+ //
+ // Return the IP address status
+ //
+ DBG_EXIT_STATUS ( Status );
+ return Status;
+}
+
+
+/**
Interface between the socket layer and the network specific
code that supports SOCK_DGRAM sockets over UDPv4.
**/
@@ -1094,5 +1374,6 @@ CONST ESL_PROTOCOL_API cEslUdp6Api = {
NULL, // RxStart
EslUdp6TxBuffer,
EslUdp6TxComplete,
- NULL // TxOobComplete
+ NULL, // TxOobComplete
+ (PFN_API_VERIFY_LOCAL_IP_ADDRESS)EslUdp6VerifyLocalIpAddress
};
diff --git a/StdLib/Fixes.txt b/StdLib/Fixes.txt
new file mode 100644
index 000000000..0e70e05f6
--- /dev/null
+++ b/StdLib/Fixes.txt
@@ -0,0 +1,41 @@
+The following is a list of issues that have been fixed in the StdLib Package.
+See the file Issues.txt for a list of open, unresolved, problems.
+
+ Status Key:
+ Fixed Problem has been resolved and changes committed.
+
+SocketLib
+=============
+ID Category TOOLs Reported Status
+---- ------------------------ -------- -------------- -----------
+
+StdLib Issues
+=============
+ID Category TOOLs Reported Status
+---- ------------------------ -------- -------------- -----------
+ 1: Compilation Error vs2010 2012 Fixed 3/2013
+ stdlib\libc\gdtoa\strtod.c(825) : warning C4789: destination of memory copy
+ is too small: runtime crashes when using floating-point formats with printf
+
+ 2: Compilation Error ALL 2012 Fixed 1/2012
+ StdLib/LibC/Uefi/SysCalls.c: In function 'utimes':
+ error: 'va_start' used in function with fixed args
+
+ 4: Execution/Compile errors 2012 Fixed 1/2013
+ Mismatch in use of EFIAPI between declaration and definition of some functions.
+
+ 7: Compilation Error GCC46 Jan, 2013 Fixed 1/2013
+ StdLib/LibC/Containers/Queues/Fifo.c:508:27:
+ error: assignment from incompatible pointer type
+
+ 8: Compilation Error Jan. 2013 Fixed 1/2013
+ StdLib\LibC\Uefi\InteractiveIO\IIOutilities.c
+ IIO_CursorDelta: Declaration return type differs from definition return type.
+
+ 11: printf("-%ls-", L"test") will only print "--" 2013 Fixed 3/2013
+
+
+PosixLib
+=============
+ID Category TOOLs Reported Status
+---- ------------------------ -------- -------------- -----------
diff --git a/StdLib/ISSUES.txt b/StdLib/ISSUES.txt
index 25317f7a6..947450001 100644
--- a/StdLib/ISSUES.txt
+++ b/StdLib/ISSUES.txt
@@ -1,3 +1,6 @@
+What follows is a list of currently known issues with the StdLib package.
+Please see the separate file "Fixes.txt" for a list of issues that have been fixed.
+
Status Key:
Open Problem is unresolved and final disposition unknown.
Verified Problem has been reproduced.
@@ -7,52 +10,53 @@
SocketLib
=============
- Category TOOLs Reported Status
- ------------------------ -------- -------------- -----------
-
-StdLib Issues
-=============
- Category TOOLs Reported Status
- ------------------------ -------- -------------- -----------
-1: Compilation Error vs2010 2012 Fixed 3/2013
- stdlib\libc\gdtoa\strtod.c(825) : warning C4789: destination of memory copy is too small
- runtime crashes when using floating-point formats with printf
+ID Category TOOLs Reported Status
+---- ------------------------ -------- -------------- -----------
+ 13: EFIAPI usage 2013-01-15 Understood
+ Mismatch between functions declared EFIAPI but not defined EFIAPI.
-2: Compilation Error ALL 2012 Fixed 1/2012
- StdLib/LibC/Uefi/SysCalls.c: In function 'utimes': error: 'va_start' used in function with fixed args
+ 14: EFIAPI usage 2013-01-15 Understood
+ Function pointer type PFN_NET_CONFIGURE is NOT defined as EFIAPI but is
+ used to point to EFIAPI functions. This causes conflicts and results in
+ improper operation.
-3: Usage Clarification 2012 Document
- Clarify that the current StdLib may not be used for developing drivers.
+ 15: Build Error 2013-09-20 Open
+ Predicates in ns_addr.c and res_mkupdate.c need to also include explicit
+ comparisons if an assignment side-effect is used. Otherwise a warning
+ will be generated which is promoted to a fatal error.
-4: Execution/Compile errors 2012 Fixed 1/2013
- Mismatch in use of EFIAPI between declaration and definition of some functions.
-
-5: Error message Quality during execution 2012 Verified
- Performing filesystem operations when a filesystem driver has not been
- linked into the application results in hangs or error messages that are
- misleading or unclear as to the cause.
+StdLib Issues
+=============
+ID Category TOOLs Reported Status
+---- ------------------------ -------- -------------- -----------
+ 3: Usage Clarification 2012 Document
+ Clarify that the current StdLib may not be used for developing drivers.
-6: Application error return 2012 Verified
- On error, applications will sometimes return large positive numbers.
+ 5: Error message Quality during execution 2012 Verified
+ Performing filesystem operations when a filesystem driver has not been
+ linked into the application results in hangs or error messages that are
+ misleading or unclear as to the cause.
-7: Compilation Error GCC46 Jan, 2013 Fixed 1/2013
- StdLib/LibC/Containers/Queues/Fifo.c:508:27: error: assignment from incompatible pointer type
+ 6: Application error return 2012 Verified
+ On error, applications will sometimes return large positive numbers.
-8: Compilation Error
- StdLib\LibC\Uefi\InteractiveIO\IIOutilities.c Jan. 2013 Fixed 1/2013
- IIO_CursorDelta: Declaration return type differs from definition return type.
+ 9: chdir/cwd not in EFI Shell 2012 Understood
+ The chdir and getcwd functions only work if one is using the UEFI Shell.
-9: chdir/cwd not in EFI Shell 2012 Understood
- The chdir and getcwd functions only work if one is using the UEFI Shell.
+ 10: No current volume/directory at app. startup. 2012 Understood
+ If the Shell does not have a current volume or directory, file operations
+ may hang or fail.
-10: No current volume/directory at app. startup. 2012 Understood
- If the Shell does not have a current volume or directory, file operations
- may hang or fail.
+ 12: Differentiate between binary and text streams. Aug. 2013 Understood
+ Implement differentiated text streams as specified by section 7.19.2 Streams,
+ of the C standard.
-11: printf("-%ls-", L"test") will only print "--" 2013 Fixed 3/2013
+ 16: Build Error 2013-08-12 Understood
+ LibC/Stdio/vsnprintf_ss.c:145: (error) Uninitialized variable: n
+ _DIAGASSERT expressions not appropriate for the UEFI environment.
PosixLib
=============
- Category TOOLs Reported Status
- ------------------------ -------- -------------- -----------
+ID Category TOOLs Reported Status
+---- ------------------------ -------- -------------- -----------
diff --git a/StdLib/Include/Efi/EfiSocketLib.h b/StdLib/Include/Efi/EfiSocketLib.h
index d78e9f6a1..efd6a61b1 100644
--- a/StdLib/Include/Efi/EfiSocketLib.h
+++ b/StdLib/Include/Efi/EfiSocketLib.h
@@ -24,6 +24,8 @@
#include <Library/UefiLib.h>
#include <Protocol/EfiSocket.h>
+#include <Protocol/Ip4Config.h>
+#include <Protocol/Ip6Config.h>
#include <Protocol/ServiceBinding.h>
#include <Protocol/Tcp4.h>
#include <Protocol/Tcp6.h>
diff --git a/StdLib/ReadMe.txt b/StdLib/ReadMe.txt
index 003969196..35e3b6a87 100644
--- a/StdLib/ReadMe.txt
+++ b/StdLib/ReadMe.txt
@@ -1,9 +1,8 @@
- EADK
+ EADK
EDK II Standard Libraries and Applications
ReadMe
- Beta-1 Release
- 27 Jan. 2012
- DRAFT
+ Version 1.02
+ 21 Dec. 2012
OVERVIEW
@@ -17,8 +16,9 @@ At this time, applications developed with the EADK are intended to reside
on, and be loaded from, storage separate from the core firmware. This is
primarily due to size and environmental requirements.
-Some components of the EADK can be built as drivers. These will be identified
-explicitly in their documentation.
+This release of the EADK should only be used to produce UEFI Applications. Due to the execution
+environment built by the StdLib component, execution as a UEFI driver can cause system stability
+issues.
This document describes the EDK II specific aspects of installing, building,
and using the Standard C Library component of the EDK II Application
@@ -28,7 +28,7 @@ The EADK is comprised of three packages:
AppPkg, StdLib, and StdLibPrivateInternalFiles.
AppPkg This package contains applications which demonstrate use of the
- Standard C Library.
+ Standard C and Sockets Libraries.
These applications reside in AppPkg/Applications.
Enquire This is a program that determines many properties of the
@@ -43,7 +43,7 @@ The EADK is comprised of three packages:
Main This application is functionally identical to Hello, except that
it uses the Standard C Library to provide a main() entry point.
- Python A port of the Python-2.7.2 interpreter for UEFI. This
+ Python A port of the Python-2.7.2 interpreter for UEFI. Building this
application is disabled by default.
See the PythonReadMe.txt file, in the Python directory,
for information on configuring and building Python.
@@ -51,28 +51,19 @@ The EADK is comprised of three packages:
Sockets A collection of applications demonstrating use of the
EDK II Socket Libraries. These applications include:
- * DataSink
- * DataSource
- * GetAddrInfo
- * GetHostByAddr
- * GetHostByDns
- * GetHostByName
- * GetNetByAddr
- * GetNetByName
- * GetServByName
- * GetServByPort
- * OobRx
- * OobTx
- * RawIp4Rx
- * RawIp4Tx
- * RecvDgram
- * SetHostName
- * SetSockOpt
- * TftpServer
+ * DataSink * DataSource
+ * GetAddrInfo * GetHostByAddr
+ * GetHostByDns * GetHostByName
+ * GetNetByAddr * GetNetByName
+ * GetServByName * GetServByPort
+ * OobRx * OobTx
+ * RawIp4Rx * RawIp4Tx
+ * RecvDgram * SetHostName
+ * SetSockOpt * TftpServer
* WebServer
StdLib The StdLib package contains the standard header files as well as
- implementations of standards based libraries.
+ implementations of other standards-based libraries.
* BsdSocketLib
Support routines above the sockets layer and C interface for
@@ -109,44 +100,31 @@ RELEASE NOTES
=============
Fixes and Additions
-------------------
-Beginning with this release, applications built with the StdLib package
+Beginning with release 1.01, applications built with the StdLib package
no longer have a dependency on the TimerLib.
Known Issues
-----------------
This release of the EADK has some restrictions, as described below.
- 1. Only the Microsoft VS2005 and VS2008, Intel C Compiler 10.1 (or later),
- GCC 4.3 (mingw32), GCC 4.4, and GCC 4.5 C compilers are supported for
- Ia32 or X64 CPU architectures. Others may work but have not been tested.
-
- 2. The target machine must be running firmware which provides the
+ 1. The target machine must be running firmware which provides the
UEFI 2.3 HII protocol.
- 3. The EADK has not been through Intel's Quality Assurance process. This
- means that specified standards compliance has not been validated, nor
- has it undergone formal functionality testing.
-
- 4. Applications must be launched from within the EFI Shell.
+ 2. Applications must be launched from within the EFI Shell.
- 6. Absolute file paths may optionally be prefixed by a volume specifier
+ 3. Absolute file paths may optionally be prefixed by a volume specifier
such as "FS0:". The volume specifier is separated from the remainder
of the path by a single colon ':'. The volume specifier must be one of
the Shell's mapped volume names as shown by the "map" command.
- 7. Absolute file paths that don't begin with a volume specifier;
+ 4. Absolute file paths that don't begin with a volume specifier;
e.g. paths that begin with "/", are relative to the currently selected
volume. When the EFI Shell first starts, there is NO selected volume.
- 8. The tmpfile(), and related, functions require that the current volume
+ 5. The tmpfile(), and related, functions require that the current volume
have a temporary directory as specified in <paths.h>. This directory
is specified by macro _PATH_TMP as /Efi/StdLib/tmp.
- 9. Input line editing is not supported. Backspacing, deleting, or
- otherwise attempting to modify interactive input will result in a
- syntax error since the editing characters are interpreted the
- same as any other character.
-
The Standard C Library provided by this package is a "hosted" implementation
conforming to the ISO/IEC 9899-1990 C Language Standard with Addendum 1. This
is commonly referred to as the "C 95" specification or ISO/IEC 9899:199409.
@@ -164,21 +142,19 @@ installed by extracting, downloading or copying them to the root of your EDK II
source tree. The three package directories should be peers to the Conf,
MdePkg, Nt32Pkg, etc. directories.
-The Python 2.7.2 distribution must be downloaded from python.org before the
-Python application can be built. Extracting Python-2.7.2.tgz into the
-AppPkg\Applications\Python directory will produce a Python-2.7.2 directory
-containing the Python distribution. Python files that had to be modified for
-EDK II are in the AppPkg\Applications\Python\PyMod-2.7.2 directory. These
-files need to be copied into the corresponding directories within Python-2.7.2.
-
-The Python 2.7.1 port was superseded before it was completed. The PyMod-2.7.1
-directory tree will be deleted in the near future. Use the Python 2.7.2 port,
-as described above.
-
There are some boiler-plate declarations and definitions that need to be
included in your application's INF and DSC build files. These are described
in the CONFIGURATION section, below.
+A subset of the Python 2.7.2 distribution is included as part of AppPkg. If desired,
+the full Python 2.7.2 distribution may be downloaded from python.org and used instead.
+Delete or rename the existing Python-2.7.2 directory then extract the downloaded
+Python-2.7.2.tgz file into the AppPkg\Applications\Python directory. This will produce a
+Python-2.7.2 directory containing the full Python distribution. Python files that had to be
+modified for EDK II are in the AppPkg\Applications\Python\PyMod-2.7.2 directory. These
+files need to be copied into the corresponding directories within the extracted Python-2.7.2
+directory before Python can be built.
+
BUILDING
========
@@ -240,13 +216,13 @@ LibUefi sys/EfiSysCall.h Provides the UEFI system interface and
"System Calls"
LibWchar wchar.h Extended multibyte and wide character utilities
LibNetUtil Network address and number manipulation utilities
-DevConsole Automatically provided File I/O abstractions for
+DevConsole Automatically provided File I/O abstractions for
the UEFI Console device. No need to list this
library class in your INF file(s).
DevShell Add if desired File I/O abstractions using UEFI shell
facilities. Add this to the application's main
INF file if file-system access needed.
-DevUtility -- Do Not Use -- Utility functions used by the Device abstractions
+DevUtility -- Do Not Use -- Utility functions used internally by the Device abstractions
LibGdtoa -- Do Not Use -- This library is used internally and should not
need to be explicitly specified by an
application. It must be defined as one of the
@@ -256,6 +232,10 @@ LibGdtoa -- Do Not Use -- This library is used internally and should not
Table 1: Standard Libraries
============================
+The DevConsole and DevShell libraries provide device I/O functionality and are treated
+specially. DevConsole is automatically included so there is no need to reference it in your
+application's DSC or INF files. DevShell must be listed, in your application's INF file in the
+[LibraryClasses] section, if your application does file I/O.
These libraries must be fully described in the [LibraryClasses] section of the
application package's DSC file. Then, each individual application needs to
@@ -264,6 +244,11 @@ above table, in the [LibraryClasses] section of the application's INF file. The
AppPkg.dsc, StdLib.dsc, and Enquire.inf files provide good examples of this.
More details are in the CONFIGURATION section, below.
+In order to simplify this process, the [LibraryClasses] definitions, and others, are
+specified in the StdLib.inc file. If this file is included in the DSC file, usually at the
+end, then other DSC file changes or additions are unnecessary. This is further described in
+the CONFIGURATION section, below.
+
Within the source files of the application, use of the Standard headers and
library functions follow standard C programming practices as formalized by
ISO/IEC 9899:1990, with Addendum 1, (C 95) C language specification.
@@ -281,8 +266,44 @@ consolidated into a single file, StdLib/StdLib.inc, which can be included in
your .dsc file using the !include directive. The provided AppPkg.dsc and
StdLib.dsc files do this on their last line.
+The "boilerplate" text can be included using a !include directive in the
+package's .dsc file. The provided AppPkg.dsc and StdLib.dsc files include
+the following "boilerplate" text:
+
+ ##############################################################################
+ #
+ # Specify whether we are running in an emulation environment, or not.
+ # Define EMULATE if we are, else keep the DEFINE commented out.
+ #
+ # DEFINE EMULATE = 1
+
+ ##############################################################################
+ #
+ # Include Boilerplate text required for building with the Standard Libraries.
+ #
+ ##############################################################################
+ !include StdLib/StdLib.inc
+
+ Figure 1: "Boilerplate" Inclusion
+ =================================
+
+The EMULATE macro must be defined if one desires to do source-level debugging within one of
+the emulated environments such as NT32Pkg or UnixPkg.
+
+The final boilerplate line, in Figure 1, includes the StdLib.inc file.
Each section of StdLib/StdLib.inc is described below.
+If desired, all of the Socket applications, in AppPkg, can be built by including Sockets.inc:
+
+ !include AppPkg/Applications/Sockets/Sockets.inc
+
+ Figure 2: Socket Applications "Boilerplate" Inclusion
+ =====================================================
+
+
+Descriptions of the Library Classes comprising the Standard Libraries,
+as shown in Figure 3: Library Class Descriptions, are provided.
+
[LibraryClasses]
#
# C Standard Libraries
@@ -318,14 +339,11 @@ Each section of StdLib/StdLib.inc is described below.
[LibraryClasses.ARM.UEFI_APPLICATION]
NULL|ArmPkg/Library/CompilerIntrinsicsLib/CompilerIntrinsicsLib.inf
- Figure 1: Library Class Descriptions
+ Figure 3: Library Class Descriptions
====================================
-Descriptions of the Library Classes comprising the Standard Libraries,
-as shown above in Figure 1: Library Class Descriptions, are provided.
-
-The directives in Figure 2: Package Component Descriptions will create
+The directives in Figure 4: Package Component Descriptions will create
instances of the BaseLib and BaseMemoryLib library classes that are built
with Link-time-Code-Generation disabled. This is necessary when using the
Microsoft tool chains in order to allow the library's functions to be
@@ -354,50 +372,43 @@ A DXE driver version of the Socket library is also built.
##########
StdLib/SocketDxe/SocketDxe.inf
- Figure 2: Package Component Descriptions
+ Figure 4: Package Component Descriptions
========================================
Each compiler assumes, by default, that it will be used with standard libraries
and headers provided by the compiler vendor. Many of these assumptions are
incorrect for the UEFI environment. By including a BuildOptions section, as
-shown in Figure 3: Package Build Options, these assumptions can be
+shown in Figure 5: Package Build Options, these assumptions can be
tailored for compatibility with UEFI and the EDK II Standard Libraries.
+Note that the set of BuildOptions used is determined by the state of the EMULATE macro.
+
[BuildOptions]
+ !ifndef $(EMULATE)
+ # These Build Options are used when building the Standard Libraries to be run
+ # on real hardware.
INTEL:*_*_IA32_CC_FLAGS = /Qfreestanding
MSFT:*_*_IA32_CC_FLAGS = /X /Zc:wchar_t
GCC:*_*_IA32_CC_FLAGS = -nostdinc -nostdlib
- # The Build Options, below, are only used when building the C library
- # to be run under an emulation environment. They disable optimization
- # which facillitates debugging under the Emulation environment.
+ !else
+ # The Build Options, below, are only used when building the Standard Libraries
+ # to be run under an emulation environment.
+ # They disable optimization which facillitates debugging under the Emulation environment.
+ INTEL:*_*_IA32_CC_FLAGS = /Od
+ MSFT:*_*_IA32_CC_FLAGS = /Od
+ GCC:*_*_IA32_CC_FLAGS = -O0
- # INTEL:*_*_IA32_CC_FLAGS = /Od
- # MSFT:*_*_IA32_CC_FLAGS = /Od
- # GCC:*_*_IA32_CC_FLAGS = -O0
-
- Figure 4: Package Build Options
+ Figure 5: Package Build Options
===============================
-The "boilerplate" text can be included using a !include directive in the
-package's .dsc file. The provided AppPkg.dsc and StdLib.dsc files include
-the "boilerplate" text as follows:
-
- # Include Boilerplate text required for building with the Standard Libraries.
- #
- #############################################################################
- !include StdLib/StdLib.inc
-
- Figure 5: "Boilerplate" Inclusion
- =================================
-
INF Files
=========
The INF files for most modules will not require special directives in order to
-support the Standard Libraries. The two cases which could occur are described
-below.
+support the Standard Libraries. The two sections which require attention: LibraryClasses
+and BuildOptions, are described below.
[LibraryClasses]
UefiLib
@@ -410,9 +421,16 @@ below.
================================
-Modules of type UEFI_APPLICATION that perform file I/O should include library
+Modules of type UEFI_APPLICATION that perform file I/O must include library
class DevShell. Including this library class will allow file operations to be
-handled by the UEFI Shell. Without this class, only Console I/O is permitted.
+handled by the UEFI Shell. Without this class, only Console I/O is supported.
+
+
+An application's INF file might need to include a [BuildOptions] section
+specifying additional compiler and linker flags necessary to allow the
+application to be built. Usually, this section is not needed. When building
+code from external sources, though, it may be necessary to disable some
+warnings or enable/disable some compiler features.
[BuildOptions]
INTEL:*_*_*_CC_FLAGS = /Qdiag-disable:181,186
@@ -423,13 +441,6 @@ handled by the UEFI Shell. Without this class, only Console I/O is permitted.
==============================
-An application's INF file may need to include a [BuildOptions] section
-specifying additional compiler and linker flags necessary to allow the
-application to be built. Usually, this section is not needed. When building
-code from external sources, though, it may be necessary to disable some
-warnings or enable/disable some compiler features.
-
-
TARGET-SYSTEM INSTALLATION
==========================
Applications that use file system features or the Socket library depend upon
@@ -444,13 +455,13 @@ the application was loaded from. This tree structure is described below:
|- /tmp Temporary files created by tmpfile(), etc.
-The /Efi/StdLib/etc directory is populated from the StdLib/Efi/etc source
+The /Efi/StdLib/etc directory must be manually populated from the StdLib/Efi/etc source
directory.
IMPLEMENTATION-Specific Features
================================
It is very strongly recommended that applications not use the long or
-unsigned long types. The size of this type varies between compilers and is one
+unsigned long types. The size of these types varies between compilers and is one
of the less portable aspects of C. Instead, one should use the UEFI defined
types whenever possible. Use of these types, listed below for reference,
ensures that the declared objects have unambiguous, explicitly declared, sizes
diff --git a/StdLib/StdLib.dsc b/StdLib/StdLib.dsc
index f9f28b872..b0309e2bf 100644
--- a/StdLib/StdLib.dsc
+++ b/StdLib/StdLib.dsc
@@ -29,11 +29,18 @@
BUILD_TARGETS = DEBUG|RELEASE
SKUID_IDENTIFIER = DEFAULT
+#
+# Debug output control
+#
+ DEFINE DEBUG_ENABLE_OUTPUT = FALSE # Set to TRUE to enable debug output
+ DEFINE DEBUG_PRINT_ERROR_LEVEL = 0x80000000 # Flags to control amount of debug output
+ DEFINE DEBUG_PROPERTY_MASK = 0x0f
+
[PcdsFeatureFlag]
[PcdsFixedAtBuild]
- gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0x0f
- gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0x80000000
+ gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|$(DEBUG_PROPERTY_MASK)
+ gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|$(DEBUG_PRINT_ERROR_LEVEL)
[PcdsFixedAtBuild.IPF]
@@ -55,7 +62,12 @@
MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf
UefiBootServicesTableLib|MdePkg/Library/UefiBootServicesTableLib/UefiBootServicesTableLib.inf
UefiRuntimeServicesTableLib|MdePkg/Library/UefiRuntimeServicesTableLib/UefiRuntimeServicesTableLib.inf
- DebugLib|MdePkg/Library/BaseDebugLibNull/BaseDebugLibNull.inf
+ !if $(DEBUG_ENABLE_OUTPUT)
+ DebugLib|MdePkg/Library/UefiDebugLibConOut/UefiDebugLibConOut.inf
+ DebugPrintErrorLevelLib|MdePkg/Library/BaseDebugPrintErrorLevelLib/BaseDebugPrintErrorLevelLib.inf
+ !else ## DEBUG_ENABLE_OUTPUT
+ DebugLib|MdePkg/Library/BaseDebugLibNull/BaseDebugLibNull.inf
+ !endif ## DEBUG_ENABLE_OUTPUT
DevicePathLib|MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.inf
PeCoffGetEntryPointLib|MdePkg/Library/BasePeCoffGetEntryPointLib/BasePeCoffGetEntryPointLib.inf
IoLib|MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsic.inf
diff --git a/StdLibPrivateInternalFiles/ReadMe.txt b/StdLibPrivateInternalFiles/ReadMe.txt
index 003969196..35e3b6a87 100644
--- a/StdLibPrivateInternalFiles/ReadMe.txt
+++ b/StdLibPrivateInternalFiles/ReadMe.txt
@@ -1,9 +1,8 @@
- EADK
+ EADK
EDK II Standard Libraries and Applications
ReadMe
- Beta-1 Release
- 27 Jan. 2012
- DRAFT
+ Version 1.02
+ 21 Dec. 2012
OVERVIEW
@@ -17,8 +16,9 @@ At this time, applications developed with the EADK are intended to reside
on, and be loaded from, storage separate from the core firmware. This is
primarily due to size and environmental requirements.
-Some components of the EADK can be built as drivers. These will be identified
-explicitly in their documentation.
+This release of the EADK should only be used to produce UEFI Applications. Due to the execution
+environment built by the StdLib component, execution as a UEFI driver can cause system stability
+issues.
This document describes the EDK II specific aspects of installing, building,
and using the Standard C Library component of the EDK II Application
@@ -28,7 +28,7 @@ The EADK is comprised of three packages:
AppPkg, StdLib, and StdLibPrivateInternalFiles.
AppPkg This package contains applications which demonstrate use of the
- Standard C Library.
+ Standard C and Sockets Libraries.
These applications reside in AppPkg/Applications.
Enquire This is a program that determines many properties of the
@@ -43,7 +43,7 @@ The EADK is comprised of three packages:
Main This application is functionally identical to Hello, except that
it uses the Standard C Library to provide a main() entry point.
- Python A port of the Python-2.7.2 interpreter for UEFI. This
+ Python A port of the Python-2.7.2 interpreter for UEFI. Building this
application is disabled by default.
See the PythonReadMe.txt file, in the Python directory,
for information on configuring and building Python.
@@ -51,28 +51,19 @@ The EADK is comprised of three packages:
Sockets A collection of applications demonstrating use of the
EDK II Socket Libraries. These applications include:
- * DataSink
- * DataSource
- * GetAddrInfo
- * GetHostByAddr
- * GetHostByDns
- * GetHostByName
- * GetNetByAddr
- * GetNetByName
- * GetServByName
- * GetServByPort
- * OobRx
- * OobTx
- * RawIp4Rx
- * RawIp4Tx
- * RecvDgram
- * SetHostName
- * SetSockOpt
- * TftpServer
+ * DataSink * DataSource
+ * GetAddrInfo * GetHostByAddr
+ * GetHostByDns * GetHostByName
+ * GetNetByAddr * GetNetByName
+ * GetServByName * GetServByPort
+ * OobRx * OobTx
+ * RawIp4Rx * RawIp4Tx
+ * RecvDgram * SetHostName
+ * SetSockOpt * TftpServer
* WebServer
StdLib The StdLib package contains the standard header files as well as
- implementations of standards based libraries.
+ implementations of other standards-based libraries.
* BsdSocketLib
Support routines above the sockets layer and C interface for
@@ -109,44 +100,31 @@ RELEASE NOTES
=============
Fixes and Additions
-------------------
-Beginning with this release, applications built with the StdLib package
+Beginning with release 1.01, applications built with the StdLib package
no longer have a dependency on the TimerLib.
Known Issues
-----------------
This release of the EADK has some restrictions, as described below.
- 1. Only the Microsoft VS2005 and VS2008, Intel C Compiler 10.1 (or later),
- GCC 4.3 (mingw32), GCC 4.4, and GCC 4.5 C compilers are supported for
- Ia32 or X64 CPU architectures. Others may work but have not been tested.
-
- 2. The target machine must be running firmware which provides the
+ 1. The target machine must be running firmware which provides the
UEFI 2.3 HII protocol.
- 3. The EADK has not been through Intel's Quality Assurance process. This
- means that specified standards compliance has not been validated, nor
- has it undergone formal functionality testing.
-
- 4. Applications must be launched from within the EFI Shell.
+ 2. Applications must be launched from within the EFI Shell.
- 6. Absolute file paths may optionally be prefixed by a volume specifier
+ 3. Absolute file paths may optionally be prefixed by a volume specifier
such as "FS0:". The volume specifier is separated from the remainder
of the path by a single colon ':'. The volume specifier must be one of
the Shell's mapped volume names as shown by the "map" command.
- 7. Absolute file paths that don't begin with a volume specifier;
+ 4. Absolute file paths that don't begin with a volume specifier;
e.g. paths that begin with "/", are relative to the currently selected
volume. When the EFI Shell first starts, there is NO selected volume.
- 8. The tmpfile(), and related, functions require that the current volume
+ 5. The tmpfile(), and related, functions require that the current volume
have a temporary directory as specified in <paths.h>. This directory
is specified by macro _PATH_TMP as /Efi/StdLib/tmp.
- 9. Input line editing is not supported. Backspacing, deleting, or
- otherwise attempting to modify interactive input will result in a
- syntax error since the editing characters are interpreted the
- same as any other character.
-
The Standard C Library provided by this package is a "hosted" implementation
conforming to the ISO/IEC 9899-1990 C Language Standard with Addendum 1. This
is commonly referred to as the "C 95" specification or ISO/IEC 9899:199409.
@@ -164,21 +142,19 @@ installed by extracting, downloading or copying them to the root of your EDK II
source tree. The three package directories should be peers to the Conf,
MdePkg, Nt32Pkg, etc. directories.
-The Python 2.7.2 distribution must be downloaded from python.org before the
-Python application can be built. Extracting Python-2.7.2.tgz into the
-AppPkg\Applications\Python directory will produce a Python-2.7.2 directory
-containing the Python distribution. Python files that had to be modified for
-EDK II are in the AppPkg\Applications\Python\PyMod-2.7.2 directory. These
-files need to be copied into the corresponding directories within Python-2.7.2.
-
-The Python 2.7.1 port was superseded before it was completed. The PyMod-2.7.1
-directory tree will be deleted in the near future. Use the Python 2.7.2 port,
-as described above.
-
There are some boiler-plate declarations and definitions that need to be
included in your application's INF and DSC build files. These are described
in the CONFIGURATION section, below.
+A subset of the Python 2.7.2 distribution is included as part of AppPkg. If desired,
+the full Python 2.7.2 distribution may be downloaded from python.org and used instead.
+Delete or rename the existing Python-2.7.2 directory then extract the downloaded
+Python-2.7.2.tgz file into the AppPkg\Applications\Python directory. This will produce a
+Python-2.7.2 directory containing the full Python distribution. Python files that had to be
+modified for EDK II are in the AppPkg\Applications\Python\PyMod-2.7.2 directory. These
+files need to be copied into the corresponding directories within the extracted Python-2.7.2
+directory before Python can be built.
+
BUILDING
========
@@ -240,13 +216,13 @@ LibUefi sys/EfiSysCall.h Provides the UEFI system interface and
"System Calls"
LibWchar wchar.h Extended multibyte and wide character utilities
LibNetUtil Network address and number manipulation utilities
-DevConsole Automatically provided File I/O abstractions for
+DevConsole Automatically provided File I/O abstractions for
the UEFI Console device. No need to list this
library class in your INF file(s).
DevShell Add if desired File I/O abstractions using UEFI shell
facilities. Add this to the application's main
INF file if file-system access needed.
-DevUtility -- Do Not Use -- Utility functions used by the Device abstractions
+DevUtility -- Do Not Use -- Utility functions used internally by the Device abstractions
LibGdtoa -- Do Not Use -- This library is used internally and should not
need to be explicitly specified by an
application. It must be defined as one of the
@@ -256,6 +232,10 @@ LibGdtoa -- Do Not Use -- This library is used internally and should not
Table 1: Standard Libraries
============================
+The DevConsole and DevShell libraries provide device I/O functionality and are treated
+specially. DevConsole is automatically included so there is no need to reference it in your
+application's DSC or INF files. DevShell must be listed, in your application's INF file in the
+[LibraryClasses] section, if your application does file I/O.
These libraries must be fully described in the [LibraryClasses] section of the
application package's DSC file. Then, each individual application needs to
@@ -264,6 +244,11 @@ above table, in the [LibraryClasses] section of the application's INF file. The
AppPkg.dsc, StdLib.dsc, and Enquire.inf files provide good examples of this.
More details are in the CONFIGURATION section, below.
+In order to simplify this process, the [LibraryClasses] definitions, and others, are
+specified in the StdLib.inc file. If this file is included in the DSC file, usually at the
+end, then other DSC file changes or additions are unnecessary. This is further described in
+the CONFIGURATION section, below.
+
Within the source files of the application, use of the Standard headers and
library functions follow standard C programming practices as formalized by
ISO/IEC 9899:1990, with Addendum 1, (C 95) C language specification.
@@ -281,8 +266,44 @@ consolidated into a single file, StdLib/StdLib.inc, which can be included in
your .dsc file using the !include directive. The provided AppPkg.dsc and
StdLib.dsc files do this on their last line.
+The "boilerplate" text can be included using a !include directive in the
+package's .dsc file. The provided AppPkg.dsc and StdLib.dsc files include
+the following "boilerplate" text:
+
+ ##############################################################################
+ #
+ # Specify whether we are running in an emulation environment, or not.
+ # Define EMULATE if we are, else keep the DEFINE commented out.
+ #
+ # DEFINE EMULATE = 1
+
+ ##############################################################################
+ #
+ # Include Boilerplate text required for building with the Standard Libraries.
+ #
+ ##############################################################################
+ !include StdLib/StdLib.inc
+
+ Figure 1: "Boilerplate" Inclusion
+ =================================
+
+The EMULATE macro must be defined if one desires to do source-level debugging within one of
+the emulated environments such as NT32Pkg or UnixPkg.
+
+The final boilerplate line, in Figure 1, includes the StdLib.inc file.
Each section of StdLib/StdLib.inc is described below.
+If desired, all of the Socket applications, in AppPkg, can be built by including Sockets.inc:
+
+ !include AppPkg/Applications/Sockets/Sockets.inc
+
+ Figure 2: Socket Applications "Boilerplate" Inclusion
+ =====================================================
+
+
+Descriptions of the Library Classes comprising the Standard Libraries,
+as shown in Figure 3: Library Class Descriptions, are provided.
+
[LibraryClasses]
#
# C Standard Libraries
@@ -318,14 +339,11 @@ Each section of StdLib/StdLib.inc is described below.
[LibraryClasses.ARM.UEFI_APPLICATION]
NULL|ArmPkg/Library/CompilerIntrinsicsLib/CompilerIntrinsicsLib.inf
- Figure 1: Library Class Descriptions
+ Figure 3: Library Class Descriptions
====================================
-Descriptions of the Library Classes comprising the Standard Libraries,
-as shown above in Figure 1: Library Class Descriptions, are provided.
-
-The directives in Figure 2: Package Component Descriptions will create
+The directives in Figure 4: Package Component Descriptions will create
instances of the BaseLib and BaseMemoryLib library classes that are built
with Link-time-Code-Generation disabled. This is necessary when using the
Microsoft tool chains in order to allow the library's functions to be
@@ -354,50 +372,43 @@ A DXE driver version of the Socket library is also built.
##########
StdLib/SocketDxe/SocketDxe.inf
- Figure 2: Package Component Descriptions
+ Figure 4: Package Component Descriptions
========================================
Each compiler assumes, by default, that it will be used with standard libraries
and headers provided by the compiler vendor. Many of these assumptions are
incorrect for the UEFI environment. By including a BuildOptions section, as
-shown in Figure 3: Package Build Options, these assumptions can be
+shown in Figure 5: Package Build Options, these assumptions can be
tailored for compatibility with UEFI and the EDK II Standard Libraries.
+Note that the set of BuildOptions used is determined by the state of the EMULATE macro.
+
[BuildOptions]
+ !ifndef $(EMULATE)
+ # These Build Options are used when building the Standard Libraries to be run
+ # on real hardware.
INTEL:*_*_IA32_CC_FLAGS = /Qfreestanding
MSFT:*_*_IA32_CC_FLAGS = /X /Zc:wchar_t
GCC:*_*_IA32_CC_FLAGS = -nostdinc -nostdlib
- # The Build Options, below, are only used when building the C library
- # to be run under an emulation environment. They disable optimization
- # which facillitates debugging under the Emulation environment.
+ !else
+ # The Build Options, below, are only used when building the Standard Libraries
+ # to be run under an emulation environment.
+ # They disable optimization which facillitates debugging under the Emulation environment.
+ INTEL:*_*_IA32_CC_FLAGS = /Od
+ MSFT:*_*_IA32_CC_FLAGS = /Od
+ GCC:*_*_IA32_CC_FLAGS = -O0
- # INTEL:*_*_IA32_CC_FLAGS = /Od
- # MSFT:*_*_IA32_CC_FLAGS = /Od
- # GCC:*_*_IA32_CC_FLAGS = -O0
-
- Figure 4: Package Build Options
+ Figure 5: Package Build Options
===============================
-The "boilerplate" text can be included using a !include directive in the
-package's .dsc file. The provided AppPkg.dsc and StdLib.dsc files include
-the "boilerplate" text as follows:
-
- # Include Boilerplate text required for building with the Standard Libraries.
- #
- #############################################################################
- !include StdLib/StdLib.inc
-
- Figure 5: "Boilerplate" Inclusion
- =================================
-
INF Files
=========
The INF files for most modules will not require special directives in order to
-support the Standard Libraries. The two cases which could occur are described
-below.
+support the Standard Libraries. The two sections which require attention: LibraryClasses
+and BuildOptions, are described below.
[LibraryClasses]
UefiLib
@@ -410,9 +421,16 @@ below.
================================
-Modules of type UEFI_APPLICATION that perform file I/O should include library
+Modules of type UEFI_APPLICATION that perform file I/O must include library
class DevShell. Including this library class will allow file operations to be
-handled by the UEFI Shell. Without this class, only Console I/O is permitted.
+handled by the UEFI Shell. Without this class, only Console I/O is supported.
+
+
+An application's INF file might need to include a [BuildOptions] section
+specifying additional compiler and linker flags necessary to allow the
+application to be built. Usually, this section is not needed. When building
+code from external sources, though, it may be necessary to disable some
+warnings or enable/disable some compiler features.
[BuildOptions]
INTEL:*_*_*_CC_FLAGS = /Qdiag-disable:181,186
@@ -423,13 +441,6 @@ handled by the UEFI Shell. Without this class, only Console I/O is permitted.
==============================
-An application's INF file may need to include a [BuildOptions] section
-specifying additional compiler and linker flags necessary to allow the
-application to be built. Usually, this section is not needed. When building
-code from external sources, though, it may be necessary to disable some
-warnings or enable/disable some compiler features.
-
-
TARGET-SYSTEM INSTALLATION
==========================
Applications that use file system features or the Socket library depend upon
@@ -444,13 +455,13 @@ the application was loaded from. This tree structure is described below:
|- /tmp Temporary files created by tmpfile(), etc.
-The /Efi/StdLib/etc directory is populated from the StdLib/Efi/etc source
+The /Efi/StdLib/etc directory must be manually populated from the StdLib/Efi/etc source
directory.
IMPLEMENTATION-Specific Features
================================
It is very strongly recommended that applications not use the long or
-unsigned long types. The size of this type varies between compilers and is one
+unsigned long types. The size of these types varies between compilers and is one
of the less portable aspects of C. Instead, one should use the UEFI defined
types whenever possible. Use of these types, listed below for reference,
ensures that the declared objects have unambiguous, explicitly declared, sizes
diff --git a/UefiCpuPkg/CpuDxe/CpuDxe.c b/UefiCpuPkg/CpuDxe/CpuDxe.c
index 2dfde0677..f165e17c5 100644
--- a/UefiCpuPkg/CpuDxe/CpuDxe.c
+++ b/UefiCpuPkg/CpuDxe/CpuDxe.c
@@ -1,7 +1,7 @@
/** @file
CPU DXE Module.
- Copyright (c) 2008 - 2012, Intel Corporation. All rights reserved.<BR>
+ Copyright (c) 2008 - 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
@@ -17,16 +17,11 @@
//
// Global Variables
//
-IA32_IDT_GATE_DESCRIPTOR gIdtTable[INTERRUPT_VECTOR_NUMBER] = { { { 0 } } };
-
-EFI_CPU_INTERRUPT_HANDLER ExternalVectorTable[0x100];
BOOLEAN InterruptState = FALSE;
EFI_HANDLE mCpuHandle = NULL;
BOOLEAN mIsFlushingGCD;
UINT64 mValidMtrrAddressMask = MTRR_LIB_CACHE_VALID_ADDRESS;
UINT64 mValidMtrrBitsMask = MTRR_LIB_MSR_VALID_MASK;
-IA32_IDT_GATE_DESCRIPTOR *mOrigIdtEntry = NULL;
-UINT16 mOrigIdtEntryCount = 0;
FIXED_MTRR mFixedMtrrTable[] = {
{
@@ -101,258 +96,9 @@ EFI_CPU_ARCH_PROTOCOL gCpu = {
};
//
-// Error code flag indicating whether or not an error code will be
-// pushed on the stack if an exception occurs.
-//
-// 1 means an error code will be pushed, otherwise 0
-//
-// bit 0 - exception 0
-// bit 1 - exception 1
-// etc.
-//
-UINT32 mErrorCodeFlag = 0x00027d00;
-
-//
-// Local function prototypes
-//
-
-/**
- Set Interrupt Descriptor Table Handler Address.
-
- @param Index The Index of the interrupt descriptor table handle.
- @param Handler Handler address.
-
-**/
-VOID
-SetInterruptDescriptorTableHandlerAddress (
- IN UINTN Index,
- IN VOID *Handler OPTIONAL
- );
-
-//
// CPU Arch Protocol Functions
//
-
-/**
- Common exception handler.
-
- @param InterruptType Exception type
- @param SystemContext EFI_SYSTEM_CONTEXT
-
-**/
-VOID
-EFIAPI
-CommonExceptionHandler (
- IN EFI_EXCEPTION_TYPE InterruptType,
- IN EFI_SYSTEM_CONTEXT SystemContext
- )
-{
-#if defined (MDE_CPU_IA32)
- DEBUG ((
- EFI_D_ERROR,
- "!!!! IA32 Exception Type - %08x !!!!\n",
- InterruptType
- ));
- if ((mErrorCodeFlag & (1 << InterruptType)) != 0) {
- DEBUG ((
- EFI_D_ERROR,
- "ExceptionData - %08x\n",
- SystemContext.SystemContextIa32->ExceptionData
- ));
- }
- DEBUG ((
- EFI_D_ERROR,
- "CS - %04x, EIP - %08x, EFL - %08x, SS - %04x\n",
- SystemContext.SystemContextIa32->Cs,
- SystemContext.SystemContextIa32->Eip,
- SystemContext.SystemContextIa32->Eflags,
- SystemContext.SystemContextIa32->Ss
- ));
- DEBUG ((
- EFI_D_ERROR,
- "DS - %04x, ES - %04x, FS - %04x, GS - %04x\n",
- SystemContext.SystemContextIa32->Ds,
- SystemContext.SystemContextIa32->Es,
- SystemContext.SystemContextIa32->Fs,
- SystemContext.SystemContextIa32->Gs
- ));
- DEBUG ((
- EFI_D_ERROR,
- "EAX - %08x, EBX - %08x, ECX - %08x, EDX - %08x\n",
- SystemContext.SystemContextIa32->Eax,
- SystemContext.SystemContextIa32->Ebx,
- SystemContext.SystemContextIa32->Ecx,
- SystemContext.SystemContextIa32->Edx
- ));
- DEBUG ((
- EFI_D_ERROR,
- "ESP - %08x, EBP - %08x, ESI - %08x, EDI - %08x\n",
- SystemContext.SystemContextIa32->Esp,
- SystemContext.SystemContextIa32->Ebp,
- SystemContext.SystemContextIa32->Esi,
- SystemContext.SystemContextIa32->Edi
- ));
- DEBUG ((
- EFI_D_ERROR,
- "GDT - %08x LIM - %04x, IDT - %08x LIM - %04x\n",
- SystemContext.SystemContextIa32->Gdtr[0],
- SystemContext.SystemContextIa32->Gdtr[1],
- SystemContext.SystemContextIa32->Idtr[0],
- SystemContext.SystemContextIa32->Idtr[1]
- ));
- DEBUG ((
- EFI_D_ERROR,
- "LDT - %08x, TR - %08x\n",
- SystemContext.SystemContextIa32->Ldtr,
- SystemContext.SystemContextIa32->Tr
- ));
- DEBUG ((
- EFI_D_ERROR,
- "CR0 - %08x, CR2 - %08x, CR3 - %08x, CR4 - %08x\n",
- SystemContext.SystemContextIa32->Cr0,
- SystemContext.SystemContextIa32->Cr2,
- SystemContext.SystemContextIa32->Cr3,
- SystemContext.SystemContextIa32->Cr4
- ));
- DEBUG ((
- EFI_D_ERROR,
- "DR0 - %08x, DR1 - %08x, DR2 - %08x, DR3 - %08x\n",
- SystemContext.SystemContextIa32->Dr0,
- SystemContext.SystemContextIa32->Dr1,
- SystemContext.SystemContextIa32->Dr2,
- SystemContext.SystemContextIa32->Dr3
- ));
- DEBUG ((
- EFI_D_ERROR,
- "DR6 - %08x, DR7 - %08x\n",
- SystemContext.SystemContextIa32->Dr6,
- SystemContext.SystemContextIa32->Dr7
- ));
-#elif defined (MDE_CPU_X64)
- DEBUG ((
- EFI_D_ERROR,
- "!!!! X64 Exception Type - %016lx !!!!\n",
- (UINT64)InterruptType
- ));
- if ((mErrorCodeFlag & (1 << InterruptType)) != 0) {
- DEBUG ((
- EFI_D_ERROR,
- "ExceptionData - %016lx\n",
- SystemContext.SystemContextX64->ExceptionData
- ));
- }
- DEBUG ((
- EFI_D_ERROR,
- "RIP - %016lx, RFL - %016lx\n",
- SystemContext.SystemContextX64->Rip,
- SystemContext.SystemContextX64->Rflags
- ));
- DEBUG ((
- EFI_D_ERROR,
- "RAX - %016lx, RCX - %016lx, RDX - %016lx\n",
- SystemContext.SystemContextX64->Rax,
- SystemContext.SystemContextX64->Rcx,
- SystemContext.SystemContextX64->Rdx
- ));
- DEBUG ((
- EFI_D_ERROR,
- "RBX - %016lx, RSP - %016lx, RBP - %016lx\n",
- SystemContext.SystemContextX64->Rbx,
- SystemContext.SystemContextX64->Rsp,
- SystemContext.SystemContextX64->Rbp
- ));
- DEBUG ((
- EFI_D_ERROR,
- "RSI - %016lx, RDI - %016lx\n",
- SystemContext.SystemContextX64->Rsi,
- SystemContext.SystemContextX64->Rdi
- ));
- DEBUG ((
- EFI_D_ERROR,
- "R8 - %016lx, R9 - %016lx, R10 - %016lx\n",
- SystemContext.SystemContextX64->R8,
- SystemContext.SystemContextX64->R9,
- SystemContext.SystemContextX64->R10
- ));
- DEBUG ((
- EFI_D_ERROR,
- "R11 - %016lx, R12 - %016lx, R13 - %016lx\n",
- SystemContext.SystemContextX64->R11,
- SystemContext.SystemContextX64->R12,
- SystemContext.SystemContextX64->R13
- ));
- DEBUG ((
- EFI_D_ERROR,
- "R14 - %016lx, R15 - %016lx\n",
- SystemContext.SystemContextX64->R14,
- SystemContext.SystemContextX64->R15
- ));
- DEBUG ((
- EFI_D_ERROR,
- "CS - %04lx, DS - %04lx, ES - %04lx, FS - %04lx, GS - %04lx, SS - %04lx\n",
- SystemContext.SystemContextX64->Cs,
- SystemContext.SystemContextX64->Ds,
- SystemContext.SystemContextX64->Es,
- SystemContext.SystemContextX64->Fs,
- SystemContext.SystemContextX64->Gs,
- SystemContext.SystemContextX64->Ss
- ));
- DEBUG ((
- EFI_D_ERROR,
- "GDT - %016lx; %04lx, IDT - %016lx; %04lx\n",
- SystemContext.SystemContextX64->Gdtr[0],
- SystemContext.SystemContextX64->Gdtr[1],
- SystemContext.SystemContextX64->Idtr[0],
- SystemContext.SystemContextX64->Idtr[1]
- ));
- DEBUG ((
- EFI_D_ERROR,
- "LDT - %016lx, TR - %016lx\n",
- SystemContext.SystemContextX64->Ldtr,
- SystemContext.SystemContextX64->Tr
- ));
- DEBUG ((
- EFI_D_ERROR,
- "CR0 - %016lx, CR2 - %016lx, CR3 - %016lx\n",
- SystemContext.SystemContextX64->Cr0,
- SystemContext.SystemContextX64->Cr2,
- SystemContext.SystemContextX64->Cr3
- ));
- DEBUG ((
- EFI_D_ERROR,
- "CR4 - %016lx, CR8 - %016lx\n",
- SystemContext.SystemContextX64->Cr4,
- SystemContext.SystemContextX64->Cr8
- ));
- DEBUG ((
- EFI_D_ERROR,
- "DR0 - %016lx, DR1 - %016lx, DR2 - %016lx\n",
- SystemContext.SystemContextX64->Dr0,
- SystemContext.SystemContextX64->Dr1,
- SystemContext.SystemContextX64->Dr2
- ));
- DEBUG ((
- EFI_D_ERROR,
- "DR3 - %016lx, DR6 - %016lx, DR7 - %016lx\n",
- SystemContext.SystemContextX64->Dr3,
- SystemContext.SystemContextX64->Dr6,
- SystemContext.SystemContextX64->Dr7
- ));
-#else
-#error CPU type not supported for exception information dump!
-#endif
-
- //
- // Hang the system with CpuSleep so the processor will enter a lower power
- // state.
- //
- while (TRUE) {
- CpuSleep ();
- };
-}
-
-
/**
Flush CPU data cache. If the instruction cache is fully coherent
with all DMA operations then function can just return EFI_SUCCESS.
@@ -510,29 +256,7 @@ CpuRegisterInterruptHandler (
IN EFI_CPU_INTERRUPT_HANDLER InterruptHandler
)
{
- if (InterruptType < 0 || InterruptType > 0xff) {
- return EFI_UNSUPPORTED;
- }
-
- if (InterruptHandler == NULL && ExternalVectorTable[InterruptType] == NULL) {
- return EFI_INVALID_PARAMETER;
- }
-
- if (InterruptHandler != NULL && ExternalVectorTable[InterruptType] != NULL) {
- return EFI_ALREADY_STARTED;
- }
-
- if (InterruptHandler != NULL) {
- SetInterruptDescriptorTableHandlerAddress ((UINTN)InterruptType, NULL);
- } else {
- //
- // Restore the original IDT handler address if InterruptHandler is NULL.
- //
- RestoreInterruptDescriptorTableHandlerAddress ((UINTN)InterruptType);
- }
-
- ExternalVectorTable[InterruptType] = InterruptHandler;
- return EFI_SUCCESS;
+ return RegisterCpuInterruptHandler (InterruptType, InterruptHandler);
}
@@ -1061,57 +785,6 @@ RefreshGcdMemoryAttributes (
}
/**
- Set Interrupt Descriptor Table Handler Address.
-
- @param Index The Index of the interrupt descriptor table handle.
- @param Handler Handler address.
-
-**/
-VOID
-SetInterruptDescriptorTableHandlerAddress (
- IN UINTN Index,
- IN VOID *Handler OPTIONAL
- )
-{
- UINTN UintnHandler;
-
- if (Handler != NULL) {
- UintnHandler = (UINTN) Handler;
- } else {
- UintnHandler = ((UINTN) AsmIdtVector00) + (8 * Index);
- }
-
- gIdtTable[Index].Bits.OffsetLow = (UINT16)UintnHandler;
- gIdtTable[Index].Bits.Reserved_0 = 0;
- gIdtTable[Index].Bits.GateType = IA32_IDT_GATE_TYPE_INTERRUPT_32;
- gIdtTable[Index].Bits.OffsetHigh = (UINT16)(UintnHandler >> 16);
-#if defined (MDE_CPU_X64)
- gIdtTable[Index].Bits.OffsetUpper = (UINT32)(UintnHandler >> 32);
- gIdtTable[Index].Bits.Reserved_1 = 0;
-#endif
-}
-
-/**
- Restore original Interrupt Descriptor Table Handler Address.
-
- @param Index The Index of the interrupt descriptor table handle.
-
-**/
-VOID
-RestoreInterruptDescriptorTableHandlerAddress (
- IN UINTN Index
- )
-{
- if (Index < mOrigIdtEntryCount) {
- gIdtTable[Index].Bits.OffsetLow = mOrigIdtEntry[Index].Bits.OffsetLow;
- gIdtTable[Index].Bits.OffsetHigh = mOrigIdtEntry[Index].Bits.OffsetHigh;
-#if defined (MDE_CPU_X64)
- gIdtTable[Index].Bits.OffsetUpper = mOrigIdtEntry[Index].Bits.OffsetUpper;
-#endif
- }
-}
-
-/**
Initialize Interrupt Descriptor Table for interrupt handling.
**/
@@ -1120,90 +793,17 @@ InitInterruptDescriptorTable (
VOID
)
{
- EFI_STATUS Status;
- IA32_DESCRIPTOR OldIdtPtr;
- IA32_IDT_GATE_DESCRIPTOR *OldIdt;
- UINTN OldIdtSize;
- VOID *IdtPtrAlignmentBuffer;
- IA32_DESCRIPTOR *IdtPtr;
- UINTN Index;
- UINT16 CurrentCs;
- VOID *IntHandler;
-
- SetMem (ExternalVectorTable, sizeof(ExternalVectorTable), 0);
-
- //
- // Get original IDT address and size.
- //
- AsmReadIdtr ((IA32_DESCRIPTOR *) &OldIdtPtr);
-
- if ((OldIdtPtr.Base != 0) && ((OldIdtPtr.Limit & 7) == 7)) {
- OldIdt = (IA32_IDT_GATE_DESCRIPTOR*) OldIdtPtr.Base;
- OldIdtSize = (OldIdtPtr.Limit + 1) / sizeof (IA32_IDT_GATE_DESCRIPTOR);
- //
- // Save original IDT entry and IDT entry count.
- //
- mOrigIdtEntry = AllocateCopyPool (OldIdtPtr.Limit + 1, (VOID *) OldIdtPtr.Base);
- ASSERT (mOrigIdtEntry != NULL);
- mOrigIdtEntryCount = (UINT16) OldIdtSize;
- } else {
- OldIdt = NULL;
- OldIdtSize = 0;
- }
-
- //
- // Intialize IDT
- //
- CurrentCs = AsmReadCs();
- for (Index = 0; Index < INTERRUPT_VECTOR_NUMBER; Index ++) {
- //
- // If the old IDT had a handler for this interrupt, then
- // preserve it.
- //
- if (Index < OldIdtSize) {
- IntHandler =
- (VOID*) (
- OldIdt[Index].Bits.OffsetLow +
- (((UINTN) OldIdt[Index].Bits.OffsetHigh) << 16)
-#if defined (MDE_CPU_X64)
- + (((UINTN) OldIdt[Index].Bits.OffsetUpper) << 32)
-#endif
- );
- } else {
- IntHandler = NULL;
- }
-
- gIdtTable[Index].Bits.Selector = CurrentCs;
- gIdtTable[Index].Bits.Reserved_0 = 0;
- gIdtTable[Index].Bits.GateType = IA32_IDT_GATE_TYPE_INTERRUPT_32;
- SetInterruptDescriptorTableHandlerAddress (Index, IntHandler);
- }
-
- //
- // Load IDT Pointer
- //
- IdtPtrAlignmentBuffer = AllocatePool (sizeof (*IdtPtr) + 16);
- IdtPtr = ALIGN_POINTER (IdtPtrAlignmentBuffer, 16);
- IdtPtr->Base = (UINT32)(((UINTN)(VOID*) gIdtTable) & (BASE_4GB-1));
- IdtPtr->Limit = (UINT16) (sizeof (gIdtTable) - 1);
-
- AsmWriteIdtr (IdtPtr);
-
- FreePool (IdtPtrAlignmentBuffer);
-
- //
- // Initialize Exception Handlers
- //
- for (Index = OldIdtSize; Index < 32; Index++) {
- Status = CpuRegisterInterruptHandler (&gCpu, Index, CommonExceptionHandler);
- ASSERT_EFI_ERROR (Status);
+ EFI_STATUS Status;
+ EFI_VECTOR_HANDOFF_INFO *VectorInfoList;
+ EFI_VECTOR_HANDOFF_INFO *VectorInfo;
+
+ VectorInfo = NULL;
+ Status = EfiGetSystemConfigurationTable (&gEfiVectorHandoffTableGuid, (VOID **) &VectorInfoList);
+ if (Status == EFI_SUCCESS && VectorInfoList != NULL) {
+ VectorInfo = VectorInfoList;
}
-
- //
- // Set the pointer to the array of C based exception handling routines.
- //
- InitializeExternalVectorTablePtr (ExternalVectorTable);
-
+ Status = InitializeCpuInterruptHandlers (VectorInfo);
+ ASSERT_EFI_ERROR (Status);
}
diff --git a/UefiCpuPkg/CpuDxe/CpuDxe.h b/UefiCpuPkg/CpuDxe/CpuDxe.h
index a75ec0593..2001cfc60 100644
--- a/UefiCpuPkg/CpuDxe/CpuDxe.h
+++ b/UefiCpuPkg/CpuDxe/CpuDxe.h
@@ -1,7 +1,7 @@
/** @file
CPU DXE Module.
- Copyright (c) 2008 - 2012, Intel Corporation. All rights reserved.<BR>
+ Copyright (c) 2008 - 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
@@ -30,12 +30,10 @@
#include <Library/MtrrLib.h>
#include <Library/LocalApicLib.h>
#include <Library/UefiCpuLib.h>
+#include <Library/UefiLib.h>
+#include <Library/CpuExceptionHandlerLib.h>
#include <Guid/IdleLoopEvent.h>
-
-//
-//
-//
-#define INTERRUPT_VECTOR_NUMBER 256
+#include <Guid/VectorHandoffTable.h>
#define EFI_MEMORY_CACHETYPE_MASK (EFI_MEMORY_UC | \
EFI_MEMORY_WC | \
@@ -221,30 +219,6 @@ CpuSetMemoryAttributes (
);
/**
- Label of base address of IDT vector 0.
-
- This is just a label of base address of IDT vector 0.
-
-**/
-VOID
-EFIAPI
-AsmIdtVector00 (
- VOID
- );
-
-/**
- Initializes the pointer to the external interrupt vector table.
-
- @param VectorTable Address of the external interrupt vector table.
-
-**/
-VOID
-EFIAPI
-InitializeExternalVectorTablePtr (
- EFI_CPU_INTERRUPT_HANDLER *VectorTable
- );
-
-/**
Initialize Global Descriptor Table.
**/
@@ -277,16 +251,5 @@ SetDataSelectors (
UINT16 Selector
);
-/**
- Restore original Interrupt Descriptor Table Handler Address.
-
- @param Index The Index of the interrupt descriptor table handle.
-
-**/
-VOID
-RestoreInterruptDescriptorTableHandlerAddress (
- IN UINTN Index
- );
-
#endif
diff --git a/UefiCpuPkg/CpuDxe/CpuDxe.inf b/UefiCpuPkg/CpuDxe/CpuDxe.inf
index b43506ef5..a8dfed163 100644
--- a/UefiCpuPkg/CpuDxe/CpuDxe.inf
+++ b/UefiCpuPkg/CpuDxe/CpuDxe.inf
@@ -2,7 +2,7 @@
#
# Component description file for simple CPU driver
#
-# Copyright (c) 2008 - 2012, Intel Corporation. All rights reserved.<BR>
+# Copyright (c) 2008 - 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
@@ -39,16 +39,14 @@
UefiDriverEntryPoint
LocalApicLib
UefiCpuLib
+ UefiLib
+ CpuExceptionHandlerLib
[Sources]
CpuDxe.c
CpuDxe.h
CpuGdt.c
- Ia32/IvtAsm.asm | MSFT
- Ia32/IvtAsm.asm | INTEL
- Ia32/IvtAsm.S | GCC
-
[Sources.IA32]
Ia32/CpuAsm.asm | MSFT
Ia32/CpuAsm.asm | INTEL
@@ -64,6 +62,7 @@
[Guids]
gIdleLoopEventGuid ## CONSUMES ## GUID
+ gEfiVectorHandoffTableGuid ## CONSUMES ## Configuration Table
[Depex]
TRUE
diff --git a/UefiCpuPkg/CpuDxe/Ia32/CpuAsm.S b/UefiCpuPkg/CpuDxe/Ia32/CpuAsm.S
index 3b43b6fd8..e034bc2e2 100644
--- a/UefiCpuPkg/CpuDxe/Ia32/CpuAsm.S
+++ b/UefiCpuPkg/CpuDxe/Ia32/CpuAsm.S
@@ -1,6 +1,6 @@
#------------------------------------------------------------------------------
#*
-#* Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.<BR>
+#* 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
@@ -19,21 +19,6 @@
#.MMX
#.XMM
-#EXTRN ASM_PFX(mErrorCodeFlag):DWORD # Error code flags for exceptions
-
-
-#
-# point to the external interrupt vector table
-#
-ExternalVectorTablePtr:
- .byte 0, 0, 0, 0
-
-ASM_GLOBAL ASM_PFX(InitializeExternalVectorTablePtr)
-ASM_PFX(InitializeExternalVectorTablePtr):
- movl 4(%esp), %eax
- movl %eax, ExternalVectorTablePtr
- ret
-
#------------------------------------------------------------------------------
# VOID
# SetCodeSelector (
@@ -68,298 +53,5 @@ ASM_PFX(SetDataSelectors):
movw %cx, %gs
ret
-#---------------------------------------;
-# CommonInterruptEntry ;
-#---------------------------------------;
-# The follow algorithm is used for the common interrupt routine.
-
-ASM_GLOBAL ASM_PFX(CommonInterruptEntry)
-ASM_PFX(CommonInterruptEntry):
- cli
- #
- # All interrupt handlers are invoked through interrupt gates, so
- # IF flag automatically cleared at the entry point
- #
-
- #
- # Calculate vector number
- #
- # Get the return address of call, actually, it is the
- # address of vector number.
- #
- xchgl (%esp), %ecx
- movw (%ecx), %cx
- andl $0x0FFFF, %ecx
- cmpl $32, %ecx # Intel reserved vector for exceptions?
- jae NoErrorCode
- bt %ecx, ASM_PFX(mErrorCodeFlag)
- jc HasErrorCode
-
-NoErrorCode:
-
- #
- # Stack:
- # +---------------------+
- # + EFlags +
- # +---------------------+
- # + CS +
- # +---------------------+
- # + EIP +
- # +---------------------+
- # + ECX +
- # +---------------------+ <-- ESP
- #
- # Registers:
- # ECX - Vector Number
- #
-
- #
- # Put Vector Number on stack
- #
- pushl %ecx
-
- #
- # Put 0 (dummy) error code on stack, and restore ECX
- #
- xorl %ecx, %ecx # ECX = 0
- xchgl 4(%esp), %ecx
-
- jmp ErrorCodeAndVectorOnStack
-
-HasErrorCode:
-
- #
- # Stack:
- # +---------------------+
- # + EFlags +
- # +---------------------+
- # + CS +
- # +---------------------+
- # + EIP +
- # +---------------------+
- # + Error Code +
- # +---------------------+
- # + ECX +
- # +---------------------+ <-- ESP
- #
- # Registers:
- # ECX - Vector Number
- #
-
- #
- # Put Vector Number on stack and restore ECX
- #
- xchgl (%esp), %ecx
-
-ErrorCodeAndVectorOnStack:
- pushl %ebp
- movl %esp, %ebp
-
- #
- # Stack:
- # +---------------------+
- # + EFlags +
- # +---------------------+
- # + CS +
- # +---------------------+
- # + EIP +
- # +---------------------+
- # + Error Code +
- # +---------------------+
- # + Vector Number +
- # +---------------------+
- # + EBP +
- # +---------------------+ <-- EBP
- #
-
- #
- # Align stack to make sure that EFI_FX_SAVE_STATE_IA32 of EFI_SYSTEM_CONTEXT_IA32
- # is 16-byte aligned
- #
- andl $0x0fffffff0, %esp
- subl $12, %esp
-
-#; UINT32 Edi, Esi, Ebp, Esp, Ebx, Edx, Ecx, Eax;
- pushl %eax
- pushl %ecx
- pushl %edx
- pushl %ebx
- leal 24(%ebp), %ecx
- pushl %ecx # ESP
- pushl (%ebp) # EBP
- pushl %esi
- pushl %edi
-
-#; UINT32 Gs, Fs, Es, Ds, Cs, Ss;
- movl %ss, %eax
- pushl %eax
- movzwl 16(%ebp), %eax
- pushl %eax
- movl %ds, %eax
- pushl %eax
- movl %es, %eax
- pushl %eax
- movl %fs, %eax
- pushl %eax
- movl %gs, %eax
- pushl %eax
-
-#; UINT32 Eip;
- movl 12(%ebp), %eax
- pushl %eax
-
-#; UINT32 Gdtr[2], Idtr[2];
- subl $8, %esp
- sidt (%esp)
- movl 2(%esp), %eax
- xchgl (%esp), %eax
- andl $0x0FFFF, %eax
- movl %eax, 4(%esp)
-
- subl $8, %esp
- sgdt (%esp)
- movl 2(%esp), %eax
- xchgl (%esp), %eax
- andl $0x0FFFF, %eax
- movl %eax, 4(%esp)
-
-#; UINT32 Ldtr, Tr;
- xorl %eax, %eax
- str %ax
- pushl %eax
- sldt %ax
- pushl %eax
-
-#; UINT32 EFlags;
- movl 20(%ebp), %eax
- pushl %eax
-
-#; UINT32 Cr0, Cr1, Cr2, Cr3, Cr4;
- movl %cr4, %eax
- orl $0x208, %eax
- movl %eax, %cr4
- pushl %eax
- movl %cr3, %eax
- pushl %eax
- movl %cr2, %eax
- pushl %eax
- xorl %eax, %eax
- pushl %eax
- movl %cr0, %eax
- pushl %eax
-
-#; UINT32 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;
- movl %dr7, %eax
- pushl %eax
- movl %dr6, %eax
- pushl %eax
- movl %dr3, %eax
- pushl %eax
- movl %dr2, %eax
- pushl %eax
- movl %dr1, %eax
- pushl %eax
- movl %dr0, %eax
- pushl %eax
-
-#; FX_SAVE_STATE_IA32 FxSaveState;
- subl $512, %esp
- movl %esp, %edi
- .byte 0x0f, 0x0ae, 0x07 #fxsave [edi]
-
-#; UEFI calling convention for IA32 requires that Direction flag in EFLAGs is clear
- cld
-
-#; UINT32 ExceptionData;
- pushl 8(%ebp)
-
-#; call into exception handler
- movl ExternalVectorTablePtr, %eax # get the interrupt vectors base
- orl %eax, %eax # NULL?
- jz nullExternalExceptionHandler
-
- mov 4(%ebp), %ecx
- movl (%eax,%ecx,4), %eax
- orl %eax, %eax # NULL?
- jz nullExternalExceptionHandler
-
-#; Prepare parameter and call
- movl %esp, %edx
- pushl %edx
- movl 4(%ebp), %edx
- pushl %edx
-
- #
- # Call External Exception Handler
- #
- call *%eax
- addl $8, %esp
-
-nullExternalExceptionHandler:
-
- cli
-#; UINT32 ExceptionData;
- addl $4, %esp
-
-#; FX_SAVE_STATE_IA32 FxSaveState;
- movl %esp, %esi
- .byte 0x0f, 0x0ae, 0x0e # fxrstor [esi]
- addl $512, %esp
-
-#; UINT32 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;
-#; Skip restoration of DRx registers to support in-circuit emualators
-#; or debuggers set breakpoint in interrupt/exception context
- addl $24, %esp
-
-#; UINT32 Cr0, Cr1, Cr2, Cr3, Cr4;
- popl %eax
- movl %eax, %cr0
- addl $4, %esp # not for Cr1
- popl %eax
- movl %eax, %cr2
- popl %eax
- movl %eax, %cr3
- popl %eax
- movl %eax, %cr4
-
-#; UINT32 EFlags;
- popl 20(%ebp)
-
-#; UINT32 Ldtr, Tr;
-#; UINT32 Gdtr[2], Idtr[2];
-#; Best not let anyone mess with these particular registers...
- addl $24, %esp
-
-#; UINT32 Eip;
- popl 12(%ebp)
-
-#; UINT32 Gs, Fs, Es, Ds, Cs, Ss;
-#; NOTE - modified segment registers could hang the debugger... We
-#; could attempt to insulate ourselves against this possibility,
-#; but that poses risks as well.
-#;
- popl %gs
- popl %fs
- popl %es
- popl %ds
- popl 16(%ebp)
- popl %ss
-
-#; UINT32 Edi, Esi, Ebp, Esp, Ebx, Edx, Ecx, Eax;
- popl %edi
- popl %esi
- addl $4, %esp # not for ebp
- addl $4, %esp # not for esp
- popl %ebx
- popl %edx
- popl %ecx
- popl %eax
-
- movl %ebp, %esp
- popl %ebp
- addl $8, %esp
- iretl
-
-
#END
diff --git a/UefiCpuPkg/CpuDxe/Ia32/CpuAsm.asm b/UefiCpuPkg/CpuDxe/Ia32/CpuAsm.asm
index 0924dc5bb..7f8f0d6f3 100644
--- a/UefiCpuPkg/CpuDxe/Ia32/CpuAsm.asm
+++ b/UefiCpuPkg/CpuDxe/Ia32/CpuAsm.asm
@@ -1,7 +1,7 @@
TITLE CpuAsm.asm:
;------------------------------------------------------------------------------
;*
-;* Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.<BR>
+;* 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
@@ -20,19 +20,6 @@
.model flat,C
.code
-EXTRN mErrorCodeFlag:DWORD ; Error code flags for exceptions
-
-;
-; point to the external interrupt vector table
-;
-ExternalVectorTablePtr DWORD 0
-
-InitializeExternalVectorTablePtr PROC PUBLIC
- mov eax, [esp+4]
- mov ExternalVectorTablePtr, eax
- ret
-InitializeExternalVectorTablePtr ENDP
-
;------------------------------------------------------------------------------
; VOID
; SetCodeSelector (
@@ -67,297 +54,5 @@ SetDataSelectors PROC PUBLIC
ret
SetDataSelectors ENDP
-;---------------------------------------;
-; CommonInterruptEntry ;
-;---------------------------------------;
-; The follow algorithm is used for the common interrupt routine.
-
-CommonInterruptEntry PROC PUBLIC
- cli
- ;
- ; All interrupt handlers are invoked through interrupt gates, so
- ; IF flag automatically cleared at the entry point
- ;
-
- ;
- ; Calculate vector number
- ;
- ; Get the return address of call, actually, it is the
- ; address of vector number.
- ;
- xchg ecx, [esp]
- mov cx, [ecx]
- and ecx, 0FFFFh
- cmp ecx, 32 ; Intel reserved vector for exceptions?
- jae NoErrorCode
- bt mErrorCodeFlag, ecx
- jc HasErrorCode
-
-NoErrorCode:
-
- ;
- ; Stack:
- ; +---------------------+
- ; + EFlags +
- ; +---------------------+
- ; + CS +
- ; +---------------------+
- ; + EIP +
- ; +---------------------+
- ; + ECX +
- ; +---------------------+ <-- ESP
- ;
- ; Registers:
- ; ECX - Vector Number
- ;
-
- ;
- ; Put Vector Number on stack
- ;
- push ecx
-
- ;
- ; Put 0 (dummy) error code on stack, and restore ECX
- ;
- xor ecx, ecx ; ECX = 0
- xchg ecx, [esp+4]
-
- jmp ErrorCodeAndVectorOnStack
-
-HasErrorCode:
-
- ;
- ; Stack:
- ; +---------------------+
- ; + EFlags +
- ; +---------------------+
- ; + CS +
- ; +---------------------+
- ; + EIP +
- ; +---------------------+
- ; + Error Code +
- ; +---------------------+
- ; + ECX +
- ; +---------------------+ <-- ESP
- ;
- ; Registers:
- ; ECX - Vector Number
- ;
-
- ;
- ; Put Vector Number on stack and restore ECX
- ;
- xchg ecx, [esp]
-
-ErrorCodeAndVectorOnStack:
- push ebp
- mov ebp, esp
-
- ;
- ; Stack:
- ; +---------------------+
- ; + EFlags +
- ; +---------------------+
- ; + CS +
- ; +---------------------+
- ; + EIP +
- ; +---------------------+
- ; + Error Code +
- ; +---------------------+
- ; + Vector Number +
- ; +---------------------+
- ; + EBP +
- ; +---------------------+ <-- EBP
- ;
-
- ;
- ; Align stack to make sure that EFI_FX_SAVE_STATE_IA32 of EFI_SYSTEM_CONTEXT_IA32
- ; is 16-byte aligned
- ;
- and esp, 0fffffff0h
- sub esp, 12
-
-;; UINT32 Edi, Esi, Ebp, Esp, Ebx, Edx, Ecx, Eax;
- push eax
- push ecx
- push edx
- push ebx
- lea ecx, [ebp + 6 * 4]
- push ecx ; ESP
- push dword ptr [ebp] ; EBP
- push esi
- push edi
-
-;; UINT32 Gs, Fs, Es, Ds, Cs, Ss;
- mov eax, ss
- push eax
- movzx eax, word ptr [ebp + 4 * 4]
- push eax
- mov eax, ds
- push eax
- mov eax, es
- push eax
- mov eax, fs
- push eax
- mov eax, gs
- push eax
-
-;; UINT32 Eip;
- mov eax, [ebp + 3 * 4]
- push eax
-
-;; UINT32 Gdtr[2], Idtr[2];
- sub esp, 8
- sidt [esp]
- mov eax, [esp + 2]
- xchg eax, [esp]
- and eax, 0FFFFh
- mov [esp+4], eax
-
- sub esp, 8
- sgdt [esp]
- mov eax, [esp + 2]
- xchg eax, [esp]
- and eax, 0FFFFh
- mov [esp+4], eax
-
-;; UINT32 Ldtr, Tr;
- xor eax, eax
- str ax
- push eax
- sldt ax
- push eax
-
-;; UINT32 EFlags;
- mov eax, [ebp + 5 * 4]
- push eax
-
-;; UINT32 Cr0, Cr1, Cr2, Cr3, Cr4;
- mov eax, cr4
- or eax, 208h
- mov cr4, eax
- push eax
- mov eax, cr3
- push eax
- mov eax, cr2
- push eax
- xor eax, eax
- push eax
- mov eax, cr0
- push eax
-
-;; UINT32 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;
- mov eax, dr7
- push eax
- mov eax, dr6
- push eax
- mov eax, dr3
- push eax
- mov eax, dr2
- push eax
- mov eax, dr1
- push eax
- mov eax, dr0
- push eax
-
-;; FX_SAVE_STATE_IA32 FxSaveState;
- sub esp, 512
- mov edi, esp
- db 0fh, 0aeh, 07h ;fxsave [edi]
-
-;; UEFI calling convention for IA32 requires that Direction flag in EFLAGs is clear
- cld
-
-;; UINT32 ExceptionData;
- push dword ptr [ebp + 2 * 4]
-
-;; call into exception handler
- mov eax, ExternalVectorTablePtr ; get the interrupt vectors base
- or eax, eax ; NULL?
- jz nullExternalExceptionHandler
-
- mov ecx, [ebp + 4]
- mov eax, [eax + ecx * 4]
- or eax, eax ; NULL?
- jz nullExternalExceptionHandler
-
-;; Prepare parameter and call
- mov edx, esp
- push edx
- mov edx, dword ptr [ebp + 1 * 4]
- push edx
-
- ;
- ; Call External Exception Handler
- ;
- call eax
- add esp, 8
-
-nullExternalExceptionHandler:
-
- cli
-;; UINT32 ExceptionData;
- add esp, 4
-
-;; FX_SAVE_STATE_IA32 FxSaveState;
- mov esi, esp
- db 0fh, 0aeh, 0eh ; fxrstor [esi]
- add esp, 512
-
-;; UINT32 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;
-;; Skip restoration of DRx registers to support in-circuit emualators
-;; or debuggers set breakpoint in interrupt/exception context
- add esp, 4 * 6
-
-;; UINT32 Cr0, Cr1, Cr2, Cr3, Cr4;
- pop eax
- mov cr0, eax
- add esp, 4 ; not for Cr1
- pop eax
- mov cr2, eax
- pop eax
- mov cr3, eax
- pop eax
- mov cr4, eax
-
-;; UINT32 EFlags;
- pop dword ptr [ebp + 5 * 4]
-
-;; UINT32 Ldtr, Tr;
-;; UINT32 Gdtr[2], Idtr[2];
-;; Best not let anyone mess with these particular registers...
- add esp, 24
-
-;; UINT32 Eip;
- pop dword ptr [ebp + 3 * 4]
-
-;; UINT32 Gs, Fs, Es, Ds, Cs, Ss;
-;; NOTE - modified segment registers could hang the debugger... We
-;; could attempt to insulate ourselves against this possibility,
-;; but that poses risks as well.
-;;
- pop gs
- pop fs
- pop es
- pop ds
- pop dword ptr [ebp + 4 * 4]
- pop ss
-
-;; UINT32 Edi, Esi, Ebp, Esp, Ebx, Edx, Ecx, Eax;
- pop edi
- pop esi
- add esp, 4 ; not for ebp
- add esp, 4 ; not for esp
- pop ebx
- pop edx
- pop ecx
- pop eax
-
- mov esp, ebp
- pop ebp
- add esp, 8
- iretd
-
-CommonInterruptEntry ENDP
END
diff --git a/UefiCpuPkg/CpuDxe/Ia32/IvtAsm.S b/UefiCpuPkg/CpuDxe/Ia32/IvtAsm.S
deleted file mode 100644
index c38461dc9..000000000
--- a/UefiCpuPkg/CpuDxe/Ia32/IvtAsm.S
+++ /dev/null
@@ -1,818 +0,0 @@
-#------------------------------------------------------------------------------
-#
-# Copyright (c) 2006 - 2009, 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.
-#
-# Module Name:
-#
-# IvtAsm.S
-#
-# Abstract:
-#
-# Interrupt Vector Table
-#
-#------------------------------------------------------------------------------
-
-#
-# Interrupt Vector Table
-#
-
-
-ASM_GLOBAL ASM_PFX(AsmIdtVector00)
-.p2align 3
-ASM_PFX(AsmIdtVector00):
- call ASM_PFX(CommonInterruptEntry)
- .short 0x00
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0x01
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0x02
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0x03
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0x04
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0x05
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0x06
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0x07
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0x08
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0x09
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0x0a
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0x0b
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0x0c
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0x0d
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0x0e
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0x0f
- nop
-
- call ASM_PFX(CommonInterruptEntry)
- .short 0x10
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0x11
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0x12
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0x13
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0x14
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0x15
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0x16
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0x17
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0x18
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0x19
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0x1a
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0x1b
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0x1c
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0x1d
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0x1e
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0x1f
- nop
-
- call ASM_PFX(CommonInterruptEntry)
- .short 0x00
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0x21
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0x22
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0x23
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0x24
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0x25
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0x26
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0x27
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0x28
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0x29
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0x2a
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0x2b
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0x2c
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0x2d
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0x2e
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0x2f
- nop
-
- call ASM_PFX(CommonInterruptEntry)
- .short 0x30
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0x31
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0x32
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0x33
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0x34
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0x35
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0x36
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0x37
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0x38
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0x39
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0x3a
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0x3b
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0x3c
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0x3d
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0x3e
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0x3f
- nop
-
- call ASM_PFX(CommonInterruptEntry)
- .short 0x40
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0x41
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0x42
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0x43
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0x44
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0x45
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0x46
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0x47
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0x48
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0x49
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0x4a
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0x4b
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0x4c
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0x4d
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0x4e
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0x4f
- nop
-
- call ASM_PFX(CommonInterruptEntry)
- .short 0x50
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0x51
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0x52
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0x53
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0x54
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0x55
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0x56
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0x57
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0x58
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0x59
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0x5a
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0x5b
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0x5c
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0x5d
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0x5e
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0x5f
- nop
-
- call ASM_PFX(CommonInterruptEntry)
- .short 0x60
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0x61
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0x62
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0x63
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0x64
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0x65
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0x66
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0x67
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0x68
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0x69
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0x6a
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0x6b
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0x6c
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0x6d
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0x6e
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0x6f
- nop
-
- call ASM_PFX(CommonInterruptEntry)
- .short 0x70
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0x71
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0x72
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0x73
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0x74
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0x75
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0x76
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0x77
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0x78
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0x79
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0x7a
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0x7b
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0x7c
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0x7d
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0x7e
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0x7f
- nop
-
- call ASM_PFX(CommonInterruptEntry)
- .short 0x80
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0x81
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0x82
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0x83
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0x84
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0x85
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0x86
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0x87
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0x88
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0x89
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0x8a
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0x8b
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0x8c
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0x8d
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0x8e
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0x8f
- nop
-
- call ASM_PFX(CommonInterruptEntry)
- .short 0x90
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0x91
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0x92
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0x93
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0x94
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0x95
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0x96
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0x97
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0x98
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0x99
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0x9a
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0x9b
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0x9c
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0x9d
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0x9e
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0x9f
- nop
-
- call ASM_PFX(CommonInterruptEntry)
- .short 0xa0
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0xa1
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0xa2
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0xa3
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0xa4
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0xa5
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0xa6
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0xa7
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0xa8
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0xa9
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0xaa
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0xab
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0xac
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0xad
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0xae
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0xaf
- nop
-
- call ASM_PFX(CommonInterruptEntry)
- .short 0xb0
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0xb1
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0xb2
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0xb3
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0xb4
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0xb5
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0xb6
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0xb7
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0xb8
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0xb9
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0xba
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0xbb
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0xbc
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0xbd
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0xbe
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0xbf
- nop
-
- call ASM_PFX(CommonInterruptEntry)
- .short 0xc0
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0xc1
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0xc2
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0xc3
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0xc4
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0xc5
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0xc6
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0xc7
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0xc8
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0xc9
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0xca
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0xcb
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0xcc
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0xcd
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0xce
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0xcf
- nop
-
- call ASM_PFX(CommonInterruptEntry)
- .short 0xd0
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0xd1
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0xd2
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0xd3
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0xd4
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0xd5
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0xd6
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0xd7
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0xd8
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0xd9
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0xda
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0xdb
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0xdc
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0xdd
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0xde
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0xdf
- nop
-
- call ASM_PFX(CommonInterruptEntry)
- .short 0xe0
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0xe1
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0xe2
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0xe3
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0xe4
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0xe5
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0xe6
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0xe7
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0xe8
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0xe9
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0xea
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0xeb
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0xec
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0xed
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0xee
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0xef
- nop
-
- call ASM_PFX(CommonInterruptEntry)
- .short 0xf0
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0xf1
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0xf2
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0xf3
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0xf4
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0xf5
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0xf6
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0xf7
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0xf8
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0xf9
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0xfa
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0xfb
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0xfc
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0xfd
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0xfe
- nop
- call ASM_PFX(CommonInterruptEntry)
- .short 0xff
- nop
-
-ASM_GLOBAL ASM_PFX(AsmCommonIdtEnd)
-ASM_PFX(AsmCommonIdtEnd):
- .byte 0
-
-
diff --git a/UefiCpuPkg/CpuDxe/Ia32/IvtAsm.asm b/UefiCpuPkg/CpuDxe/Ia32/IvtAsm.asm
deleted file mode 100644
index 02003c9fa..000000000
--- a/UefiCpuPkg/CpuDxe/Ia32/IvtAsm.asm
+++ /dev/null
@@ -1,51 +0,0 @@
- TITLE IvtAsm.asm:
-;------------------------------------------------------------------------------
-;*
-;* Copyright (c) 2008 - 2009, 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.
-;*
-;* IvtAsm.asm
-;*
-;* Abstract:
-;*
-;------------------------------------------------------------------------------
-
-#include <Base.h>
-
-#ifdef MDE_CPU_IA32
- .686
- .model flat,C
-#endif
- .code
-
-;------------------------------------------------------------------------------
-; Generic IDT Vector Handlers for the Host. They are all the same so they
-; will compress really well.
-;
-; By knowing the return address for Vector 00 you can can calculate the
-; vector number by looking at the call CommonInterruptEntry return address.
-; (return address - (AsmIdtVector00 + 5))/8 == IDT index
-;
-;------------------------------------------------------------------------------
-
-EXTRN CommonInterruptEntry:PROC
-
-ALIGN 8
-
-PUBLIC AsmIdtVector00
-
-AsmIdtVector00 LABEL BYTE
-REPEAT 256
- call CommonInterruptEntry
- dw ($ - AsmIdtVector00 - 5) / 8 ; vector number
- nop
-ENDM
-
-END
-
diff --git a/UefiCpuPkg/CpuDxe/X64/CpuAsm.S b/UefiCpuPkg/CpuDxe/X64/CpuAsm.S
index e038f2e34..e82cadf36 100644
--- a/UefiCpuPkg/CpuDxe/X64/CpuAsm.S
+++ b/UefiCpuPkg/CpuDxe/X64/CpuAsm.S
@@ -2,7 +2,7 @@
#------------------------------------------------------------------------------
#*
-#* Copyright (c) 2008 - 2011, Intel Corporation. All rights reserved.<BR>
+#* Copyright (c) 2008 - 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
@@ -21,22 +21,6 @@
#text SEGMENT
-#EXTRN ASM_PFX(mErrorCodeFlag):DWORD # Error code flags for exceptions
-
-
-#
-# point to the external interrupt vector table
-#
-ExternalVectorTablePtr:
- .byte 0, 0, 0, 0, 0, 0, 0, 0
-
-ASM_GLOBAL ASM_PFX(InitializeExternalVectorTablePtr)
-ASM_PFX(InitializeExternalVectorTablePtr):
- lea ExternalVectorTablePtr(%rip), %rax # save vector number
- mov %rcx, (%rax)
- ret
-
-
#------------------------------------------------------------------------------
# VOID
# SetCodeSelector (
@@ -69,275 +53,6 @@ ASM_PFX(SetDataSelectors):
movw %cx, %gs
ret
-#---------------------------------------;
-# CommonInterruptEntry ;
-#---------------------------------------;
-# The follow algorithm is used for the common interrupt routine.
-
-ASM_GLOBAL ASM_PFX(CommonInterruptEntry)
-ASM_PFX(CommonInterruptEntry):
- cli
- #
- # All interrupt handlers are invoked through interrupt gates, so
- # IF flag automatically cleared at the entry point
- #
- #
- # Calculate vector number
- #
- xchgq (%rsp), %rcx # get the return address of call, actually, it is the address of vector number.
- movzwl (%rcx), %ecx
- cmp $32, %ecx # Intel reserved vector for exceptions?
- jae NoErrorCode
- pushq %rax
- leaq ASM_PFX(mErrorCodeFlag)(%rip), %rax
- bt %ecx, (%rax)
- popq %rax
- jc CommonInterruptEntry_al_0000
-
-NoErrorCode:
-
- #
- # Push a dummy error code on the stack
- # to maintain coherent stack map
- #
- pushq (%rsp)
- movq $0, 8(%rsp)
-CommonInterruptEntry_al_0000:
- pushq %rbp
- movq %rsp, %rbp
-
- #
- # Stack:
- # +---------------------+ <-- 16-byte aligned ensured by processor
- # + Old SS +
- # +---------------------+
- # + Old RSP +
- # +---------------------+
- # + RFlags +
- # +---------------------+
- # + CS +
- # +---------------------+
- # + RIP +
- # +---------------------+
- # + Error Code +
- # +---------------------+
- # + RCX / Vector Number +
- # +---------------------+
- # + RBP +
- # +---------------------+ <-- RBP, 16-byte aligned
- #
-
-
- #
- # Since here the stack pointer is 16-byte aligned, so
- # EFI_FX_SAVE_STATE_X64 of EFI_SYSTEM_CONTEXT_x64
- # is 16-byte aligned
- #
-
-#; UINT64 Rdi, Rsi, Rbp, Rsp, Rbx, Rdx, Rcx, Rax;
-#; UINT64 R8, R9, R10, R11, R12, R13, R14, R15;
- pushq %r15
- pushq %r14
- pushq %r13
- pushq %r12
- pushq %r11
- pushq %r10
- pushq %r9
- pushq %r8
- pushq %rax
- pushq 8(%rbp) # RCX
- pushq %rdx
- pushq %rbx
- pushq 48(%rbp) # RSP
- pushq (%rbp) # RBP
- pushq %rsi
- pushq %rdi
-
-#; UINT64 Gs, Fs, Es, Ds, Cs, Ss; insure high 16 bits of each is zero
- movzwq 56(%rbp), %rax
- pushq %rax # for ss
- movzwq 32(%rbp), %rax
- pushq %rax # for cs
- movl %ds, %eax
- pushq %rax
- movl %es, %eax
- pushq %rax
- movl %fs, %eax
- pushq %rax
- movl %gs, %eax
- pushq %rax
-
- movq %rcx, 8(%rbp) # save vector number
-
-#; UINT64 Rip;
- pushq 24(%rbp)
-
-#; UINT64 Gdtr[2], Idtr[2];
- xorq %rax, %rax
- pushq %rax
- pushq %rax
- sidt (%rsp)
- xchgq 2(%rsp), %rax
- xchgq (%rsp), %rax
- xchgq 8(%rsp), %rax
-
- xorq %rax, %rax
- pushq %rax
- pushq %rax
- sgdt (%rsp)
- xchgq 2(%rsp), %rax
- xchgq (%rsp), %rax
- xchgq 8(%rsp), %rax
-
-#; UINT64 Ldtr, Tr;
- xorq %rax, %rax
- str %ax
- pushq %rax
- sldt %ax
- pushq %rax
-
-#; UINT64 RFlags;
- pushq 40(%rbp)
-
-#; UINT64 Cr0, Cr1, Cr2, Cr3, Cr4, Cr8;
- movq %cr8, %rax
- pushq %rax
- movq %cr4, %rax
- orq $0x208, %rax
- movq %rax, %cr4
- pushq %rax
- mov %cr3, %rax
- pushq %rax
- mov %cr2, %rax
- pushq %rax
- xorq %rax, %rax
- pushq %rax
- mov %cr0, %rax
- pushq %rax
-
-#; UINT64 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;
- movq %dr7, %rax
- pushq %rax
- movq %dr6, %rax
- pushq %rax
- movq %dr3, %rax
- pushq %rax
- movq %dr2, %rax
- pushq %rax
- movq %dr1, %rax
- pushq %rax
- movq %dr0, %rax
- pushq %rax
-
-#; FX_SAVE_STATE_X64 FxSaveState;
- subq $512, %rsp
- movq %rsp, %rdi
- .byte 0x0f, 0x0ae, 0x07 #fxsave [rdi]
-
-#; UEFI calling convention for x64 requires that Direction flag in EFLAGs is clear
- cld
-
-#; UINT32 ExceptionData;
- pushq 16(%rbp)
-
-#; call into exception handler
- movq 8(%rbp), %rcx
- leaq ExternalVectorTablePtr(%rip), %rax
- movl (%eax), %eax
- movq (%rax,%rcx,8), %rax
- orq %rax, %rax # NULL?
-
- je nonNullValue#
-
-#; Prepare parameter and call
-# mov rcx, [rbp + 8]
- mov %rsp, %rdx
- #
- # Per X64 calling convention, allocate maximum parameter stack space
- # and make sure RSP is 16-byte aligned
- #
- subq $40, %rsp
- call *%rax
- addq $40, %rsp
-
-nonNullValue:
- cli
-#; UINT64 ExceptionData;
- addq $8, %rsp
-
-#; FX_SAVE_STATE_X64 FxSaveState;
-
- movq %rsp, %rsi
- .byte 0x0f, 0x0ae, 0x0E # fxrstor [rsi]
- addq $512, %rsp
-
-#; UINT64 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;
-#; Skip restoration of DRx registers to support in-circuit emualators
-#; or debuggers set breakpoint in interrupt/exception context
- addq $48, %rsp
-
-#; UINT64 Cr0, Cr1, Cr2, Cr3, Cr4, Cr8;
- popq %rax
- movq %rax, %cr0
- addq $8, %rsp # not for Cr1
- popq %rax
- movq %rax, %cr2
- popq %rax
- movq %rax, %cr3
- popq %rax
- movq %rax, %cr4
- popq %rax
- movq %rax, %cr8
-
-#; UINT64 RFlags;
- popq 40(%rbp)
-
-#; UINT64 Ldtr, Tr;
-#; UINT64 Gdtr[2], Idtr[2];
-#; Best not let anyone mess with these particular registers...
- addq $48, %rsp
-
-#; UINT64 Rip;
- popq 24(%rbp)
-
-#; UINT64 Gs, Fs, Es, Ds, Cs, Ss;
- popq %rax
- # mov %rax, %gs ; not for gs
- popq %rax
- # mov %rax, %fs ; not for fs
- # (X64 will not use fs and gs, so we do not restore it)
- popq %rax
- movl %eax, %es
- popq %rax
- movl %eax, %ds
- popq 32(%rbp) # for cs
- popq 56(%rbp) # for ss
-
-#; UINT64 Rdi, Rsi, Rbp, Rsp, Rbx, Rdx, Rcx, Rax;
-#; UINT64 R8, R9, R10, R11, R12, R13, R14, R15;
- popq %rdi
- popq %rsi
- addq $8, %rsp # not for rbp
- popq 48(%rbp) # for rsp
- popq %rbx
- popq %rdx
- popq %rcx
- popq %rax
- popq %r8
- popq %r9
- popq %r10
- popq %r11
- popq %r12
- popq %r13
- popq %r14
- popq %r15
-
- movq %rbp, %rsp
- popq %rbp
- addq $16, %rsp
- iretq
-
-
#text ENDS
#END
diff --git a/UefiCpuPkg/CpuDxe/X64/CpuAsm.asm b/UefiCpuPkg/CpuDxe/X64/CpuAsm.asm
index 68fcd3f40..c71b06a81 100644
--- a/UefiCpuPkg/CpuDxe/X64/CpuAsm.asm
+++ b/UefiCpuPkg/CpuDxe/X64/CpuAsm.asm
@@ -1,7 +1,7 @@
TITLE CpuAsm.asm:
;------------------------------------------------------------------------------
;*
-;* Copyright (c) 2008 - 2011, Intel Corporation. All rights reserved.<BR>
+;* Copyright (c) 2008 - 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
@@ -18,18 +18,6 @@
.code
-EXTRN mErrorCodeFlag:DWORD ; Error code flags for exceptions
-
-;
-; point to the external interrupt vector table
-;
-ExternalVectorTablePtr QWORD 0
-
-InitializeExternalVectorTablePtr PROC PUBLIC
- mov ExternalVectorTablePtr, rcx
- ret
-InitializeExternalVectorTablePtr ENDP
-
;------------------------------------------------------------------------------
; VOID
; SetCodeSelector (
@@ -62,270 +50,5 @@ SetDataSelectors PROC PUBLIC
ret
SetDataSelectors ENDP
-;---------------------------------------;
-; CommonInterruptEntry ;
-;---------------------------------------;
-; The follow algorithm is used for the common interrupt routine.
-
-CommonInterruptEntry PROC PUBLIC
- cli
- ;
- ; All interrupt handlers are invoked through interrupt gates, so
- ; IF flag automatically cleared at the entry point
- ;
- ;
- ; Calculate vector number
- ;
- xchg rcx, [rsp] ; get the return address of call, actually, it is the address of vector number.
- movzx ecx, word ptr [rcx]
- cmp ecx, 32 ; Intel reserved vector for exceptions?
- jae NoErrorCode
- bt mErrorCodeFlag, ecx
- jc @F
-
-NoErrorCode:
-
- ;
- ; Push a dummy error code on the stack
- ; to maintain coherent stack map
- ;
- push [rsp]
- mov qword ptr [rsp + 8], 0
-@@:
- push rbp
- mov rbp, rsp
-
- ;
- ; Stack:
- ; +---------------------+ <-- 16-byte aligned ensured by processor
- ; + Old SS +
- ; +---------------------+
- ; + Old RSP +
- ; +---------------------+
- ; + RFlags +
- ; +---------------------+
- ; + CS +
- ; +---------------------+
- ; + RIP +
- ; +---------------------+
- ; + Error Code +
- ; +---------------------+
- ; + RCX / Vector Number +
- ; +---------------------+
- ; + RBP +
- ; +---------------------+ <-- RBP, 16-byte aligned
- ;
-
-
- ;
- ; Since here the stack pointer is 16-byte aligned, so
- ; EFI_FX_SAVE_STATE_X64 of EFI_SYSTEM_CONTEXT_x64
- ; is 16-byte aligned
- ;
-
-;; UINT64 Rdi, Rsi, Rbp, Rsp, Rbx, Rdx, Rcx, Rax;
-;; UINT64 R8, R9, R10, R11, R12, R13, R14, R15;
- push r15
- push r14
- push r13
- push r12
- push r11
- push r10
- push r9
- push r8
- push rax
- push qword ptr [rbp + 8] ; RCX
- push rdx
- push rbx
- push qword ptr [rbp + 48] ; RSP
- push qword ptr [rbp] ; RBP
- push rsi
- push rdi
-
-;; UINT64 Gs, Fs, Es, Ds, Cs, Ss; insure high 16 bits of each is zero
- movzx rax, word ptr [rbp + 56]
- push rax ; for ss
- movzx rax, word ptr [rbp + 32]
- push rax ; for cs
- mov rax, ds
- push rax
- mov rax, es
- push rax
- mov rax, fs
- push rax
- mov rax, gs
- push rax
-
- mov [rbp + 8], rcx ; save vector number
-
-;; UINT64 Rip;
- push qword ptr [rbp + 24]
-
-;; UINT64 Gdtr[2], Idtr[2];
- xor rax, rax
- push rax
- push rax
- sidt [rsp]
- xchg rax, [rsp + 2]
- xchg rax, [rsp]
- xchg rax, [rsp + 8]
-
- xor rax, rax
- push rax
- push rax
- sgdt [rsp]
- xchg rax, [rsp + 2]
- xchg rax, [rsp]
- xchg rax, [rsp + 8]
-
-;; UINT64 Ldtr, Tr;
- xor rax, rax
- str ax
- push rax
- sldt ax
- push rax
-
-;; UINT64 RFlags;
- push qword ptr [rbp + 40]
-
-;; UINT64 Cr0, Cr1, Cr2, Cr3, Cr4, Cr8;
- mov rax, cr8
- push rax
- mov rax, cr4
- or rax, 208h
- mov cr4, rax
- push rax
- mov rax, cr3
- push rax
- mov rax, cr2
- push rax
- xor rax, rax
- push rax
- mov rax, cr0
- push rax
-
-;; UINT64 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;
- mov rax, dr7
- push rax
- mov rax, dr6
- push rax
- mov rax, dr3
- push rax
- mov rax, dr2
- push rax
- mov rax, dr1
- push rax
- mov rax, dr0
- push rax
-
-;; FX_SAVE_STATE_X64 FxSaveState;
- sub rsp, 512
- mov rdi, rsp
- db 0fh, 0aeh, 07h ;fxsave [rdi]
-
-;; UEFI calling convention for x64 requires that Direction flag in EFLAGs is clear
- cld
-
-;; UINT32 ExceptionData;
- push qword ptr [rbp + 16]
-
-;; call into exception handler
- mov rcx, [rbp + 8]
- mov rax, ExternalVectorTablePtr ; get the interrupt vectors base
- mov rax, [rax + rcx * 8]
- or rax, rax ; NULL?
-
- je nonNullValue;
-
-;; Prepare parameter and call
-; mov rcx, [rbp + 8]
- mov rdx, rsp
- ;
- ; Per X64 calling convention, allocate maximum parameter stack space
- ; and make sure RSP is 16-byte aligned
- ;
- sub rsp, 4 * 8 + 8
- call rax
- add rsp, 4 * 8 + 8
-
-nonNullValue:
- cli
-;; UINT64 ExceptionData;
- add rsp, 8
-
-;; FX_SAVE_STATE_X64 FxSaveState;
-
- mov rsi, rsp
- db 0fh, 0aeh, 0Eh ; fxrstor [rsi]
- add rsp, 512
-
-;; UINT64 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;
-;; Skip restoration of DRx registers to support in-circuit emualators
-;; or debuggers set breakpoint in interrupt/exception context
- add rsp, 8 * 6
-
-;; UINT64 Cr0, Cr1, Cr2, Cr3, Cr4, Cr8;
- pop rax
- mov cr0, rax
- add rsp, 8 ; not for Cr1
- pop rax
- mov cr2, rax
- pop rax
- mov cr3, rax
- pop rax
- mov cr4, rax
- pop rax
- mov cr8, rax
-
-;; UINT64 RFlags;
- pop qword ptr [rbp + 40]
-
-;; UINT64 Ldtr, Tr;
-;; UINT64 Gdtr[2], Idtr[2];
-;; Best not let anyone mess with these particular registers...
- add rsp, 48
-
-;; UINT64 Rip;
- pop qword ptr [rbp + 24]
-
-;; UINT64 Gs, Fs, Es, Ds, Cs, Ss;
- pop rax
- ; mov gs, rax ; not for gs
- pop rax
- ; mov fs, rax ; not for fs
- ; (X64 will not use fs and gs, so we do not restore it)
- pop rax
- mov es, rax
- pop rax
- mov ds, rax
- pop qword ptr [rbp + 32] ; for cs
- pop qword ptr [rbp + 56] ; for ss
-
-;; UINT64 Rdi, Rsi, Rbp, Rsp, Rbx, Rdx, Rcx, Rax;
-;; UINT64 R8, R9, R10, R11, R12, R13, R14, R15;
- pop rdi
- pop rsi
- add rsp, 8 ; not for rbp
- pop qword ptr [rbp + 48] ; for rsp
- pop rbx
- pop rdx
- pop rcx
- pop rax
- pop r8
- pop r9
- pop r10
- pop r11
- pop r12
- pop r13
- pop r14
- pop r15
-
- mov rsp, rbp
- pop rbp
- add rsp, 16
- iretq
-
-CommonInterruptEntry ENDP
-
END
diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.c b/UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.c
index b1c692303..c075d5f16 100644
--- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.c
+++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.c
@@ -1,7 +1,7 @@
/** @file
CPU Exception Hanlder Library common functions.
- Copyright (c) 2012, Intel Corporation. All rights reserved.<BR>
+ Copyright (c) 2012 - 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
@@ -15,12 +15,13 @@
#include "CpuExceptionCommon.h"
//
-// Error code flag indicating whether or not an error code will be
+// Error code flag indicating whether or not an error code will be
// pushed on the stack if an exception occurs.
//
// 1 means an error code will be pushed, otherwise 0
//
-UINT32 mErrorCodeFlag = 0x00027d00;
+CONST UINT32 mErrorCodeFlag = 0x00027d00;
+RESERVED_VECTORS_DATA *mReservedVectors = NULL;
//
// Define the maximum message length
@@ -133,3 +134,35 @@ FindModuleImageBase (
return Pe32Data;
}
+/**
+ Read and save reserved vector information
+
+ @param[in] VectorInfo Pointer to reserved vector list.
+ @param[out] ReservedVector Pointer to reserved vector data buffer.
+ @param[in] VectorCount Vector number to be updated.
+
+ @return EFI_SUCCESS Read and save vector info successfully.
+ @retval EFI_INVALID_PARAMETER VectorInfo includes the invalid content if VectorInfo is not NULL.
+
+**/
+EFI_STATUS
+ReadAndVerifyVectorInfo (
+ IN EFI_VECTOR_HANDOFF_INFO *VectorInfo,
+ OUT RESERVED_VECTORS_DATA *ReservedVector,
+ IN UINTN VectorCount
+ )
+{
+ while (VectorInfo->Attribute != EFI_VECTOR_HANDOFF_LAST_ENTRY) {
+ if (VectorInfo->Attribute > EFI_VECTOR_HANDOFF_HOOK_AFTER) {
+ //
+ // If vector attrubute is invalid
+ //
+ return EFI_INVALID_PARAMETER;
+ }
+ if (VectorInfo->VectorNumber < VectorCount) {
+ ReservedVector[VectorInfo->VectorNumber].Attribute = VectorInfo->Attribute;
+ }
+ VectorInfo ++;
+ }
+ return EFI_SUCCESS;
+} \ No newline at end of file
diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.h b/UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.h
index 66847eaae..12d5e4634 100644
--- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.h
+++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.h
@@ -1,7 +1,7 @@
/** @file
Common header file for CPU Exception Handler Library.
- Copyright (c) 2012, Intel Corporation. All rights reserved.<BR>
+ Copyright (c) 2012 - 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
@@ -15,23 +15,35 @@
#ifndef _CPU_EXCEPTION_COMMON_H_
#define _CPU_EXCEPTION_COMMON_H_
+#include <Ppi/VectorHandoffInfo.h>
+#include <Protocol/Cpu.h>
#include <Library/BaseLib.h>
#include <Library/SerialPortLib.h>
#include <Library/PrintLib.h>
#include <Library/LocalApicLib.h>
#include <Library/PeCoffGetEntryPointLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/SynchronizationLib.h>
+
+#define CPU_EXCEPTION_NUM 32
+#define CPU_INTERRUPT_NUM 256
+#define HOOKAFTER_STUB_SIZE 16
+
+#include "ArchInterruptDefs.h"
-#define CPU_EXCEPTION_NUM 32
//
// Record exception handler information
//
typedef struct {
UINTN ExceptionStart;
UINTN ExceptionStubHeaderSize;
+ UINTN HookAfterStubHeaderStart;
} EXCEPTION_HANDLER_TEMPLATE_MAP;
-extern UINT32 mErrorCodeFlag;
-extern CONST UINTN mImageAlignSize;
+extern CONST UINT32 mErrorCodeFlag;
+extern CONST UINTN mImageAlignSize;
+extern CONST UINTN mDoFarReturnFlag;
+extern RESERVED_VECTORS_DATA *mReservedVectors;
/**
Return address map of exception handler template so that C code can generate
@@ -41,17 +53,33 @@ extern CONST UINTN mImageAlignSize;
**/
VOID
EFIAPI
-GetTemplateAddressMap (
+AsmGetTemplateAddressMap (
OUT EXCEPTION_HANDLER_TEMPLATE_MAP *AddressMap
);
/**
- Internal function to setup CPU exception handlers.
+ Return address map of exception handler template so that C code can generate
+ exception tables.
+
+ @param IdtEntry Pointer to IDT entry to be updated.
+ @param InterruptHandler IDT handler value.
**/
VOID
-InternalSetupCpuExceptionHandlers (
- VOID
+ArchUpdateIdtEntry (
+ IN IA32_IDT_GATE_DESCRIPTOR *IdtEntry,
+ IN UINTN InterruptHandler
+ );
+
+/**
+ Read IDT handler value from IDT entry.
+
+ @param IdtEntry Pointer to IDT entry to be read.
+
+**/
+UINTN
+ArchGetIdtHandler (
+ IN IA32_IDT_GATE_DESCRIPTOR *IdtEntry
);
/**
@@ -92,8 +120,120 @@ FindModuleImageBase (
**/
VOID
DumpCpuContent (
- IN UINTN InterruptType,
+ IN EFI_EXCEPTION_TYPE ExceptionType,
IN EFI_SYSTEM_CONTEXT SystemContext
);
+/**
+ Internal worker function to initialize exception handler.
+
+ @param[in] VectorInfo Pointer to reserved vector list.
+
+ @retval EFI_SUCCESS CPU Exception Entries have been successfully initialized
+ with default exception handlers.
+ @retval EFI_INVALID_PARAMETER VectorInfo includes the invalid content if VectorInfo is not NULL.
+ @retval EFI_UNSUPPORTED This function is not supported.
+
+**/
+EFI_STATUS
+InitializeCpuExceptionHandlersWorker (
+ IN EFI_VECTOR_HANDOFF_INFO *VectorInfo OPTIONAL
+ );
+
+/**
+ Registers a function to be called from the processor interrupt handler.
+
+ @param[in] InterruptType Defines which interrupt or exception to hook.
+ @param[in] InterruptHandler A pointer to a function of type EFI_CPU_INTERRUPT_HANDLER that is called
+ when a processor interrupt occurs. If this parameter is NULL, then the handler
+ will be uninstalled.
+
+ @retval EFI_SUCCESS The handler for the processor interrupt was successfully installed or uninstalled.
+ @retval EFI_ALREADY_STARTED InterruptHandler is not NULL, and a handler for InterruptType was
+ previously installed.
+ @retval EFI_INVALID_PARAMETER InterruptHandler is NULL, and a handler for InterruptType was not
+ previously installed.
+ @retval EFI_UNSUPPORTED The interrupt specified by InterruptType is not supported,
+ or this function is not supported.
+*/
+EFI_STATUS
+RegisterCpuInterruptHandlerWorker (
+ IN EFI_EXCEPTION_TYPE InterruptType,
+ IN EFI_CPU_INTERRUPT_HANDLER InterruptHandler
+ );
+
+/**
+ Internal worker function to update IDT entries accordling to vector attributes.
+
+ @param[in] IdtTable Pointer to IDT table.
+ @param[in] TemplateMap Pointer to a buffer where the address map is returned.
+ @param[in] IdtEntryCount IDT entries number to be updated.
+
+**/
+VOID
+UpdateIdtTable (
+ IN IA32_IDT_GATE_DESCRIPTOR *IdtTable,
+ IN EXCEPTION_HANDLER_TEMPLATE_MAP *TemplateMap,
+ IN UINTN IdtEntryCount
+ );
+
+/**
+ Save CPU exception context when handling EFI_VECTOR_HANDOFF_HOOK_AFTER case.
+
+ @param[in] ExceptionType Exception type.
+ @param[in] SystemContext Pointer to EFI_SYSTEM_CONTEXT.
+
+**/
+VOID
+ArchSaveExceptionContext (
+ IN UINTN ExceptionType,
+ IN EFI_SYSTEM_CONTEXT SystemContext
+ );
+
+/**
+ Restore CPU exception context when handling EFI_VECTOR_HANDOFF_HOOK_AFTER case.
+
+ @param[in] ExceptionType Exception type.
+ @param[in] SystemContext Pointer to EFI_SYSTEM_CONTEXT.
+
+**/
+VOID
+ArchRestoreExceptionContext (
+ IN UINTN ExceptionType,
+ IN EFI_SYSTEM_CONTEXT SystemContext
+ );
+
+/**
+ Fix up the vector number in the vector code.
+
+ @param[in] VectorBase Base address of the vector handler.
+ @param[in] VectorNum Index of vector.
+
+**/
+VOID
+EFIAPI
+AsmVectorNumFixup (
+ IN VOID *VectorBase,
+ IN UINT8 VectorNum
+ );
+
+/**
+ Read and save reserved vector information
+
+ @param[in] VectorInfo Pointer to reserved vector list.
+ @param[out] ReservedVector Pointer to reserved vector data buffer.
+ @param[in] VectorCount Vector number to be updated.
+
+ @return EFI_SUCCESS Read and save vector info successfully.
+ @retval EFI_INVALID_PARAMETER VectorInfo includes the invalid content if VectorInfo is not NULL.
+
+**/
+EFI_STATUS
+ReadAndVerifyVectorInfo (
+ IN EFI_VECTOR_HANDOFF_INFO *VectorInfo,
+ OUT RESERVED_VECTORS_DATA *ReservedVector,
+ IN UINTN VectorCount
+ );
+
#endif
+
diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeSmmCpuExceptionHandlerLib.inf b/UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeCpuExceptionHandlerLib.inf
index 9f0f2d9be..388708676 100644
--- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeSmmCpuExceptionHandlerLib.inf
+++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeCpuExceptionHandlerLib.inf
@@ -1,9 +1,9 @@
## @file
-# Component description file for DXE/SMM CPU Exception Handler Library instance.
+# Component description file for DXE CPU Exception Handler Library instance.
#
-# This library instance supports DXE SMM module only.
+# This library instance supports DXE module only.
#
-# Copyright (c) 2012, Intel Corporation. All rights reserved.<BR>
+# Copyright (c) 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
@@ -16,11 +16,11 @@
[Defines]
INF_VERSION = 0x00010005
- BASE_NAME = DxeSmmCpuExceptionHandlerLib
- FILE_GUID = EC629480-BD36-4e8e-8AB2-D28BF0D45864
+ BASE_NAME = DxeCpuExceptionHandlerLib
+ FILE_GUID = B6E9835A-EDCF-4748-98A8-27D3C722E02D
MODULE_TYPE = DXE_DRIVER
VERSION_STRING = 1.0
- LIBRARY_CLASS = CpuExceptionHandlerLib|DXE_CORE DXE_DRIVER DXE_SMM_DRIVER UEFI_APPLICATION
+ LIBRARY_CLASS = CpuExceptionHandlerLib|DXE_CORE DXE_DRIVER UEFI_APPLICATION
#
# The following information is for reference only and not required by the build tools.
@@ -32,16 +32,19 @@
Ia32/ExceptionHandlerAsm.asm |MSFT
Ia32/ExceptionHandlerAsm.S |GCC
Ia32/ArchExceptionHandler.c
+ Ia32/ArchInterruptDefs.h
[Sources.X64]
X64/ExceptionHandlerAsm.asm |MSFT
X64/ExceptionHandlerAsm.S |GCC
X64/ArchExceptionHandler.c
+ X64/ArchInterruptDefs.h
[Sources.common]
CpuExceptionCommon.h
CpuExceptionCommon.c
DxeSmmCpuException.c
+ DxeException.c
[Packages]
MdePkg/MdePkg.dec
@@ -55,3 +58,8 @@
SynchronizationLib
LocalApicLib
PeCoffGetEntryPointLib
+ MemoryAllocationLib
+ DebugLib
+
+[Ppis]
+ gEfiVectorHandoffInfoPpiGuid
diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeException.c b/UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeException.c
new file mode 100644
index 000000000..b4b844cde
--- /dev/null
+++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeException.c
@@ -0,0 +1,170 @@
+/** @file
+ CPU exception handler library implemenation for DXE modules.
+
+ Copyright (c) 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 <PiDxe.h>
+#include "CpuExceptionCommon.h"
+#include <Library/DebugLib.h>
+#include <Library/MemoryAllocationLib.h>
+
+CONST UINTN mDoFarReturnFlag = 0;
+
+extern SPIN_LOCK mDisplayMessageSpinLock;
+extern EFI_CPU_INTERRUPT_HANDLER *mExternalInterruptHandler;
+
+/**
+ Initializes all CPU exceptions entries and provides the default exception handlers.
+
+ Caller should try to get an array of interrupt and/or exception vectors that are in use and need to
+ persist by EFI_VECTOR_HANDOFF_INFO defined in PI 1.3 specification.
+ If caller cannot get reserved vector list or it does not exists, set VectorInfo to NULL.
+ If VectorInfo is not NULL, the exception vectors will be initialized per vector attribute accordingly.
+
+ @param[in] VectorInfo Pointer to reserved vector list.
+
+ @retval EFI_SUCCESS CPU Exception Entries have been successfully initialized
+ with default exception handlers.
+ @retval EFI_INVALID_PARAMETER VectorInfo includes the invalid content if VectorInfo is not NULL.
+ @retval EFI_UNSUPPORTED This function is not supported.
+
+**/
+EFI_STATUS
+EFIAPI
+InitializeCpuExceptionHandlers (
+ IN EFI_VECTOR_HANDOFF_INFO *VectorInfo OPTIONAL
+ )
+{
+ return InitializeCpuExceptionHandlersWorker (VectorInfo);
+}
+
+/**
+ Initializes all CPU interrupt/exceptions entries and provides the default interrupt/exception handlers.
+
+ Caller should try to get an array of interrupt and/or exception vectors that are in use and need to
+ persist by EFI_VECTOR_HANDOFF_INFO defined in PI 1.3 specification.
+ If caller cannot get reserved vector list or it does not exists, set VectorInfo to NULL.
+ If VectorInfo is not NULL, the exception vectors will be initialized per vector attribute accordingly.
+
+ @param[in] VectorInfo Pointer to reserved vector list.
+
+ @retval EFI_SUCCESS All CPU interrupt/exception entries have been successfully initialized
+ with default interrupt/exception handlers.
+ @retval EFI_INVALID_PARAMETER VectorInfo includes the invalid content if VectorInfo is not NULL.
+ @retval EFI_UNSUPPORTED This function is not supported.
+
+**/
+EFI_STATUS
+EFIAPI
+InitializeCpuInterruptHandlers (
+ IN EFI_VECTOR_HANDOFF_INFO *VectorInfo OPTIONAL
+ )
+{
+ EFI_STATUS Status;
+ IA32_IDT_GATE_DESCRIPTOR *IdtTable;
+ IA32_DESCRIPTOR IdtDescriptor;
+ UINTN IdtEntryCount;
+ EXCEPTION_HANDLER_TEMPLATE_MAP TemplateMap;
+ UINTN Index;
+ UINTN InterruptEntry;
+ UINT8 *InterruptEntryCode;
+
+ mReservedVectors = AllocatePool (sizeof (RESERVED_VECTORS_DATA) * CPU_INTERRUPT_NUM);
+ ASSERT (mReservedVectors != NULL);
+ SetMem ((VOID *) mReservedVectors, sizeof (RESERVED_VECTORS_DATA) * CPU_INTERRUPT_NUM, 0xff);
+ if (VectorInfo != NULL) {
+ Status = ReadAndVerifyVectorInfo (VectorInfo, mReservedVectors, CPU_INTERRUPT_NUM);
+ if (EFI_ERROR (Status)) {
+ FreePool (mReservedVectors);
+ return EFI_INVALID_PARAMETER;
+ }
+ }
+ InitializeSpinLock (&mDisplayMessageSpinLock);
+ mExternalInterruptHandler = AllocateZeroPool (sizeof (EFI_CPU_INTERRUPT_HANDLER) * CPU_INTERRUPT_NUM);
+ ASSERT (mExternalInterruptHandler != NULL);
+
+ //
+ // Read IDT descriptor and calculate IDT size
+ //
+ AsmReadIdtr (&IdtDescriptor);
+ IdtEntryCount = (IdtDescriptor.Limit + 1) / sizeof (IA32_IDT_GATE_DESCRIPTOR);
+ if (IdtEntryCount > CPU_INTERRUPT_NUM) {
+ IdtEntryCount = CPU_INTERRUPT_NUM;
+ }
+ //
+ // Create Interrupt Descriptor Table and Copy the old IDT table in
+ //
+ IdtTable = AllocateZeroPool (sizeof (IA32_IDT_GATE_DESCRIPTOR) * CPU_INTERRUPT_NUM);
+ ASSERT (IdtTable != NULL);
+ CopyMem (IdtTable, (VOID *)IdtDescriptor.Base, sizeof (IA32_IDT_GATE_DESCRIPTOR) * IdtEntryCount);
+
+ AsmGetTemplateAddressMap (&TemplateMap);
+ ASSERT (TemplateMap.ExceptionStubHeaderSize <= HOOKAFTER_STUB_SIZE);
+ InterruptEntryCode = AllocatePool (TemplateMap.ExceptionStubHeaderSize * CPU_INTERRUPT_NUM);
+ ASSERT (InterruptEntryCode != NULL);
+
+ InterruptEntry = (UINTN) InterruptEntryCode;
+ for (Index = 0; Index < CPU_INTERRUPT_NUM; Index ++) {
+ CopyMem (
+ (VOID *) InterruptEntry,
+ (VOID *) TemplateMap.ExceptionStart,
+ TemplateMap.ExceptionStubHeaderSize
+ );
+ AsmVectorNumFixup ((VOID *) InterruptEntry, (UINT8) Index);
+ InterruptEntry += TemplateMap.ExceptionStubHeaderSize;
+ }
+
+ TemplateMap.ExceptionStart = (UINTN) InterruptEntryCode;
+ UpdateIdtTable (IdtTable, &TemplateMap, CPU_INTERRUPT_NUM);
+
+ //
+ // Load Interrupt Descriptor Table
+ //
+ IdtDescriptor.Base = (UINTN) IdtTable;
+ IdtDescriptor.Limit = (UINT16) (sizeof (IA32_IDT_GATE_DESCRIPTOR) * CPU_INTERRUPT_NUM - 1);
+ AsmWriteIdtr ((IA32_DESCRIPTOR *) &IdtDescriptor);
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Registers a function to be called from the processor interrupt handler.
+
+ This function registers and enables the handler specified by InterruptHandler for a processor
+ interrupt or exception type specified by InterruptType. If InterruptHandler is NULL, then the
+ handler for the processor interrupt or exception type specified by InterruptType is uninstalled.
+ The installed handler is called once for each processor interrupt or exception.
+ NOTE: This function should be invoked after InitializeCpuExceptionHandlers() or
+ InitializeCpuInterruptHandlers() invoked, otherwise EFI_UNSUPPORTED returned.
+
+ @param[in] InterruptType Defines which interrupt or exception to hook.
+ @param[in] InterruptHandler A pointer to a function of type EFI_CPU_INTERRUPT_HANDLER that is called
+ when a processor interrupt occurs. If this parameter is NULL, then the handler
+ will be uninstalled.
+
+ @retval EFI_SUCCESS The handler for the processor interrupt was successfully installed or uninstalled.
+ @retval EFI_ALREADY_STARTED InterruptHandler is not NULL, and a handler for InterruptType was
+ previously installed.
+ @retval EFI_INVALID_PARAMETER InterruptHandler is NULL, and a handler for InterruptType was not
+ previously installed.
+ @retval EFI_UNSUPPORTED The interrupt specified by InterruptType is not supported,
+ or this function is not supported.
+*/
+EFI_STATUS
+EFIAPI
+RegisterCpuInterruptHandler (
+ IN EFI_EXCEPTION_TYPE InterruptType,
+ IN EFI_CPU_INTERRUPT_HANDLER InterruptHandler
+ )
+{
+ return RegisterCpuInterruptHandlerWorker (InterruptType, InterruptHandler);
+}
diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeSmmCpuException.c b/UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeSmmCpuException.c
index 682def43b..aed5cf812 100644
--- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeSmmCpuException.c
+++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeSmmCpuException.c
@@ -1,7 +1,7 @@
/** @file
- CPU Exception Library provides DXE/SMM CPU exception handler.
+ CPU Exception Library provides DXE/SMM CPU common exception handler.
-Copyright (c) 2012, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2012 - 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 that accompanies this distribution.
The full text of the license may be found at
@@ -12,10 +12,8 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
-#include <PiDxe.h>
-
#include "CpuExceptionCommon.h"
-#include <Library/SynchronizationLib.h>
+#include <Library/DebugLib.h>
//
// Spinlock for CPU information display
@@ -27,6 +25,11 @@ SPIN_LOCK mDisplayMessageSpinLock;
//
CONST UINTN mImageAlignSize = SIZE_4KB;
+RESERVED_VECTORS_DATA mReservedVectorsData[CPU_EXCEPTION_NUM];
+EFI_CPU_INTERRUPT_HANDLER mExternalInterruptHandlerTable[CPU_EXCEPTION_NUM];
+EFI_CPU_INTERRUPT_HANDLER *mExternalInterruptHandler = NULL;
+UINTN mEnabledInterruptNum = 0;
+
/**
Common exception handler.
@@ -36,49 +39,250 @@ CONST UINTN mImageAlignSize = SIZE_4KB;
VOID
EFIAPI
CommonExceptionHandler (
- IN EFI_EXCEPTION_TYPE ExceptionType,
- IN EFI_SYSTEM_CONTEXT SystemContext
+ IN EFI_EXCEPTION_TYPE ExceptionType,
+ IN EFI_SYSTEM_CONTEXT SystemContext
)
{
- //
- // Get Spinlock to display CPU information
- //
- while (!AcquireSpinLockOrFail (&mDisplayMessageSpinLock)) {
- CpuPause ();
+ EXCEPTION_HANDLER_CONTEXT *ExceptionHandlerContext;
+
+ ExceptionHandlerContext = (EXCEPTION_HANDLER_CONTEXT *) (UINTN) (SystemContext.SystemContextIa32);
+
+ switch (mReservedVectors[ExceptionType].Attribute) {
+ case EFI_VECTOR_HANDOFF_HOOK_BEFORE:
+ //
+ // Need to jmp to old IDT handler after this exception handler
+ //
+ ExceptionHandlerContext->ExceptionDataFlag = (mErrorCodeFlag & (1 << ExceptionType)) ? TRUE : FALSE;
+ ExceptionHandlerContext->OldIdtHandler = mReservedVectors[ExceptionType].ExceptonHandler;
+ break;
+ case EFI_VECTOR_HANDOFF_HOOK_AFTER:
+ while (TRUE) {
+ //
+ // If if anyone has gotten SPIN_LOCK for owner running hook after
+ //
+ if (AcquireSpinLockOrFail (&mReservedVectors[ExceptionType].SpinLock)) {
+ //
+ // Need to execute old IDT handler before running this exception handler
+ //
+ mReservedVectors[ExceptionType].ApicId = GetApicId ();
+ ArchSaveExceptionContext (ExceptionType, SystemContext);
+ ExceptionHandlerContext->ExceptionDataFlag = (mErrorCodeFlag & (1 << ExceptionType)) ? TRUE : FALSE;
+ ExceptionHandlerContext->OldIdtHandler = mReservedVectors[ExceptionType].ExceptonHandler;
+ return;
+ }
+ //
+ // If failed to acquire SPIN_LOCK, check if it was locked by processor itself
+ //
+ if (mReservedVectors[ExceptionType].ApicId == GetApicId ()) {
+ //
+ // Old IDT handler has been executed, then retore CPU exception content to
+ // run new exception handler.
+ //
+ ArchRestoreExceptionContext (ExceptionType, SystemContext);
+ //
+ // Rlease spin lock for ApicId
+ //
+ ReleaseSpinLock (&mReservedVectors[ExceptionType].SpinLock);
+ break;
+ }
+ CpuPause ();
+ }
+ break;
+ case 0xffffffff:
+ break;
+ default:
+ //
+ // It should never reach here
+ //
+ CpuDeadLoop ();
+ break;
}
+
+ if (mExternalInterruptHandler[ExceptionType] != NULL) {
+ (mExternalInterruptHandler[ExceptionType]) (ExceptionType, SystemContext);
+ } else {
+ //
+ // Get Spinlock to display CPU information
+ //
+ while (!AcquireSpinLockOrFail (&mDisplayMessageSpinLock)) {
+ CpuPause ();
+ }
+ //
+ // Display ExceptionType, CPU information and Image information
+ //
+ DumpCpuContent (ExceptionType, SystemContext);
+ //
+ // Release Spinlock of output message
+ //
+ ReleaseSpinLock (&mDisplayMessageSpinLock);
+ //
+ // Enter a dead loop if needn't to execute old IDT handler further
+ //
+ if (mReservedVectors[ExceptionType].Attribute != EFI_VECTOR_HANDOFF_HOOK_BEFORE) {
+ CpuDeadLoop ();
+ }
+ }
+}
- //
- // Display ExceptionType, CPU information and Image information
- //
- DumpCpuContent (ExceptionType, SystemContext);
+/**
+ Internal worker function to update IDT entries accordling to vector attributes.
+
+ @param[in] IdtTable Pointer to IDT table.
+ @param[in] TemplateMap Pointer to a buffer where the address map is returned.
+ @param[in] IdtEntryCount IDT entries number to be updated.
+
+**/
+VOID
+UpdateIdtTable (
+ IN IA32_IDT_GATE_DESCRIPTOR *IdtTable,
+ IN EXCEPTION_HANDLER_TEMPLATE_MAP *TemplateMap,
+ IN UINTN IdtEntryCount
+ )
+{
+ UINT16 CodeSegment;
+ UINTN Index;
+ UINTN InterruptHandler;
//
- // Release Spinlock
+ // Use current CS as the segment selector of interrupt gate in IDT
//
- ReleaseSpinLock (&mDisplayMessageSpinLock);
+ CodeSegment = AsmReadCs ();
+ for (Index = 0; Index < IdtEntryCount; Index ++) {
+ IdtTable[Index].Bits.Selector = CodeSegment;
+ //
+ // Check reserved vectors attributes
+ //
+ switch (mReservedVectors[Index].Attribute) {
+ case EFI_VECTOR_HANDOFF_DO_NOT_HOOK:
+ //
+ // Keep original IDT entry
+ //
+ continue;
+ case EFI_VECTOR_HANDOFF_HOOK_AFTER:
+ InitializeSpinLock (&mReservedVectors[Index].SpinLock);
+ CopyMem (
+ (VOID *) mReservedVectors[Index].HookAfterStubHeaderCode,
+ (VOID *) TemplateMap->HookAfterStubHeaderStart,
+ TemplateMap->ExceptionStubHeaderSize
+ );
+ AsmVectorNumFixup ((VOID *) mReservedVectors[Index].HookAfterStubHeaderCode, (UINT8) Index);
+ //
+ // Go on the following code
+ //
+ case EFI_VECTOR_HANDOFF_HOOK_BEFORE:
+ //
+ // Save original IDT handler address
+ //
+ mReservedVectors[Index].ExceptonHandler = ArchGetIdtHandler (&IdtTable[Index]);
+ //
+ // Go on the following code
+ //
+ default:
+ //
+ // Update new IDT entry
+ //
+ InterruptHandler = TemplateMap->ExceptionStart + Index * TemplateMap->ExceptionStubHeaderSize;
+ ArchUpdateIdtEntry (&IdtTable[Index], InterruptHandler);
+ break;
+ }
+ }
+
//
- // Enter a dead loop.
+ // Save Interrupt number to global variable used for RegisterCpuInterruptHandler ()
//
- CpuDeadLoop ();
+ mEnabledInterruptNum = IdtEntryCount;
}
/**
- Setup CPU exception handlers.
+ Internal worker function to initialize exception handler.
- This API will setups the CPU exception handler to display CPU contents and run into
- CpuDeadLoop().
- Note: Before invoking this API, caller must allocate memory for IDT table and load
- IDTR by AsmWriteIdtr().
+ @param[in] VectorInfo Pointer to reserved vector list.
+ @retval EFI_SUCCESS CPU Exception Entries have been successfully initialized
+ with default exception handlers.
+ @retval EFI_INVALID_PARAMETER VectorInfo includes the invalid content if VectorInfo is not NULL.
+ @retval EFI_UNSUPPORTED This function is not supported.
+
**/
-VOID
-EFIAPI
-SetupCpuExceptionHandlers (
- IN VOID
+EFI_STATUS
+InitializeCpuExceptionHandlersWorker (
+ IN EFI_VECTOR_HANDOFF_INFO *VectorInfo OPTIONAL
)
{
+ EFI_STATUS Status;
+ IA32_DESCRIPTOR IdtDescriptor;
+ UINTN IdtEntryCount;
+ EXCEPTION_HANDLER_TEMPLATE_MAP TemplateMap;
+ IA32_IDT_GATE_DESCRIPTOR *IdtTable;
+
+ mReservedVectors = mReservedVectorsData;
+ SetMem ((VOID *) mReservedVectors, sizeof (RESERVED_VECTORS_DATA) * CPU_EXCEPTION_NUM, 0xff);
+ if (VectorInfo != NULL) {
+ Status = ReadAndVerifyVectorInfo (VectorInfo, mReservedVectors, CPU_EXCEPTION_NUM);
+ if (EFI_ERROR (Status)) {
+ return EFI_INVALID_PARAMETER;
+ }
+ }
InitializeSpinLock (&mDisplayMessageSpinLock);
- InternalSetupCpuExceptionHandlers ();
+
+ mExternalInterruptHandler = mExternalInterruptHandlerTable;
+ //
+ // Read IDT descriptor and calculate IDT size
+ //
+ AsmReadIdtr (&IdtDescriptor);
+ IdtEntryCount = (IdtDescriptor.Limit + 1) / sizeof (IA32_IDT_GATE_DESCRIPTOR);
+ if (IdtEntryCount > CPU_EXCEPTION_NUM) {
+ //
+ // CPU exeption library only setup CPU_EXCEPTION_NUM exception handler at most
+ //
+ IdtEntryCount = CPU_EXCEPTION_NUM;
+ }
+
+ IdtTable = (IA32_IDT_GATE_DESCRIPTOR *) IdtDescriptor.Base;
+ AsmGetTemplateAddressMap (&TemplateMap);
+ ASSERT (TemplateMap.ExceptionStubHeaderSize <= HOOKAFTER_STUB_SIZE);
+ UpdateIdtTable (IdtTable, &TemplateMap, IdtEntryCount);
+ mEnabledInterruptNum = IdtEntryCount;
+ return EFI_SUCCESS;
+}
+
+/**
+ Registers a function to be called from the processor interrupt handler.
+
+ @param[in] InterruptType Defines which interrupt or exception to hook.
+ @param[in] InterruptHandler A pointer to a function of type EFI_CPU_INTERRUPT_HANDLER that is called
+ when a processor interrupt occurs. If this parameter is NULL, then the handler
+ will be uninstalled.
+
+ @retval EFI_SUCCESS The handler for the processor interrupt was successfully installed or uninstalled.
+ @retval EFI_ALREADY_STARTED InterruptHandler is not NULL, and a handler for InterruptType was
+ previously installed.
+ @retval EFI_INVALID_PARAMETER InterruptHandler is NULL, and a handler for InterruptType was not
+ previously installed.
+ @retval EFI_UNSUPPORTED The interrupt specified by InterruptType is not supported,
+ or this function is not supported.
+*/
+EFI_STATUS
+RegisterCpuInterruptHandlerWorker (
+ IN EFI_EXCEPTION_TYPE InterruptType,
+ IN EFI_CPU_INTERRUPT_HANDLER InterruptHandler
+ )
+{
+ if (InterruptType < 0 || InterruptType > (EFI_EXCEPTION_TYPE)mEnabledInterruptNum ||
+ mReservedVectors[InterruptType].Attribute == EFI_VECTOR_HANDOFF_DO_NOT_HOOK) {
+ return EFI_UNSUPPORTED;
+ }
+
+ if (InterruptHandler == NULL && mExternalInterruptHandler[InterruptType] == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (InterruptHandler != NULL && mExternalInterruptHandler[InterruptType] != NULL) {
+ return EFI_ALREADY_STARTED;
+ }
+
+ mExternalInterruptHandler[InterruptType] = InterruptHandler;
+ return EFI_SUCCESS;
}
diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ArchExceptionHandler.c b/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ArchExceptionHandler.c
index a69f0d3d2..ba2cc6f22 100644
--- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ArchExceptionHandler.c
+++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ArchExceptionHandler.c
@@ -1,7 +1,7 @@
/** @file
IA32 CPU Exception Hanlder functons.
- Copyright (c) 2012, Intel Corporation. All rights reserved.<BR>
+ Copyright (c) 2012 - 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
@@ -15,49 +15,87 @@
#include "CpuExceptionCommon.h"
/**
- Internal function to setup CPU exception handlers.
+ Return address map of exception handler template so that C code can generate
+ exception tables.
+
+ @param IdtEntry Pointer to IDT entry to be updated.
+ @param InterruptHandler IDT handler value.
**/
VOID
-InternalSetupCpuExceptionHandlers (
- VOID
+ArchUpdateIdtEntry (
+ IN IA32_IDT_GATE_DESCRIPTOR *IdtEntry,
+ IN UINTN InterruptHandler
+ )
+{
+ IdtEntry->Bits.OffsetLow = (UINT16)(UINTN)InterruptHandler;
+ IdtEntry->Bits.OffsetHigh = (UINT16)((UINTN)InterruptHandler >> 16);
+ IdtEntry->Bits.GateType = IA32_IDT_GATE_TYPE_INTERRUPT_32;
+}
+
+/**
+ Read IDT handler value from IDT entry.
+
+ @param IdtEntry Pointer to IDT entry to be read.
+
+**/
+UINTN
+ArchGetIdtHandler (
+ IN IA32_IDT_GATE_DESCRIPTOR *IdtEntry
)
{
- IA32_DESCRIPTOR IdtDescriptor;
- UINTN IdtSize;
- EXCEPTION_HANDLER_TEMPLATE_MAP TemplateMap;
- UINT16 CodeSegment;
- IA32_IDT_GATE_DESCRIPTOR *IdtEntry;
- UINTN Index;
- UINTN InterruptHandler;;
+ return (UINTN)IdtEntry->Bits.OffsetLow + (((UINTN)IdtEntry->Bits.OffsetHigh) << 16);
+}
+
+/**
+ Save CPU exception context when handling EFI_VECTOR_HANDOFF_HOOK_AFTER case.
+ @param ExceptionType Exception type.
+ @param SystemContext Pointer to EFI_SYSTEM_CONTEXT.
+
+**/
+VOID
+ArchSaveExceptionContext (
+ IN UINTN ExceptionType,
+ IN EFI_SYSTEM_CONTEXT SystemContext
+ )
+{
+ IA32_EFLAGS32 Eflags;
//
- // Read IDT descriptor and calculate IDT size
+ // Save Exception context in global variable
//
- AsmReadIdtr (&IdtDescriptor);
- IdtSize = (IdtDescriptor.Limit + 1) / sizeof (IA32_IDT_GATE_DESCRIPTOR);
- if (IdtSize > CPU_EXCEPTION_NUM) {
- //
- // CPU exeption library only setup CPU_EXCEPTION_NUM exception handler at most
- //
- IdtSize = CPU_EXCEPTION_NUM;
- }
-
+ mReservedVectors[ExceptionType].OldFlags = SystemContext.SystemContextIa32->Eflags;
+ mReservedVectors[ExceptionType].OldCs = SystemContext.SystemContextIa32->Cs;
+ mReservedVectors[ExceptionType].OldIp = SystemContext.SystemContextIa32->Eip;
+ mReservedVectors[ExceptionType].ExceptionData = SystemContext.SystemContextIa32->ExceptionData;
+ //
+ // Clear IF flag to avoid old IDT handler enable interrupt by IRET
//
- // Use current CS as the segment selector of interrupt gate in IDT
+ Eflags.UintN = SystemContext.SystemContextIa32->Eflags;
+ Eflags.Bits.IF = 0;
+ SystemContext.SystemContextIa32->Eflags = Eflags.UintN;
//
- CodeSegment = AsmReadCs ();
- IdtEntry = (IA32_IDT_GATE_DESCRIPTOR *) IdtDescriptor.Base;
+ // Modify the EIP in stack, then old IDT handler will return to the stub code
+ //
+ SystemContext.SystemContextIa32->Eip = (UINTN) mReservedVectors[ExceptionType].HookAfterStubHeaderCode;
+}
- GetTemplateAddressMap (&TemplateMap);
+/**
+ Restore CPU exception context when handling EFI_VECTOR_HANDOFF_HOOK_AFTER case.
- for (Index = 0; Index < IdtSize; Index ++) {
- InterruptHandler = TemplateMap.ExceptionStart + Index * TemplateMap.ExceptionStubHeaderSize;
- IdtEntry[Index].Bits.OffsetLow = (UINT16)(UINTN)InterruptHandler;
- IdtEntry[Index].Bits.OffsetHigh = (UINT16)((UINTN)InterruptHandler >> 16);
- IdtEntry[Index].Bits.Selector = CodeSegment;
- IdtEntry[Index].Bits.GateType = IA32_IDT_GATE_TYPE_INTERRUPT_32;
- }
+ @param ExceptionType Exception type.
+ @param SystemContext Pointer to EFI_SYSTEM_CONTEXT.
+**/
+VOID
+ArchRestoreExceptionContext (
+ IN UINTN ExceptionType,
+ IN EFI_SYSTEM_CONTEXT SystemContext
+ )
+{
+ SystemContext.SystemContextIa32->Eflags = mReservedVectors[ExceptionType].OldFlags;
+ SystemContext.SystemContextIa32->Cs = mReservedVectors[ExceptionType].OldCs;
+ SystemContext.SystemContextIa32->Eip = mReservedVectors[ExceptionType].OldIp;
+ SystemContext.SystemContextIa32->ExceptionData = mReservedVectors[ExceptionType].ExceptionData;
}
/**
@@ -68,7 +106,7 @@ InternalSetupCpuExceptionHandlers (
**/
VOID
DumpCpuContent (
- IN UINTN ExceptionType,
+ IN EFI_EXCEPTION_TYPE ExceptionType,
IN EFI_SYSTEM_CONTEXT SystemContext
)
{
diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ArchInterruptDefs.h b/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ArchInterruptDefs.h
new file mode 100644
index 000000000..a8d3556a8
--- /dev/null
+++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ArchInterruptDefs.h
@@ -0,0 +1,44 @@
+/** @file
+ Ia32 arch definition for CPU Exception Handler Library.
+
+ Copyright (c) 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 _ARCH_CPU_INTERRUPT_DEFS_H_
+#define _ARCH_CPU_INTERRUPT_DEFS_H_
+
+typedef struct {
+ EFI_SYSTEM_CONTEXT_IA32 SystemContext;
+ BOOLEAN ExceptionDataFlag;
+ UINTN OldIdtHandler;
+} EXCEPTION_HANDLER_CONTEXT;
+
+//
+// Register Structure Definitions
+//
+typedef struct {
+ EFI_STATUS_CODE_DATA Header;
+ EFI_SYSTEM_CONTEXT_IA32 SystemContext;
+} CPU_STATUS_CODE_TEMPLATE;
+
+typedef struct {
+ SPIN_LOCK SpinLock;
+ UINT32 ApicId;
+ UINT32 Attribute;
+ UINTN ExceptonHandler;
+ UINTN OldFlags;
+ UINTN OldCs;
+ UINTN OldIp;
+ UINTN ExceptionData;
+ UINT8 HookAfterStubHeaderCode[HOOKAFTER_STUB_SIZE];
+} RESERVED_VECTORS_DATA;
+
+#endif
diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ExceptionHandlerAsm.S b/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ExceptionHandlerAsm.S
index b9e881ac5..387b4b26b 100644
--- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ExceptionHandlerAsm.S
+++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ExceptionHandlerAsm.S
@@ -1,6 +1,6 @@
#------------------------------------------------------------------------------
#*
-#* Copyright (c) 2012, Intel Corporation. All rights reserved.<BR>
+#* Copyright (c) 2012 - 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
@@ -18,16 +18,15 @@
#------------------------------------------------------------------------------
-
-
-
#.MMX
#.XMM
ASM_GLOBAL ASM_PFX(CommonExceptionHandler)
ASM_GLOBAL ASM_PFX(CommonInterruptEntry)
+ASM_GLOBAL ASM_PFX(HookAfterStubHeaderEnd)
-#EXTRN ASM_PFX(mErrorCodeFlag):DWORD # Error code flags for exceptions
+#EXTRN ASM_PFX(mErrorCodeFlag):DWORD # Error code flags for exceptions
+#EXTRN ASM_PFX(mDoFarReturnFlag):DWORD # Do far return flag
.text
@@ -35,101 +34,250 @@ ASM_GLOBAL ASM_PFX(CommonInterruptEntry)
# exception handler stub table
#
Exception0Handle:
- pushl $0
- jmp ASM_PFX(CommonInterruptEntry)
+ .byte 0x6a # push #VectorNum
+ .byte 0
+ pushl %eax
+ .byte 0xB8
+ .long ASM_PFX(CommonInterruptEntry)
+ jmp *%eax
Exception1Handle:
- pushl $1
- jmp ASM_PFX(CommonInterruptEntry)
+ .byte 0x6a # push #VectorNum
+ .byte 1
+ pushl %eax
+ .byte 0xB8
+ .long ASM_PFX(CommonInterruptEntry)
+ jmp *%eax
Exception2Handle:
- pushl $2
- jmp ASM_PFX(CommonInterruptEntry)
+ .byte 0x6a # push #VectorNum
+ .byte 2
+ pushl %eax
+ .byte 0xB8
+ .long ASM_PFX(CommonInterruptEntry)
+ jmp *%eax
Exception3Handle:
- pushl $3
- jmp ASM_PFX(CommonInterruptEntry)
+ .byte 0x6a # push #VectorNum
+ .byte 3
+ pushl %eax
+ .byte 0xB8
+ .long ASM_PFX(CommonInterruptEntry)
+ jmp *%eax
Exception4Handle:
- pushl $4
- jmp ASM_PFX(CommonInterruptEntry)
+ .byte 0x6a # push #VectorNum
+ .byte 4
+ pushl %eax
+ .byte 0xB8
+ .long ASM_PFX(CommonInterruptEntry)
+ jmp *%eax
Exception5Handle:
- pushl $5
- jmp ASM_PFX(CommonInterruptEntry)
+ .byte 0x6a # push #VectorNum
+ .byte 5
+ pushl %eax
+ .byte 0xB8
+ .long ASM_PFX(CommonInterruptEntry)
+ jmp *%eax
Exception6Handle:
- pushl $6
- jmp ASM_PFX(CommonInterruptEntry)
+ .byte 0x6a # push #VectorNum
+ .byte 6
+ pushl %eax
+ .byte 0xB8
+ .long ASM_PFX(CommonInterruptEntry)
+ jmp *%eax
Exception7Handle:
- pushl $7
- jmp ASM_PFX(CommonInterruptEntry)
+ .byte 0x6a # push #VectorNum
+ .byte 7
+ pushl %eax
+ .byte 0xB8
+ .long ASM_PFX(CommonInterruptEntry)
+ jmp *%eax
Exception8Handle:
- pushl $8
- jmp ASM_PFX(CommonInterruptEntry)
+ .byte 0x6a # push #VectorNum
+ .byte 8
+ pushl %eax
+ .byte 0xB8
+ .long ASM_PFX(CommonInterruptEntry)
+ jmp *%eax
Exception9Handle:
- pushl $9
- jmp ASM_PFX(CommonInterruptEntry)
+ .byte 0x6a # push #VectorNum
+ .byte 9
+ pushl %eax
+ .byte 0xB8
+ .long ASM_PFX(CommonInterruptEntry)
+ jmp *%eax
Exception10Handle:
- pushl $10
- jmp ASM_PFX(CommonInterruptEntry)
+ .byte 0x6a # push #VectorNum
+ .byte 10
+ pushl %eax
+ .byte 0xB8
+ .long ASM_PFX(CommonInterruptEntry)
+ jmp *%eax
Exception11Handle:
- pushl $11
- jmp ASM_PFX(CommonInterruptEntry)
+ .byte 0x6a # push #VectorNum
+ .byte 11
+ pushl %eax
+ .byte 0xB8
+ .long ASM_PFX(CommonInterruptEntry)
+ jmp *%eax
Exception12Handle:
- pushl $12
- jmp ASM_PFX(CommonInterruptEntry)
+ .byte 0x6a # push #VectorNum
+ .byte 12
+ pushl %eax
+ .byte 0xB8
+ .long ASM_PFX(CommonInterruptEntry)
+ jmp *%eax
Exception13Handle:
- pushl $13
- jmp ASM_PFX(CommonInterruptEntry)
+ .byte 0x6a # push #VectorNum
+ .byte 13
+ pushl %eax
+ .byte 0xB8
+ .long ASM_PFX(CommonInterruptEntry)
+ jmp *%eax
Exception14Handle:
- pushl $14
- jmp ASM_PFX(CommonInterruptEntry)
+ .byte 0x6a # push #VectorNum
+ .byte 14
+ pushl %eax
+ .byte 0xB8
+ .long ASM_PFX(CommonInterruptEntry)
+ jmp *%eax
Exception15Handle:
- pushl $15
- jmp ASM_PFX(CommonInterruptEntry)
+ .byte 0x6a # push #VectorNum
+ .byte 15
+ pushl %eax
+ .byte 0xB8
+ .long ASM_PFX(CommonInterruptEntry)
+ jmp *%eax
Exception16Handle:
- pushl $16
- jmp ASM_PFX(CommonInterruptEntry)
+ .byte 0x6a # push #VectorNum
+ .byte 16
+ pushl %eax
+ .byte 0xB8
+ .long ASM_PFX(CommonInterruptEntry)
+ jmp *%eax
Exception17Handle:
- pushl $17
- jmp ASM_PFX(CommonInterruptEntry)
+ .byte 0x6a # push #VectorNum
+ .byte 17
+ pushl %eax
+ .byte 0xB8
+ .long ASM_PFX(CommonInterruptEntry)
+ jmp *%eax
Exception18Handle:
- pushl $18
- jmp ASM_PFX(CommonInterruptEntry)
+ .byte 0x6a # push #VectorNum
+ .byte 18
+ pushl %eax
+ .byte 0xB8
+ .long ASM_PFX(CommonInterruptEntry)
+ jmp *%eax
Exception19Handle:
- pushl $19
- jmp ASM_PFX(CommonInterruptEntry)
+ .byte 0x6a # push #VectorNum
+ .byte 19
+ pushl %eax
+ .byte 0xB8
+ .long ASM_PFX(CommonInterruptEntry)
+ jmp *%eax
Exception20Handle:
- pushl $20
- jmp ASM_PFX(CommonInterruptEntry)
+ .byte 0x6a # push #VectorNum
+ .byte 20
+ pushl %eax
+ .byte 0xB8
+ .long ASM_PFX(CommonInterruptEntry)
+ jmp *%eax
Exception21Handle:
- pushl $21
- jmp ASM_PFX(CommonInterruptEntry)
+ .byte 0x6a # push #VectorNum
+ .byte 21
+ pushl %eax
+ .byte 0xB8
+ .long ASM_PFX(CommonInterruptEntry)
+ jmp *%eax
Exception22Handle:
- pushl $22
- jmp ASM_PFX(CommonInterruptEntry)
+ .byte 0x6a # push #VectorNum
+ .byte 22
+ pushl %eax
+ .byte 0xB8
+ .long ASM_PFX(CommonInterruptEntry)
+ jmp *%eax
Exception23Handle:
- pushl $23
- jmp ASM_PFX(CommonInterruptEntry)
+ .byte 0x6a # push #VectorNum
+ .byte 23
+ pushl %eax
+ .byte 0xB8
+ .long ASM_PFX(CommonInterruptEntry)
+ jmp *%eax
Exception24Handle:
- pushl $24
- jmp ASM_PFX(CommonInterruptEntry)
+ .byte 0x6a # push #VectorNum
+ .byte 24
+ pushl %eax
+ .byte 0xB8
+ .long ASM_PFX(CommonInterruptEntry)
+ jmp *%eax
Exception25Handle:
- pushl $25
- jmp ASM_PFX(CommonInterruptEntry)
+ .byte 0x6a # push #VectorNum
+ .byte 25
+ pushl %eax
+ .byte 0xB8
+ .long ASM_PFX(CommonInterruptEntry)
+ jmp *%eax
Exception26Handle:
- pushl $26
- jmp ASM_PFX(CommonInterruptEntry)
+ .byte 0x6a # push #VectorNum
+ .byte 26
+ pushl %eax
+ .byte 0xB8
+ .long ASM_PFX(CommonInterruptEntry)
+ jmp *%eax
Exception27Handle:
- pushl $27
- jmp ASM_PFX(CommonInterruptEntry)
+ .byte 0x6a # push #VectorNum
+ .byte 27
+ pushl %eax
+ .byte 0xB8
+ .long ASM_PFX(CommonInterruptEntry)
+ jmp *%eax
Exception28Handle:
- pushl $28
- jmp ASM_PFX(CommonInterruptEntry)
+ .byte 0x6a # push #VectorNum
+ .byte 28
+ pushl %eax
+ .byte 0xB8
+ .long ASM_PFX(CommonInterruptEntry)
+ jmp *%eax
Exception29Handle:
- pushl $29
- jmp ASM_PFX(CommonInterruptEntry)
+ .byte 0x6a # push #VectorNum
+ .byte 29
+ pushl %eax
+ .byte 0xB8
+ .long ASM_PFX(CommonInterruptEntry)
+ jmp *%eax
Exception30Handle:
- pushl $30
- jmp ASM_PFX(CommonInterruptEntry)
+ .byte 0x6a # push #VectorNum
+ .byte 30
+ pushl %eax
+ .byte 0xB8
+ .long ASM_PFX(CommonInterruptEntry)
+ jmp *%eax
Exception31Handle:
- pushl $31
- jmp ASM_PFX(CommonInterruptEntry)
+ .byte 0x6a # push #VectorNum
+ .byte 31
+ pushl %eax
+ .byte 0xB8
+ .long ASM_PFX(CommonInterruptEntry)
+ jmp *%eax
+
+HookAfterStubBegin:
+ .byte 0x6a # push
+VectorNum:
+ .byte 0 # 0 will be fixed
+ pushl %eax
+ .byte 0xB8 # movl ASM_PFX(HookAfterStubHeaderEnd), %eax
+ .long ASM_PFX(HookAfterStubHeaderEnd)
+ jmp *%eax
+ASM_GLOBAL ASM_PFX(HookAfterStubHeaderEnd)
+ASM_PFX(HookAfterStubHeaderEnd):
+ popl %eax
+ subl $8, %esp # reserve room for filling exception data later
+ pushl 8(%esp)
+ xchgl (%esp), %ecx # get vector number
+ bt %ecx, ASM_PFX(mErrorCodeFlag)
+ jnc NoErrorData
+ pushl (%esp) # addition push if exception data needed
+NoErrorData:
+ xchg (%esp), %ecx # restore ecx
+ pushl %eax
#---------------------------------------;
# CommonInterruptEntry ;
@@ -139,19 +287,17 @@ Exception31Handle:
ASM_GLOBAL ASM_PFX(CommonInterruptEntry)
ASM_PFX(CommonInterruptEntry):
cli
+ popl %eax
#
# All interrupt handlers are invoked through interrupt gates, so
# IF flag automatically cleared at the entry point
#
#
- # Calculate vector number
- #
- # Get the return address of call, actually, it is the
- # address of vector number.
+ # Get vector number from top of stack
#
xchgl (%esp), %ecx
- andl $0x0FFFF, %ecx
+ andl $0x0FF, %ecx # Vector number should be less than 256
cmpl $32, %ecx # Intel reserved vector for exceptions?
jae NoErrorCode
bt %ecx, ASM_PFX(mErrorCodeFlag)
@@ -241,6 +387,10 @@ ErrorCodeAndVectorOnStack:
andl $0x0fffffff0, %esp
subl $12, %esp
+ subl $8, %esp
+ pushl $0 # check EXCEPTION_HANDLER_CONTEXT.OldIdtHandler
+ pushl $0 # check EXCEPTION_HANDLER_CONTEXT.ExceptionDataFlag
+
#; UINT32 Edi, Esi, Ebp, Esp, Ebx, Edx, Ecx, Eax;
pushl %eax
pushl %ecx
@@ -405,18 +555,41 @@ ErrorCodeAndVectorOnStack:
popl %ecx
popl %eax
+ popl -8(%ebp)
+ popl -4(%ebp)
movl %ebp, %esp
popl %ebp
addl $8, %esp
+ cmpl $0, -16(%esp) # check EXCEPTION_HANDLER_CONTEXT.OldIdtHandler
+ jz DoReturn
+ cmpl $1, -20(%esp) # check EXCEPTION_HANDLER_CONTEXT.ExceptionDataFlag
+ jz ErrorCode
+ jmp *-16(%esp)
+ErrorCode:
+ subl $4, %esp
+ jmp *-12(%esp)
+
+DoReturn:
+ cmpl $0, ASM_PFX(mDoFarReturnFlag)
+ jz DoIret
+ pushl 8(%esp) # save EFLAGS
+ addl $16, %esp
+ pushl -8(%esp) # save CS in new location
+ pushl -8(%esp) # save EIP in new location
+ pushl -8(%esp) # save EFLAGS in new location
+ popfl # restore EFLAGS
+ retf # far return
+
+DoIret:
iretl
#---------------------------------------;
-# _GetTemplateAddressMap ;
-#----------------------------------------------------------------------------;
+# _AsmGetTemplateAddressMap ;
+#---------------------------------------;
#
# Protocol prototype
-# GetTemplateAddressMap (
+# AsmGetTemplateAddressMap (
# EXCEPTION_HANDLER_TEMPLATE_MAP *AddressMap
# );
#
@@ -443,8 +616,8 @@ ErrorCodeAndVectorOnStack:
#-------------------------------------------------------------------------------------
# AsmGetAddressMap (&AddressMap);
#-------------------------------------------------------------------------------------
-ASM_GLOBAL ASM_PFX(GetTemplateAddressMap)
-ASM_PFX(GetTemplateAddressMap):
+ASM_GLOBAL ASM_PFX(AsmGetTemplateAddressMap)
+ASM_PFX(AsmGetTemplateAddressMap):
pushl %ebp
movl %esp,%ebp
@@ -453,8 +626,17 @@ ASM_PFX(GetTemplateAddressMap):
movl 0x8(%ebp), %ebx
movl $Exception0Handle, (%ebx)
movl $(Exception1Handle - Exception0Handle), 0x4(%ebx)
+ movl $(HookAfterStubBegin), 0x8(%ebx)
popal
popl %ebp
ret
-
+#-------------------------------------------------------------------------------------
+# AsmVectorNumFixup (*VectorBase, VectorNum);
+#-------------------------------------------------------------------------------------
+ASM_GLOBAL ASM_PFX(AsmVectorNumFixup)
+ASM_PFX(AsmVectorNumFixup):
+ movl 8(%esp), %eax
+ movl 4(%esp), %ecx
+ movb %al, (VectorNum - HookAfterStubBegin)(%ecx)
+ ret
diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ExceptionHandlerAsm.asm b/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ExceptionHandlerAsm.asm
index 869f18dfd..74d4e8904 100644
--- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ExceptionHandlerAsm.asm
+++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ExceptionHandlerAsm.asm
@@ -1,5 +1,5 @@
;------------------------------------------------------------------------------ ;
-; Copyright (c) 2012, Intel Corporation. All rights reserved.<BR>
+; Copyright (c) 2012 - 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
@@ -30,133 +30,77 @@ CommonExceptionHandler PROTO C
.data
-CommonEntryAddr DD CommonInterruptEntry
-
-EXTRN mErrorCodeFlag:DWORD ; Error code flags for exceptions
+EXTRN mErrorCodeFlag:DWORD ; Error code flags for exceptions
+EXTRN mDoFarReturnFlag:DWORD ; Do far return flag
.code
+ALIGN 8
+
;
; exception handler stub table
;
-Exception0Handle:
- push 0
- jmp dword ptr [CommonEntryAddr]
-Exception1Handle:
- push 1
- jmp dword ptr [CommonEntryAddr]
-Exception2Handle:
- push 2
- jmp dword ptr [CommonEntryAddr]
-Exception3Handle:
- push 3
- jmp dword ptr [CommonEntryAddr]
-Exception4Handle:
- push 4
- jmp dword ptr [CommonEntryAddr]
-Exception5Handle:
- push 5
- jmp dword ptr [CommonEntryAddr]
-Exception6Handle:
- push 6
- jmp dword ptr [CommonEntryAddr]
-Exception7Handle:
- push 7
- jmp dword ptr [CommonEntryAddr]
-Exception8Handle:
- push 8
- jmp dword ptr [CommonEntryAddr]
-Exception9Handle:
- push 9
- jmp dword ptr [CommonEntryAddr]
-Exception10Handle:
- push 10
- jmp dword ptr [CommonEntryAddr]
-Exception11Handle:
- push 11
- jmp dword ptr [CommonEntryAddr]
-Exception12Handle:
- push 12
- jmp dword ptr [CommonEntryAddr]
-Exception13Handle:
- push 13
- jmp dword ptr [CommonEntryAddr]
-Exception14Handle:
- push 14
- jmp dword ptr [CommonEntryAddr]
-Exception15Handle:
- push 15
- jmp dword ptr [CommonEntryAddr]
-Exception16Handle:
- push 16
- jmp dword ptr [CommonEntryAddr]
-Exception17Handle:
- push 17
- jmp dword ptr [CommonEntryAddr]
-Exception18Handle:
- push 18
- jmp dword ptr [CommonEntryAddr]
-Exception19Handle:
- push 19
- jmp dword ptr [CommonEntryAddr]
-Exception20Handle:
- push 20
- jmp dword ptr [CommonEntryAddr]
-Exception21Handle:
- push 21
- jmp dword ptr [CommonEntryAddr]
-Exception22Handle:
- push 22
- jmp dword ptr [CommonEntryAddr]
-Exception23Handle:
- push 23
- jmp dword ptr [CommonEntryAddr]
-Exception24Handle:
- push 24
- jmp dword ptr [CommonEntryAddr]
-Exception25Handle:
- push 25
- jmp dword ptr [CommonEntryAddr]
-Exception26Handle:
- push 26
- jmp dword ptr [CommonEntryAddr]
-Exception27Handle:
- push 27
- jmp dword ptr [CommonEntryAddr]
-Exception28Handle:
- push 28
- jmp dword ptr [CommonEntryAddr]
-Exception29Handle:
- push 29
- jmp dword ptr [CommonEntryAddr]
-Exception30Handle:
- push 30
- jmp dword ptr [CommonEntryAddr]
-Exception31Handle:
- push 31
- jmp dword ptr [CommonEntryAddr]
+AsmIdtVectorBegin:
+REPEAT 32
+ db 6ah ; push #VectorNum
+ db ($ - AsmIdtVectorBegin) / ((AsmIdtVectorEnd - AsmIdtVectorBegin) / 32) ; VectorNum
+ push eax
+ mov eax, CommonInterruptEntry
+ jmp eax
+ENDM
+AsmIdtVectorEnd:
+
+HookAfterStubBegin:
+ db 6ah ; push
+VectorNum:
+ db 0 ; 0 will be fixed
+ push eax
+ mov eax, HookAfterStubHeaderEnd
+ jmp eax
+HookAfterStubHeaderEnd:
+ pop eax
+ sub esp, 8 ; reserve room for filling exception data later
+ push [esp + 8]
+ xchg ecx, [esp] ; get vector number
+ bt mErrorCodeFlag, ecx
+ jnc @F
+ push [esp] ; addition push if exception data needed
+@@:
+ xchg ecx, [esp] ; restore ecx
+ push eax
;----------------------------------------------------------------------------;
; CommonInterruptEntry ;
;----------------------------------------------------------------------------;
; The follow algorithm is used for the common interrupt routine.
; Entry from each interrupt with a push eax and eax=interrupt number
-
+; Stack:
+; +---------------------+
+; + EFlags +
+; +---------------------+
+; + CS +
+; +---------------------+
+; + EIP +
+; +---------------------+
+; + Error Code +
+; +---------------------+
+; + Vector Number +
+; +---------------------+
+; + EBP +
+; +---------------------+ <-- EBP
CommonInterruptEntry PROC PUBLIC
cli
+ pop eax
;
; All interrupt handlers are invoked through interrupt gates, so
; IF flag automatically cleared at the entry point
;
;
- ; Calculate vector number
- ;
- ; Get the return address of call, actually, it is the
- ; address of vector number.
+ ; Get vector number from top of stack
;
xchg ecx, [esp]
- and ecx, 0FFFFh
+ and ecx, 0FFh ; Vector number should be less than 256
cmp ecx, 32 ; Intel reserved vector for exceptions?
jae NoErrorCode
bt mErrorCodeFlag, ecx
@@ -246,6 +190,10 @@ ErrorCodeAndVectorOnStack:
and esp, 0fffffff0h
sub esp, 12
+ sub esp, 8
+ push 0 ; clear EXCEPTION_HANDLER_CONTEXT.OldIdtHandler
+ push 0 ; clear EXCEPTION_HANDLER_CONTEXT.ExceptionDataFlag
+
;; UINT32 Edi, Esi, Ebp, Esp, Ebx, Edx, Ecx, Eax;
push eax
push ecx
@@ -411,19 +359,42 @@ ErrorCodeAndVectorOnStack:
pop ecx
pop eax
+ pop dword ptr [ebp - 8]
+ pop dword ptr [ebp - 4]
mov esp, ebp
pop ebp
add esp, 8
+ cmp dword ptr [esp - 16], 0 ; check EXCEPTION_HANDLER_CONTEXT.OldIdtHandler
+ jz DoReturn
+ cmp dword ptr [esp - 20], 1 ; check EXCEPTION_HANDLER_CONTEXT.ExceptionDataFlag
+ jz ErrorCode
+ jmp dword ptr [esp - 16]
+ErrorCode:
+ sub esp, 4
+ jmp dword ptr [esp - 12]
+
+DoReturn:
+ cmp mDoFarReturnFlag, 0 ; Check if need to do far return instead of IRET
+ jz DoIret
+ push [esp + 8] ; save EFLAGS
+ add esp, 16
+ push [esp - 8] ; save CS in new location
+ push [esp - 8] ; save EIP in new location
+ push [esp - 8] ; save EFLAGS in new location
+ popfd ; restore EFLAGS
+ retf ; far return
+
+DoIret:
iretd
CommonInterruptEntry ENDP
;---------------------------------------;
-; _GetTemplateAddressMap ;
+; _AsmGetTemplateAddressMap ;
;----------------------------------------------------------------------------;
;
; Protocol prototype
-; GetTemplateAddressMap (
+; AsmGetTemplateAddressMap (
; EXCEPTION_HANDLER_TEMPLATE_MAP *AddressMap
; );
;
@@ -447,18 +418,28 @@ CommonInterruptEntry ENDP
;
; Destroys: Nothing
;-----------------------------------------------------------------------------;
-GetTemplateAddressMap proc near public
+AsmGetTemplateAddressMap proc near public
push ebp ; C prolog
mov ebp, esp
pushad
- mov ebx, dword ptr [ebp+08h]
- mov dword ptr [ebx], Exception0Handle
- mov dword ptr [ebx+4h], Exception1Handle - Exception0Handle
+ mov ebx, dword ptr [ebp + 08h]
+ mov dword ptr [ebx], AsmIdtVectorBegin
+ mov dword ptr [ebx + 4h], (AsmIdtVectorEnd - AsmIdtVectorBegin) / 32
+ mov dword ptr [ebx + 8h], HookAfterStubBegin
popad
pop ebp
ret
-GetTemplateAddressMap ENDP
-
+AsmGetTemplateAddressMap ENDP
+
+;-------------------------------------------------------------------------------------
+; AsmVectorNumFixup (*VectorBase, VectorNum);
+;-------------------------------------------------------------------------------------
+AsmVectorNumFixup proc near public
+ mov eax, dword ptr [esp + 8]
+ mov ecx, [esp + 4]
+ mov [ecx + (VectorNum - HookAfterStubBegin)], al
+ ret
+AsmVectorNumFixup ENDP
END
diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/SecPeiCpuException.c b/UefiCpuPkg/Library/CpuExceptionHandlerLib/SecPeiCpuException.c
index ebd9fe32b..f2e7c8125 100644
--- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/SecPeiCpuException.c
+++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/SecPeiCpuException.c
@@ -1,7 +1,7 @@
/** @file
- CPU Exception Library provides SEC/PEIM CPU exception handler.
+ CPU exception handler library implemenation for SEC/PEIM modules.
-Copyright (c) 2012, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2012 - 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 that accompanies this distribution.
The full text of the license may be found at
@@ -18,7 +18,8 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
//
// Image Aglinment size for SEC/PEI phase
//
-CONST UINTN mImageAlignSize = 4;
+CONST UINTN mImageAlignSize = 4;
+CONST UINTN mDoFarReturnFlag = 0;
/**
Common exception handler.
@@ -45,19 +46,138 @@ CommonExceptionHandler (
}
/**
- Setup CPU exception handlers.
-
- This API will setups the CPU exception handler to display CPU contents and run into
- CpuDeadLoop().
+ Initializes all CPU exceptions entries and provides the default exception handlers.
+
+ Caller should try to get an array of interrupt and/or exception vectors that are in use and need to
+ persist by EFI_VECTOR_HANDOFF_INFO defined in PI 1.3 specification.
+ If caller cannot get reserved vector list or it does not exists, set VectorInfo to NULL.
+ If VectorInfo is not NULL, the exception vectors will be initialized per vector attribute accordingly.
Note: Before invoking this API, caller must allocate memory for IDT table and load
IDTR by AsmWriteIdtr().
+
+ @param[in] VectorInfo Pointer to reserved vector list.
+ @retval EFI_SUCCESS CPU Exception Entries have been successfully initialized
+ with default exception handlers.
+ @retval EFI_INVALID_PARAMETER VectorInfo includes the invalid content if VectorInfo is not NULL.
+ @retval EFI_UNSUPPORTED This function is not supported.
+
**/
-VOID
+EFI_STATUS
+EFIAPI
+InitializeCpuExceptionHandlers (
+ IN EFI_VECTOR_HANDOFF_INFO *VectorInfo OPTIONAL
+ )
+{
+ EFI_STATUS Status;
+ RESERVED_VECTORS_DATA ReservedVectorData[CPU_EXCEPTION_NUM];
+ IA32_DESCRIPTOR IdtDescriptor;
+ UINTN IdtEntryCount;
+ UINT16 CodeSegment;
+ EXCEPTION_HANDLER_TEMPLATE_MAP TemplateMap;
+ IA32_IDT_GATE_DESCRIPTOR *IdtTable;
+ UINTN Index;
+ UINTN InterruptHandler;
+
+ if (VectorInfo != NULL) {
+ SetMem ((VOID *) ReservedVectorData, sizeof (RESERVED_VECTORS_DATA) * CPU_EXCEPTION_NUM, 0xff);
+ Status = ReadAndVerifyVectorInfo (VectorInfo, ReservedVectorData, CPU_EXCEPTION_NUM);
+ if (EFI_ERROR (Status)) {
+ return EFI_INVALID_PARAMETER;
+ }
+ }
+ //
+ // Read IDT descriptor and calculate IDT size
+ //
+ AsmReadIdtr (&IdtDescriptor);
+ IdtEntryCount = (IdtDescriptor.Limit + 1) / sizeof (IA32_IDT_GATE_DESCRIPTOR);
+ if (IdtEntryCount > CPU_EXCEPTION_NUM) {
+ //
+ // CPU exeption library only setup CPU_EXCEPTION_NUM exception handler at most
+ //
+ IdtEntryCount = CPU_EXCEPTION_NUM;
+ }
+ //
+ // Use current CS as the segment selector of interrupt gate in IDT
+ //
+ CodeSegment = AsmReadCs ();
+
+ AsmGetTemplateAddressMap (&TemplateMap);
+ IdtTable = (IA32_IDT_GATE_DESCRIPTOR *)IdtDescriptor.Base;
+ for (Index = 0; Index < IdtEntryCount; Index ++) {
+ IdtTable[Index].Bits.Selector = CodeSegment;
+ //
+ // Check reserved vectors attributes if has, only EFI_VECTOR_HANDOFF_DO_NOT_HOOK
+ // supported in this instance
+ //
+ if (VectorInfo != NULL) {
+ if (ReservedVectorData[Index].Attribute == EFI_VECTOR_HANDOFF_DO_NOT_HOOK) {
+ continue;
+ }
+ }
+ //
+ // Update IDT entry
+ //
+ InterruptHandler = TemplateMap.ExceptionStart + Index * TemplateMap.ExceptionStubHeaderSize;
+ ArchUpdateIdtEntry (&IdtTable[Index], InterruptHandler);
+ }
+ return EFI_SUCCESS;
+}
+
+/**
+ Initializes all CPU interrupt/exceptions entries and provides the default interrupt/exception handlers.
+
+ Caller should try to get an array of interrupt and/or exception vectors that are in use and need to
+ persist by EFI_VECTOR_HANDOFF_INFO defined in PI 1.3 specification.
+ If caller cannot get reserved vector list or it does not exists, set VectorInfo to NULL.
+ If VectorInfo is not NULL, the exception vectors will be initialized per vector attribute accordingly.
+
+ @param[in] VectorInfo Pointer to reserved vector list.
+
+ @retval EFI_SUCCESS All CPU interrupt/exception entries have been successfully initialized
+ with default interrupt/exception handlers.
+ @retval EFI_INVALID_PARAMETER VectorInfo includes the invalid content if VectorInfo is not NULL.
+ @retval EFI_UNSUPPORTED This function is not supported.
+
+**/
+EFI_STATUS
EFIAPI
-SetupCpuExceptionHandlers (
- IN VOID
+InitializeCpuInterruptHandlers (
+ IN EFI_VECTOR_HANDOFF_INFO *VectorInfo OPTIONAL
)
{
- InternalSetupCpuExceptionHandlers ();
+ return EFI_UNSUPPORTED;
}
+
+/**
+ Registers a function to be called from the processor interrupt handler.
+
+ This function registers and enables the handler specified by InterruptHandler for a processor
+ interrupt or exception type specified by InterruptType. If InterruptHandler is NULL, then the
+ handler for the processor interrupt or exception type specified by InterruptType is uninstalled.
+ The installed handler is called once for each processor interrupt or exception.
+ NOTE: This function should be invoked after InitializeCpuExceptionHandlers() or
+ InitializeCpuInterruptHandlers() invoked, otherwise EFI_UNSUPPORTED returned.
+
+ @param[in] InterruptType Defines which interrupt or exception to hook.
+ @param[in] InterruptHandler A pointer to a function of type EFI_CPU_INTERRUPT_HANDLER that is called
+ when a processor interrupt occurs. If this parameter is NULL, then the handler
+ will be uninstalled.
+
+ @retval EFI_SUCCESS The handler for the processor interrupt was successfully installed or uninstalled.
+ @retval EFI_ALREADY_STARTED InterruptHandler is not NULL, and a handler for InterruptType was
+ previously installed.
+ @retval EFI_INVALID_PARAMETER InterruptHandler is NULL, and a handler for InterruptType was not
+ previously installed.
+ @retval EFI_UNSUPPORTED The interrupt specified by InterruptType is not supported,
+ or this function is not supported.
+*/
+EFI_STATUS
+EFIAPI
+RegisterCpuInterruptHandler (
+ IN EFI_EXCEPTION_TYPE InterruptType,
+ IN EFI_CPU_INTERRUPT_HANDLER InterruptHandler
+ )
+{
+ return EFI_UNSUPPORTED;
+} \ No newline at end of file
diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/SecPeiCpuExceptionHandlerLib.inf b/UefiCpuPkg/Library/CpuExceptionHandlerLib/SecPeiCpuExceptionHandlerLib.inf
index 96ddaafd4..159d3c61f 100644
--- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/SecPeiCpuExceptionHandlerLib.inf
+++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/SecPeiCpuExceptionHandlerLib.inf
@@ -3,7 +3,7 @@
#
# This library instance supports SEC/PEI module only.
#
-# Copyright (c) 2012, Intel Corporation. All rights reserved.<BR>
+# Copyright (c) 2012 - 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
@@ -32,11 +32,13 @@
Ia32/ExceptionHandlerAsm.asm |MSFT
Ia32/ExceptionHandlerAsm.S |GCC
Ia32/ArchExceptionHandler.c
+ Ia32/ArchInterruptDefs.h
[Sources.X64]
X64/ExceptionHandlerAsm.asm |MSFT
X64/ExceptionHandlerAsm.S |GCC
X64/ArchExceptionHandler.c
+ X64/ArchInterruptDefs.h
[Sources.common]
CpuExceptionCommon.h
@@ -54,3 +56,6 @@
PrintLib
LocalApicLib
PeCoffGetEntryPointLib
+
+[Ppis]
+ gEfiVectorHandoffInfoPpiGuid
diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/SmmCpuExceptionHandlerLib.inf b/UefiCpuPkg/Library/CpuExceptionHandlerLib/SmmCpuExceptionHandlerLib.inf
new file mode 100644
index 000000000..9fe87be8a
--- /dev/null
+++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/SmmCpuExceptionHandlerLib.inf
@@ -0,0 +1,64 @@
+## @file
+# Component description file for SMM CPU Exception Handler Library instance.
+#
+# This library instance supports SMM module only.
+#
+# Copyright (c) 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.
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = SmmCpuExceptionHandlerLib
+ FILE_GUID = 8D2C439B-3981-42ff-9CE5-1B50ECA502D6
+ MODULE_TYPE = DXE_SMM_DRIVER
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = CpuExceptionHandlerLib|DXE_SMM_DRIVER
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64
+#
+
+[Sources.Ia32]
+ Ia32/ExceptionHandlerAsm.asm |MSFT
+ Ia32/ExceptionHandlerAsm.S |GCC
+ Ia32/ArchExceptionHandler.c
+ Ia32/ArchInterruptDefs.h
+
+[Sources.X64]
+ X64/ExceptionHandlerAsm.asm |MSFT
+ X64/ExceptionHandlerAsm.S |GCC
+ X64/ArchExceptionHandler.c
+ X64/ArchInterruptDefs.h
+
+[Sources.common]
+ CpuExceptionCommon.h
+ CpuExceptionCommon.c
+ DxeSmmCpuException.c
+ SmmException.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ UefiCpuPkg/UefiCpuPkg.dec
+
+[LibraryClasses]
+ BaseLib
+ SerialPortLib
+ PrintLib
+ SynchronizationLib
+ LocalApicLib
+ PeCoffGetEntryPointLib
+ DebugLib
+
+[Ppis]
+ gEfiVectorHandoffInfoPpiGuid
diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/SmmException.c b/UefiCpuPkg/Library/CpuExceptionHandlerLib/SmmException.c
new file mode 100644
index 000000000..c3f4425e0
--- /dev/null
+++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/SmmException.c
@@ -0,0 +1,101 @@
+/** @file
+ CPU exception handler library implemenation for SMM modules.
+
+ Copyright (c) 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 <PiSmm.h>
+#include "CpuExceptionCommon.h"
+
+CONST UINTN mDoFarReturnFlag = 1;
+
+/**
+ Initializes all CPU exceptions entries and provides the default exception handlers.
+
+ Caller should try to get an array of interrupt and/or exception vectors that are in use and need to
+ persist by EFI_VECTOR_HANDOFF_INFO defined in PI 1.3 specification.
+ If caller cannot get reserved vector list or it does not exists, set VectorInfo to NULL.
+ If VectorInfo is not NULL, the exception vectors will be initialized per vector attribute accordingly.
+
+ @param[in] VectorInfo Pointer to reserved vector list.
+
+ @retval EFI_SUCCESS CPU Exception Entries have been successfully initialized
+ with default exception handlers.
+ @retval EFI_INVALID_PARAMETER VectorInfo includes the invalid content if VectorInfo is not NULL.
+ @retval EFI_UNSUPPORTED This function is not supported.
+
+**/
+EFI_STATUS
+EFIAPI
+InitializeCpuExceptionHandlers (
+ IN EFI_VECTOR_HANDOFF_INFO *VectorInfo OPTIONAL
+ )
+{
+ return InitializeCpuExceptionHandlersWorker (VectorInfo);
+}
+
+/**
+ Initializes all CPU interrupt/exceptions entries and provides the default interrupt/exception handlers.
+
+ Caller should try to get an array of interrupt and/or exception vectors that are in use and need to
+ persist by EFI_VECTOR_HANDOFF_INFO defined in PI 1.3 specification.
+ If caller cannot get reserved vector list or it does not exists, set VectorInfo to NULL.
+ If VectorInfo is not NULL, the exception vectors will be initialized per vector attribute accordingly.
+
+ @param[in] VectorInfo Pointer to reserved vector list.
+
+ @retval EFI_SUCCESS All CPU interrupt/exception entries have been successfully initialized
+ with default interrupt/exception handlers.
+ @retval EFI_INVALID_PARAMETER VectorInfo includes the invalid content if VectorInfo is not NULL.
+ @retval EFI_UNSUPPORTED This function is not supported.
+
+**/
+EFI_STATUS
+EFIAPI
+InitializeCpuInterruptHandlers (
+ IN EFI_VECTOR_HANDOFF_INFO *VectorInfo OPTIONAL
+ )
+{
+ return EFI_UNSUPPORTED;
+}
+
+/**
+ Registers a function to be called from the processor interrupt handler.
+
+ This function registers and enables the handler specified by InterruptHandler for a processor
+ interrupt or exception type specified by InterruptType. If InterruptHandler is NULL, then the
+ handler for the processor interrupt or exception type specified by InterruptType is uninstalled.
+ The installed handler is called once for each processor interrupt or exception.
+ NOTE: This function should be invoked after InitializeCpuExceptionHandlers() or
+ InitializeCpuInterruptHandlers() invoked, otherwise EFI_UNSUPPORTED returned.
+
+ @param[in] InterruptType Defines which interrupt or exception to hook.
+ @param[in] InterruptHandler A pointer to a function of type EFI_CPU_INTERRUPT_HANDLER that is called
+ when a processor interrupt occurs. If this parameter is NULL, then the handler
+ will be uninstalled.
+
+ @retval EFI_SUCCESS The handler for the processor interrupt was successfully installed or uninstalled.
+ @retval EFI_ALREADY_STARTED InterruptHandler is not NULL, and a handler for InterruptType was
+ previously installed.
+ @retval EFI_INVALID_PARAMETER InterruptHandler is NULL, and a handler for InterruptType was not
+ previously installed.
+ @retval EFI_UNSUPPORTED The interrupt specified by InterruptType is not supported,
+ or this function is not supported.
+*/
+EFI_STATUS
+EFIAPI
+RegisterCpuInterruptHandler (
+ IN EFI_EXCEPTION_TYPE InterruptType,
+ IN EFI_CPU_INTERRUPT_HANDLER InterruptHandler
+ )
+{
+ return RegisterCpuInterruptHandlerWorker (InterruptType, InterruptHandler);
+} \ No newline at end of file
diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchExceptionHandler.c b/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchExceptionHandler.c
index 664472a66..1af2999ac 100644
--- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchExceptionHandler.c
+++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchExceptionHandler.c
@@ -1,7 +1,7 @@
/** @file
x64 CPU Exception Hanlder.
- Copyright (c) 2012, Intel Corporation. All rights reserved.<BR>
+ Copyright (c) 2012 - 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
@@ -15,61 +15,102 @@
#include "CpuExceptionCommon.h"
/**
- Internal function to setup CPU exception handlers.
+ Return address map of exception handler template so that C code can generate
+ exception tables.
+ @param IdtEntry Pointer to IDT entry to be updated.
+ @param InterruptHandler IDT handler value.
**/
VOID
-InternalSetupCpuExceptionHandlers (
- VOID
+ArchUpdateIdtEntry (
+ IN IA32_IDT_GATE_DESCRIPTOR *IdtEntry,
+ IN UINTN InterruptHandler
)
{
- IA32_DESCRIPTOR IdtDescriptor;
- UINTN IdtSize;
- EXCEPTION_HANDLER_TEMPLATE_MAP TemplateMap;
- UINT16 CodeSegment;
- IA32_IDT_GATE_DESCRIPTOR *IdtEntry;
- UINTN Index;
- UINTN InterruptHandler;
+ IdtEntry->Bits.OffsetLow = (UINT16)(UINTN)InterruptHandler;
+ IdtEntry->Bits.OffsetHigh = (UINT16)((UINTN)InterruptHandler >> 16);
+ IdtEntry->Bits.OffsetUpper = (UINT32)((UINTN)InterruptHandler >> 32);
+ IdtEntry->Bits.GateType = IA32_IDT_GATE_TYPE_INTERRUPT_32;
+}
+
+/**
+ Read IDT handler value from IDT entry.
+
+ @param IdtEntry Pointer to IDT entry to be read.
+
+**/
+UINTN
+ArchGetIdtHandler (
+ IN IA32_IDT_GATE_DESCRIPTOR *IdtEntry
+ )
+{
+ return IdtEntry->Bits.OffsetLow + (((UINTN) IdtEntry->Bits.OffsetHigh) << 16) +
+ (((UINTN) IdtEntry->Bits.OffsetUpper) << 32);
+}
+/**
+ Save CPU exception context when handling EFI_VECTOR_HANDOFF_HOOK_AFTER case.
+
+ @param ExceptionType Exception type.
+ @param SystemContext Pointer to EFI_SYSTEM_CONTEXT.
+**/
+VOID
+ArchSaveExceptionContext (
+ IN UINTN ExceptionType,
+ IN EFI_SYSTEM_CONTEXT SystemContext
+ )
+{
+ IA32_EFLAGS32 Eflags;
//
- // Read IDT descriptor and calculate IDT size
+ // Save Exception context in global variable
//
- AsmReadIdtr (&IdtDescriptor);
- IdtSize = (IdtDescriptor.Limit + 1) / sizeof (IA32_IDT_GATE_DESCRIPTOR);
- if (IdtSize > CPU_EXCEPTION_NUM) {
- //
- // CPU exeption library only setup CPU_EXCEPTION_NUM exception handler at most
- //
- IdtSize = CPU_EXCEPTION_NUM;
- }
-
+ mReservedVectors[ExceptionType].OldSs = SystemContext.SystemContextX64->Ss;
+ mReservedVectors[ExceptionType].OldSp = SystemContext.SystemContextX64->Rsp;
+ mReservedVectors[ExceptionType].OldFlags = SystemContext.SystemContextX64->Rflags;
+ mReservedVectors[ExceptionType].OldCs = SystemContext.SystemContextX64->Cs;
+ mReservedVectors[ExceptionType].OldIp = SystemContext.SystemContextX64->Rip;
+ mReservedVectors[ExceptionType].ExceptionData = SystemContext.SystemContextX64->ExceptionData;
//
- // Use current CS as the segment selector of interrupt gate in IDT
+ // Clear IF flag to avoid old IDT handler enable interrupt by IRET
//
- CodeSegment = AsmReadCs ();
- IdtEntry = (IA32_IDT_GATE_DESCRIPTOR *) IdtDescriptor.Base;
-
- GetTemplateAddressMap (&TemplateMap);
-
- for (Index = 0; Index < IdtSize; Index ++) {
- InterruptHandler = TemplateMap.ExceptionStart + Index * TemplateMap.ExceptionStubHeaderSize;
- IdtEntry[Index].Bits.OffsetLow = (UINT16)(UINTN)InterruptHandler;
- IdtEntry[Index].Bits.OffsetHigh = (UINT16)((UINTN)InterruptHandler >> 16);
- IdtEntry[Index].Bits.OffsetUpper = (UINT32)((UINTN)InterruptHandler >> 32);
- IdtEntry[Index].Bits.Selector = CodeSegment;
- IdtEntry[Index].Bits.GateType = IA32_IDT_GATE_TYPE_INTERRUPT_32;
- }
+ Eflags.UintN = SystemContext.SystemContextX64->Rflags;
+ Eflags.Bits.IF = 0;
+ SystemContext.SystemContextX64->Rflags = Eflags.UintN;
+ //
+ // Modify the EIP in stack, then old IDT handler will return to the stub code
+ //
+ SystemContext.SystemContextX64->Rip = (UINTN) mReservedVectors[ExceptionType].HookAfterStubHeaderCode;
}
/**
- Common exception handler.
+ Restore CPU exception context when handling EFI_VECTOR_HANDOFF_HOOK_AFTER case.
@param ExceptionType Exception type.
@param SystemContext Pointer to EFI_SYSTEM_CONTEXT.
**/
VOID
-DumpCpuContent (
+ArchRestoreExceptionContext (
IN UINTN ExceptionType,
+ IN EFI_SYSTEM_CONTEXT SystemContext
+ )
+{
+ SystemContext.SystemContextX64->Ss = mReservedVectors[ExceptionType].OldSs;
+ SystemContext.SystemContextX64->Rsp = mReservedVectors[ExceptionType].OldSp;
+ SystemContext.SystemContextX64->Rflags = mReservedVectors[ExceptionType].OldFlags;
+ SystemContext.SystemContextX64->Cs = mReservedVectors[ExceptionType].OldCs;
+ SystemContext.SystemContextX64->Rip = mReservedVectors[ExceptionType].OldIp;
+ SystemContext.SystemContextX64->ExceptionData = mReservedVectors[ExceptionType].ExceptionData;
+}
+
+/**
+ Dump CPU content information.
+
+ @param ExceptionType Exception type.
+ @param SystemContext Pointer to EFI_SYSTEM_CONTEXT.
+**/
+VOID
+DumpCpuContent (
+ IN EFI_EXCEPTION_TYPE ExceptionType,
IN EFI_SYSTEM_CONTEXT SystemContext
)
{
diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchInterruptDefs.h b/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchInterruptDefs.h
new file mode 100644
index 000000000..906480134
--- /dev/null
+++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchInterruptDefs.h
@@ -0,0 +1,46 @@
+/** @file
+ X64 arch definition for CPU Exception Handler Library.
+
+ Copyright (c) 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 _ARCH_CPU_INTERRUPT_DEFS_H_
+#define _ARCH_CPU_INTERRUPT_DEFS_H_
+
+typedef struct {
+ EFI_SYSTEM_CONTEXT_X64 SystemContext;
+ BOOLEAN ExceptionDataFlag;
+ UINTN OldIdtHandler;
+} EXCEPTION_HANDLER_CONTEXT;
+
+//
+// Register Structure Definitions
+//
+typedef struct {
+ EFI_STATUS_CODE_DATA Header;
+ EFI_SYSTEM_CONTEXT_X64 SystemContext;
+} CPU_STATUS_CODE_TEMPLATE;
+
+typedef struct {
+ SPIN_LOCK SpinLock;
+ UINT32 ApicId;
+ UINT32 Attribute;
+ UINTN ExceptonHandler;
+ UINTN OldSs;
+ UINTN OldSp;
+ UINTN OldFlags;
+ UINTN OldCs;
+ UINTN OldIp;
+ UINTN ExceptionData;
+ UINT8 HookAfterStubHeaderCode[HOOKAFTER_STUB_SIZE];
+} RESERVED_VECTORS_DATA;
+
+#endif
diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ExceptionHandlerAsm.S b/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ExceptionHandlerAsm.S
index cd101475a..6e80d848f 100644
--- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ExceptionHandlerAsm.S
+++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ExceptionHandlerAsm.S
@@ -1,5 +1,5 @@
#------------------------------------------------------------------------------ ;
-# Copyright (c) 2012, Intel Corporation. All rights reserved.<BR>
+# Copyright (c) 2012 - 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
@@ -21,114 +21,267 @@
#------------------------------------------------------------------------------
-#EXTRN ASM_PFX(mErrorCodeFlag):DWORD # Error code flags for exceptions
ASM_GLOBAL ASM_PFX(CommonExceptionHandler)
ASM_GLOBAL ASM_PFX(CommonInterruptEntry)
+ASM_GLOBAL ASM_PFX(HookAfterStubHeaderEnd)
-
+#EXTRN ASM_PFX(mErrorCodeFlag):DWORD # Error code flags for exceptions
+#EXTRN ASM_PFX(mDoFarReturnFlag):QWORD # Do far return flag
.text
#
-# point to the external interrupt vector table
+# exception handler stub table
#
Exception0Handle:
- pushq $0
- jmp ASM_PFX(CommonInterruptEntry)
+ .byte 0x6a # push #VectorNum
+ .byte 0
+ pushq %rax
+ .byte 0x48, 0xB8
+ .quad ASM_PFX(CommonInterruptEntry)
+ jmp *%rax
Exception1Handle:
- pushq $1
- jmp ASM_PFX(CommonInterruptEntry)
+ .byte 0x6a # push #VectorNum
+ .byte 1
+ pushq %rax
+ .byte 0x48, 0xB8
+ .quad ASM_PFX(CommonInterruptEntry)
+ jmp *%rax
Exception2Handle:
- pushq $2
- jmp ASM_PFX(CommonInterruptEntry)
+ .byte 0x6a # push #VectorNum
+ .byte 2
+ pushq %rax
+ .byte 0x48, 0xB8
+ .quad ASM_PFX(CommonInterruptEntry)
+ jmp *%rax
Exception3Handle:
- pushq $3
- jmp ASM_PFX(CommonInterruptEntry)
+ .byte 0x6a # push #VectorNum
+ .byte 3
+ pushq %rax
+ .byte 0x48, 0xB8
+ .quad ASM_PFX(CommonInterruptEntry)
+ jmp *%rax
Exception4Handle:
- pushq $4
- jmp ASM_PFX(CommonInterruptEntry)
+ .byte 0x6a # push #VectorNum
+ .byte 4
+ pushq %rax
+ .byte 0x48, 0xB8
+ .quad ASM_PFX(CommonInterruptEntry)
+ jmp *%rax
Exception5Handle:
- pushq $5
- jmp ASM_PFX(CommonInterruptEntry)
+ .byte 0x6a # push #VectorNum
+ .byte 5
+ pushq %rax
+ .byte 0x48, 0xB8
+ .quad ASM_PFX(CommonInterruptEntry)
+ jmp *%rax
Exception6Handle:
- pushq $6
- jmp ASM_PFX(CommonInterruptEntry)
+ .byte 0x6a # push #VectorNum
+ .byte 6
+ pushq %rax
+ .byte 0x48, 0xB8
+ .quad ASM_PFX(CommonInterruptEntry)
+ jmp *%rax
Exception7Handle:
- pushq $7
- jmp ASM_PFX(CommonInterruptEntry)
+ .byte 0x6a # push #VectorNum
+ .byte 7
+ pushq %rax
+ .byte 0x48, 0xB8
+ .quad ASM_PFX(CommonInterruptEntry)
+ jmp *%rax
Exception8Handle:
- pushq $8
- jmp ASM_PFX(CommonInterruptEntry)
+ .byte 0x6a # push #VectorNum
+ .byte 8
+ pushq %rax
+ .byte 0x48, 0xB8
+ .quad ASM_PFX(CommonInterruptEntry)
+ jmp *%rax
Exception9Handle:
- pushq $9
- jmp ASM_PFX(CommonInterruptEntry)
+ .byte 0x6a # push #VectorNum
+ .byte 9
+ pushq %rax
+ .byte 0x48, 0xB8
+ .quad ASM_PFX(CommonInterruptEntry)
+ jmp *%rax
Exception10Handle:
- pushq $10
- jmp ASM_PFX(CommonInterruptEntry)
+ .byte 0x6a # push #VectorNum
+ .byte 10
+ pushq %rax
+ .byte 0x48, 0xB8
+ .quad ASM_PFX(CommonInterruptEntry)
+ jmp *%rax
Exception11Handle:
- pushq $11
- jmp ASM_PFX(CommonInterruptEntry)
+ .byte 0x6a # push #VectorNum
+ .byte 11
+ pushq %rax
+ .byte 0x48, 0xB8
+ .quad ASM_PFX(CommonInterruptEntry)
+ jmp *%rax
Exception12Handle:
- pushq $12
- jmp ASM_PFX(CommonInterruptEntry)
+ .byte 0x6a # push #VectorNum
+ .byte 12
+ pushq %rax
+ .byte 0x48, 0xB8
+ .quad ASM_PFX(CommonInterruptEntry)
+ jmp *%rax
Exception13Handle:
- pushq $13
- jmp ASM_PFX(CommonInterruptEntry)
+ .byte 0x6a # push #VectorNum
+ .byte 13
+ pushq %rax
+ .byte 0x48, 0xB8
+ .quad ASM_PFX(CommonInterruptEntry)
+ jmp *%rax
Exception14Handle:
- pushq $14
- jmp ASM_PFX(CommonInterruptEntry)
+ .byte 0x6a # push #VectorNum
+ .byte 14
+ pushq %rax
+ .byte 0x48, 0xB8
+ .quad ASM_PFX(CommonInterruptEntry)
+ jmp *%rax
Exception15Handle:
- pushq $15
- jmp ASM_PFX(CommonInterruptEntry)
+ .byte 0x6a # push #VectorNum
+ .byte 15
+ pushq %rax
+ .byte 0x48, 0xB8
+ .quad ASM_PFX(CommonInterruptEntry)
+ jmp *%rax
Exception16Handle:
- pushq $16
- jmp ASM_PFX(CommonInterruptEntry)
+ .byte 0x6a # push #VectorNum
+ .byte 16
+ pushq %rax
+ .byte 0x48, 0xB8
+ .quad ASM_PFX(CommonInterruptEntry)
+ jmp *%rax
Exception17Handle:
- pushq $17
- jmp ASM_PFX(CommonInterruptEntry)
+ .byte 0x6a # push #VectorNum
+ .byte 17
+ pushq %rax
+ .byte 0x48, 0xB8
+ .quad ASM_PFX(CommonInterruptEntry)
+ jmp *%rax
Exception18Handle:
- pushq $18
- jmp ASM_PFX(CommonInterruptEntry)
+ .byte 0x6a # push #VectorNum
+ .byte 18
+ pushq %rax
+ .byte 0x48, 0xB8
+ .quad ASM_PFX(CommonInterruptEntry)
+ jmp *%rax
Exception19Handle:
- pushq $19
- jmp ASM_PFX(CommonInterruptEntry)
+ .byte 0x6a # push #VectorNum
+ .byte 19
+ pushq %rax
+ .byte 0x48, 0xB8
+ .quad ASM_PFX(CommonInterruptEntry)
+ jmp *%rax
Exception20Handle:
- pushq $20
- jmp ASM_PFX(CommonInterruptEntry)
+ .byte 0x6a # push #VectorNum
+ .byte 20
+ pushq %rax
+ .byte 0x48, 0xB8
+ .quad ASM_PFX(CommonInterruptEntry)
+ jmp *%rax
Exception21Handle:
- pushq $21
- jmp ASM_PFX(CommonInterruptEntry)
+ .byte 0x6a # push #VectorNum
+ .byte 21
+ pushq %rax
+ .byte 0x48, 0xB8
+ .quad ASM_PFX(CommonInterruptEntry)
+ jmp *%rax
Exception22Handle:
- pushq $22
- jmp ASM_PFX(CommonInterruptEntry)
+ .byte 0x6a # push #VectorNum
+ .byte 22
+ pushq %rax
+ .byte 0x48, 0xB8
+ .quad ASM_PFX(CommonInterruptEntry)
+ jmp *%rax
Exception23Handle:
- pushq $23
- jmp ASM_PFX(CommonInterruptEntry)
+ .byte 0x6a # push #VectorNum
+ .byte 23
+ pushq %rax
+ .byte 0x48, 0xB8
+ .quad ASM_PFX(CommonInterruptEntry)
+ jmp *%rax
Exception24Handle:
- pushq $24
- jmp ASM_PFX(CommonInterruptEntry)
+ .byte 0x6a # push #VectorNum
+ .byte 24
+ pushq %rax
+ .byte 0x48, 0xB8
+ .quad ASM_PFX(CommonInterruptEntry)
+ jmp *%rax
Exception25Handle:
- pushq $25
- jmp ASM_PFX(CommonInterruptEntry)
+ .byte 0x6a # push #VectorNum
+ .byte 25
+ pushq %rax
+ .byte 0x48, 0xB8
+ .quad ASM_PFX(CommonInterruptEntry)
+ jmp *%rax
Exception26Handle:
- pushq $26
- jmp ASM_PFX(CommonInterruptEntry)
+ .byte 0x6a # push #VectorNum
+ .byte 26
+ pushq %rax
+ .byte 0x48, 0xB8
+ .quad ASM_PFX(CommonInterruptEntry)
+ jmp *%rax
Exception27Handle:
- pushq $27
- jmp ASM_PFX(CommonInterruptEntry)
+ .byte 0x6a # push #VectorNum
+ .byte 27
+ pushq %rax
+ .byte 0x48, 0xB8
+ .quad ASM_PFX(CommonInterruptEntry)
+ jmp *%rax
Exception28Handle:
- pushq $28
- jmp ASM_PFX(CommonInterruptEntry)
+ .byte 0x6a # push #VectorNum
+ .byte 28
+ pushq %rax
+ .byte 0x48, 0xB8
+ .quad ASM_PFX(CommonInterruptEntry)
+ jmp *%rax
Exception29Handle:
- pushq $29
- jmp ASM_PFX(CommonInterruptEntry)
+ .byte 0x6a # push #VectorNum
+ .byte 29
+ pushq %rax
+ .byte 0x48, 0xB8
+ .quad ASM_PFX(CommonInterruptEntry)
+ jmp *%rax
Exception30Handle:
- pushq $30
- jmp ASM_PFX(CommonInterruptEntry)
+ .byte 0x6a # push #VectorNum
+ .byte 30
+ pushq %rax
+ .byte 0x48, 0xB8
+ .quad ASM_PFX(CommonInterruptEntry)
+ jmp *%rax
Exception31Handle:
- pushq $31
- jmp ASM_PFX(CommonInterruptEntry)
-
+ .byte 0x6a # push #VectorNum
+ .byte 31
+ pushq %rax
+ .byte 0x48, 0xB8
+ .quad ASM_PFX(CommonInterruptEntry)
+ jmp *%rax
+
+HookAfterStubHeaderBegin:
+ .byte 0x6a # push
+VectorNum:
+ .byte 0 # 0 will be fixed
+ pushq %rax
+ .byte 0x48, 0xB8 # movq ASM_PFX(HookAfterStubHeaderEnd), %rax
+ .quad ASM_PFX(HookAfterStubHeaderEnd)
+ jmp *%rax
+ASM_GLOBAL ASM_PFX(HookAfterStubHeaderEnd)
+ASM_PFX(HookAfterStubHeaderEnd):
+ movq %rsp, %rax
+ subq $8, %rsp
+ andl $0x0fffffff0, %esp
+ pushq %rcx
+ movq 8(%rax), %rcx
+ pushq %rax
+ movabsl ASM_PFX(mErrorCodeFlag), %eax
+ bt %ecx, %eax
+ popq %rax
+ jc NoErrorData
+ pushq (%rsp) # push additional rcx to make stack alignment
+NoErrorData:
+ xchgq (%rsp), %rcx # restore rcx, save Exception Number in stack
+ pushq (%rax) # push rax into stack to keep code consistence
#---------------------------------------;
# CommonInterruptEntry ;
@@ -138,6 +291,7 @@ Exception31Handle:
ASM_GLOBAL ASM_PFX(CommonInterruptEntry)
ASM_PFX(CommonInterruptEntry):
cli
+ popq %rax
#
# All interrupt handlers are invoked through interrupt gates, so
# IF flag automatically cleared at the entry point
@@ -145,12 +299,13 @@ ASM_PFX(CommonInterruptEntry):
#
# Calculate vector number
#
- xchgq (%rsp), %rcx # get the return address of call, actually, it is the address of vector number.
+ xchgq (%rsp), %rcx # get the return address of call, actually, it is the address of vector number.
+ andq $0x0FF, %rcx
cmp $32, %ecx # Intel reserved vector for exceptions?
jae NoErrorCode
pushq %rax
- leaq ASM_PFX(mErrorCodeFlag)(%rip), %rax
- bt %ecx, (%rax)
+ movabsl ASM_PFX(mErrorCodeFlag), %eax
+ bt %ecx, %eax
popq %rax
jc CommonInterruptEntry_al_0000
@@ -165,6 +320,8 @@ NoErrorCode:
CommonInterruptEntry_al_0000:
pushq %rbp
movq %rsp, %rbp
+ pushq $0 # check EXCEPTION_HANDLER_CONTEXT.OldIdtHandler
+ pushq $0 # check EXCEPTION_HANDLER_CONTEXT.ExceptionDataFlag
#
# Stack:
@@ -385,20 +542,56 @@ CommonInterruptEntry_al_0000:
movq %rbp, %rsp
popq %rbp
addq $16, %rsp
+ cmpq $0, -32(%rsp) # check EXCEPTION_HANDLER_CONTEXT.OldIdtHandler
+ jz DoReturn # check EXCEPTION_HANDLER_CONTEXT.ExceptionDataFlag
+ cmpb $1, -40(%rsp)
+ jz ErrorCode
+ jmp *-32(%rsp)
+ErrorCode:
+ subq $8, %rsp
+ jmp *-24(%rsp)
+
+DoReturn:
+ pushq %rax
+ movabsq ASM_PFX(mDoFarReturnFlag), %rax
+ cmpq $0, %rax # Check if need to do far return instead of IRET
+ popq %rax
+ jz DoIret
+ pushq %rax
+ movq %rsp, %rax # save old RSP to rax
+ movq 0x20(%rsp), %rsp
+ pushq 0x10(%rax) # save CS in new location
+ pushq 0x8(%rax) # save EIP in new location
+ pushq 0x18(%rax) # save EFLAGS in new location
+ movq (%rax), %rax # restore rax
+ popfq # restore EFLAGS
+ .byte 0x48 # prefix to composite "retq" with next "retf"
+ retf # far return
+DoIret:
iretq
#-------------------------------------------------------------------------------------
-# AsmGetAddressMap (&AddressMap);
+# AsmGetTemplateAddressMap (&AddressMap);
#-------------------------------------------------------------------------------------
# comments here for definition of address map
-ASM_GLOBAL ASM_PFX(GetTemplateAddressMap)
-ASM_PFX(GetTemplateAddressMap):
+ASM_GLOBAL ASM_PFX(AsmGetTemplateAddressMap)
+ASM_PFX(AsmGetTemplateAddressMap):
movabsq $Exception0Handle, %rax
movq %rax, (%rcx)
movq $(Exception1Handle - Exception0Handle), 0x08(%rcx)
+ movabsq $HookAfterStubHeaderBegin, %rax
+ movq %rax, 0x10(%rcx)
+ ret
+#-------------------------------------------------------------------------------------
+# AsmVectorNumFixup (*VectorBase, VectorNum);
+#-------------------------------------------------------------------------------------
+ASM_GLOBAL ASM_PFX(AsmVectorNumFixup)
+ASM_PFX(AsmVectorNumFixup):
+ movq %rdx, %rax
+ movb %al, (VectorNum - HookAfterStubHeaderBegin)(%rcx)
ret
#END
diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ExceptionHandlerAsm.asm b/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ExceptionHandlerAsm.asm
index 2cc78db37..f348efe4b 100644
--- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ExceptionHandlerAsm.asm
+++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ExceptionHandlerAsm.asm
@@ -25,133 +25,79 @@
;
externdef CommonExceptionHandler:near
-EXTRN mErrorCodeFlag:DWORD ; Error code flags for exceptions
+EXTRN mErrorCodeFlag:DWORD ; Error code flags for exceptions
+EXTRN mDoFarReturnFlag:QWORD ; Do far return flag
data SEGMENT
-CommonEntryAddr dq CommonInterruptEntry;
-
.code
-Exception0Handle:
- push 0
- jmp qword ptr [CommonEntryAddr]
-Exception1Handle:
- push 1
- jmp qword ptr [CommonEntryAddr]
-Exception2Handle:
- push 2
- jmp qword ptr [CommonEntryAddr]
-Exception3Handle:
- push 3
- jmp qword ptr [CommonEntryAddr]
-Exception4Handle:
- push 4
- jmp qword ptr [CommonEntryAddr]
-Exception5Handle:
- push 5
- jmp qword ptr [CommonEntryAddr]
-Exception6Handle:
- push 6
- jmp qword ptr [CommonEntryAddr]
-Exception7Handle:
- push 7
- jmp qword ptr [CommonEntryAddr]
-Exception8Handle:
- push 8
- jmp qword ptr [CommonEntryAddr]
-Exception9Handle:
- push 9
- jmp qword ptr [CommonEntryAddr]
-Exception10Handle:
- push 10
- jmp qword ptr [CommonEntryAddr]
-Exception11Handle:
- push 11
- jmp qword ptr [CommonEntryAddr]
-Exception12Handle:
- push 12
- jmp qword ptr [CommonEntryAddr]
-Exception13Handle:
- push 13
- jmp qword ptr [CommonEntryAddr]
-Exception14Handle:
- push 14
- jmp qword ptr [CommonEntryAddr]
-Exception15Handle:
- push 15
- jmp qword ptr [CommonEntryAddr]
-Exception16Handle:
- push 16
- jmp qword ptr [CommonEntryAddr]
-Exception17Handle:
- push 17
- jmp qword ptr [CommonEntryAddr]
-Exception18Handle:
- push 18
- jmp qword ptr [CommonEntryAddr]
-Exception19Handle:
- push 19
- jmp qword ptr [CommonEntryAddr]
-Exception20Handle:
- push 20
- jmp qword ptr [CommonEntryAddr]
-Exception21Handle:
- push 21
- jmp qword ptr [CommonEntryAddr]
-Exception22Handle:
- push 22
- jmp qword ptr [CommonEntryAddr]
-Exception23Handle:
- push 23
- jmp qword ptr [CommonEntryAddr]
-Exception24Handle:
- push 24
- jmp qword ptr [CommonEntryAddr]
-Exception25Handle:
- push 25
- jmp qword ptr [CommonEntryAddr]
-Exception26Handle:
- push 26
- jmp qword ptr [CommonEntryAddr]
-Exception27Handle:
- push 27
- jmp qword ptr [CommonEntryAddr]
-Exception28Handle:
- push 28
- jmp qword ptr [CommonEntryAddr]
-Exception29Handle:
- push 29
- jmp qword ptr [CommonEntryAddr]
-Exception30Handle:
- push 30
- jmp qword ptr [CommonEntryAddr]
-Exception31Handle:
- push 31
- jmp qword ptr [CommonEntryAddr]
-
-;CommonInterruptEntrypoint:
-;---------------------------------------;
-; _CommonEntry ;
-;----------------------------------------------------------------------------;
-; The follow algorithm is used for the common interrupt routine.
-; Entry from each interrupt with a push eax and eax=interrupt number
+ALIGN 8
+
+AsmIdtVectorBegin:
+REPEAT 32
+ db 6ah ; push #VectorNum
+ db ($ - AsmIdtVectorBegin) / ((AsmIdtVectorEnd - AsmIdtVectorBegin) / 32) ; VectorNum
+ push rax
+ mov rax, CommonInterruptEntry
+ jmp rax
+ENDM
+AsmIdtVectorEnd:
+
+HookAfterStubHeaderBegin:
+ db 6ah ; push
+@VectorNum:
+ db 0 ; 0 will be fixed
+ push rax
+ mov rax, HookAfterStubHeaderEnd
+ jmp rax
+HookAfterStubHeaderEnd:
+ mov rax, rsp
+ sub rsp, 8h
+ and sp, 0fff0h
+ push rcx
+ mov rcx, [rax + 8]
+ bt mErrorCodeFlag, ecx
+ jc @F
+ push [rsp] ; push additional rcx to make stack alignment
+@@:
+ xchg rcx, [rsp] ; restore rcx, save Exception Number in stack
+ push [rax] ; push rax into stack to keep code consistence
;---------------------------------------;
; CommonInterruptEntry ;
;---------------------------------------;
; The follow algorithm is used for the common interrupt routine.
-
+; Entry from each interrupt with a push eax and eax=interrupt number
+; Stack frame would be as follows as specified in IA32 manuals:
+;
+; +---------------------+ <-- 16-byte aligned ensured by processor
+; + Old SS +
+; +---------------------+
+; + Old RSP +
+; +---------------------+
+; + RFlags +
+; +---------------------+
+; + CS +
+; +---------------------+
+; + RIP +
+; +---------------------+
+; + Error Code +
+; +---------------------+
+; + Vector Number +
+; +---------------------+
+; + RBP +
+; +---------------------+ <-- RBP, 16-byte aligned
+; The follow algorithm is used for the common interrupt routine.
CommonInterruptEntry PROC PUBLIC
cli
+ pop rax
;
; All interrupt handlers are invoked through interrupt gates, so
; IF flag automatically cleared at the entry point
;
- ;
- ; Calculate vector number
- ;
- xchg rcx, [rsp] ; get the return address of call, actually, it is the address of vector number.
+ xchg rcx, [rsp] ; Save rcx into stack and save vector number into rcx
+ and rcx, 0FFh
cmp ecx, 32 ; Intel reserved vector for exceptions?
jae NoErrorCode
bt mErrorCodeFlag, ecx
@@ -168,6 +114,8 @@ NoErrorCode:
@@:
push rbp
mov rbp, rsp
+ push 0 ; clear EXCEPTION_HANDLER_CONTEXT.OldIdtHandler
+ push 0 ; clear EXCEPTION_HANDLER_CONTEXT.ExceptionDataFlag
;
; Stack:
@@ -389,6 +337,29 @@ NoErrorCode:
mov rsp, rbp
pop rbp
add rsp, 16
+ cmp qword ptr [rsp - 32], 0 ; check EXCEPTION_HANDLER_CONTEXT.OldIdtHandler
+ jz DoReturn
+ cmp qword ptr [rsp - 40], 1 ; check EXCEPTION_HANDLER_CONTEXT.ExceptionDataFlag
+ jz ErrorCode
+ jmp qword ptr [rsp - 32]
+ErrorCode:
+ sub rsp, 8
+ jmp qword ptr [rsp - 24]
+
+DoReturn:
+ cmp mDoFarReturnFlag, 0 ; Check if need to do far return instead of IRET
+ jz DoIret
+ push rax
+ mov rax, rsp ; save old RSP to rax
+ mov rsp, [rsp + 20h]
+ push [rax + 10h] ; save CS in new location
+ push [rax + 8h] ; save EIP in new location
+ push [rax + 18h] ; save EFLAGS in new location
+ mov rax, [rax] ; restore rax
+ popfq ; restore EFLAGS
+ DB 48h ; prefix to composite "retq" with next "retf"
+ retf ; far return
+DoIret:
iretq
CommonInterruptEntry ENDP
@@ -397,11 +368,22 @@ CommonInterruptEntry ENDP
; GetTemplateAddressMap (&AddressMap);
;-------------------------------------------------------------------------------------
; comments here for definition of address map
-GetTemplateAddressMap PROC
- mov rax, offset Exception0Handle
- mov qword ptr [rcx], rax
- mov qword ptr [rcx+8h], Exception1Handle - Exception0Handle
- ret
-GetTemplateAddressMap ENDP
+AsmGetTemplateAddressMap PROC
+ mov rax, offset AsmIdtVectorBegin
+ mov qword ptr [rcx], rax
+ mov qword ptr [rcx + 8h], (AsmIdtVectorEnd - AsmIdtVectorBegin) / 32
+ mov rax, offset HookAfterStubHeaderBegin
+ mov qword ptr [rcx + 10h], rax
+ ret
+AsmGetTemplateAddressMap ENDP
+
+;-------------------------------------------------------------------------------------
+; AsmVectorNumFixup (*VectorBase, VectorNum);
+;-------------------------------------------------------------------------------------
+AsmVectorNumFixup PROC
+ mov rax, rdx
+ mov [rcx + (@VectorNum - HookAfterStubHeaderBegin)], al
+ ret
+AsmVectorNumFixup ENDP
END
diff --git a/UefiCpuPkg/UefiCpuPkg.dsc b/UefiCpuPkg/UefiCpuPkg.dsc
index 505c69e4c..fa33c1342 100644
--- a/UefiCpuPkg/UefiCpuPkg.dsc
+++ b/UefiCpuPkg/UefiCpuPkg.dsc
@@ -1,7 +1,7 @@
## @file
# UefiCpuPkg Package
#
-# Copyright (c) 2007 - 2012, Intel Corporation. All rights reserved.<BR>
+# 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
@@ -50,7 +50,8 @@
TimerLib|MdePkg/Library/BaseTimerLibNullTemplate/BaseTimerLibNullTemplate.inf
DebugAgentLib|MdeModulePkg/Library/DebugAgentLibNull/DebugAgentLibNull.inf
LocalApicLib|UefiCpuPkg/Library/BaseXApicX2ApicLib/BaseXApicX2ApicLib.inf
- ReportStatusCodeLib|MdePkg/Library/BaseReportStatusCodeLibNull/BaseReportStatusCodeLibNull.inf
+ ReportStatusCodeLib|MdePkg/Library/BaseReportStatusCodeLibNull/BaseReportStatusCodeLibNull.inf
+ CpuExceptionHandlerLib|MdeModulePkg/Library/CpuExceptionHandlerLibNull/CpuExceptionHandlerLibNull.inf
[LibraryClasses.common.PEIM]
MemoryAllocationLib|MdePkg/Library/PeiMemoryAllocationLib/PeiMemoryAllocationLib.inf
@@ -87,6 +88,7 @@
UefiCpuPkg/Library/BaseXApicX2ApicLib/BaseXApicX2ApicLib.inf
UefiCpuPkg/Library/BaseXApicLib/BaseXApicLib.inf
UefiCpuPkg/Library/CpuExceptionHandlerLib/SecPeiCpuExceptionHandlerLib.inf
- UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeSmmCpuExceptionHandlerLib.inf
+ UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeCpuExceptionHandlerLib.inf
+ UefiCpuPkg/Library/CpuExceptionHandlerLib/SmmCpuExceptionHandlerLib.inf
UefiCpuPkg/Universal/Acpi/S3Resume2Pei/S3Resume2Pei.inf