summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLeif Lindholm <leif.lindholm@linaro.org>2015-01-26 14:02:04 +0000
committerLeif Lindholm <leif.lindholm@linaro.org>2015-01-26 14:02:04 +0000
commitb81715b7758c45885234cc5e098fed1bb6601f05 (patch)
treecce463116b002c028b579d9627788a01b628400b
parentfd3f8b3629822eb3e9ee216cad70f9d87353c4e6 (diff)
parente60fbd59cabe28d2205cbdb335e5be29d8b978e8 (diff)
Merged 2015.01 release into masterlinaro-edk2-2015.01
Signed-off-by: Leif Lindholm <leif.lindholm@linaro.org>
-rw-r--r--ArmPkg/ArmPkg.dec8
-rw-r--r--ArmPkg/ArmPkg.dsc16
-rw-r--r--ArmPkg/Drivers/GenericWatchdogDxe/GenericWatchdog.h (renamed from ArmPlatformPkg/ArmJunoPkg/Include/Drivers/GenericWatchdog.h)0
-rw-r--r--ArmPkg/Drivers/GenericWatchdogDxe/GenericWatchdogDxe.c (renamed from ArmPlatformPkg/ArmJunoPkg/Drivers/GenericWatchdogDxe/GenericWatchdogDxe.c)8
-rw-r--r--ArmPkg/Drivers/GenericWatchdogDxe/GenericWatchdogDxe.inf (renamed from ArmPlatformPkg/ArmJunoPkg/Drivers/GenericWatchdogDxe/GenericWatchdogDxe.inf)9
-rw-r--r--ArmPkg/Include/AsmMacroIoLib.h4
-rw-r--r--ArmPkg/Include/AsmMacroIoLib.inc2
-rw-r--r--ArmPkg/Include/Library/ArmBdsHelperLib.h96
-rw-r--r--ArmPkg/Library/ArmBdsHelperLib/ArmBdsHelperLib.c487
-rw-r--r--ArmPkg/Library/ArmBdsHelperLib/ArmBdsHelperLib.inf45
-rw-r--r--ArmPkg/Library/BdsLib/BdsFilePath.c364
-rw-r--r--ArmPkg/Library/BdsLib/BdsHelper.c112
-rw-r--r--ArmPkg/Library/BdsLib/BdsLib.inf1
-rw-r--r--ArmPlatformPkg/APMXGenePkg/APMXGene.dsc.inc1
-rw-r--r--ArmPlatformPkg/ArmJunoPkg/AcpiTables/AcpiTables.inf4
-rw-r--r--ArmPlatformPkg/ArmJunoPkg/ArmJuno.dec4
-rw-r--r--ArmPlatformPkg/ArmJunoPkg/ArmJuno.dsc28
-rw-r--r--ArmPlatformPkg/ArmJunoPkg/ArmJuno.fdf13
-rw-r--r--ArmPlatformPkg/ArmJunoPkg/Drivers/ArmJunoDxe/ArmJunoDxe.inf2
-rw-r--r--ArmPlatformPkg/ArmJunoPkg/Drivers/ArmJunoDxe/InstallFdt.c2
-rw-r--r--ArmPlatformPkg/ArmJunoPkg/Library/ArmJunoLib/ArmJunoLib.inf2
-rw-r--r--ArmPlatformPkg/ArmJunoPkg/dts/juno.dtbbin0 -> 6844 bytes
-rw-r--r--ArmPlatformPkg/ArmJunoPkg/dts/juno.dts340
-rw-r--r--ArmPlatformPkg/ArmPlatformPkg.dsc2
-rw-r--r--ArmPlatformPkg/ArmVExpressPkg/ArmVExpress-CTA15-A7.dsc7
-rw-r--r--ArmPlatformPkg/ArmVExpressPkg/ArmVExpress.dsc.inc8
-rw-r--r--ArmPlatformPkg/ArmVirtualizationPkg/ArmVirtualization.dsc.inc2
-rw-r--r--ArmPlatformPkg/ArmVirtualizationPkg/ArmVirtualizationPkg.dec3
-rw-r--r--ArmPlatformPkg/ArmVirtualizationPkg/ArmVirtualizationQemu.dsc20
-rw-r--r--ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationPlatformLib/ArmVirtualizationPlatformLib.inf2
-rw-r--r--ArmPlatformPkg/ArmVirtualizationPkg/Library/PlatformIntelBdsLib/IntelBdsPlatform.c395
-rw-r--r--ArmPlatformPkg/ArmVirtualizationPkg/Library/PlatformIntelBdsLib/IntelBdsPlatform.h63
-rw-r--r--ArmPlatformPkg/ArmVirtualizationPkg/Library/PlatformIntelBdsLib/PlatformIntelBdsLib.inf77
-rw-r--r--ArmPlatformPkg/ArmVirtualizationPkg/Library/PlatformIntelBdsLib/QemuKernel.c1103
-rw-r--r--ArmPlatformPkg/ArmVirtualizationPkg/Library/QemuFwCfgLib/QemuFwCfgLib.c358
-rw-r--r--ArmPlatformPkg/ArmVirtualizationPkg/Library/QemuFwCfgLib/QemuFwCfgLib.inf52
-rw-r--r--ArmPlatformPkg/ArmVirtualizationPkg/VirtFdtDxe/VirtFdtDxe.c38
-rw-r--r--ArmPlatformPkg/ArmVirtualizationPkg/VirtFdtDxe/VirtFdtDxe.inf5
-rw-r--r--ArmPlatformPkg/Bds/BootMenu.c7
-rw-r--r--ArmPlatformPkg/Bds/BootOption.c6
-rw-r--r--ArmPlatformPkg/Drivers/PL011Uart/PL011Uart.c7
-rw-r--r--ArmPlatformPkg/FileSystem/BootMonFs/BootMonFs.inf3
-rw-r--r--ArmPlatformPkg/FileSystem/BootMonFs/BootMonFsApi.h179
-rw-r--r--ArmPlatformPkg/FileSystem/BootMonFs/BootMonFsDir.c429
-rw-r--r--ArmPlatformPkg/FileSystem/BootMonFs/BootMonFsEntryPoint.c89
-rw-r--r--ArmPlatformPkg/FileSystem/BootMonFs/BootMonFsInternal.h8
-rw-r--r--ArmPlatformPkg/FileSystem/BootMonFs/BootMonFsOpenClose.c582
-rw-r--r--ArmPlatformPkg/FileSystem/BootMonFs/BootMonFsReadWrite.c146
-rw-r--r--ArmPlatformPkg/Include/Drivers/PL011Uart.h8
-rw-r--r--ArmPlatformPkg/Library/PlatformIntelBdsLib/IntelBdsPlatform.c1
-rw-r--r--ArmPlatformPkg/Library/PlatformIntelBdsLib/PlatformIntelBdsLib.inf2
-rw-r--r--BaseTools/Conf/tools_def.template4
-rw-r--r--BaseTools/Source/Python/AutoGen/UniClassObject.py1
-rw-r--r--BaseTools/Source/Python/Common/DataType.py1
-rw-r--r--BaseTools/Source/Python/CommonDataClass/DataClass.py2
-rw-r--r--BaseTools/Source/Python/Ecc/Check.py2
-rw-r--r--BaseTools/Source/Python/Ecc/MetaFileWorkspace/MetaFileParser.py25
-rw-r--r--BaseTools/Source/Python/build/build.py5
-rw-r--r--BeagleBoardPkg/BeagleBoardPkg.dsc1
-rw-r--r--CryptoPkg/Include/Library/BaseCryptLib.h27
-rw-r--r--CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf2
-rw-r--r--CryptoPkg/Library/BaseCryptLib/Pk/CryptX509.c78
-rw-r--r--CryptoPkg/Library/BaseCryptLib/Pk/CryptX509Null.c28
-rw-r--r--CryptoPkg/Library/BaseCryptLibRuntimeCryptProtocol/Pk/CryptX509Null.c28
-rw-r--r--EmbeddedPkg/EmbeddedPkg.dsc2
-rw-r--r--HisiPkg/D01BoardPkg/Bds/Bds.c219
-rw-r--r--HisiPkg/D01BoardPkg/Bds/BdsInternal.h6
-rw-r--r--HisiPkg/D01BoardPkg/Bds/BootMenu.c37
-rw-r--r--HisiPkg/D01BoardPkg/D01BoardPkg.dsc31
-rw-r--r--HisiPkg/D01BoardPkg/D01BoardPkg.dsc.inc3
-rw-r--r--HisiPkg/D01BoardPkg/D01BoardPkg.fdf8
-rw-r--r--HisiPkg/D01BoardPkg/Library/D01SecLibRTSM/RTSMArmD01SecLib.libbin266912 -> 263988 bytes
-rw-r--r--IntelFrameworkModulePkg/Csm/BiosThunk/KeyboardDxe/BiosKeyboard.c12
-rw-r--r--IntelFrameworkModulePkg/Library/GenericBdsLib/BdsBoot.c4
-rw-r--r--IntelFrameworkPkg/Library/PeiHobLibFramework/HobLib.c64
-rw-r--r--IntelFspPkg/FspDxeIpl/DxeIpl.c11
-rw-r--r--IntelFspPkg/FspSecCore/Ia32/FspApiEntry.asm11
-rw-r--r--IntelFspPkg/FspSecCore/Ia32/FspApiEntry.s723
-rw-r--r--IntelFspPkg/Include/FspApi.h2
-rw-r--r--IntelFspPkg/Library/BaseFspPlatformLib/BaseFspPlatformLib.inf3
-rw-r--r--IntelFspPkg/Library/BaseFspPlatformLib/FspPlatformNotify.c32
-rw-r--r--IntelFspPkg/Tools/GenCfgOpt.py4
-rw-r--r--IntelFspWrapperPkg/Library/BaseFspApiLib/FspApiLib.c4
-rw-r--r--MdeModulePkg/Bus/Ata/AtaAtapiPassThru/AhciMode.c4
-rwxr-xr-x[-rw-r--r--]MdeModulePkg/Bus/Pci/EhciDxe/Ehci.c6
-rw-r--r--MdeModulePkg/Bus/Pci/EhciDxe/EhciSched.c9
-rw-r--r--MdeModulePkg/Bus/Pci/EhciDxe/EhciUrb.c1
-rw-r--r--MdeModulePkg/Bus/Pci/EhciDxe/EhciUrb.h3
-rw-r--r--MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpressPassthru.c4
-rwxr-xr-x[-rw-r--r--]MdeModulePkg/Bus/Usb/UsbBusDxe/UsbHub.c11
-rw-r--r--MdeModulePkg/Core/Dxe/DxeMain.h6
-rw-r--r--MdeModulePkg/Core/Dxe/FwVol/FwVol.c4
-rw-r--r--MdeModulePkg/Core/Dxe/Gcd/Gcd.c48
-rw-r--r--MdeModulePkg/Core/Dxe/Mem/Page.c8
-rw-r--r--MdeModulePkg/Core/Dxe/Mem/Pool.c2
-rw-r--r--MdeModulePkg/Core/Pei/FwVol/FwVol.c12
-rw-r--r--MdeModulePkg/Core/PiSmmCore/PiSmmCore.c119
-rw-r--r--MdeModulePkg/Core/PiSmmCore/PiSmmCore.h1
-rw-r--r--MdeModulePkg/Core/PiSmmCore/PiSmmCore.inf1
-rw-r--r--MdeModulePkg/Include/Guid/SmmVariableCommon.h15
-rw-r--r--MdeModulePkg/Include/Protocol/SmmVarCheck.h36
-rw-r--r--MdeModulePkg/Include/Protocol/VarCheck.h120
-rw-r--r--MdeModulePkg/Library/BaseSerialPortLib16550/BaseSerialPortLib16550.c3
-rw-r--r--MdeModulePkg/Library/CustomizedDisplayLib/CustomizedDisplayLib.c16
-rw-r--r--MdeModulePkg/Library/DxeIpIoLib/DxeIpIoLib.c7
-rw-r--r--MdeModulePkg/MdeModulePkg.dec8
-rw-r--r--MdeModulePkg/MdeModulePkg.dsc12
-rw-r--r--MdeModulePkg/Universal/Acpi/FirmwarePerformanceDataTableDxe/FirmwarePerformanceDxe.c105
-rw-r--r--MdeModulePkg/Universal/CapsulePei/Common/CapsuleCoalesce.c3
-rw-r--r--MdeModulePkg/Universal/Console/TerminalDxe/TerminalConIn.c3
-rw-r--r--MdeModulePkg/Universal/DebugSupportDxe/X64/AsmFuncs.S2
-rw-r--r--MdeModulePkg/Universal/Disk/PartitionDxe/ElTorito.c58
-rw-r--r--MdeModulePkg/Universal/FvSimpleFileSystemDxe/ComponentName.c187
-rw-r--r--MdeModulePkg/Universal/FvSimpleFileSystemDxe/FvSimpleFileSystem.c981
-rw-r--r--MdeModulePkg/Universal/FvSimpleFileSystemDxe/FvSimpleFileSystem.unibin0 -> 2018 bytes
-rw-r--r--MdeModulePkg/Universal/FvSimpleFileSystemDxe/FvSimpleFileSystemDxe.inf74
-rw-r--r--MdeModulePkg/Universal/FvSimpleFileSystemDxe/FvSimpleFileSystemEntryPoint.c676
-rw-r--r--MdeModulePkg/Universal/FvSimpleFileSystemDxe/FvSimpleFileSystemExtra.unibin0 -> 1384 bytes
-rw-r--r--MdeModulePkg/Universal/FvSimpleFileSystemDxe/FvSimpleFileSystemInternal.h622
-rw-r--r--MdeModulePkg/Universal/Network/Ip4ConfigDxe/Ip4Config.c3
-rw-r--r--MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Impl.c7
-rw-r--r--MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Rrq.c9
-rw-r--r--MdeModulePkg/Universal/Network/Tcp4Dxe/Tcp4Dispatcher.c9
-rw-r--r--MdeModulePkg/Universal/Network/Udp4Dxe/Udp4Main.c11
-rw-r--r--MdeModulePkg/Universal/SetupBrowserDxe/IfrParse.c45
-rw-r--r--MdeModulePkg/Universal/Variable/RuntimeDxe/VarCheck.c1063
-rw-r--r--MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.c147
-rw-r--r--MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.h135
-rw-r--r--MdeModulePkg/Universal/Variable/RuntimeDxe/VariableDxe.c40
-rw-r--r--MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf5
-rw-r--r--MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmm.c73
-rw-r--r--MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmm.inf7
-rw-r--r--MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmmRuntimeDxe.c191
-rw-r--r--MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmmRuntimeDxe.inf3
-rw-r--r--MdePkg/Include/Library/BaseLib.h31
-rw-r--r--MdePkg/Include/Library/HobLib.h44
-rw-r--r--MdePkg/Library/BaseLib/String.c26
-rw-r--r--MdePkg/Library/DxeCoreHobLib/HobLib.c48
-rw-r--r--MdePkg/Library/DxeHobLib/HobLib.c48
-rw-r--r--MdePkg/Library/PeiHobLib/HobLib.c64
-rw-r--r--MdePkg/Library/UefiDevicePathLibDevicePathProtocol/UefiDevicePathLib.c11
-rw-r--r--NetworkPkg/Dhcp6Dxe/Dhcp6Io.c5
-rw-r--r--NetworkPkg/IScsiDxe/IScsiMisc.c1
-rw-r--r--NetworkPkg/Ip6Dxe/Ip6Impl.c3
-rw-r--r--NetworkPkg/NetworkPkg.dsc11
-rw-r--r--NetworkPkg/TcpDxe/TcpDispatcher.c31
-rw-r--r--NetworkPkg/TcpDxe/TcpMain.c7
-rw-r--r--NetworkPkg/TcpDxe/TcpMisc.c3
-rw-r--r--NetworkPkg/UefiPxeBcDxe/PxeBcDhcp6.c11
-rw-r--r--NetworkPkg/UefiPxeBcDxe/PxeBcDriver.c3
-rw-r--r--OvmfPkg/Include/Guid/VirtioMmioTransport.h25
-rw-r--r--OvmfPkg/Include/Library/QemuBootOrderLib.h (renamed from OvmfPkg/Library/PlatformBdsLib/QemuBootOrder.h)6
-rw-r--r--OvmfPkg/Library/PlatformBdsLib/BdsPlatform.c2
-rw-r--r--OvmfPkg/Library/PlatformBdsLib/PlatformBdsLib.inf3
-rw-r--r--OvmfPkg/Library/QemuBootOrderLib/QemuBootOrderLib.c (renamed from OvmfPkg/Library/PlatformBdsLib/QemuBootOrder.c)299
-rw-r--r--OvmfPkg/Library/QemuBootOrderLib/QemuBootOrderLib.inf59
-rw-r--r--OvmfPkg/OvmfPkg.dec8
-rw-r--r--OvmfPkg/OvmfPkgIa32.dsc21
-rw-r--r--OvmfPkg/OvmfPkgIa32.fdf16
-rw-r--r--OvmfPkg/OvmfPkgIa32X64.dsc21
-rw-r--r--OvmfPkg/OvmfPkgIa32X64.fdf16
-rw-r--r--OvmfPkg/OvmfPkgX64.dsc21
-rw-r--r--OvmfPkg/OvmfPkgX64.fdf16
-rw-r--r--PandaBoardPkg/PandaBoardPkg.dsc1
-rw-r--r--SecurityPkg/Include/Library/Tpm2CommandLib.h152
-rw-r--r--SecurityPkg/Library/DxeImageVerificationLib/DxeImageVerificationLib.c65
-rw-r--r--SecurityPkg/Library/Tpm2CommandLib/Tpm2CommandLib.inf3
-rw-r--r--SecurityPkg/Library/Tpm2CommandLib/Tpm2Context.c86
-rw-r--r--SecurityPkg/Library/Tpm2CommandLib/Tpm2EnhancedAuthorization.c377
-rw-r--r--SecurityPkg/Library/Tpm2CommandLib/Tpm2Hierarchy.c96
-rw-r--r--SecurityPkg/Library/Tpm2CommandLib/Tpm2Session.c169
-rw-r--r--SecurityPkg/Tcg/TcgDxe/TcgDxe.c2
-rw-r--r--SecurityPkg/Tcg/TrEEDxe/TrEEDxe.c4
-rw-r--r--SecurityPkg/VariableAuthenticated/RuntimeDxe/VarCheck.c1225
-rw-r--r--SecurityPkg/VariableAuthenticated/RuntimeDxe/Variable.c192
-rw-r--r--SecurityPkg/VariableAuthenticated/RuntimeDxe/Variable.h127
-rw-r--r--SecurityPkg/VariableAuthenticated/RuntimeDxe/VariableDxe.c41
-rw-r--r--SecurityPkg/VariableAuthenticated/RuntimeDxe/VariableRuntimeDxe.inf5
-rw-r--r--SecurityPkg/VariableAuthenticated/RuntimeDxe/VariableSmm.c73
-rw-r--r--SecurityPkg/VariableAuthenticated/RuntimeDxe/VariableSmm.inf8
-rw-r--r--SecurityPkg/VariableAuthenticated/RuntimeDxe/VariableSmmRuntimeDxe.c191
-rw-r--r--SecurityPkg/VariableAuthenticated/RuntimeDxe/VariableSmmRuntimeDxe.inf4
-rw-r--r--SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigImpl.c11
-rw-r--r--ShellBinPkg/MinUefiShell/Ia32/Shell.efibin331392 -> 334624 bytes
-rw-r--r--ShellBinPkg/MinUefiShell/X64/Shell.efibin378464 -> 382336 bytes
-rw-r--r--ShellBinPkg/ReadMe.txt2
-rw-r--r--ShellBinPkg/UefiShell/Ia32/Shell.efibin787328 -> 790976 bytes
-rw-r--r--ShellBinPkg/UefiShell/X64/Shell.efibin893184 -> 897632 bytes
-rw-r--r--ShellPkg/Application/Shell/Shell.c184
-rw-r--r--ShellPkg/Library/UefiHandleParsingLib/UefiHandleParsingLib.c87
-rw-r--r--ShellPkg/Library/UefiHandleParsingLib/UefiHandleParsingLib.h2
-rw-r--r--ShellPkg/Library/UefiHandleParsingLib/UefiHandleParsingLib.inf3
-rw-r--r--ShellPkg/Library/UefiShellCommandLib/ConsistMapping.c41
-rw-r--r--ShellPkg/Library/UefiShellDriver1CommandsLib/Connect.c26
-rw-r--r--ShellPkg/Library/UefiShellDriver1CommandsLib/Reconnect.c65
-rw-r--r--ShellPkg/Library/UefiShellDriver1CommandsLib/UefiShellDriver1CommandsLib.h15
-rw-r--r--ShellPkg/Library/UefiShellLib/UefiShellLib.c1
-rw-r--r--SourceLevelDebugPkg/Library/DebugAgent/DebugAgentCommon/X64/AsmFuncs.S14
-rw-r--r--StdLib/BsdSocketLib/ns_addr.c355
-rw-r--r--StdLib/BsdSocketLib/ns_ntoa.c108
-rw-r--r--TexasInstrumentsPkg/BeagleBoneBlackPkg/BeagleBoneBlackPkg.dsc2
-rw-r--r--UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ExceptionHandlerAsm.S12
202 files changed, 13581 insertions, 2473 deletions
diff --git a/ArmPkg/ArmPkg.dec b/ArmPkg/ArmPkg.dec
index e5e7c0a97a..d7a4826d93 100644
--- a/ArmPkg/ArmPkg.dec
+++ b/ArmPkg/ArmPkg.dec
@@ -229,6 +229,14 @@
gArmTokenSpaceGuid.PcdArmArchTimerVirtIntrNum|27|UINT32|0x00000041
#
+ # ARM Generic Watchdog
+ #
+
+ gArmTokenSpaceGuid.PcdGenericWatchdogControlBase|0x2A440000|UINT32|0x00000007
+ gArmTokenSpaceGuid.PcdGenericWatchdogRefreshBase|0x2A450000|UINT32|0x00000008
+ gArmTokenSpaceGuid.PcdGenericWatchdogEl2IntrNum|93|UINT32|0x00000009
+
+ #
# ARM Generic Interrupt Controller
#
gArmTokenSpaceGuid.PcdGicDistributorBase|0|UINT32|0x0000000C
diff --git a/ArmPkg/ArmPkg.dsc b/ArmPkg/ArmPkg.dsc
index dcf95ba722..a90dea22d1 100644
--- a/ArmPkg/ArmPkg.dsc
+++ b/ArmPkg/ArmPkg.dsc
@@ -31,14 +31,11 @@
[BuildOptions]
XCODE:*_*_ARM_PLATFORM_FLAGS == -arch armv7
- XCODE:RELEASE_*_*_CC_FLAGS = -DMDEPKG_NDEBUG
-
GCC:*_*_ARM_PLATFORM_FLAGS == -march=armv7-a -mfpu=neon
- GCC:RELEASE_*_*_CC_FLAGS = -DMDEPKG_NDEBUG
-
# We use A15 to get the Secure and Virtualization extensions
RVCT:*_*_ARM_PLATFORM_FLAGS == --cpu Cortex-A15
- RVCT:RELEASE_*_*_CC_FLAGS = -DMDEPKG_NDEBUG
+
+ RELEASE_*_*_CC_FLAGS = -DMDEPKG_NDEBUG
[LibraryClasses.common]
BaseLib|MdePkg/Library/BaseLib/BaseLib.inf
@@ -78,7 +75,9 @@
PerformanceLib|MdePkg/Library/BasePerformanceLibNull/BasePerformanceLibNull.inf
SerialPortLib|MdePkg/Library/BaseSerialPortLibNull/BaseSerialPortLibNull.inf
+!ifndef INTEL_BDS
BdsLib|ArmPkg/Library/BdsLib/BdsLib.inf
+!endif
FdtLib|EmbeddedPkg/Library/FdtLib/FdtLib.inf
IoLib|MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsic.inf
@@ -111,7 +110,9 @@
ArmPkg/Library/ArmDmaLib/ArmDmaLib.inf
ArmPkg/Library/ArmLib/Null/NullArmLib.inf
ArmPkg/Library/BaseMemoryLibStm/BaseMemoryLibStm.inf
+!ifndef INTEL_BDS
ArmPkg/Library/BdsLib/BdsLib.inf
+!endif
ArmPkg/Library/CompilerIntrinsicsLib/CompilerIntrinsicsLib.inf
ArmPkg/Library/DebugAgentSymbolsBaseLib/DebugAgentSymbolsBaseLib.inf
ArmPkg/Library/DebugPeCoffExtraActionLib/DebugPeCoffExtraActionLib.inf
@@ -129,6 +130,7 @@
ArmPkg/Drivers/ArmGic/ArmGicDxe.inf
ArmPkg/Drivers/ArmGic/ArmGicLib.inf
ArmPkg/Drivers/ArmGic/ArmGicSecLib.inf
+ ArmPkg/Drivers/GenericWatchdogDxe/GenericWatchdogDxe.inf
ArmPkg/Drivers/TimerDxe/TimerDxe.inf
ArmPkg/Library/ArmGenericTimerPhyCounterLib/ArmGenericTimerPhyCounterLib.inf
@@ -140,7 +142,9 @@
ArmPkg/Filesystem/SemihostFs/SemihostFs.inf
+!ifndef NO_LINUX_LOADER
ArmPkg/Application/LinuxLoader/LinuxFdtLoader.inf
+!endif
[Components.ARM]
ArmPkg/Library/BaseMemoryLibVstm/BaseMemoryLibVstm.inf
@@ -156,7 +160,9 @@
ArmPkg/Library/ArmLib/ArmV7/ArmV7LibSec.inf
ArmPkg/Library/ArmLib/ArmV7/ArmV7LibPrePi.inf
+!ifndef NO_LINUX_LOADER
ArmPkg/Application/LinuxLoader/LinuxAtagLoader.inf
+!endif
[Components.AARCH64]
ArmPkg/Drivers/ArmCpuLib/ArmCortexAEMv8Lib/ArmCortexAEMv8Lib.inf
diff --git a/ArmPlatformPkg/ArmJunoPkg/Include/Drivers/GenericWatchdog.h b/ArmPkg/Drivers/GenericWatchdogDxe/GenericWatchdog.h
index 578fd1e85f..578fd1e85f 100644
--- a/ArmPlatformPkg/ArmJunoPkg/Include/Drivers/GenericWatchdog.h
+++ b/ArmPkg/Drivers/GenericWatchdogDxe/GenericWatchdog.h
diff --git a/ArmPlatformPkg/ArmJunoPkg/Drivers/GenericWatchdogDxe/GenericWatchdogDxe.c b/ArmPkg/Drivers/GenericWatchdogDxe/GenericWatchdogDxe.c
index 827d27e2ca..b1d9c027d8 100644
--- a/ArmPlatformPkg/ArmJunoPkg/Drivers/GenericWatchdogDxe/GenericWatchdogDxe.c
+++ b/ArmPkg/Drivers/GenericWatchdogDxe/GenericWatchdogDxe.c
@@ -27,7 +27,7 @@
#include <Protocol/WatchdogTimer.h>
#include <Protocol/HardwareInterrupt.h>
-#include <Drivers/GenericWatchdog.h>
+#include "GenericWatchdog.h"
// The number of 100ns periods (the unit of time passed to these functions)
// in a second
@@ -181,7 +181,7 @@ WatchdogSetTimerPeriod (
IN UINT64 TimerPeriod // In 100ns units
)
{
- UINTN TimerVal;
+ UINTN SystemCount;
EFI_STATUS Status;
// if TimerPerdiod is 0, this is a request to stop the watchdog.
@@ -210,8 +210,8 @@ WatchdogSetTimerPeriod (
return Status;
}
WatchdogEnable ();
- TimerVal = ArmGenericTimerGetTimerVal ();
- Status = WatchdogWriteCompareRegister (TimerVal + mNumTimerTicks);
+ SystemCount = ArmGenericTimerGetSystemCount ();
+ Status = WatchdogWriteCompareRegister (SystemCount + mNumTimerTicks);
} else {
Status = WatchdogWriteOffsetRegister ((UINT32)mNumTimerTicks);
WatchdogEnable ();
diff --git a/ArmPlatformPkg/ArmJunoPkg/Drivers/GenericWatchdogDxe/GenericWatchdogDxe.inf b/ArmPkg/Drivers/GenericWatchdogDxe/GenericWatchdogDxe.inf
index 82f226fb56..fece14cc18 100644
--- a/ArmPlatformPkg/ArmJunoPkg/Drivers/GenericWatchdogDxe/GenericWatchdogDxe.inf
+++ b/ArmPkg/Drivers/GenericWatchdogDxe/GenericWatchdogDxe.inf
@@ -27,7 +27,6 @@
EmbeddedPkg/EmbeddedPkg.dec
ArmPkg/ArmPkg.dec
ArmPlatformPkg/ArmPlatformPkg.dec
- ArmPlatformPkg/ArmJunoPkg/ArmJuno.dec
[LibraryClasses]
ArmGenericTimerCounterLib
@@ -41,10 +40,10 @@
UefiDriverEntryPoint
UefiRuntimeServicesTableLib
-[FixedPcd]
- gArmJunoTokenSpaceGuid.PcdGenericWatchdogControlBase
- gArmJunoTokenSpaceGuid.PcdGenericWatchdogRefreshBase
- gArmJunoTokenSpaceGuid.PcdGenericWatchdogEl2IntrNum
+[Pcd.common]
+ gArmTokenSpaceGuid.PcdGenericWatchdogControlBase
+ gArmTokenSpaceGuid.PcdGenericWatchdogRefreshBase
+ gArmTokenSpaceGuid.PcdGenericWatchdogEl2IntrNum
[Protocols]
gEfiWatchdogTimerArchProtocolGuid
diff --git a/ArmPkg/Include/AsmMacroIoLib.h b/ArmPkg/Include/AsmMacroIoLib.h
index 408b2ca280..6904bdc9b0 100644
--- a/ArmPkg/Include/AsmMacroIoLib.h
+++ b/ArmPkg/Include/AsmMacroIoLib.h
@@ -149,7 +149,7 @@ _SetPrimaryStackEnd:
_InitializePrimaryStackLoop: ; \
cmp Tmp1, sp ; \
bls _InitializePrimaryStackEnd ; \
- str GlobalSize, [Tmp1], #-4 ; \
+ str GlobalSize, [Tmp1, #-4]! ; \
b _InitializePrimaryStackLoop ; \
_InitializePrimaryStackEnd:
@@ -228,7 +228,7 @@ _SetPrimaryStackEnd:
_InitializePrimaryStackLoop: ; \
cmp Tmp1, sp ; \
bls _InitializePrimaryStackEnd ; \
- str GlobalSize, [Tmp1], #-4 ; \
+ str GlobalSize, [Tmp1, #-4]! ; \
b _InitializePrimaryStackLoop ; \
_InitializePrimaryStackEnd:
diff --git a/ArmPkg/Include/AsmMacroIoLib.inc b/ArmPkg/Include/AsmMacroIoLib.inc
index 87e497b31a..301bd890ac 100644
--- a/ArmPkg/Include/AsmMacroIoLib.inc
+++ b/ArmPkg/Include/AsmMacroIoLib.inc
@@ -113,7 +113,7 @@ _SetPrimaryStackEnd
_InitializePrimaryStackLoop
cmp $Tmp1, sp
bls _InitializePrimaryStackEnd
- str $GlobalSize, [$Tmp1], #-4
+ str $GlobalSize, [$Tmp1, #-4]!
b _InitializePrimaryStackLoop
_InitializePrimaryStackEnd
MEND
diff --git a/ArmPkg/Include/Library/ArmBdsHelperLib.h b/ArmPkg/Include/Library/ArmBdsHelperLib.h
new file mode 100644
index 0000000000..eefe921333
--- /dev/null
+++ b/ArmPkg/Include/Library/ArmBdsHelperLib.h
@@ -0,0 +1,96 @@
+#ifndef __ARMBDSHELPERLIB_H
+#define __ARMBDSHELPERLIB_H
+
+#include <Uefi/UefiBaseType.h>
+
+/**
+ Return the value of a global variable defined by its VariableName.
+ The variable must be defined with the VendorGuid gEfiGlobalVariableGuid.
+
+ @param VariableName A Null-terminated string that is the name of the vendor's
+ variable.
+ @param DefaultValue Value returned by the function if the variable does not exist
+ @param DataSize On input, the size in bytes of the return Data buffer.
+ On output the size of data returned in Data.
+ @param Value Value read from the UEFI Variable or copy of the default value
+ if the UEFI Variable does not exist
+
+ @retval EFI_SUCCESS All drivers have been connected
+ @retval EFI_NOT_FOUND No handles match the search.
+ @retval EFI_OUT_OF_RESOURCES There is not resource pool memory to store the matching results.
+
+**/
+EFI_STATUS
+GetGlobalEnvironmentVariable (
+ IN CONST CHAR16* VariableName,
+ IN VOID* DefaultValue,
+ IN OUT UINTN* Size,
+ OUT VOID** Value
+ );
+
+/**
+ Return the value of the variable defined by its VariableName and VendorGuid
+
+ @param VariableName A Null-terminated string that is the name of the vendor's
+ variable.
+ @param VendorGuid A unique identifier for the vendor.
+ @param DefaultValue Value returned by the function if the variable does not exist
+ @param DataSize On input, the size in bytes of the return Data buffer.
+ On output the size of data returned in Data.
+ @param Value Value read from the UEFI Variable or copy of the default value
+ if the UEFI Variable does not exist
+
+ @retval EFI_SUCCESS All drivers have been connected
+ @retval EFI_NOT_FOUND No handles match the search.
+ @retval EFI_OUT_OF_RESOURCES There is not resource pool memory to store the matching results.
+
+**/
+EFI_STATUS
+GetEnvironmentVariable (
+ IN CONST CHAR16* VariableName,
+ IN EFI_GUID* VendorGuid,
+ IN VOID* DefaultValue,
+ IN OUT UINTN* Size,
+ OUT VOID** Value
+ );
+
+EFI_STATUS
+BdsConnectAndUpdateDevicePath (
+ IN OUT EFI_DEVICE_PATH_PROTOCOL **DevicePath,
+ OUT EFI_HANDLE *Handle,
+ OUT EFI_DEVICE_PATH_PROTOCOL **RemainingDevicePath
+ );
+
+/**
+ Connect a Device Path and return the handle of the driver that support this DevicePath
+
+ @param DevicePath Device Path of the File to connect
+ @param Handle Handle of the driver that support this DevicePath
+ @param RemainingDevicePath Remaining DevicePath nodes that do not match the driver DevicePath
+
+ @retval EFI_SUCCESS A driver that matches the Device Path has been found
+ @retval EFI_NOT_FOUND No handles match the search.
+ @retval EFI_INVALID_PARAMETER DevicePath or Handle is NULL
+
+**/
+EFI_STATUS
+BdsConnectDevicePath (
+ IN EFI_DEVICE_PATH_PROTOCOL* DevicePath,
+ OUT EFI_HANDLE *Handle,
+ OUT EFI_DEVICE_PATH_PROTOCOL **RemainingDevicePath
+ );
+
+/**
+ Connect all DXE drivers
+
+ @retval EFI_SUCCESS All drivers have been connected
+ @retval EFI_NOT_FOUND No handles match the search.
+ @retval EFI_OUT_OF_RESOURCES There is not resource pool memory to store the matching results.
+
+**/
+EFI_STATUS
+BdsConnectAllDrivers (
+ VOID
+ );
+
+#endif
diff --git a/ArmPkg/Library/ArmBdsHelperLib/ArmBdsHelperLib.c b/ArmPkg/Library/ArmBdsHelperLib/ArmBdsHelperLib.c
new file mode 100644
index 0000000000..8d8bab4e2f
--- /dev/null
+++ b/ArmPkg/Library/ArmBdsHelperLib/ArmBdsHelperLib.c
@@ -0,0 +1,487 @@
+#include <Guid/GlobalVariable.h>
+#include <Library/ArmBdsHelperLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DevicePathLib.h>
+#include <Library/DxeServicesTableLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+#include <Protocol/DiskIo.h>
+#include <Protocol/UsbIo.h>
+
+#define IS_DEVICE_PATH_NODE(node,type,subtype) (((node)->Type == (type)) && ((node)->SubType == (subtype)))
+
+EFI_STATUS
+GetGlobalEnvironmentVariable (
+ IN CONST CHAR16* VariableName,
+ IN VOID* DefaultValue,
+ IN OUT UINTN* Size,
+ OUT VOID** Value
+ )
+{
+ return GetEnvironmentVariable (VariableName, &gEfiGlobalVariableGuid,
+ DefaultValue, Size, Value);
+}
+
+EFI_STATUS
+GetEnvironmentVariable (
+ IN CONST CHAR16* VariableName,
+ IN EFI_GUID* VendorGuid,
+ IN VOID* DefaultValue,
+ IN OUT UINTN* Size,
+ OUT VOID** Value
+ )
+{
+ EFI_STATUS Status;
+ UINTN VariableSize;
+
+ // Try to get the variable size.
+ *Value = NULL;
+ VariableSize = 0;
+ Status = gRT->GetVariable ((CHAR16 *) VariableName, VendorGuid, NULL, &VariableSize, *Value);
+ if (Status == EFI_NOT_FOUND) {
+ if ((DefaultValue != NULL) && (Size != NULL) && (*Size != 0)) {
+ // If the environment variable does not exist yet then set it with the default value
+ Status = gRT->SetVariable (
+ (CHAR16*)VariableName,
+ VendorGuid,
+ EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
+ *Size,
+ DefaultValue
+ );
+ *Value = AllocateCopyPool (*Size, DefaultValue);
+ } else {
+ return EFI_NOT_FOUND;
+ }
+ } else if (Status == EFI_BUFFER_TOO_SMALL) {
+ // Get the environment variable value
+ *Value = AllocatePool (VariableSize);
+ if (*Value == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ Status = gRT->GetVariable ((CHAR16 *)VariableName, VendorGuid, NULL, &VariableSize, *Value);
+ if (EFI_ERROR (Status)) {
+ FreePool(*Value);
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (Size) {
+ *Size = VariableSize;
+ }
+ } else {
+ *Value = AllocateCopyPool (*Size, DefaultValue);
+ return Status;
+ }
+
+ return EFI_SUCCESS;
+}
+
+BOOLEAN
+BdsIsRemovableUsb (
+ IN EFI_DEVICE_PATH* DevicePath
+ )
+{
+ return ((DevicePathType (DevicePath) == MESSAGING_DEVICE_PATH) &&
+ ((DevicePathSubType (DevicePath) == MSG_USB_CLASS_DP) ||
+ (DevicePathSubType (DevicePath) == MSG_USB_WWID_DP)));
+}
+
+EFI_STATUS
+BdsGetDeviceUsb (
+ IN EFI_DEVICE_PATH* RemovableDevicePath,
+ OUT EFI_HANDLE* DeviceHandle,
+ OUT EFI_DEVICE_PATH** NewDevicePath
+ )
+{
+ EFI_STATUS Status;
+ UINTN Index;
+ UINTN UsbIoHandleCount;
+ EFI_HANDLE *UsbIoBuffer;
+ EFI_DEVICE_PATH* UsbIoDevicePath;
+ EFI_DEVICE_PATH* TmpDevicePath;
+ USB_WWID_DEVICE_PATH* WwidDevicePath1;
+ USB_WWID_DEVICE_PATH* WwidDevicePath2;
+ USB_CLASS_DEVICE_PATH* UsbClassDevicePath1;
+ USB_CLASS_DEVICE_PATH* UsbClassDevicePath2;
+
+ // Get all the UsbIo handles
+ UsbIoHandleCount = 0;
+ Status = gBS->LocateHandleBuffer (ByProtocol, &gEfiUsbIoProtocolGuid, NULL, &UsbIoHandleCount, &UsbIoBuffer);
+ if (EFI_ERROR (Status) || (UsbIoHandleCount == 0)) {
+ return Status;
+ }
+
+ // Check if one of the handles matches the USB description
+ for (Index = 0; Index < UsbIoHandleCount; Index++) {
+ Status = gBS->HandleProtocol (UsbIoBuffer[Index], &gEfiDevicePathProtocolGuid, (VOID **) &UsbIoDevicePath);
+ if (!EFI_ERROR (Status)) {
+ TmpDevicePath = UsbIoDevicePath;
+ while (!IsDevicePathEnd (TmpDevicePath)) {
+ // Check if the Device Path node is a USB Removable device Path node
+ if (BdsIsRemovableUsb (TmpDevicePath)) {
+ if (TmpDevicePath->SubType == MSG_USB_WWID_DP) {
+ WwidDevicePath1 = (USB_WWID_DEVICE_PATH*)RemovableDevicePath;
+ WwidDevicePath2 = (USB_WWID_DEVICE_PATH*)TmpDevicePath;
+ if ((WwidDevicePath1->VendorId == WwidDevicePath2->VendorId) &&
+ (WwidDevicePath1->ProductId == WwidDevicePath2->ProductId) &&
+ (CompareMem (WwidDevicePath1+1, WwidDevicePath2+1, DevicePathNodeLength(WwidDevicePath1)-sizeof (USB_WWID_DEVICE_PATH)) == 0))
+ {
+ *DeviceHandle = UsbIoBuffer[Index];
+ // Add the additional original Device Path Nodes (eg: FilePath Device Path Node) to the new Device Path
+ *NewDevicePath = AppendDevicePath (UsbIoDevicePath, NextDevicePathNode (RemovableDevicePath));
+ return EFI_SUCCESS;
+ }
+ } else {
+ UsbClassDevicePath1 = (USB_CLASS_DEVICE_PATH*)RemovableDevicePath;
+ UsbClassDevicePath2 = (USB_CLASS_DEVICE_PATH*)TmpDevicePath;
+ if ((UsbClassDevicePath1->VendorId != 0xFFFF) && (UsbClassDevicePath1->VendorId == UsbClassDevicePath2->VendorId) &&
+ (UsbClassDevicePath1->ProductId != 0xFFFF) && (UsbClassDevicePath1->ProductId == UsbClassDevicePath2->ProductId) &&
+ (UsbClassDevicePath1->DeviceClass != 0xFF) && (UsbClassDevicePath1->DeviceClass == UsbClassDevicePath2->DeviceClass) &&
+ (UsbClassDevicePath1->DeviceSubClass != 0xFF) && (UsbClassDevicePath1->DeviceSubClass == UsbClassDevicePath2->DeviceSubClass) &&
+ (UsbClassDevicePath1->DeviceProtocol != 0xFF) && (UsbClassDevicePath1->DeviceProtocol == UsbClassDevicePath2->DeviceProtocol))
+ {
+ *DeviceHandle = UsbIoBuffer[Index];
+ // Add the additional original Device Path Nodes (eg: FilePath Device Path Node) to the new Device Path
+ *NewDevicePath = AppendDevicePath (UsbIoDevicePath, NextDevicePathNode (RemovableDevicePath));
+ return EFI_SUCCESS;
+ }
+ }
+ }
+ TmpDevicePath = NextDevicePathNode (TmpDevicePath);
+ }
+
+ }
+ }
+
+ return EFI_NOT_FOUND;
+}
+
+BOOLEAN
+BdsIsRemovableHd (
+ IN EFI_DEVICE_PATH* DevicePath
+ )
+{
+ return IS_DEVICE_PATH_NODE (DevicePath, MEDIA_DEVICE_PATH, MEDIA_HARDDRIVE_DP);
+}
+
+EFI_STATUS
+BdsGetDeviceHd (
+ IN EFI_DEVICE_PATH* RemovableDevicePath,
+ OUT EFI_HANDLE* DeviceHandle,
+ OUT EFI_DEVICE_PATH** NewDevicePath
+ )
+{
+ EFI_STATUS Status;
+ UINTN Index;
+ UINTN PartitionHandleCount;
+ EFI_HANDLE *PartitionBuffer;
+ EFI_DEVICE_PATH* PartitionDevicePath;
+ EFI_DEVICE_PATH* TmpDevicePath;
+ HARDDRIVE_DEVICE_PATH* HardDriveDevicePath1;
+ HARDDRIVE_DEVICE_PATH* HardDriveDevicePath2;
+
+ // Get all the DiskIo handles
+ PartitionHandleCount = 0;
+ Status = gBS->LocateHandleBuffer (ByProtocol, &gEfiDiskIoProtocolGuid, NULL, &PartitionHandleCount, &PartitionBuffer);
+ if (EFI_ERROR (Status) || (PartitionHandleCount == 0)) {
+ return Status;
+ }
+
+ // Check if one of the handles matches the Hard Disk Description
+ for (Index = 0; Index < PartitionHandleCount; Index++) {
+ Status = gBS->HandleProtocol (PartitionBuffer[Index], &gEfiDevicePathProtocolGuid, (VOID **) &PartitionDevicePath);
+ if (!EFI_ERROR (Status)) {
+ TmpDevicePath = PartitionDevicePath;
+ while (!IsDevicePathEnd (TmpDevicePath)) {
+ // Check if the Device Path node is a HD Removable device Path node
+ if (BdsIsRemovableHd (TmpDevicePath)) {
+ HardDriveDevicePath1 = (HARDDRIVE_DEVICE_PATH*)RemovableDevicePath;
+ HardDriveDevicePath2 = (HARDDRIVE_DEVICE_PATH*)TmpDevicePath;
+ if ((HardDriveDevicePath1->SignatureType == HardDriveDevicePath2->SignatureType) &&
+ (CompareGuid ((EFI_GUID *)HardDriveDevicePath1->Signature, (EFI_GUID *)HardDriveDevicePath2->Signature) == TRUE) &&
+ (HardDriveDevicePath1->PartitionNumber == HardDriveDevicePath2->PartitionNumber))
+ {
+ *DeviceHandle = PartitionBuffer[Index];
+ // Add the additional original Device Path Nodes (eg: FilePath Device Path Node) to the new Device Path
+ *NewDevicePath = AppendDevicePath (PartitionDevicePath, NextDevicePathNode (RemovableDevicePath));
+ return EFI_SUCCESS;
+ }
+ }
+ TmpDevicePath = NextDevicePathNode (TmpDevicePath);
+ }
+
+ }
+ }
+
+ return EFI_NOT_FOUND;
+}
+
+/*BOOLEAN
+BdsIsRemovableCdrom (
+ IN EFI_DEVICE_PATH* DevicePath
+ )
+{
+ return IS_DEVICE_PATH_NODE (DevicePath, MEDIA_DEVICE_PATH, MEDIA_CDROM_DP);
+}
+
+EFI_STATUS
+BdsGetDeviceCdrom (
+ IN EFI_DEVICE_PATH* RemovableDevicePath,
+ OUT EFI_HANDLE* DeviceHandle,
+ OUT EFI_DEVICE_PATH** DevicePath
+ )
+{
+ ASSERT(0);
+ return EFI_UNSUPPORTED;
+}*/
+
+typedef BOOLEAN
+(*BDS_IS_REMOVABLE) (
+ IN EFI_DEVICE_PATH* DevicePath
+ );
+
+typedef EFI_STATUS
+(*BDS_GET_DEVICE) (
+ IN EFI_DEVICE_PATH* RemovableDevicePath,
+ OUT EFI_HANDLE* DeviceHandle,
+ OUT EFI_DEVICE_PATH** DevicePath
+ );
+
+typedef struct {
+ BDS_IS_REMOVABLE IsRemovable;
+ BDS_GET_DEVICE GetDevice;
+} BDS_REMOVABLE_DEVICE_SUPPORT;
+
+BDS_REMOVABLE_DEVICE_SUPPORT RemovableDeviceSupport[] = {
+ { BdsIsRemovableUsb, BdsGetDeviceUsb },
+ { BdsIsRemovableHd, BdsGetDeviceHd },
+ //{ BdsIsRemovableCdrom, BdsGetDeviceCdrom }
+};
+
+STATIC
+BOOLEAN
+IsRemovableDevice (
+ IN EFI_DEVICE_PATH* DevicePath
+ )
+{
+ UINTN Index;
+ EFI_DEVICE_PATH* TmpDevicePath;
+
+ TmpDevicePath = DevicePath;
+ while (!IsDevicePathEnd (TmpDevicePath)) {
+ for (Index = 0; Index < sizeof (RemovableDeviceSupport) / sizeof (BDS_REMOVABLE_DEVICE_SUPPORT); Index++) {
+ if (RemovableDeviceSupport[Index].IsRemovable (TmpDevicePath)) {
+ return TRUE;
+ }
+ }
+ TmpDevicePath = NextDevicePathNode (TmpDevicePath);
+ }
+
+ return FALSE;
+}
+
+STATIC
+EFI_STATUS
+TryRemovableDevice (
+ IN EFI_DEVICE_PATH* DevicePath,
+ OUT EFI_HANDLE* DeviceHandle,
+ OUT EFI_DEVICE_PATH** NewDevicePath
+ )
+{
+ EFI_STATUS Status;
+ UINTN Index;
+ EFI_DEVICE_PATH* TmpDevicePath;
+ BDS_REMOVABLE_DEVICE_SUPPORT* RemovableDevice;
+ EFI_DEVICE_PATH* RemovableDevicePath;
+ BOOLEAN RemovableFound;
+
+ RemovableDevice = NULL;
+ RemovableDevicePath = NULL;
+ RemovableFound = FALSE;
+ TmpDevicePath = DevicePath;
+
+ while (!IsDevicePathEnd (TmpDevicePath) && !RemovableFound) {
+ for (Index = 0; Index < sizeof (RemovableDeviceSupport) / sizeof (BDS_REMOVABLE_DEVICE_SUPPORT); Index++) {
+ RemovableDevice = &RemovableDeviceSupport[Index];
+ if (RemovableDevice->IsRemovable (TmpDevicePath)) {
+ RemovableDevicePath = TmpDevicePath;
+ RemovableFound = TRUE;
+ break;
+ }
+ }
+ TmpDevicePath = NextDevicePathNode (TmpDevicePath);
+ }
+
+ if (!RemovableFound) {
+ return EFI_NOT_FOUND;
+ }
+
+ // Search into the current started drivers
+ Status = RemovableDevice->GetDevice (RemovableDevicePath, DeviceHandle, NewDevicePath);
+ if (Status == EFI_NOT_FOUND) {
+ // Connect all the drivers
+ BdsConnectAllDrivers ();
+
+ // Search again into all the drivers
+ Status = RemovableDevice->GetDevice (RemovableDevicePath, DeviceHandle, NewDevicePath);
+ }
+
+ return Status;
+}
+
+EFI_STATUS
+BdsConnectAndUpdateDevicePath (
+ IN OUT EFI_DEVICE_PATH_PROTOCOL **DevicePath,
+ OUT EFI_HANDLE *Handle,
+ OUT EFI_DEVICE_PATH_PROTOCOL **RemainingDevicePath
+ )
+{
+ EFI_DEVICE_PATH* Remaining;
+ EFI_DEVICE_PATH* NewDevicePath;
+ EFI_STATUS Status;
+ EFI_HANDLE PreviousHandle;
+
+ if ((DevicePath == NULL) || (*DevicePath == NULL) || (Handle == NULL)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ PreviousHandle = NULL;
+ do {
+ Remaining = *DevicePath;
+
+ // The LocateDevicePath() function locates all devices on DevicePath that support Protocol and returns
+ // the handle to the device that is closest to DevicePath. On output, the device path pointer is modified
+ // to point to the remaining part of the device path
+ Status = gBS->LocateDevicePath (&gEfiDevicePathProtocolGuid, &Remaining, Handle);
+
+ if (!EFI_ERROR (Status)) {
+ if (*Handle == PreviousHandle) {
+ //
+ // If no forward progress is made try invoking the Dispatcher.
+ // A new FV may have been added to the system and new drivers
+ // may now be found.
+ // Status == EFI_SUCCESS means a driver was dispatched
+ // Status == EFI_NOT_FOUND means no new drivers were dispatched
+ //
+ Status = gDS->Dispatch ();
+ }
+
+ if (!EFI_ERROR (Status)) {
+ PreviousHandle = *Handle;
+
+ // Recursive = FALSE: We do not want to start the whole device tree
+ Status = gBS->ConnectController (*Handle, NULL, Remaining, FALSE);
+ }
+ }
+ } while (!EFI_ERROR (Status) && !IsDevicePathEnd (Remaining));
+
+ if (!EFI_ERROR (Status)) {
+ // Now, we have got the whole Device Path connected, call again ConnectController to ensure all the supported Driver
+ // Binding Protocol are connected (such as DiskIo and SimpleFileSystem)
+ Remaining = *DevicePath;
+ Status = gBS->LocateDevicePath (&gEfiDevicePathProtocolGuid, &Remaining, Handle);
+ if (!EFI_ERROR (Status)) {
+ Status = gBS->ConnectController (*Handle, NULL, Remaining, FALSE);
+ if (EFI_ERROR (Status)) {
+ // If the last node is a Memory Map Device Path just return EFI_SUCCESS.
+ if ((Remaining->Type == HARDWARE_DEVICE_PATH) && (Remaining->SubType == HW_MEMMAP_DP)) {
+ Status = EFI_SUCCESS;
+ }
+ }
+ }
+ } else if (!IsDevicePathEnd (Remaining) && !IsRemovableDevice (Remaining)) {
+
+ /*// If the remaining Device Path is a FilePath or MemoryMap then we consider the Device Path has been loaded correctly
+ if ((Remaining->Type == MEDIA_DEVICE_PATH) && (Remaining->SubType == MEDIA_FILEPATH_DP)) {
+ Status = EFI_SUCCESS;
+ } else if ((Remaining->Type == HARDWARE_DEVICE_PATH) && (Remaining->SubType == HW_MEMMAP_DP)) {
+ Status = EFI_SUCCESS;
+ }*/
+
+ //TODO: Should we just return success and leave the caller decide if it is the expected RemainingPath
+ Status = EFI_SUCCESS;
+ } else {
+ Status = TryRemovableDevice (*DevicePath, Handle, &NewDevicePath);
+ if (!EFI_ERROR (Status)) {
+ Status = BdsConnectAndUpdateDevicePath (&NewDevicePath, Handle, RemainingDevicePath);
+ *DevicePath = NewDevicePath;
+ return Status;
+ }
+ }
+
+ if (RemainingDevicePath) {
+ *RemainingDevicePath = Remaining;
+ }
+
+ return Status;
+}
+
+/**
+ Connect a Device Path and return the handle of the driver that support this DevicePath
+
+ @param DevicePath Device Path of the File to connect
+ @param Handle Handle of the driver that support this DevicePath
+ @param RemainingDevicePath Remaining DevicePath nodes that do not match the driver DevicePath
+
+ @retval EFI_SUCCESS A driver that matches the Device Path has been found
+ @retval EFI_NOT_FOUND No handles match the search.
+ @retval EFI_INVALID_PARAMETER DevicePath or Handle is NULL
+
+**/
+EFI_STATUS
+BdsConnectDevicePath (
+ IN EFI_DEVICE_PATH_PROTOCOL* DevicePath,
+ OUT EFI_HANDLE *Handle,
+ OUT EFI_DEVICE_PATH_PROTOCOL **RemainingDevicePath
+ )
+{
+ return BdsConnectAndUpdateDevicePath (&DevicePath, Handle, RemainingDevicePath);
+}
+
+/**
+ Connect all DXE drivers
+
+ @retval EFI_SUCCESS All drivers have been connected
+ @retval EFI_NOT_FOUND No handles match the search.
+ @retval EFI_OUT_OF_RESOURCES There is not resource pool memory to store the matching results.
+
+**/
+EFI_STATUS
+BdsConnectAllDrivers (
+ VOID
+ )
+{
+ UINTN HandleCount, Index;
+ EFI_HANDLE *HandleBuffer;
+ EFI_STATUS Status;
+
+ do {
+ // Locate all the driver handles
+ Status = gBS->LocateHandleBuffer (
+ AllHandles,
+ NULL,
+ NULL,
+ &HandleCount,
+ &HandleBuffer
+ );
+ if (EFI_ERROR (Status)) {
+ break;
+ }
+
+ // Connect every handles
+ for (Index = 0; Index < HandleCount; Index++) {
+ gBS->ConnectController (HandleBuffer[Index], NULL, NULL, TRUE);
+ }
+
+ if (HandleBuffer != NULL) {
+ FreePool (HandleBuffer);
+ }
+
+ // Check if new handles have been created after the start of the previous handles
+ Status = gDS->Dispatch ();
+ } while (!EFI_ERROR(Status));
+
+ return EFI_SUCCESS;
+}
+
diff --git a/ArmPkg/Library/ArmBdsHelperLib/ArmBdsHelperLib.inf b/ArmPkg/Library/ArmBdsHelperLib/ArmBdsHelperLib.inf
new file mode 100644
index 0000000000..7b7e2d047d
--- /dev/null
+++ b/ArmPkg/Library/ArmBdsHelperLib/ArmBdsHelperLib.inf
@@ -0,0 +1,45 @@
+#/* @file
+#
+# Copyright (c) 2011-2014, 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]
+ INF_VERSION = 0x00010005
+ BASE_NAME = ArmBdsHelperLib
+ FILE_GUID = f2d77b71-f2a5-4a6d-85f3-0b7760510804
+ MODULE_TYPE = DXE_DRIVER
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = ArmBdsHelperLib
+
+[Sources]
+ ArmBdsHelperLib.c
+
+[Packages]
+ ArmPkg/ArmPkg.dec
+ ArmPlatformPkg/ArmPlatformPkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ MdePkg/MdePkg.dec
+
+[LibraryClasses]
+ BaseLib
+ DebugLib
+ DevicePathLib
+ PcdLib
+
+[Guids]
+ gArmGlobalVariableGuid
+
+[Protocols]
+ gEfiDevicePathFromTextProtocolGuid
+ gEfiDevicePathProtocolGuid
+ gEfiDiskIoProtocolGuid
+ gEfiUsbIoProtocolGuid
diff --git a/ArmPkg/Library/BdsLib/BdsFilePath.c b/ArmPkg/Library/BdsLib/BdsFilePath.c
index 0057d94126..954cafdce4 100644
--- a/ArmPkg/Library/BdsLib/BdsFilePath.c
+++ b/ArmPkg/Library/BdsLib/BdsFilePath.c
@@ -14,6 +14,7 @@
#include "BdsInternal.h"
+#include <Library/ArmBdsHelperLib.h>
#include <Library/NetLib.h>
#include <Protocol/Bds.h>
@@ -76,369 +77,6 @@ BdsExtractFilePathFromDevicePath (
}
BOOLEAN
-BdsIsRemovableUsb (
- IN EFI_DEVICE_PATH* DevicePath
- )
-{
- return ((DevicePathType (DevicePath) == MESSAGING_DEVICE_PATH) &&
- ((DevicePathSubType (DevicePath) == MSG_USB_CLASS_DP) ||
- (DevicePathSubType (DevicePath) == MSG_USB_WWID_DP)));
-}
-
-EFI_STATUS
-BdsGetDeviceUsb (
- IN EFI_DEVICE_PATH* RemovableDevicePath,
- OUT EFI_HANDLE* DeviceHandle,
- OUT EFI_DEVICE_PATH** NewDevicePath
- )
-{
- EFI_STATUS Status;
- UINTN Index;
- UINTN UsbIoHandleCount;
- EFI_HANDLE *UsbIoBuffer;
- EFI_DEVICE_PATH* UsbIoDevicePath;
- EFI_DEVICE_PATH* TmpDevicePath;
- USB_WWID_DEVICE_PATH* WwidDevicePath1;
- USB_WWID_DEVICE_PATH* WwidDevicePath2;
- USB_CLASS_DEVICE_PATH* UsbClassDevicePath1;
- USB_CLASS_DEVICE_PATH* UsbClassDevicePath2;
-
- // Get all the UsbIo handles
- UsbIoHandleCount = 0;
- Status = gBS->LocateHandleBuffer (ByProtocol, &gEfiUsbIoProtocolGuid, NULL, &UsbIoHandleCount, &UsbIoBuffer);
- if (EFI_ERROR (Status) || (UsbIoHandleCount == 0)) {
- return Status;
- }
-
- // Check if one of the handles matches the USB description
- for (Index = 0; Index < UsbIoHandleCount; Index++) {
- Status = gBS->HandleProtocol (UsbIoBuffer[Index], &gEfiDevicePathProtocolGuid, (VOID **) &UsbIoDevicePath);
- if (!EFI_ERROR (Status)) {
- TmpDevicePath = UsbIoDevicePath;
- while (!IsDevicePathEnd (TmpDevicePath)) {
- // Check if the Device Path node is a USB Removable device Path node
- if (BdsIsRemovableUsb (TmpDevicePath)) {
- if (TmpDevicePath->SubType == MSG_USB_WWID_DP) {
- WwidDevicePath1 = (USB_WWID_DEVICE_PATH*)RemovableDevicePath;
- WwidDevicePath2 = (USB_WWID_DEVICE_PATH*)TmpDevicePath;
- if ((WwidDevicePath1->VendorId == WwidDevicePath2->VendorId) &&
- (WwidDevicePath1->ProductId == WwidDevicePath2->ProductId) &&
- (CompareMem (WwidDevicePath1+1, WwidDevicePath2+1, DevicePathNodeLength(WwidDevicePath1)-sizeof (USB_WWID_DEVICE_PATH)) == 0))
- {
- *DeviceHandle = UsbIoBuffer[Index];
- // Add the additional original Device Path Nodes (eg: FilePath Device Path Node) to the new Device Path
- *NewDevicePath = AppendDevicePath (UsbIoDevicePath, NextDevicePathNode (RemovableDevicePath));
- return EFI_SUCCESS;
- }
- } else {
- UsbClassDevicePath1 = (USB_CLASS_DEVICE_PATH*)RemovableDevicePath;
- UsbClassDevicePath2 = (USB_CLASS_DEVICE_PATH*)TmpDevicePath;
- if ((UsbClassDevicePath1->VendorId != 0xFFFF) && (UsbClassDevicePath1->VendorId == UsbClassDevicePath2->VendorId) &&
- (UsbClassDevicePath1->ProductId != 0xFFFF) && (UsbClassDevicePath1->ProductId == UsbClassDevicePath2->ProductId) &&
- (UsbClassDevicePath1->DeviceClass != 0xFF) && (UsbClassDevicePath1->DeviceClass == UsbClassDevicePath2->DeviceClass) &&
- (UsbClassDevicePath1->DeviceSubClass != 0xFF) && (UsbClassDevicePath1->DeviceSubClass == UsbClassDevicePath2->DeviceSubClass) &&
- (UsbClassDevicePath1->DeviceProtocol != 0xFF) && (UsbClassDevicePath1->DeviceProtocol == UsbClassDevicePath2->DeviceProtocol))
- {
- *DeviceHandle = UsbIoBuffer[Index];
- // Add the additional original Device Path Nodes (eg: FilePath Device Path Node) to the new Device Path
- *NewDevicePath = AppendDevicePath (UsbIoDevicePath, NextDevicePathNode (RemovableDevicePath));
- return EFI_SUCCESS;
- }
- }
- }
- TmpDevicePath = NextDevicePathNode (TmpDevicePath);
- }
-
- }
- }
-
- return EFI_NOT_FOUND;
-}
-
-BOOLEAN
-BdsIsRemovableHd (
- IN EFI_DEVICE_PATH* DevicePath
- )
-{
- return IS_DEVICE_PATH_NODE (DevicePath, MEDIA_DEVICE_PATH, MEDIA_HARDDRIVE_DP);
-}
-
-EFI_STATUS
-BdsGetDeviceHd (
- IN EFI_DEVICE_PATH* RemovableDevicePath,
- OUT EFI_HANDLE* DeviceHandle,
- OUT EFI_DEVICE_PATH** NewDevicePath
- )
-{
- EFI_STATUS Status;
- UINTN Index;
- UINTN PartitionHandleCount;
- EFI_HANDLE *PartitionBuffer;
- EFI_DEVICE_PATH* PartitionDevicePath;
- EFI_DEVICE_PATH* TmpDevicePath;
- HARDDRIVE_DEVICE_PATH* HardDriveDevicePath1;
- HARDDRIVE_DEVICE_PATH* HardDriveDevicePath2;
-
- // Get all the DiskIo handles
- PartitionHandleCount = 0;
- Status = gBS->LocateHandleBuffer (ByProtocol, &gEfiDiskIoProtocolGuid, NULL, &PartitionHandleCount, &PartitionBuffer);
- if (EFI_ERROR (Status) || (PartitionHandleCount == 0)) {
- return Status;
- }
-
- // Check if one of the handles matches the Hard Disk Description
- for (Index = 0; Index < PartitionHandleCount; Index++) {
- Status = gBS->HandleProtocol (PartitionBuffer[Index], &gEfiDevicePathProtocolGuid, (VOID **) &PartitionDevicePath);
- if (!EFI_ERROR (Status)) {
- TmpDevicePath = PartitionDevicePath;
- while (!IsDevicePathEnd (TmpDevicePath)) {
- // Check if the Device Path node is a HD Removable device Path node
- if (BdsIsRemovableHd (TmpDevicePath)) {
- HardDriveDevicePath1 = (HARDDRIVE_DEVICE_PATH*)RemovableDevicePath;
- HardDriveDevicePath2 = (HARDDRIVE_DEVICE_PATH*)TmpDevicePath;
- if ((HardDriveDevicePath1->SignatureType == HardDriveDevicePath2->SignatureType) &&
- (CompareGuid ((EFI_GUID *)HardDriveDevicePath1->Signature, (EFI_GUID *)HardDriveDevicePath2->Signature) == TRUE) &&
- (HardDriveDevicePath1->PartitionNumber == HardDriveDevicePath2->PartitionNumber))
- {
- *DeviceHandle = PartitionBuffer[Index];
- // Add the additional original Device Path Nodes (eg: FilePath Device Path Node) to the new Device Path
- *NewDevicePath = AppendDevicePath (PartitionDevicePath, NextDevicePathNode (RemovableDevicePath));
- return EFI_SUCCESS;
- }
- }
- TmpDevicePath = NextDevicePathNode (TmpDevicePath);
- }
-
- }
- }
-
- return EFI_NOT_FOUND;
-}
-
-/*BOOLEAN
-BdsIsRemovableCdrom (
- IN EFI_DEVICE_PATH* DevicePath
- )
-{
- return IS_DEVICE_PATH_NODE (DevicePath, MEDIA_DEVICE_PATH, MEDIA_CDROM_DP);
-}
-
-EFI_STATUS
-BdsGetDeviceCdrom (
- IN EFI_DEVICE_PATH* RemovableDevicePath,
- OUT EFI_HANDLE* DeviceHandle,
- OUT EFI_DEVICE_PATH** DevicePath
- )
-{
- ASSERT(0);
- return EFI_UNSUPPORTED;
-}*/
-
-typedef BOOLEAN
-(*BDS_IS_REMOVABLE) (
- IN EFI_DEVICE_PATH* DevicePath
- );
-
-typedef EFI_STATUS
-(*BDS_GET_DEVICE) (
- IN EFI_DEVICE_PATH* RemovableDevicePath,
- OUT EFI_HANDLE* DeviceHandle,
- OUT EFI_DEVICE_PATH** DevicePath
- );
-
-typedef struct {
- BDS_IS_REMOVABLE IsRemovable;
- BDS_GET_DEVICE GetDevice;
-} BDS_REMOVABLE_DEVICE_SUPPORT;
-
-BDS_REMOVABLE_DEVICE_SUPPORT RemovableDeviceSupport[] = {
- { BdsIsRemovableUsb, BdsGetDeviceUsb },
- { BdsIsRemovableHd, BdsGetDeviceHd },
- //{ BdsIsRemovableCdrom, BdsGetDeviceCdrom }
-};
-
-STATIC
-BOOLEAN
-IsRemovableDevice (
- IN EFI_DEVICE_PATH* DevicePath
- )
-{
- UINTN Index;
- EFI_DEVICE_PATH* TmpDevicePath;
-
- TmpDevicePath = DevicePath;
- while (!IsDevicePathEnd (TmpDevicePath)) {
- for (Index = 0; Index < sizeof (RemovableDeviceSupport) / sizeof (BDS_REMOVABLE_DEVICE_SUPPORT); Index++) {
- if (RemovableDeviceSupport[Index].IsRemovable (TmpDevicePath)) {
- return TRUE;
- }
- }
- TmpDevicePath = NextDevicePathNode (TmpDevicePath);
- }
-
- return FALSE;
-}
-
-STATIC
-EFI_STATUS
-TryRemovableDevice (
- IN EFI_DEVICE_PATH* DevicePath,
- OUT EFI_HANDLE* DeviceHandle,
- OUT EFI_DEVICE_PATH** NewDevicePath
- )
-{
- EFI_STATUS Status;
- UINTN Index;
- EFI_DEVICE_PATH* TmpDevicePath;
- BDS_REMOVABLE_DEVICE_SUPPORT* RemovableDevice;
- EFI_DEVICE_PATH* RemovableDevicePath;
- BOOLEAN RemovableFound;
-
- RemovableDevice = NULL;
- RemovableDevicePath = NULL;
- RemovableFound = FALSE;
- TmpDevicePath = DevicePath;
-
- while (!IsDevicePathEnd (TmpDevicePath) && !RemovableFound) {
- for (Index = 0; Index < sizeof (RemovableDeviceSupport) / sizeof (BDS_REMOVABLE_DEVICE_SUPPORT); Index++) {
- RemovableDevice = &RemovableDeviceSupport[Index];
- if (RemovableDevice->IsRemovable (TmpDevicePath)) {
- RemovableDevicePath = TmpDevicePath;
- RemovableFound = TRUE;
- break;
- }
- }
- TmpDevicePath = NextDevicePathNode (TmpDevicePath);
- }
-
- if (!RemovableFound) {
- return EFI_NOT_FOUND;
- }
-
- // Search into the current started drivers
- Status = RemovableDevice->GetDevice (RemovableDevicePath, DeviceHandle, NewDevicePath);
- if (Status == EFI_NOT_FOUND) {
- // Connect all the drivers
- BdsConnectAllDrivers ();
-
- // Search again into all the drivers
- Status = RemovableDevice->GetDevice (RemovableDevicePath, DeviceHandle, NewDevicePath);
- }
-
- return Status;
-}
-
-STATIC
-EFI_STATUS
-BdsConnectAndUpdateDevicePath (
- IN OUT EFI_DEVICE_PATH_PROTOCOL **DevicePath,
- OUT EFI_HANDLE *Handle,
- OUT EFI_DEVICE_PATH_PROTOCOL **RemainingDevicePath
- )
-{
- EFI_DEVICE_PATH* Remaining;
- EFI_DEVICE_PATH* NewDevicePath;
- EFI_STATUS Status;
- EFI_HANDLE PreviousHandle;
-
- if ((DevicePath == NULL) || (*DevicePath == NULL) || (Handle == NULL)) {
- return EFI_INVALID_PARAMETER;
- }
-
- PreviousHandle = NULL;
- do {
- Remaining = *DevicePath;
-
- // The LocateDevicePath() function locates all devices on DevicePath that support Protocol and returns
- // the handle to the device that is closest to DevicePath. On output, the device path pointer is modified
- // to point to the remaining part of the device path
- Status = gBS->LocateDevicePath (&gEfiDevicePathProtocolGuid, &Remaining, Handle);
-
- if (!EFI_ERROR (Status)) {
- if (*Handle == PreviousHandle) {
- //
- // If no forward progress is made try invoking the Dispatcher.
- // A new FV may have been added to the system and new drivers
- // may now be found.
- // Status == EFI_SUCCESS means a driver was dispatched
- // Status == EFI_NOT_FOUND means no new drivers were dispatched
- //
- Status = gDS->Dispatch ();
- }
-
- if (!EFI_ERROR (Status)) {
- PreviousHandle = *Handle;
-
- // Recursive = FALSE: We do not want to start the whole device tree
- Status = gBS->ConnectController (*Handle, NULL, Remaining, FALSE);
- }
- }
- } while (!EFI_ERROR (Status) && !IsDevicePathEnd (Remaining));
-
- if (!EFI_ERROR (Status)) {
- // Now, we have got the whole Device Path connected, call again ConnectController to ensure all the supported Driver
- // Binding Protocol are connected (such as DiskIo and SimpleFileSystem)
- Remaining = *DevicePath;
- Status = gBS->LocateDevicePath (&gEfiDevicePathProtocolGuid, &Remaining, Handle);
- if (!EFI_ERROR (Status)) {
- Status = gBS->ConnectController (*Handle, NULL, Remaining, FALSE);
- if (EFI_ERROR (Status)) {
- // If the last node is a Memory Map Device Path just return EFI_SUCCESS.
- if ((Remaining->Type == HARDWARE_DEVICE_PATH) && (Remaining->SubType == HW_MEMMAP_DP)) {
- Status = EFI_SUCCESS;
- }
- }
- }
- } else if (!IsDevicePathEnd (Remaining) && !IsRemovableDevice (Remaining)) {
-
- /*// If the remaining Device Path is a FilePath or MemoryMap then we consider the Device Path has been loaded correctly
- if ((Remaining->Type == MEDIA_DEVICE_PATH) && (Remaining->SubType == MEDIA_FILEPATH_DP)) {
- Status = EFI_SUCCESS;
- } else if ((Remaining->Type == HARDWARE_DEVICE_PATH) && (Remaining->SubType == HW_MEMMAP_DP)) {
- Status = EFI_SUCCESS;
- }*/
-
- //TODO: Should we just return success and leave the caller decide if it is the expected RemainingPath
- Status = EFI_SUCCESS;
- } else {
- Status = TryRemovableDevice (*DevicePath, Handle, &NewDevicePath);
- if (!EFI_ERROR (Status)) {
- Status = BdsConnectAndUpdateDevicePath (&NewDevicePath, Handle, RemainingDevicePath);
- *DevicePath = NewDevicePath;
- return Status;
- }
- }
-
- if (RemainingDevicePath) {
- *RemainingDevicePath = Remaining;
- }
-
- return Status;
-}
-
-/**
- Connect a Device Path and return the handle of the driver that support this DevicePath
-
- @param DevicePath Device Path of the File to connect
- @param Handle Handle of the driver that support this DevicePath
- @param RemainingDevicePath Remaining DevicePath nodes that do not match the driver DevicePath
-
- @retval EFI_SUCCESS A driver that matches the Device Path has been found
- @retval EFI_NOT_FOUND No handles match the search.
- @retval EFI_INVALID_PARAMETER DevicePath or Handle is NULL
-
-**/
-EFI_STATUS
-BdsConnectDevicePath (
- IN EFI_DEVICE_PATH_PROTOCOL* DevicePath,
- OUT EFI_HANDLE *Handle,
- OUT EFI_DEVICE_PATH_PROTOCOL **RemainingDevicePath
- )
-{
- return BdsConnectAndUpdateDevicePath (&DevicePath, Handle, RemainingDevicePath);
-}
-
-BOOLEAN
BdsFileSystemSupport (
IN EFI_DEVICE_PATH *DevicePath,
IN EFI_HANDLE Handle,
diff --git a/ArmPkg/Library/BdsLib/BdsHelper.c b/ArmPkg/Library/BdsLib/BdsHelper.c
index 7f83c2be8a..63eccae575 100644
--- a/ArmPkg/Library/BdsLib/BdsHelper.c
+++ b/ArmPkg/Library/BdsLib/BdsHelper.c
@@ -83,52 +83,6 @@ ShutdownUefiBootServices (
return Status;
}
-/**
- Connect all DXE drivers
-
- @retval EFI_SUCCESS All drivers have been connected
- @retval EFI_NOT_FOUND No handles match the search.
- @retval EFI_OUT_OF_RESOURCES There is not resource pool memory to store the matching results.
-
-**/
-EFI_STATUS
-BdsConnectAllDrivers (
- VOID
- )
-{
- UINTN HandleCount, Index;
- EFI_HANDLE *HandleBuffer;
- EFI_STATUS Status;
-
- do {
- // Locate all the driver handles
- Status = gBS->LocateHandleBuffer (
- AllHandles,
- NULL,
- NULL,
- &HandleCount,
- &HandleBuffer
- );
- if (EFI_ERROR (Status)) {
- break;
- }
-
- // Connect every handles
- for (Index = 0; Index < HandleCount; Index++) {
- gBS->ConnectController (HandleBuffer[Index], NULL, NULL, TRUE);
- }
-
- if (HandleBuffer != NULL) {
- FreePool (HandleBuffer);
- }
-
- // Check if new handles have been created after the start of the previous handles
- Status = gDS->Dispatch ();
- } while (!EFI_ERROR(Status));
-
- return EFI_SUCCESS;
-}
-
STATIC
EFI_STATUS
InsertSystemMemoryResources (
@@ -291,69 +245,3 @@ PrintPerformance (
CharCount = AsciiSPrint (Buffer,sizeof (Buffer),"Total Time = %ld ms\n\n", DivU64x64Remainder (MultU64x32 (TimeStamp, 1000), TicksPerSecond, NULL));
SerialPortWrite ((UINT8 *) Buffer, CharCount);
}
-
-EFI_STATUS
-GetGlobalEnvironmentVariable (
- IN CONST CHAR16* VariableName,
- IN VOID* DefaultValue,
- IN OUT UINTN* Size,
- OUT VOID** Value
- )
-{
- return GetEnvironmentVariable (VariableName, &gEfiGlobalVariableGuid,
- DefaultValue, Size, Value);
-}
-
-EFI_STATUS
-GetEnvironmentVariable (
- IN CONST CHAR16* VariableName,
- IN EFI_GUID* VendorGuid,
- IN VOID* DefaultValue,
- IN OUT UINTN* Size,
- OUT VOID** Value
- )
-{
- EFI_STATUS Status;
- UINTN VariableSize;
-
- // Try to get the variable size.
- *Value = NULL;
- VariableSize = 0;
- Status = gRT->GetVariable ((CHAR16 *) VariableName, VendorGuid, NULL, &VariableSize, *Value);
- if (Status == EFI_NOT_FOUND) {
- if ((DefaultValue != NULL) && (Size != NULL) && (*Size != 0)) {
- // If the environment variable does not exist yet then set it with the default value
- Status = gRT->SetVariable (
- (CHAR16*)VariableName,
- VendorGuid,
- EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
- *Size,
- DefaultValue
- );
- *Value = AllocateCopyPool (*Size, DefaultValue);
- } else {
- return EFI_NOT_FOUND;
- }
- } else if (Status == EFI_BUFFER_TOO_SMALL) {
- // Get the environment variable value
- *Value = AllocatePool (VariableSize);
- if (*Value == NULL) {
- return EFI_OUT_OF_RESOURCES;
- }
-
- Status = gRT->GetVariable ((CHAR16 *)VariableName, VendorGuid, NULL, &VariableSize, *Value);
- if (EFI_ERROR (Status)) {
- FreePool(*Value);
- return EFI_INVALID_PARAMETER;
- }
-
- if (Size) {
- *Size = VariableSize;
- }
- } else {
- *Value = AllocateCopyPool (*Size, DefaultValue);
- return Status;
- }
-
- return EFI_SUCCESS;
-}
diff --git a/ArmPkg/Library/BdsLib/BdsLib.inf b/ArmPkg/Library/BdsLib/BdsLib.inf
index 6d6a2dfa8a..830a57420b 100644
--- a/ArmPkg/Library/BdsLib/BdsLib.inf
+++ b/ArmPkg/Library/BdsLib/BdsLib.inf
@@ -43,6 +43,7 @@
ArmPlatformPkg/ArmPlatformPkg.dec
[LibraryClasses]
+ ArmBdsHelperLib
ArmLib
ArmSmcLib
BaseLib
diff --git a/ArmPlatformPkg/APMXGenePkg/APMXGene.dsc.inc b/ArmPlatformPkg/APMXGenePkg/APMXGene.dsc.inc
index 1cdf4b020f..c3c22097d2 100644
--- a/ArmPlatformPkg/APMXGenePkg/APMXGene.dsc.inc
+++ b/ArmPlatformPkg/APMXGenePkg/APMXGene.dsc.inc
@@ -90,6 +90,7 @@
SemihostLib|ArmPkg/Library/SemihostLib/SemihostLib.inf
# BDS Libraries
+ ArmBdsHelperLib|ArmPkg/Library/ArmBdsHelperLib/ArmBdsHelperLib.inf
BdsLib|ArmPkg/Library/BdsLib/BdsLib.inf
FdtLib|EmbeddedPkg/Library/FdtLib/FdtLib.inf
diff --git a/ArmPlatformPkg/ArmJunoPkg/AcpiTables/AcpiTables.inf b/ArmPlatformPkg/ArmJunoPkg/AcpiTables/AcpiTables.inf
index 7e59562f2d..76a0d0aa34 100644
--- a/ArmPlatformPkg/ArmJunoPkg/AcpiTables/AcpiTables.inf
+++ b/ArmPlatformPkg/ArmJunoPkg/AcpiTables/AcpiTables.inf
@@ -47,5 +47,5 @@
gArmTokenSpaceGuid.PcdArmArchTimerHypIntrNum
gArmTokenSpaceGuid.PcdArmArchTimerVirtIntrNum
- gArmJunoTokenSpaceGuid.PcdGenericWatchdogControlBase
- gArmJunoTokenSpaceGuid.PcdGenericWatchdogRefreshBase
+ gArmTokenSpaceGuid.PcdGenericWatchdogControlBase
+ gArmTokenSpaceGuid.PcdGenericWatchdogRefreshBase
diff --git a/ArmPlatformPkg/ArmJunoPkg/ArmJuno.dec b/ArmPlatformPkg/ArmJunoPkg/ArmJuno.dec
index 7270f7c8e4..051ffbbb60 100644
--- a/ArmPlatformPkg/ArmJunoPkg/ArmJuno.dec
+++ b/ArmPlatformPkg/ArmJunoPkg/ArmJuno.dec
@@ -32,9 +32,5 @@
gArmJunoTokenSpaceGuid = { 0xa1147a20, 0x3144, 0x4f8d, { 0x82, 0x95, 0xb4, 0x83, 0x11, 0xc8, 0xe4, 0xa4 } }
[PcdsFixedAtBuild.common]
- gArmJunoTokenSpaceGuid.PcdGenericWatchdogControlBase|0x2A440000|UINT32|0x00000001
- gArmJunoTokenSpaceGuid.PcdGenericWatchdogRefreshBase|0x2A450000|UINT32|0x00000002
- gArmJunoTokenSpaceGuid.PcdGenericWatchdogEl2IntrNum|93|UINT32|0x00000003
-
gArmJunoTokenSpaceGuid.PcdSynopsysUsbOhciBaseAddress|0x7FFB0000|UINT32|0x00000004
gArmJunoTokenSpaceGuid.PcdSynopsysUsbEhciBaseAddress|0x7FFC0000|UINT32|0x00000005
diff --git a/ArmPlatformPkg/ArmJunoPkg/ArmJuno.dsc b/ArmPlatformPkg/ArmJunoPkg/ArmJuno.dsc
index d7db5abf5c..a24849f799 100644
--- a/ArmPlatformPkg/ArmJunoPkg/ArmJuno.dsc
+++ b/ArmPlatformPkg/ArmJunoPkg/ArmJuno.dsc
@@ -20,7 +20,11 @@
PLATFORM_GUID = ca0722fd-7d3d-45ea-948c-d62b2199807d
PLATFORM_VERSION = 0.1
DSC_SPECIFICATION = 0x00010005
+!ifdef EDK2_OUT_DIR
+ OUTPUT_DIRECTORY = $(EDK2_OUT_DIR)
+!else
OUTPUT_DIRECTORY = Build/ArmJuno
+!endif
SUPPORTED_ARCHITECTURES = AARCH64|ARM
BUILD_TARGETS = DEBUG|RELEASE
SKUID_IDENTIFIER = DEFAULT
@@ -39,6 +43,14 @@
TimerLib|ArmPkg/Library/ArmArchTimerLib/ArmArchTimerLib.inf
+ ArmBdsHelperLib|ArmPkg/Library/ArmBdsHelperLib/ArmBdsHelperLib.inf
+!ifdef INTEL_BDS
+ CapsuleLib|MdeModulePkg/Library/DxeCapsuleLibNull/DxeCapsuleLibNull.inf
+ GenericBdsLib|IntelFrameworkModulePkg/Library/GenericBdsLib/GenericBdsLib.inf
+ PlatformBdsLib|ArmPlatformPkg/Library/PlatformIntelBdsLib/PlatformIntelBdsLib.inf
+ CustomizedDisplayLib|MdeModulePkg/Library/CustomizedDisplayLib/CustomizedDisplayLib.inf
+!endif
+
# USB Requirements
UefiUsbLib|MdePkg/Library/UefiUsbLib/UefiUsbLib.inf
@@ -60,7 +72,7 @@
MemoryInitPeiLib|ArmPlatformPkg/MemoryInitPei/MemoryInitPeiLib.inf
[BuildOptions]
- GCC:*_*_*_PLATFORM_FLAGS == -I$(WORKSPACE)/ArmPlatformPkg/ArmVExpressPkg/Include -I$(WORKSPACE)/ArmPlatformPkg/ArmJunoPkg/Include
+ *_*_*_PLATFORM_FLAGS == -I$(WORKSPACE)/ArmPlatformPkg/ArmVExpressPkg/Include -I$(WORKSPACE)/ArmPlatformPkg/ArmJunoPkg/Include
################################################################################
#
@@ -146,6 +158,11 @@
gArmTokenSpaceGuid.PcdArmArchTimerFreqInHz|50000000
gEmbeddedTokenSpaceGuid.PcdMetronomeTickPeriod|1000
+!ifdef INTEL_BDS
+ gEfiMdeModulePkgTokenSpaceGuid.PcdResetOnMemoryTypeInformationChange|FALSE
+ gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdShellFile|{ 0x83, 0xA5, 0x04, 0x7C, 0x3E, 0x9E, 0x1C, 0x4F, 0xAD, 0x65, 0xE0, 0x52, 0x68, 0xD0, 0xB4, 0xD1 }
+!endif
+
[PcdsPatchableInModule]
# Console Resolution (Full HD)
gEfiMdeModulePkgTokenSpaceGuid.PcdVideoHorizontalResolution|1920
@@ -208,7 +225,7 @@
ArmPkg/Drivers/ArmGic/ArmGicDxe.inf
ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashDxe.inf
ArmPkg/Drivers/TimerDxe/TimerDxe.inf
- ArmPlatformPkg/ArmJunoPkg/Drivers/GenericWatchdogDxe/GenericWatchdogDxe.inf
+ ArmPkg/Drivers/GenericWatchdogDxe/GenericWatchdogDxe.inf
#
# Semi-hosting filesystem
@@ -243,5 +260,12 @@
# Bds
#
MdeModulePkg/Universal/DevicePathDxe/DevicePathDxe.inf
+!ifdef INTEL_BDS
+ MdeModulePkg/Universal/DisplayEngineDxe/DisplayEngineDxe.inf
+ MdeModulePkg/Universal/SetupBrowserDxe/SetupBrowserDxe.inf
+ IntelFrameworkModulePkg/Universal/BdsDxe/BdsDxe.inf
+!else
ArmPlatformPkg/Bds/Bds.inf
+!endif
+ MdeModulePkg/Universal/Fdt/FdtTableDxe/FdtTableDxe.inf
diff --git a/ArmPlatformPkg/ArmJunoPkg/ArmJuno.fdf b/ArmPlatformPkg/ArmJunoPkg/ArmJuno.fdf
index 21f2a2dc3b..a6087e481f 100644
--- a/ArmPlatformPkg/ArmJunoPkg/ArmJuno.fdf
+++ b/ArmPlatformPkg/ArmJunoPkg/ArmJuno.fdf
@@ -122,7 +122,7 @@ READ_LOCK_STATUS = TRUE
INF ArmPkg/Drivers/ArmGic/ArmGicDxe.inf
INF ArmPkg/Drivers/TimerDxe/TimerDxe.inf
- INF ArmPlatformPkg/ArmJunoPkg/Drivers/GenericWatchdogDxe/GenericWatchdogDxe.inf
+ INF ArmPkg/Drivers/GenericWatchdogDxe/GenericWatchdogDxe.inf
# NOR Flash driver
INF ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashDxe.inf
@@ -178,7 +178,18 @@ READ_LOCK_STATUS = TRUE
# Bds
#
INF MdeModulePkg/Universal/DevicePathDxe/DevicePathDxe.inf
+!ifdef INTEL_BDS
+ INF MdeModulePkg/Universal/DisplayEngineDxe/DisplayEngineDxe.inf
+ INF MdeModulePkg/Universal/SetupBrowserDxe/SetupBrowserDxe.inf
+ INF IntelFrameworkModulePkg/Universal/BdsDxe/BdsDxe.inf
+!else
INF ArmPlatformPkg/Bds/Bds.inf
+!endif
+
+ INF MdeModulePkg/Universal/Fdt/FdtTableDxe/FdtTableDxe.inf
+ FILE FREEFORM = PCD(gEfiMdeModulePkgTokenSpaceGuid.PcdFdtImage) {
+ SECTION RAW = ArmPlatformPkg/ArmJunoPkg/dts/juno.dtb
+ }
[FV.FVMAIN_COMPACT]
FvAlignment = 8
diff --git a/ArmPlatformPkg/ArmJunoPkg/Drivers/ArmJunoDxe/ArmJunoDxe.inf b/ArmPlatformPkg/ArmJunoPkg/Drivers/ArmJunoDxe/ArmJunoDxe.inf
index 9f8bbed768..a4c9e45e67 100644
--- a/ArmPlatformPkg/ArmJunoPkg/Drivers/ArmJunoDxe/ArmJunoDxe.inf
+++ b/ArmPlatformPkg/ArmJunoPkg/Drivers/ArmJunoDxe/ArmJunoDxe.inf
@@ -33,9 +33,9 @@
[LibraryClasses]
AcpiLib
+ ArmBdsHelperLib
ArmShellCmdRunAxfLib
BaseMemoryLib
- BdsLib
DebugLib
DmaLib
DxeServicesTableLib
diff --git a/ArmPlatformPkg/ArmJunoPkg/Drivers/ArmJunoDxe/InstallFdt.c b/ArmPlatformPkg/ArmJunoPkg/Drivers/ArmJunoDxe/InstallFdt.c
index a4220a1895..4ccd5d366c 100644
--- a/ArmPlatformPkg/ArmJunoPkg/Drivers/ArmJunoDxe/InstallFdt.c
+++ b/ArmPlatformPkg/ArmJunoPkg/Drivers/ArmJunoDxe/InstallFdt.c
@@ -19,8 +19,8 @@
#include <Protocol/DriverBinding.h>
#include <Protocol/SimpleFileSystem.h>
+#include <Library/ArmBdsHelperLib.h>
#include <Library/BaseMemoryLib.h>
-#include <Library/BdsLib.h>
#include <Library/DevicePathLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/PrintLib.h>
diff --git a/ArmPlatformPkg/ArmJunoPkg/Library/ArmJunoLib/ArmJunoLib.inf b/ArmPlatformPkg/ArmJunoPkg/Library/ArmJunoLib/ArmJunoLib.inf
index f137ab8471..b677e9dec3 100644
--- a/ArmPlatformPkg/ArmJunoPkg/Library/ArmJunoLib/ArmJunoLib.inf
+++ b/ArmPlatformPkg/ArmJunoPkg/Library/ArmJunoLib/ArmJunoLib.inf
@@ -38,7 +38,7 @@
ArmJunoMem.c
[Sources.AARCH64]
- AArch64/ArmJunoHelper.S | GCC
+ AArch64/ArmJunoHelper.S
[Sources.ARM]
Arm/ArmJunoHelper.S | GCC
diff --git a/ArmPlatformPkg/ArmJunoPkg/dts/juno.dtb b/ArmPlatformPkg/ArmJunoPkg/dts/juno.dtb
new file mode 100644
index 0000000000..66f74e6817
--- /dev/null
+++ b/ArmPlatformPkg/ArmJunoPkg/dts/juno.dtb
Binary files differ
diff --git a/ArmPlatformPkg/ArmJunoPkg/dts/juno.dts b/ArmPlatformPkg/ArmJunoPkg/dts/juno.dts
new file mode 100644
index 0000000000..d4dec5baff
--- /dev/null
+++ b/ArmPlatformPkg/ArmJunoPkg/dts/juno.dts
@@ -0,0 +1,340 @@
+/dts-v1/;
+
+/ {
+ model = "Juno";
+ compatible = "arm,juno", "arm,vexpress";
+ interrupt-parent = <0x1>;
+ #address-cells = <0x2>;
+ #size-cells = <0x2>;
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+
+ aliases {
+ serial0 = "/uart@7ff80000";
+ };
+
+ cpus {
+ #address-cells = <0x2>;
+ #size-cells = <0x0>;
+
+ cpu@100 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a53", "arm,armv8";
+ reg = <0x0 0x100>;
+ enable-method = "psci";
+ };
+
+ cpu@101 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a53", "arm,armv8";
+ reg = <0x0 0x101>;
+ enable-method = "psci";
+ };
+
+ cpu@102 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a53", "arm,armv8";
+ reg = <0x0 0x102>;
+ enable-method = "psci";
+ };
+
+ cpu@103 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a53", "arm,armv8";
+ reg = <0x0 0x103>;
+ enable-method = "psci";
+ };
+
+ cpu@0 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a57", "arm,armv8";
+ reg = <0x0 0x0>;
+ enable-method = "psci";
+ };
+
+ cpu@1 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a57", "arm,armv8";
+ reg = <0x0 0x1>;
+ enable-method = "psci";
+ };
+ };
+
+ memory@80000000 {
+ device_type = "memory";
+ reg = <0x0 0x80000000 0x0 0x7f000000 0x8 0x80000000 0x1 0x80000000>;
+ };
+
+ interrupt-controller@2c001000 {
+ compatible = "arm,cortex-a15-gic";
+ #interrupt-cells = <0x3>;
+ #address-cells = <0x0>;
+ interrupt-controller;
+ reg = <0x0 0x2c010000 0x0 0x1000 0x0 0x2c02f000 0x0 0x2000 0x0 0x2c04f000 0x0 0x2000 0x0 0x2c06f000 0x0 0x2000>;
+ interrupts = <0x1 0x9 0x3f04>;
+ linux,phandle = <0x1>;
+ phandle = <0x1>;
+ };
+
+ timer {
+ compatible = "arm,armv8-timer";
+ interrupts = <0x1 0xd 0x3f01 0x1 0xe 0x3f01 0x1 0xb 0x3f01 0x1 0xa 0x3f01>;
+ };
+
+ pmu {
+ compatible = "arm,armv8-pmuv3";
+ interrupts = <0x0 0x12 0x4 0x0 0x16 0x4 0x0 0x1a 0x4 0x0 0x1e 0x4 0x0 0x2 0x4 0x0 0x6 0x4>;
+ };
+
+ psci {
+ compatible = "arm,psci-0.2";
+ method = "smc";
+ };
+
+ refclk72738khz {
+ compatible = "fixed-clock";
+ #clock-cells = <0x0>;
+ clock-frequency = <0x6efd48>;
+ clock-output-names = "juno:uartclk";
+ linux,phandle = <0x4>;
+ phandle = <0x4>;
+ };
+
+ clk48mhz {
+ compatible = "fixed-clock";
+ #clock-cells = <0x0>;
+ clock-frequency = <0x2dc6c00>;
+ clock-output-names = "clk48mhz";
+ linux,phandle = <0x6>;
+ phandle = <0x6>;
+ };
+
+ clk50mhz {
+ compatible = "fixed-clock";
+ #clock-cells = <0x0>;
+ clock-frequency = <0x2faf080>;
+ clock-output-names = "smc_clk";
+ linux,phandle = <0x2>;
+ phandle = <0x2>;
+ };
+
+ refclk100mhz {
+ compatible = "fixed-clock";
+ #clock-cells = <0x0>;
+ clock-frequency = <0x5f5e100>;
+ clock-output-names = "apb_pclk";
+ linux,phandle = <0x5>;
+ phandle = <0x5>;
+ };
+
+ clk24mhz {
+ compatible = "fixed-clock";
+ #clock-cells = <0x0>;
+ clock-frequency = <0x16e3600>;
+ clock-output-names = "juno:clk24mhz";
+ linux,phandle = <0xa>;
+ phandle = <0xa>;
+ };
+
+ refclk533mhz {
+ compatible = "fixed-clock";
+ #clock-cells = <0x0>;
+ clock-frequency = <0x1fc4ef40>;
+ clock-output-names = "faxi_clk";
+ linux,phandle = <0x3>;
+ phandle = <0x3>;
+ };
+
+ clk25mhz {
+ compatible = "fixed-clock";
+ #clock-cells = <0x0>;
+ clock-frequency = <0x17d7840>;
+ clock-output-names = "ethclk25mhz";
+ linux,phandle = <0x8>;
+ phandle = <0x8>;
+ };
+
+ fixedregulator@0 {
+ compatible = "regulator-fixed";
+ regulator-name = "3V3";
+ regulator-min-microvolt = <0x325aa0>;
+ regulator-max-microvolt = <0x325aa0>;
+ regulator-always-on;
+ linux,phandle = <0x9>;
+ phandle = <0x9>;
+ };
+
+ memory-controller@7ffd0000 {
+ compatible = "arm,pl354", "arm,primecell";
+ reg = <0x0 0x7ffd0000 0x0 0x1000>;
+ interrupts = <0x0 0x56 0x4 0x0 0x57 0x4>;
+ clocks = <0x2>;
+ clock-names = "apb_pclk";
+ chip5-memwidth = <0x10>;
+ };
+
+ dma@0x7ff00000 {
+ compatible = "arm,pl330", "arm,primecell";
+ reg = <0x0 0x7ff00000 0x0 0x1000>;
+ interrupts = <0x0 0x5f 0x4 0x0 0x58 0x4 0x0 0x59 0x4 0x0 0x5a 0x4 0x0 0x5b 0x4 0x0 0x6c 0x4 0x0 0x6d 0x4 0x0 0x6e 0x4 0x0 0x6f 0x4>;
+ #dma-cells = <0x1>;
+ #dma-channels = <0x8>;
+ #dma-requests = <0x20>;
+ clocks = <0x3>;
+ clock-names = "apb_pclk";
+ };
+
+ uart@7ff80000 {
+ compatible = "arm,pl011", "arm,primecell";
+ reg = <0x0 0x7ff80000 0x0 0x1000>;
+ interrupts = <0x0 0x53 0x4>;
+ clocks = <0x4 0x5>;
+ clock-names = "uartclk", "apb_pclk";
+ };
+
+ phy@0 {
+ compatible = "phy-ulpi-generic";
+ reg = <0x0 0x94 0x0 0x4>;
+ phy-id = <0x0>;
+ linux,phandle = <0x7>;
+ phandle = <0x7>;
+ };
+
+ ehci@7ffc0000 {
+ compatible = "generic-ehci";
+ reg = <0x0 0x7ffc0000 0x0 0x10000>;
+ interrupts = <0x0 0x75 0x4>;
+ clocks = <0x6>;
+ phys = <0x7>;
+ phy-names = "usb_ulpi";
+ };
+
+ ohci@0x7ffb0000 {
+ compatible = "generic-ohci";
+ reg = <0x0 0x7ffb0000 0x0 0x10000>;
+ interrupts = <0x0 0x74 0x4>;
+ clocks = <0x6>;
+ phys = <0x7>;
+ phy-names = "usb_ulpi";
+ };
+
+ i2c@0x7ffa0000 {
+ #address-cells = <0x1>;
+ #size-cells = <0x0>;
+ compatible = "snps,designware-i2c";
+ reg = <0x0 0x7ffa0000 0x0 0x1000>;
+ interrupts = <0x0 0x68 0x4>;
+ clock-frequency = <0x61a80>;
+ i2c-sda-hold-time-ns = <0x1f4>;
+ clocks = <0x2>;
+
+ dvi-transmitter@70 {
+ compatible = "nxp,tda998x";
+ reg = <0x70>;
+ };
+
+ dvi-transmitter@71 {
+ compatible = "nxp,tda998x";
+ reg = <0x71>;
+ };
+ };
+
+ smb {
+ compatible = "simple-bus";
+ #address-cells = <0x2>;
+ #size-cells = <0x1>;
+ ranges = <0x0 0x0 0x0 0x8000000 0x4000000 0x1 0x0 0x0 0x14000000 0x4000000 0x2 0x0 0x0 0x18000000 0x4000000 0x3 0x0 0x0 0x1c000000 0x4000000 0x4 0x0 0x0 0xc000000 0x4000000 0x5 0x0 0x0 0x10000000 0x4000000>;
+ #interrupt-cells = <0x1>;
+ interrupt-map-mask = <0x0 0x0 0xf>;
+ interrupt-map = <0x0 0x0 0x0 0x1 0x0 0x44 0x4 0x0 0x0 0x1 0x1 0x0 0x45 0x4 0x0 0x0 0x2 0x1 0x0 0x46 0x4 0x0 0x0 0x3 0x1 0x0 0xa0 0x4 0x0 0x0 0x4 0x1 0x0 0xa1 0x4 0x0 0x0 0x5 0x1 0x0 0xa2 0x4 0x0 0x0 0x6 0x1 0x0 0xa3 0x4 0x0 0x0 0x7 0x1 0x0 0xa4 0x4 0x0 0x0 0x8 0x1 0x0 0xa5 0x4 0x0 0x0 0x9 0x1 0x0 0xa6 0x4 0x0 0x0 0xa 0x1 0x0 0xa7 0x4 0x0 0x0 0xb 0x1 0x0 0xa8 0x4 0x0 0x0 0xc 0x1 0x0 0xa9 0x4>;
+
+ motherboard {
+ model = "V2M-Juno";
+ arm,hbi = <0x252>;
+ arm,vexpress,site = <0x0>;
+ arm,v2m-memory-map = "rs1";
+ compatible = "arm,vexpress,v2p-p1", "simple-bus";
+ #address-cells = <0x2>;
+ #size-cells = <0x1>;
+ #interrupt-cells = <0x1>;
+ ranges;
+
+ usb@5,00000000 {
+ compatible = "nxp,usb-isp1763";
+ reg = <0x5 0x0 0x20000>;
+ bus-width = <0x10>;
+ interrupts = <0x4>;
+ };
+
+ ethernet@2,00000000 {
+ compatible = "smsc,lan9118", "smsc,lan9115";
+ reg = <0x2 0x0 0x10000>;
+ interrupts = <0x3>;
+ phy-mode = "mii";
+ reg-io-width = <0x4>;
+ smsc,irq-active-high;
+ smsc,irq-push-pull;
+ clocks = <0x8>;
+ vdd33a-supply = <0x9>;
+ vddvario-supply = <0x9>;
+ };
+
+ iofpga@3,00000000 {
+ compatible = "arm,amba-bus", "simple-bus";
+ #address-cells = <0x1>;
+ #size-cells = <0x1>;
+ ranges = <0x0 0x3 0x0 0x200000>;
+
+ kmi@060000 {
+ compatible = "arm,pl050", "arm,primecell";
+ reg = <0x60000 0x1000>;
+ interrupts = <0x8>;
+ clocks = <0xa 0x2>;
+ clock-names = "KMIREFCLK", "apb_pclk";
+ };
+
+ kmi@070000 {
+ compatible = "arm,pl050", "arm,primecell";
+ reg = <0x70000 0x1000>;
+ interrupts = <0x8>;
+ clocks = <0xa 0x2>;
+ clock-names = "KMIREFCLK", "apb_pclk";
+ };
+
+ wdt@0f0000 {
+ compatible = "arm,sp805", "arm,primecell";
+ reg = <0xf0000 0x10000>;
+ interrupts = <0x7>;
+ clocks = <0xa 0x2>;
+ clock-names = "wdogclk", "apb_pclk";
+ };
+
+ timer@110000 {
+ compatible = "arm,sp804", "arm,primecell";
+ reg = <0x110000 0x10000>;
+ interrupts = <0x9>;
+ clocks = <0xa 0x2>;
+ clock-names = "timclken1", "apb_pclk";
+ };
+
+ timer@120000 {
+ compatible = "arm,sp804", "arm,primecell";
+ reg = <0x120000 0x10000>;
+ interrupts = <0x9>;
+ clocks = <0xa 0x2>;
+ clock-names = "timclken1", "apb_pclk";
+ };
+
+ rtc@170000 {
+ compatible = "arm,pl031", "arm,primecell";
+ reg = <0x170000 0x10000>;
+ interrupts = <0x0>;
+ clocks = <0x2>;
+ clock-names = "apb_pclk";
+ };
+ };
+ };
+ };
+};
diff --git a/ArmPlatformPkg/ArmPlatformPkg.dsc b/ArmPlatformPkg/ArmPlatformPkg.dsc
index 81402da5b3..dfc84304c4 100644
--- a/ArmPlatformPkg/ArmPlatformPkg.dsc
+++ b/ArmPlatformPkg/ArmPlatformPkg.dsc
@@ -110,7 +110,9 @@
SemihostLib|ArmPkg/Library/SemihostLib/SemihostLib.inf
# BDS Libraries
+!ifndef INTEL_BDS
BdsLib|ArmPkg/Library/BdsLib/BdsLib.inf
+!endif
FdtLib|EmbeddedPkg/Library/FdtLib/FdtLib.inf
[LibraryClasses.ARM]
diff --git a/ArmPlatformPkg/ArmVExpressPkg/ArmVExpress-CTA15-A7.dsc b/ArmPlatformPkg/ArmVExpressPkg/ArmVExpress-CTA15-A7.dsc
index 24deb22b22..571d981eef 100644
--- a/ArmPlatformPkg/ArmVExpressPkg/ArmVExpress-CTA15-A7.dsc
+++ b/ArmPlatformPkg/ArmVExpressPkg/ArmVExpress-CTA15-A7.dsc
@@ -53,11 +53,8 @@
[BuildOptions]
!ifdef ARM_BIGLITTLE_TC2
- RVCT:*_*_ARM_ARCHCC_FLAGS = -DARM_BIGLITTLE_TC2=1
- RVCT:*_*_ARM_PP_FLAGS = -DARM_BIGLITTLE_TC2=1
-
- GCC:*_*_ARM_ARCHCC_FLAGS = -DARM_BIGLITTLE_TC2=1
- GCC:*_*_ARM_PP_FLAGS = -DARM_BIGLITTLE_TC2=1
+ *_*_ARM_ARCHCC_FLAGS = -DARM_BIGLITTLE_TC2=1
+ *_*_ARM_PP_FLAGS = -DARM_BIGLITTLE_TC2=1
!endif
RVCT:*_*_ARM_PLATFORM_FLAGS == --cpu Cortex-A15 -I$(WORKSPACE)/ArmPlatformPkg/ArmVExpressPkg/Include -I$(WORKSPACE)/ArmPlatformPkg/ArmVExpressPkg/Include/Platform/CTA15-A7
diff --git a/ArmPlatformPkg/ArmVExpressPkg/ArmVExpress.dsc.inc b/ArmPlatformPkg/ArmVExpressPkg/ArmVExpress.dsc.inc
index 1514eb7806..9896d5bd4d 100644
--- a/ArmPlatformPkg/ArmVExpressPkg/ArmVExpress.dsc.inc
+++ b/ArmPlatformPkg/ArmVExpressPkg/ArmVExpress.dsc.inc
@@ -23,6 +23,7 @@
DebugPrintErrorLevelLib|MdePkg/Library/BaseDebugPrintErrorLevelLib/BaseDebugPrintErrorLevelLib.inf
BaseLib|MdePkg/Library/BaseLib/BaseLib.inf
+ BasePathLib|ShellPkg/Library/BasePathLib/BasePathLib.inf
SynchronizationLib|MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLib.inf
PerformanceLib|MdePkg/Library/BasePerformanceLibNull/BasePerformanceLibNull.inf
PrintLib|MdePkg/Library/BasePrintLib/BasePrintLib.inf
@@ -111,7 +112,10 @@
SemihostLib|ArmPkg/Library/SemihostLib/SemihostLib.inf
# BDS Libraries
+ ArmBdsHelperLib|ArmPkg/Library/ArmBdsHelperLib/ArmBdsHelperLib.inf
+!ifndef INTEL_BDS
BdsLib|ArmPkg/Library/BdsLib/BdsLib.inf
+!endif
AcpiLib|EmbeddedPkg/Library/AcpiLib/AcpiLib.inf
FdtLib|EmbeddedPkg/Library/FdtLib/FdtLib.inf
@@ -336,9 +340,11 @@
gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiLoaderCode|20
gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiLoaderData|0
+!ifndef NO_LINUX_LOADER
# Device path of block device on which Android Fastboot should flash
# partitions. We just use the SD card on VExpress.
gArmVExpressTokenSpaceGuid.PcdAndroidFastbootNvmDevicePath|L"VenHw(09831032-6FA3-4484-AF4F-0A000A8D3A82)"
+!endif
#
# ARM Pcds
@@ -408,9 +414,11 @@
# ISP1761 USB OTG Controller
EmbeddedPkg/Drivers/Isp1761UsbDxe/Isp1761UsbDxe.inf
+!ifndef NO_LINUX_LOADER
#
# Android Fastboot
#
EmbeddedPkg/Application/AndroidFastboot/AndroidFastbootApp.inf
EmbeddedPkg/Drivers/AndroidFastbootTransportUsbDxe/FastbootTransportUsbDxe.inf
ArmPlatformPkg/ArmVExpressPkg/ArmVExpressFastBootDxe/ArmVExpressFastBootDxe.inf
+!endif
diff --git a/ArmPlatformPkg/ArmVirtualizationPkg/ArmVirtualization.dsc.inc b/ArmPlatformPkg/ArmVirtualizationPkg/ArmVirtualization.dsc.inc
index b05f1ec7c6..230a6fc90c 100644
--- a/ArmPlatformPkg/ArmVirtualizationPkg/ArmVirtualization.dsc.inc
+++ b/ArmPlatformPkg/ArmVirtualizationPkg/ArmVirtualization.dsc.inc
@@ -96,7 +96,9 @@
DebugAgentTimerLib|EmbeddedPkg/Library/DebugAgentTimerLibNull/DebugAgentTimerLibNull.inf
# BDS Libraries
+!ifndef INTEL_BDS
BdsLib|ArmPkg/Library/BdsLib/BdsLib.inf
+!endif
FdtLib|EmbeddedPkg/Library/FdtLib/FdtLib.inf
[LibraryClasses.common.SEC]
diff --git a/ArmPlatformPkg/ArmVirtualizationPkg/ArmVirtualizationPkg.dec b/ArmPlatformPkg/ArmVirtualizationPkg/ArmVirtualizationPkg.dec
index b581add024..99411548af 100644
--- a/ArmPlatformPkg/ArmVirtualizationPkg/ArmVirtualizationPkg.dec
+++ b/ArmPlatformPkg/ArmVirtualizationPkg/ArmVirtualizationPkg.dec
@@ -53,3 +53,6 @@
# PcdArmPsciMethod == 2 : use SMC
#
gArmVirtualizationTokenSpaceGuid.PcdArmPsciMethod|0|UINT32|0x00000003
+
+ gArmVirtualizationTokenSpaceGuid.PcdFwCfgSelectorAddress|0x0|UINT64|0x00000004
+ gArmVirtualizationTokenSpaceGuid.PcdFwCfgDataAddress|0x0|UINT64|0x00000005
diff --git a/ArmPlatformPkg/ArmVirtualizationPkg/ArmVirtualizationQemu.dsc b/ArmPlatformPkg/ArmVirtualizationPkg/ArmVirtualizationQemu.dsc
index c7066b091c..9078c4c147 100644
--- a/ArmPlatformPkg/ArmVirtualizationPkg/ArmVirtualizationQemu.dsc
+++ b/ArmPlatformPkg/ArmVirtualizationPkg/ArmVirtualizationQemu.dsc
@@ -22,7 +22,11 @@
PLATFORM_GUID = 37d7e986-f7e9-45c2-8067-e371421a626c
PLATFORM_VERSION = 0.1
DSC_SPECIFICATION = 0x00010005
+!ifdef EDK2_OUT_DIR
+ OUTPUT_DIRECTORY = $(EDK2_OUT_DIR)-$(ARCH)
+!else
OUTPUT_DIRECTORY = Build/ArmVirtualizationQemu-$(ARCH)
+!endif
SUPPORTED_ARCHITECTURES = AARCH64|ARM
BUILD_TARGETS = DEBUG|RELEASE
SKUID_IDENTIFIER = DEFAULT
@@ -42,17 +46,20 @@
# Virtio Support
VirtioLib|OvmfPkg/Library/VirtioLib/VirtioLib.inf
VirtioMmioDeviceLib|OvmfPkg/Library/VirtioMmioDeviceLib/VirtioMmioDeviceLib.inf
+ QemuFwCfgLib|ArmPlatformPkg/ArmVirtualizationPkg/Library/QemuFwCfgLib/QemuFwCfgLib.inf
ArmPlatformLib|ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationPlatformLib/ArmVirtualizationPlatformLib.inf
ArmPlatformSysConfigLib|ArmPlatformPkg/Library/ArmPlatformSysConfigLibNull/ArmPlatformSysConfigLibNull.inf
TimerLib|ArmPkg/Library/ArmArchTimerLib/ArmArchTimerLib.inf
+ ArmBdsHelperLib|ArmPkg/Library/ArmBdsHelperLib/ArmBdsHelperLib.inf
!ifdef INTEL_BDS
CapsuleLib|MdeModulePkg/Library/DxeCapsuleLibNull/DxeCapsuleLibNull.inf
GenericBdsLib|IntelFrameworkModulePkg/Library/GenericBdsLib/GenericBdsLib.inf
- PlatformBdsLib|ArmPlatformPkg/Library/PlatformIntelBdsLib/PlatformIntelBdsLib.inf
+ PlatformBdsLib|ArmPlatformPkg/ArmVirtualizationPkg/Library/PlatformIntelBdsLib/PlatformIntelBdsLib.inf
CustomizedDisplayLib|MdeModulePkg/Library/CustomizedDisplayLib/CustomizedDisplayLib.inf
+ QemuBootOrderLib|OvmfPkg/Library/QemuBootOrderLib/QemuBootOrderLib.inf
!endif
[LibraryClasses.common.UEFI_DRIVER]
@@ -67,7 +74,7 @@
[BuildOptions]
RVCT:*_*_ARM_PLATFORM_FLAGS == --cpu Cortex-A15 -I$(WORKSPACE)/ArmPlatformPkg/ArmVirtualizationPkg/Include
GCC:*_*_ARM_PLATFORM_FLAGS == -mcpu=cortex-a15 -I$(WORKSPACE)/ArmPlatformPkg/ArmVirtualizationPkg/Include
- GCC:*_*_AARCH64_PLATFORM_FLAGS == -I$(WORKSPACE)/ArmPlatformPkg/ArmVirtualizationPkg/Include
+ *_*_AARCH64_PLATFORM_FLAGS == -I$(WORKSPACE)/ArmPlatformPkg/ArmVirtualizationPkg/Include
################################################################################
@@ -77,6 +84,9 @@
################################################################################
[PcdsFeatureFlag.common]
+ gUefiOvmfPkgTokenSpaceGuid.PcdQemuBootOrderPciTranslation|FALSE
+ gUefiOvmfPkgTokenSpaceGuid.PcdQemuBootOrderMmioTranslation|TRUE
+
## If TRUE, Graphics Output Protocol will be installed on virtual handle created by ConsplitterDxe.
# It could be set FALSE to save size.
gEfiMdeModulePkgTokenSpaceGuid.PcdConOutGopSupport|FALSE
@@ -148,6 +158,7 @@
!ifdef INTEL_BDS
gEfiMdeModulePkgTokenSpaceGuid.PcdResetOnMemoryTypeInformationChange|FALSE
+ gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdShellFile|{ 0x83, 0xA5, 0x04, 0x7C, 0x3E, 0x9E, 0x1C, 0x4F, 0xAD, 0x65, 0xE0, 0x52, 0x68, 0xD0, 0xB4, 0xD1 }
!endif
[PcdsDynamicDefault.common]
@@ -173,6 +184,11 @@
gArmVirtualizationTokenSpaceGuid.PcdArmPsciMethod|0
+ gArmVirtualizationTokenSpaceGuid.PcdFwCfgSelectorAddress|0x0
+ gArmVirtualizationTokenSpaceGuid.PcdFwCfgDataAddress|0x0
+
+ gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdPlatformBootTimeOut|3
+
################################################################################
#
# Components Section - list of all EDK II Modules needed by this Platform
diff --git a/ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationPlatformLib/ArmVirtualizationPlatformLib.inf b/ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationPlatformLib/ArmVirtualizationPlatformLib.inf
index 57bebff13e..d1572882af 100644
--- a/ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationPlatformLib/ArmVirtualizationPlatformLib.inf
+++ b/ArmPlatformPkg/ArmVirtualizationPkg/Library/ArmVirtualizationPlatformLib/ArmVirtualizationPlatformLib.inf
@@ -41,7 +41,7 @@
VirtMem.c
[Sources.AARCH64]
- AARCH64/VirtHelper.S | GCC
+ AARCH64/VirtHelper.S
[Sources.ARM]
ARM/VirtHelper.S | GCC
diff --git a/ArmPlatformPkg/ArmVirtualizationPkg/Library/PlatformIntelBdsLib/IntelBdsPlatform.c b/ArmPlatformPkg/ArmVirtualizationPkg/Library/PlatformIntelBdsLib/IntelBdsPlatform.c
new file mode 100644
index 0000000000..6fea2b0aeb
--- /dev/null
+++ b/ArmPlatformPkg/ArmVirtualizationPkg/Library/PlatformIntelBdsLib/IntelBdsPlatform.c
@@ -0,0 +1,395 @@
+/** @file
+
+Copyright (c) 2004 - 2008, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2014, 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 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 "IntelBdsPlatform.h"
+
+#include <Library/QemuBootOrderLib.h>
+
+///
+/// Predefined platform default time out value
+///
+UINT16 gPlatformBootTimeOutDefault;
+
+EFI_STATUS
+EFIAPI
+PlatformIntelBdsConstructor (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ gPlatformBootTimeOutDefault = (UINT16)PcdGet16 (PcdPlatformBootTimeOut);
+ return EFI_SUCCESS;
+}
+
+//
+// BDS Platform Functions
+//
+/**
+ Platform Bds init. Include the platform firmware vendor, revision
+ and so crc check.
+
+**/
+VOID
+EFIAPI
+PlatformBdsInit (
+ VOID
+ )
+{
+}
+
+STATIC
+EFI_STATUS
+GetConsoleDevicePathFromVariable (
+ IN CHAR16* ConsoleVarName,
+ IN CHAR16* DefaultConsolePaths,
+ OUT EFI_DEVICE_PATH** DevicePaths
+ )
+{
+ EFI_STATUS Status;
+ UINTN Size;
+ EFI_DEVICE_PATH_PROTOCOL* DevicePathInstances;
+ EFI_DEVICE_PATH_PROTOCOL* DevicePathInstance;
+ CHAR16* DevicePathStr;
+ CHAR16* NextDevicePathStr;
+ EFI_DEVICE_PATH_FROM_TEXT_PROTOCOL *EfiDevicePathFromTextProtocol;
+
+ Status = GetGlobalEnvironmentVariable (ConsoleVarName, NULL, NULL, (VOID**)&DevicePathInstances);
+ if (EFI_ERROR (Status)) {
+ // In case no default console device path has been defined we assume a driver handles the console (eg: SimpleTextInOutSerial)
+ if ((DefaultConsolePaths == NULL) || (DefaultConsolePaths[0] == L'\0')) {
+ *DevicePaths = NULL;
+ return EFI_SUCCESS;
+ }
+
+ Status = gBS->LocateProtocol (&gEfiDevicePathFromTextProtocolGuid, NULL, (VOID **)&EfiDevicePathFromTextProtocol);
+ ASSERT_EFI_ERROR (Status);
+
+ DevicePathInstances = NULL;
+
+ // Extract the Device Path instances from the multi-device path string
+ while ((DefaultConsolePaths != NULL) && (DefaultConsolePaths[0] != L'\0')) {
+ NextDevicePathStr = StrStr (DefaultConsolePaths, L";");
+ if (NextDevicePathStr == NULL) {
+ DevicePathStr = DefaultConsolePaths;
+ DefaultConsolePaths = NULL;
+ } else {
+ DevicePathStr = (CHAR16*)AllocateCopyPool ((NextDevicePathStr - DefaultConsolePaths + 1) * sizeof (CHAR16), DefaultConsolePaths);
+ *(DevicePathStr + (NextDevicePathStr - DefaultConsolePaths)) = L'\0';
+ DefaultConsolePaths = NextDevicePathStr;
+ if (DefaultConsolePaths[0] == L';') {
+ DefaultConsolePaths++;
+ }
+ }
+
+ DevicePathInstance = EfiDevicePathFromTextProtocol->ConvertTextToDevicePath (DevicePathStr);
+ ASSERT (DevicePathInstance != NULL);
+ DevicePathInstances = AppendDevicePathInstance (DevicePathInstances, DevicePathInstance);
+
+ if (NextDevicePathStr != NULL) {
+ FreePool (DevicePathStr);
+ }
+ FreePool (DevicePathInstance);
+ }
+
+ // Set the environment variable with this device path multi-instances
+ Size = GetDevicePathSize (DevicePathInstances);
+ if (Size > 0) {
+ gRT->SetVariable (
+ ConsoleVarName,
+ &gEfiGlobalVariableGuid,
+ EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
+ Size,
+ DevicePathInstances
+ );
+ } else {
+ Status = EFI_INVALID_PARAMETER;
+ }
+ }
+
+ if (!EFI_ERROR (Status)) {
+ *DevicePaths = DevicePathInstances;
+ }
+ return Status;
+}
+
+STATIC
+EFI_STATUS
+InitializeConsolePipe (
+ IN EFI_DEVICE_PATH *ConsoleDevicePaths,
+ IN EFI_GUID *Protocol,
+ OUT EFI_HANDLE *Handle,
+ OUT VOID* *Interface
+ )
+{
+ EFI_STATUS Status;
+ UINTN Size;
+ UINTN NoHandles;
+ EFI_HANDLE *Buffer;
+ EFI_DEVICE_PATH_PROTOCOL* DevicePath;
+
+ // Connect all the Device Path Consoles
+ while (ConsoleDevicePaths != NULL) {
+ DevicePath = GetNextDevicePathInstance (&ConsoleDevicePaths, &Size);
+
+ Status = BdsConnectDevicePath (DevicePath, Handle, NULL);
+ DEBUG_CODE_BEGIN ();
+ if (EFI_ERROR (Status)) {
+ // We convert back to the text representation of the device Path
+ EFI_DEVICE_PATH_TO_TEXT_PROTOCOL* DevicePathToTextProtocol;
+ CHAR16* DevicePathTxt;
+ EFI_STATUS Status;
+
+ Status = gBS->LocateProtocol (&gEfiDevicePathToTextProtocolGuid, NULL, (VOID **)&DevicePathToTextProtocol);
+ if (!EFI_ERROR (Status)) {
+ DevicePathTxt = DevicePathToTextProtocol->ConvertDevicePathToText (DevicePath, TRUE, TRUE);
+
+ DEBUG ((EFI_D_ERROR, "Fail to start the console with the Device Path '%s'. (Error '%r')\n", DevicePathTxt, Status));
+
+ FreePool (DevicePathTxt);
+ }
+ }
+ DEBUG_CODE_END ();
+
+ // If the console splitter driver is not supported by the platform then use the first Device Path
+ // instance for the console interface.
+ if (!EFI_ERROR (Status) && (*Interface == NULL)) {
+ Status = gBS->HandleProtocol (*Handle, Protocol, Interface);
+ }
+ }
+
+ // No Device Path has been defined for this console interface. We take the first protocol implementation
+ if (*Interface == NULL) {
+ Status = gBS->LocateHandleBuffer (ByProtocol, Protocol, NULL, &NoHandles, &Buffer);
+ if (EFI_ERROR (Status)) {
+ BdsConnectAllDrivers ();
+ Status = gBS->LocateHandleBuffer (ByProtocol, Protocol, NULL, &NoHandles, &Buffer);
+ }
+
+ if (!EFI_ERROR (Status)) {
+ *Handle = Buffer[0];
+ Status = gBS->HandleProtocol (*Handle, Protocol, Interface);
+ ASSERT_EFI_ERROR (Status);
+ }
+ FreePool (Buffer);
+ } else {
+ Status = EFI_SUCCESS;
+ }
+
+ return Status;
+}
+
+/**
+ Connect the predefined platform default console device. Always try to find
+ and enable the vga device if have.
+
+ @param PlatformConsole Predefined platform default console device array.
+
+ @retval EFI_SUCCESS Success connect at least one ConIn and ConOut
+ device, there must have one ConOut device is
+ active vga device.
+ @return Return the status of BdsLibConnectAllDefaultConsoles ()
+
+**/
+EFI_STATUS
+PlatformBdsConnectConsole (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+ EFI_DEVICE_PATH* ConOutDevicePaths;
+ EFI_DEVICE_PATH* ConInDevicePaths;
+ EFI_DEVICE_PATH* ConErrDevicePaths;
+
+ // By getting the Console Device Paths from the environment variables before initializing the console pipe, we
+ // create the 3 environment variables (ConIn, ConOut, ConErr) that allows to initialize all the console interface
+ // of newly installed console drivers
+ Status = GetConsoleDevicePathFromVariable (L"ConOut", (CHAR16*)PcdGetPtr (PcdDefaultConOutPaths), &ConOutDevicePaths);
+ ASSERT_EFI_ERROR (Status);
+ Status = GetConsoleDevicePathFromVariable (L"ConIn", (CHAR16*)PcdGetPtr (PcdDefaultConInPaths), &ConInDevicePaths);
+ ASSERT_EFI_ERROR (Status);
+ Status = GetConsoleDevicePathFromVariable (L"ErrOut", (CHAR16*)PcdGetPtr (PcdDefaultConOutPaths), &ConErrDevicePaths);
+ ASSERT_EFI_ERROR (Status);
+
+ // Initialize the Consoles
+ Status = InitializeConsolePipe (ConOutDevicePaths, &gEfiSimpleTextOutProtocolGuid, &gST->ConsoleOutHandle, (VOID **)&gST->ConOut);
+ ASSERT_EFI_ERROR (Status);
+ Status = InitializeConsolePipe (ConInDevicePaths, &gEfiSimpleTextInProtocolGuid, &gST->ConsoleInHandle, (VOID **)&gST->ConIn);
+ ASSERT_EFI_ERROR (Status);
+ Status = InitializeConsolePipe (ConErrDevicePaths, &gEfiSimpleTextOutProtocolGuid, &gST->StandardErrorHandle, (VOID **)&gST->StdErr);
+ if (EFI_ERROR (Status)) {
+ // In case of error, we reuse the console output for the error output
+ gST->StandardErrorHandle = gST->ConsoleOutHandle;
+ gST->StdErr = gST->ConOut;
+ }
+
+ return Status;
+}
+
+/**
+ Connect with predefined platform connect sequence,
+ the OEM/IBV can customize with their own connect sequence.
+**/
+VOID
+PlatformBdsConnectSequence (
+ VOID
+ )
+{
+}
+
+/**
+ Load the predefined driver option, OEM/IBV can customize this
+ to load their own drivers
+
+ @param BdsDriverLists - The header of the driver option link list.
+
+**/
+VOID
+PlatformBdsGetDriverOption (
+ IN OUT LIST_ENTRY *BdsDriverLists
+ )
+{
+}
+
+/**
+ Perform the platform diagnostic, such like test memory. OEM/IBV also
+ can customize this function to support specific platform diagnostic.
+
+ @param MemoryTestLevel The memory test intensive level
+ @param QuietBoot Indicate if need to enable the quiet boot
+ @param BaseMemoryTest A pointer to BdsMemoryTest()
+
+**/
+VOID
+PlatformBdsDiagnostics (
+ IN EXTENDMEM_COVERAGE_LEVEL MemoryTestLevel,
+ IN BOOLEAN QuietBoot,
+ IN BASEM_MEMORY_TEST BaseMemoryTest
+ )
+{
+}
+
+/**
+ The function will execute with as the platform policy, current policy
+ is driven by boot mode. IBV/OEM can customize this code for their specific
+ policy action.
+
+ @param DriverOptionList The header of the driver option link list
+ @param BootOptionList The header of the boot option link list
+ @param ProcessCapsules A pointer to ProcessCapsules()
+ @param BaseMemoryTest A pointer to BaseMemoryTest()
+
+**/
+VOID
+EFIAPI
+PlatformBdsPolicyBehavior (
+ IN LIST_ENTRY *DriverOptionList,
+ IN LIST_ENTRY *BootOptionList,
+ IN PROCESS_CAPSULES ProcessCapsules,
+ IN BASEM_MEMORY_TEST BaseMemoryTest
+ )
+{
+ EFI_STATUS Status;
+
+ Status = PlatformBdsConnectConsole ();
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Process QEMU's -kernel command line option
+ //
+ TryRunningQemuKernel ();
+
+ BdsLibConnectAll ();
+ BdsLibEnumerateAllBootOption (BootOptionList);
+
+ SetBootOrderFromQemu (BootOptionList);
+ //
+ // The BootOrder variable may have changed, reload the in-memory list with
+ // it.
+ //
+ BdsLibBuildOptionFromVar (BootOptionList, L"BootOrder");
+
+ PlatformBdsEnterFrontPage (gPlatformBootTimeOutDefault, TRUE);
+}
+
+/**
+ Hook point after a boot attempt succeeds. We don't expect a boot option to
+ return, so the UEFI 2.0 specification defines that you will default to an
+ interactive mode and stop processing the BootOrder list in this case. This
+ is also a platform implementation and can be customized by IBV/OEM.
+
+ @param Option Pointer to Boot Option that succeeded to boot.
+
+**/
+VOID
+EFIAPI
+PlatformBdsBootSuccess (
+ IN BDS_COMMON_OPTION *Option
+ )
+{
+}
+
+/**
+ Hook point after a boot attempt fails.
+
+ @param Option Pointer to Boot Option that failed to boot.
+ @param Status Status returned from failed boot.
+ @param ExitData Exit data returned from failed boot.
+ @param ExitDataSize Exit data size returned from failed boot.
+
+**/
+VOID
+EFIAPI
+PlatformBdsBootFail (
+ IN BDS_COMMON_OPTION *Option,
+ IN EFI_STATUS Status,
+ IN CHAR16 *ExitData,
+ IN UINTN ExitDataSize
+ )
+{
+}
+
+/**
+ This function locks platform flash that is not allowed to be updated during normal boot path.
+ The flash layout is platform specific.
+**/
+VOID
+EFIAPI
+PlatformBdsLockNonUpdatableFlash (
+ VOID
+ )
+{
+ return;
+}
+
+
+/**
+ Lock the ConsoleIn device in system table. All key
+ presses will be ignored until the Password is typed in. The only way to
+ disable the password is to type it in to a ConIn device.
+
+ @param Password Password used to lock ConIn device.
+
+ @retval EFI_SUCCESS lock the Console In Spliter virtual handle successfully.
+ @retval EFI_UNSUPPORTED Password not found
+
+**/
+EFI_STATUS
+EFIAPI
+LockKeyboards (
+ IN CHAR16 *Password
+ )
+{
+ return EFI_UNSUPPORTED;
+}
diff --git a/ArmPlatformPkg/ArmVirtualizationPkg/Library/PlatformIntelBdsLib/IntelBdsPlatform.h b/ArmPlatformPkg/ArmVirtualizationPkg/Library/PlatformIntelBdsLib/IntelBdsPlatform.h
new file mode 100644
index 0000000000..cfc496d292
--- /dev/null
+++ b/ArmPlatformPkg/ArmVirtualizationPkg/Library/PlatformIntelBdsLib/IntelBdsPlatform.h
@@ -0,0 +1,63 @@
+/** @file
+ Head file for BDS Platform specific code
+
+Copyright (c) 2004 - 2008, 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 _INTEL_BDS_PLATFORM_H_
+#define _INTEL_BDS_PLATFORM_H_
+
+#include <Protocol/DevicePathFromText.h>
+#include <Protocol/DevicePathToText.h>
+
+#include <Library/BaseMemoryLib.h>
+#include <Library/BdsLib.h>
+#include <Library/DebugLib.h>
+#include <Library/DevicePathLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/BaseLib.h>
+#include <Library/PcdLib.h>
+#include <Library/GenericBdsLib.h>
+#include <Library/PlatformBdsLib.h>
+
+#include <Guid/GlobalVariable.h>
+
+VOID
+PlatformBdsEnterFrontPage (
+ IN UINT16 TimeoutDefault,
+ IN BOOLEAN ConnectAllHappened
+ );
+
+/**
+ Download the kernel, the initial ramdisk, and the kernel command line from
+ QEMU's fw_cfg. Construct a minimal SimpleFileSystem that contains the two
+ image files, and load and start the kernel from it.
+
+ The kernel will be instructed via its command line to load the initrd from
+ the same Simple FileSystem.
+
+ @retval EFI_NOT_FOUND Kernel image was not found.
+ @retval EFI_OUT_OF_RESOURCES Memory allocation failed.
+ @retval EFI_PROTOCOL_ERROR Unterminated kernel command line.
+
+ @return Error codes from any of the underlying
+ functions. On success, the function doesn't
+ return.
+**/
+EFI_STATUS
+EFIAPI
+TryRunningQemuKernel (
+ VOID
+ );
+
+#endif // _INTEL_BDS_PLATFORM_H
diff --git a/ArmPlatformPkg/ArmVirtualizationPkg/Library/PlatformIntelBdsLib/PlatformIntelBdsLib.inf b/ArmPlatformPkg/ArmVirtualizationPkg/Library/PlatformIntelBdsLib/PlatformIntelBdsLib.inf
new file mode 100644
index 0000000000..499a3b5b4e
--- /dev/null
+++ b/ArmPlatformPkg/ArmVirtualizationPkg/Library/PlatformIntelBdsLib/PlatformIntelBdsLib.inf
@@ -0,0 +1,77 @@
+## @file
+# Implementation for PlatformBdsLib library class interfaces.
+# using ARM Platform framework.
+#
+# Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.<BR>
+# Copyright (c) 2014, 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 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 = PlatformIntelBdsLib
+ FILE_GUID = 46DF84EB-F603-4D39-99D8-E1E86B50BCC2
+ MODULE_TYPE = DXE_DRIVER
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = PlatformBdsLib|DXE_DRIVER
+ CONSTRUCTOR = PlatformIntelBdsConstructor
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = ARM AARCH64
+#
+
+[Sources]
+ IntelBdsPlatform.c
+ IntelBdsPlatform.h
+ QemuKernel.c
+
+[Packages]
+ ArmPkg/ArmPkg.dec
+ ArmPlatformPkg/ArmPlatformPkg.dec
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ IntelFrameworkModulePkg/IntelFrameworkModulePkg.dec
+ OvmfPkg/OvmfPkg.dec
+
+[LibraryClasses]
+ ArmBdsHelperLib
+ BaseLib
+ BaseMemoryLib
+ DebugLib
+ DevicePathLib
+ MemoryAllocationLib
+ UefiBootServicesTableLib
+ PcdLib
+ GenericBdsLib
+ QemuBootOrderLib
+ QemuFwCfgLib
+ PrintLib
+ UefiRuntimeServicesTableLib
+
+[Guids]
+ gArmGlobalVariableGuid
+ gEfiFileInfoGuid
+ gEfiFileSystemInfoGuid
+ gEfiFileSystemVolumeLabelInfoIdGuid
+
+[Pcd]
+ gArmPlatformTokenSpaceGuid.PcdDefaultConInPaths
+ gArmPlatformTokenSpaceGuid.PcdDefaultConOutPaths
+ gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdPlatformBootTimeOut
+
+[Protocols]
+ gEfiDevicePathFromTextProtocolGuid
+ gEfiDevicePathToTextProtocolGuid
+ gEfiDevicePathProtocolGuid
+ gEfiLoadedImageProtocolGuid
+ gEfiSimpleFileSystemProtocolGuid
diff --git a/ArmPlatformPkg/ArmVirtualizationPkg/Library/PlatformIntelBdsLib/QemuKernel.c b/ArmPlatformPkg/ArmVirtualizationPkg/Library/PlatformIntelBdsLib/QemuKernel.c
new file mode 100644
index 0000000000..abcac777eb
--- /dev/null
+++ b/ArmPlatformPkg/ArmVirtualizationPkg/Library/PlatformIntelBdsLib/QemuKernel.c
@@ -0,0 +1,1103 @@
+/** @file
+ Try to load an EFI-stubbed ARM Linux kernel from QEMU's fw_cfg.
+
+ This implementation differs from OvmfPkg/Library/LoadLinuxLib. An EFI
+ stub in the subject kernel is a hard requirement here.
+
+ Copyright (C) 2014, Red Hat, Inc.
+
+ This program and the accompanying materials are licensed and made available
+ under the terms and conditions of the BSD License which accompanies this
+ distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, WITHOUT
+ WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+**/
+
+#include <Guid/FileInfo.h>
+#include <Guid/FileSystemInfo.h>
+#include <Guid/FileSystemVolumeLabelInfo.h>
+#include <Library/PrintLib.h>
+#include <Library/QemuFwCfgLib.h>
+#include <Protocol/DevicePath.h>
+#include <Protocol/LoadedImage.h>
+#include <Protocol/SimpleFileSystem.h>
+
+#include "IntelBdsPlatform.h"
+
+//
+// Static data that hosts the fw_cfg blobs and serves file requests.
+//
+typedef enum {
+ KernelBlobTypeKernel,
+ KernelBlobTypeInitrd,
+ KernelBlobTypeCommandLine,
+ KernelBlobTypeMax
+} KERNEL_BLOB_TYPE;
+
+typedef struct {
+ FIRMWARE_CONFIG_ITEM CONST SizeKey;
+ FIRMWARE_CONFIG_ITEM CONST DataKey;
+ CONST CHAR16 * CONST Name;
+ UINT32 Size;
+ UINT8 *Data;
+} KERNEL_BLOB;
+
+STATIC KERNEL_BLOB mKernelBlob[KernelBlobTypeMax] = {
+ { QemuFwCfgItemKernelSize, QemuFwCfgItemKernelData, L"kernel" },
+ { QemuFwCfgItemInitrdSize, QemuFwCfgItemInitrdData, L"initrd" },
+ { QemuFwCfgItemCommandLineSize, QemuFwCfgItemCommandLineData, L"cmdline" }
+};
+
+STATIC UINT64 mTotalBlobBytes;
+
+//
+// Device path for the handle that incorporates our "EFI stub filesystem". The
+// GUID is arbitrary and need not be standardized or advertized.
+//
+#pragma pack(1)
+typedef struct {
+ VENDOR_DEVICE_PATH VenHwNode;
+ EFI_DEVICE_PATH_PROTOCOL EndNode;
+} SINGLE_VENHW_NODE_DEVPATH;
+#pragma pack()
+
+STATIC CONST SINGLE_VENHW_NODE_DEVPATH mFileSystemDevicePath = {
+ {
+ { HARDWARE_DEVICE_PATH, HW_VENDOR_DP, { sizeof (VENDOR_DEVICE_PATH) } },
+ {
+ 0xb0fae7e7, 0x6b07, 0x49d0,
+ { 0x9e, 0x5b, 0x3b, 0xde, 0xc8, 0x3b, 0x03, 0x9d }
+ }
+ },
+
+ {
+ END_DEVICE_PATH_TYPE, END_ENTIRE_DEVICE_PATH_SUBTYPE,
+ { sizeof (EFI_DEVICE_PATH_PROTOCOL) }
+ }
+};
+
+//
+// The "file in the EFI stub filesystem" abstraction.
+//
+STATIC EFI_TIME mInitTime;
+
+#define STUB_FILE_SIG SIGNATURE_64 ('S', 'T', 'U', 'B', 'F', 'I', 'L', 'E')
+
+typedef struct {
+ UINT64 Signature; // Carries STUB_FILE_SIG.
+
+ KERNEL_BLOB_TYPE BlobType; // Index into mKernelBlob. KernelBlobTypeMax
+ // denotes the root directory of the filesystem.
+
+ UINT64 Position; // Byte position for regular files;
+ // next directory entry to return for the root
+ // directory.
+
+ EFI_FILE_PROTOCOL File; // Standard protocol interface.
+} STUB_FILE;
+
+#define STUB_FILE_FROM_FILE(FilePointer) \
+ CR (FilePointer, STUB_FILE, File, STUB_FILE_SIG)
+
+//
+// Tentative definition of the file protocol template. The initializer
+// (external definition) will be provided later.
+//
+STATIC CONST EFI_FILE_PROTOCOL mEfiFileProtocolTemplate;
+
+
+//
+// Protocol member functions for File.
+//
+
+/**
+ Opens a new file relative to the source file's location.
+
+ @param[in] This A pointer to the EFI_FILE_PROTOCOL instance that is
+ the file handle to the source location. This would
+ typically be an open handle to a directory.
+
+ @param[out] NewHandle A pointer to the location to return the opened handle
+ for the new file.
+
+ @param[in] 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[in] 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[in] Attributes Only valid for EFI_FILE_MODE_CREATE, in which case
+ these are the attribute bits for the newly created
+ file.
+
+ @retval EFI_SUCCESS The file was opened.
+ @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.
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+StubFileOpen (
+ IN EFI_FILE_PROTOCOL *This,
+ OUT EFI_FILE_PROTOCOL **NewHandle,
+ IN CHAR16 *FileName,
+ IN UINT64 OpenMode,
+ IN UINT64 Attributes
+ )
+{
+ CONST STUB_FILE *StubFile;
+ UINTN BlobType;
+ STUB_FILE *NewStubFile;
+
+ //
+ // We're read-only.
+ //
+ switch (OpenMode) {
+ case EFI_FILE_MODE_READ:
+ break;
+
+ case EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE:
+ case EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE | EFI_FILE_MODE_CREATE:
+ return EFI_WRITE_PROTECTED;
+
+ default:
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // Only the root directory supports opening files in it.
+ //
+ StubFile = STUB_FILE_FROM_FILE (This);
+ if (StubFile->BlobType != KernelBlobTypeMax) {
+ return EFI_UNSUPPORTED;
+ }
+
+ //
+ // Locate the file.
+ //
+ for (BlobType = 0; BlobType < KernelBlobTypeMax; ++BlobType) {
+ if (StrCmp (FileName, mKernelBlob[BlobType].Name) == 0) {
+ break;
+ }
+ }
+ if (BlobType == KernelBlobTypeMax) {
+ return EFI_NOT_FOUND;
+ }
+
+ //
+ // Found it.
+ //
+ NewStubFile = AllocatePool (sizeof *NewStubFile);
+ if (NewStubFile == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ NewStubFile->Signature = STUB_FILE_SIG;
+ NewStubFile->BlobType = (KERNEL_BLOB_TYPE)BlobType;
+ NewStubFile->Position = 0;
+ CopyMem (&NewStubFile->File, &mEfiFileProtocolTemplate,
+ sizeof mEfiFileProtocolTemplate);
+ *NewHandle = &NewStubFile->File;
+
+ return EFI_SUCCESS;
+}
+
+
+/**
+ Closes a specified file handle.
+
+ @param[in] This A pointer to the EFI_FILE_PROTOCOL instance that is the file
+ handle to close.
+
+ @retval EFI_SUCCESS The file was closed.
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+StubFileClose (
+ IN EFI_FILE_PROTOCOL *This
+ )
+{
+ FreePool (STUB_FILE_FROM_FILE (This));
+ return EFI_SUCCESS;
+}
+
+
+/**
+ Close and delete the file handle.
+
+ @param[in] This A pointer to the EFI_FILE_PROTOCOL instance that is the
+ handle to the file to delete.
+
+ @retval EFI_SUCCESS The file was closed and deleted, and the
+ handle was closed.
+ @retval EFI_WARN_DELETE_FAILURE The handle was closed, but the file was not
+ deleted.
+
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+StubFileDelete (
+ IN EFI_FILE_PROTOCOL *This
+ )
+{
+ FreePool (STUB_FILE_FROM_FILE (This));
+ return EFI_WARN_DELETE_FAILURE;
+}
+
+
+/**
+ Helper function that formats an EFI_FILE_INFO structure into the
+ user-allocated buffer, for any valid KERNEL_BLOB_TYPE value (including
+ KernelBlobTypeMax, which stands for the root directory).
+
+ The interface follows the EFI_FILE_GET_INFO -- and for directories, the
+ EFI_FILE_READ -- interfaces.
+
+ @param[in] BlobType The KERNEL_BLOB_TYPE value identifying the fw_cfg
+ blob backing the STUB_FILE that information is
+ being requested about. If BlobType equals
+ KernelBlobTypeMax, then information will be
+ provided about the root directory of the
+ filesystem.
+
+ @param[in,out] BufferSize On input, the size of Buffer. On output, the
+ amount of data returned in Buffer. In both cases,
+ the size is measured in bytes.
+
+ @param[out] Buffer A pointer to the data buffer to return. The
+ buffer's type is EFI_FILE_INFO.
+
+ @retval EFI_SUCCESS The information was returned.
+ @retval EFI_BUFFER_TOO_SMALL BufferSize is too small to store the
+ EFI_FILE_INFO structure. BufferSize has been
+ updated with the size needed to complete the
+ request.
+**/
+STATIC
+EFI_STATUS
+ConvertKernelBlobTypeToFileInfo (
+ IN KERNEL_BLOB_TYPE BlobType,
+ IN OUT UINTN *BufferSize,
+ OUT VOID *Buffer
+ )
+{
+ CONST CHAR16 *Name;
+ UINT64 FileSize;
+ UINT64 Attribute;
+
+ UINTN NameSize;
+ UINTN FileInfoSize;
+ EFI_FILE_INFO *FileInfo;
+ UINTN OriginalBufferSize;
+
+ if (BlobType == KernelBlobTypeMax) {
+ //
+ // getting file info about the root directory
+ //
+ Name = L"\\";
+ FileSize = KernelBlobTypeMax;
+ Attribute = EFI_FILE_READ_ONLY | EFI_FILE_DIRECTORY;
+ } else {
+ CONST KERNEL_BLOB *Blob;
+
+ Blob = &mKernelBlob[BlobType];
+ Name = Blob->Name;
+ FileSize = Blob->Size;
+ Attribute = EFI_FILE_READ_ONLY;
+ }
+
+ NameSize = (StrLen(Name) + 1) * 2;
+ FileInfoSize = OFFSET_OF (EFI_FILE_INFO, FileName) + NameSize;
+ ASSERT (FileInfoSize >= sizeof *FileInfo);
+
+ OriginalBufferSize = *BufferSize;
+ *BufferSize = FileInfoSize;
+ if (OriginalBufferSize < *BufferSize) {
+ return EFI_BUFFER_TOO_SMALL;
+ }
+
+ FileInfo = (EFI_FILE_INFO *)Buffer;
+ FileInfo->Size = FileInfoSize;
+ FileInfo->FileSize = FileSize;
+ FileInfo->PhysicalSize = FileSize;
+ FileInfo->Attribute = Attribute;
+
+ CopyMem (&FileInfo->CreateTime, &mInitTime, sizeof mInitTime);
+ CopyMem (&FileInfo->LastAccessTime, &mInitTime, sizeof mInitTime);
+ CopyMem (&FileInfo->ModificationTime, &mInitTime, sizeof mInitTime);
+ CopyMem (FileInfo->FileName, Name, NameSize);
+
+ return EFI_SUCCESS;
+}
+
+
+/**
+ Reads data from a file, or continues scanning a directory.
+
+ @param[in] This A pointer to the EFI_FILE_PROTOCOL instance that
+ is the file handle to read data from.
+
+ @param[in,out] BufferSize 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. If the read goes
+ beyond the end of the file, the read length is
+ truncated to the end of the file.
+
+ If This is a directory, the function reads the
+ directory entry at the current position and
+ returns the entry (as EFI_FILE_INFO) in Buffer. If
+ there are no more directory entries, the
+ BufferSize is set to zero on output.
+
+ @param[out] Buffer The buffer into which the data is read.
+
+ @retval EFI_SUCCESS Data was read.
+ @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_BUFFER_TOO_SMALL The BufferSize is too small to store the
+ current directory entry as a EFI_FILE_INFO
+ structure. BufferSize has been updated with the
+ size needed to complete the request, and the
+ directory position has not been advanced.
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+StubFileRead (
+ IN EFI_FILE_PROTOCOL *This,
+ IN OUT UINTN *BufferSize,
+ OUT VOID *Buffer
+ )
+{
+ STUB_FILE *StubFile;
+ CONST KERNEL_BLOB *Blob;
+ UINT64 Left;
+
+ StubFile = STUB_FILE_FROM_FILE (This);
+
+ //
+ // Scanning the root directory?
+ //
+ if (StubFile->BlobType == KernelBlobTypeMax) {
+ EFI_STATUS Status;
+
+ if (StubFile->Position == KernelBlobTypeMax) {
+ //
+ // Scanning complete.
+ //
+ *BufferSize = 0;
+ return EFI_SUCCESS;
+ }
+
+ Status = ConvertKernelBlobTypeToFileInfo (StubFile->Position, BufferSize,
+ Buffer);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ ++StubFile->Position;
+ return EFI_SUCCESS;
+ }
+
+ //
+ // Reading a file.
+ //
+ Blob = &mKernelBlob[StubFile->BlobType];
+ if (StubFile->Position > Blob->Size) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ Left = Blob->Size - StubFile->Position;
+ if (*BufferSize > Left) {
+ *BufferSize = (UINTN)Left;
+ }
+ if (Blob->Data != NULL) {
+ CopyMem (Buffer, Blob->Data + StubFile->Position, *BufferSize);
+ }
+ StubFile->Position += *BufferSize;
+ return EFI_SUCCESS;
+}
+
+
+/**
+ Writes data to a file.
+
+ @param[in] This A pointer to the EFI_FILE_PROTOCOL instance that
+ is the file handle to write data to.
+
+ @param[in,out] BufferSize On input, the size of the Buffer. On output, the
+ amount of data actually written. In both cases,
+ the size is measured in bytes.
+
+ @param[in] Buffer The buffer of data to write.
+
+ @retval EFI_SUCCESS Data was written.
+ @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.
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+StubFileWrite (
+ IN EFI_FILE_PROTOCOL *This,
+ IN OUT UINTN *BufferSize,
+ IN VOID *Buffer
+ )
+{
+ STUB_FILE *StubFile;
+
+ StubFile = STUB_FILE_FROM_FILE (This);
+ return (StubFile->BlobType == KernelBlobTypeMax) ?
+ EFI_UNSUPPORTED :
+ EFI_WRITE_PROTECTED;
+}
+
+
+/**
+ Returns a file's current position.
+
+ @param[in] This A pointer to the EFI_FILE_PROTOCOL instance that is the
+ file handle to get the current position on.
+
+ @param[out] Position The address to return the file's current position
+ value.
+
+ @retval EFI_SUCCESS The position was returned.
+ @retval EFI_UNSUPPORTED The request is not valid on open directories.
+ @retval EFI_DEVICE_ERROR An attempt was made to get the position from a
+ deleted file.
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+StubFileGetPosition (
+ IN EFI_FILE_PROTOCOL *This,
+ OUT UINT64 *Position
+ )
+{
+ STUB_FILE *StubFile;
+
+ StubFile = STUB_FILE_FROM_FILE (This);
+ if (StubFile->BlobType == KernelBlobTypeMax) {
+ return EFI_UNSUPPORTED;
+ }
+
+ *Position = StubFile->Position;
+ return EFI_SUCCESS;
+}
+
+
+/**
+ Sets a file's current position.
+
+ @param[in] This A pointer to the EFI_FILE_PROTOCOL instance that is the
+ file handle to set the requested position on.
+
+ @param[in] Position The byte position from the start of the file to set. For
+ regular files, MAX_UINT64 means "seek to end". For
+ directories, zero means "rewind directory scan".
+
+ @retval EFI_SUCCESS The position was set.
+ @retval EFI_UNSUPPORTED The seek request for nonzero is not valid on open
+ directories.
+ @retval EFI_DEVICE_ERROR An attempt was made to set the position of a
+ deleted file.
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+StubFileSetPosition (
+ IN EFI_FILE_PROTOCOL *This,
+ IN UINT64 Position
+ )
+{
+ STUB_FILE *StubFile;
+ KERNEL_BLOB *Blob;
+
+ StubFile = STUB_FILE_FROM_FILE (This);
+
+ if (StubFile->BlobType == KernelBlobTypeMax) {
+ if (Position == 0) {
+ //
+ // rewinding a directory scan is allowed
+ //
+ StubFile->Position = 0;
+ return EFI_SUCCESS;
+ }
+ return EFI_UNSUPPORTED;
+ }
+
+ //
+ // regular file seek
+ //
+ Blob = &mKernelBlob[StubFile->BlobType];
+ if (Position == MAX_UINT64) {
+ //
+ // seek to end
+ //
+ StubFile->Position = Blob->Size;
+ } else {
+ //
+ // absolute seek from beginning -- seeking past the end is allowed
+ //
+ StubFile->Position = Position;
+ }
+ return EFI_SUCCESS;
+}
+
+
+/**
+ Returns information about a file.
+
+ @param[in] This A pointer to the EFI_FILE_PROTOCOL instance
+ that is the file handle the requested
+ information is for.
+
+ @param[in] InformationType The type identifier GUID for the information
+ being requested. The following information
+ types are supported, storing the
+ corresponding structures in Buffer:
+
+ - gEfiFileInfoGuid: EFI_FILE_INFO
+
+ - gEfiFileSystemInfoGuid:
+ EFI_FILE_SYSTEM_INFO
+
+ - gEfiFileSystemVolumeLabelInfoIdGuid:
+ EFI_FILE_SYSTEM_VOLUME_LABEL
+
+ @param[in,out] BufferSize On input, the size of Buffer. On output, the
+ amount of data returned in Buffer. In both
+ cases, the size is measured in bytes.
+
+ @param[out] Buffer A pointer to the data buffer to return. The
+ buffer's type is indicated by
+ InformationType.
+
+ @retval EFI_SUCCESS The information was returned.
+ @retval EFI_UNSUPPORTED The InformationType is not known.
+ @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_BUFFER_TOO_SMALL The BufferSize is too small to store the
+ information structure requested by
+ InformationType. BufferSize has been updated
+ with the size needed to complete the request.
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+StubFileGetInfo (
+ IN EFI_FILE_PROTOCOL *This,
+ IN EFI_GUID *InformationType,
+ IN OUT UINTN *BufferSize,
+ OUT VOID *Buffer
+ )
+{
+ CONST STUB_FILE *StubFile;
+ UINTN OriginalBufferSize;
+
+ StubFile = STUB_FILE_FROM_FILE (This);
+
+ if (CompareGuid (InformationType, &gEfiFileInfoGuid)) {
+ return ConvertKernelBlobTypeToFileInfo (StubFile->BlobType, BufferSize,
+ Buffer);
+ }
+
+ OriginalBufferSize = *BufferSize;
+
+ if (CompareGuid (InformationType, &gEfiFileSystemInfoGuid)) {
+ EFI_FILE_SYSTEM_INFO *FileSystemInfo;
+
+ *BufferSize = sizeof *FileSystemInfo;
+ if (OriginalBufferSize < *BufferSize) {
+ return EFI_BUFFER_TOO_SMALL;
+ }
+
+ FileSystemInfo = (EFI_FILE_SYSTEM_INFO *)Buffer;
+ FileSystemInfo->Size = sizeof *FileSystemInfo;
+ FileSystemInfo->ReadOnly = TRUE;
+ FileSystemInfo->VolumeSize = mTotalBlobBytes;
+ FileSystemInfo->FreeSpace = 0;
+ FileSystemInfo->BlockSize = 1;
+ FileSystemInfo->VolumeLabel[0] = L'\0';
+
+ return EFI_SUCCESS;
+ }
+
+ if (CompareGuid (InformationType, &gEfiFileSystemVolumeLabelInfoIdGuid)) {
+ EFI_FILE_SYSTEM_VOLUME_LABEL *FileSystemVolumeLabel;
+
+ *BufferSize = sizeof *FileSystemVolumeLabel;
+ if (OriginalBufferSize < *BufferSize) {
+ return EFI_BUFFER_TOO_SMALL;
+ }
+
+ FileSystemVolumeLabel = (EFI_FILE_SYSTEM_VOLUME_LABEL *)Buffer;
+ FileSystemVolumeLabel->VolumeLabel[0] = L'\0';
+
+ return EFI_SUCCESS;
+ }
+
+ return EFI_UNSUPPORTED;
+}
+
+
+/**
+ Sets information about a file.
+
+ @param[in] File A pointer to the EFI_FILE_PROTOCOL instance that
+ is the file handle the information is for.
+
+ @param[in] InformationType The type identifier for the information being
+ set.
+
+ @param[in] BufferSize The size, in bytes, of Buffer.
+
+ @param[in] Buffer A pointer to the data buffer to write. The
+ buffer's type is indicated by InformationType.
+
+ @retval EFI_SUCCESS The information was set.
+ @retval EFI_UNSUPPORTED The InformationType is not known.
+ @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 InformationType is EFI_FILE_INFO_ID and the
+ media is read-only.
+ @retval EFI_WRITE_PROTECTED InformationType is
+ EFI_FILE_PROTOCOL_SYSTEM_INFO_ID and the media
+ is read only.
+ @retval EFI_WRITE_PROTECTED InformationType is
+ EFI_FILE_SYSTEM_VOLUME_LABEL_ID and the media
+ is read-only.
+ @retval EFI_ACCESS_DENIED An attempt is made to change the name of a file
+ to a file that is already present.
+ @retval EFI_ACCESS_DENIED An attempt is being made to change the
+ EFI_FILE_DIRECTORY Attribute.
+ @retval EFI_ACCESS_DENIED An attempt is being made to change the size of
+ a directory.
+ @retval EFI_ACCESS_DENIED InformationType is EFI_FILE_INFO_ID and the
+ file was opened read-only and an attempt is
+ being made to modify a field other than
+ Attribute.
+ @retval EFI_VOLUME_FULL The volume is full.
+ @retval EFI_BAD_BUFFER_SIZE BufferSize is smaller than the size of the type
+ indicated by InformationType.
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+StubFileSetInfo (
+ IN EFI_FILE_PROTOCOL *This,
+ IN EFI_GUID *InformationType,
+ IN UINTN BufferSize,
+ IN VOID *Buffer
+ )
+{
+ return EFI_WRITE_PROTECTED;
+}
+
+
+/**
+ Flushes all modified data associated with a file to a device.
+
+ @param [in] This A pointer to the EFI_FILE_PROTOCOL instance that is the
+ file handle to flush.
+
+ @retval EFI_SUCCESS The data was flushed.
+ @retval EFI_NO_MEDIA The device has no medium.
+ @retval EFI_DEVICE_ERROR The device reported an error.
+ @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted.
+ @retval EFI_WRITE_PROTECTED The file or medium is write-protected.
+ @retval EFI_ACCESS_DENIED The file was opened read-only.
+ @retval EFI_VOLUME_FULL The volume is full.
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+StubFileFlush (
+ IN EFI_FILE_PROTOCOL *This
+ )
+{
+ return EFI_WRITE_PROTECTED;
+}
+
+//
+// External definition of the file protocol template.
+//
+STATIC CONST EFI_FILE_PROTOCOL mEfiFileProtocolTemplate = {
+ EFI_FILE_PROTOCOL_REVISION, // revision 1
+ StubFileOpen,
+ StubFileClose,
+ StubFileDelete,
+ StubFileRead,
+ StubFileWrite,
+ StubFileGetPosition,
+ StubFileSetPosition,
+ StubFileGetInfo,
+ StubFileSetInfo,
+ StubFileFlush,
+ NULL, // OpenEx, revision 2
+ NULL, // ReadEx, revision 2
+ NULL, // WriteEx, revision 2
+ NULL // FlushEx, revision 2
+};
+
+
+//
+// Protocol member functions for SimpleFileSystem.
+//
+
+/**
+ Open the root directory on a volume.
+
+ @param[in] This A pointer to the volume to open the root directory on.
+
+ @param[out] Root A pointer to the location to return the opened file handle
+ for the root directory in.
+
+ @retval EFI_SUCCESS The device was opened.
+ @retval EFI_UNSUPPORTED This volume does not support the requested file
+ system type.
+ @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_ACCESS_DENIED The service denied access to the file.
+ @retval EFI_OUT_OF_RESOURCES The volume was not opened due to lack of
+ resources.
+ @retval EFI_MEDIA_CHANGED The device has a different medium in it or the
+ medium is no longer supported. Any existing
+ file handles for this volume are no longer
+ valid. To access the files on the new medium,
+ the volume must be reopened with OpenVolume().
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+StubFileSystemOpenVolume (
+ IN EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *This,
+ OUT EFI_FILE_PROTOCOL **Root
+ )
+{
+ STUB_FILE *StubFile;
+
+ StubFile = AllocatePool (sizeof *StubFile);
+ if (StubFile == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ StubFile->Signature = STUB_FILE_SIG;
+ StubFile->BlobType = KernelBlobTypeMax;
+ StubFile->Position = 0;
+ CopyMem (&StubFile->File, &mEfiFileProtocolTemplate,
+ sizeof mEfiFileProtocolTemplate);
+ *Root = &StubFile->File;
+
+ return EFI_SUCCESS;
+}
+
+STATIC CONST EFI_SIMPLE_FILE_SYSTEM_PROTOCOL mFileSystem = {
+ EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_REVISION,
+ StubFileSystemOpenVolume
+};
+
+
+//
+// Utility functions.
+//
+
+/**
+ Populate a blob in mKernelBlob.
+
+ param[in,out] Blob Pointer to the KERNEL_BLOB element in mKernelBlob that is
+ to be filled from fw_cfg.
+
+ @retval EFI_SUCCESS Blob has been populated. If fw_cfg reported a
+ size of zero for the blob, then Blob->Data has
+ been left unchanged.
+
+ @retval EFI_OUT_OF_RESOURCES Failed to allocate memory for Blob->Data.
+**/
+STATIC
+EFI_STATUS
+FetchBlob (
+ IN OUT KERNEL_BLOB *Blob
+ )
+{
+ UINT32 Left;
+
+ //
+ // Read blob size.
+ //
+ QemuFwCfgSelectItem (Blob->SizeKey);
+ Blob->Size = QemuFwCfgRead32 ();
+ if (Blob->Size == 0) {
+ return EFI_SUCCESS;
+ }
+
+ //
+ // Read blob.
+ //
+ Blob->Data = AllocatePool (Blob->Size);
+ if (Blob->Data == NULL) {
+ DEBUG ((EFI_D_ERROR, "%a: failed to allocate %Ld bytes for \"%s\"\n",
+ __FUNCTION__, (INT64)Blob->Size, Blob->Name));
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ DEBUG ((EFI_D_INFO, "%a: loading %Ld bytes for \"%s\"\n", __FUNCTION__,
+ (INT64)Blob->Size, Blob->Name));
+ QemuFwCfgSelectItem (Blob->DataKey);
+
+ Left = Blob->Size;
+ do {
+ UINT32 Chunk;
+
+ Chunk = (Left < SIZE_1MB) ? Left : SIZE_1MB;
+ QemuFwCfgReadBytes (Chunk, Blob->Data + (Blob->Size - Left));
+ Left -= Chunk;
+ DEBUG ((EFI_D_VERBOSE, "%a: %Ld bytes remaining for \"%s\"\n",
+ __FUNCTION__, (INT64)Left, Blob->Name));
+ } while (Left > 0);
+ return EFI_SUCCESS;
+}
+
+
+//
+// The entry point of the feature.
+//
+
+/**
+ Download the kernel, the initial ramdisk, and the kernel command line from
+ QEMU's fw_cfg. Construct a minimal SimpleFileSystem that contains the two
+ image files, and load and start the kernel from it.
+
+ The kernel will be instructed via its command line to load the initrd from
+ the same Simple FileSystem.
+
+ @retval EFI_NOT_FOUND Kernel image was not found.
+ @retval EFI_OUT_OF_RESOURCES Memory allocation failed.
+ @retval EFI_PROTOCOL_ERROR Unterminated kernel command line.
+
+ @return Error codes from any of the underlying
+ functions. On success, the function doesn't
+ return.
+**/
+EFI_STATUS
+EFIAPI
+TryRunningQemuKernel (
+ VOID
+ )
+{
+ UINTN BlobType;
+ KERNEL_BLOB *CurrentBlob;
+ KERNEL_BLOB *KernelBlob, *InitrdBlob, *CommandLineBlob;
+ EFI_STATUS Status;
+ EFI_HANDLE FileSystemHandle;
+ EFI_DEVICE_PATH_PROTOCOL *KernelDevicePath;
+ EFI_HANDLE KernelImageHandle;
+ EFI_LOADED_IMAGE_PROTOCOL *KernelLoadedImage;
+
+ Status = gRT->GetTime (&mInitTime, NULL /* Capabilities */);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR, "%a: GetTime(): %r\n", __FUNCTION__, Status));
+ return Status;
+ }
+
+ //
+ // Fetch all blobs.
+ //
+ for (BlobType = 0; BlobType < KernelBlobTypeMax; ++BlobType) {
+ CurrentBlob = &mKernelBlob[BlobType];
+ Status = FetchBlob (CurrentBlob);
+ if (EFI_ERROR (Status)) {
+ goto FreeBlobs;
+ }
+ mTotalBlobBytes += CurrentBlob->Size;
+ }
+ KernelBlob = &mKernelBlob[KernelBlobTypeKernel];
+ InitrdBlob = &mKernelBlob[KernelBlobTypeInitrd];
+ CommandLineBlob = &mKernelBlob[KernelBlobTypeCommandLine];
+
+ //
+ // Create a new handle with a single VenHw() node device path protocol on it,
+ // plus a custom SimpleFileSystem protocol on it.
+ //
+ FileSystemHandle = NULL;
+ Status = gBS->InstallMultipleProtocolInterfaces (&FileSystemHandle,
+ &gEfiDevicePathProtocolGuid, &mFileSystemDevicePath,
+ &gEfiSimpleFileSystemProtocolGuid, &mFileSystem,
+ NULL);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR, "%a: InstallMultipleProtocolInterfaces(): %r\n",
+ __FUNCTION__, Status));
+ goto FreeBlobs;
+ }
+
+ //
+ // Create a device path for the kernel image to be loaded from that will call
+ // back into our file system.
+ //
+ KernelDevicePath = FileDevicePath (FileSystemHandle, KernelBlob->Name);
+ if (KernelDevicePath == NULL) {
+ DEBUG ((EFI_D_ERROR, "%a: failed to allocate kernel device path\n",
+ __FUNCTION__));
+ Status = EFI_OUT_OF_RESOURCES;
+ goto UninstallProtocols;
+ }
+
+ //
+ // Load the image. This should call back into our file system.
+ //
+ Status = gBS->LoadImage (
+ FALSE, // BootPolicy: exact match required
+ gImageHandle, // ParentImageHandle
+ KernelDevicePath,
+ NULL, // SourceBuffer
+ 0, // SourceSize
+ &KernelImageHandle
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR, "%a: LoadImage(): %r\n", __FUNCTION__, Status));
+ goto FreeKernelDevicePath;
+ }
+
+ //
+ // Construct the kernel command line.
+ //
+ Status = gBS->OpenProtocol (
+ KernelImageHandle,
+ &gEfiLoadedImageProtocolGuid,
+ (VOID **)&KernelLoadedImage,
+ gImageHandle, // AgentHandle
+ NULL, // ControllerHandle
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ if (CommandLineBlob->Data == NULL) {
+ KernelLoadedImage->LoadOptionsSize = 0;
+ } else {
+ //
+ // Verify NUL-termination of the command line.
+ //
+ if (CommandLineBlob->Data[CommandLineBlob->Size - 1] != '\0') {
+ DEBUG ((EFI_D_ERROR, "%a: kernel command line is not NUL-terminated\n",
+ __FUNCTION__));
+ Status = EFI_PROTOCOL_ERROR;
+ goto UnloadKernelImage;
+ }
+
+ //
+ // Drop the terminating NUL, convert to UTF-16.
+ //
+ KernelLoadedImage->LoadOptionsSize = (CommandLineBlob->Size - 1) * 2;
+ }
+
+ if (InitrdBlob->Data != NULL) {
+ //
+ // Append ' initrd=<name>' in UTF-16.
+ //
+ KernelLoadedImage->LoadOptionsSize +=
+ (8 + StrLen(InitrdBlob->Name)) * 2;
+ }
+
+ if (KernelLoadedImage->LoadOptionsSize == 0) {
+ KernelLoadedImage->LoadOptions = NULL;
+ } else {
+ //
+ // NUL-terminate in UTF-16.
+ //
+ KernelLoadedImage->LoadOptionsSize += 2;
+
+ KernelLoadedImage->LoadOptions = AllocatePool (
+ KernelLoadedImage->LoadOptionsSize);
+ if (KernelLoadedImage->LoadOptions == NULL) {
+ KernelLoadedImage->LoadOptionsSize = 0;
+ Status = EFI_OUT_OF_RESOURCES;
+ goto UnloadKernelImage;
+ }
+
+ UnicodeSPrintAsciiFormat (
+ KernelLoadedImage->LoadOptions,
+ KernelLoadedImage->LoadOptionsSize,
+ "%a%a%s",
+ (CommandLineBlob->Data == NULL) ? "" : (CHAR8 *)CommandLineBlob->Data,
+ (InitrdBlob->Data == NULL) ? "" : " initrd=",
+ (InitrdBlob->Data == NULL) ? L"" : InitrdBlob->Name
+ );
+ DEBUG ((EFI_D_INFO, "%a: command line: \"%s\"\n", __FUNCTION__,
+ (CHAR16 *)KernelLoadedImage->LoadOptions));
+ }
+
+ //
+ // Start the image.
+ //
+ Status = gBS->StartImage (
+ KernelImageHandle,
+ NULL, // ExitDataSize
+ NULL // ExitData
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR, "%a: StartImage(): %r\n", __FUNCTION__, Status));
+ }
+
+ if (KernelLoadedImage->LoadOptions != NULL) {
+ FreePool (KernelLoadedImage->LoadOptions);
+ }
+ KernelLoadedImage->LoadOptionsSize = 0;
+
+UnloadKernelImage:
+ gBS->UnloadImage (KernelImageHandle);
+
+FreeKernelDevicePath:
+ FreePool (KernelDevicePath);
+
+UninstallProtocols:
+ gBS->UninstallMultipleProtocolInterfaces (FileSystemHandle,
+ &gEfiSimpleFileSystemProtocolGuid, &mFileSystem,
+ &gEfiDevicePathProtocolGuid, &mFileSystemDevicePath,
+ NULL);
+
+FreeBlobs:
+ while (BlobType > 0) {
+ CurrentBlob = &mKernelBlob[--BlobType];
+ if (CurrentBlob->Data != NULL) {
+ FreePool (CurrentBlob->Data);
+ CurrentBlob->Size = 0;
+ CurrentBlob->Data = NULL;
+ }
+ }
+
+ return Status;
+}
diff --git a/ArmPlatformPkg/ArmVirtualizationPkg/Library/QemuFwCfgLib/QemuFwCfgLib.c b/ArmPlatformPkg/ArmVirtualizationPkg/Library/QemuFwCfgLib/QemuFwCfgLib.c
new file mode 100644
index 0000000000..e9e96d7a8d
--- /dev/null
+++ b/ArmPlatformPkg/ArmVirtualizationPkg/Library/QemuFwCfgLib/QemuFwCfgLib.c
@@ -0,0 +1,358 @@
+/** @file
+
+ Stateful and implicitly initialized fw_cfg library implementation.
+
+ Copyright (C) 2013 - 2014, Red Hat, Inc.
+ 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
+ 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/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/IoLib.h>
+#include <Library/PcdLib.h>
+#include <Library/QemuFwCfgLib.h>
+
+STATIC UINTN mFwCfgSelectorAddress;
+STATIC UINTN mFwCfgDataAddress;
+
+
+/**
+ Returns a boolean indicating if the firmware configuration interface is
+ available for library-internal purposes.
+
+ This function never changes fw_cfg state.
+
+ @retval TRUE The interface is available internally.
+ @retval FALSE The interface is not available internally.
+**/
+BOOLEAN
+EFIAPI
+InternalQemuFwCfgIsAvailable (
+ VOID
+ )
+{
+ return (BOOLEAN)(mFwCfgSelectorAddress != 0 && mFwCfgDataAddress != 0);
+}
+
+
+/**
+ Returns a boolean indicating if the firmware configuration interface
+ is available or not.
+
+ This function may change fw_cfg state.
+
+ @retval TRUE The interface is available
+ @retval FALSE The interface is not available
+
+**/
+BOOLEAN
+EFIAPI
+QemuFwCfgIsAvailable (
+ VOID
+ )
+{
+ return InternalQemuFwCfgIsAvailable ();
+}
+
+
+RETURN_STATUS
+EFIAPI
+QemuFwCfgInitialize (
+ VOID
+ )
+{
+ mFwCfgSelectorAddress = (UINTN)PcdGet64 (PcdFwCfgSelectorAddress);
+ mFwCfgDataAddress = (UINTN)PcdGet64 (PcdFwCfgDataAddress);
+
+ if (InternalQemuFwCfgIsAvailable ()) {
+ UINT32 Signature;
+
+ QemuFwCfgSelectItem (QemuFwCfgItemSignature);
+ Signature = QemuFwCfgRead32 ();
+ if (Signature != SIGNATURE_32 ('Q', 'E', 'M', 'U')) {
+ mFwCfgSelectorAddress = 0;
+ mFwCfgDataAddress = 0;
+ }
+ }
+ return RETURN_SUCCESS;
+}
+
+
+/**
+ Selects a firmware configuration item for reading.
+
+ Following this call, any data read from this item will start from the
+ beginning of the configuration item's data.
+
+ @param[in] QemuFwCfgItem Firmware Configuration item to read
+
+**/
+VOID
+EFIAPI
+QemuFwCfgSelectItem (
+ IN FIRMWARE_CONFIG_ITEM QemuFwCfgItem
+ )
+{
+ if (InternalQemuFwCfgIsAvailable ()) {
+ MmioWrite16 (mFwCfgSelectorAddress, SwapBytes16 ((UINT16)QemuFwCfgItem));
+ }
+}
+
+
+/**
+ Reads firmware configuration bytes into a buffer
+
+ @param[in] Size Size in bytes to read
+ @param[in] Buffer Buffer to store data into (OPTIONAL if Size is 0)
+
+**/
+STATIC
+VOID
+EFIAPI
+InternalQemuFwCfgReadBytes (
+ IN UINTN Size,
+ IN VOID *Buffer OPTIONAL
+ )
+{
+ UINTN Left;
+ UINT8 *Ptr;
+ UINT8 *End;
+
+#ifdef MDE_CPU_AARCH64
+ Left = Size & 7;
+#else
+ Left = Size & 3;
+#endif
+
+ Size -= Left;
+ Ptr = Buffer;
+ End = Ptr + Size;
+
+#ifdef MDE_CPU_AARCH64
+ while (Ptr < End) {
+ *(UINT64 *)Ptr = MmioRead64 (mFwCfgDataAddress);
+ Ptr += 8;
+ }
+ if (Left & 4) {
+ *(UINT32 *)Ptr = MmioRead32 (mFwCfgDataAddress);
+ Ptr += 4;
+ }
+#else
+ while (Ptr < End) {
+ *(UINT32 *)Ptr = MmioRead32 (mFwCfgDataAddress);
+ Ptr += 4;
+ }
+#endif
+
+ if (Left & 2) {
+ *(UINT16 *)Ptr = MmioRead16 (mFwCfgDataAddress);
+ Ptr += 2;
+ }
+ if (Left & 1) {
+ *Ptr = MmioRead8 (mFwCfgDataAddress);
+ }
+}
+
+
+/**
+ Reads firmware configuration bytes into a buffer
+
+ If called multiple times, then the data read will continue at the offset of
+ the firmware configuration item where the previous read ended.
+
+ @param[in] Size Size in bytes to read
+ @param[in] Buffer Buffer to store data into
+
+**/
+VOID
+EFIAPI
+QemuFwCfgReadBytes (
+ IN UINTN Size,
+ IN VOID *Buffer
+ )
+{
+ if (InternalQemuFwCfgIsAvailable ()) {
+ InternalQemuFwCfgReadBytes (Size, Buffer);
+ } else {
+ ZeroMem (Buffer, Size);
+ }
+}
+
+/**
+ Write firmware configuration bytes from a buffer
+
+ If called multiple times, then the data written will continue at the offset
+ of the firmware configuration item where the previous write ended.
+
+ @param[in] Size Size in bytes to write
+ @param[in] Buffer Buffer to read data from
+
+**/
+VOID
+EFIAPI
+QemuFwCfgWriteBytes (
+ IN UINTN Size,
+ IN VOID *Buffer
+ )
+{
+ if (InternalQemuFwCfgIsAvailable ()) {
+ UINTN Idx;
+
+ for (Idx = 0; Idx < Size; ++Idx) {
+ MmioWrite8 (mFwCfgDataAddress, ((UINT8 *)Buffer)[Idx]);
+ }
+ }
+}
+
+
+/**
+ Reads a UINT8 firmware configuration value
+
+ @return Value of Firmware Configuration item read
+
+**/
+UINT8
+EFIAPI
+QemuFwCfgRead8 (
+ VOID
+ )
+{
+ UINT8 Result;
+
+ QemuFwCfgReadBytes (sizeof Result, &Result);
+ return Result;
+}
+
+
+/**
+ Reads a UINT16 firmware configuration value
+
+ @return Value of Firmware Configuration item read
+
+**/
+UINT16
+EFIAPI
+QemuFwCfgRead16 (
+ VOID
+ )
+{
+ UINT16 Result;
+
+ QemuFwCfgReadBytes (sizeof Result, &Result);
+ return Result;
+}
+
+
+/**
+ Reads a UINT32 firmware configuration value
+
+ @return Value of Firmware Configuration item read
+
+**/
+UINT32
+EFIAPI
+QemuFwCfgRead32 (
+ VOID
+ )
+{
+ UINT32 Result;
+
+ QemuFwCfgReadBytes (sizeof Result, &Result);
+ return Result;
+}
+
+
+/**
+ Reads a UINT64 firmware configuration value
+
+ @return Value of Firmware Configuration item read
+
+**/
+UINT64
+EFIAPI
+QemuFwCfgRead64 (
+ VOID
+ )
+{
+ UINT64 Result;
+
+ QemuFwCfgReadBytes (sizeof Result, &Result);
+ return Result;
+}
+
+
+/**
+ Find the configuration item corresponding to the firmware configuration file.
+
+ @param[in] Name Name of file to look up.
+ @param[out] Item Configuration item corresponding to the file, to be passed
+ to QemuFwCfgSelectItem ().
+ @param[out] Size Number of bytes in the file.
+
+ @retval RETURN_SUCCESS If file is found.
+ @retval RETURN_NOT_FOUND If file is not found.
+ @retval RETURN_UNSUPPORTED If firmware configuration is unavailable.
+
+**/
+RETURN_STATUS
+EFIAPI
+QemuFwCfgFindFile (
+ IN CONST CHAR8 *Name,
+ OUT FIRMWARE_CONFIG_ITEM *Item,
+ OUT UINTN *Size
+ )
+{
+ UINT32 Count;
+ UINT32 Idx;
+
+ if (!InternalQemuFwCfgIsAvailable ()) {
+ return RETURN_UNSUPPORTED;
+ }
+
+ QemuFwCfgSelectItem (QemuFwCfgItemFileDir);
+ Count = SwapBytes32 (QemuFwCfgRead32 ());
+
+ for (Idx = 0; Idx < Count; ++Idx) {
+ UINT32 FileSize;
+ UINT16 FileSelect;
+ CHAR8 FName[QEMU_FW_CFG_FNAME_SIZE];
+
+ FileSize = QemuFwCfgRead32 ();
+ FileSelect = QemuFwCfgRead16 ();
+ QemuFwCfgRead16 (); // skip the field called "reserved"
+ InternalQemuFwCfgReadBytes (sizeof (FName), FName);
+
+ if (AsciiStrCmp (Name, FName) == 0) {
+ *Item = SwapBytes16 (FileSelect);
+ *Size = SwapBytes32 (FileSize);
+ return RETURN_SUCCESS;
+ }
+ }
+
+ return RETURN_NOT_FOUND;
+}
+
+
+/**
+ Determine if S3 support is explicitly enabled.
+
+ @retval TRUE if S3 support is explicitly enabled.
+ FALSE otherwise. This includes unavailability of the firmware
+ configuration interface.
+**/
+BOOLEAN
+EFIAPI
+QemuFwCfgS3Enabled (
+ VOID
+ )
+{
+ return FALSE;
+}
diff --git a/ArmPlatformPkg/ArmVirtualizationPkg/Library/QemuFwCfgLib/QemuFwCfgLib.inf b/ArmPlatformPkg/ArmVirtualizationPkg/Library/QemuFwCfgLib/QemuFwCfgLib.inf
new file mode 100644
index 0000000000..21ab2bf186
--- /dev/null
+++ b/ArmPlatformPkg/ArmVirtualizationPkg/Library/QemuFwCfgLib/QemuFwCfgLib.inf
@@ -0,0 +1,52 @@
+## @file
+#
+# Stateful, implicitly initialized fw_cfg library.
+#
+# Copyright (C) 2013 - 2014, Red Hat, Inc.
+# Copyright (c) 2008 - 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.
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = QemuFwCfgLib
+ FILE_GUID = B271F41F-B841-48A9-BA8D-545B4BC2E2BF
+ MODULE_TYPE = BASE
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = QemuFwCfgLib|DXE_DRIVER
+
+ CONSTRUCTOR = QemuFwCfgInitialize
+
+#
+# The following information is for reference only and not required by the build
+# tools.
+#
+# VALID_ARCHITECTURES = ARM AARCH64
+#
+
+[Sources]
+ QemuFwCfgLib.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ OvmfPkg/OvmfPkg.dec
+ ArmPlatformPkg/ArmVirtualizationPkg/ArmVirtualizationPkg.dec
+
+[LibraryClasses]
+ BaseLib
+ BaseMemoryLib
+ IoLib
+ PcdLib
+
+[Pcd]
+ gArmVirtualizationTokenSpaceGuid.PcdFwCfgSelectorAddress
+ gArmVirtualizationTokenSpaceGuid.PcdFwCfgDataAddress
diff --git a/ArmPlatformPkg/ArmVirtualizationPkg/VirtFdtDxe/VirtFdtDxe.c b/ArmPlatformPkg/ArmVirtualizationPkg/VirtFdtDxe/VirtFdtDxe.c
index d002e668aa..751864d4db 100644
--- a/ArmPlatformPkg/ArmVirtualizationPkg/VirtFdtDxe/VirtFdtDxe.c
+++ b/ArmPlatformPkg/ArmVirtualizationPkg/VirtFdtDxe/VirtFdtDxe.c
@@ -27,6 +27,7 @@
#include <libfdt.h>
#include <Guid/Fdt.h>
+#include <Guid/VirtioMmioTransport.h>
#pragma pack (1)
typedef struct {
@@ -44,6 +45,7 @@ typedef enum {
PropertyTypeUart,
PropertyTypeTimer,
PropertyTypePsci,
+ PropertyTypeFwCfg,
} PROPERTY_TYPE;
typedef struct {
@@ -59,6 +61,7 @@ STATIC CONST PROPERTY CompatibleProperties[] = {
{ PropertyTypeTimer, "arm,armv7-timer" },
{ PropertyTypeTimer, "arm,armv8-timer" },
{ PropertyTypePsci, "arm,psci-0.2" },
+ { PropertyTypeFwCfg, "qemu,fw-cfg-mmio" },
{ PropertyTypeUnknown, "" }
};
@@ -115,6 +118,10 @@ InitializeVirtFdtDxe (
CONST INTERRUPT_PROPERTY *InterruptProp;
INT32 SecIntrNum, IntrNum, VirtIntrNum, HypIntrNum;
CONST CHAR8 *PsciMethod;
+ UINT64 FwCfgSelectorAddress;
+ UINT64 FwCfgSelectorSize;
+ UINT64 FwCfgDataAddress;
+ UINT64 FwCfgDataSize;
DeviceTreeBase = (VOID *)(UINTN)PcdGet64 (PcdDeviceTreeBaseAddress);
ASSERT (DeviceTreeBase != NULL);
@@ -160,6 +167,34 @@ InitializeVirtFdtDxe (
(PropType == PropertyTypePsci));
switch (PropType) {
+ case PropertyTypeFwCfg:
+ ASSERT (Len == 2 * sizeof (UINT64));
+
+ FwCfgDataAddress = fdt64_to_cpu (((UINT64 *)RegProp)[0]);
+ FwCfgDataSize = 8;
+ FwCfgSelectorAddress = FwCfgDataAddress + FwCfgDataSize;
+ FwCfgSelectorSize = 2;
+
+ //
+ // The following ASSERT()s express
+ //
+ // Address + Size - 1 <= MAX_UINTN
+ //
+ // for both registers, that is, that the last byte in each MMIO range is
+ // expressible as a MAX_UINTN. The form below is mathematically
+ // equivalent, and it also prevents any unsigned overflow before the
+ // comparison.
+ //
+ ASSERT (FwCfgSelectorAddress <= MAX_UINTN - FwCfgSelectorSize + 1);
+ ASSERT (FwCfgDataAddress <= MAX_UINTN - FwCfgDataSize + 1);
+
+ PcdSet64 (PcdFwCfgSelectorAddress, FwCfgSelectorAddress);
+ PcdSet64 (PcdFwCfgDataAddress, FwCfgDataAddress);
+
+ DEBUG ((EFI_D_INFO, "Found FwCfg @ 0x%Lx/0x%Lx\n", FwCfgSelectorAddress,
+ FwCfgDataAddress));
+ break;
+
case PropertyTypeVirtio:
ASSERT (Len == 16);
//
@@ -175,7 +210,8 @@ InitializeVirtFdtDxe (
break;
}
- CopyMem (&DevicePath->Vendor.Guid, &gEfiCallerIdGuid, sizeof (EFI_GUID));
+ CopyMem (&DevicePath->Vendor.Guid, &gVirtioMmioTransportGuid,
+ sizeof (EFI_GUID));
DevicePath->PhysBase = RegBase;
SetDevicePathNodeLength (&DevicePath->Vendor,
sizeof (*DevicePath) - sizeof (DevicePath->End));
diff --git a/ArmPlatformPkg/ArmVirtualizationPkg/VirtFdtDxe/VirtFdtDxe.inf b/ArmPlatformPkg/ArmVirtualizationPkg/VirtFdtDxe/VirtFdtDxe.inf
index 1c9dd20580..514ce2fdf6 100644
--- a/ArmPlatformPkg/ArmVirtualizationPkg/VirtFdtDxe/VirtFdtDxe.inf
+++ b/ArmPlatformPkg/ArmVirtualizationPkg/VirtFdtDxe/VirtFdtDxe.inf
@@ -16,7 +16,7 @@
[Defines]
INF_VERSION = 0x00010005
BASE_NAME = VirtFdtDxe
- FILE_GUID = 837DCA9E-E874-4D82-B29A-23FE0E23D1E2
+ FILE_GUID = 9AD7DCB4-E6EC-472E-96BF-81C219A3F77E
MODULE_TYPE = DXE_DRIVER
VERSION_STRING = 1.0
@@ -43,10 +43,13 @@
[Guids]
gFdtTableGuid
+ gVirtioMmioTransportGuid
[Pcd]
gArmVirtualizationTokenSpaceGuid.PcdDeviceTreeBaseAddress
gArmVirtualizationTokenSpaceGuid.PcdArmPsciMethod
+ gArmVirtualizationTokenSpaceGuid.PcdFwCfgSelectorAddress
+ gArmVirtualizationTokenSpaceGuid.PcdFwCfgDataAddress
gArmTokenSpaceGuid.PcdGicDistributorBase
gArmTokenSpaceGuid.PcdGicInterruptInterfaceBase
gArmTokenSpaceGuid.PcdArmArchTimerSecIntrNum
diff --git a/ArmPlatformPkg/Bds/BootMenu.c b/ArmPlatformPkg/Bds/BootMenu.c
index 91e00b759e..3a72df0495 100644
--- a/ArmPlatformPkg/Bds/BootMenu.c
+++ b/ArmPlatformPkg/Bds/BootMenu.c
@@ -341,6 +341,9 @@ BootMenuAddBootOption (
if (InitrdPathNodes != NULL) {
// Append the Device Path to the selected device path
InitrdPath = AppendDevicePath (SupportedBootDevice->DevicePathProtocol, (CONST EFI_DEVICE_PATH_PROTOCOL *)InitrdPathNodes);
+ // Free the InitrdPathNodes created by Support->CreateDevicePathNode()
+ FreePool (InitrdPathNodes);
+
if (InitrdPath == NULL) {
Status = EFI_OUT_OF_RESOURCES;
goto EXIT;
@@ -540,6 +543,8 @@ BootMenuUpdateBootOption (
// Append the Device Path to the selected device path
InitrdPath = AppendDevicePath (TempInitrdPath, (CONST EFI_DEVICE_PATH_PROTOCOL *)InitrdPathNodes);
FreePool (TempInitrdPath);
+ // Free the InitrdPathNodes created by Support->CreateDevicePathNode()
+ FreePool (InitrdPathNodes);
if (InitrdPath == NULL) {
Status = EFI_OUT_OF_RESOURCES;
goto EXIT;
@@ -846,6 +851,8 @@ UpdateFdtPath (
if (FdtDevicePathNodes != NULL) {
// Append the Device Path node to the select device path
FdtDevicePath = AppendDevicePath (SupportedBootDevice->DevicePathProtocol, FdtDevicePathNodes);
+ // Free the FdtDevicePathNodes created by Support->CreateDevicePathNode()
+ FreePool (FdtDevicePathNodes);
FdtDevicePathSize = GetDevicePathSize (FdtDevicePath);
Status = gRT->SetVariable (
(CHAR16*)L"Fdt",
diff --git a/ArmPlatformPkg/Bds/BootOption.c b/ArmPlatformPkg/Bds/BootOption.c
index 5712d2ccb4..80982222e1 100644
--- a/ArmPlatformPkg/Bds/BootOption.c
+++ b/ArmPlatformPkg/Bds/BootOption.c
@@ -221,6 +221,8 @@ BootOptionSetFields (
WriteUnaligned32 ((UINT32 *)EfiLoadOptionPtr, ARM_BDS_OPTIONAL_DATA_SIGNATURE);
WriteUnaligned32 ((UINT32 *)(EfiLoadOptionPtr + 4), BootType);
+ // OptionalData should have been initialized by the caller of this function
+ ASSERT (OptionalData != NULL);
BootArguments = (ARM_BDS_LOADER_ARGUMENTS*)OptionalData;
SrcLinuxArguments = &(BootArguments->LinuxArguments);
DestLinuxArguments = &((ARM_BDS_LOADER_OPTIONAL_DATA*)EfiLoadOptionPtr)->Arguments.LinuxArguments;
@@ -237,7 +239,9 @@ BootOptionSetFields (
CopyMem (InitrdPathListPtr, (VOID*)((UINTN)(SrcLinuxArguments + 1) + SrcLinuxArguments->CmdLineSize), SrcLinuxArguments->InitrdSize);
}
} else {
- CopyMem (BootOption->OptionalData, OptionalData, OptionalDataSize);
+ if (OptionalData != NULL) {
+ CopyMem (BootOption->OptionalData, OptionalData, OptionalDataSize);
+ }
}
BootOption->OptionalDataSize = OptionalDataSize;
diff --git a/ArmPlatformPkg/Drivers/PL011Uart/PL011Uart.c b/ArmPlatformPkg/Drivers/PL011Uart/PL011Uart.c
index 7e74a05df7..90a41abd95 100644
--- a/ArmPlatformPkg/Drivers/PL011Uart/PL011Uart.c
+++ b/ArmPlatformPkg/Drivers/PL011Uart/PL011Uart.c
@@ -50,12 +50,15 @@ PL011UartInitializePort (
LineControl = 0;
- // The PL011 supports a buffer of either 1 or 32 chars. Therefore we can accept
+ // The PL011 supports a buffer of 1, 16 or 32 chars. Therefore we can accept
// 1 char buffer as the minimum fifo size. Because everything can be rounded down,
// there is no maximum fifo size.
if ((*ReceiveFifoDepth == 0) || (*ReceiveFifoDepth >= 32)) {
LineControl |= PL011_UARTLCR_H_FEN;
- *ReceiveFifoDepth = 32;
+ if (PL011_UARTPID2_VER(MmioRead32 (UartBase + UARTPID2)) > PL011_VER_R1P4)
+ *ReceiveFifoDepth = 32;
+ else
+ *ReceiveFifoDepth = 16;
} else {
ASSERT (*ReceiveFifoDepth < 32);
// Nothing else to do. 1 byte fifo is default.
diff --git a/ArmPlatformPkg/FileSystem/BootMonFs/BootMonFs.inf b/ArmPlatformPkg/FileSystem/BootMonFs/BootMonFs.inf
index 94e8916e1b..43595d88ee 100644
--- a/ArmPlatformPkg/FileSystem/BootMonFs/BootMonFs.inf
+++ b/ArmPlatformPkg/FileSystem/BootMonFs/BootMonFs.inf
@@ -33,9 +33,12 @@
[Packages]
ArmPlatformPkg/ArmPlatformPkg.dec
MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ ShellPkg/ShellPkg.dec
[LibraryClasses]
BaseLib
+ BasePathLib
DevicePathLib
MemoryAllocationLib
PrintLib
diff --git a/ArmPlatformPkg/FileSystem/BootMonFs/BootMonFsApi.h b/ArmPlatformPkg/FileSystem/BootMonFs/BootMonFsApi.h
index 9c1daa523b..d690520a0f 100644
--- a/ArmPlatformPkg/FileSystem/BootMonFs/BootMonFsApi.h
+++ b/ArmPlatformPkg/FileSystem/BootMonFs/BootMonFsApi.h
@@ -79,18 +79,70 @@ BootMonFsFlushDirectory (
IN EFI_FILE_PROTOCOL *This
);
+/**
+ Flush all modified data associated with a file to a device.
+
+ @param[in] This A pointer to the EFI_FILE_PROTOCOL instance that is the
+ file handle to flush.
+
+ @retval EFI_SUCCESS The data was flushed.
+ @retval EFI_ACCESS_DENIED The file was opened read-only.
+ @retval EFI_DEVICE_ERROR The device reported an error.
+ @retval EFI_VOLUME_FULL The volume is full.
+ @retval EFI_OUT_OF_RESOURCES Not enough resources were available to flush the data.
+ @retval EFI_INVALID_PARAMETER At least one of the parameters is invalid.
+
+**/
EFIAPI
EFI_STATUS
BootMonFsFlushFile (
IN EFI_FILE_PROTOCOL *This
);
+/**
+ Close a specified file handle.
+
+ @param[in] This A pointer to the EFI_FILE_PROTOCOL instance that is the file
+ handle to close.
+
+ @retval EFI_SUCCESS The file was closed.
+ @retval EFI_INVALID_PARAMETER The parameter "This" is NULL or is not an open
+ file handle.
+
+**/
EFIAPI
EFI_STATUS
BootMonFsCloseFile (
IN EFI_FILE_PROTOCOL *This
);
+/**
+ Open a file on the boot monitor file system.
+
+ The boot monitor file system does not allow for sub-directories. There is only
+ one directory, the root one. On any attempt to create a directory, the function
+ returns in error with the EFI_WRITE_PROTECTED error code.
+
+ @param[in] This A pointer to the EFI_FILE_PROTOCOL instance that is
+ the file handle to source location.
+ @param[out] NewHandle A pointer to the location to return the opened
+ handle for the new file.
+ @param[in] FileName The Null-terminated string of the name of the file
+ to be opened.
+ @param[in] OpenMode The mode to open the file : Read or Read/Write or
+ Read/Write/Create
+ @param[in] Attributes Attributes of the file in case of a file creation
+
+ @retval EFI_SUCCESS The file was open.
+ @retval EFI_NOT_FOUND The specified file could not be found or the specified
+ directory in which to create a file could not be found.
+ @retval EFI_DEVICE_ERROR The device reported an error.
+ @retval EFI_WRITE_PROTECTED Attempt to create a directory. This is not possible
+ with the Boot Monitor file system.
+ @retval EFI_OUT_OF_RESOURCES Not enough resources were available to open the file.
+ @retval EFI_INVALID_PARAMETER At least one of the parameters is invalid.
+
+**/
EFIAPI
EFI_STATUS
BootMonFsOpenFile (
@@ -101,7 +153,24 @@ BootMonFsOpenFile (
IN UINT64 Attributes
);
+/**
+ Read data from an open file.
+ @param[in] This A pointer to the EFI_FILE_PROTOCOL instance that
+ is the file handle to read data from.
+ @param[in out] BufferSize 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.
+ @param[out] Buffer The buffer into which the data is read.
+
+ @retval EFI_SUCCESS The data was read.
+ @retval EFI_DEVICE_ERROR On entry, the current file position is
+ beyond the end of the file, or the device
+ reported an error while performing the read
+ operation.
+ @retval EFI_INVALID_PARAMETER At least one of the parameters is invalid.
+
+**/
EFIAPI
EFI_STATUS
BootMonFsReadFile (
@@ -124,6 +193,26 @@ BootMonFsGetPosition (
OUT UINT64 *Position
);
+/**
+ Write data to an open file.
+
+ The data is not written to the flash yet. It will be written when the file
+ will be either read, closed or flushed.
+
+ @param[in] This A pointer to the EFI_FILE_PROTOCOL instance that
+ is the file handle to write data to.
+ @param[in out] BufferSize On input, the size of the Buffer. On output, the
+ size of the data actually written. In both cases,
+ the size is measured in bytes.
+ @param[in] Buffer The buffer of data to write.
+
+ @retval EFI_SUCCESS The data was written.
+ @retval EFI_ACCESS_DENIED The file was opened read only.
+ @retval EFI_OUT_OF_RESOURCES Unable to allocate the buffer to store the
+ data to write.
+ @retval EFI_INVALID_PARAMETER At least one of the parameters is invalid.
+
+**/
EFIAPI
EFI_STATUS
BootMonFsWriteFile (
@@ -138,12 +227,35 @@ BootMonFsDeleteFail (
IN EFI_FILE_PROTOCOL *This
);
+/**
+ Close and delete a file from the boot monitor file system.
+
+ @param[in] This A pointer to the EFI_FILE_PROTOCOL instance that is the file
+ handle to delete.
+
+ @retval EFI_SUCCESS The file was closed and deleted.
+ @retval EFI_INVALID_PARAMETER The parameter "This" is NULL or is not an open
+ file handle.
+ @retval EFI_WARN_DELETE_FAILURE The handle was closed, but the file was not deleted.
+
+**/
EFIAPI
EFI_STATUS
BootMonFsDelete (
IN EFI_FILE_PROTOCOL *This
);
+/**
+ Set a file's current position.
+
+ @param[in] This A pointer to the EFI_FILE_PROTOCOL instance that is
+ the file handle to set the requested position on.
+ @param[in] Position The byte position from the start of the file to set.
+
+ @retval EFI_SUCCESS The position was set.
+ @retval EFI_INVALID_PARAMETER At least one of the parameters is invalid.
+
+**/
EFIAPI
EFI_STATUS
BootMonFsSetPosition (
@@ -151,6 +263,17 @@ BootMonFsSetPosition (
IN UINT64 Position
);
+/**
+ Return a file's current position.
+
+ @param[in] This A pointer to the EFI_FILE_PROTOCOL instance that is
+ the file handle to get the current position on.
+ @param[out] Position The address to return the file's current position value.
+
+ @retval EFI_SUCCESS The position was returned.
+ @retval EFI_INVALID_PARAMETER At least one of the parameters is invalid.
+
+**/
EFIAPI
EFI_STATUS
BootMonFsGetPosition(
@@ -169,6 +292,37 @@ BootMonFsGetPositionUnsupported (
OUT UINT64 *Position
);
+/**
+ Set information about a file or a volume.
+
+ @param[in] This A pointer to the EFI_FILE_PROTOCOL instance that
+ is the file handle the information is for.
+ @param[in] InformationType The type identifier for the information being set :
+ EFI_FILE_INFO_ID or EFI_FILE_SYSTEM_INFO_ID or
+ EFI_FILE_SYSTEM_VOLUME_LABEL_ID
+ @param[in] BufferSize The size, in bytes, of Buffer.
+ @param[in] Buffer A pointer to the data buffer to write. The type of the
+ data inside the buffer is indicated by InformationType.
+
+ @retval EFI_SUCCESS The information was set.
+ @retval EFI_UNSUPPORTED The InformationType is not known.
+ @retval EFI_DEVICE_ERROR The last issued semi-hosting operation failed.
+ @retval EFI_ACCESS_DENIED An attempt is made to change the name of a file
+ to a file that is already present.
+ @retval EFI_ACCESS_DENIED An attempt is being made to change the
+ EFI_FILE_DIRECTORY Attribute.
+ @retval EFI_ACCESS_DENIED InformationType is EFI_FILE_INFO_ID and
+ the file was opened in read-only mode and an
+ attempt is being made to modify a field other
+ than Attribute.
+ @retval EFI_WRITE_PROTECTED An attempt is being made to modify a read-only
+ attribute.
+ @retval EFI_BAD_BUFFER_SIZE The size of the buffer is lower than that indicated by
+ the data inside the buffer.
+ @retval EFI_OUT_OF_RESOURCES A allocation needed to process the request failed.
+ @retval EFI_INVALID_PARAMETER At least one of the parameters is invalid.
+
+**/
EFIAPI
EFI_STATUS
BootMonFsSetInfo (
@@ -192,6 +346,31 @@ BootMonFsOpenDirectory (
//
// Internal API
//
+
+/**
+ Search for a file given its name coded in Ascii.
+
+ When searching through the files of the volume, if a file is currently not
+ open, its name was written on the media and is kept in RAM in the
+ "HwDescription.Footer.Filename[]" field of the file's description.
+
+ If a file is currently open, its name might not have been written on the
+ media yet, and as the "HwDescription" is a mirror in RAM of what is on the
+ media the "HwDescription.Footer.Filename[]" might be outdated. In that case,
+ the up to date name of the file is stored in the "Info" field of the file's
+ description.
+
+ @param[in] Instance Pointer to the description of the volume in which
+ the file has to be search for.
+ @param[in] AsciiFileName Name of the file.
+
+ @param[out] File Pointer to the description of the file if the
+ file was found.
+
+ @retval EFI_SUCCESS The file was found.
+ @retval EFI_NOT_FOUND The file was not found.
+
+**/
EFI_STATUS
BootMonGetFileFromAsciiFileName (
IN BOOTMON_FS_INSTANCE *Instance,
diff --git a/ArmPlatformPkg/FileSystem/BootMonFs/BootMonFsDir.c b/ArmPlatformPkg/FileSystem/BootMonFs/BootMonFsDir.c
index 835cdae18a..450a707f18 100644
--- a/ArmPlatformPkg/FileSystem/BootMonFs/BootMonFsDir.c
+++ b/ArmPlatformPkg/FileSystem/BootMonFs/BootMonFsDir.c
@@ -28,6 +28,8 @@ OpenBootMonFsOpenVolume (
return EFI_DEVICE_ERROR;
}
+ Instance->RootFile->Info->Attribute = EFI_FILE_READ_ONLY | EFI_FILE_DIRECTORY;
+
*Root = &Instance->RootFile->File;
return EFI_SUCCESS;
@@ -114,6 +116,8 @@ BootMonFsOpenDirectory (
return EFI_UNSUPPORTED;
}
+
+STATIC
EFI_STATUS
GetFileSystemVolumeLabelInfo (
IN BOOTMON_FS_INSTANCE *Instance,
@@ -178,6 +182,7 @@ ComputeFreeSpace (
return MediaSize - (FileSizeSum + (Media->BlockSize + NumFiles));
}
+STATIC
EFI_STATUS
GetFilesystemInfo (
IN BOOTMON_FS_INSTANCE *Instance,
@@ -199,26 +204,19 @@ GetFilesystemInfo (
return Status;
}
+STATIC
EFI_STATUS
GetFileInfo (
- IN BOOTMON_FS_INSTANCE *Instance,
- IN BOOTMON_FS_FILE *File,
- IN OUT UINTN *BufferSize,
- OUT VOID *Buffer
+ IN BOOTMON_FS_INSTANCE *Instance,
+ IN BOOTMON_FS_FILE *File,
+ IN OUT UINTN *BufferSize,
+ OUT VOID *Buffer
)
{
- EFI_FILE_INFO *Info;
- UINTN ResultSize;
- UINTN NameSize;
- UINTN Index;
+ EFI_FILE_INFO *Info;
+ UINTN ResultSize;
- if (File == Instance->RootFile) {
- NameSize = 0;
- ResultSize = SIZE_OF_EFI_FILE_INFO + sizeof (CHAR16);
- } else {
- NameSize = AsciiStrLen (File->HwDescription.Footer.Filename) + 1;
- ResultSize = SIZE_OF_EFI_FILE_INFO + (NameSize * sizeof (CHAR16));
- }
+ ResultSize = SIZE_OF_EFI_FILE_INFO + StrSize (File->Info->FileName);
if (*BufferSize < ResultSize) {
*BufferSize = ResultSize;
@@ -227,24 +225,10 @@ GetFileInfo (
Info = Buffer;
- // Zero out the structure
- ZeroMem (Info, ResultSize);
-
- // Fill in the structure
+ CopyMem (Info, File->Info, ResultSize);
+ // Size of the information
Info->Size = ResultSize;
- if (File == Instance->RootFile) {
- Info->Attribute = EFI_FILE_READ_ONLY | EFI_FILE_DIRECTORY;
- Info->FileName[0] = L'\0';
- } else {
- Info->FileSize = BootMonFsGetImageLength (File);
- Info->PhysicalSize = BootMonFsGetPhysicalSize (File);
-
- for (Index = 0; Index < NameSize; Index++) {
- Info->FileName[Index] = File->HwDescription.Footer.Filename[Index];
- }
- }
-
*BufferSize = ResultSize;
return EFI_SUCCESS;
@@ -297,171 +281,253 @@ GetBootMonFsFileInfo (
return Status;
}
+/**
+ Set the name of a file.
+
+ This is a helper function for SetFileInfo().
+
+ @param[in] Instance A pointer to the description of the volume
+ the file belongs to.
+ @param[in] File A pointer to the description of the file.
+ @param[in] FileName A pointer to the new name of the file.
+
+ @retval EFI_SUCCESS The name was set.
+ @retval EFI_ACCESS_DENIED An attempt is made to change the name of a file
+ to a file that is already present.
+
+**/
STATIC
EFI_STATUS
SetFileName (
- IN BOOTMON_FS_FILE *File,
- IN CHAR16 *FileNameUnicode
+ IN BOOTMON_FS_INSTANCE *Instance,
+ IN BOOTMON_FS_FILE *File,
+ IN CONST CHAR16 *FileName
)
{
- CHAR8 *FileNameAscii;
- UINT16 SavedChar;
- UINTN FileNameSize;
- BOOTMON_FS_FILE *SameFile;
- EFI_STATUS Status;
+ CHAR16 TruncFileName[MAX_NAME_LENGTH];
+ CHAR8 AsciiFileName[MAX_NAME_LENGTH];
+ BOOTMON_FS_FILE *SameFile;
- // EFI Shell inserts '\' in front of the filename that must be stripped
- if (FileNameUnicode[0] == L'\\') {
- FileNameUnicode++;
+ // If the file path start with a \ strip it. The EFI Shell may
+ // insert a \ in front of the file name.
+ if (FileName[0] == L'\\') {
+ FileName++;
}
- //
- // Convert Unicode into Ascii
- //
- SavedChar = L'\0';
- FileNameSize = StrLen (FileNameUnicode) + 1;
- FileNameAscii = AllocatePool (FileNameSize * sizeof (CHAR8));
- if (FileNameAscii == NULL) {
- return EFI_OUT_OF_RESOURCES;
- }
- // If Unicode string is too long then truncate it.
- if (FileNameSize > MAX_NAME_LENGTH) {
- SavedChar = FileNameUnicode[MAX_NAME_LENGTH - 1];
- FileNameUnicode[MAX_NAME_LENGTH - 1] = L'\0';
- }
- UnicodeStrToAsciiStr (FileNameUnicode, FileNameAscii);
- // If the unicode string was truncated then restore its original content.
- if (SavedChar != L'\0') {
- FileNameUnicode[MAX_NAME_LENGTH - 1] = SavedChar;
- }
-
- // If we're changing the file name
- if (AsciiStrCmp (FileNameAscii, File->HwDescription.Footer.Filename) == 0) {
- // No change to filename.
- Status = EFI_SUCCESS;
- } else if (!(File->OpenMode & EFI_FILE_MODE_WRITE)) {
- // You can only change the filename if you open the file for write.
- Status = EFI_ACCESS_DENIED;
- } else if (BootMonGetFileFromAsciiFileName (
- File->Instance,
- File->HwDescription.Footer.Filename,
- &SameFile) != EFI_NOT_FOUND) {
+
+ StrnCpy (TruncFileName, FileName, MAX_NAME_LENGTH - 1);
+ TruncFileName[MAX_NAME_LENGTH - 1] = 0;
+ UnicodeStrToAsciiStr (TruncFileName, AsciiFileName);
+
+ if (BootMonGetFileFromAsciiFileName (
+ File->Instance,
+ AsciiFileName,
+ &SameFile
+ ) != EFI_NOT_FOUND) {
// A file with that name already exists.
- Status = EFI_ACCESS_DENIED;
+ return EFI_ACCESS_DENIED;
} else {
// OK, change the filename.
- AsciiStrCpy (FileNameAscii, File->HwDescription.Footer.Filename);
- Status = EFI_SUCCESS;
+ AsciiStrToUnicodeStr (AsciiFileName, File->Info->FileName);
+ return EFI_SUCCESS;
}
-
- FreePool (FileNameAscii);
- return Status;
}
-// Set the file's size (NB "size", not "physical size"). If the change amounts
-// to an increase, simply do a write followed by a flush.
-// (This is a helper function for SetFileInfo.)
+/**
+ Set the size of a file.
+
+ This is a helper function for SetFileInfo().
+
+ @param[in] Instance A pointer to the description of the volume
+ the file belongs to.
+ @param[in] File A pointer to the description of the file.
+ @param[in] NewSize The requested new size for the file.
+
+ @retval EFI_SUCCESS The size was set.
+ @retval EFI_OUT_OF_RESOURCES An allocation needed to process the request failed.
+
+**/
STATIC
EFI_STATUS
SetFileSize (
- IN BOOTMON_FS_INSTANCE *Instance,
- IN BOOTMON_FS_FILE *BootMonFsFile,
- IN UINTN NewSize
+ IN BOOTMON_FS_INSTANCE *Instance,
+ IN BOOTMON_FS_FILE *BootMonFsFile,
+ IN UINTN NewSize
)
{
- UINT64 StoredPosition;
- EFI_STATUS Status;
- EFI_FILE_PROTOCOL *File;
- CHAR8 Buffer;
- UINTN BufferSize;
- UINT32 OldSize;
-
- OldSize = BootMonFsFile->HwDescription.Region[0].Size;
-
- if (OldSize == NewSize) {
- return EFI_SUCCESS;
- }
-
- Buffer = 0;
- BufferSize = sizeof (Buffer);
+ EFI_STATUS Status;
+ UINT32 OldSize;
+ LIST_ENTRY *RegionToFlushLink;
+ LIST_ENTRY *NextRegionToFlushLink;
+ BOOTMON_FS_FILE_REGION *Region;
+ EFI_FILE_PROTOCOL *File;
+ CHAR8 *Buffer;
+ UINTN BufferSize;
+ UINT64 StoredPosition;
- File = &BootMonFsFile->File;
+ OldSize = BootMonFsFile->Info->FileSize;
- if (!(BootMonFsFile->OpenMode & EFI_FILE_MODE_WRITE)) {
- return EFI_ACCESS_DENIED;
- }
+ //
+ // In case of file truncation, force the regions waiting for writing to
+ // not overflow the new size of the file.
+ //
+ if (NewSize < OldSize) {
+ for (RegionToFlushLink = GetFirstNode (&BootMonFsFile->RegionToFlushLink);
+ !IsNull (&BootMonFsFile->RegionToFlushLink, RegionToFlushLink);
+ )
+ {
+ NextRegionToFlushLink = GetNextNode (&BootMonFsFile->RegionToFlushLink, RegionToFlushLink);
+ Region = (BOOTMON_FS_FILE_REGION*)RegionToFlushLink;
+ if (Region->Offset > NewSize) {
+ RemoveEntryList (RegionToFlushLink);
+ FreePool (Region->Buffer);
+ FreePool (Region);
+ } else {
+ Region->Size = MIN (Region->Size, NewSize - Region->Offset);
+ }
+ RegionToFlushLink = NextRegionToFlushLink;
+ }
- if (NewSize <= OldSize) {
- OldSize = NewSize;
- } else {
+ } else if (NewSize > OldSize) {
// Increasing a file's size is potentially complicated as it may require
// moving the image description on media. The simplest way to do it is to
// seek past the end of the file (which is valid in UEFI) and perform a
// Write.
+ File = &BootMonFsFile->File;
// Save position
Status = File->GetPosition (File, &StoredPosition);
if (EFI_ERROR (Status)) {
return Status;
}
-
- Status = File->SetPosition (File, NewSize - 1);
+ // Set position at the end of the file
+ Status = File->SetPosition (File, OldSize);
if (EFI_ERROR (Status)) {
return Status;
}
- Status = File->Write (File, &BufferSize, &Buffer);
- if (EFI_ERROR (Status)) {
- return Status;
+
+ BufferSize = NewSize - OldSize;
+ Buffer = AllocateZeroPool (BufferSize);
+ if (Buffer == NULL) {
+ return EFI_OUT_OF_RESOURCES;
}
- // Restore saved position
- Status = File->SetPosition (File, NewSize - 1);
+ Status = File->Write (File, &BufferSize, Buffer);
+ FreePool (Buffer);
if (EFI_ERROR (Status)) {
return Status;
}
- Status = File->Flush (File);
+ // Restore saved position
+ Status = File->SetPosition (File, StoredPosition);
if (EFI_ERROR (Status)) {
return Status;
}
}
+
+ BootMonFsFile->Info->FileSize = NewSize;
+
return EFI_SUCCESS;
}
+/**
+ Set information about a file.
+
+ @param[in] Instance A pointer to the description of the volume
+ the file belongs to.
+ @param[in] File A pointer to the description of the file.
+ @param[in] Info A pointer to the file information to write.
+
+ @retval EFI_SUCCESS The information was set.
+ @retval EFI_ACCESS_DENIED An attempt is being made to change the
+ EFI_FILE_DIRECTORY Attribute.
+ @retval EFI_ACCESS_DENIED The file was opened in read-only mode and an
+ attempt is being made to modify a field other
+ than Attribute.
+ @retval EFI_ACCESS_DENIED An attempt is made to change the name of a file
+ to a file that is already present.
+ @retval EFI_WRITE_PROTECTED An attempt is being made to modify a read-only
+ attribute.
+ @retval EFI_OUT_OF_RESOURCES An allocation needed to process the request
+ failed.
+
+**/
+STATIC
EFI_STATUS
SetFileInfo (
- IN BOOTMON_FS_INSTANCE *Instance,
- IN BOOTMON_FS_FILE *File,
- IN UINTN BufferSize,
- IN EFI_FILE_INFO *Info
+ IN BOOTMON_FS_INSTANCE *Instance,
+ IN BOOTMON_FS_FILE *File,
+ IN EFI_FILE_INFO *Info
)
{
- EFI_STATUS Status;
+ EFI_STATUS Status;
+ BOOLEAN FileSizeIsDifferent;
+ BOOLEAN FileNameIsDifferent;
+ BOOLEAN TimeIsDifferent;
- Status = EFI_SUCCESS;
+ //
+ // A directory can not be changed to a file and a file can
+ // not be changed to a directory.
+ //
+ if ((Info->Attribute & EFI_FILE_DIRECTORY) !=
+ (File->Info->Attribute & EFI_FILE_DIRECTORY) ) {
+ return EFI_ACCESS_DENIED;
+ }
- // Note that a call to this function on a file opened read-only is only
- // invalid if it actually changes fields, so we don't immediately fail if the
- // OpenMode is wrong.
- // Also note that the only fields supported are filename and size, others are
- // ignored.
+ FileSizeIsDifferent = (Info->FileSize != File->Info->FileSize);
+ FileNameIsDifferent = (StrnCmp (
+ Info->FileName,
+ File->Info->FileName,
+ MAX_NAME_LENGTH - 1
+ ) != 0);
+ //
+ // Check if the CreateTime, LastAccess or ModificationTime
+ // have been changed. The file system does not support file
+ // timestamps thus the three times in "File->Info" are
+ // always equal to zero. The following comparison actually
+ // checks if all three times are still equal to 0 or not.
+ //
+ TimeIsDifferent = CompareMem (
+ &Info->CreateTime,
+ &File->Info->CreateTime,
+ 3 * sizeof (EFI_TIME)
+ ) != 0;
- if (File != Instance->RootFile) {
- if (!(File->OpenMode & EFI_FILE_MODE_WRITE)) {
+ //
+ // For a file opened in read-only mode, only the Attribute field can be
+ // modified. The root directory open mode is forced to read-only at opening
+ // thus the following test protects the root directory to be somehow modified.
+ //
+ if (File->OpenMode == EFI_FILE_MODE_READ) {
+ if (FileSizeIsDifferent || FileNameIsDifferent || TimeIsDifferent) {
return EFI_ACCESS_DENIED;
}
+ }
+
+ if (TimeIsDifferent) {
+ return EFI_WRITE_PROTECTED;
+ }
- Status = SetFileName (File, Info->FileName);
+ if (FileSizeIsDifferent) {
+ Status = SetFileSize (Instance, File, Info->FileSize);
if (EFI_ERROR (Status)) {
return Status;
}
+ }
- // Update file size
- Status = SetFileSize (Instance, File, Info->FileSize);
+ //
+ // Note down in RAM the Attribute field but we can not
+ // ask to store it in flash for the time being.
+ //
+ File->Info->Attribute = Info->Attribute;
+
+ if (FileNameIsDifferent) {
+ Status = SetFileName (Instance, File, Info->FileName);
if (EFI_ERROR (Status)) {
return Status;
}
}
- return Status;
+
+ return EFI_SUCCESS;
}
EFIAPI
@@ -477,11 +543,17 @@ BootMonFsGetInfo (
BOOTMON_FS_FILE *File;
BOOTMON_FS_INSTANCE *Instance;
- File = BOOTMON_FS_FILE_FROM_FILE_THIS (This);
- if (File == NULL) {
- return EFI_DEVICE_ERROR;
+ if ((This == NULL) ||
+ (InformationType == NULL) ||
+ (BufferSize == NULL) ||
+ ((Buffer == NULL) && (*BufferSize > 0)) ) {
+ return EFI_INVALID_PARAMETER;
}
+ File = BOOTMON_FS_FILE_FROM_FILE_THIS (This);
+ if (File->Info == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
Instance = File->Instance;
// If the instance has not been initialized yet then do it ...
@@ -509,6 +581,37 @@ BootMonFsGetInfo (
return Status;
}
+/**
+ Set information about a file or a volume.
+
+ @param[in] This A pointer to the EFI_FILE_PROTOCOL instance that
+ is the file handle the information is for.
+ @param[in] InformationType The type identifier for the information being set :
+ EFI_FILE_INFO_ID or EFI_FILE_SYSTEM_INFO_ID or
+ EFI_FILE_SYSTEM_VOLUME_LABEL_ID
+ @param[in] BufferSize The size, in bytes, of Buffer.
+ @param[in] Buffer A pointer to the data buffer to write. The type of the
+ data inside the buffer is indicated by InformationType.
+
+ @retval EFI_SUCCESS The information was set.
+ @retval EFI_UNSUPPORTED The InformationType is not known.
+ @retval EFI_DEVICE_ERROR The last issued semi-hosting operation failed.
+ @retval EFI_ACCESS_DENIED An attempt is made to change the name of a file
+ to a file that is already present.
+ @retval EFI_ACCESS_DENIED An attempt is being made to change the
+ EFI_FILE_DIRECTORY Attribute.
+ @retval EFI_ACCESS_DENIED InformationType is EFI_FILE_INFO_ID and
+ the file was opened in read-only mode and an
+ attempt is being made to modify a field other
+ than Attribute.
+ @retval EFI_WRITE_PROTECTED An attempt is being made to modify a read-only
+ attribute.
+ @retval EFI_BAD_BUFFER_SIZE The size of the buffer is lower than that indicated by
+ the data inside the buffer.
+ @retval EFI_OUT_OF_RESOURCES A allocation needed to process the request failed.
+ @retval EFI_INVALID_PARAMETER At least one of the parameters is invalid.
+
+**/
EFIAPI
EFI_STATUS
BootMonFsSetInfo (
@@ -518,28 +621,56 @@ BootMonFsSetInfo (
IN VOID *Buffer
)
{
- EFI_STATUS Status;
- BOOTMON_FS_FILE *File;
- BOOTMON_FS_INSTANCE *Instance;
+ BOOTMON_FS_FILE *File;
+ EFI_FILE_INFO *Info;
+ EFI_FILE_SYSTEM_INFO *SystemInfo;
+
+ if ((This == NULL) ||
+ (InformationType == NULL) ||
+ (Buffer == NULL) ) {
+ return EFI_INVALID_PARAMETER;
+ }
File = BOOTMON_FS_FILE_FROM_FILE_THIS (This);
- if (File == NULL) {
- return EFI_DEVICE_ERROR;
+ if (File->Info == NULL) {
+ return EFI_INVALID_PARAMETER;
}
- Instance = File->Instance;
+ if (CompareGuid (InformationType, &gEfiFileInfoGuid)) {
+ Info = Buffer;
+ if (Info->Size < (SIZE_OF_EFI_FILE_INFO + StrSize (Info->FileName))) {
+ return EFI_INVALID_PARAMETER;
+ }
+ if (BufferSize < Info->Size) {
+ return EFI_BAD_BUFFER_SIZE;
+ }
+ return (SetFileInfo (File->Instance, File, Info));
+ }
- if (CompareGuid (InformationType, &gEfiFileInfoGuid) != 0) {
- Status = SetFileInfo (Instance, File, BufferSize, (EFI_FILE_INFO *) Buffer);
- } else {
- // The only writable field in the other two information types
- // (i.e. EFI_FILE_SYSTEM_INFO and EFI_FILE_SYSTEM_VOLUME_LABEL) is the
- // filesystem volume label. This can be retrieved with GetInfo, but it is
- // hard-coded into this driver, not stored on media.
- Status = EFI_UNSUPPORTED;
+ //
+ // The only writable field in the other two information types
+ // (i.e. EFI_FILE_SYSTEM_INFO and EFI_FILE_SYSTEM_VOLUME_LABEL) is the
+ // filesystem volume label. This can be retrieved with GetInfo, but it is
+ // hard-coded into this driver, not stored on media.
+ //
+
+ if (CompareGuid (InformationType, &gEfiFileSystemInfoGuid)) {
+ SystemInfo = Buffer;
+ if (SystemInfo->Size <
+ (SIZE_OF_EFI_FILE_SYSTEM_INFO + StrSize (SystemInfo->VolumeLabel))) {
+ return EFI_INVALID_PARAMETER;
+ }
+ if (BufferSize < SystemInfo->Size) {
+ return EFI_BAD_BUFFER_SIZE;
+ }
+ return EFI_WRITE_PROTECTED;
}
- return Status;
+ if (CompareGuid (InformationType, &gEfiFileSystemVolumeLabelInfoIdGuid)) {
+ return EFI_WRITE_PROTECTED;
+ }
+
+ return EFI_UNSUPPORTED;
}
EFIAPI
diff --git a/ArmPlatformPkg/FileSystem/BootMonFs/BootMonFsEntryPoint.c b/ArmPlatformPkg/FileSystem/BootMonFs/BootMonFsEntryPoint.c
index 5eb7afca7c..3d71760fef 100644
--- a/ArmPlatformPkg/FileSystem/BootMonFs/BootMonFsEntryPoint.c
+++ b/ArmPlatformPkg/FileSystem/BootMonFs/BootMonFsEntryPoint.c
@@ -54,6 +54,30 @@ EFI_FILE_PROTOCOL mBootMonFsFileTemplate = {
BootMonFsFlushFile
};
+/**
+ Search for a file given its name coded in Ascii.
+
+ When searching through the files of the volume, if a file is currently not
+ open, its name was written on the media and is kept in RAM in the
+ "HwDescription.Footer.Filename[]" field of the file's description.
+
+ If a file is currently open, its name might not have been written on the
+ media yet, and as the "HwDescription" is a mirror in RAM of what is on the
+ media the "HwDescription.Footer.Filename[]" might be outdated. In that case,
+ the up to date name of the file is stored in the "Info" field of the file's
+ description.
+
+ @param[in] Instance Pointer to the description of the volume in which
+ the file has to be search for.
+ @param[in] AsciiFileName Name of the file.
+
+ @param[out] File Pointer to the description of the file if the
+ file was found.
+
+ @retval EFI_SUCCESS The file was found.
+ @retval EFI_NOT_FOUND The file was not found.
+
+**/
EFI_STATUS
BootMonGetFileFromAsciiFileName (
IN BOOTMON_FS_INSTANCE *Instance,
@@ -61,22 +85,26 @@ BootMonGetFileFromAsciiFileName (
OUT BOOTMON_FS_FILE **File
)
{
- LIST_ENTRY *Entry;
- BOOTMON_FS_FILE *FileEntry;
-
- // Remove the leading '\\'
- if (*AsciiFileName == '\\') {
- AsciiFileName++;
- }
+ LIST_ENTRY *Entry;
+ BOOTMON_FS_FILE *FileEntry;
+ CHAR8 OpenFileAsciiFileName[MAX_NAME_LENGTH];
+ CHAR8 *AsciiFileNameToCompare;
// Go through all the files in the list and return the file handle
for (Entry = GetFirstNode (&Instance->RootFile->Link);
- !IsNull (&Instance->RootFile->Link, Entry);
- Entry = GetNextNode (&Instance->RootFile->Link, Entry)
- )
+ !IsNull (&Instance->RootFile->Link, Entry);
+ Entry = GetNextNode (&Instance->RootFile->Link, Entry)
+ )
{
FileEntry = BOOTMON_FS_FILE_FROM_LINK_THIS (Entry);
- if (AsciiStrCmp (FileEntry->HwDescription.Footer.Filename, AsciiFileName) == 0) {
+ if (FileEntry->Info != NULL) {
+ UnicodeStrToAsciiStr (FileEntry->Info->FileName, OpenFileAsciiFileName);
+ AsciiFileNameToCompare = OpenFileAsciiFileName;
+ } else {
+ AsciiFileNameToCompare = FileEntry->HwDescription.Footer.Filename;
+ }
+
+ if (AsciiStrCmp (AsciiFileNameToCompare, AsciiFileName) == 0) {
*File = FileEntry;
return EFI_SUCCESS;
}
@@ -291,6 +319,7 @@ BootMonFsDriverStart (
BOOTMON_FS_INSTANCE *Instance;
EFI_STATUS Status;
UINTN VolumeNameSize;
+ EFI_FILE_INFO *Info;
Instance = AllocateZeroPool (sizeof (BOOTMON_FS_INSTANCE));
if (Instance == NULL) {
@@ -307,8 +336,7 @@ BootMonFsDriverStart (
EFI_OPEN_PROTOCOL_GET_PROTOCOL
);
if (EFI_ERROR (Status)) {
- FreePool (Instance);
- return Status;
+ goto Error;
}
Status = gBS->OpenProtocol (
@@ -320,8 +348,7 @@ BootMonFsDriverStart (
EFI_OPEN_PROTOCOL_BY_DRIVER
);
if (EFI_ERROR (Status)) {
- FreePool (Instance);
- return Status;
+ goto Error;
}
//
@@ -350,10 +377,16 @@ BootMonFsDriverStart (
// Initialize the root file
Status = BootMonFsCreateFile (Instance, &Instance->RootFile);
if (EFI_ERROR (Status)) {
- FreePool (Instance);
- return Status;
+ goto Error;
}
+ Info = AllocateZeroPool (sizeof (EFI_FILE_INFO));
+ if (Info == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto Error;
+ }
+ Instance->RootFile->Info = Info;
+
// Initialize the DevicePath of the Instance
Status = gBS->OpenProtocol (
ControllerHandle,
@@ -364,8 +397,7 @@ BootMonFsDriverStart (
EFI_OPEN_PROTOCOL_GET_PROTOCOL
);
if (EFI_ERROR (Status)) {
- FreePool (Instance);
- return Status;
+ goto Error;
}
//
@@ -376,9 +408,24 @@ BootMonFsDriverStart (
&gEfiSimpleFileSystemProtocolGuid, &Instance->Fs,
NULL
);
+ if (EFI_ERROR (Status)) {
+ goto Error;
+ }
InsertTailList (&mInstances, &Instance->Link);
+ return EFI_SUCCESS;
+
+Error:
+
+ if (Instance->RootFile != NULL) {
+ if (Instance->RootFile->Info != NULL) {
+ FreePool (Instance->RootFile->Info);
+ }
+ FreePool (Instance->RootFile);
+ }
+ FreePool (Instance);
+
return Status;
}
@@ -434,6 +481,10 @@ BootMonFsDriverStop (
&gEfiSimpleFileSystemProtocolGuid, &Instance->Fs,
NULL);
+ FreePool (Instance->RootFile->Info);
+ FreePool (Instance->RootFile);
+ FreePool (Instance);
+
return Status;
}
diff --git a/ArmPlatformPkg/FileSystem/BootMonFs/BootMonFsInternal.h b/ArmPlatformPkg/FileSystem/BootMonFs/BootMonFsInternal.h
index 57343618ab..c0c6599cb7 100644
--- a/ArmPlatformPkg/FileSystem/BootMonFs/BootMonFsInternal.h
+++ b/ArmPlatformPkg/FileSystem/BootMonFs/BootMonFsInternal.h
@@ -54,8 +54,14 @@ typedef struct {
EFI_FILE_PROTOCOL File;
+ //
+ // The following fields are relevant only if the file is open.
+ //
+
+ EFI_FILE_INFO *Info;
UINT64 Position;
- // If the file needs to be flushed then this list contain the memory buffer that creates this file
+ // If the file needs to be flushed then this list contain the memory
+ // buffer that creates this file
LIST_ENTRY RegionToFlushLink;
UINT64 OpenMode;
} BOOTMON_FS_FILE;
diff --git a/ArmPlatformPkg/FileSystem/BootMonFs/BootMonFsOpenClose.c b/ArmPlatformPkg/FileSystem/BootMonFs/BootMonFsOpenClose.c
index 6616b4f694..dc83b3882b 100644
--- a/ArmPlatformPkg/FileSystem/BootMonFs/BootMonFsOpenClose.c
+++ b/ArmPlatformPkg/FileSystem/BootMonFs/BootMonFsOpenClose.c
@@ -12,6 +12,7 @@
*
**/
+#include <Library/PathLib.h>
#include "BootMonFsInternal.h"
// Clear a file's image description on storage media:
@@ -38,6 +39,10 @@ InvalidateImageDescription (
Buffer = AllocateZeroPool (sizeof (HW_IMAGE_DESCRIPTION));
+ if (Buffer == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
Status = DiskIo->WriteDisk (DiskIo,
MediaId,
File->HwDescAddress,
@@ -50,83 +55,75 @@ InvalidateImageDescription (
return Status;
}
-// Flush file data that will extend the file's length. Update and, if necessary,
-// move the image description.
-// We need to pass the file's starting position on media (FileStart), because
-// if the file hasn't been flushed before its Description->BlockStart won't
-// have been initialised.
-// FileStart must be aligned to the media's block size.
-// Note that this function uses DiskIo to flush, so call BlockIo->FlushBlocks()
-// after calling it.
+/**
+ Write the description of a file to storage media.
+
+ This function uses DiskIo to write to the media, so call BlockIo->FlushBlocks()
+ after calling it to ensure the data are written on the media.
+
+ @param[in] File Description of the file whose description on the
+ storage media has to be updated.
+ @param[in] FileName Name of the file. Its length is assumed to be
+ lower than MAX_NAME_LENGTH.
+ @param[in] DataSize Number of data bytes of the file.
+ @param[in] FileStart File's starting position on media. FileStart must
+ be aligned to the media's block size.
+
+ @retval EFI_WRITE_PROTECTED The device cannot be written to.
+ @retval EFI_DEVICE_ERROR The device reported an error while performing
+ the write operation.
+
+**/
STATIC
EFI_STATUS
-FlushAppendRegion (
- IN BOOTMON_FS_FILE *File,
- IN BOOTMON_FS_FILE_REGION *Region,
- IN UINT64 NewFileSize,
- IN UINT64 FileStart
+WriteFileDescription (
+ IN BOOTMON_FS_FILE *File,
+ IN CHAR8 *FileName,
+ IN UINT32 DataSize,
+ IN UINT64 FileStart
)
{
- EFI_STATUS Status;
- EFI_DISK_IO_PROTOCOL *DiskIo;
- UINTN BlockSize;
- HW_IMAGE_DESCRIPTION *Description;
-
- DiskIo = File->Instance->DiskIo;
+ EFI_STATUS Status;
+ EFI_DISK_IO_PROTOCOL *DiskIo;
+ UINTN BlockSize;
+ UINT32 FileSize;
+ HW_IMAGE_DESCRIPTION *Description;
+ DiskIo = File->Instance->DiskIo;
BlockSize = File->Instance->BlockIo->Media->BlockSize;
-
ASSERT (FileStart % BlockSize == 0);
- // Only invalidate the Image Description of files that have already been
- // written in Flash
- if (File->HwDescAddress != 0) {
- Status = InvalidateImageDescription (File);
- ASSERT_EFI_ERROR (Status);
- }
-
//
- // Update File Description
+ // Construct the file description
//
+
+ FileSize = DataSize + sizeof (HW_IMAGE_DESCRIPTION);
Description = &File->HwDescription;
Description->Attributes = 1;
Description->BlockStart = FileStart / BlockSize;
- Description->BlockEnd = Description->BlockStart + (NewFileSize / BlockSize);
- Description->Footer.FooterSignature1 = HW_IMAGE_FOOTER_SIGNATURE_1;
- Description->Footer.FooterSignature2 = HW_IMAGE_FOOTER_SIGNATURE_2;
+ Description->BlockEnd = Description->BlockStart + (FileSize / BlockSize);
+ AsciiStrCpy (Description->Footer.Filename, FileName);
+
#ifdef MDE_CPU_ARM
+ Description->Footer.Offset = HW_IMAGE_FOOTER_OFFSET;
Description->Footer.Version = HW_IMAGE_FOOTER_VERSION;
- Description->Footer.Offset = HW_IMAGE_FOOTER_OFFSET;
#else
+ Description->Footer.Offset = HW_IMAGE_FOOTER_OFFSET2;
Description->Footer.Version = HW_IMAGE_FOOTER_VERSION2;
- Description->Footer.Offset = HW_IMAGE_FOOTER_OFFSET2;
#endif
+ Description->Footer.FooterSignature1 = HW_IMAGE_FOOTER_SIGNATURE_1;
+ Description->Footer.FooterSignature2 = HW_IMAGE_FOOTER_SIGNATURE_2;
Description->RegionCount = 1;
Description->Region[0].Checksum = 0;
Description->Region[0].Offset = Description->BlockStart * BlockSize;
- Description->Region[0].Size = NewFileSize - sizeof (HW_IMAGE_DESCRIPTION);
+ Description->Region[0].Size = DataSize;
Status = BootMonFsComputeFooterChecksum (Description);
if (EFI_ERROR (Status)) {
return Status;
}
- // Write the new file data
- Status = DiskIo->WriteDisk (
- DiskIo,
- File->Instance->Media->MediaId,
- FileStart + Region->Offset,
- Region->Size,
- Region->Buffer
- );
- ASSERT_EFI_ERROR (Status);
-
- // Round the file size up to the nearest block size
- if ((NewFileSize % BlockSize) > 0) {
- NewFileSize += BlockSize - (NewFileSize % BlockSize);
- }
-
- File->HwDescAddress = (FileStart + NewFileSize) - sizeof (HW_IMAGE_DESCRIPTION);
+ File->HwDescAddress = ((Description->BlockEnd + 1) * BlockSize) - sizeof (HW_IMAGE_DESCRIPTION);
// Update the file description on the media
Status = DiskIo->WriteDisk (
@@ -141,14 +138,6 @@ FlushAppendRegion (
return Status;
}
-BOOLEAN
-BootMonFsFileNeedFlush (
- IN BOOTMON_FS_FILE *File
- )
-{
- return !IsListEmpty (&File->RegionToFlushLink);
-}
-
// Find a space on media for a file that has not yet been flushed to disk.
// Just returns the first space that's big enough.
// This function could easily be adapted to:
@@ -166,6 +155,7 @@ STATIC
EFI_STATUS
BootMonFsFindSpaceForNewFile (
IN BOOTMON_FS_FILE *File,
+ IN UINT64 FileSize,
OUT UINT64 *FileStart
)
{
@@ -173,26 +163,16 @@ BootMonFsFindSpaceForNewFile (
BOOTMON_FS_FILE *RootFile;
BOOTMON_FS_FILE *FileEntry;
UINTN BlockSize;
- UINT64 FileSize;
EFI_BLOCK_IO_MEDIA *Media;
Media = File->Instance->BlockIo->Media;
BlockSize = Media->BlockSize;
RootFile = File->Instance->RootFile;
- if (IsListEmpty (&RootFile->Link)) {
- return EFI_SUCCESS;
- }
-
// This function must only be called for file which has not been flushed into
// Flash yet
ASSERT (File->HwDescription.RegionCount == 0);
- // Find out how big the file will be
- FileSize = BootMonFsGetImageLength (File);
- // Add the file header to the file
- FileSize += sizeof (HW_IMAGE_DESCRIPTION);
-
*FileStart = 0;
// Go through all the files in the list
for (FileLink = GetFirstNode (&RootFile->Link);
@@ -252,6 +232,20 @@ FreeFileRegions (
}
}
+/**
+ Flush all modified data associated with a file to a device.
+
+ @param[in] This A pointer to the EFI_FILE_PROTOCOL instance that is the
+ file handle to flush.
+
+ @retval EFI_SUCCESS The data was flushed.
+ @retval EFI_ACCESS_DENIED The file was opened read-only.
+ @retval EFI_DEVICE_ERROR The device reported an error.
+ @retval EFI_VOLUME_FULL The volume is full.
+ @retval EFI_OUT_OF_RESOURCES Not enough resources were available to flush the data.
+ @retval EFI_INVALID_PARAMETER At least one of the parameters is invalid.
+
+**/
EFIAPI
EFI_STATUS
BootMonFsFlushFile (
@@ -260,52 +254,62 @@ BootMonFsFlushFile (
{
EFI_STATUS Status;
BOOTMON_FS_INSTANCE *Instance;
+ EFI_FILE_INFO *Info;
+ EFI_BLOCK_IO_PROTOCOL *BlockIo;
+ EFI_BLOCK_IO_MEDIA *Media;
+ EFI_DISK_IO_PROTOCOL *DiskIo;
+ UINTN BlockSize;
+ CHAR8 AsciiFileName[MAX_NAME_LENGTH];
LIST_ENTRY *RegionToFlushLink;
BOOTMON_FS_FILE *File;
BOOTMON_FS_FILE *NextFile;
BOOTMON_FS_FILE_REGION *Region;
LIST_ENTRY *FileLink;
UINTN CurrentPhysicalSize;
- UINTN BlockSize;
UINT64 FileStart;
UINT64 FileEnd;
UINT64 RegionStart;
UINT64 RegionEnd;
+ UINT64 NewDataSize;
UINT64 NewFileSize;
UINT64 EndOfAppendSpace;
BOOLEAN HasSpace;
- EFI_DISK_IO_PROTOCOL *DiskIo;
- EFI_BLOCK_IO_PROTOCOL *BlockIo;
- Status = EFI_SUCCESS;
- FileStart = 0;
+ if (This == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
File = BOOTMON_FS_FILE_FROM_FILE_THIS (This);
- if (File == NULL) {
+ if (File->Info == NULL) {
return EFI_INVALID_PARAMETER;
}
- // Check if the file needs to be flushed
- if (!BootMonFsFileNeedFlush (File)) {
- return Status;
+ if (File->OpenMode == EFI_FILE_MODE_READ) {
+ return EFI_ACCESS_DENIED;
}
- Instance = File->Instance;
- BlockIo = Instance->BlockIo;
- DiskIo = Instance->DiskIo;
- BlockSize = BlockIo->Media->BlockSize;
+ Instance = File->Instance;
+ Info = File->Info;
+ BlockIo = Instance->BlockIo;
+ Media = BlockIo->Media;
+ DiskIo = Instance->DiskIo;
+ BlockSize = Media->BlockSize;
+
+ UnicodeStrToAsciiStr (Info->FileName, AsciiFileName);
// If the file doesn't exist then find a space for it
if (File->HwDescription.RegionCount == 0) {
- Status = BootMonFsFindSpaceForNewFile (File, &FileStart);
- // FileStart has changed so we need to recompute RegionEnd
+ Status = BootMonFsFindSpaceForNewFile (
+ File,
+ Info->FileSize + sizeof (HW_IMAGE_DESCRIPTION),
+ &FileStart
+ );
if (EFI_ERROR (Status)) {
return Status;
}
} else {
FileStart = File->HwDescription.BlockStart * BlockSize;
}
-
// FileEnd is the current NOR address of the end of the file's data
FileEnd = FileStart + File->HwDescription.Region[0].Size;
@@ -315,17 +319,20 @@ BootMonFsFlushFile (
)
{
Region = (BOOTMON_FS_FILE_REGION*)RegionToFlushLink;
+ if (Region->Size == 0) {
+ continue;
+ }
// RegionStart and RegionEnd are the the intended NOR address of the
// start and end of the region
- RegionStart = FileStart + Region->Offset;
- RegionEnd = RegionStart + Region->Size;
+ RegionStart = FileStart + Region->Offset;
+ RegionEnd = RegionStart + Region->Size;
if (RegionEnd < FileEnd) {
// Handle regions representing edits to existing portions of the file
// Write the region data straight into the file
Status = DiskIo->WriteDisk (DiskIo,
- BlockIo->Media->MediaId,
+ Media->MediaId,
RegionStart,
Region->Size,
Region->Buffer
@@ -344,7 +351,8 @@ BootMonFsFlushFile (
// Check if there is space to append the new region
HasSpace = FALSE;
- NewFileSize = (RegionEnd - FileStart) + sizeof (HW_IMAGE_DESCRIPTION);
+ NewDataSize = RegionEnd - FileStart;
+ NewFileSize = NewDataSize + sizeof (HW_IMAGE_DESCRIPTION);
CurrentPhysicalSize = BootMonFsGetPhysicalSize (File);
if (NewFileSize <= CurrentPhysicalSize) {
HasSpace = TRUE;
@@ -359,7 +367,7 @@ BootMonFsFlushFile (
EndOfAppendSpace = NextFile->HwDescription.BlockStart * BlockSize;
} else {
// We are flushing the last file.
- EndOfAppendSpace = (BlockIo->Media->LastBlock + 1) * BlockSize;
+ EndOfAppendSpace = (Media->LastBlock + 1) * BlockSize;
}
if (EndOfAppendSpace - FileStart >= NewFileSize) {
HasSpace = TRUE;
@@ -367,10 +375,31 @@ BootMonFsFlushFile (
}
if (HasSpace == TRUE) {
- Status = FlushAppendRegion (File, Region, NewFileSize, FileStart);
+ // Invalidate the current image description of the file if any.
+ if (File->HwDescAddress != 0) {
+ Status = InvalidateImageDescription (File);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ }
+
+ // Write the new file data
+ Status = DiskIo->WriteDisk (
+ DiskIo,
+ Media->MediaId,
+ RegionStart,
+ Region->Size,
+ Region->Buffer
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ Status = WriteFileDescription (File, AsciiFileName, NewDataSize, FileStart);
if (EFI_ERROR (Status)) {
return Status;
}
+
} else {
// There isn't a space for the file.
// Options here are to move the file or fragment it. However as files
@@ -384,20 +413,32 @@ BootMonFsFlushFile (
}
FreeFileRegions (File);
+ Info->PhysicalSize = BootMonFsGetPhysicalSize (File);
+
+ if ((AsciiStrCmp (AsciiFileName, File->HwDescription.Footer.Filename) != 0) ||
+ (Info->FileSize != File->HwDescription.Region[0].Size) ) {
+ Status = WriteFileDescription (File, AsciiFileName, Info->FileSize, FileStart);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ }
// Flush DiskIo Buffers (see UEFI Spec 12.7 - DiskIo buffers are flushed by
// calling FlushBlocks on the same device's BlockIo).
BlockIo->FlushBlocks (BlockIo);
- return Status;
+ return EFI_SUCCESS;
}
/**
- Closes a file on the Nor Flash FS volume.
+ Close a specified file handle.
- @param This The EFI_FILE_PROTOCOL to close.
+ @param[in] This A pointer to the EFI_FILE_PROTOCOL instance that is the file
+ handle to close.
- @return Always returns EFI_SUCCESS.
+ @retval EFI_SUCCESS The file was closed.
+ @retval EFI_INVALID_PARAMETER The parameter "This" is NULL or is not an open
+ file handle.
**/
EFIAPI
@@ -406,98 +447,101 @@ BootMonFsCloseFile (
IN EFI_FILE_PROTOCOL *This
)
{
- // Flush the file if needed
- This->Flush (This);
- return EFI_SUCCESS;
-}
-
-// Create a new instance of BOOTMON_FS_FILE.
-// Uses BootMonFsCreateFile to
-STATIC
-EFI_STATUS
-CreateNewFile (
- IN BOOTMON_FS_INSTANCE *Instance,
- IN CHAR8* AsciiFileName,
- OUT BOOTMON_FS_FILE **NewHandle
- )
-{
- EFI_STATUS Status;
- BOOTMON_FS_FILE *File;
+ BOOTMON_FS_FILE *File;
- Status = BootMonFsCreateFile (Instance, &File);
- if (EFI_ERROR (Status)) {
- return Status;
+ if (This == NULL) {
+ return EFI_INVALID_PARAMETER;
}
- // Remove the leading '\\'
- if (*AsciiFileName == '\\') {
- AsciiFileName++;
+ File = BOOTMON_FS_FILE_FROM_FILE_THIS (This);
+ if (File->Info == NULL) {
+ return EFI_INVALID_PARAMETER;
}
- // Set the file name
- CopyMem (File->HwDescription.Footer.Filename, AsciiFileName, MAX_NAME_LENGTH);
-
- // Add the file to list of files of the File System
- InsertHeadList (&Instance->RootFile->Link, &File->Link);
+ // In the case of a file and not the root directory
+ if (This != &File->Instance->RootFile->File) {
+ This->Flush (This);
+ FreePool (File->Info);
+ File->Info = NULL;
+ }
- *NewHandle = File;
- return Status;
+ return EFI_SUCCESS;
}
/**
- Opens a file on the Nor Flash FS volume
-
- Calls BootMonFsGetFileFromAsciiFilename to search the list of tracked files.
-
- @param This The EFI_FILE_PROTOCOL parent handle.
- @param NewHandle Double-pointer to the newly created protocol.
- @param FileName The name of the image/metadata on flash
- @param OpenMode Read,write,append etc
- @param Attributes ?
-
- @return EFI_STATUS
- OUT_OF_RESOURCES
- Run out of space to keep track of the allocated structures
- DEVICE_ERROR
- Unable to locate the volume associated with the parent file handle
- NOT_FOUND
- Filename wasn't found on flash
- SUCCESS
+ Open a file on the boot monitor file system.
+
+ The boot monitor file system does not allow for sub-directories. There is only
+ one directory, the root one. On any attempt to create a directory, the function
+ returns in error with the EFI_WRITE_PROTECTED error code.
+
+ @param[in] This A pointer to the EFI_FILE_PROTOCOL instance that is
+ the file handle to source location.
+ @param[out] NewHandle A pointer to the location to return the opened
+ handle for the new file.
+ @param[in] FileName The Null-terminated string of the name of the file
+ to be opened.
+ @param[in] OpenMode The mode to open the file : Read or Read/Write or
+ Read/Write/Create
+ @param[in] Attributes Attributes of the file in case of a file creation
+
+ @retval EFI_SUCCESS The file was open.
+ @retval EFI_NOT_FOUND The specified file could not be found or the specified
+ directory in which to create a file could not be found.
+ @retval EFI_DEVICE_ERROR The device reported an error.
+ @retval EFI_WRITE_PROTECTED Attempt to create a directory. This is not possible
+ with the Boot Monitor file system.
+ @retval EFI_OUT_OF_RESOURCES Not enough resources were available to open the file.
+ @retval EFI_INVALID_PARAMETER At least one of the parameters is invalid.
**/
EFIAPI
EFI_STATUS
BootMonFsOpenFile (
- IN EFI_FILE_PROTOCOL *This,
- OUT EFI_FILE_PROTOCOL **NewHandle,
- IN CHAR16 *FileName,
- IN UINT64 OpenMode,
- IN UINT64 Attributes
+ IN EFI_FILE_PROTOCOL *This,
+ OUT EFI_FILE_PROTOCOL **NewHandle,
+ IN CHAR16 *FileName,
+ IN UINT64 OpenMode,
+ IN UINT64 Attributes
)
{
- BOOTMON_FS_FILE *Directory;
- BOOTMON_FS_FILE *File;
- BOOTMON_FS_INSTANCE *Instance;
- CHAR8* AsciiFileName;
EFI_STATUS Status;
+ BOOTMON_FS_FILE *Directory;
+ BOOTMON_FS_FILE *File;
+ BOOTMON_FS_INSTANCE *Instance;
+ CHAR8 *Buf;
+ CHAR16 *Path;
+ CHAR16 *Separator;
+ CHAR8 *AsciiFileName;
+ EFI_FILE_INFO *Info;
+
+ if (This == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
- if ((FileName == NULL) || (NewHandle == NULL)) {
+ Directory = BOOTMON_FS_FILE_FROM_FILE_THIS (This);
+ if (Directory->Info == NULL) {
return EFI_INVALID_PARAMETER;
}
- // The only valid modes are read, read/write, and read/write/create
- if (!(OpenMode & EFI_FILE_MODE_READ) || ((OpenMode & EFI_FILE_MODE_CREATE) && !(OpenMode & EFI_FILE_MODE_WRITE))) {
+ if ((FileName == NULL) || (NewHandle == NULL)) {
return EFI_INVALID_PARAMETER;
}
- Directory = BOOTMON_FS_FILE_FROM_FILE_THIS (This);
- if (Directory == NULL) {
- return EFI_DEVICE_ERROR;
+ //
+ // The only valid modes are read, read/write, and read/write/create
+ //
+ if ( (OpenMode != EFI_FILE_MODE_READ) &&
+ (OpenMode != (EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE)) &&
+ (OpenMode != (EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE | EFI_FILE_MODE_CREATE)) ) {
+ return EFI_INVALID_PARAMETER;
}
Instance = Directory->Instance;
- // If the instance has not been initialized it yet then do it ...
+ //
+ // If the instance has not been initialized yet then do it ...
+ //
if (!Instance->Initialized) {
Status = BootMonFsInitialize (Instance);
if (EFI_ERROR (Status)) {
@@ -505,58 +549,165 @@ BootMonFsOpenFile (
}
}
+ //
+ // Copy the file path to be able to work on it. We do not want to
+ // modify the input file name string "FileName".
+ //
+ Buf = AllocateCopyPool (StrSize (FileName), FileName);
+ if (Buf == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+ Path = (CHAR16*)Buf;
+ AsciiFileName = NULL;
+ Info = NULL;
+
+ //
+ // Handle single periods, double periods and convert forward slashes '/'
+ // to backward '\' ones. Does not handle a '.' at the beginning of the
+ // path for the time being.
+ //
+ if (PathCleanUpDirectories (Path) == NULL) {
+ Status = EFI_INVALID_PARAMETER;
+ goto Error;
+ }
+
+ //
+ // Detect if the first component of the path refers to a directory.
+ // This is done to return the correct error code when trying to
+ // access or create a directory other than the root directory.
+ //
+
+ //
+ // Search for the '\\' sequence and if found return in error
+ // with the EFI_INVALID_PARAMETER error code. ere in the path.
+ //
+ if (StrStr (Path, L"\\\\") != NULL) {
+ Status = EFI_INVALID_PARAMETER;
+ goto Error;
+ }
+ //
+ // Get rid of the leading '\' if any.
+ //
+ Path += (Path[0] == L'\\');
+
+ //
+ // Look for a '\' in the file path. If one is found then
+ // the first component of the path refers to a directory
+ // that is not the root directory.
+ //
+ Separator = StrStr (Path, L"\\");
+ if (Separator != NULL) {
+ //
+ // In the case '<dir name>\' and a creation, return
+ // EFI_WRITE_PROTECTED if this is for a directory
+ // creation, EFI_INVALID_PARAMETER otherwise.
+ //
+ if ((*(Separator + 1) == '\0') && ((OpenMode & EFI_FILE_MODE_CREATE) != 0)) {
+ if (Attributes & EFI_FILE_DIRECTORY) {
+ Status = EFI_WRITE_PROTECTED;
+ } else {
+ Status = EFI_INVALID_PARAMETER;
+ }
+ } else {
+ //
+ // Attempt to open a file or a directory that is not in the
+ // root directory or to open without creation a directory
+ // located in the root directory, returns EFI_NOT_FOUND.
+ //
+ Status = EFI_NOT_FOUND;
+ }
+ goto Error;
+ }
+
+ //
// BootMonFs interface requires ASCII filenames
- AsciiFileName = AllocatePool ((StrLen (FileName) + 1) * sizeof (CHAR8));
+ //
+ AsciiFileName = AllocatePool (StrLen (Path) + 1);
if (AsciiFileName == NULL) {
- return EFI_OUT_OF_RESOURCES;
+ Status = EFI_OUT_OF_RESOURCES;
+ goto Error;
+ }
+ UnicodeStrToAsciiStr (Path, AsciiFileName);
+ if (AsciiStrSize (AsciiFileName) > MAX_NAME_LENGTH) {
+ AsciiFileName[MAX_NAME_LENGTH - 1] = '\0';
}
- UnicodeStrToAsciiStr (FileName, AsciiFileName);
- if ((AsciiStrCmp (AsciiFileName, "\\") == 0) ||
- (AsciiStrCmp (AsciiFileName, "/") == 0) ||
- (AsciiStrCmp (AsciiFileName, "") == 0) ||
- (AsciiStrCmp (AsciiFileName, ".") == 0))
- {
+ if ((AsciiFileName[0] == '\0') ||
+ (AsciiFileName[0] == '.' ) ) {
//
- // Opening '/', '\', '.', or the NULL pathname is trying to open the root directory
+ // Opening the root directory
//
*NewHandle = &Instance->RootFile->File;
Instance->RootFile->Position = 0;
Status = EFI_SUCCESS;
} else {
+
+ if ((OpenMode & EFI_FILE_MODE_CREATE) &&
+ (Attributes & EFI_FILE_DIRECTORY) ) {
+ Status = EFI_WRITE_PROTECTED;
+ goto Error;
+ }
+
//
- // Open or Create a regular file
+ // Allocate a buffer to store the characteristics of the file while the
+ // file is open. We allocate the maximum size to not have to reallocate
+ // if the file name is changed.
+ //
+ Info = AllocateZeroPool (
+ SIZE_OF_EFI_FILE_INFO + (sizeof (CHAR16) * MAX_NAME_LENGTH));
+ if (Info == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto Error;
+ }
+
+ //
+ // Open or create a file in the root directory.
//
- // Check if the file already exists
Status = BootMonGetFileFromAsciiFileName (Instance, AsciiFileName, &File);
if (Status == EFI_NOT_FOUND) {
- // The file doesn't exist.
- if (OpenMode & EFI_FILE_MODE_CREATE) {
- // If the file does not exist but is required then create it.
- if (Attributes & EFI_FILE_DIRECTORY) {
- // BootMonFS doesn't support subdirectories
- Status = EFI_UNSUPPORTED;
- } else {
- // Create a new file
- Status = CreateNewFile (Instance, AsciiFileName, &File);
- if (!EFI_ERROR (Status)) {
- File->OpenMode = OpenMode;
- *NewHandle = &File->File;
- File->Position = 0;
- }
- }
+ if ((OpenMode & EFI_FILE_MODE_CREATE) == 0) {
+ goto Error;
+ }
+
+ Status = BootMonFsCreateFile (Instance, &File);
+ if (EFI_ERROR (Status)) {
+ goto Error;
+ }
+ InsertHeadList (&Instance->RootFile->Link, &File->Link);
+ Info->Attribute = Attributes;
+ } else {
+ //
+ // File already open, not supported yet.
+ //
+ if (File->Info != NULL) {
+ Status = EFI_UNSUPPORTED;
+ goto Error;
}
- } else if (Status == EFI_SUCCESS) {
- // The file exists
- File->OpenMode = OpenMode;
- *NewHandle = &File->File;
- File->Position = 0;
}
+
+ Info->FileSize = BootMonFsGetImageLength (File);
+ Info->PhysicalSize = BootMonFsGetPhysicalSize (File);
+ AsciiStrToUnicodeStr (AsciiFileName, Info->FileName);
+
+ File->Info = Info;
+ Info = NULL;
+ File->Position = 0;
+ File->OpenMode = OpenMode;
+
+ *NewHandle = &File->File;
}
- FreePool (AsciiFileName);
+Error:
+
+ FreePool (Buf);
+ if (AsciiFileName != NULL) {
+ FreePool (AsciiFileName);
+ }
+ if (Info != NULL) {
+ FreePool (Info);
+ }
return Status;
}
@@ -572,6 +723,19 @@ BootMonFsDeleteFail (
// You can't delete the root directory
return EFI_WARN_DELETE_FAILURE;
}
+
+/**
+ Close and delete a file from the boot monitor file system.
+
+ @param[in] This A pointer to the EFI_FILE_PROTOCOL instance that is the file
+ handle to delete.
+
+ @retval EFI_SUCCESS The file was closed and deleted.
+ @retval EFI_INVALID_PARAMETER The parameter "This" is NULL or is not an open
+ file handle.
+ @retval EFI_WARN_DELETE_FAILURE The handle was closed, but the file was not deleted.
+
+**/
EFIAPI
EFI_STATUS
BootMonFsDelete (
@@ -582,23 +746,26 @@ BootMonFsDelete (
BOOTMON_FS_FILE *File;
LIST_ENTRY *RegionToFlushLink;
BOOTMON_FS_FILE_REGION *Region;
- EFI_BLOCK_IO_PROTOCOL *BlockIo;
- UINT8 *EmptyBuffer;
- File = BOOTMON_FS_FILE_FROM_FILE_THIS (This);
- if (File == NULL) {
- return EFI_DEVICE_ERROR;
+ if (This == NULL) {
+ return EFI_INVALID_PARAMETER;
}
- Status = EFI_SUCCESS;
+ File = BOOTMON_FS_FILE_FROM_FILE_THIS (This);
+ if (File->Info == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
- if (BootMonFsFileNeedFlush (File)) {
+ if (!IsListEmpty (&File->RegionToFlushLink)) {
// Free the entries from the Buffer List
RegionToFlushLink = GetFirstNode (&File->RegionToFlushLink);
do {
Region = (BOOTMON_FS_FILE_REGION*)RegionToFlushLink;
- // Get Next entry
+ //
+ // Get next element of the list before deleting the region description
+ // that contain the LIST_ENTRY structure.
+ //
RegionToFlushLink = RemoveEntryList (RegionToFlushLink);
// Free the buffers
@@ -609,25 +776,18 @@ BootMonFsDelete (
// If (RegionCount is greater than 0) then the file already exists
if (File->HwDescription.RegionCount > 0) {
- BlockIo = File->Instance->BlockIo;
-
- // Create an empty buffer
- EmptyBuffer = AllocateZeroPool (BlockIo->Media->BlockSize);
- if (EmptyBuffer == NULL) {
- FreePool (File);
- return EFI_OUT_OF_RESOURCES;
- }
-
// Invalidate the last Block
Status = InvalidateImageDescription (File);
ASSERT_EFI_ERROR (Status);
-
- FreePool (EmptyBuffer);
+ if (EFI_ERROR (Status)) {
+ return EFI_WARN_DELETE_FAILURE;
+ }
}
// Remove the entry from the list
RemoveEntryList (&File->Link);
+ FreePool (File->Info);
FreePool (File);
- return Status;
-}
+ return EFI_SUCCESS;
+}
diff --git a/ArmPlatformPkg/FileSystem/BootMonFs/BootMonFsReadWrite.c b/ArmPlatformPkg/FileSystem/BootMonFs/BootMonFsReadWrite.c
index 653b2c507c..f8124e95ac 100644
--- a/ArmPlatformPkg/FileSystem/BootMonFs/BootMonFsReadWrite.c
+++ b/ArmPlatformPkg/FileSystem/BootMonFs/BootMonFsReadWrite.c
@@ -20,6 +20,24 @@
#include "BootMonFsInternal.h"
+/**
+ Read data from an open file.
+
+ @param[in] This A pointer to the EFI_FILE_PROTOCOL instance that
+ is the file handle to read data from.
+ @param[in out] BufferSize 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.
+ @param[out] Buffer The buffer into which the data is read.
+
+ @retval EFI_SUCCESS The data was read.
+ @retval EFI_DEVICE_ERROR On entry, the current file position is
+ beyond the end of the file, or the device
+ reported an error while performing the read
+ operation.
+ @retval EFI_INVALID_PARAMETER At least one of the parameters is invalid.
+
+**/
EFIAPI
EFI_STATUS
BootMonFsReadFile (
@@ -36,28 +54,38 @@ BootMonFsReadFile (
EFI_STATUS Status;
UINTN RemainingFileSize;
- // Ensure the file has been written in Flash before reading it.
- // This keeps the code simple and avoids having to manage a non-flushed file.
- BootMonFsFlushFile (This);
-
+ if ((This == NULL) ||
+ (BufferSize == NULL) ||
+ (Buffer == NULL) ) {
+ return EFI_INVALID_PARAMETER;
+ }
File = BOOTMON_FS_FILE_FROM_FILE_THIS (This);
- if (File == NULL) {
+ if (File->Info == NULL) {
return EFI_INVALID_PARAMETER;
}
- Instance = File->Instance;
- DiskIo = Instance->DiskIo;
- Media = Instance->Media;
+ // Ensure the file has been written in Flash before reading it.
+ // This keeps the code simple and avoids having to manage a non-flushed file.
+ BootMonFsFlushFile (This);
+
+ Instance = File->Instance;
+ DiskIo = Instance->DiskIo;
+ Media = Instance->Media;
FileStart = (Media->LowestAlignedLba + File->HwDescription.BlockStart) * Media->BlockSize;
- if (File->Position >= File->HwDescription.Region[0].Size) {
- // The entire file has been read
+ if (File->Position >= File->Info->FileSize) {
+ // The entire file has been read or the position has been
+ // set past the end of the file.
*BufferSize = 0;
- return EFI_DEVICE_ERROR;
+ if (File->Position > File->Info->FileSize) {
+ return EFI_DEVICE_ERROR;
+ } else {
+ return EFI_SUCCESS;
+ }
}
// This driver assumes that the entire file is in region 0.
- RemainingFileSize = File->HwDescription.Region[0].Size - File->Position;
+ RemainingFileSize = File->Info->FileSize - File->Position;
// If read would go past end of file, truncate the read
if (*BufferSize > RemainingFileSize) {
@@ -80,7 +108,26 @@ BootMonFsReadFile (
return Status;
}
-// Inserts an entry into the write chain
+/**
+ Write data to an open file.
+
+ The data is not written to the flash yet. It will be written when the file
+ will be either read, closed or flushed.
+
+ @param[in] This A pointer to the EFI_FILE_PROTOCOL instance that
+ is the file handle to write data to.
+ @param[in out] BufferSize On input, the size of the Buffer. On output, the
+ size of the data actually written. In both cases,
+ the size is measured in bytes.
+ @param[in] Buffer The buffer of data to write.
+
+ @retval EFI_SUCCESS The data was written.
+ @retval EFI_ACCESS_DENIED The file was opened read only.
+ @retval EFI_OUT_OF_RESOURCES Unable to allocate the buffer to store the
+ data to write.
+ @retval EFI_INVALID_PARAMETER At least one of the parameters is invalid.
+
+**/
EFIAPI
EFI_STATUS
BootMonFsWriteFile (
@@ -92,38 +139,57 @@ BootMonFsWriteFile (
BOOTMON_FS_FILE *File;
BOOTMON_FS_FILE_REGION *Region;
+ if (This == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
File = BOOTMON_FS_FILE_FROM_FILE_THIS (This);
- if (File == NULL) {
+ if (File->Info == NULL) {
return EFI_INVALID_PARAMETER;
}
- if (!(File->OpenMode & EFI_FILE_MODE_WRITE)) {
+ if (File->OpenMode == EFI_FILE_MODE_READ) {
return EFI_ACCESS_DENIED;
}
// Allocate and initialize the memory region
Region = (BOOTMON_FS_FILE_REGION*)AllocateZeroPool (sizeof (BOOTMON_FS_FILE_REGION));
if (Region == NULL) {
+ *BufferSize = 0;
return EFI_OUT_OF_RESOURCES;
}
- Region->Buffer = AllocateCopyPool (*BufferSize, Buffer);
+ Region->Buffer = AllocateCopyPool (*BufferSize, Buffer);
if (Region->Buffer == NULL) {
+ *BufferSize = 0;
FreePool (Region);
return EFI_OUT_OF_RESOURCES;
}
- Region->Size = *BufferSize;
-
+ Region->Size = *BufferSize;
Region->Offset = File->Position;
InsertTailList (&File->RegionToFlushLink, &Region->Link);
File->Position += *BufferSize;
+ if (File->Position > File->Info->FileSize) {
+ File->Info->FileSize = File->Position;
+ }
+
return EFI_SUCCESS;
}
+/**
+ Set a file's current position.
+
+ @param[in] This A pointer to the EFI_FILE_PROTOCOL instance that is
+ the file handle to set the requested position on.
+ @param[in] Position The byte position from the start of the file to set.
+
+ @retval EFI_SUCCESS The position was set.
+ @retval EFI_INVALID_PARAMETER At least one of the parameters is invalid.
+
+**/
EFIAPI
EFI_STATUS
BootMonFsSetPosition (
@@ -131,33 +197,63 @@ BootMonFsSetPosition (
IN UINT64 Position
)
{
- BOOTMON_FS_FILE *File;
+ BOOTMON_FS_FILE *File;
+ if (This == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
File = BOOTMON_FS_FILE_FROM_FILE_THIS (This);
+ if (File->Info == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+ //
// UEFI Spec section 12.5:
// "Seeking to position 0xFFFFFFFFFFFFFFFF causes the current position to
- // be set to the end of the file."
+ // be set to the end of the file."
+ //
if (Position == 0xFFFFFFFFFFFFFFFF) {
- File->Position = BootMonFsGetImageLength (File);
- } else {
- // NB: Seeking past the end of the file is valid.
- File->Position = Position;
+ Position = File->Info->FileSize;
}
+ File->Position = Position;
+
return EFI_SUCCESS;
}
+/**
+ Return a file's current position.
+
+ @param[in] This A pointer to the EFI_FILE_PROTOCOL instance that is
+ the file handle to get the current position on.
+ @param[out] Position The address to return the file's current position value.
+
+ @retval EFI_SUCCESS The position was returned.
+ @retval EFI_INVALID_PARAMETER At least one of the parameters is invalid.
+
+**/
EFIAPI
EFI_STATUS
BootMonFsGetPosition (
IN EFI_FILE_PROTOCOL *This,
OUT UINT64 *Position
- ) {
+ )
+{
BOOTMON_FS_FILE *File;
+ if (This == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
File = BOOTMON_FS_FILE_FROM_FILE_THIS (This);
+ if (File->Info == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (Position == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
*Position = File->Position;
+
return EFI_SUCCESS;
}
diff --git a/ArmPlatformPkg/Include/Drivers/PL011Uart.h b/ArmPlatformPkg/Include/Drivers/PL011Uart.h
index 6675cefeb3..2fe796f9e4 100644
--- a/ArmPlatformPkg/Include/Drivers/PL011Uart.h
+++ b/ArmPlatformPkg/Include/Drivers/PL011Uart.h
@@ -35,6 +35,11 @@
#define UARTICR 0x044
#define UARTDMACR 0x048
+#define UARTPID0 0xFE0
+#define UARTPID1 0xFE4
+#define UARTPID2 0xFE8
+#define UARTPID3 0xFEC
+
// Data status bits
#define UART_DATA_ERROR_MASK 0x0F00
@@ -81,6 +86,9 @@
#define PL011_UARTLCR_H_PEN (1 << 1) // Parity Enable
#define PL011_UARTLCR_H_BRK (1 << 0) // Send break
+#define PL011_UARTPID2_VER(X) (((X) >> 4) & 0xF)
+#define PL011_VER_R1P4 0x2
+
/*
Programmed hardware of Serial port.
diff --git a/ArmPlatformPkg/Library/PlatformIntelBdsLib/IntelBdsPlatform.c b/ArmPlatformPkg/Library/PlatformIntelBdsLib/IntelBdsPlatform.c
index c07fc0f607..2d02f38296 100644
--- a/ArmPlatformPkg/Library/PlatformIntelBdsLib/IntelBdsPlatform.c
+++ b/ArmPlatformPkg/Library/PlatformIntelBdsLib/IntelBdsPlatform.c
@@ -14,6 +14,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#include "IntelBdsPlatform.h"
+#include <Library/ArmBdsHelperLib.h>
///
/// Predefined platform default time out value
diff --git a/ArmPlatformPkg/Library/PlatformIntelBdsLib/PlatformIntelBdsLib.inf b/ArmPlatformPkg/Library/PlatformIntelBdsLib/PlatformIntelBdsLib.inf
index 235589adf5..95b9f1564d 100644
--- a/ArmPlatformPkg/Library/PlatformIntelBdsLib/PlatformIntelBdsLib.inf
+++ b/ArmPlatformPkg/Library/PlatformIntelBdsLib/PlatformIntelBdsLib.inf
@@ -42,9 +42,9 @@
IntelFrameworkModulePkg/IntelFrameworkModulePkg.dec
[LibraryClasses]
+ ArmBdsHelperLib
BaseLib
BaseMemoryLib
- BdsLib
DebugLib
DevicePathLib
MemoryAllocationLib
diff --git a/BaseTools/Conf/tools_def.template b/BaseTools/Conf/tools_def.template
index cacf4bf28b..60cb39b81c 100644
--- a/BaseTools/Conf/tools_def.template
+++ b/BaseTools/Conf/tools_def.template
@@ -3864,7 +3864,7 @@ DEFINE GCC46_IA32_X64_DLINK_FLAGS = DEF(GCC45_IA32_X64_DLINK_FLAGS)
DEFINE GCC46_X64_DLINK_FLAGS = DEF(GCC45_X64_DLINK_FLAGS)
DEFINE GCC46_ASM_FLAGS = DEF(GCC45_ASM_FLAGS)
DEFINE GCC46_ARM_ASM_FLAGS = $(ARCHASM_FLAGS) $(PLATFORM_FLAGS) DEF(GCC_ASM_FLAGS) -mlittle-endian
-DEFINE GCC46_ARM_CC_FLAGS = $(ARCHCC_FLAGS) $(PLATFORM_FLAGS) DEF(GCC44_ALL_CC_FLAGS) DEF(GCC_ARM_CC_FLAGS) -mno-unaligned-access -fstack-protector
+DEFINE GCC46_ARM_CC_FLAGS = $(ARCHCC_FLAGS) $(PLATFORM_FLAGS) DEF(GCC44_ALL_CC_FLAGS) DEF(GCC_ARM_CC_FLAGS) -fstack-protector
DEFINE GCC46_ARM_DLINK_FLAGS = DEF(GCC_ARM_AARCH64_DLINK_COMMON) --oformat=elf32-littlearm
DEFINE GCC46_ARM_ASLDLINK_FLAGS = DEF(GCC_ARM_AARCH64_ASLDLINK_FLAGS) --oformat=elf32-littlearm
@@ -3877,7 +3877,7 @@ DEFINE GCC47_X64_DLINK_FLAGS = DEF(GCC46_X64_DLINK_FLAGS)
DEFINE GCC47_ASM_FLAGS = DEF(GCC46_ASM_FLAGS)
DEFINE GCC47_ARM_ASM_FLAGS = DEF(GCC46_ARM_ASM_FLAGS)
DEFINE GCC47_AARCH64_ASM_FLAGS = $(ARCHASM_FLAGS) $(PLATFORM_FLAGS) DEF(GCC_ASM_FLAGS) -mlittle-endian
-DEFINE GCC47_ARM_CC_FLAGS = DEF(GCC46_ARM_CC_FLAGS)
+DEFINE GCC47_ARM_CC_FLAGS = DEF(GCC46_ARM_CC_FLAGS) -mno-unaligned-access
DEFINE GCC47_AARCH64_CC_FLAGS = $(ARCHCC_FLAGS) $(PLATFORM_FLAGS) DEF(GCC44_ALL_CC_FLAGS) DEF(GCC_AARCH64_CC_FLAGS)
DEFINE GCC47_ARM_DLINK_FLAGS = DEF(GCC46_ARM_DLINK_FLAGS)
DEFINE GCC47_AARCH64_DLINK_FLAGS = DEF(GCC_ARM_AARCH64_DLINK_COMMON)
diff --git a/BaseTools/Source/Python/AutoGen/UniClassObject.py b/BaseTools/Source/Python/AutoGen/UniClassObject.py
index 8c3e84876c..aa54f4fbd6 100644
--- a/BaseTools/Source/Python/AutoGen/UniClassObject.py
+++ b/BaseTools/Source/Python/AutoGen/UniClassObject.py
@@ -340,6 +340,7 @@ class UniFileClassObject(object):
Line = Line.replace(u'\\n', CR + LF)
Line = Line.replace(u'\\r', CR)
Line = Line.replace(u'\\t', u' ')
+ Line = Line.replace(u'\t', u' ')
Line = Line.replace(u'\\"', u'"')
Line = Line.replace(u"\\'", u"'")
Line = Line.replace(BACK_SLASH_PLACEHOLDER, u'\\')
diff --git a/BaseTools/Source/Python/Common/DataType.py b/BaseTools/Source/Python/Common/DataType.py
index 57e5063ff2..6d66523847 100644
--- a/BaseTools/Source/Python/Common/DataType.py
+++ b/BaseTools/Source/Python/Common/DataType.py
@@ -442,6 +442,7 @@ TAB_ELSE = '!else'
TAB_IF_DEF = '!ifdef'
TAB_IF_N_DEF = '!ifndef'
TAB_IF_EXIST = '!if exist'
+TAB_ERROR = '!ERROR'
#
# Unknown section
diff --git a/BaseTools/Source/Python/CommonDataClass/DataClass.py b/BaseTools/Source/Python/CommonDataClass/DataClass.py
index 3f6c3c65a5..3be369a0f4 100644
--- a/BaseTools/Source/Python/CommonDataClass/DataClass.py
+++ b/BaseTools/Source/Python/CommonDataClass/DataClass.py
@@ -86,6 +86,7 @@ MODEL_META_DATA_CONDITIONAL_STATEMENT_IF = 5004
MODEL_META_DATA_CONDITIONAL_STATEMENT_ELSE = 5005
MODEL_META_DATA_CONDITIONAL_STATEMENT_IFDEF = 5006
MODEL_META_DATA_CONDITIONAL_STATEMENT_IFNDEF = 5007
+MODEL_META_DATA_CONDITIONAL_STATEMENT_ERROR = 5400
MODEL_META_DATA_BUILD_OPTION = 5008
MODEL_META_DATA_COMPONENT = 5009
MODEL_META_DATA_USER_EXTENSION = 5010
@@ -164,6 +165,7 @@ MODEL_LIST = [('MODEL_UNKNOWN', MODEL_UNKNOWN),
("MODEL_META_DATA_CONDITIONAL_STATEMENT_ELSE", MODEL_META_DATA_CONDITIONAL_STATEMENT_ELSE),
("MODEL_META_DATA_CONDITIONAL_STATEMENT_IFDEF", MODEL_META_DATA_CONDITIONAL_STATEMENT_IFDEF),
("MODEL_META_DATA_CONDITIONAL_STATEMENT_IFNDEF", MODEL_META_DATA_CONDITIONAL_STATEMENT_IFNDEF),
+ ("MODEL_META_DATA_CONDITIONAL_STATEMENT_ERROR", MODEL_META_DATA_CONDITIONAL_STATEMENT_ERROR),
("MODEL_META_DATA_COMPONENT_SOURCE_OVERRIDE_PATH", MODEL_META_DATA_COMPONENT_SOURCE_OVERRIDE_PATH),
("MODEL_META_DATA_BUILD_OPTION", MODEL_META_DATA_BUILD_OPTION),
("MODEL_META_DATA_COMPONENT", MODEL_META_DATA_COMPONENT),
diff --git a/BaseTools/Source/Python/Ecc/Check.py b/BaseTools/Source/Python/Ecc/Check.py
index cfa96c156e..5bee6dba7c 100644
--- a/BaseTools/Source/Python/Ecc/Check.py
+++ b/BaseTools/Source/Python/Ecc/Check.py
@@ -63,7 +63,7 @@ class Check(object):
def GeneralCheckNonAcsii(self):
if EccGlobalData.gConfig.GeneralCheckNonAcsii == '1' or EccGlobalData.gConfig.GeneralCheckAll == '1' or EccGlobalData.gConfig.CheckAll == '1':
EdkLogger.quiet("Checking Non-ACSII char in file ...")
- SqlCommand = """select ID, FullPath, ExtName from File"""
+ SqlCommand = """select ID, FullPath, ExtName from File where ExtName in ('.dec', '.inf', '.dsc', 'c', 'h')"""
RecordSet = EccGlobalData.gDb.TblFile.Exec(SqlCommand)
for Record in RecordSet:
if Record[2].upper() not in EccGlobalData.gConfig.BinaryExtList:
diff --git a/BaseTools/Source/Python/Ecc/MetaFileWorkspace/MetaFileParser.py b/BaseTools/Source/Python/Ecc/MetaFileWorkspace/MetaFileParser.py
index 1c3e968785..9f31d4d4de 100644
--- a/BaseTools/Source/Python/Ecc/MetaFileWorkspace/MetaFileParser.py
+++ b/BaseTools/Source/Python/Ecc/MetaFileWorkspace/MetaFileParser.py
@@ -461,13 +461,14 @@ class InfParser(MetaFileParser):
MODEL_PCD_DYNAMIC_EX,
MODEL_PCD_DYNAMIC]:
Line = Content[Index].strip()
- if Line.startswith(TAB_COMMENT_SPLIT):
+ if Line.startswith(TAB_SPECIAL_COMMENT):
+ Usage += ' ' + Line[Line.find(TAB_SPECIAL_COMMENT):]
+ continue
+ elif Line.startswith(TAB_COMMENT_SPLIT):
continue
elif Line.find(TAB_COMMENT_SPLIT) > 0:
- Usage = Line[Line.find(TAB_COMMENT_SPLIT):]
+ Usage += ' ' + Line[Line.find(TAB_COMMENT_SPLIT):]
Line = Line[:Line.find(TAB_COMMENT_SPLIT)]
- else:
- Usage = ''
else:
# skip empty, commented, block commented lines
Line = CleanString(Content[Index], AllowCppStyleComment=True)
@@ -545,6 +546,7 @@ class InfParser(MetaFileParser):
# LineBegin=-1, ColumnBegin=-1, LineEnd=-1, ColumnEnd=-1, Enabled=-1
#
self._ValueList[0] = self._ValueList[0].replace('/', '\\')
+ Usage = Usage.strip()
for Arch, Platform in self._Scope:
self._Store(self._SectionType,
self._ValueList[0],
@@ -561,6 +563,7 @@ class InfParser(MetaFileParser):
0,
Usage
)
+ Usage = ''
if IsFindBlockComment:
EdkLogger.error("Parser", FORMAT_INVALID, "Open block comments (starting with /*) are expected to end with */",
File=self.MetaFile)
@@ -731,6 +734,7 @@ class DscParser(MetaFileParser):
TAB_ELSE_IF.upper() : MODEL_META_DATA_CONDITIONAL_STATEMENT_ELSEIF,
TAB_ELSE.upper() : MODEL_META_DATA_CONDITIONAL_STATEMENT_ELSE,
TAB_END_IF.upper() : MODEL_META_DATA_CONDITIONAL_STATEMENT_ENDIF,
+ TAB_ERROR.upper() : MODEL_META_DATA_CONDITIONAL_STATEMENT_ERROR,
}
# Valid names in define section
@@ -1117,6 +1121,7 @@ class DscParser(MetaFileParser):
MODEL_META_DATA_BUILD_OPTION : self.__ProcessBuildOption,
MODEL_UNKNOWN : self._Skip,
MODEL_META_DATA_USER_EXTENSION : self._Skip,
+ MODEL_META_DATA_CONDITIONAL_STATEMENT_ERROR : self._Skip,
}
self._RawTable = self._Table
@@ -1152,9 +1157,10 @@ class DscParser(MetaFileParser):
# Only catch expression evaluation error here. We need to report
# the precise number of line on which the error occurred
#
- EdkLogger.error('Parser', FORMAT_INVALID, "Invalid expression: %s" % str(Excpt),
- File=self._FileWithError, ExtraData=' '.join(self._ValueList),
- Line=self._LineIndex+1)
+ pass
+# EdkLogger.error('Parser', FORMAT_INVALID, "Invalid expression: %s" % str(Excpt),
+# File=self._FileWithError, ExtraData=' '.join(self._ValueList),
+# Line=self._LineIndex+1)
except MacroException, Excpt:
EdkLogger.error('Parser', FORMAT_INVALID, str(Excpt),
File=self._FileWithError, ExtraData=' '.join(self._ValueList),
@@ -1809,7 +1815,10 @@ class Fdf(FdfObject):
# Load Fdf file if filename is not None
#
if Filename != None:
- self.LoadFdfFile(Filename)
+ try:
+ self.LoadFdfFile(Filename)
+ except Exception:
+ pass
#
# Insert a FDF file record into database
diff --git a/BaseTools/Source/Python/build/build.py b/BaseTools/Source/Python/build/build.py
index 7d68b45417..40d4055bfc 100644
--- a/BaseTools/Source/Python/build/build.py
+++ b/BaseTools/Source/Python/build/build.py
@@ -1,6 +1,7 @@
## @file
# build a platform or a module
#
+# Copyright (c) 2014, Hewlett-Packard Development Company, L.P.<BR>
# Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.<BR>
#
# This program and the accompanying materials
@@ -938,7 +939,7 @@ class Build():
# run
if Target == 'run':
- RunDir = os.path.normpath(os.path.join(AutoGenObject.BuildDir, 'IA32'))
+ RunDir = os.path.normpath(os.path.join(AutoGenObject.BuildDir, GlobalData.gGlobalDefines['ARCH']))
Command = '.\SecMain'
os.chdir(RunDir)
LaunchCommand(Command, RunDir)
@@ -1061,7 +1062,7 @@ class Build():
# run
if Target == 'run':
- RunDir = os.path.normpath(os.path.join(AutoGenObject.BuildDir, 'IA32'))
+ RunDir = os.path.normpath(os.path.join(AutoGenObject.BuildDir, GlobalData.gGlobalDefines['ARCH']))
Command = '.\SecMain'
os.chdir(RunDir)
LaunchCommand(Command, RunDir)
diff --git a/BeagleBoardPkg/BeagleBoardPkg.dsc b/BeagleBoardPkg/BeagleBoardPkg.dsc
index 64d207e33f..94b6f010d3 100644
--- a/BeagleBoardPkg/BeagleBoardPkg.dsc
+++ b/BeagleBoardPkg/BeagleBoardPkg.dsc
@@ -123,6 +123,7 @@
DmaLib|ArmPkg/Library/ArmDmaLib/ArmDmaLib.inf
NetLib|MdeModulePkg/Library/DxeNetLib/DxeNetLib.inf
+ ArmBdsHelperLib|ArmPkg/Library/ArmBdsHelperLib/ArmBdsHelperLib.inf
BdsLib|ArmPkg/Library/BdsLib/BdsLib.inf
FdtLib|EmbeddedPkg/Library/FdtLib/FdtLib.inf
diff --git a/CryptoPkg/Include/Library/BaseCryptLib.h b/CryptoPkg/Include/Library/BaseCryptLib.h
index e36041bf4f..bc36ac7fd1 100644
--- a/CryptoPkg/Include/Library/BaseCryptLib.h
+++ b/CryptoPkg/Include/Library/BaseCryptLib.h
@@ -1907,6 +1907,32 @@ X509StackFree (
);
/**
+ Retrieve the TBSCertificate from one given X.509 certificate.
+
+ @param[in] Cert Pointer to the given DER-encoded X509 certificate.
+ @param[in] CertSize Size of the X509 certificate in bytes.
+ @param[out] TBSCert DER-Encoded To-Be-Signed certificate.
+ @param[out] TBSCertSize Size of the TBS certificate in bytes.
+
+ If Cert is NULL, then return FALSE.
+ If TBSCert is NULL, then return FALSE.
+ If TBSCertSize is NULL, then return FALSE.
+ If this interface is not supported, then return FALSE.
+
+ @retval TRUE The TBSCertificate was retrieved successfully.
+ @retval FALSE Invalid X.509 certificate.
+
+**/
+BOOLEAN
+EFIAPI
+X509GetTBSCert (
+ IN CONST UINT8 *Cert,
+ IN UINTN CertSize,
+ OUT UINT8 **TBSCert,
+ OUT UINTN *TBSCertSize
+ );
+
+/**
Get the signer's certificates from PKCS#7 signed data as described in "PKCS #7:
Cryptographic Message Syntax Standard". The input signed data could be wrapped
in a ContentInfo structure.
@@ -2067,6 +2093,7 @@ AuthenticodeVerify (
signature.
If AuthData is NULL, then return FALSE.
+ If this interface is not supported, then return FALSE.
@param[in] AuthData Pointer to the Authenticode Signature retrieved from signed
PE/COFF image to be verified.
diff --git a/CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf b/CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf
index 550afd912b..05cfe11b2c 100644
--- a/CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf
+++ b/CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf
@@ -93,5 +93,5 @@
[BuildOptions]
# suppress the following warnings so we do not break the build with warnings-as-errors:
# C4305: truncation from type1 to type2 (Introduced by RFC3161 Timestamp ASN.1 declarations)
- MSFT:*_*_X64_CC_FLAGS = /wd4305
+ MSFT:*_*_*_CC_FLAGS = /wd4305
GCC:*_GCC44_IA32_CC_FLAGS = "-D__cdecl=__attribute__((cdecl))" "-D__declspec(t)=__attribute__((t))"
diff --git a/CryptoPkg/Library/BaseCryptLib/Pk/CryptX509.c b/CryptoPkg/Library/BaseCryptLib/Pk/CryptX509.c
index 5abe970cce..29efc42b02 100644
--- a/CryptoPkg/Library/BaseCryptLib/Pk/CryptX509.c
+++ b/CryptoPkg/Library/BaseCryptLib/Pk/CryptX509.c
@@ -1,7 +1,7 @@
/** @file
X.509 Certificate Handler Wrapper Implementation over OpenSSL.
-Copyright (c) 2010 - 2012, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2010 - 2014, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
@@ -484,3 +484,79 @@ _Exit:
return Status;
}
+
+/**
+ Retrieve the TBSCertificate from one given X.509 certificate.
+
+ @param[in] Cert Pointer to the given DER-encoded X509 certificate.
+ @param[in] CertSize Size of the X509 certificate in bytes.
+ @param[out] TBSCert DER-Encoded To-Be-Signed certificate.
+ @param[out] TBSCertSize Size of the TBS certificate in bytes.
+
+ If Cert is NULL, then return FALSE.
+ If TBSCert is NULL, then return FALSE.
+ If TBSCertSize is NULL, then return FALSE.
+
+ @retval TRUE The TBSCertificate was retrieved successfully.
+ @retval FALSE Invalid X.509 certificate.
+
+**/
+BOOLEAN
+EFIAPI
+X509GetTBSCert (
+ IN CONST UINT8 *Cert,
+ IN UINTN CertSize,
+ OUT UINT8 **TBSCert,
+ OUT UINTN *TBSCertSize
+ )
+{
+ CONST UINT8 *Temp;
+ INTN Asn1Tag;
+ INTN ObjClass;
+ UINTN Length;
+
+ //
+ // Check input parameters.
+ //
+ if ((Cert == NULL) || (TBSCert == NULL) || (TBSCertSize == NULL)) {
+ return FALSE;
+ }
+
+ //
+ // An X.509 Certificate is: (defined in RFC3280)
+ // Certificate ::= SEQUENCE {
+ // tbsCertificate TBSCertificate,
+ // signatureAlgorithm AlgorithmIdentifier,
+ // signature BIT STRING }
+ //
+ // and
+ //
+ // TBSCertificate ::= SEQUENCE {
+ // version [0] Version DEFAULT v1,
+ // ...
+ // }
+ //
+ // So we can just ASN1-parse the x.509 DER-encoded data. If we strip
+ // the first SEQUENCE, the second SEQUENCE is the TBSCertificate.
+ //
+ Temp = Cert;
+ ASN1_get_object (&Temp, (long *)&Length, (int *)&Asn1Tag, (int *)&ObjClass, (long)CertSize);
+
+ if (Asn1Tag != V_ASN1_SEQUENCE) {
+ return FALSE;
+ }
+
+ *TBSCert = (UINT8 *)Temp;
+
+ ASN1_get_object (&Temp, (long *)&Length, (int *)&Asn1Tag, (int *)&ObjClass, (long)Length);
+ //
+ // Verify the parsed TBSCertificate is one correct SEQUENCE data.
+ //
+ if (Asn1Tag != V_ASN1_SEQUENCE) {
+ return FALSE;
+ }
+
+ *TBSCertSize = Length + (Temp - *TBSCert);
+
+ return TRUE;
+}
diff --git a/CryptoPkg/Library/BaseCryptLib/Pk/CryptX509Null.c b/CryptoPkg/Library/BaseCryptLib/Pk/CryptX509Null.c
index 5dbddca423..e1eb84d99b 100644
--- a/CryptoPkg/Library/BaseCryptLib/Pk/CryptX509Null.c
+++ b/CryptoPkg/Library/BaseCryptLib/Pk/CryptX509Null.c
@@ -2,7 +2,7 @@
X.509 Certificate Handler Wrapper Implementation which does not provide
real capabilities.
-Copyright (c) 2012, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2012 - 2014, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
@@ -178,3 +178,29 @@ X509VerifyCert (
ASSERT (FALSE);
return FALSE;
}
+
+/**
+ Retrieve the TBSCertificate from one given X.509 certificate.
+
+ Return FALSE to indicate this interface is not supported.
+
+ @param[in] Cert Pointer to the given DER-encoded X509 certificate.
+ @param[in] CertSize Size of the X509 certificate in bytes.
+ @param[out] TBSCert DER-Encoded To-Be-Signed certificate.
+ @param[out] TBSCertSize Size of the TBS certificate in bytes.
+
+ @retval FALSE This interface is not supported.
+
+**/
+BOOLEAN
+EFIAPI
+X509GetTBSCert (
+ IN CONST UINT8 *Cert,
+ IN UINTN CertSize,
+ OUT UINT8 **TBSCert,
+ OUT UINTN *TBSCertSize
+ )
+{
+ ASSERT (FALSE);
+ return FALSE;
+}
diff --git a/CryptoPkg/Library/BaseCryptLibRuntimeCryptProtocol/Pk/CryptX509Null.c b/CryptoPkg/Library/BaseCryptLibRuntimeCryptProtocol/Pk/CryptX509Null.c
index 5dbddca423..c43ca07583 100644
--- a/CryptoPkg/Library/BaseCryptLibRuntimeCryptProtocol/Pk/CryptX509Null.c
+++ b/CryptoPkg/Library/BaseCryptLibRuntimeCryptProtocol/Pk/CryptX509Null.c
@@ -2,7 +2,7 @@
X.509 Certificate Handler Wrapper Implementation which does not provide
real capabilities.
-Copyright (c) 2012, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2012 - 2014, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
@@ -178,3 +178,29 @@ X509VerifyCert (
ASSERT (FALSE);
return FALSE;
}
+
+/**
+ Retrieve the TBSCertificate from one given X.509 certificate.
+
+ Return FALSE to indicate this interface is not supported.
+
+ @param[in] Cert Pointer to the given DER-encoded X509 certificate.
+ @param[in] CertSize Size of the X509 certificate in bytes.
+ @param[out] TBSCert DER-Encoded To-Be-Signed certificate.
+ @param[out] TBSCertSize Size of the TBS certificate in bytes.
+
+ @retval FALSE This interface is not supported.
+
+**/
+BOOLEAN
+EFIAPI
+X509GetTBSCert (
+ IN CONST UINT8 *Cert,
+ IN UINTN CertSize,
+ OUT UINT8 **TBSCert,
+ OUT UINTN *TBSCertSize
+ )
+{
+ ASSERT (FALSE);
+ return FALSE;
+} \ No newline at end of file
diff --git a/EmbeddedPkg/EmbeddedPkg.dsc b/EmbeddedPkg/EmbeddedPkg.dsc
index a3a136da32..7a0e54a1cc 100644
--- a/EmbeddedPkg/EmbeddedPkg.dsc
+++ b/EmbeddedPkg/EmbeddedPkg.dsc
@@ -267,9 +267,11 @@
# FDT Support
EmbeddedPkg/Library/FdtLoadLib/FdtLoadLib.inf
+!ifndef NO_LINUX_LOADER
EmbeddedPkg/Application/AndroidFastboot/AndroidFastbootApp.inf
EmbeddedPkg/Drivers/AndroidFastbootTransportUsbDxe/FastbootTransportUsbDxe.inf
EmbeddedPkg/Drivers/AndroidFastbootTransportTcpDxe/FastbootTransportTcpDxe.inf
+!endif
# Drivers
EmbeddedPkg/Drivers/Isp1761UsbDxe/Isp1761UsbDxe.inf
diff --git a/HisiPkg/D01BoardPkg/Bds/Bds.c b/HisiPkg/D01BoardPkg/Bds/Bds.c
index 0c367fad54..deffd91a27 100644
--- a/HisiPkg/D01BoardPkg/Bds/Bds.c
+++ b/HisiPkg/D01BoardPkg/Bds/Bds.c
@@ -37,6 +37,7 @@ typedef unsigned char U8;
#define RAM_TEST_NOWORK_TAG (0x0A0A0A0A)
EFI_HANDLE mImageHandle;
+static int skip_enter_bootwrapper;
//************************************************
#define SEEK_SET 0
@@ -72,12 +73,6 @@ BootGo (
);
//************************************************
-//address of Linux in DDR
-#define TEXT_DDR_BASE 0x10c00000
-#define MONITOR_DDR_BASE 0x10c08000
-#define KERNEL_DDR_BASE 0x10008000
-#define FILESYSTEM_DDR_BASE 0x10d00000
-
//estimate size of Linux kernel,the size for copying file to DDR isn't bigger than this
#define TEXT_SIZE 0x400000
#define MONITOR_SIZE 0x400000
@@ -85,8 +80,8 @@ BootGo (
#define FILESYSTEM_SIZE 0x1800000
//actual size of copying file to DDR, it should not bigger than estimate size
-#define TEXT_COPY_SIZE 0x20000
-#define MONITOR_COPY_SIZE 0x20000
+#define TEXT_COPY_SIZE 0x8000
+#define MONITOR_COPY_SIZE 0x8000
#define KERNEL_COPY_SIZE 0xa00000
#define FILESYSTEM_COPY_SIZE 0x1800000
@@ -552,12 +547,61 @@ EFI_STATUS CopyNandToMem(void* Dest, UINT32 StartBlockNum, UINT32 LengthCopy)
}
gBS->FreePool(pucData);
return EFI_SUCCESS;
-}
-#define NANDFLASHREAD 1
-
-/**
- This function uses policy data from the platform to determine what operating
- system or system utility should be loaded and invoked. This function call
+}
+#define NANDFLASHREAD 1
+
+static void ReadBootwrapper(void)
+{
+ void *buf;
+ NAND_CMD_INFO_STRU ulNandCMDInfo = { 0 };
+ #ifdef NANDFLASHREAD
+ EFI_NAND_DRIVER_PROTOCOL *nandDriver = NULL;
+
+ gBS->LocateProtocol (&gNANDDriverProtocolGuid, NULL, (VOID *) &nandDriver);
+ ulNandCMDInfo = nandDriver->NandFlashGetCMDInfo(nandDriver);
+ #endif
+ buf = AllocatePool(ulNandCMDInfo.ulBlockSize);
+
+ (VOID)AsciiPrint("\nCopy Bootwrapper from FLASH to SRAM...");
+
+ #ifdef NANDFLASHREAD
+ CopyNandToMem(buf, TEXT_BLOCKNUM_NANDFLASH, ulNandCMDInfo.ulBlockSize);
+ memcpy((void *)TEXT_SRAM_BASE, buf, TEXT_COPY_SIZE);
+ (VOID)AsciiPrint("\nThe .text file is transmitted ok!\n");
+ #else
+ /* copy.text */
+ memcpy((void *)TEXT_SRAM_BASE, (void *)TEXT_FLASH_BASE, TEXT_COPY_SIZE);
+ (VOID)AsciiPrint("\nThe .text file is transmitted ok!\n");
+ #endif
+
+ #ifdef NANDFLASHREAD
+ /* copy .monitor */
+ CopyNandToMem(buf, MONITOR_BLOCKNUM_NANDFLASH, ulNandCMDInfo.ulBlockSize);
+ memcpy((void *)MONITOR_SRAM_BASE, buf, MONITOR_COPY_SIZE);
+ (VOID)AsciiPrint("The .monitor file is transmitted ok!\n");
+ #else
+ /* copy .monitor */
+ memcpy((void *)MONITOR_SRAM_BASE, (void *)MONITOR_FLASH_BASE, MONITOR_COPY_SIZE);
+ (VOID)AsciiPrint("The .monitor file is transmitted ok!\n");
+ #endif
+
+ gBS->FreePool(buf);
+}
+
+static void ReadNandFileSystem(void)
+{
+ #ifdef NANDFLASHREAD
+ CopyNandToMem((VOID *)FILESYSTEM_DDR_BASE, FILESYSTEM_BLOCKNUM_NANDFLASH, FILESYSTEM_COPY_SIZE);
+ (VOID)AsciiPrint("THE .FILESYSTEM FILE IS TRANSMITTED OK!\n");
+ #else
+ memcpy((VOID *)FILESYSTEM_DDR_BASE, (VOID *)FILESYSTEM_FLASH_BASE, FILESYSTEM_COPY_SIZE);
+ (VOID)AsciiPrint("THE .FILESYSTEM FILE IS TRANSMITTED OK!\n");
+ #endif
+}
+
+/**
+ This function uses policy data from the platform to determine what operating
+ system or system utility should be loaded and invoked. This function call
also optionally make the use of user input to determine the operating system
or system utility to be loaded and invoked. When the DXE Core has dispatched
all the drivers on the dispatch queue, this function is called. This
@@ -681,55 +725,17 @@ BdsEntry (
{
DEBUG((EFI_D_ERROR, "LocateProtocol:gNANDDriverProtocolGuid fail!\n"));
}
-
- //Status = BootMenuMain ();
- //ASSERT_EFI_ERROR (Status);
-
- #if 1
- /*2.copy image from FLASH to DDR,and start*/
- (VOID)AsciiPrint("\nTransmit OS from FLASH to DDR now, please wait!");
-
- #ifdef NANDFLASHREAD
- CopyNandToMem((void *)TEXT_DDR_BASE, TEXT_BLOCKNUM_NANDFLASH, TEXT_COPY_SIZE);
- (VOID)AsciiPrint("\nThe .text file is transmitted ok!\n");
- #else
- /* copy.text */
- memcpy((void *)TEXT_DDR_BASE, (void *)TEXT_FLASH_BASE, TEXT_COPY_SIZE);
- (VOID)AsciiPrint("\nThe .text file is transmitted ok!\n");
- #endif
-// /* compare text in FLASH and the same file in DDR*/
-// if (CompareMem((void *)TEXT_DDR_BASE, (void *)TEXT_FLASH_BASE, TEXT_COPY_SIZE) != 0)
-// {
-// (VOID)AsciiPrint("The .text file check fail!\n");
-// //return;
-// }
-// else
-// {
-// (VOID)AsciiPrint("The .text file check sucess!\n");
-// }
-
- #ifdef NANDFLASHREAD
- /* copy .monitor */
- CopyNandToMem((void *)MONITOR_DDR_BASE, MONITOR_BLOCKNUM_NANDFLASH, MONITOR_COPY_SIZE);
- (VOID)AsciiPrint("The .monitor file is transmitted ok!\n");
- #else
- /* copy .monitor */
- memcpy((void *)MONITOR_DDR_BASE, (void *)MONITOR_FLASH_BASE, MONITOR_COPY_SIZE);
- (VOID)AsciiPrint("The .monitor file is transmitted ok!\n");
- #endif
-// /* compare uimage in FLASH and the same file in DDR*/
-// if (CompareMem((void *)MONITOR_DDR_BASE, (void *)MONITOR_FLASH_BASE, MONITOR_COPY_SIZE) != 0)
-// {
-// (VOID)AsciiPrint("The .monitor file check fail!\n");
-// //return;
-// }
-// else
-// {
-// (VOID)AsciiPrint("The .monitor file check sucess!\n");
-// }
-
- #ifdef NANDFLASHREAD
- /* copy.kernel */
+
+ //Status = BootMenuMain ();
+ //ASSERT_EFI_ERROR (Status);
+
+ #if 1
+
+ /*2.copy image from FLASH to DDR,and start*/
+ (VOID)AsciiPrint("\nTransmit OS from FLASH to DDR now, please wait!");
+
+ #ifdef NANDFLASHREAD
+ /* copy.kernel */
CopyNandToMem((void *)KERNEL_DDR_BASE, KERNEL_BLOCKNUM_NANDFLASH, KERNEL_COPY_SIZE);
(VOID)AsciiPrint("\nThe .kernel file is transmitted ok!\n");
#else
@@ -748,14 +754,6 @@ BdsEntry (
// (VOID)AsciiPrint("The .kernel file check sucess!\n\n");
// }
- #ifdef NANDFLASHREAD
- CopyNandToMem((void *)FILESYSTEM_DDR_BASE, FILESYSTEM_BLOCKNUM_NANDFLASH, FILESYSTEM_COPY_SIZE);
- (VOID)AsciiPrint("The .filesystem file is transmitted ok!\n");
- #else
- memcpy((void *)FILESYSTEM_DDR_BASE, (void *)FILESYSTEM_FLASH_BASE, FILESYSTEM_COPY_SIZE);
- (VOID)AsciiPrint("The .filesystem file is transmitted ok!\n");
- #endif
-
// /* compare initrd in FLASH and the same file in DDR*/
// if (CompareMem((void *)FILESYSTEM_DDR_BASE, (void *)FILESYSTEM_FLASH_BASE, FILESYSTEM_COPY_SIZE) != 0)
// {
@@ -768,6 +766,7 @@ BdsEntry (
// }
/*---------------OS-----------------*/
+ skip_enter_bootwrapper = 1;
BootOptionList (&BootOptionsList);
BootGo (&BootOptionsList);
#endif
@@ -780,12 +779,64 @@ BdsEntry (
// Start the Boot Menu
Status = BootMenuMain ();
ASSERT_EFI_ERROR (Status);
-
-}
-
-EFI_BDS_ARCH_PROTOCOL gBdsProtocol = {
- BdsEntry,
-};
+
+}
+
+long bootwrapper_saved_stack;
+static void EnterBootwrapper(void)
+{
+#if !defined(__thumb__)
+#error Please compile in thumb mode
+#endif
+
+ /*
+ * This chunk of assembly enters the bootwrapper code, then
+ * immediately returns here and recovers all clobbered registers
+ */
+ asm volatile("ldr r0, =return_from_bootwrapper \n\
+ orr r0, r0, #1 \n\
+ ldr r4, =bootwrapper_saved_stack \n\
+ str sp, [r4] \n\
+ b RunBootwrapper \n\
+ return_from_bootwrapper: \n\
+ ldr r4, =bootwrapper_saved_stack \n\
+ ldr sp, [r4]"
+ : :
+ : "cc", "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8",
+ "r9", "r10", "r11", "r12", "r14");
+}
+
+/**
+ EFI Exit Event
+
+ Exiting EFI Boot Services can only mean we're bootstrapping into a real OS.
+ So let's copy the bootwrapper code into place to make sure the OS can use it.
+
+ @param[in] Event The Event that is being processed
+ @param[in] Context Event Context
+**/
+
+static EFI_EVENT EfiExitBootServicesEvent;
+
+VOID
+EFIAPI
+ExitBootServicesEvent (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+{
+ ReadBootwrapper();
+ ReadNandFileSystem();
+
+ if (skip_enter_bootwrapper)
+ return;
+
+ EnterBootwrapper();
+}
+
+EFI_BDS_ARCH_PROTOCOL gBdsProtocol = {
+ BdsEntry,
+};
EFI_STATUS
EFIAPI
@@ -802,8 +853,12 @@ BdsInitialize (
&ImageHandle,
&gEfiBdsArchProtocolGuid, &gBdsProtocol,
NULL
- );
- ASSERT_EFI_ERROR (Status);
-
- return Status;
-}
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ // Register for an ExitBootServicesEvent
+ Status = gBS->CreateEvent (EVT_SIGNAL_EXIT_BOOT_SERVICES, TPL_NOTIFY, ExitBootServicesEvent, NULL, &EfiExitBootServicesEvent);
+ ASSERT_EFI_ERROR (Status);
+
+ return Status;
+}
diff --git a/HisiPkg/D01BoardPkg/Bds/BdsInternal.h b/HisiPkg/D01BoardPkg/Bds/BdsInternal.h
index 447b8c9cd1..0b0d11ef43 100644
--- a/HisiPkg/D01BoardPkg/Bds/BdsInternal.h
+++ b/HisiPkg/D01BoardPkg/Bds/BdsInternal.h
@@ -37,6 +37,12 @@
#define BOOT_DEVICE_OPTION_MAX 300
#define BOOT_DEVICE_ADDRESS_MAX (sizeof(L"0x0000000000000000"))
+//address of Linux in DDR
+#define TEXT_SRAM_BASE 0xe00f0000
+#define MONITOR_SRAM_BASE 0xe00f8000
+#define KERNEL_DDR_BASE 0x10008000
+#define FILESYSTEM_DDR_BASE 0x10d00000
+
#define ARM_BDS_OPTIONAL_DATA_SIGNATURE SIGNATURE_32('a', 'b', 'o', 'd')
#define IS_ARM_BDS_BOOTENTRY(ptr) \
diff --git a/HisiPkg/D01BoardPkg/Bds/BootMenu.c b/HisiPkg/D01BoardPkg/Bds/BootMenu.c
index c9cc4b08d7..3cbafb5bfc 100644
--- a/HisiPkg/D01BoardPkg/Bds/BootMenu.c
+++ b/HisiPkg/D01BoardPkg/Bds/BootMenu.c
@@ -772,34 +772,28 @@ BootLinuxAtagLoader (
EFI_STATUS LoadLinuxAtSecEnd()
{
- LinuxEntry entry = (LinuxEntry)(0x10c00000);
+ LinuxEntry entry = (LinuxEntry)(TEXT_SRAM_BASE);
EFI_STATUS Status = EFI_SUCCESS;
ArmDisableDataCache();
ArmCleanInvalidateDataCache();
ArmDisableInstructionCache ();
ArmInvalidateInstructionCache ();
ArmDisableMmu();
- DEBUG(( EFI_D_ERROR, "MOVE PC 0x10c00000\n"));
+ DEBUG(( EFI_D_ERROR, "MOVE PC TEXT_SRAM_BASE\n"));
(void)entry();
return Status;
}
-EFI_STATUS
-BootGo (
- IN LIST_ENTRY *BootOptionsList
- )
+EFI_STATUS RunBootwrapper(unsigned long kernel_entry)
{
EFI_STATUS Status;
- Status = ShutdownUefiBootServices ();
- if(EFI_ERROR(Status)) {
- DEBUG((EFI_D_ERROR,"ERROR: Can not shutdown UEFI boot services. Status=0x%X\n", Status));
- }
-
*(UINTN*)(UINTN)(0xe302b000 + 0x18) = 0;
*(UINTN*)(UINTN)(0xe302b000 + 0x1c) = 0;
-
- *(volatile UINT32 *)(0xe0000000 + 0x100) = 0x10c00000;
+
+ *(volatile UINT32 *)(0xe0000000 + 0x100) = TEXT_SRAM_BASE;
+ *(volatile UINT32 *)(TEXT_SRAM_BASE + 0x800) = kernel_entry;
+
ArmCleanDataCache();
*(UINT8*)(0xf4007000) = 'G';
Status = LoadLinuxAtSecEnd();
@@ -811,6 +805,23 @@ BootGo (
return Status;
}
+EFI_STATUS
+BootGo (
+ IN LIST_ENTRY *BootOptionsList
+ )
+{
+ EFI_STATUS Status;
+
+ Status = ShutdownUefiBootServices ();
+ if(EFI_ERROR(Status)) {
+ DEBUG((EFI_D_ERROR,"ERROR: Can not shutdown UEFI boot services. Status=0x%X\n", Status));
+ }
+
+ Status = RunBootwrapper(KERNEL_DDR_BASE);
+
+ return Status;
+}
+
struct BOOT_MAIN_ENTRY {
CONST CHAR16* Description;
EFI_STATUS (*Callback) (IN LIST_ENTRY *BootOptionsList);
diff --git a/HisiPkg/D01BoardPkg/D01BoardPkg.dsc b/HisiPkg/D01BoardPkg/D01BoardPkg.dsc
index fcf09d0a64..aaa5ebb05b 100644
--- a/HisiPkg/D01BoardPkg/D01BoardPkg.dsc
+++ b/HisiPkg/D01BoardPkg/D01BoardPkg.dsc
@@ -22,7 +22,11 @@
PLATFORM_GUID = 3a91a0f8-3af4-409d-a71d-a199dc134357
PLATFORM_VERSION = 0.1
DSC_SPECIFICATION = 0x00010005
+!ifdef EDK2_OUT_DIR
+ OUTPUT_DIRECTOY = Build/D01-IntelBds
+!else
OUTPUT_DIRECTORY = Build/D01
+!endif
SUPPORTED_ARCHITECTURES = ARM
BUILD_TARGETS = DEBUG|RELEASE
SKUID_IDENTIFIER = DEFAULT
@@ -48,6 +52,13 @@
UdpIoLib|MdeModulePkg/Library/DxeUdpIoLib/DxeUdpIoLib.inf
IpIoLib|MdeModulePkg/Library/DxeIpIoLib/DxeIpIoLib.inf
+!ifdef INTEL_BDS
+ CapsuleLib|MdeModulePkg/Library/DxeCapsuleLibNull/DxeCapsuleLibNull.inf
+ GenericBdsLib|IntelFrameworkModulePkg/Library/GenericBdsLib/GenericBdsLib.inf
+ PlatformBdsLib|ArmPlatformPkg/Library/PlatformIntelBdsLib/PlatformIntelBdsLib.inf
+ CustomizedDisplayLib|MdeModulePkg/Library/CustomizedDisplayLib/CustomizedDisplayLib.inf
+!endif
+
[LibraryClasses.common.SEC]
ArmLib|ArmPkg/Library/ArmLib/ArmV7/ArmV7LibSec.inf
ArmPlatformSecLib|HisiPkg/D01BoardPkg/Library/D01SecLibRTSM/D01SecLib.inf
@@ -140,6 +151,7 @@
gArmTokenSpaceGuid.PcdGicDistributorBase|0xe0C01000
gArmTokenSpaceGuid.PcdGicInterruptInterfaceBase|0xe0C02000
+!ifndef NO_LINUX_LOADER
#
# ARM OS Loader
#
@@ -152,6 +164,7 @@
gArmPlatformTokenSpaceGuid.PcdDefaultBootInitrdPath|L"VenMsg(06ED4DD0-FF78-11D3-BDC4-00A0C94053D1,0000000000000000)/initrd"
gArmPlatformTokenSpaceGuid.PcdDefaultBootArgument|"mem=256M console=ttyAMA0,115200"
gArmPlatformTokenSpaceGuid.PcdDefaultBootType|1
+!endif
# Use the serial console (ConIn & ConOut) and the Graphic driver (ConOut)
#gArmPlatformTokenSpaceGuid.PcdDefaultConOutPaths|L"VenHw(D3987D4B-971A-435F-8CAF-4967EB627241)/Uart(115200,8,N,1)/VenPcAnsi();VenHw(407B4008-BF5B-11DF-9547-CF16E0D72085)"
@@ -166,7 +179,7 @@
#
# ARM Architectual Timer Frequency
#
- gArmTokenSpaceGuid.PcdArmArchTimerFreqInHz|168750000
+ gArmTokenSpaceGuid.PcdArmArchTimerFreqInHz|50000000
gHwTokenSpaceGuid.PcdNorFlashBase|0xf0000000
@@ -176,6 +189,12 @@
gArmTokenSpaceGuid.PcdTimer0InterruptNum|130
gEfiMdeModulePkgTokenSpaceGuid.PcdFirmwareVersionString|L"EVB_SECURE_UEFI_BIOS"
+
+!ifdef INTEL_BDS
+ gEfiMdeModulePkgTokenSpaceGuid.PcdResetOnMemoryTypeInformationChange|FALSE
+ gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdShellFile|{ 0x83, 0xA5, 0x04, 0x7C, 0x3E, 0x9E, 0x1C, 0x4F, 0xAD, 0x65, 0xE0, 0x52, 0x68, 0xD0, 0xB4, 0xD1 }
+!endif
+
################################################################################
#
@@ -324,10 +343,16 @@
# Bds
#
MdeModulePkg/Universal/DevicePathDxe/DevicePathDxe.inf
+!ifdef INTEL_BDS
+ MdeModulePkg/Universal/DisplayEngineDxe/DisplayEngineDxe.inf
+ MdeModulePkg/Universal/SetupBrowserDxe/SetupBrowserDxe.inf
+ IntelFrameworkModulePkg/Universal/BdsDxe/BdsDxe.inf
+!else
HisiPkg/D01BoardPkg/Bds/Bds.inf
-
+!endif
+!ifndef NO_LINUX_LOADER
HisiPkg/Drivers/LinuxAtagList/LinuxAtagList.inf
-
+!endif
#HisiPkg/Drivers/AtaAtapiPassThru/AtaAtapiPassThru.inf
MdeModulePkg/Bus/Ata/AtaBusDxe/AtaBusDxe.inf
diff --git a/HisiPkg/D01BoardPkg/D01BoardPkg.dsc.inc b/HisiPkg/D01BoardPkg/D01BoardPkg.dsc.inc
index d915c35484..85fea4ff9c 100644
--- a/HisiPkg/D01BoardPkg/D01BoardPkg.dsc.inc
+++ b/HisiPkg/D01BoardPkg/D01BoardPkg.dsc.inc
@@ -107,7 +107,10 @@
ArmSmcLib|ArmPkg/Library/ArmSmcLib/ArmSmcLib.inf
# BDS Libraries
+ ArmBdsHelperLib|ArmPkg/Library/ArmBdsHelperLib/ArmBdsHelperLib.inf
+!ifndef INTEL_BDS
BdsLib|ArmPkg/Library/BdsLib/BdsLib.inf
+!endif
FdtLib|EmbeddedPkg/Library/FdtLib/FdtLib.inf
ArmGenericTimerCounterLib|ArmPkg/Library/ArmGenericTimerPhyCounterLib/ArmGenericTimerPhyCounterLib.inf
diff --git a/HisiPkg/D01BoardPkg/D01BoardPkg.fdf b/HisiPkg/D01BoardPkg/D01BoardPkg.fdf
index f191849e7f..0dd7fdb77b 100644
--- a/HisiPkg/D01BoardPkg/D01BoardPkg.fdf
+++ b/HisiPkg/D01BoardPkg/D01BoardPkg.fdf
@@ -148,7 +148,9 @@ READ_LOCK_STATUS = TRUE
INF MdeModulePkg/Universal/WatchdogTimerDxe/WatchdogTimer.inf
INF HisiPkg/Drivers/WatchDogDriver/WatchDogDriver.inf
+!ifndef NO_LINUX_LOADER
INF HisiPkg/Drivers/LinuxAtagList/LinuxAtagList.inf
+!endif
#
# Semi-hosting filesystem
@@ -209,7 +211,13 @@ READ_LOCK_STATUS = TRUE
# Bds
#
INF MdeModulePkg/Universal/DevicePathDxe/DevicePathDxe.inf
+!ifdef INTEL_BDS
+ INF MdeModulePkg/Universal/DisplayEngineDxe/DisplayEngineDxe.inf
+ INF MdeModulePkg/Universal/SetupBrowserDxe/SetupBrowserDxe.inf
+ INF IntelFrameworkModulePkg/Universal/BdsDxe/BdsDxe.inf
+!else
INF HisiPkg/D01BoardPkg/Bds/Bds.inf
+!endif
[FV.FVMAIN_COMPACT]
FvAlignment = 8
diff --git a/HisiPkg/D01BoardPkg/Library/D01SecLibRTSM/RTSMArmD01SecLib.lib b/HisiPkg/D01BoardPkg/Library/D01SecLibRTSM/RTSMArmD01SecLib.lib
index a6b5ba0053..a52a0605cf 100644
--- a/HisiPkg/D01BoardPkg/Library/D01SecLibRTSM/RTSMArmD01SecLib.lib
+++ b/HisiPkg/D01BoardPkg/Library/D01SecLibRTSM/RTSMArmD01SecLib.lib
Binary files differ
diff --git a/IntelFrameworkModulePkg/Csm/BiosThunk/KeyboardDxe/BiosKeyboard.c b/IntelFrameworkModulePkg/Csm/BiosThunk/KeyboardDxe/BiosKeyboard.c
index 4ee20df1f7..8c7019f4f6 100644
--- a/IntelFrameworkModulePkg/Csm/BiosThunk/KeyboardDxe/BiosKeyboard.c
+++ b/IntelFrameworkModulePkg/Csm/BiosThunk/KeyboardDxe/BiosKeyboard.c
@@ -1,7 +1,7 @@
/** @file
ConsoleOut Routines that speak VGA.
-Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions
@@ -2202,15 +2202,18 @@ BiosKeyboardSetState (
Status = KeyboardWrite (BiosKeyboardPrivate, 0xed);
if (EFI_ERROR (Status)) {
- return EFI_DEVICE_ERROR;
+ Status = EFI_DEVICE_ERROR;
+ goto Exit;
}
Status = KeyboardWaitForValue (BiosKeyboardPrivate, 0xfa, KEYBOARD_WAITFORVALUE_TIMEOUT);
if (EFI_ERROR (Status)) {
- return EFI_DEVICE_ERROR;
+ Status = EFI_DEVICE_ERROR;
+ goto Exit;
}
Status = KeyboardWrite (BiosKeyboardPrivate, Command);
if (EFI_ERROR (Status)) {
- return EFI_DEVICE_ERROR;
+ Status = EFI_DEVICE_ERROR;
+ goto Exit;
}
//
// Call Legacy BIOS Protocol to set whatever is necessary
@@ -2219,6 +2222,7 @@ BiosKeyboardSetState (
Status = EFI_SUCCESS;
+Exit:
//
// Leave critical section and return
//
diff --git a/IntelFrameworkModulePkg/Library/GenericBdsLib/BdsBoot.c b/IntelFrameworkModulePkg/Library/GenericBdsLib/BdsBoot.c
index 3a74d24613..33e2902197 100644
--- a/IntelFrameworkModulePkg/Library/GenericBdsLib/BdsBoot.c
+++ b/IntelFrameworkModulePkg/Library/GenericBdsLib/BdsBoot.c
@@ -1042,7 +1042,7 @@ BdsCreateDevOrder (
Status = gRT->SetVariable (
VAR_LEGACY_DEV_ORDER,
&gEfiLegacyDevOrderVariableGuid,
- EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
+ EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE,
TotalSize,
DevOrder
);
@@ -1363,7 +1363,7 @@ BdsUpdateLegacyDevOrder (
Status = gRT->SetVariable (
VAR_LEGACY_DEV_ORDER,
&gEfiLegacyDevOrderVariableGuid,
- EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
+ EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE,
TotalSize,
NewDevOrder
);
diff --git a/IntelFrameworkPkg/Library/PeiHobLibFramework/HobLib.c b/IntelFrameworkPkg/Library/PeiHobLibFramework/HobLib.c
index 898d07b6ff..b41536e2a1 100644
--- a/IntelFrameworkPkg/Library/PeiHobLibFramework/HobLib.c
+++ b/IntelFrameworkPkg/Library/PeiHobLibFramework/HobLib.c
@@ -304,45 +304,45 @@ BuildModuleHob (
Hob->EntryPoint = EntryPoint;
}
-/**
+/**
Builds a HOB that describes a chunk of system memory with Owner GUID.
-
- This function builds a HOB that describes a chunk of system memory.
- It can only be invoked during PEI phase;
- for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.
-
- If there is no additional space for HOB creation, then ASSERT().
-
- @param ResourceType The type of resource described by this HOB.
- @param ResourceAttribute The resource attributes of the memory described by this HOB.
- @param PhysicalStart The 64 bit physical address of memory described by this HOB.
- @param NumberOfBytes The length of the memory described by this HOB in bytes.
+
+ This function builds a HOB that describes a chunk of system memory.
+ It can only be invoked during PEI phase;
+ for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.
+
+ If there is no additional space for HOB creation, then ASSERT().
+
+ @param ResourceType The type of resource described by this HOB.
+ @param ResourceAttribute The resource attributes of the memory described by this HOB.
+ @param PhysicalStart The 64 bit physical address of memory described by this HOB.
+ @param NumberOfBytes The length of the memory described by this HOB in bytes.
@param OwnerGUID GUID for the owner of this resource.
-
-**/
-VOID
-EFIAPI
-BuildResourceDescriptorWithOwnerHob (
- IN EFI_RESOURCE_TYPE ResourceType,
- IN EFI_RESOURCE_ATTRIBUTE_TYPE ResourceAttribute,
- IN EFI_PHYSICAL_ADDRESS PhysicalStart,
- IN UINT64 NumberOfBytes,
- IN EFI_GUID *OwnerGUID
- )
-{
- EFI_HOB_RESOURCE_DESCRIPTOR *Hob;
+
+**/
+VOID
+EFIAPI
+BuildResourceDescriptorWithOwnerHob (
+ IN EFI_RESOURCE_TYPE ResourceType,
+ IN EFI_RESOURCE_ATTRIBUTE_TYPE ResourceAttribute,
+ IN EFI_PHYSICAL_ADDRESS PhysicalStart,
+ IN UINT64 NumberOfBytes,
+ IN EFI_GUID *OwnerGUID
+ )
+{
+ EFI_HOB_RESOURCE_DESCRIPTOR *Hob;
Hob = InternalPeiCreateHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR, (UINT16) sizeof (EFI_HOB_RESOURCE_DESCRIPTOR));
if (Hob == NULL) {
return;
}
-
- Hob->ResourceType = ResourceType;
- Hob->ResourceAttribute = ResourceAttribute;
- Hob->PhysicalStart = PhysicalStart;
- Hob->ResourceLength = NumberOfBytes;
-
- CopyGuid (&Hob->Owner, OwnerGUID);
+
+ Hob->ResourceType = ResourceType;
+ Hob->ResourceAttribute = ResourceAttribute;
+ Hob->PhysicalStart = PhysicalStart;
+ Hob->ResourceLength = NumberOfBytes;
+
+ CopyGuid (&Hob->Owner, OwnerGUID);
}
/**
diff --git a/IntelFspPkg/FspDxeIpl/DxeIpl.c b/IntelFspPkg/FspDxeIpl/DxeIpl.c
index 24e6ef75cd..cddc29e054 100644
--- a/IntelFspPkg/FspDxeIpl/DxeIpl.c
+++ b/IntelFspPkg/FspDxeIpl/DxeIpl.c
@@ -424,6 +424,12 @@ DxeLoadCore (
DEBUG ((DEBUG_INFO | DEBUG_INIT, "FSP HOB is located at 0x%08X\n", HobList));
//
+ // End of PEI phase signal
+ //
+ Status = PeiServicesInstallPpi (&gEndOfPeiSignalPpi);
+ ASSERT_EFI_ERROR (Status);
+
+ //
// Give control back to bootloader after FspInit
//
DEBUG ((DEBUG_INFO | DEBUG_INIT, "FSP is waiting for NOTIFY\n"));
@@ -434,11 +440,6 @@ DxeLoadCore (
//
FspWaitForNotify ();
- //
- // End of PEI phase signal
- //
- Status = PeiServicesInstallPpi (&gEndOfPeiSignalPpi);
- ASSERT_EFI_ERROR (Status);
//
// Give control back to the boot loader framework caller
diff --git a/IntelFspPkg/FspSecCore/Ia32/FspApiEntry.asm b/IntelFspPkg/FspSecCore/Ia32/FspApiEntry.asm
index 8ad9744ab4..219b0ee9c1 100644
--- a/IntelFspPkg/FspSecCore/Ia32/FspApiEntry.asm
+++ b/IntelFspPkg/FspSecCore/Ia32/FspApiEntry.asm
@@ -214,16 +214,21 @@ advance_fixed_size:
check_address:
; Is valid Microcode start point ?
- cmp dword ptr [esi], 0ffffffffh
+ cmp dword ptr [esi].ucode_hdr.version, 0ffffffffh
jz done
+ ; Is automatic size detection ?
+ mov eax, [esp].LOAD_UCODE_PARAMS.ucode_code_size
+ cmp eax, 0ffffffffh
+ jz @f
+
; Address >= microcode region address + microcode region size?
- mov eax, [esp].LOAD_UCODE_PARAMS.ucode_code_addr
- add eax, [esp].LOAD_UCODE_PARAMS.ucode_code_size
+ add eax, [esp].LOAD_UCODE_PARAMS.ucode_code_addr
cmp esi, eax
jae done ;Jif address is outside of ucode region
jmp check_main_header
+@@:
load_check:
; Get the revision of the current microcode update loaded
mov ecx, MSR_IA32_BIOS_SIGN_ID
diff --git a/IntelFspPkg/FspSecCore/Ia32/FspApiEntry.s b/IntelFspPkg/FspSecCore/Ia32/FspApiEntry.s
index 433ef921c4..fb09fedb29 100644
--- a/IntelFspPkg/FspSecCore/Ia32/FspApiEntry.s
+++ b/IntelFspPkg/FspSecCore/Ia32/FspApiEntry.s
@@ -15,310 +15,438 @@
#
#------------------------------------------------------------------------------
-#.INCLUDE "UcodeLoad.inc"
+#.INCLUDE "UcodeLoadGcc.inc" - begin
+
+.equ MSR_IA32_PLATFORM_ID, 0x00000017
+.equ MSR_IA32_BIOS_UPDT_TRIG, 0x00000079
+.equ MSR_IA32_BIOS_SIGN_ID, 0x0000008b
+
+Ucode:
+.equ UcodeVersion, 0x0000
+.equ UcodeRevision, 0x0004
+.equ UcodeDate, 0x0008
+.equ UcodeProcessor, 0x000C
+.equ UcodeChecksum, 0x0010
+.equ UcodeLoader, 0x0014
+.equ UcodeRsvd, 0x0018
+UcodeEnd:
+
+UcodeHdr:
+.equ UcodeHdrVersion, 0x0000
+.equ UcodeHdrRevision, 0x0004
+.equ UcodeHdrDate, 0x0008
+.equ UcodeHdrProcessor, 0x000c
+.equ UcodeHdrChecksum, 0x0010
+.equ UcodeHdrLoader, 0x0014
+.equ UcodeHdrFlags, 0x0018
+.equ UcodeHdrDataSize, 0x001C
+.equ UcodeHdrTotalSize, 0x0020
+.equ UcodeHdrRsvd, 0x0024
+UcodeHdrEnd:
+.equ UcodeHdrLength, 0x0030 # UcodeHdrLength = UcodeHdrEnd - UcodeHdr
+
+
+ExtSigHdr:
+.equ ExtSigHdrCount, 0x0000
+.equ ExtSigHdrChecksum, 0x0004
+.equ rsvd, 0x0008
+ExtSigHdrEnd:
+.equ ExtSigHdrLength, 0x0014 #ExtSigHdrLength = ExtSigHdrEnd - ExtSigHdr
+
+ExtSig:
+.equ ExtSigProcessor, 0x0000
+.equ ExtSigFlags, 0x0004
+.equ ExtSigChecksum, 0x0008
+ExtSigEnd:
+.equ ExtSigLength, 0x000C #ExtSigLength = ExtSigEnd - ExtSig
+
+LoadUcodeParams:
+.equ LoadUcodeParamsUcodeCodeAddr, 0x0000
+.equ LoadUcodeParamsUcodeCodeSize, 0x0004
+LoadUcodeParamsEnd:
+
+#.INCLUDE "UcodeLoadGcc.inc" - end
+
+#.INCLUDE "SaveRestoreSseGcc.inc" - begin
+.macro SAVE_REGS
+ pinsrw $0x00, %ebp, %xmm7
+ ror $0x10, %ebp
+ pinsrw $0x01, %ebp, %xmm7
+ ror $0x10, %ebp
#
-# Following are fixed PCDs
+ pinsrw $0x02, %ebx, %xmm7
+ ror $0x10, %ebx
+ pinsrw $0x03, %ebx, %xmm7
+ ror $0x10, %ebx
#
-
-.equ MSR_IA32_PLATFORM_ID, 0x000000017
-.equ MSR_IA32_BIOS_UPDT_TRIG, 0x000000079
-.equ MSR_IA32_BIOS_SIGN_ID, 0x00000008b
-
-ASM_GLOBAL ASM_PFX(_gPcd_FixedAtBuild_PcdTemporaryRamBase)
-ASM_GLOBAL ASM_PFX(_gPcd_FixedAtBuild_PcdTemporaryRamSize)
-ASM_GLOBAL ASM_PFX(_gPcd_FixedAtBuild_PcdFspTemporaryRamSize)
-ASM_GLOBAL ASM_PFX(_gPcd_FixedAtBuild_PcdFspAreaSize)
-
-
+ pinsrw $0x04, %esi, %xmm7
+ ror $0x10, %esi
+ pinsrw $0x05, %esi, %xmm7
+ ror $0x10, %esi
#
-# Following functions will be provided in C
+ pinsrw $0x06, %edi, %xmm7
+ ror $0x10, %edi
+ pinsrw $0x07, %edi, %xmm7
+ ror $0x10, %edi
#
-#EXTERNDEF SecStartup:PROC
-#EXTERNDEF FspApiCallingCheck:PROC
+ pinsrw $0x00, %esp, %xmm6
+ ror $0x10, %esp
+ pinsrw $0x01, %esp, %xmm6
+ ror $0x10, %esp
+.endm
+.macro LOAD_REGS
+ pshufd $0xe4, %xmm7, %xmm7
+ movd %xmm7, %ebp
+ pshufd $0xe4, %xmm7, %xmm7
#
-# Following functions will be provided in PlatformSecLib
+ pshufd $0x39, %xmm7, %xmm7
+ movd %xmm7, %ebx
+ pshufd $0x93, %xmm7, %xmm7
#
-#EXTERNDEF GetFspBaseAddress:PROC
-#EXTERNDEF GetBootFirmwareVolumeOffset:PROC
-#EXTERNDEF PlatformTempRamInit:PROC
-#EXTERNDEF Pei2LoaderSwitchStack:PROC
-#EXTERN FspSelfCheck(FspSelfCheckDflt):PROC
-#EXTERN PlatformBasicInit(PlatformBasicInitDflt):PROC
-
+ pshufd $0x4e, %xmm7, %xmm7
+ movd %xmm7, %esi
+ pshufd $0x4e, %xmm7, %xmm7
#
-# Define the data length that we saved on the stack top
+ pshufd $0x93, %xmm7, %xmm7
+ movd %xmm7, %edi
+ pshufd $0x39, %xmm7, %xmm7
#
-.equ DATA_LEN_OF_PER0, 0x018
-.equ DATA_LEN_OF_MCUD, 0x018
-.equ DATA_LEN_AT_STACK_TOP, (DATA_LEN_OF_PER0 + DATA_LEN_OF_MCUD + 4)
+ movd %xmm6, %esp
+.endm
-#
-# Define SSE macros
-#
-.macro ENABLE_SSE
- movl %cr4, %eax
- orl $0x00000600,%eax # Set OSFXSR bit (bit #9) & OSXMMEXCPT bit (bit #10)
- movl %eax,%cr4
+.macro LOAD_EAX
+ pshufd $0x39, %xmm6, %xmm6
+ movd %xmm6, %eax
+ pshufd $0x93, %xmm6, %xmm6
.endm
-.macro SAVE_REGS
- movd %ebp, %xmm7
- pshufd $0x93, %xmm7, %xmm7
- movd %ebx, %xmm6
- por %xmm6, %xmm7
- pshufd $0x93, %xmm7, %xmm7
- movd %esi,%xmm6
- por %xmm6, %xmm7
- pshufd $0x93, %xmm7, %xmm7
- movd %edi, %xmm6
- por %xmm6, %xmm7
- movd %esp, %xmm6
+.macro LOAD_EDX
+ pshufd $0xe4, %xmm6, %xmm6
+ movd %xmm6, %edx
+ pshufd $0xe4, %xmm6, %xmm6
.endm
-.macro LOAD_REGS
- movd %xmm6, %esp
- movd %xmm7, %edi
- pshufd $0x39,%xmm7, %xmm7
- movd %xmm7, %esi
- pshufd $0x39,%xmm7, %xmm7
- movd %xmm7, %ebx
- pshufd $0x39, %xmm7, %xmm7
- movd %xmm7, %ebp
+.macro SAVE_EAX
+ pinsrw $0x02, %eax, %xmm6
+ ror $0x10, %eax
+ pinsrw $0x03, %eax, %xmm6
+ ror $0x10, %eax
+.endm
+
+.macro SAVE_EDX
+ pinsrw $0x04, %edx, %xmm6
+ ror $0x10, %edx
+ pinsrw $0x05, %edx, %xmm6
+ ror $0x10, %edx
.endm
.macro LOAD_ESP
movd %xmm6, %esp
.endm
+.macro ENABLE_SSE
+ movl %cr4, %eax
+ orl $0x00000600, %eax # Set OSFXSR bit (bit #9) & OSXMMEXCPT bit (bit #10)
+ movl %eax,%cr4
+.endm
+
+#.INCLUDE "SaveRestoreSseGcc.inc" - end
+
+
+#
+# Following are fixed PCDs
+#
+ASM_GLOBAL ASM_PFX(_gPcd_FixedAtBuild_PcdTemporaryRamBase)
+ASM_GLOBAL ASM_PFX(_gPcd_FixedAtBuild_PcdTemporaryRamSize)
+ASM_GLOBAL ASM_PFX(_gPcd_FixedAtBuild_PcdFspTemporaryRamSize)
+
+#
+# Following functions will be provided in C
+#
+ASM_GLOBAL ASM_PFX(FspImageSizeOffset)
+ASM_GLOBAL ASM_PFX(SecStartup)
+ASM_GLOBAL ASM_PFX(FspApiCallingCheck)
+
+#
+# Following functions will be provided in PlatformSecLib
+#
+ASM_GLOBAL ASM_PFX(GetBootFirmwareVolumeOffset)
+ASM_GLOBAL ASM_PFX(Pei2LoaderSwitchStack)
+
+
+#
+# Define the data length that we saved on the stack top
+#
+.equ DATA_LEN_OF_PER0, 0x018
+.equ DATA_LEN_OF_MCUD, 0x018
+.equ DATA_LEN_AT_STACK_TOP, (DATA_LEN_OF_PER0 + DATA_LEN_OF_MCUD + 4)
+
+#------------------------------------------------------------------------------
+# FspSelfCheckDflt
+# Inputs:
+# eax -> Return address
+# Outputs:
+# eax -> 0 - Successful, Non-zero - Failed.
+# Register Usage:
+# eax is cleared and ebp is used for return address.
+# All others reserved.
#------------------------------------------------------------------------------
ASM_GLOBAL ASM_PFX(FspSelfCheckDflt)
ASM_PFX(FspSelfCheckDflt):
- # Inputs:
- # eax -> Return address
- # Outputs:
- # eax -> 0 - Successful, Non-zero - Failed.
- # Register Usage:
- # eax is cleared and ebp is used for return address.
- # All others reserved.
-
+ #
# Save return address to EBP
+ #
movl %eax, %ebp
xorl %eax, %eax
-exit:
+
+FspSelfCheckDfltExit:
jmp *%ebp
-#FspSelfCheckDflt ENDP
+
+#------------------------------------------------------------------------------
+# PlatformBasicInitDflt
+# Inputs:
+# eax -> Return address
+# Outputs:
+# eax -> 0 - Successful, Non-zero - Failed.
+# Register Usage:
+# eax is cleared and ebp is used for return address.
+# All others reserved.
#------------------------------------------------------------------------------
ASM_GLOBAL ASM_PFX(PlatformBasicInitDflt)
ASM_PFX(PlatformBasicInitDflt):
- # Inputs:
- # eax -> Return address
- # Outputs:
- # eax -> 0 - Successful, Non-zero - Failed.
- # Register Usage:
- # eax is cleared and ebp is used for return address.
- # All others reserved.
-
+ #
# Save return address to EBP
+ #
movl %eax, %ebp
xorl %eax, %eax
-exit2:
+
+PlatformBasicInitDfltExit:
jmp *%ebp
-#PlatformBasicInitDflt ENDP
+
#------------------------------------------------------------------------------
+# LoadUcode
+#
+# Inputs:
+# esp -> LOAD_UCODE_PARAMS pointer
+# Register Usage:
+# esp Preserved
+# All others destroyed
+# Assumptions:
+# No memory available, stack is hard-coded and used for return address
+# Executed by SBSP and NBSP
+# Beginning of microcode update region starts on paragraph boundary
+#------------------------------------------------------------------------------
ASM_GLOBAL ASM_PFX(LoadUcode)
-ASM_PFX(LoadUcode):
- # Inputs:
- # esp -> LOAD_UCODE_PARAMS pointer
- # Register Usage:
- # esp Preserved
- # All others destroyed
- # Assumptions:
- # No memory available, stack is hard-coded and used for return address
- # Executed by SBSP and NBSP
- # Beginning of microcode update region starts on paragraph boundary
-
- #
+ASM_PFX(LoadUcode):
#
# Save return address to EBP
+ #
movl %eax, %ebp
- cmpl $0, %esp
- jz paramerror
- movl (%esp), %eax #dword ptr [] Parameter pointer
- cmpl $0, %eax
- jz paramerror
+ cmpl $0x00, %esp
+ jz ParamError
+ movl (%esp), %eax #dword ptr [] Parameter pointer
+ cmpl $0x00, %eax
+ jz ParamError
movl %eax, %esp
- movl (%esp), %esi #LOAD_UCODE_PARAMS.ucode_code_addr
- cmpl $0, %esi
- jnz L0
+ movl LoadUcodeParamsUcodeCodeAddr(%esp), %esi #mov esi, [esp].LOAD_UCODE_PARAMS.ucode_code_addr
+ cmpl $0x00, %esi
+ jnz CheckMainHeader
-paramerror:
- movl $0x080000002, %eax
- jmp exit4
+ParamError:
+ movl $0x080000002, %eax
+ jmp LoadUcodeExit
- movl (%esp), %esi #.LOAD_UCODE_PARAMS.ucode_code_addr
-
-check_main_header:
+CheckMainHeader:
+ #
# Get processor signature and platform ID from the installed processor
# and save into registers for later use
# ebx = processor signature
# edx = platform ID
- movl $1, %eax
+ #
+ movl $0x01, %eax
cpuid
movl %eax, %ebx
- movl MSR_IA32_PLATFORM_ID, %ecx
+ movl $MSR_IA32_PLATFORM_ID, %ecx
rdmsr
- movl %edx, %ecx
- #--------------------------------------------------------------------------------------------------------------------
- shrl $18, %ecx #($50-$32)
- andl $0x7, %ecx
- movl $1, %edx
- shll %cl,%edx
+ movl %edx, %ecx
+ shrl $0x12, %ecx #($50-$32)
+ andl $0x07, %ecx
+ movl $0x01, %edx
+ shll %cl,%edx
+ #
# Current register usage
# esp -> stack with paramters
# esi -> microcode update to check
# ebx = processor signature
# edx = platform ID
+ #
+ #
# Check for valid microcode header
# Minimal test checking for header version and loader version as 1
- movl $1, %eax
- cmpl %eax, (%esi) #.ucode_hdr.version
- jne advance_fixed_size
- cmpl %eax, 0x18(%esi) #.ucode_hdr.loader
- jne advance_fixed_size
+ #
+ movl $0x01, %eax
+ cmpl %eax, UcodeHdrVersion(%esi) #cmp [esi].ucode_hdr.version, eax
+ jne AdvanceFixedSize
+ cmpl %eax, UcodeHdrLoader(%esi) #cmp [esi].ucode_hdr.loader, eax
+ jne AdvanceFixedSize
+ #
# Check if signature and plaform ID match
- #--------------------------------------------------------------------------------------------------------------------------
- cmpl 0x10(%esi), %ebx #(%esi).ucode_hdr.processor
- jne L0
- testl 0x1c(%esi) , %edx #(%esi).ucode_hdr.flags
- jnz load_check # Jif signature and platform ID match
+ #
+ cmpl UcodeHdrProcessor(%esi), %ebx #cmp ebx, [esi].ucode_hdr.processor
+ jne LoadUcodeL0
+ testl UcodeHdrFlags(%esi), %edx #test edx, [esi].ucode_hdr.flags
+ jnz LoadCheck #Jif signature and platform ID match
-L0:
+LoadUcodeL0:
+ #
# Check if extended header exists
# First check if total_size and data_size are valid
- xorl %eax, %eax
- cmpl %eax,0x24(%esi) #(%esi).ucode_hdr.total_size
- je next_microcode
- cmpl %eax,0x20(%esi) #(%esi) .ucode_hdr.data_size
- je next_microcode
+ #
+ xorl %eax, %eax
+ cmpl %eax, UcodeHdrTotalSize(%esi) #cmp [esi].ucode_hdr.total_size, eax
+ je NextMicrocode
+ cmpl %eax, UcodeHdrDataSize(%esi) #cmp [esi].ucode_hdr.data_size, eax
+ je NextMicrocode
+ #
# Then verify total size - sizeof header > data size
- movl 0x24(%esi), %ecx #(%esi).ucode_hdr.total_size
- subl $0x30, %ecx #sizeof ucode_hdr = 48
- cmpl 0x20(%esi), %ecx #(%esi).ucode_hdr.data_size
- jz load_check
- jb next_microcode # Jif extended header does not exist
-
- # Check if total size fits in microcode region
- movl %esi , %edi
- addl 0x24(%esi), %edi # (%esi).ucode_hdr.total_size
- movl (%esp), %ecx # (%esp).LOAD_UCODE_PARAMS.ucode_code_addr
- addl 4(%esp), %ecx #.LOAD_UCODE_PARAMS.ucode_code_size
- cmpl %ecx , %edi
- xorl %eax, %eax
- ja exit4 # Jif address is outside of ucode region
+ #
+ movl UcodeHdrTotalSize(%esi), %ecx #mov ecx, [esi].ucode_hdr.total_size
+ subl $UcodeHdrLength, %ecx #sub ecx, sizeof ucode_hdr
+ cmpl UcodeHdrDataSize(%esi), %ecx #cmp ecx, [esi].ucode_hdr.data_size
+ jle NextMicrocode
+ #
# Set edi -> extended header
- movl %esi , %edi
- addl $0x30 , %edi #sizeof ucode_hdr = 48
- addl 0x20(%esi), %edi #%esi.ucode_hdr.data_size
+ #
+ movl %esi, %edi
+ addl $UcodeHdrLength, %edi #add edi, sizeof ucode_hdr
+ addl UcodeHdrDataSize(%esi), %edi #add edi, [esi].ucode_hdr.data_size
+ #
# Get count of extended structures
- movl (%edi), %ecx #(%edi).ext_sig_hdr.count
+ #
+ movl ExtSigHdrCount(%edi), %ecx #mov ecx, [edi].ext_sig_hdr.count
+ #
# Move pointer to first signature structure
- addl $0x20, %edi # sizeof ext_sig_hdr = 20
+ #
+ addl ExtSigHdrLength, %edi #add edi, sizeof ext_sig_hdr
-check_ext_sig:
+CheckExtSig:
+ #
# Check if extended signature and platform ID match
- cmpl %ebx, (%edi) #[edi].ext_sig.processor
- jne L1
- test %edx, 4(%edi) #[edi].ext_sig.flags
- jnz load_check # Jif signature and platform ID match
-L9:
+ #
+ cmpl %ebx, ExtSigProcessor(%edi) #cmp [edi].ext_sig.processor, ebx
+ jne LoadUcodeL1
+ test %edx, ExtSigFlags(%edi) #test [edi].ext_sig.flags, edx
+ jnz LoadCheck # Jif signature and platform ID match
+LoadUcodeL1:
+ #
# Check if any more extended signatures exist
- addl $0xc, %edi #sizeof ext_sig = 12
- loop check_ext_sig
+ #
+ addl $ExtSigLength, %edi #add edi, sizeof ext_sig
+ loop CheckExtSig
-next_microcode:
+NextMicrocode:
+ #
# Advance just after end of this microcode
+ #
xorl %eax, %eax
- cmpl %eax, 0x24(%esi) #(%esi).ucode_hdr.total_size
- je L2
- add 0x24(%esi) , %esi #(%esi).ucode_hdr.total_size
- jmp check_address
-L10:
- addl $0x800, %esi
- jmp check_address
-
-advance_fixed_size:
+ cmpl %eax, UcodeHdrTotalSize(%esi) #cmp [esi].ucode_hdr.total_size, eax
+ je LoadUcodeL2
+ addl UcodeHdrTotalSize(%esi), %esi #add esi, [esi].ucode_hdr.total_size
+ jmp CheckAddress
+LoadUcodeL2:
+ addl $0x800, %esi #add esi, dword ptr 2048
+ jmp CheckAddress
+
+AdvanceFixedSize:
+ #
# Advance by 4X dwords
- addl $0x400, %esi
+ #
+ addl $0x400, %esi #add esi, dword ptr 1024
-check_address:
+CheckAddress:
+ #
# Is valid Microcode start point ?
- cmp $0x0ffffffff , %esi
- jz done
+ #
+ cmpl $0x0ffffffff, UcodeHdrVersion(%esi)
+ #
+ # Is automatic size detection ?
+ #
+ movl LoadUcodeParamsUcodeCodeSize(%esp), %eax
+ cmpl $0x0ffffffff, %eax
+ jz LoadUcodeL3
+ #
# Address >= microcode region address + microcode region size?
- movl (%esp), %eax #(%esp).LOAD_UCODE_PARAMS.ucode_code_addr
- addl 4(%esp), %eax #(%esp).LOAD_UCODE_PARAMS.ucode_code_size
+ #
+ addl LoadUcodeParamsUcodeCodeAddr(%esp), %eax #mov eax, [esp].LOAD_UCODE_PARAMS.ucode_code_addr
+
cmpl %eax, %esi
- jae done #Jif address is outside of ucode region
- jmp check_main_header
+ jae Done #Jif address is outside of ucode region
+ jmp CheckMainHeader
-load_check:
+LoadUcodeL3:
+LoadCheck:
+ #
# Get the revision of the current microcode update loaded
- movl MSR_IA32_BIOS_SIGN_ID, %ecx
- xorl %eax, %eax # Clear EAX
- xorl %edx, %edx # Clear EDX
- wrmsr # Load 0 to MSR at 8Bh
+ #
+ movl $MSR_IA32_BIOS_SIGN_ID, %ecx
+ xorl %eax, %eax # Clear EAX
+ xorl %edx, %edx # Clear EDX
+ wrmsr # Load 0 to MSR at 8Bh
- movl $1, %eax
+ movl $0x01, %eax
cpuid
- movl MSR_IA32_BIOS_SIGN_ID, %ecx
- rdmsr # Get current microcode signature
+ movl $MSR_IA32_BIOS_SIGN_ID, %ecx
+ rdmsr # Get current microcode signature
+ #
# Verify this microcode update is not already loaded
- cmpl %edx, 4(%esi) #(%esi).ucode_hdr.revision
- je continue
+ #
+ cmpl %edx, UcodeHdrRevision(%esi) #cmp [esi].ucode_hdr.revision, edx
+ je Continue
-load_microcode:
+LoadMicrocode:
+ #
# EAX contains the linear address of the start of the Update Data
# EDX contains zero
# ECX contains 79h (IA32_BIOS_UPDT_TRIG)
# Start microcode load with wrmsr
- mov %esi, %eax
- add $0x30, %eax #sizeof ucode_hdr = 48
- xorl %edx, %edx
- mov MSR_IA32_BIOS_UPDT_TRIG,%ecx
+ #
+ movl %esi, %eax
+ addl $UcodeHdrLength, %eax #add eax, sizeof ucode_hdr
+ xorl %edx, %edx
+ movl $MSR_IA32_BIOS_UPDT_TRIG, %ecx
wrmsr
- mov $1, %eax
+ movl $0x01, %eax
cpuid
-continue:
- jmp next_microcode
+Continue:
+ jmp NextMicrocode
-done:
- mov $1, %eax
+Done:
+ movl $0x01, %eax
cpuid
- mov MSR_IA32_BIOS_SIGN_ID, %ecx
- rdmsr # Get current microcode signature
+ movl $MSR_IA32_BIOS_SIGN_ID, %ecx
+ rdmsr # Get current microcode signature
xorl %eax, %eax
- cmp $0 , %edx
- jnz exit4
- mov $0x08000000E, %eax
+ cmpl $0x00, %edx
+ jnz LoadUcodeExit
+ movl $0x08000000E, %eax
-exit4:
+LoadUcodeExit:
jmp *%ebp
-#LoadUcode ENDP
#----------------------------------------------------------------------------
# TempRamInit API
@@ -344,102 +472,103 @@ ASM_PFX(TempRamInitApi):
# Save timestamp into XMM4 & XMM5
#
rdtsc
- movd %edx, %xmm4
- movd %eax, %xmm5
+ SAVE_EAX
+ SAVE_EDX
+
+ #
+ # Check Parameter
+ #
+ movl 4(%esp), %eax
+ cmpl $0x00, %eax
+ movl $0x80000002, %eax
+ jz NemInitExit
#
# CPUID/DeviceID check
#
- movl L11, %eax
- jmp ASM_PFX(FspSelfCheck) # Note: ESP can not be changed.
-L11:
- cmpl $0, %eax
- jnz NemInitExit
+ movl $TempRamInitApiL0, %eax
+ jmp ASM_PFX(FspSelfCheckDflt) # Note: ESP can not be changed.
+TempRamInitApiL0:
+ cmpl $0x00, %eax
+ jnz NemInitExit
#
# Platform Basic Init.
#
- movl L1, %eax
- jmp ASM_PFX(PlatformBasicInitDflt)
-L1:
- cmp $0, %eax
- jnz NemInitExit
+ movl $TempRamInitApiL1, %eax
+ jmp ASM_PFX(PlatformBasicInitDflt)
+TempRamInitApiL1:
+ cmpl $0x00, %eax
+ jnz NemInitExit
#
# Load microcode
#
- movl L2, %eax
- addl $4, %esp
- jmp LoadUcode
-L2:
+ movl $TempRamInitApiL2, %eax
+ addl $0x04, %esp
+ jmp LoadUcode
+
+TempRamInitApiL2:
LOAD_ESP
- cmpl $0, %eax
- jnz NemInitExit
+ cmpl $0x00, %eax
+ jnz NemInitExit
#
# Call platform NEM init
- #-------------------------------------------------------------------------------------------------------------------------
- movl L3, %eax
- addl $4, %esp
- jmp ASM_PFX(PlatformTempRamInit)
-L3:
- subl $4, %esp
- cmpl $0, %eax
- jnz NemInitExit
+ #
+ movl $TempRamInitApiL3, %eax
+ addl $0x04, %esp
+ jmp ASM_PFX(PlatformTempRamInit)
+TempRamInitApiL3:
+ subl $0x04, %esp
+ cmpl $0x00, %eax
+ jnz NemInitExit
#
# Save parameter pointer in edx
#
- movl 4(%esp), %edx
+ movl 4(%esp), %edx
#
# Enable FSP STACK
#
- movl ASM_PFX(_gPcd_FixedAtBuild_PcdTemporaryRamBase), %esp
- addl ASM_PFX(_gPcd_FixedAtBuild_PcdTemporaryRamSize), %esp
-
- pushl $DATA_LEN_OF_MCUD # Size of the data region
- pushl 0x4455434D # Signature of the data region 'MCUD'
- pushl 12(%edx) # Code size
- pushl 8(%edx) # Code base
- cmpl $0, %edx # Is parameter pointer valid ?
- jz InvalidMicrocodeRegion
- pushl 4(%edx) # Microcode size
- pushl (%edx) # Microcode base
- jmp L4
+ movl ASM_PFX(_gPcd_FixedAtBuild_PcdTemporaryRamBase), %esp
+ addl ASM_PFX(_gPcd_FixedAtBuild_PcdTemporaryRamSize), %esp
-InvalidMicrocodeRegion:
- pushl $0 # Microcode size
- pushl $0 # Microcode base
+ pushl $DATA_LEN_OF_MCUD # Size of the data region
+ pushl $0x4455434D # Signature of the data region 'MCUD'
+ pushl 4(%edx) # Microcode size
+ pushl (%edx) # Microcode base
+ pushl 12(%edx) # Code size
+ pushl 8(%edx) # Code base
-L4:
#
# Save API entry/exit timestamp into stack
#
- pushl DATA_LEN_OF_PER0 # Size of the data region
- pushl 0x30524550 # Signature of the data region 'PER0'
- movd %xmm4, %eax
- pushl %eax
- movd %xmm5, %eax
- pushl %eax
+ pushl $DATA_LEN_OF_PER0 # Size of the data region
+ pushl $0x30524550 # Signature of the data region 'PER0'
rdtsc
- pushl %edx
- pushl %eax
+ pushl %edx
+ pushl %eax
+ LOAD_EAX
+ LOAD_EDX
+ pushl %edx
+ pushl %eax
#
# Terminator for the data on stack
#
- pushl $0
+ pushl $0x00
#
# Set ECX/EDX to the bootloader temporary memory range
#
- movl ASM_PFX(_gPcd_FixedAtBuild_PcdTemporaryRamBase), %ecx
- movl %ecx, %edx
- addl ASM_PFX(_gPcd_FixedAtBuild_PcdTemporaryRamSize), %edx
- subl ASM_PFX(_gPcd_FixedAtBuild_PcdFspTemporaryRamSize), %edx
+ movl ASM_PFX(_gPcd_FixedAtBuild_PcdTemporaryRamBase), %ecx
+ movl %ecx, %edx
+ addl ASM_PFX(_gPcd_FixedAtBuild_PcdTemporaryRamSize), %edx
+ subl ASM_PFX(_gPcd_FixedAtBuild_PcdFspTemporaryRamSize), %edx
- xorl %eax, %eax
+ xorl %eax, %eax
NemInitExit:
#
@@ -447,7 +576,7 @@ NemInitExit:
#
LOAD_REGS
ret
-#TempRamInitApi ENDP
+
#----------------------------------------------------------------------------
# FspInit API
@@ -463,60 +592,53 @@ ASM_PFX(FspInitApi):
# Stack must be ready
#
pushl $0x087654321
- pop %eax
+ popl %eax
cmpl $0x087654321, %eax
- jz L5
+ jz FspInitApiL0
movl $0x080000003, %eax
- jmp exit3
+ jmp FspInitApiexit
-L5:
+FspInitApiL0:
#
# Additional check
#
pusha
- pushl $1
+ pushl $0x01
call ASM_PFX(FspApiCallingCheck)
- addl $4, %esp
- movl %eax, 28(%esp)
+ addl $0x04, %esp
+ movl %eax, 28(%esp)
popa
- cmpl $0 , %eax
- jz L6
- jmp exit3
-
-L6:
- #
- # Save the Platform Data Pointer in EDI
- #
- movl 4(%esp), %edi
+ cmpl $0x00, %eax
+ jz FspInitApiL1
+ jmp FspInitApiexit
+FspInitApiL1:
#
# Store the address in FSP which will return control to the BL
#
- pushl $exit3
+ pushl $FspInitApiexit
#
# Create a Task Frame in the stack for the Boot Loader
#
- pushfl
pushfl # 2 pushf for 4 byte alignment
cli
pushal
+ #
# Reserve 8 bytes for IDT save/restore
- pushl $0
- pushl $0
- sidt (%esp)
+ #
+ subl $0x08, %esp
+ sidt (%esp)
#
# Setup new FSP stack
#
- movl %esp, %eax
- movl ASM_PFX(_gPcd_FixedAtBuild_PcdTemporaryRamBase), %esp
- addl ASM_PFX(_gPcd_FixedAtBuild_PcdTemporaryRamSize) , %esp
- subl DATA_LEN_AT_STACK_TOP, %esp
- addl $0x0FFFFFFC0, %esp
+ movl %esp, %eax
+ movl ASM_PFX(_gPcd_FixedAtBuild_PcdTemporaryRamBase), %esp
+ addl ASM_PFX(_gPcd_FixedAtBuild_PcdTemporaryRamSize), %esp
+ subl $(DATA_LEN_AT_STACK_TOP + 0x40), %esp
- #
# Save the bootloader's stack pointer
#
pushl %eax
@@ -525,10 +647,11 @@ L6:
# Pass entry point of the PEI core
#
call ASM_PFX(GetFspBaseAddress)
- movl %eax, %edi
- addl ASM_PFX(_gPcd_FixedAtBuild_PcdFspAreaSize), %edi
+ movl ASM_PFX(FspImageSizeOffset), %edi
+ movl (%eax, %edi), %edi
+ addl %eax, %edi
subl $0x20, %edi
- addl %ds:(%edi), %eax
+ addl (%edi), %eax
pushl %eax
#
@@ -558,10 +681,9 @@ L6:
#
call ASM_PFX(SecStartup)
-exit3:
+FspInitApiexit:
ret
-# FspInitApi ENDP
#----------------------------------------------------------------------------
# NotifyPhase API
@@ -576,36 +698,35 @@ ASM_PFX(NotifyPhaseApi):
# Stack must be ready
#
pushl $0x0087654321
- pop %eax
+ popl %eax
cmpl $0x087654321, %eax
- jz L7
+ jz NotifyPhaseApiL0
movl $0x080000003, %eax
- jmp err_exit
+ jmp NotifyPhaseApiErrExit
-L7:
+NotifyPhaseApiL0:
#
# Verify the calling condition
#
pusha
- pushl $2
- call ASM_PFX(FspApiCallingCheck)
- add $4, %esp
- mov %eax, 28(%esp)
+ pushl $0x02
+ call ASM_PFX(FspApiCallingCheck)
+ addl $0x04, %esp
+ movl %eax, 28(%esp)
popa
- cmpl $0, %eax
- jz L8
+ cmpl $0x00, %eax
+ jz NotifyPhaseApiL1
#
# Error return
#
-err_exit:
+NotifyPhaseApiErrExit:
ret
-L8:
+NotifyPhaseApiL1:
jmp ASM_PFX(Pei2LoaderSwitchStack)
-#NotifyPhaseApi ENDP
#END
diff --git a/IntelFspPkg/Include/FspApi.h b/IntelFspPkg/Include/FspApi.h
index 934a5766c3..0ec930b0ca 100644
--- a/IntelFspPkg/Include/FspApi.h
+++ b/IntelFspPkg/Include/FspApi.h
@@ -185,7 +185,7 @@ FSP_STATUS
**/
typedef
FSP_STATUS
-(FSPAPI *FSP_NOTFY_PHASE) (
+(FSPAPI *FSP_NOTIFY_PHASE) (
IN NOTIFY_PHASE_PARAMS *NotifyPhaseParamPtr
);
diff --git a/IntelFspPkg/Library/BaseFspPlatformLib/BaseFspPlatformLib.inf b/IntelFspPkg/Library/BaseFspPlatformLib/BaseFspPlatformLib.inf
index debce76c30..4122508baa 100644
--- a/IntelFspPkg/Library/BaseFspPlatformLib/BaseFspPlatformLib.inf
+++ b/IntelFspPkg/Library/BaseFspPlatformLib/BaseFspPlatformLib.inf
@@ -36,6 +36,9 @@
gIntelFspPkgTokenSpaceGuid.PcdTemporaryRamSize
gIntelFspPkgTokenSpaceGuid.PcdFspTemporaryRamSize
+[Guids]
+ gFspBootLoaderTemporaryMemoryGuid
+
[FixedPcd]
gIntelFspPkgTokenSpaceGuid.PcdFspMaxPatchEntry
gIntelFspPkgTokenSpaceGuid.PcdFspMaxPerfEntry
diff --git a/IntelFspPkg/Library/BaseFspPlatformLib/FspPlatformNotify.c b/IntelFspPkg/Library/BaseFspPlatformLib/FspPlatformNotify.c
index ef4406bec5..d405233e41 100644
--- a/IntelFspPkg/Library/BaseFspPlatformLib/FspPlatformNotify.c
+++ b/IntelFspPkg/Library/BaseFspPlatformLib/FspPlatformNotify.c
@@ -38,7 +38,7 @@ EFI_PEI_PPI_DESCRIPTOR mPeiReadyToBootPpi = {
};
-UINT32 mFspNotfifySequence[] = {
+UINT32 mFspNotifySequence[] = {
EnumInitPhaseAfterPciEnumeration,
EnumInitPhaseReadyToBoot
};
@@ -46,23 +46,23 @@ UINT32 mFspNotfifySequence[] = {
/**
Install FSP notification.
- @param[in] NotificatonCode FSP notification code
+ @param[in] NotificationCode FSP notification code
@retval EFI_SUCCESS Notify FSP successfully
- @retval EFI_INVALID_PARAMETER NotificatonCode is invalid
+ @retval EFI_INVALID_PARAMETER NotificationCode is invalid
**/
EFI_STATUS
EFIAPI
FspNotificationHandler (
- IN UINT32 NotificatonCode
+ IN UINT32 NotificationCode
)
{
EFI_STATUS Status;
Status = EFI_SUCCESS;
- switch (NotificatonCode) {
+ switch (NotificationCode) {
case EnumInitPhaseAfterPciEnumeration:
//
// Do POST PCI initialization if needed
@@ -134,20 +134,20 @@ FspWaitForNotify (
)
{
EFI_STATUS Status;
- UINT32 NotificatonValue;
- UINT32 NotificatonCount;
+ UINT32 NotificationValue;
+ UINT32 NotificationCount;
UINT8 Count;
- NotificatonCount = 0;
- while (NotificatonCount < sizeof(mFspNotfifySequence) / sizeof(UINT32)) {
+ NotificationCount = 0;
+ while (NotificationCount < sizeof(mFspNotifySequence) / sizeof(UINT32)) {
- Count = (UINT8)((NotificatonCount << 1) & 0x07);
+ Count = (UINT8)((NotificationCount << 1) & 0x07);
SetFspMeasurePoint (FSP_PERF_ID_API_NOTIFY_POSTPCI_ENTRY + Count);
- NotificatonValue = ((NOTIFY_PHASE_PARAMS *)(UINTN)GetFspApiParameter ())->Phase;
- DEBUG ((DEBUG_INFO, "FSP Got Notification. Notification Value : 0x%08X\n", NotificatonValue));
+ NotificationValue = ((NOTIFY_PHASE_PARAMS *)(UINTN)GetFspApiParameter ())->Phase;
+ DEBUG ((DEBUG_INFO, "FSP Got Notification. Notification Value : 0x%08X\n", NotificationValue));
- if (mFspNotfifySequence[NotificatonCount] != NotificatonValue) {
+ if (mFspNotifySequence[NotificationCount] != NotificationValue) {
//
// Notify code does not follow the predefined order
//
@@ -156,12 +156,12 @@ FspWaitForNotify (
//
// Process Notification and Give control back to the boot loader framework caller
//
- Status = FspNotificationHandler (NotificatonValue);
+ Status = FspNotificationHandler (NotificationValue);
SetFspApiReturnStatus(Status);
if (!EFI_ERROR(Status)) {
- NotificatonCount++;
+ NotificationCount++;
SetFspApiReturnStatus(EFI_SUCCESS);
- if (NotificatonValue == EnumInitPhaseReadyToBoot) {
+ if (NotificationValue == EnumInitPhaseReadyToBoot) {
break;
}
}
diff --git a/IntelFspPkg/Tools/GenCfgOpt.py b/IntelFspPkg/Tools/GenCfgOpt.py
index 4417bc33fe..555099bbd2 100644
--- a/IntelFspPkg/Tools/GenCfgOpt.py
+++ b/IntelFspPkg/Tools/GenCfgOpt.py
@@ -614,8 +614,8 @@ EndList
BinFd = open(BinFile, "rb")
IdStr = BinFd.read(0x08)
- ImageId = struct.unpack('Q', IdStr)
- ImageRev = struct.unpack('L', BinFd.read(0x04))
+ ImageId = struct.unpack('<Q', IdStr)
+ ImageRev = struct.unpack('<I', BinFd.read(0x04))
BinFd.close()
HeaderFd.write("#define VPD_IMAGE_ID 0x%016X /* '%s' */\n" % (ImageId[0], IdStr))
diff --git a/IntelFspWrapperPkg/Library/BaseFspApiLib/FspApiLib.c b/IntelFspWrapperPkg/Library/BaseFspApiLib/FspApiLib.c
index 590238e391..abe61b7aff 100644
--- a/IntelFspWrapperPkg/Library/BaseFspApiLib/FspApiLib.c
+++ b/IntelFspWrapperPkg/Library/BaseFspApiLib/FspApiLib.c
@@ -117,10 +117,10 @@ CallFspNotifyPhase (
IN NOTIFY_PHASE_PARAMS *NotifyPhaseParams
)
{
- FSP_NOTFY_PHASE NotifyPhaseApi;
+ FSP_NOTIFY_PHASE NotifyPhaseApi;
FSP_STATUS FspStatus;
- NotifyPhaseApi = (FSP_NOTFY_PHASE)(UINTN)(FspHeader->ImageBase + FspHeader->NotifyPhaseEntryOffset);
+ NotifyPhaseApi = (FSP_NOTIFY_PHASE)(UINTN)(FspHeader->ImageBase + FspHeader->NotifyPhaseEntryOffset);
FspStatus = Execute32BitCode ((UINTN)NotifyPhaseApi, (UINTN)NotifyPhaseParams);
return FspStatus;
diff --git a/MdeModulePkg/Bus/Ata/AtaAtapiPassThru/AhciMode.c b/MdeModulePkg/Bus/Ata/AtaAtapiPassThru/AhciMode.c
index 186d40c062..4d1b5848a5 100644
--- a/MdeModulePkg/Bus/Ata/AtaAtapiPassThru/AhciMode.c
+++ b/MdeModulePkg/Bus/Ata/AtaAtapiPassThru/AhciMode.c
@@ -1340,10 +1340,6 @@ AhciStartCommand (
//
// Setting the command
//
- Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_SACT;
- AhciAndReg (PciIo, Offset, 0);
- AhciOrReg (PciIo, Offset, CmdSlotBit);
-
Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_CI;
AhciAndReg (PciIo, Offset, 0);
AhciOrReg (PciIo, Offset, CmdSlotBit);
diff --git a/MdeModulePkg/Bus/Pci/EhciDxe/Ehci.c b/MdeModulePkg/Bus/Pci/EhciDxe/Ehci.c
index 3fcb0f9914..a3eb14b28c 100644..100755
--- a/MdeModulePkg/Bus/Pci/EhciDxe/Ehci.c
+++ b/MdeModulePkg/Bus/Pci/EhciDxe/Ehci.c
@@ -1095,6 +1095,12 @@ EhcAsyncInterruptTransfer (
EhcLinkQhToPeriod (Ehc, Urb->Qh);
InsertHeadList (&Ehc->AsyncIntTransfers, &Urb->UrbList);
+ // ARM: Force an asynchonous transfer after waiting an interval
+ // Polling interval is in milliseconds while BS.Stall except
+ // Microseconds.
+ gBS->Stall (PollingInterval * 1000);
+ EhcMonitorAsyncRequests (Ehc->PollTimer, Ehc);
+
ON_EXIT:
Ehc->PciIo->Flush (Ehc->PciIo);
gBS->RestoreTPL (OldTpl);
diff --git a/MdeModulePkg/Bus/Pci/EhciDxe/EhciSched.c b/MdeModulePkg/Bus/Pci/EhciDxe/EhciSched.c
index 5594e6699e..cc6e77e385 100644
--- a/MdeModulePkg/Bus/Pci/EhciDxe/EhciSched.c
+++ b/MdeModulePkg/Bus/Pci/EhciDxe/EhciSched.c
@@ -573,6 +573,12 @@ EhcCheckUrbResult (
ASSERT ((Ehc != NULL) && (Urb != NULL) && (Urb->Qh != NULL));
+ // The URB is already being processed, we do not want the callback to be
+ // called twice for the same URB
+ if (Urb->InProgress) {
+ return FALSE;
+ }
+
Finished = TRUE;
Urb->Completed = 0;
@@ -992,6 +998,9 @@ EhcMonitorAsyncRequests (
continue;
}
+ // Mark the URB as 'in-progress' to prevent the URB to be processed twice.
+ Urb->InProgress = TRUE;
+
//
// Flush any PCI posted write transactions from a PCI host
// bridge to system memory.
diff --git a/MdeModulePkg/Bus/Pci/EhciDxe/EhciUrb.c b/MdeModulePkg/Bus/Pci/EhciDxe/EhciUrb.c
index 6afb327df1..1ad37d5bd1 100644
--- a/MdeModulePkg/Bus/Pci/EhciDxe/EhciUrb.c
+++ b/MdeModulePkg/Bus/Pci/EhciDxe/EhciUrb.c
@@ -600,6 +600,7 @@ EhcCreateUrb (
Urb->DataLen = DataLen;
Urb->Callback = Callback;
Urb->Context = Context;
+ Urb->InProgress = FALSE;
PciIo = Ehc->PciIo;
Urb->Qh = EhcCreateQh (Ehc, &Urb->Ep);
diff --git a/MdeModulePkg/Bus/Pci/EhciDxe/EhciUrb.h b/MdeModulePkg/Bus/Pci/EhciDxe/EhciUrb.h
index 02e9af81be..0c80e76248 100644
--- a/MdeModulePkg/Bus/Pci/EhciDxe/EhciUrb.h
+++ b/MdeModulePkg/Bus/Pci/EhciDxe/EhciUrb.h
@@ -232,7 +232,8 @@ struct _URB {
// Transaction result
//
UINT32 Result;
- UINTN Completed; // completed data length
+ BOOLEAN InProgress; // defined when the URB is being processed
+ UINTN Completed; // Length of the data being processed
UINT8 DataToggle;
};
diff --git a/MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpressPassthru.c b/MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpressPassthru.c
index 4320549ed4..468785807f 100644
--- a/MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpressPassthru.c
+++ b/MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpressPassthru.c
@@ -2,6 +2,7 @@
NvmExpressDxe driver is used to manage non-volatile memory subsystem which follows
NVM Express specification.
+ (C) Copyright 2014 Hewlett-Packard Development Company, L.P.<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
@@ -852,7 +853,6 @@ NvmExpressBuildDevicePath (
IN OUT EFI_DEVICE_PATH_PROTOCOL **DevicePath
)
{
- NVME_CONTROLLER_PRIVATE_DATA *Private;
NVME_NAMESPACE_DEVICE_PATH *Node;
//
@@ -862,8 +862,6 @@ NvmExpressBuildDevicePath (
return EFI_INVALID_PARAMETER;
}
- Private = NVME_CONTROLLER_PRIVATE_DATA_FROM_PASS_THRU (This);
-
if (NamespaceId == 0) {
return EFI_NOT_FOUND;
}
diff --git a/MdeModulePkg/Bus/Usb/UsbBusDxe/UsbHub.c b/MdeModulePkg/Bus/Usb/UsbBusDxe/UsbHub.c
index e3752d1f83..be07a740cb 100644..100755
--- a/MdeModulePkg/Bus/Usb/UsbBusDxe/UsbHub.c
+++ b/MdeModulePkg/Bus/Usb/UsbBusDxe/UsbHub.c
@@ -668,7 +668,10 @@ UsbOnHubInterrupt (
}
CopyMem (HubIf->ChangeMap, Data, DataLength);
- gBS->SignalEvent (HubIf->HubNotify);
+
+ //ARM: We do not use BS.SignalEvent in order to initialize the new device immediately
+ //gBS->SignalEvent (HubIf->HubNotify);
+ UsbHubEnumeration (HubIf->HubNotify, HubIf);
return EFI_SUCCESS;
}
@@ -1112,7 +1115,11 @@ UsbRootHubInit (
// It should signal the event immediately here, or device detection
// by bus enumeration might be delayed by the timer interval.
//
- gBS->SignalEvent (HubIf->HubNotify);
+
+ //ARM: We invoke the function directly to ensure the enumeration is
+ // done immediately.
+ //gBS->SignalEvent (HubIf->HubNotify);
+ UsbRootHubEnumeration (NULL, HubIf);
Status = gBS->SetTimer (
HubIf->HubNotify,
diff --git a/MdeModulePkg/Core/Dxe/DxeMain.h b/MdeModulePkg/Core/Dxe/DxeMain.h
index 059a38336a..1e98df9cdf 100644
--- a/MdeModulePkg/Core/Dxe/DxeMain.h
+++ b/MdeModulePkg/Core/Dxe/DxeMain.h
@@ -2850,12 +2850,6 @@ CoreUpdateProfile (
@param NumberOfPages The number of pages to convert
@param NewAttributes The new attributes value for the range.
- @retval EFI_INVALID_PARAMETER Invalid parameter
- @retval EFI_NOT_FOUND Could not find a descriptor cover the specified
- range or convertion not allowed.
- @retval EFI_SUCCESS Successfully converts the memory range to the
- specified attributes.
-
**/
VOID
CoreUpdateMemoryAttributes (
diff --git a/MdeModulePkg/Core/Dxe/FwVol/FwVol.c b/MdeModulePkg/Core/Dxe/FwVol/FwVol.c
index 585d2437dc..0ca765d691 100644
--- a/MdeModulePkg/Core/Dxe/FwVol/FwVol.c
+++ b/MdeModulePkg/Core/Dxe/FwVol/FwVol.c
@@ -482,7 +482,7 @@ FvCheck (
FfsHeader = (EFI_FFS_FILE_HEADER *) (FvDevice->CachedFv);
}
TopFvAddress = FvDevice->EndOfCachedFv;
- while ((UINT8 *) FfsHeader < TopFvAddress) {
+ while (((UINTN) FfsHeader >= (UINTN) FvDevice->CachedFv) && ((UINTN) FfsHeader <= (UINTN) ((UINTN) TopFvAddress - sizeof (EFI_FFS_FILE_HEADER)))) {
if (FileCached) {
CoreFreePool (CacheFfsHeader);
@@ -672,7 +672,7 @@ NotifyFwVolBlock (
//
Status = GetFwVolHeader (Fvb, &FwVolHeader);
if (EFI_ERROR (Status)) {
- return;
+ continue;
}
ASSERT (FwVolHeader != NULL);
diff --git a/MdeModulePkg/Core/Dxe/Gcd/Gcd.c b/MdeModulePkg/Core/Dxe/Gcd/Gcd.c
index 7268465f36..6703c84517 100644
--- a/MdeModulePkg/Core/Dxe/Gcd/Gcd.c
+++ b/MdeModulePkg/Core/Dxe/Gcd/Gcd.c
@@ -812,22 +812,22 @@ CoreConvertSpace (
goto Done;
}
break;
- //
- // Set capabilities operation
- //
- case GCD_SET_CAPABILITIES_MEMORY_OPERATION:
- if ((BaseAddress & EFI_PAGE_MASK) != 0 || (Length & EFI_PAGE_MASK) != 0) {
- Status = EFI_INVALID_PARAMETER;
-
- goto Done;
+ //
+ // Set capabilities operation
+ //
+ case GCD_SET_CAPABILITIES_MEMORY_OPERATION:
+ if ((BaseAddress & EFI_PAGE_MASK) != 0 || (Length & EFI_PAGE_MASK) != 0) {
+ Status = EFI_INVALID_PARAMETER;
+
+ goto Done;
}
- //
+ //
// Current attributes must still be supported with new capabilities
- //
- if ((Capabilities & Entry->Attributes) != Entry->Attributes) {
- Status = EFI_UNSUPPORTED;
- goto Done;
- }
+ //
+ if ((Capabilities & Entry->Attributes) != Entry->Attributes) {
+ Status = EFI_UNSUPPORTED;
+ goto Done;
+ }
break;
}
Link = Link->ForwardLink;
@@ -916,8 +916,8 @@ CoreConvertSpace (
//
// Set capabilities operation
//
- case GCD_SET_CAPABILITIES_MEMORY_OPERATION:
- Entry->Capabilities = Capabilities;
+ case GCD_SET_CAPABILITIES_MEMORY_OPERATION:
+ Entry->Capabilities = Capabilities;
break;
}
Link = Link->ForwardLink;
@@ -1606,16 +1606,16 @@ CoreSetMemorySpaceCapabilities (
IN UINT64 Capabilities
)
{
- EFI_STATUS Status;
-
+ EFI_STATUS Status;
+
DEBUG ((DEBUG_GCD, "GCD:CoreSetMemorySpaceCapabilities(Base=%016lx,Length=%016lx)\n", BaseAddress, Length));
- DEBUG ((DEBUG_GCD, " Capabilities = %016lx\n", Capabilities));
-
- Status = CoreConvertSpace (GCD_SET_CAPABILITIES_MEMORY_OPERATION, (EFI_GCD_MEMORY_TYPE) 0, (EFI_GCD_IO_TYPE) 0, BaseAddress, Length, Capabilities, 0);
+ DEBUG ((DEBUG_GCD, " Capabilities = %016lx\n", Capabilities));
+
+ Status = CoreConvertSpace (GCD_SET_CAPABILITIES_MEMORY_OPERATION, (EFI_GCD_MEMORY_TYPE) 0, (EFI_GCD_IO_TYPE) 0, BaseAddress, Length, Capabilities, 0);
if (!EFI_ERROR(Status)) {
- CoreUpdateMemoryAttributes(BaseAddress, RShiftU64(Length, EFI_PAGE_SHIFT), Capabilities);
- }
-
+ CoreUpdateMemoryAttributes(BaseAddress, RShiftU64(Length, EFI_PAGE_SHIFT), Capabilities);
+ }
+
return Status;
}
diff --git a/MdeModulePkg/Core/Dxe/Mem/Page.c b/MdeModulePkg/Core/Dxe/Mem/Page.c
index 64967259a2..fa84e26125 100644
--- a/MdeModulePkg/Core/Dxe/Mem/Page.c
+++ b/MdeModulePkg/Core/Dxe/Mem/Page.c
@@ -937,12 +937,6 @@ CoreConvertPages (
@param NumberOfPages The number of pages to convert
@param NewAttributes The new attributes value for the range.
- @retval EFI_INVALID_PARAMETER Invalid parameter
- @retval EFI_NOT_FOUND Could not find a descriptor cover the specified
- range or convertion not allowed.
- @retval EFI_SUCCESS Successfully converts the memory range to the
- specified attributes.
-
**/
VOID
CoreUpdateMemoryAttributes (
@@ -1405,7 +1399,7 @@ CoreFreePages (
Status = CoreInternalFreePages (Memory, NumberOfPages);
if (!EFI_ERROR (Status)) {
- CoreUpdateProfile ((EFI_PHYSICAL_ADDRESS) (UINTN) RETURN_ADDRESS (0), MemoryProfileActionFreePages, 0, EFI_PAGES_TO_SIZE (NumberOfPages), (VOID *) (UINTN) Memory);
+ CoreUpdateProfile ((EFI_PHYSICAL_ADDRESS) (UINTN) RETURN_ADDRESS (0), MemoryProfileActionFreePages, (EFI_MEMORY_TYPE) 0, EFI_PAGES_TO_SIZE (NumberOfPages), (VOID *) (UINTN) Memory);
}
return Status;
}
diff --git a/MdeModulePkg/Core/Dxe/Mem/Pool.c b/MdeModulePkg/Core/Dxe/Mem/Pool.c
index 1891bb7387..a40ddd51bd 100644
--- a/MdeModulePkg/Core/Dxe/Mem/Pool.c
+++ b/MdeModulePkg/Core/Dxe/Mem/Pool.c
@@ -436,7 +436,7 @@ CoreFreePool (
Status = CoreInternalFreePool (Buffer);
if (!EFI_ERROR (Status)) {
- CoreUpdateProfile ((EFI_PHYSICAL_ADDRESS) (UINTN) RETURN_ADDRESS (0), MemoryProfileActionFreePool, 0, 0, Buffer);
+ CoreUpdateProfile ((EFI_PHYSICAL_ADDRESS) (UINTN) RETURN_ADDRESS (0), MemoryProfileActionFreePool, (EFI_MEMORY_TYPE) 0, 0, Buffer);
}
return Status;
}
diff --git a/MdeModulePkg/Core/Pei/FwVol/FwVol.c b/MdeModulePkg/Core/Pei/FwVol/FwVol.c
index 357f0979e2..22098c9c3e 100644
--- a/MdeModulePkg/Core/Pei/FwVol/FwVol.c
+++ b/MdeModulePkg/Core/Pei/FwVol/FwVol.c
@@ -530,12 +530,6 @@ FirmwareVolmeInfoPpiNotifyCallback (
Status = EFI_SUCCESS;
PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS (PeiServices);
- if (PrivateData->FvCount >= PcdGet32 (PcdPeiCoreMaxFvSupported)) {
- DEBUG ((EFI_D_ERROR, "The number of Fv Images (%d) exceed the max supported FVs (%d) in Pei", PrivateData->FvCount + 1, PcdGet32 (PcdPeiCoreMaxFvSupported)));
- DEBUG ((EFI_D_ERROR, "PcdPeiCoreMaxFvSupported value need be reconfigurated in DSC"));
- ASSERT (FALSE);
- }
-
if (CompareGuid (NotifyDescriptor->Guid, &gEfiPeiFirmwareVolumeInfo2PpiGuid)) {
//
// It is FvInfo2PPI.
@@ -584,6 +578,12 @@ FirmwareVolmeInfoPpiNotifyCallback (
}
}
+ if (PrivateData->FvCount >= PcdGet32 (PcdPeiCoreMaxFvSupported)) {
+ DEBUG ((EFI_D_ERROR, "The number of Fv Images (%d) exceed the max supported FVs (%d) in Pei", PrivateData->FvCount + 1, PcdGet32 (PcdPeiCoreMaxFvSupported)));
+ DEBUG ((EFI_D_ERROR, "PcdPeiCoreMaxFvSupported value need be reconfigurated in DSC"));
+ ASSERT (FALSE);
+ }
+
//
// Update internal PEI_CORE_FV array.
//
diff --git a/MdeModulePkg/Core/PiSmmCore/PiSmmCore.c b/MdeModulePkg/Core/PiSmmCore/PiSmmCore.c
index 3222a92a79..d8790241e3 100644
--- a/MdeModulePkg/Core/PiSmmCore/PiSmmCore.c
+++ b/MdeModulePkg/Core/PiSmmCore/PiSmmCore.c
@@ -85,6 +85,11 @@ SMM_CORE_SMI_HANDLERS mSmmCoreSmiHandlers[] = {
UINTN mFullSmramRangeCount;
EFI_SMRAM_DESCRIPTOR *mFullSmramRanges;
+//
+// Maximum support address used to check input CommunicationBuffer
+//
+UINTN mMaximumSupportAddress = 0;
+
/**
Place holder function until all the SMM System Table Service are available.
@@ -275,6 +280,76 @@ SmmEndOfDxeHandler (
}
/**
+ Caculate and save the maximum support address.
+
+**/
+VOID
+CaculateMaximumSupportAddress (
+ VOID
+ )
+{
+ VOID *Hob;
+ UINT32 RegEax;
+ UINT8 PhysicalAddressBits;
+
+ //
+ // Get physical address bits supported.
+ //
+ Hob = GetFirstHob (EFI_HOB_TYPE_CPU);
+ if (Hob != NULL) {
+ PhysicalAddressBits = ((EFI_HOB_CPU *) Hob)->SizeOfMemorySpace;
+ } else {
+ AsmCpuid (0x80000000, &RegEax, NULL, NULL, NULL);
+ if (RegEax >= 0x80000008) {
+ AsmCpuid (0x80000008, &RegEax, NULL, NULL, NULL);
+ PhysicalAddressBits = (UINT8) RegEax;
+ } else {
+ PhysicalAddressBits = 36;
+ }
+ }
+ //
+ // IA-32e paging translates 48-bit linear addresses to 52-bit physical addresses.
+ //
+ ASSERT (PhysicalAddressBits <= 52);
+ if (PhysicalAddressBits > 48) {
+ PhysicalAddressBits = 48;
+ }
+
+ //
+ // Save the maximum support address in one global variable
+ //
+ mMaximumSupportAddress = (UINTN) (LShiftU64 (1, PhysicalAddressBits) - 1);
+ DEBUG ((EFI_D_INFO, "mMaximumSupportAddress = 0x%lx\n", mMaximumSupportAddress));
+}
+
+/**
+ Check if input buffer is in valid address scope or not.
+
+ @param[in] Pointer Pointer to the input buffer.
+ @param[in] BufferSize Input buffer size in bytes.
+
+ @retval TRUE The input buffer is in valid address scope.
+ @retval FALSE The input buffer is not in valid address scope.
+
+**/
+BOOLEAN
+IsValidPointer (
+ IN VOID *Pointer,
+ IN UINTN BufferSize
+ )
+{
+ if ((UINTN) Pointer > mMaximumSupportAddress) {
+ return FALSE;
+ }
+
+ if (BufferSize > (mMaximumSupportAddress - (UINTN) Pointer)) {
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+/**
The main entry point to SMM Foundation.
Note: This function is only used by SMRAM invocation. It is never used by DXE invocation.
@@ -323,22 +398,29 @@ SmmEntryPoint (
//
// Synchronous SMI for SMM Core or request from Communicate protocol
//
- CommunicateHeader = (EFI_SMM_COMMUNICATE_HEADER *)gSmmCorePrivate->CommunicationBuffer;
- gSmmCorePrivate->BufferSize -= OFFSET_OF (EFI_SMM_COMMUNICATE_HEADER, Data);
- Status = SmiManage (
- &CommunicateHeader->HeaderGuid,
- NULL,
- CommunicateHeader->Data,
- &gSmmCorePrivate->BufferSize
- );
-
- //
- // Update CommunicationBuffer, BufferSize and ReturnStatus
- // Communicate service finished, reset the pointer to CommBuffer to NULL
- //
- gSmmCorePrivate->BufferSize += OFFSET_OF (EFI_SMM_COMMUNICATE_HEADER, Data);
- gSmmCorePrivate->CommunicationBuffer = NULL;
- gSmmCorePrivate->ReturnStatus = (Status == EFI_SUCCESS) ? EFI_SUCCESS : EFI_NOT_FOUND;
+ if (!IsValidPointer (gSmmCorePrivate->CommunicationBuffer, gSmmCorePrivate->BufferSize)) {
+ //
+ // If CommunicationBuffer is not in valid address scope, return EFI_INVALID_PARAMETER
+ //
+ gSmmCorePrivate->CommunicationBuffer = NULL;
+ gSmmCorePrivate->ReturnStatus = EFI_INVALID_PARAMETER;
+ } else {
+ CommunicateHeader = (EFI_SMM_COMMUNICATE_HEADER *)gSmmCorePrivate->CommunicationBuffer;
+ gSmmCorePrivate->BufferSize -= OFFSET_OF (EFI_SMM_COMMUNICATE_HEADER, Data);
+ Status = SmiManage (
+ &CommunicateHeader->HeaderGuid,
+ NULL,
+ CommunicateHeader->Data,
+ &gSmmCorePrivate->BufferSize
+ );
+ //
+ // Update CommunicationBuffer, BufferSize and ReturnStatus
+ // Communicate service finished, reset the pointer to CommBuffer to NULL
+ //
+ gSmmCorePrivate->BufferSize += OFFSET_OF (EFI_SMM_COMMUNICATE_HEADER, Data);
+ gSmmCorePrivate->CommunicationBuffer = NULL;
+ gSmmCorePrivate->ReturnStatus = (Status == EFI_SUCCESS) ? EFI_SUCCESS : EFI_NOT_FOUND;
+ }
}
}
@@ -430,5 +512,10 @@ SmmMain (
RegisterSmramProfileHandler ();
+ //
+ // Caculate and save maximum support address used in SmmEntryPoint().
+ //
+ CaculateMaximumSupportAddress ();
+
return EFI_SUCCESS;
}
diff --git a/MdeModulePkg/Core/PiSmmCore/PiSmmCore.h b/MdeModulePkg/Core/PiSmmCore/PiSmmCore.h
index d494519d2c..34bd6411d6 100644
--- a/MdeModulePkg/Core/PiSmmCore/PiSmmCore.h
+++ b/MdeModulePkg/Core/PiSmmCore/PiSmmCore.h
@@ -50,6 +50,7 @@
#include <Library/SmmCorePlatformHookLib.h>
#include <Library/PerformanceLib.h>
#include <Library/TimerLib.h>
+#include <Library/HobLib.h>
#include "PiSmmCorePrivateData.h"
diff --git a/MdeModulePkg/Core/PiSmmCore/PiSmmCore.inf b/MdeModulePkg/Core/PiSmmCore/PiSmmCore.inf
index 0c8e690846..bf030d60e7 100644
--- a/MdeModulePkg/Core/PiSmmCore/PiSmmCore.inf
+++ b/MdeModulePkg/Core/PiSmmCore/PiSmmCore.inf
@@ -59,6 +59,7 @@
SmmCorePlatformHookLib
PerformanceLib
TimerLib
+ HobLib
[Protocols]
gEfiDxeSmmReadyToLockProtocolGuid ## UNDEFINED # SmiHandlerRegister
diff --git a/MdeModulePkg/Include/Guid/SmmVariableCommon.h b/MdeModulePkg/Include/Guid/SmmVariableCommon.h
index a2daae8fe3..e92ab7fe79 100644
--- a/MdeModulePkg/Include/Guid/SmmVariableCommon.h
+++ b/MdeModulePkg/Include/Guid/SmmVariableCommon.h
@@ -1,7 +1,7 @@
/** @file
The file defined some common structures used for communicating between SMM variable module and SMM variable wrapper module.
-Copyright (c) 2011 - 2013, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2011 - 2015, 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
@@ -15,6 +15,8 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#ifndef _SMM_VARIABLE_COMMON_H_
#define _SMM_VARIABLE_COMMON_H_
+#include <Protocol/VarCheck.h>
+
#define EFI_SMM_VARIABLE_WRITE_GUID \
{ 0x93ba1826, 0xdffb, 0x45dd, { 0x82, 0xa7, 0xe7, 0xdc, 0xaa, 0x3b, 0xbd, 0xf3 } }
@@ -65,6 +67,10 @@ typedef struct {
//
#define SMM_VARIABLE_FUNCTION_LOCK_VARIABLE 8
+#define SMM_VARIABLE_FUNCTION_VAR_CHECK_VARIABLE_PROPERTY_SET 9
+
+#define SMM_VARIABLE_FUNCTION_VAR_CHECK_VARIABLE_PROPERTY_GET 10
+
///
/// Size of SMM communicate header, without including the payload.
///
@@ -107,4 +113,11 @@ typedef struct {
typedef SMM_VARIABLE_COMMUNICATE_GET_NEXT_VARIABLE_NAME SMM_VARIABLE_COMMUNICATE_LOCK_VARIABLE;
+typedef struct {
+ EFI_GUID Guid;
+ UINTN NameSize;
+ VAR_CHECK_VARIABLE_PROPERTY VariableProperty;
+ CHAR16 Name[1];
+} SMM_VARIABLE_COMMUNICATE_VAR_CHECK_VARIABLE_PROPERTY;
+
#endif // _SMM_VARIABLE_COMMON_H_ \ No newline at end of file
diff --git a/MdeModulePkg/Include/Protocol/SmmVarCheck.h b/MdeModulePkg/Include/Protocol/SmmVarCheck.h
new file mode 100644
index 0000000000..7faf5a95d3
--- /dev/null
+++ b/MdeModulePkg/Include/Protocol/SmmVarCheck.h
@@ -0,0 +1,36 @@
+/** @file
+ SMM variable check definitions, it reuses the interface definitions of variable check.
+
+ Copyright (c) 2015, 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 __SMM_VAR_CHECK_H__
+#define __SMM_VAR_CHECK_H__
+
+#include <Protocol/VarCheck.h>
+
+#define EDKII_SMM_VAR_CHECK_PROTOCOL_GUID \
+ { \
+ 0xb0d8f3c1, 0xb7de, 0x4c11, { 0xbc, 0x89, 0x2f, 0xb5, 0x62, 0xc8, 0xc4, 0x11 } \
+ };
+
+typedef struct _EDKII_SMM_VAR_CHECK_PROTOCOL EDKII_SMM_VAR_CHECK_PROTOCOL;
+
+struct _EDKII_SMM_VAR_CHECK_PROTOCOL {
+ EDKII_VAR_CHECK_REGISTER_SET_VARIABLE_CHECK_HANDLER SmmRegisterSetVariableCheckHandler;
+ EDKII_VAR_CHECK_VARIABLE_PROPERTY_SET SmmVariablePropertySet;
+ EDKII_VAR_CHECK_VARIABLE_PROPERTY_GET SmmVariablePropertyGet;
+};
+
+extern EFI_GUID gEdkiiSmmVarCheckProtocolGuid;
+
+#endif
+
diff --git a/MdeModulePkg/Include/Protocol/VarCheck.h b/MdeModulePkg/Include/Protocol/VarCheck.h
new file mode 100644
index 0000000000..1a79216516
--- /dev/null
+++ b/MdeModulePkg/Include/Protocol/VarCheck.h
@@ -0,0 +1,120 @@
+/** @file
+ Variable check definitions.
+
+ Copyright (c) 2015, 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 _VARIABLE_CHECK_H_
+#define _VARIABLE_CHECK_H_
+
+#include <Uefi/UefiSpec.h>
+
+typedef struct _EDKII_VAR_CHECK_PROTOCOL EDKII_VAR_CHECK_PROTOCOL;
+
+#define EDKII_VAR_CHECK_PROTOCOL_GUID { \
+ 0xaf23b340, 0x97b4, 0x4685, { 0x8d, 0x4f, 0xa3, 0xf2, 0x81, 0x69, 0xb2, 0x1d } \
+};
+
+typedef EFI_SET_VARIABLE VAR_CHECK_SET_VARIABLE_CHECK_HANDLER;
+
+/**
+ Register SetVariable check handler.
+ Variable driver will call the handler to do check before
+ really setting the variable into variable storage.
+
+ @param[in] Handler Pointer to the check handler.
+
+ @retval EFI_SUCCESS The SetVariable check handler was registered successfully.
+ @retval EFI_INVALID_PARAMETER Handler is NULL.
+ @retval EFI_ACCESS_DENIED EFI_END_OF_DXE_EVENT_GROUP_GUID or EFI_EVENT_GROUP_READY_TO_BOOT has already been signaled.
+ @retval EFI_OUT_OF_RESOURCES There is not enough resource for the SetVariable check handler register request.
+ @retval EFI_UNSUPPORTED This interface is not implemented.
+ For example, it is unsupported in VarCheck protocol if both VarCheck and SmmVarCheck protocols are present.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI * EDKII_VAR_CHECK_REGISTER_SET_VARIABLE_CHECK_HANDLER) (
+ IN VAR_CHECK_SET_VARIABLE_CHECK_HANDLER Handler
+ );
+
+#define VAR_CHECK_VARIABLE_PROPERTY_REVISION 0x0001
+//
+// 1. Set by VariableLock PROTOCOL
+// 2. Set by VarCheck PROTOCOL
+//
+// If set, other fields for check will be ignored.
+//
+#define VAR_CHECK_VARIABLE_PROPERTY_READ_ONLY BIT0
+
+typedef struct {
+ UINT16 Revision;
+ UINT16 Property;
+ UINT32 Attributes;
+ UINTN MinSize;
+ UINTN MaxSize;
+} VAR_CHECK_VARIABLE_PROPERTY;
+
+/**
+ Variable property set.
+ Variable driver will do check according to the VariableProperty before
+ really setting the variable into variable storage.
+
+ @param[in] Name Pointer to the variable name.
+ @param[in] Guid Pointer to the vendor GUID.
+ @param[in] VariableProperty Pointer to the input variable property.
+
+ @retval EFI_SUCCESS The property of variable specified by the Name and Guid was set successfully.
+ @retval EFI_INVALID_PARAMETER Name, Guid or VariableProperty is NULL, or Name is an empty string,
+ or the fields of VariableProperty are not valid.
+ @retval EFI_ACCESS_DENIED EFI_END_OF_DXE_EVENT_GROUP_GUID or EFI_EVENT_GROUP_READY_TO_BOOT has
+ already been signaled.
+ @retval EFI_OUT_OF_RESOURCES There is not enough resource for the variable property set request.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI * EDKII_VAR_CHECK_VARIABLE_PROPERTY_SET) (
+ IN CHAR16 *Name,
+ IN EFI_GUID *Guid,
+ IN VAR_CHECK_VARIABLE_PROPERTY *VariableProperty
+ );
+
+/**
+ Variable property get.
+
+ @param[in] Name Pointer to the variable name.
+ @param[in] Guid Pointer to the vendor GUID.
+ @param[out] VariableProperty Pointer to the output variable property.
+
+ @retval EFI_SUCCESS The property of variable specified by the Name and Guid was got successfully.
+ @retval EFI_INVALID_PARAMETER Name, Guid or VariableProperty is NULL, or Name is an empty string.
+ @retval EFI_NOT_FOUND The property of variable specified by the Name and Guid was not found.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI * EDKII_VAR_CHECK_VARIABLE_PROPERTY_GET) (
+ IN CHAR16 *Name,
+ IN EFI_GUID *Guid,
+ OUT VAR_CHECK_VARIABLE_PROPERTY *VariableProperty
+ );
+
+struct _EDKII_VAR_CHECK_PROTOCOL {
+ EDKII_VAR_CHECK_REGISTER_SET_VARIABLE_CHECK_HANDLER RegisterSetVariableCheckHandler;
+ EDKII_VAR_CHECK_VARIABLE_PROPERTY_SET VariablePropertySet;
+ EDKII_VAR_CHECK_VARIABLE_PROPERTY_GET VariablePropertyGet;
+};
+
+extern EFI_GUID gEdkiiVarCheckProtocolGuid;
+
+#endif
+
diff --git a/MdeModulePkg/Library/BaseSerialPortLib16550/BaseSerialPortLib16550.c b/MdeModulePkg/Library/BaseSerialPortLib16550/BaseSerialPortLib16550.c
index 0ade9b2311..abf4f8f26a 100644
--- a/MdeModulePkg/Library/BaseSerialPortLib16550/BaseSerialPortLib16550.c
+++ b/MdeModulePkg/Library/BaseSerialPortLib16550/BaseSerialPortLib16550.c
@@ -1,6 +1,7 @@
/** @file
16550 UART Serial Port library functions
+ (C) Copyright 2014 Hewlett-Packard Development Company, L.P.<BR>
Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
@@ -184,7 +185,6 @@ GetSerialRegisterBase (
)
{
UINTN PciLibAddress;
- UINTN PrimaryBusNumber;
UINTN BusNumber;
UINTN SubordinateBusNumber;
UINT32 ParentIoBase;
@@ -233,7 +233,6 @@ GetSerialRegisterBase (
//
// Retrieve and verify the bus numbers in the PCI to PCI Bridge
//
- PrimaryBusNumber = PciRead8 (PciLibAddress + PCI_BRIDGE_PRIMARY_BUS_REGISTER_OFFSET);
BusNumber = PciRead8 (PciLibAddress + PCI_BRIDGE_SECONDARY_BUS_REGISTER_OFFSET);
SubordinateBusNumber = PciRead8 (PciLibAddress + PCI_BRIDGE_SUBORDINATE_BUS_REGISTER_OFFSET);
if (BusNumber == 0 || BusNumber > SubordinateBusNumber) {
diff --git a/MdeModulePkg/Library/CustomizedDisplayLib/CustomizedDisplayLib.c b/MdeModulePkg/Library/CustomizedDisplayLib/CustomizedDisplayLib.c
index f442f7d3d9..622410359c 100644
--- a/MdeModulePkg/Library/CustomizedDisplayLib/CustomizedDisplayLib.c
+++ b/MdeModulePkg/Library/CustomizedDisplayLib/CustomizedDisplayLib.c
@@ -2,7 +2,7 @@
This library class defines a set of interfaces to customize Display module
-Copyright (c) 2013, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2013 - 2014, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials are licensed and made available under
the terms and conditions of the BSD License that accompanies this distribution.
The full text of the license may be found at
@@ -164,6 +164,9 @@ RefreshKeyHelp (
SecCol = gScreenDimensions.LeftColumn + (gScreenDimensions.RightColumn - gScreenDimensions.LeftColumn) / 3;
ThdCol = gScreenDimensions.LeftColumn + (gScreenDimensions.RightColumn - gScreenDimensions.LeftColumn) / 3 * 2;
+ //
+ // + 2 means leave 1 space before the first hotkey info.
+ //
StartColumnOfHelp = gScreenDimensions.LeftColumn + 2;
RightColumnOfHelp = gScreenDimensions.RightColumn - 1;
TopRowOfHelp = gScreenDimensions.BottomRow - STATUS_BAR_HEIGHT - gFooterHeight + 1;
@@ -176,6 +179,12 @@ RefreshKeyHelp (
ColumnStr2 = gLibEmptyString;
ColumnStr3 = gLibEmptyString;
+ //
+ // Clean the space at gScreenDimensions.LeftColumn + 1.
+ //
+ PrintStringAtWithWidth (StartColumnOfHelp - 1, BottomRowOfHelp, gLibEmptyString, 1);
+ PrintStringAtWithWidth (StartColumnOfHelp - 1, TopRowOfHelp, gLibEmptyString, 1);
+
if (Statement == NULL) {
//
// Print Key for Form without showable statement.
@@ -184,7 +193,10 @@ RefreshKeyHelp (
PrintStringAtWithWidth (StartColumnOfHelp, BottomRowOfHelp, gLibEmptyString, ColumnWidth1);
PrintStringAtWithWidth (SecCol, BottomRowOfHelp, gLibEmptyString, ColumnWidth2);
PrintStringAtWithWidth (StartColumnOfHelp, TopRowOfHelp, gLibEmptyString, ColumnWidth1);
- PrintStringAtWithWidth (ThdCol, BottomRowOfHelp, gEscapeString, ColumnWidth3);
+ if (gClassOfVfr == FORMSET_CLASS_PLATFORM_SETUP) {
+ ColumnStr3 = gEscapeString;
+ }
+ PrintStringAtWithWidth (ThdCol, BottomRowOfHelp, ColumnStr3, ColumnWidth3);
return;
}
diff --git a/MdeModulePkg/Library/DxeIpIoLib/DxeIpIoLib.c b/MdeModulePkg/Library/DxeIpIoLib/DxeIpIoLib.c
index 837a1dba4d..cc93c2b89c 100644
--- a/MdeModulePkg/Library/DxeIpIoLib/DxeIpIoLib.c
+++ b/MdeModulePkg/Library/DxeIpIoLib/DxeIpIoLib.c
@@ -1,6 +1,7 @@
/** @file
IpIo Library.
+(C) Copyright 2014 Hewlett-Packard Development Company, L.P.<BR>
Copyright (c) 2005 - 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
@@ -703,7 +704,7 @@ IpIoCreateSndEntry (
Ip4TxData = &TxData->Ip4TxData;
- CopyMem (&Ip4TxData->DestinationAddress, Dest, sizeof (EFI_IPv4_ADDRESS));
+ IP4_COPY_ADDRESS (&Ip4TxData->DestinationAddress, Dest);
Ip4TxData->OverrideData = &OverrideData->Ip4OverrideData;
Ip4TxData->OptionsLength = 0;
@@ -1765,8 +1766,8 @@ IpIoConfigIp (
NULL
);
- ((EFI_IP4_CONFIG_DATA*) IpConfigData)->StationAddress = Ip4ModeData.ConfigData.StationAddress;
- ((EFI_IP4_CONFIG_DATA*) IpConfigData)->SubnetMask = Ip4ModeData.ConfigData.SubnetMask;
+ IP4_COPY_ADDRESS (&((EFI_IP4_CONFIG_DATA*) IpConfigData)->StationAddress, &Ip4ModeData.ConfigData.StationAddress);
+ IP4_COPY_ADDRESS (&((EFI_IP4_CONFIG_DATA*) IpConfigData)->SubnetMask, &Ip4ModeData.ConfigData.SubnetMask);
}
CopyMem (
diff --git a/MdeModulePkg/MdeModulePkg.dec b/MdeModulePkg/MdeModulePkg.dec
index 753f77baf0..387a63ca4f 100644
--- a/MdeModulePkg/MdeModulePkg.dec
+++ b/MdeModulePkg/MdeModulePkg.dec
@@ -3,7 +3,7 @@
# It also provides the definitions(including PPIs/PROTOCOLs/GUIDs and library classes)
# and libraries instances, which are used for those modules.
#
-# Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.<BR>
+# Copyright (c) 2007 - 2015, 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
@@ -355,6 +355,12 @@
# Include/Protocol/VariableLock.h
gEdkiiVariableLockProtocolGuid = { 0xcd3d0a05, 0x9e24, 0x437c, { 0xa8, 0x91, 0x1e, 0xe0, 0x53, 0xdb, 0x76, 0x38 }}
+ ## Include/Protocol/VarCheck.h
+ gEdkiiVarCheckProtocolGuid = { 0xaf23b340, 0x97b4, 0x4685, { 0x8d, 0x4f, 0xa3, 0xf2, 0x81, 0x69, 0xb2, 0x1d } }
+
+ ## Include/Protocol/SmmVarCheck.h
+ gEdkiiSmmVarCheckProtocolGuid = { 0xb0d8f3c1, 0xb7de, 0x4c11, { 0xbc, 0x89, 0x2f, 0xb5, 0x62, 0xc8, 0xc4, 0x11 } }
+
## This protocol is similar with DXE FVB protocol and used in the UEFI SMM evvironment.
# Include/Protocol/SmmFirmwareVolumeBlock.h
gEfiSmmFirmwareVolumeBlockProtocolGuid = { 0xd326d041, 0xbd31, 0x4c01, { 0xb5, 0xa8, 0x62, 0x8b, 0xe8, 0x7f, 0x6, 0x53 }}
diff --git a/MdeModulePkg/MdeModulePkg.dsc b/MdeModulePkg/MdeModulePkg.dsc
index 85dda92ca5..80c19a32ca 100644
--- a/MdeModulePkg/MdeModulePkg.dsc
+++ b/MdeModulePkg/MdeModulePkg.dsc
@@ -1,6 +1,7 @@
## @file
# EFI/PI Reference Module Package for All Architectures
#
+# (C) Copyright 2014 Hewlett-Packard Development Company, L.P.<BR>
# Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.<BR>
#
# This program and the accompanying materials
@@ -123,6 +124,7 @@
LockBoxLib|MdeModulePkg/Library/SmmLockBoxLib/SmmLockBoxDxeLib.inf
[LibraryClasses.common.SMM_CORE]
+ HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf
MemoryAllocationLib|MdeModulePkg/Library/PiSmmCoreMemoryAllocationLib/PiSmmCoreMemoryAllocationLib.inf
SmmServicesTableLib|MdeModulePkg/Library/PiSmmCoreSmmServicesTableLib/PiSmmCoreSmmServicesTableLib.inf
SmmCorePlatformHookLib|MdeModulePkg/Library/SmmCorePlatformHookLibNull/SmmCorePlatformHookLibNull.inf
@@ -145,10 +147,10 @@
MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf
DebugLib|MdePkg/Library/UefiDebugLibStdErr/UefiDebugLibStdErr.inf
-[LibraryClasses.ARM]
+[LibraryClasses.ARM, LibraryClasses.AARCH64]
#
- # It is not possible to prevent the ARM compiler for generic intrinsic functions.
- # This library provides the instrinsic functions generate by a given compiler.
+ # It is not possible to prevent ARM compiler calls to generic intrinsic functions.
+ # This library provides the instrinsic functions generated by a given compiler.
# [LibraryClasses.ARM] and NULL mean link this library into all ARM images.
#
NULL|ArmPkg/Library/CompilerIntrinsicsLib/CompilerIntrinsicsLib.inf
@@ -334,8 +336,8 @@
<LibraryClasses>
NULL|MdeModulePkg/Library/PeiCrc32GuidedSectionExtractLib/PeiCrc32GuidedSectionExtractLib.inf
}
-
- MdeModulePkg/Universal/FvSimpleFilesystemDxe/FvSimpleFilesystemDxe.inf
+
+ MdeModulePkg/Universal/FvSimpleFileSystemDxe/FvSimpleFileSystemDxe.inf
MdeModulePkg/Universal/Fdt/FdtTableDxe/FdtTableDxe.inf
[Components.IA32, Components.X64, Components.IPF]
diff --git a/MdeModulePkg/Universal/Acpi/FirmwarePerformanceDataTableDxe/FirmwarePerformanceDxe.c b/MdeModulePkg/Universal/Acpi/FirmwarePerformanceDataTableDxe/FirmwarePerformanceDxe.c
index caf924ccf8..dbe7ef75c3 100644
--- a/MdeModulePkg/Universal/Acpi/FirmwarePerformanceDataTableDxe/FirmwarePerformanceDxe.c
+++ b/MdeModulePkg/Universal/Acpi/FirmwarePerformanceDataTableDxe/FirmwarePerformanceDxe.c
@@ -54,6 +54,7 @@ UINTN mFirmwarePerformanceTableTemplateKey = 0;
UINT32 mBootRecordSize = 0;
UINT32 mBootRecordMaxSize = 0;
UINT8 *mBootRecordBuffer = NULL;
+BOOLEAN mDxeCoreReportStatusCodeEnable = FALSE;
BOOT_PERFORMANCE_TABLE *mAcpiBootPerformanceTable = NULL;
S3_PERFORMANCE_TABLE *mAcpiS3PerformanceTable = NULL;
@@ -595,45 +596,6 @@ FpdtLegacyBootEventNotify (
}
/**
- Notify function for event EVT_SIGNAL_EXIT_BOOT_SERVICES. This is used to record
- performance data for ExitBootServicesEntry in FPDT.
-
- @param[in] Event The Event that is being processed.
- @param[in] Context The Event Context.
-
-**/
-VOID
-EFIAPI
-FpdtExitBootServicesEventNotify (
- IN EFI_EVENT Event,
- IN VOID *Context
- )
-{
- if (mAcpiBootPerformanceTable == NULL) {
- //
- // Firmware Performance Data Table not installed, do nothing.
- //
- return ;
- }
-
- //
- // Update Firmware Basic Boot Performance Record for UEFI boot.
- //
- mAcpiBootPerformanceTable->BasicBoot.ExitBootServicesEntry = GetTimeInNanoSecond (GetPerformanceCounter ());
-
- //
- // Dump FPDT Boot Performance record.
- //
- DEBUG ((EFI_D_INFO, "FPDT: Boot Performance - ResetEnd = %ld\n", mAcpiBootPerformanceTable->BasicBoot.ResetEnd));
- DEBUG ((EFI_D_INFO, "FPDT: Boot Performance - OsLoaderLoadImageStart = %ld\n", mAcpiBootPerformanceTable->BasicBoot.OsLoaderLoadImageStart));
- DEBUG ((EFI_D_INFO, "FPDT: Boot Performance - OsLoaderStartImageStart = %ld\n", mAcpiBootPerformanceTable->BasicBoot.OsLoaderStartImageStart));
- DEBUG ((EFI_D_INFO, "FPDT: Boot Performance - ExitBootServicesEntry = %ld\n", mAcpiBootPerformanceTable->BasicBoot.ExitBootServicesEntry));
- //
- // ExitBootServicesExit will be updated later, so don't dump it here.
- //
-}
-
-/**
Report status code listener of FPDT. This is used to collect performance data
for OsLoaderLoadImageStart and OsLoaderStartImageStart in FPDT.
@@ -670,6 +632,13 @@ FpdtStatusCodeListenerDxe (
if ((CodeType & EFI_STATUS_CODE_TYPE_MASK) != EFI_PROGRESS_CODE) {
return EFI_UNSUPPORTED;
}
+
+ if (Value == (EFI_SOFTWARE_DXE_CORE | EFI_SW_DXE_CORE_PC_HANDOFF_TO_NEXT)) {
+ //
+ // DxeCore ReportStatusCode Enable so that the capability can be supported.
+ //
+ mDxeCoreReportStatusCodeEnable = TRUE;
+ }
Status = EFI_SUCCESS;
if (Value == PcdGet32 (PcdProgressCodeOsLoaderLoad)) {
@@ -698,6 +667,11 @@ FpdtStatusCodeListenerDxe (
mAcpiBootPerformanceTable->BasicBoot.OsLoaderStartImageStart = GetTimeInNanoSecond (GetPerformanceCounter ());
} else if (Value == (EFI_SOFTWARE_EFI_BOOT_SERVICE | EFI_SW_BS_PC_EXIT_BOOT_SERVICES)) {
//
+ // Unregister boot time report status code listener.
+ //
+ mRscHandlerProtocol->Unregister (FpdtStatusCodeListenerDxe);
+
+ //
// Progress code for ExitBootServices.
//
if (mAcpiBootPerformanceTable == NULL) {
@@ -708,11 +682,6 @@ FpdtStatusCodeListenerDxe (
// Update ExitBootServicesExit for UEFI boot.
//
mAcpiBootPerformanceTable->BasicBoot.ExitBootServicesExit = GetTimeInNanoSecond (GetPerformanceCounter ());
-
- //
- // Unregister boot time report status code listener.
- //
- mRscHandlerProtocol->Unregister (FpdtStatusCodeListenerDxe);
} else if (Data != NULL && CompareGuid (&Data->Type, &gEfiFirmwarePerformanceGuid)) {
//
// Append one or more Boot records
@@ -759,6 +728,54 @@ FpdtStatusCodeListenerDxe (
return Status;
}
+
+/**
+ Notify function for event EVT_SIGNAL_EXIT_BOOT_SERVICES. This is used to record
+ performance data for ExitBootServicesEntry in FPDT.
+
+ @param[in] Event The Event that is being processed.
+ @param[in] Context The Event Context.
+
+**/
+VOID
+EFIAPI
+FpdtExitBootServicesEventNotify (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+{
+ if (!mDxeCoreReportStatusCodeEnable) {
+ //
+ // When DxeCore Report Status Code is disabled,
+ // Unregister boot time report status code listener at ExitBootService Event.
+ //
+ mRscHandlerProtocol->Unregister (FpdtStatusCodeListenerDxe);
+ }
+
+ if (mAcpiBootPerformanceTable == NULL) {
+ //
+ // Firmware Performance Data Table not installed, do nothing.
+ //
+ return ;
+ }
+
+ //
+ // Update Firmware Basic Boot Performance Record for UEFI boot.
+ //
+ mAcpiBootPerformanceTable->BasicBoot.ExitBootServicesEntry = GetTimeInNanoSecond (GetPerformanceCounter ());
+
+ //
+ // Dump FPDT Boot Performance record.
+ //
+ DEBUG ((EFI_D_INFO, "FPDT: Boot Performance - ResetEnd = %ld\n", mAcpiBootPerformanceTable->BasicBoot.ResetEnd));
+ DEBUG ((EFI_D_INFO, "FPDT: Boot Performance - OsLoaderLoadImageStart = %ld\n", mAcpiBootPerformanceTable->BasicBoot.OsLoaderLoadImageStart));
+ DEBUG ((EFI_D_INFO, "FPDT: Boot Performance - OsLoaderStartImageStart = %ld\n", mAcpiBootPerformanceTable->BasicBoot.OsLoaderStartImageStart));
+ DEBUG ((EFI_D_INFO, "FPDT: Boot Performance - ExitBootServicesEntry = %ld\n", mAcpiBootPerformanceTable->BasicBoot.ExitBootServicesEntry));
+ //
+ // ExitBootServicesExit will be updated later, so don't dump it here.
+ //
+}
+
/**
The module Entry Point of the Firmware Performance Data Table DXE driver.
diff --git a/MdeModulePkg/Universal/CapsulePei/Common/CapsuleCoalesce.c b/MdeModulePkg/Universal/CapsulePei/Common/CapsuleCoalesce.c
index 507f862de7..d789fbbc75 100644
--- a/MdeModulePkg/Universal/CapsulePei/Common/CapsuleCoalesce.c
+++ b/MdeModulePkg/Universal/CapsulePei/Common/CapsuleCoalesce.c
@@ -9,6 +9,7 @@
CapsuleDataCoalesce() will do basic validation before coalesce capsule data
into memory.
+(C) Copyright 2014 Hewlett-Packard Development Company, L.P.<BR>
Copyright (c) 2011 - 2014, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
@@ -960,7 +961,6 @@ CapsuleDataCoalesce (
UINT8 *DestPtr;
UINTN DestLength;
UINT8 *RelocPtr;
- UINT64 *AddDataPtr;
UINTN CapsuleTimes;
UINT64 SizeLeft;
UINT64 CapsuleImageSize;
@@ -986,7 +986,6 @@ CapsuleDataCoalesce (
CapsuleTimes = 0;
CapsuleImageSize = 0;
PrivateDataPtr = NULL;
- AddDataPtr = NULL;
CapsuleHeader = NULL;
CapsuleBeginFlag = TRUE;
CapsuleSize = 0;
diff --git a/MdeModulePkg/Universal/Console/TerminalDxe/TerminalConIn.c b/MdeModulePkg/Universal/Console/TerminalDxe/TerminalConIn.c
index 1f29b61646..4a008c9ada 100644
--- a/MdeModulePkg/Universal/Console/TerminalDxe/TerminalConIn.c
+++ b/MdeModulePkg/Universal/Console/TerminalDxe/TerminalConIn.c
@@ -1,6 +1,7 @@
/** @file
Implementation for EFI_SIMPLE_TEXT_INPUT_PROTOCOL protocol.
+(C) Copyright 2014 Hewlett-Packard Development Company, L.P.<BR>
Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
@@ -847,7 +848,7 @@ EfiKeyFiFoRemoveOneKey (
return FALSE;
}
- *Output = TerminalDevice->EfiKeyFiFo->Data[Head];
+ CopyMem (Output, &TerminalDevice->EfiKeyFiFo->Data[Head], sizeof (EFI_INPUT_KEY));
TerminalDevice->EfiKeyFiFo->Head = (UINT8) ((Head + 1) % (FIFO_MAX_NUMBER + 1));
diff --git a/MdeModulePkg/Universal/DebugSupportDxe/X64/AsmFuncs.S b/MdeModulePkg/Universal/DebugSupportDxe/X64/AsmFuncs.S
index 9783ec6b80..7f0919ee1b 100644
--- a/MdeModulePkg/Universal/DebugSupportDxe/X64/AsmFuncs.S
+++ b/MdeModulePkg/Universal/DebugSupportDxe/X64/AsmFuncs.S
@@ -280,7 +280,7 @@ ExtraPushDone:
mov %ds, %rax
pushq %rax
- movw %es, %rax
+ mov %es, %rax
pushq %rax
mov %fs, %rax
pushq %rax
diff --git a/MdeModulePkg/Universal/Disk/PartitionDxe/ElTorito.c b/MdeModulePkg/Universal/Disk/PartitionDxe/ElTorito.c
index 3d7cf2dc6c..9264ef3119 100644
--- a/MdeModulePkg/Universal/Disk/PartitionDxe/ElTorito.c
+++ b/MdeModulePkg/Universal/Disk/PartitionDxe/ElTorito.c
@@ -45,8 +45,8 @@ PartitionInstallElToritoChildHandles (
)
{
EFI_STATUS Status;
- UINT32 VolDescriptorLba;
- UINT32 Lba;
+ UINT64 VolDescriptorOffset;
+ UINT32 Lba2KB;
EFI_BLOCK_IO_MEDIA *Media;
CDROM_VOLUME_DESCRIPTOR *VolDescriptor;
ELTORITO_CATALOG *Catalog;
@@ -67,13 +67,17 @@ PartitionInstallElToritoChildHandles (
VolSpaceSize = 0;
//
- // CD_ROM has the fixed block size as 2048 bytes
+ // CD_ROM has the fixed block size as 2048 bytes (SIZE_2KB)
//
- if (Media->BlockSize != 2048) {
+
+ // If the ISO image has been copied onto a different storage media
+ // then the block size might be different (eg: USB).
+ // Ensure 2048 (SIZE_2KB) is a multiple of block size
+ if (((SIZE_2KB % Media->BlockSize) != 0) || (Media->BlockSize > SIZE_2KB)) {
return EFI_NOT_FOUND;
}
- VolDescriptor = AllocatePool ((UINTN) Media->BlockSize);
+ VolDescriptor = AllocatePool ((UINTN)SIZE_2KB);
if (VolDescriptor == NULL) {
return EFI_NOT_FOUND;
@@ -82,31 +86,17 @@ PartitionInstallElToritoChildHandles (
Catalog = (ELTORITO_CATALOG *) VolDescriptor;
//
- // the ISO-9660 volume descriptor starts at 32k on the media
- // and CD_ROM has the fixed block size as 2048 bytes, so...
- //
- //
- // ((16*2048) / Media->BlockSize) - 1;
- //
- VolDescriptorLba = 15;
- //
// Loop: handle one volume descriptor per time
+ // The ISO-9660 volume descriptor starts at 32k on the media
//
- while (TRUE) {
-
- VolDescriptorLba += 1;
- if (VolDescriptorLba > Media->LastBlock) {
- //
- // We are pointing past the end of the device so exit
- //
- break;
- }
-
+ for (VolDescriptorOffset = SIZE_32KB;
+ VolDescriptorOffset <= MultU64x32 (Media->LastBlock, Media->BlockSize);
+ VolDescriptorOffset += SIZE_2KB) {
Status = DiskIo->ReadDisk (
DiskIo,
Media->MediaId,
- MultU64x32 (VolDescriptorLba, Media->BlockSize),
- Media->BlockSize,
+ VolDescriptorOffset,
+ SIZE_2KB,
VolDescriptor
);
if (EFI_ERROR (Status)) {
@@ -139,17 +129,19 @@ PartitionInstallElToritoChildHandles (
}
//
// Read in the boot El Torito boot catalog
+ // The LBA unit used by El Torito boot catalog is 2KB unit
//
- Lba = UNPACK_INT32 (VolDescriptor->BootRecordVolume.EltCatalog);
- if (Lba > Media->LastBlock) {
+ Lba2KB = UNPACK_INT32 (VolDescriptor->BootRecordVolume.EltCatalog);
+ // Ensure the LBA (in 2KB unit) fits into our media
+ if (Lba2KB * (SIZE_2KB / Media->BlockSize) > Media->LastBlock) {
continue;
}
Status = DiskIo->ReadDisk (
DiskIo,
Media->MediaId,
- MultU64x32 (Lba, Media->BlockSize),
- Media->BlockSize,
+ MultU64x32 (Lba2KB, SIZE_2KB),
+ SIZE_2KB,
Catalog
);
if (EFI_ERROR (Status)) {
@@ -191,7 +183,7 @@ PartitionInstallElToritoChildHandles (
}
SubBlockSize = 512;
- SectorCount = Catalog->Boot.SectorCount;
+ SectorCount = Catalog->Boot.SectorCount * (SIZE_2KB / Media->BlockSize);
switch (Catalog->Boot.MediaType) {
@@ -236,7 +228,7 @@ PartitionInstallElToritoChildHandles (
CdDev.BootEntry = (UINT32) BootEntry;
BootEntry++;
- CdDev.PartitionStart = Catalog->Boot.Lba;
+ CdDev.PartitionStart = Catalog->Boot.Lba * (SIZE_2KB / Media->BlockSize);
if (SectorCount < 2) {
//
// When the SectorCount < 2, set the Partition as the whole CD.
@@ -265,8 +257,8 @@ PartitionInstallElToritoChildHandles (
BlockIo2,
DevicePath,
(EFI_DEVICE_PATH_PROTOCOL *) &CdDev,
- Catalog->Boot.Lba,
- Catalog->Boot.Lba + CdDev.PartitionSize - 1,
+ Catalog->Boot.Lba * (SIZE_2KB / Media->BlockSize),
+ (Catalog->Boot.Lba + CdDev.PartitionSize - 1) * (SIZE_2KB / Media->BlockSize),
SubBlockSize,
FALSE
);
diff --git a/MdeModulePkg/Universal/FvSimpleFileSystemDxe/ComponentName.c b/MdeModulePkg/Universal/FvSimpleFileSystemDxe/ComponentName.c
new file mode 100644
index 0000000000..5ea05975ae
--- /dev/null
+++ b/MdeModulePkg/Universal/FvSimpleFileSystemDxe/ComponentName.c
@@ -0,0 +1,187 @@
+/** @file
+ UEFI Component Name(2) protocol implementation for FvSimpleFileSystem driver.
+
+Copyright (c) 2014, ARM Limited. All rights reserved.
+Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>
+
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include "FvSimpleFileSystemInternal.h"
+
+//
+// EFI Component Name Protocol
+//
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME_PROTOCOL gFvSimpleFileSystemComponentName = {
+ FvSimpleFileSystemComponentNameGetDriverName,
+ FvSimpleFileSystemComponentNameGetControllerName,
+ "eng"
+};
+
+//
+// EFI Component Name 2 Protocol
+//
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME2_PROTOCOL gFvSimpleFileSystemComponentName2 = {
+ (EFI_COMPONENT_NAME2_GET_DRIVER_NAME) FvSimpleFileSystemComponentNameGetDriverName,
+ (EFI_COMPONENT_NAME2_GET_CONTROLLER_NAME) FvSimpleFileSystemComponentNameGetControllerName,
+ "en"
+};
+
+//
+// Driver name table for FvSimpleFileSystem module.
+// It is shared by the implementation of ComponentName & ComponentName2 Protocol.
+//
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE mFvSimpleFileSystemDriverNameTable[] = {
+ {
+ "eng;en",
+ (CHAR16 *)L"Fv Simple File System Driver"
+ },
+ {
+ NULL,
+ NULL
+ }
+};
+
+/**
+ Retrieves a Unicode string that is the user readable name of the driver.
+
+ This function retrieves the user readable name of a driver in the form of a
+ Unicode string. If the driver specified by This has a user readable name in
+ the language specified by Language, then a pointer to the driver name is
+ returned in DriverName, and EFI_SUCCESS is returned. If the driver specified
+ by This does not support the language specified by Language,
+ then EFI_UNSUPPORTED is returned.
+
+ @param This[in] A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or
+ EFI_COMPONENT_NAME_PROTOCOL instance.
+
+ @param Language[in] A pointer to a Null-terminated ASCII string
+ array indicating the language. This is the
+ language of the driver name that the caller is
+ requesting, and it must match one of the
+ languages specified in SupportedLanguages. The
+ number of languages supported by a driver is up
+ to the driver writer. Language is specified
+ in RFC 4646 or ISO 639-2 language code format.
+
+ @param DriverName[out] A pointer to the Unicode string to return.
+ This Unicode string is the name of the
+ driver specified by This in the language
+ specified by Language.
+
+ @retval EFI_SUCCESS The Unicode string for the Driver specified by
+ This and the language specified by Language was
+ returned in DriverName.
+
+ @retval EFI_INVALID_PARAMETER Language is NULL.
+
+ @retval EFI_INVALID_PARAMETER DriverName is NULL.
+
+ @retval EFI_UNSUPPORTED The driver specified by This does not support
+ the language specified by Language.
+
+**/
+EFI_STATUS
+EFIAPI
+FvSimpleFileSystemComponentNameGetDriverName (
+ IN EFI_COMPONENT_NAME_PROTOCOL *This,
+ IN CHAR8 *Language,
+ OUT CHAR16 **DriverName
+ )
+{
+ return LookupUnicodeString2 (
+ Language,
+ This->SupportedLanguages,
+ mFvSimpleFileSystemDriverNameTable,
+ DriverName,
+ (BOOLEAN)(This == &gFvSimpleFileSystemComponentName)
+ );
+}
+
+/**
+ Retrieves a Unicode string that is the user readable name of the controller
+ that is being managed by a driver.
+
+ This function retrieves the user readable name of the controller specified by
+ ControllerHandle and ChildHandle in the form of a Unicode string. If the
+ driver specified by This has a user readable name in the language specified by
+ Language, then a pointer to the controller name is returned in ControllerName,
+ and EFI_SUCCESS is returned. If the driver specified by This is not currently
+ managing the controller specified by ControllerHandle and ChildHandle,
+ then EFI_UNSUPPORTED is returned. If the driver specified by This does not
+ support the language specified by Language, then EFI_UNSUPPORTED is returned.
+
+ @param This[in] A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or
+ EFI_COMPONENT_NAME_PROTOCOL instance.
+
+ @param ControllerHandle[in] The handle of a controller that the driver
+ specified by This is managing. This handle
+ specifies the controller whose name is to be
+ returned.
+
+ @param ChildHandle[in] The handle of the child controller to retrieve
+ the name of. This is an optional parameter that
+ may be NULL. It will be NULL for device
+ drivers. It will also be NULL for a bus drivers
+ that wish to retrieve the name of the bus
+ controller. It will not be NULL for a bus
+ driver that wishes to retrieve the name of a
+ child controller.
+
+ @param Language[in] A pointer to a Null-terminated ASCII string
+ array indicating the language. This is the
+ language of the driver name that the caller is
+ requesting, and it must match one of the
+ languages specified in SupportedLanguages. The
+ number of languages supported by a driver is up
+ to the driver writer. Language is specified in
+ RFC 4646 or ISO 639-2 language code format.
+
+ @param ControllerName[out] A pointer to the Unicode string to return.
+ This Unicode string is the name of the
+ controller specified by ControllerHandle and
+ ChildHandle in the language specified by
+ Language from the point of view of the driver
+ specified by This.
+
+ @retval EFI_SUCCESS The Unicode string for the user readable name in
+ the language specified by Language for the
+ driver specified by This was returned in
+ DriverName.
+
+ @retval EFI_INVALID_PARAMETER ControllerHandle is NULL.
+
+ @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid
+ EFI_HANDLE.
+
+ @retval EFI_INVALID_PARAMETER Language is NULL.
+
+ @retval EFI_INVALID_PARAMETER ControllerName is NULL.
+
+ @retval EFI_UNSUPPORTED The driver specified by This is not currently
+ managing the controller specified by
+ ControllerHandle and ChildHandle.
+
+ @retval EFI_UNSUPPORTED The driver specified by This does not support
+ the language specified by Language.
+
+**/
+EFI_STATUS
+EFIAPI
+FvSimpleFileSystemComponentNameGetControllerName (
+ IN EFI_COMPONENT_NAME_PROTOCOL *This,
+ IN EFI_HANDLE ControllerHandle,
+ IN EFI_HANDLE ChildHandle OPTIONAL,
+ IN CHAR8 *Language,
+ OUT CHAR16 **ControllerName
+ )
+{
+ return EFI_UNSUPPORTED;
+}
diff --git a/MdeModulePkg/Universal/FvSimpleFileSystemDxe/FvSimpleFileSystem.c b/MdeModulePkg/Universal/FvSimpleFileSystemDxe/FvSimpleFileSystem.c
new file mode 100644
index 0000000000..019be26757
--- /dev/null
+++ b/MdeModulePkg/Universal/FvSimpleFileSystemDxe/FvSimpleFileSystem.c
@@ -0,0 +1,981 @@
+/** @file
+ This driver uses the EFI_FIRMWARE_VOLUME2_PROTOCOL to expose files in firmware
+ volumes via the the EFI_SIMPLE_FILESYSTEM_PROTOCOL and EFI_FILE_PROTOCOL.
+
+ It will expose a single directory, containing one file for each file in the firmware
+ volume. If a file has a UI section, its contents will be used as a filename.
+ Otherwise, a string representation of the GUID will be used.
+ Files of an executable type (That is PEIM, DRIVER, COMBINED_PEIM_DRIVER and APPLICATION)
+ will have ".efi" added to their filename.
+
+ Its primary intended use is to be able to start EFI applications embedded in FVs
+ from the UEFI shell. It is entirely read-only.
+
+Copyright (c) 2014, ARM Limited. All rights reserved.
+Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>
+
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include "FvSimpleFileSystemInternal.h"
+
+//
+// Template for EFI_FILE_SYSTEM_INFO data structure.
+//
+EFI_FILE_SYSTEM_INFO mFsInfoTemplate = {
+ 0, // Populate at runtime
+ TRUE, // Read-only
+ 0, // Don't know volume size
+ 0, // No free space
+ 0, // Don't know block size
+ L"" // Populate at runtime
+};
+
+//
+// Template for EFI_FILE_PROTOCOL data structure.
+//
+EFI_FILE_PROTOCOL mFileSystemTemplate = {
+ EFI_FILE_PROTOCOL_REVISION,
+ FvSimpleFileSystemOpen,
+ FvSimpleFileSystemClose,
+ FvSimpleFileSystemDelete,
+ FvSimpleFileSystemRead,
+ FvSimpleFileSystemWrite,
+ FvSimpleFileSystemGetPosition,
+ FvSimpleFileSystemSetPosition,
+ FvSimpleFileSystemGetInfo,
+ FvSimpleFileSystemSetInfo,
+ FvSimpleFileSystemFlush
+};
+
+/**
+ Find and call ReadSection on the first section found of an executable type.
+
+ @param FvProtocol A pointer to the EFI_FIRMWARE_VOLUME2_PROTOCOL instance.
+ @param FvFileInfo A pointer to the FV_FILESYSTEM_FILE_INFO instance that is a struct
+ representing a file's info.
+ @param BufferSize Pointer to a caller-allocated UINTN. It indicates the size of
+ the memory represented by *Buffer.
+ @param Buffer Pointer to a pointer to a data buffer to contain file content.
+
+ @retval EFI_SUCCESS The call completed successfully.
+ @retval EFI_WARN_BUFFER_TOO_SMALL The buffer is too small to contain the requested output.
+ @retval EFI_ACCESS_DENIED The firmware volume is configured to disallow reads.
+ @retval EFI_NOT_FOUND The requested file was not found in the firmware volume.
+ @retval EFI_DEVICE_ERROR A hardware error occurred when attempting toaccess the firmware volume.
+
+**/
+EFI_STATUS
+FvFsFindExecutableSection (
+ IN EFI_FIRMWARE_VOLUME2_PROTOCOL *FvProtocol,
+ IN FV_FILESYSTEM_FILE_INFO *FvFileInfo,
+ IN OUT UINTN *BufferSize,
+ IN OUT VOID **Buffer
+ )
+{
+ EFI_SECTION_TYPE SectionType;
+ UINT32 AuthenticationStatus;
+ EFI_STATUS Status;
+
+ for (SectionType = EFI_SECTION_PE32; SectionType <= EFI_SECTION_TE; SectionType++) {
+ Status = FvProtocol->ReadSection (
+ FvProtocol,
+ &FvFileInfo->NameGuid,
+ SectionType,
+ 0,
+ Buffer,
+ BufferSize,
+ &AuthenticationStatus
+ );
+ if (Status != EFI_NOT_FOUND) {
+ return Status;
+ }
+ }
+
+ return EFI_NOT_FOUND;
+}
+
+/**
+ Get the size of the buffer that will be returned by FvFsReadFile.
+
+ @param FvProtocol A pointer to the EFI_FIRMWARE_VOLUME2_PROTOCOL instance.
+ @param FvFileInfo A pointer to the FV_FILESYSTEM_FILE_INFO instance that is a struct
+ representing a file's info.
+
+ @retval EFI_SUCCESS The file size was gotten correctly.
+ @retval Others The file size wasn't gotten correctly.
+
+**/
+EFI_STATUS
+FvFsGetFileSize (
+ IN EFI_FIRMWARE_VOLUME2_PROTOCOL *FvProtocol,
+ IN OUT FV_FILESYSTEM_FILE_INFO *FvFileInfo
+ )
+{
+ UINT32 AuthenticationStatus;
+ EFI_FV_FILETYPE FoundType;
+ EFI_FV_FILE_ATTRIBUTES Attributes;
+ EFI_STATUS Status;
+ UINT8 IgnoredByte;
+ VOID *IgnoredPtr;
+
+ //
+ // To get the size of a section, we pass 0 for BufferSize. But we can't pass
+ // NULL for Buffer, as that will cause a return of INVALID_PARAMETER, and we
+ // can't pass NULL for *Buffer, as that will cause the callee to allocate
+ // a buffer of the sections size.
+ //
+ IgnoredPtr = &IgnoredByte;
+ FvFileInfo->FileInfo.FileSize = 0;
+
+ if (FV_FILETYPE_IS_EXECUTABLE (FvFileInfo->Type)) {
+ //
+ // Get the size of the first executable section out of the file.
+ //
+ Status = FvFsFindExecutableSection (FvProtocol, FvFileInfo, (UINTN*)&FvFileInfo->FileInfo.FileSize, &IgnoredPtr);
+ if (Status == EFI_WARN_BUFFER_TOO_SMALL) {
+ return EFI_SUCCESS;
+ }
+ } else if (FvFileInfo->Type == EFI_FV_FILETYPE_FREEFORM) {
+ //
+ // Try to get the size of a raw section out of the file
+ //
+ Status = FvProtocol->ReadSection (
+ FvProtocol,
+ &FvFileInfo->NameGuid,
+ EFI_SECTION_RAW,
+ 0,
+ &IgnoredPtr,
+ (UINTN*)&FvFileInfo->FileInfo.FileSize,
+ &AuthenticationStatus
+ );
+ if (Status == EFI_WARN_BUFFER_TOO_SMALL) {
+ return EFI_SUCCESS;
+ }
+ if (EFI_ERROR (Status)) {
+ //
+ // Didn't find a raw section, just return the whole file's size.
+ //
+ return FvProtocol->ReadFile (
+ FvProtocol,
+ &FvFileInfo->NameGuid,
+ NULL,
+ (UINTN*)&FvFileInfo->FileInfo.FileSize,
+ &FoundType,
+ &Attributes,
+ &AuthenticationStatus
+ );
+ }
+ } else {
+ //
+ // Get the size of the entire file
+ //
+ return FvProtocol->ReadFile (
+ FvProtocol,
+ &FvFileInfo->NameGuid,
+ NULL,
+ (UINTN*)&FvFileInfo->FileInfo.FileSize,
+ &FoundType,
+ &Attributes,
+ &AuthenticationStatus
+ );
+ }
+
+ return Status;
+}
+
+/**
+ Helper function to read a file.
+
+ The data returned depends on the type of the underlying FV file:
+ - For executable types, the first section found that contains executable code is returned.
+ - For files of type FREEFORM, the driver attempts to return the first section of type RAW.
+ If none is found, the entire contents of the FV file are returned.
+ - On all other files the entire contents of the FV file is returned, as by
+ EFI_FIRMWARE_VOLUME2_PROTOCOL.ReadFile.
+
+ @param FvProtocol A pointer to the EFI_FIRMWARE_VOLUME2_PROTOCOL instance.
+ @param FvFileInfo A pointer to the FV_FILESYSTEM_FILE_INFO instance that is a struct
+ representing a file's info.
+ @param BufferSize Pointer to a caller-allocated UINTN. It indicates the size of
+ the memory represented by *Buffer.
+ @param Buffer Pointer to a pointer to a data buffer to contain file content.
+
+ @retval EFI_SUCCESS The call completed successfully.
+ @retval EFI_WARN_BUFFER_TOO_SMALL The buffer is too small to contain the requested output.
+ @retval EFI_ACCESS_DENIED The firmware volume is configured to disallow reads.
+ @retval EFI_NOT_FOUND The requested file was not found in the firmware volume.
+ @retval EFI_DEVICE_ERROR A hardware error occurred when attempting toaccess the firmware volume.
+
+**/
+EFI_STATUS
+FvFsReadFile (
+ IN EFI_FIRMWARE_VOLUME2_PROTOCOL *FvProtocol,
+ IN FV_FILESYSTEM_FILE_INFO *FvFileInfo,
+ IN OUT UINTN *BufferSize,
+ IN OUT VOID **Buffer
+ )
+{
+ UINT32 AuthenticationStatus;
+ EFI_FV_FILETYPE FoundType;
+ EFI_FV_FILE_ATTRIBUTES Attributes;
+ EFI_STATUS Status;
+
+ if (FV_FILETYPE_IS_EXECUTABLE (FvFileInfo->Type)) {
+ //
+ // Read the first executable section out of the file.
+ //
+ Status = FvFsFindExecutableSection (FvProtocol, FvFileInfo, BufferSize, Buffer);
+ } else if (FvFileInfo->Type == EFI_FV_FILETYPE_FREEFORM) {
+ //
+ // Try to read a raw section out of the file
+ //
+ Status = FvProtocol->ReadSection (
+ FvProtocol,
+ &FvFileInfo->NameGuid,
+ EFI_SECTION_RAW,
+ 0,
+ Buffer,
+ BufferSize,
+ &AuthenticationStatus
+ );
+ if (EFI_ERROR (Status)) {
+ //
+ // Didn't find a raw section, just return the whole file.
+ //
+ Status = FvProtocol->ReadFile (
+ FvProtocol,
+ &FvFileInfo->NameGuid,
+ Buffer,
+ BufferSize,
+ &FoundType,
+ &Attributes,
+ &AuthenticationStatus
+ );
+ }
+ } else {
+ //
+ // Read the entire file
+ //
+ Status = FvProtocol->ReadFile (
+ FvProtocol,
+ &FvFileInfo->NameGuid,
+ Buffer,
+ BufferSize,
+ &FoundType,
+ &Attributes,
+ &AuthenticationStatus
+ );
+ }
+
+ return Status;
+}
+
+/**
+ Helper function for populating an EFI_FILE_INFO for a file.
+
+ Note the CreateTime, LastAccessTime and ModificationTime fields in EFI_FILE_INFO
+ are full zero as FV2 protocol has no corresponding info to fill.
+
+ @param FvFileInfo A pointer to the FV_FILESYSTEM_FILE_INFO instance that is a struct
+ representing a file's info.
+ @param BufferSize Pointer to a caller-allocated UINTN. It indicates the size of
+ the memory represented by FileInfo.
+ @param FileInfo A pointer to EFI_FILE_INFO to contain the returned file info.
+
+ @retval EFI_SUCCESS The call completed successfully.
+ @retval EFI_BUFFER_TOO_SMALL The buffer is too small to contain the requested output.
+
+**/
+EFI_STATUS
+FvFsGetFileInfo (
+ IN FV_FILESYSTEM_FILE_INFO *FvFileInfo,
+ IN OUT UINTN *BufferSize,
+ OUT EFI_FILE_INFO *FileInfo
+ )
+{
+ UINTN InfoSize;
+
+ InfoSize = (UINTN)FvFileInfo->FileInfo.Size;
+ if (*BufferSize < InfoSize) {
+ *BufferSize = InfoSize;
+ return EFI_BUFFER_TOO_SMALL;
+ }
+
+ //
+ // Initialize FileInfo
+ //
+ CopyMem (FileInfo, &FvFileInfo->FileInfo, InfoSize);
+
+ *BufferSize = InfoSize;
+ return EFI_SUCCESS;
+}
+
+/**
+ Removes the last directory or file entry in a path by changing the last
+ L'\' to a CHAR_NULL.
+
+ @param Path The pointer to the path to modify.
+
+ @retval FALSE Nothing was found to remove.
+ @retval TRUE A directory or file was removed.
+
+**/
+BOOLEAN
+EFIAPI
+RemoveLastItemFromPath (
+ IN OUT CHAR16 *Path
+ )
+{
+ CHAR16 *Walker;
+ CHAR16 *LastSlash;
+ //
+ // get directory name from path... ('chop' off extra)
+ //
+ for ( Walker = Path, LastSlash = NULL
+ ; Walker != NULL && *Walker != CHAR_NULL
+ ; Walker++
+ ){
+ if (*Walker == L'\\' && *(Walker + 1) != CHAR_NULL) {
+ LastSlash = Walker + 1;
+ }
+ }
+
+ if (LastSlash != NULL) {
+ *LastSlash = CHAR_NULL;
+ return (TRUE);
+ }
+
+ return (FALSE);
+}
+
+/**
+ Function to clean up paths.
+
+ - Single periods in the path are removed.
+ - Double periods in the path are removed along with a single parent directory.
+ - Forward slashes L'/' are converted to backward slashes L'\'.
+
+ This will be done inline and the existing buffer may be larger than required
+ upon completion.
+
+ @param Path The pointer to the string containing the path.
+
+ @retval NULL An error occured.
+ @return Path in all other instances.
+
+**/
+CHAR16*
+EFIAPI
+TrimFilePathToAbsolutePath (
+ IN CHAR16 *Path
+ )
+{
+ CHAR16 *TempString;
+ UINTN TempSize;
+
+ if (Path == NULL) {
+ return NULL;
+ }
+
+ //
+ // Fix up the '/' vs '\'
+ //
+ for (TempString = Path ; (TempString != NULL) && (*TempString != CHAR_NULL); TempString++) {
+ if (*TempString == L'/') {
+ *TempString = L'\\';
+ }
+ }
+
+ //
+ // Fix up the ..
+ //
+ while ((TempString = StrStr (Path, L"\\..\\")) != NULL) {
+ *TempString = CHAR_NULL;
+ TempString += 4;
+ RemoveLastItemFromPath (Path);
+ TempSize = StrSize (TempString);
+ CopyMem (Path + StrLen (Path), TempString, TempSize);
+ }
+
+ if (((TempString = StrStr (Path, L"\\..")) != NULL) && (*(TempString + 3) == CHAR_NULL)) {
+ *TempString = CHAR_NULL;
+ RemoveLastItemFromPath (Path);
+ }
+
+ //
+ // Fix up the .
+ //
+ while ((TempString = StrStr (Path, L"\\.\\")) != NULL) {
+ *TempString = CHAR_NULL;
+ TempString += 2;
+ TempSize = StrSize (TempString);
+ CopyMem(Path + StrLen (Path), TempString, TempSize);
+ }
+
+ if (((TempString = StrStr (Path, L"\\.")) != NULL) && (*(TempString + 2) == CHAR_NULL)) {
+ *(TempString + 1) = CHAR_NULL;
+ }
+
+ while ((TempString = StrStr (Path, L"\\\\")) != NULL) {
+ *TempString = CHAR_NULL;
+ TempString += 1;
+ TempSize = StrSize(TempString);
+ CopyMem(Path + StrLen(Path), TempString, TempSize);
+ }
+
+ if (((TempString = StrStr(Path, L"\\\\")) != NULL) && (*(TempString + 1) == CHAR_NULL)) {
+ *(TempString) = CHAR_NULL;
+ }
+
+ return Path;
+}
+
+/**
+ Opens a new file relative to the source file's location.
+
+ @param This A pointer to the EFI_FILE_PROTOCOL instance that is the file
+ handle to the source location. This would typically be an open
+ handle to a directory.
+ @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.
+
+ @retval EFI_SUCCESS The file was opened.
+ @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.
+
+**/
+EFI_STATUS
+EFIAPI
+FvSimpleFileSystemOpen (
+ IN EFI_FILE_PROTOCOL *This,
+ OUT EFI_FILE_PROTOCOL **NewHandle,
+ IN CHAR16 *FileName,
+ IN UINT64 OpenMode,
+ IN UINT64 Attributes
+ )
+{
+ FV_FILESYSTEM_INSTANCE *Instance;
+ FV_FILESYSTEM_FILE *File;
+ FV_FILESYSTEM_FILE *NewFile;
+ FV_FILESYSTEM_FILE_INFO *FvFileInfo;
+ LIST_ENTRY *FvFileInfoLink;
+
+ //
+ // Check for a valid mode
+ //
+ switch (OpenMode) {
+ case EFI_FILE_MODE_READ:
+ break;
+
+ default:
+ return EFI_WRITE_PROTECTED;
+ }
+
+ File = FVFS_FILE_FROM_FILE_THIS (This);
+ Instance = File->Instance;
+
+ FileName = TrimFilePathToAbsolutePath (FileName);
+ if (FileName == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (FileName[0] == L'\\') {
+ FileName++;
+ }
+
+ //
+ // Check for opening root
+ //
+ if (StrCmp (FileName, L".") == 0 || StrCmp (FileName, L"") == 0) {
+ NewFile = AllocateZeroPool (sizeof (FV_FILESYSTEM_FILE));
+ if (NewFile == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+ NewFile->Signature = FVFS_FILE_SIGNATURE;
+ NewFile->Instance = Instance;
+ NewFile->FvFileInfo = File->FvFileInfo;
+ CopyMem (&NewFile->FileProtocol, &mFileSystemTemplate, sizeof (mFileSystemTemplate));
+ InitializeListHead (&NewFile->Link);
+ InsertHeadList (&Instance->FileHead, &NewFile->Link);
+
+ NewFile->DirReadNext = FVFS_GET_FIRST_FILE_INFO (Instance);
+
+ *NewHandle = &NewFile->FileProtocol;
+ return EFI_SUCCESS;
+ }
+
+ //
+ // Do a linear search for a file in the FV with a matching filename
+ //
+ for (FvFileInfoLink = GetFirstNode (&Instance->FileInfoHead);
+ !IsNull (&Instance->FileInfoHead, FvFileInfoLink);
+ FvFileInfoLink = GetNextNode (&Instance->FileInfoHead, FvFileInfoLink)) {
+ FvFileInfo = FVFS_FILE_INFO_FROM_LINK (FvFileInfoLink);
+ if (mUnicodeCollation->StriColl (mUnicodeCollation, &FvFileInfo->FileInfo.FileName[0], FileName) == 0) {
+ NewFile = AllocateZeroPool (sizeof (FV_FILESYSTEM_FILE));
+ if (NewFile == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ NewFile->Signature = FVFS_FILE_SIGNATURE;
+ NewFile->Instance = Instance;
+ NewFile->FvFileInfo = FvFileInfo;
+ CopyMem (&NewFile->FileProtocol, &mFileSystemTemplate, sizeof (mFileSystemTemplate));
+ InitializeListHead (&NewFile->Link);
+ InsertHeadList (&Instance->FileHead, &NewFile->Link);
+
+ *NewHandle = &NewFile->FileProtocol;
+ return EFI_SUCCESS;
+ }
+ }
+
+ return EFI_NOT_FOUND;
+}
+
+/**
+ Closes a specified file handle.
+
+ @param This A pointer to the EFI_FILE_PROTOCOL instance that is the file
+ handle to close.
+
+ @retval EFI_SUCCESS The file was closed.
+
+**/
+EFI_STATUS
+EFIAPI
+FvSimpleFileSystemClose (
+ IN EFI_FILE_PROTOCOL *This
+ )
+{
+ FV_FILESYSTEM_INSTANCE *Instance;
+ FV_FILESYSTEM_FILE *File;
+
+ File = FVFS_FILE_FROM_FILE_THIS (This);
+ Instance = File->Instance;
+
+ if (File != Instance->Root) {
+ RemoveEntryList (&File->Link);
+ FreePool (File);
+ }
+ return EFI_SUCCESS;
+}
+
+/**
+ 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 BufferSize 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.
+ @param Buffer The buffer into which the data is read.
+
+ @retval EFI_SUCCESS Data was read.
+ @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_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.
+
+**/
+EFI_STATUS
+EFIAPI
+FvSimpleFileSystemRead (
+ IN EFI_FILE_PROTOCOL *This,
+ IN OUT UINTN *BufferSize,
+ OUT VOID *Buffer
+ )
+{
+ FV_FILESYSTEM_INSTANCE *Instance;
+ FV_FILESYSTEM_FILE *File;
+ EFI_STATUS Status;
+ LIST_ENTRY *FvFileInfoLink;
+ VOID *FileBuffer;
+ UINTN FileSize;
+
+ File = FVFS_FILE_FROM_FILE_THIS (This);
+ Instance = File->Instance;
+
+ if (File->FvFileInfo == Instance->Root->FvFileInfo) {
+ if (File->DirReadNext) {
+ //
+ // Directory read: populate Buffer with an EFI_FILE_INFO
+ //
+ Status = FvFsGetFileInfo (File->DirReadNext, BufferSize, Buffer);
+ if (!EFI_ERROR (Status)) {
+ //
+ // Successfully read a directory entry, now update the pointer to the
+ // next file, which will be read on the next call to this function
+ //
+ FvFileInfoLink = GetNextNode (&Instance->FileInfoHead, &File->DirReadNext->Link);
+ if (IsNull (&Instance->FileInfoHead, FvFileInfoLink)) {
+ //
+ // No more files left
+ //
+ File->DirReadNext = NULL;
+ } else {
+ File->DirReadNext = FVFS_FILE_INFO_FROM_LINK (FvFileInfoLink);
+ }
+ }
+ return Status;
+ } else {
+ //
+ // Directory read. All entries have been read, so return a zero-size
+ // buffer.
+ //
+ *BufferSize = 0;
+ return EFI_SUCCESS;
+ }
+ } else {
+ FileSize = (UINTN)File->FvFileInfo->FileInfo.FileSize;
+
+ FileBuffer = AllocateZeroPool (FileSize);
+ if (FileBuffer == NULL) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ Status = FvFsReadFile (File->Instance->FvProtocol, File->FvFileInfo, &FileSize, &FileBuffer);
+ if (EFI_ERROR (Status)) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ if (*BufferSize + File->Position > FileSize) {
+ *BufferSize = (UINTN)(FileSize - File->Position);
+ }
+
+ CopyMem (Buffer, (UINT8*)FileBuffer + File->Position, *BufferSize);
+ File->Position += *BufferSize;
+
+ return EFI_SUCCESS;
+ }
+}
+
+/**
+ 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 BufferSize On input, the size of the Buffer. On output, the amount of data
+ actually written. In both cases, the size is measured in bytes.
+ @param Buffer The buffer of data to write.
+
+ @retval EFI_SUCCESS Data was written.
+ @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.
+
+**/
+EFI_STATUS
+EFIAPI
+FvSimpleFileSystemWrite (
+ IN EFI_FILE_PROTOCOL *This,
+ IN OUT UINTN *BufferSize,
+ IN VOID *Buffer
+ )
+{
+ FV_FILESYSTEM_INSTANCE *Instance;
+ FV_FILESYSTEM_FILE *File;
+
+ File = FVFS_FILE_FROM_FILE_THIS (This);
+ Instance = File->Instance;
+
+ if (File->FvFileInfo == Instance->Root->FvFileInfo) {
+ return EFI_UNSUPPORTED;
+ } else {
+ return EFI_WRITE_PROTECTED;
+ }
+}
+
+/**
+ Returns a file's current position.
+
+ @param This A pointer to the EFI_FILE_PROTOCOL instance that is the file
+ handle to get the current position on.
+ @param Position The address to return the file's current position value.
+
+ @retval EFI_SUCCESS The position was returned.
+ @retval EFI_UNSUPPORTED The request is not valid on open directories.
+ @retval EFI_DEVICE_ERROR An attempt was made to get the position from a deleted file.
+
+**/
+EFI_STATUS
+EFIAPI
+FvSimpleFileSystemGetPosition (
+ IN EFI_FILE_PROTOCOL *This,
+ OUT UINT64 *Position
+ )
+{
+ FV_FILESYSTEM_INSTANCE *Instance;
+ FV_FILESYSTEM_FILE *File;
+
+ File = FVFS_FILE_FROM_FILE_THIS (This);
+ Instance = File->Instance;
+
+ if (File->FvFileInfo == Instance->Root->FvFileInfo) {
+ return EFI_UNSUPPORTED;
+ } else {
+ *Position = File->Position;
+ return EFI_SUCCESS;
+ }
+}
+
+/**
+ Sets a file's current position.
+
+ @param This A pointer to the EFI_FILE_PROTOCOL instance that is the
+ file handle to set the requested position on.
+ @param Position The byte position from the start of the file to set.
+
+ @retval EFI_SUCCESS The position was set.
+ @retval EFI_UNSUPPORTED The seek request for nonzero is not valid on open
+ directories.
+ @retval EFI_DEVICE_ERROR An attempt was made to set the position of a deleted file.
+
+**/
+EFI_STATUS
+EFIAPI
+FvSimpleFileSystemSetPosition (
+ IN EFI_FILE_PROTOCOL *This,
+ IN UINT64 Position
+ )
+{
+ FV_FILESYSTEM_INSTANCE *Instance;
+ FV_FILESYSTEM_FILE *File;
+
+ File = FVFS_FILE_FROM_FILE_THIS (This);
+ Instance = File->Instance;
+
+ if (File->FvFileInfo == Instance->Root->FvFileInfo) {
+ if (Position != 0) {
+ return EFI_UNSUPPORTED;
+ }
+ //
+ // Reset directory position to first entry
+ //
+ File->DirReadNext = FVFS_GET_FIRST_FILE_INFO (Instance);
+ } else if (Position == 0xFFFFFFFFFFFFFFFFull) {
+ File->Position = File->FvFileInfo->FileInfo.FileSize;
+ } else {
+ File->Position = Position;
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ 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.
+
+ @retval EFI_SUCCESS The data was flushed.
+ @retval EFI_NO_MEDIA The device has no medium.
+ @retval EFI_DEVICE_ERROR The device reported an error.
+ @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted.
+ @retval EFI_WRITE_PROTECTED The file or medium is write-protected.
+ @retval EFI_ACCESS_DENIED The file was opened read-only.
+ @retval EFI_VOLUME_FULL The volume is full.
+
+**/
+EFI_STATUS
+EFIAPI
+FvSimpleFileSystemFlush (
+ IN EFI_FILE_PROTOCOL *This
+ )
+{
+ return EFI_WRITE_PROTECTED;
+}
+
+/**
+ Close and delete the file handle.
+
+ @param This A pointer to the EFI_FILE_PROTOCOL instance that is the
+ handle to the file to delete.
+
+ @retval EFI_SUCCESS The file was closed and deleted, and the handle was closed.
+ @retval EFI_WARN_DELETE_FAILURE The handle was closed, but the file was not deleted.
+
+**/
+EFI_STATUS
+EFIAPI
+FvSimpleFileSystemDelete (
+ IN EFI_FILE_PROTOCOL *This
+ )
+{
+ EFI_STATUS Status;
+
+ Status = FvSimpleFileSystemClose (This);
+ ASSERT_EFI_ERROR (Status);
+
+ return EFI_WARN_DELETE_FAILURE;
+}
+
+/**
+ Returns information about a file.
+
+ @param This A pointer to the EFI_FILE_PROTOCOL instance that is the file
+ handle the requested information is for.
+ @param InformationType The type identifier for the information being requested.
+ @param BufferSize On input, the size of Buffer. On output, the amount of data
+ returned in Buffer. In both cases, the size is measured in bytes.
+ @param Buffer A pointer to the data buffer to return. The buffer's type is
+ indicated by InformationType.
+
+ @retval EFI_SUCCESS The information was returned.
+ @retval EFI_UNSUPPORTED The InformationType is not known.
+ @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_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.
+**/
+EFI_STATUS
+EFIAPI
+FvSimpleFileSystemGetInfo (
+ IN EFI_FILE_PROTOCOL *This,
+ IN EFI_GUID *InformationType,
+ IN OUT UINTN *BufferSize,
+ OUT VOID *Buffer
+ )
+{
+ FV_FILESYSTEM_FILE *File;
+ EFI_FILE_SYSTEM_INFO *FsInfoOut;
+ EFI_FILE_SYSTEM_VOLUME_LABEL *FsVolumeLabel;
+ FV_FILESYSTEM_INSTANCE *Instance;
+ UINTN Size;
+ EFI_STATUS Status;
+
+ File = FVFS_FILE_FROM_FILE_THIS (This);
+
+ if (CompareGuid (InformationType, &gEfiFileSystemInfoGuid)) {
+ //
+ // Return filesystem info
+ //
+ Instance = File->Instance;
+
+ Size = sizeof (EFI_FILE_SYSTEM_INFO) + StrSize (Instance->VolumeLabel) - sizeof (CHAR16);
+
+ if (*BufferSize < Size) {
+ *BufferSize = Size;
+ return EFI_BUFFER_TOO_SMALL;
+ }
+
+ //
+ // Cast output buffer for convenience
+ //
+ FsInfoOut = (EFI_FILE_SYSTEM_INFO *) Buffer;
+
+ CopyMem (FsInfoOut, &mFsInfoTemplate, sizeof (EFI_FILE_SYSTEM_INFO));
+ Status = StrnCpyS (FsInfoOut->VolumeLabel, (*BufferSize - OFFSET_OF (EFI_FILE_SYSTEM_INFO, VolumeLabel)) / sizeof (CHAR16), Instance->VolumeLabel, StrLen (Instance->VolumeLabel));
+ ASSERT_EFI_ERROR (Status);
+ FsInfoOut->Size = Size;
+ return Status;
+ } else if (CompareGuid (InformationType, &gEfiFileInfoGuid)) {
+ //
+ // Return file info
+ //
+ return FvFsGetFileInfo (File->FvFileInfo, BufferSize, (EFI_FILE_INFO *) Buffer);
+ } else if (CompareGuid (InformationType, &gEfiFileSystemVolumeLabelInfoIdGuid)) {
+ //
+ // Return Volume Label
+ //
+ Instance = File->Instance;
+ Size = sizeof (EFI_FILE_SYSTEM_VOLUME_LABEL) + StrSize (Instance->VolumeLabel) - sizeof (CHAR16);;
+ if (*BufferSize < Size) {
+ *BufferSize = Size;
+ return EFI_BUFFER_TOO_SMALL;
+ }
+
+ FsVolumeLabel = (EFI_FILE_SYSTEM_VOLUME_LABEL*) Buffer;
+ Status = StrnCpyS (FsVolumeLabel->VolumeLabel, (*BufferSize - OFFSET_OF (EFI_FILE_SYSTEM_VOLUME_LABEL, VolumeLabel)) / sizeof (CHAR16), Instance->VolumeLabel, StrLen (Instance->VolumeLabel));
+ ASSERT_EFI_ERROR (Status);
+ return Status;
+ } else {
+ return EFI_UNSUPPORTED;
+ }
+}
+
+/**
+ Sets information about a file.
+
+ @param This A pointer to the EFI_FILE_PROTOCOL instance that is the file
+ handle the information is for.
+ @param InformationType The type identifier for the information being set.
+ @param BufferSize The size, in bytes, of Buffer.
+ @param Buffer A pointer to the data buffer to write. The buffer's type is
+ indicated by InformationType.
+
+ @retval EFI_SUCCESS The information was set.
+ @retval EFI_UNSUPPORTED The InformationType is not known.
+ @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 InformationType is EFI_FILE_INFO_ID and the media is
+ read-only.
+ @retval EFI_WRITE_PROTECTED InformationType is EFI_FILE_PROTOCOL_SYSTEM_INFO_ID
+ and the media is read only.
+ @retval EFI_WRITE_PROTECTED InformationType is EFI_FILE_SYSTEM_VOLUME_LABEL_ID
+ and the media is read-only.
+ @retval EFI_ACCESS_DENIED An attempt is made to change the name of a file to a
+ file that is already present.
+ @retval EFI_ACCESS_DENIED An attempt is being made to change the EFI_FILE_DIRECTORY
+ Attribute.
+ @retval EFI_ACCESS_DENIED An attempt is being made to change the size of a directory.
+ @retval EFI_ACCESS_DENIED InformationType is EFI_FILE_INFO_ID and the file was opened
+ read-only and an attempt is being made to modify a field
+ other than Attribute.
+ @retval EFI_VOLUME_FULL The volume is full.
+ @retval EFI_BAD_BUFFER_SIZE BufferSize is smaller than the size of the type indicated
+ by InformationType.
+
+**/
+EFI_STATUS
+EFIAPI
+FvSimpleFileSystemSetInfo (
+ IN EFI_FILE_PROTOCOL *This,
+ IN EFI_GUID *InformationType,
+ IN UINTN BufferSize,
+ IN VOID *Buffer
+ )
+{
+ if (CompareGuid (InformationType, &gEfiFileSystemInfoGuid) ||
+ CompareGuid (InformationType, &gEfiFileInfoGuid) ||
+ CompareGuid (InformationType, &gEfiFileSystemVolumeLabelInfoIdGuid)) {
+ return EFI_WRITE_PROTECTED;
+ }
+
+ return EFI_UNSUPPORTED;
+}
+
diff --git a/MdeModulePkg/Universal/FvSimpleFileSystemDxe/FvSimpleFileSystem.uni b/MdeModulePkg/Universal/FvSimpleFileSystemDxe/FvSimpleFileSystem.uni
new file mode 100644
index 0000000000..fc8c9291ab
--- /dev/null
+++ b/MdeModulePkg/Universal/FvSimpleFileSystemDxe/FvSimpleFileSystem.uni
Binary files differ
diff --git a/MdeModulePkg/Universal/FvSimpleFileSystemDxe/FvSimpleFileSystemDxe.inf b/MdeModulePkg/Universal/FvSimpleFileSystemDxe/FvSimpleFileSystemDxe.inf
new file mode 100644
index 0000000000..a648c2efc8
--- /dev/null
+++ b/MdeModulePkg/Universal/FvSimpleFileSystemDxe/FvSimpleFileSystemDxe.inf
@@ -0,0 +1,74 @@
+## @file
+# Support for Simple File System over Firmware Volume.
+#
+# This driver uses the EFI_FIRMWARE_VOLUME2_PROTOCOL to expose files in firmware
+# volumes via the the EFI_SIMPLE_FILESYSTEM_PROTOCOL and EFI_FILE_PROTOCOL.
+#
+# It will expose a single directory, containing one file for each file in the firmware
+# volume. If a file has a UI section, its contents will be used as a filename.
+# Otherwise, a string representation of the GUID will be used.
+# Files of an executable type (That is PEIM, DRIVER, COMBINED_PEIM_DRIVER and APPLICATION)
+# will have ".efi" added to their filename.
+#
+# Its primary intended use is to be able to start EFI applications embedded in FVs
+# from the UEFI shell. It is entirely read-only.
+#
+# Copyright (c) 2014, ARM Ltd. All rights reserved.<BR>
+# Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>
+#
+# This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = FvSimpleFileSystem
+ MODULE_UNI_FILE = FvSimpleFileSystem.uni
+ FILE_GUID = 907125c0-a5f1-11e3-a3fe-a3198b49350c
+ MODULE_TYPE = UEFI_DRIVER
+ VERSION_STRING = 1.0
+ ENTRY_POINT = FvSimpleFileSystemEntryPoint
+
+[Sources]
+
+ ComponentName.c
+ FvSimpleFileSystem.c
+ FvSimpleFileSystemEntryPoint.c
+ FvSimpleFileSystemInternal.h
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+
+[LibraryClasses]
+ BaseLib
+ DevicePathLib
+ MemoryAllocationLib
+ PrintLib
+ UefiDriverEntryPoint
+ UefiLib
+
+[Pcd]
+ gEfiMdePkgTokenSpaceGuid.PcdUefiVariableDefaultPlatformLang ## SOMETIMES_CONSUMES
+ gEfiMdePkgTokenSpaceGuid.PcdUefiVariableDefaultLang ## SOMETIMES_CONSUMES
+
+[Guids]
+ gEfiFileInfoGuid ## SOMETIMES_CONSUMES ## UNDEFINED
+ gEfiFileSystemInfoGuid ## SOMETIMES_CONSUMES ## UNDEFINED
+ gEfiFileSystemVolumeLabelInfoIdGuid ## SOMETIMES_CONSUMES ## UNDEFINED
+
+[Protocols]
+ gEfiDevicePathProtocolGuid ## TO_START
+ gEfiFirmwareVolume2ProtocolGuid ## TO_START
+ gEfiUnicodeCollationProtocolGuid ## TO_START
+ gEfiUnicodeCollation2ProtocolGuid ## TO_START
+ gEfiSimpleFileSystemProtocolGuid ## BY_START
+
+[UserExtensions.TianoCore."ExtraFiles"]
+ FvSimpleFileSystemExtra.uni \ No newline at end of file
diff --git a/MdeModulePkg/Universal/FvSimpleFileSystemDxe/FvSimpleFileSystemEntryPoint.c b/MdeModulePkg/Universal/FvSimpleFileSystemDxe/FvSimpleFileSystemEntryPoint.c
new file mode 100644
index 0000000000..975ab88ca1
--- /dev/null
+++ b/MdeModulePkg/Universal/FvSimpleFileSystemDxe/FvSimpleFileSystemEntryPoint.c
@@ -0,0 +1,676 @@
+/** @file
+ This driver uses the EFI_FIRMWARE_VOLUME2_PROTOCOL to expose files in firmware
+ volumes via the the EFI_SIMPLE_FILESYSTEM_PROTOCOL and EFI_FILE_PROTOCOL.
+
+ It will expose a single directory, containing one file for each file in the firmware
+ volume. If a file has a UI section, its contents will be used as a filename.
+ Otherwise, a string representation of the GUID will be used.
+ Files of an executable type (That is PEIM, DRIVER, COMBINED_PEIM_DRIVER and APPLICATION)
+ will have ".efi" added to their filename.
+
+ Its primary intended use is to be able to start EFI applications embedded in FVs
+ from the UEFI shell. It is entirely read-only.
+
+Copyright (c) 2014, ARM Limited. All rights reserved.
+Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>
+
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include "FvSimpleFileSystemInternal.h"
+
+EFI_UNICODE_COLLATION_PROTOCOL *mUnicodeCollation = NULL;
+
+//
+// A Guid string is 32 hex characters with 4 hyphens and a NULL-terminated char: 37 characters total
+//
+#define GUID_STRING_SIZE (37 * sizeof (CHAR16))
+
+#define FVFS_VOLUME_LABEL_PREFIX L"Firmware Volume: "
+#define FVFS_VOLUME_LABEL_SIZE (sizeof (FVFS_VOLUME_LABEL_PREFIX) + GUID_STRING_SIZE - sizeof (CHAR16))
+#define FVFS_FALLBACK_VOLUME_LABEL L"Firmware Volume"
+
+//
+// Template for EFI_SIMPLE_FILE_SYSTEM_PROTOCOL data structure.
+//
+EFI_SIMPLE_FILE_SYSTEM_PROTOCOL mSimpleFsTemplate = {
+ EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_REVISION,
+ FvSimpleFileSystemOpenVolume
+};
+
+//
+// Template for EFI_DRIVER_BINDING_PROTOCOL data structure.
+//
+EFI_DRIVER_BINDING_PROTOCOL mDriverBinding = {
+ FvSimpleFileSystemDriverSupported,
+ FvSimpleFileSystemDriverStart,
+ FvSimpleFileSystemDriverStop,
+ 0,
+ NULL,
+ NULL
+};
+
+/**
+ Open the root directory on a volume.
+
+ @param This A pointer to the volume to open the root directory.
+ @param RootFile A pointer to the location to return the opened file handle for the
+ root directory.
+
+ @retval EFI_SUCCESS The device was opened.
+ @retval EFI_UNSUPPORTED This volume does not support the requested file system type.
+ @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_ACCESS_DENIED The service denied access to the file.
+ @retval EFI_OUT_OF_RESOURCES The volume was not opened due to lack of resources.
+ @retval EFI_MEDIA_CHANGED The device has a different medium in it or the medium is no
+ longer supported. Any existing file handles for this volume are
+ no longer valid. To access the files on the new medium, the
+ volume must be reopened with OpenVolume().
+
+**/
+EFI_STATUS
+EFIAPI
+FvSimpleFileSystemOpenVolume (
+ IN EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *This,
+ OUT EFI_FILE_PROTOCOL **RootFile
+ )
+{
+ EFI_STATUS Status;
+ FV_FILESYSTEM_FILE *Root;
+ CHAR16 *UiSection;
+ EFI_GUID NameGuid;
+ EFI_FV_FILE_ATTRIBUTES Attributes;
+ UINT32 Authentication;
+ UINTN Key;
+ EFI_FV_FILETYPE FileType;
+ UINTN Size;
+ FV_FILESYSTEM_INSTANCE *Instance;
+ FV_FILESYSTEM_FILE_INFO *FvFileInfo;
+ EFI_FIRMWARE_VOLUME2_PROTOCOL *FvProtocol;
+ CHAR16 *Name;
+ UINTN NameLen;
+ UINTN NumChars;
+ UINTN DestMax;
+
+ Instance = FVFS_INSTANCE_FROM_SIMPLE_FS_THIS (This);
+ Status = EFI_SUCCESS;
+
+ if (Instance->Root == NULL) {
+ //
+ // Allocate file structure for root file
+ //
+ Root = AllocateZeroPool (sizeof (FV_FILESYSTEM_FILE));
+ if (Root == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ Instance->Root = Root;
+ Root->Instance = Instance;
+ Root->Signature = FVFS_FILE_SIGNATURE;
+ CopyMem (&Root->FileProtocol, &mFileSystemTemplate, sizeof (mFileSystemTemplate));
+ Root->FvFileInfo = AllocateZeroPool (sizeof (FV_FILESYSTEM_FILE_INFO));
+ if (Root->FvFileInfo == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+ Root->FvFileInfo->FileInfo.Size = sizeof (EFI_FILE_INFO);
+ Root->FvFileInfo->FileInfo.Attribute = EFI_FILE_DIRECTORY | EFI_FILE_READ_ONLY;
+
+ //
+ // Populate the instance's list of files. We consider anything a file that
+ // has a UI_SECTION, which we consider to be its filename.
+ //
+ FvProtocol = Instance->FvProtocol;
+ //
+ // Allocate Key
+ //
+ Key = 0;
+
+ do {
+ FileType = EFI_FV_FILETYPE_ALL;
+
+ Status = FvProtocol->GetNextFile (
+ FvProtocol,
+ &Key,
+ &FileType,
+ &NameGuid,
+ &Attributes,
+ &Size
+ );
+ if (EFI_ERROR (Status)) {
+ ASSERT (Status == EFI_NOT_FOUND);
+ break;
+ }
+
+ //
+ // Get a file's name: If it has a UI section, use that, otherwise use
+ // its NameGuid.
+ //
+ UiSection = NULL;
+ Status = FvProtocol->ReadSection (
+ FvProtocol,
+ &NameGuid,
+ EFI_SECTION_USER_INTERFACE,
+ 0,
+ (VOID **)&UiSection,
+ &Size,
+ &Authentication
+ );
+ if (!EFI_ERROR (Status)) {
+ Name = UiSection;
+ } else {
+ Name = AllocateZeroPool (GUID_STRING_SIZE);
+ if (Name == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+ NumChars = UnicodeSPrint (Name, GUID_STRING_SIZE, L"%g", &NameGuid);
+ ASSERT ((NumChars + 1) * sizeof (CHAR16) == GUID_STRING_SIZE);
+ }
+
+ //
+ // Found a file.
+ // Allocate a file structure and populate it.
+ //
+ NameLen = StrSize (Name);
+ if (FV_FILETYPE_IS_EXECUTABLE (FileType)) {
+ NameLen += StrSize (L".efi") - sizeof (CHAR16);
+ }
+
+ FvFileInfo = AllocateZeroPool (sizeof (FV_FILESYSTEM_FILE_INFO) + NameLen - sizeof (CHAR16));
+ if (FvFileInfo == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ FvFileInfo->Signature = FVFS_FILE_INFO_SIGNATURE;
+ InitializeListHead (&FvFileInfo->Link);
+ CopyMem (&FvFileInfo->NameGuid, &NameGuid, sizeof (EFI_GUID));
+ FvFileInfo->Type = FileType;
+
+ //
+ // Add ".efi" to filenames of drivers and applications.
+ //
+ DestMax = NameLen / sizeof (CHAR16);
+ Status = StrnCpyS (&FvFileInfo->FileInfo.FileName[0], DestMax, Name, StrLen (Name));
+ ASSERT_EFI_ERROR (Status);
+
+ if (FV_FILETYPE_IS_EXECUTABLE (FileType)) {
+ Status = StrnCatS (&FvFileInfo->FileInfo.FileName[0], DestMax, L".efi", StrLen (L".efi"));
+ ASSERT_EFI_ERROR (Status);
+ }
+
+ FvFileInfo->FileInfo.Size = sizeof (EFI_FILE_INFO) + NameLen - sizeof (CHAR16);
+ Status = FvFsGetFileSize (FvProtocol, FvFileInfo);
+ ASSERT_EFI_ERROR (Status);
+ FvFileInfo->FileInfo.PhysicalSize = FvFileInfo->FileInfo.FileSize;
+ FvFileInfo->FileInfo.Attribute = EFI_FILE_READ_ONLY;
+
+ InsertHeadList (&Instance->FileInfoHead, &FvFileInfo->Link);
+
+ FreePool (Name);
+
+ } while (TRUE);
+
+ if (Status == EFI_NOT_FOUND) {
+ Status = EFI_SUCCESS;
+ }
+ }
+
+ Instance->Root->DirReadNext = FVFS_GET_FIRST_FILE_INFO (Instance);
+ *RootFile = &Instance->Root->FileProtocol;
+ return Status;
+}
+
+/**
+ Worker function to initialize Unicode Collation support.
+
+ It tries to locate Unicode Collation (2) protocol and matches it with current
+ platform language code.
+
+ @param AgentHandle The handle used to open Unicode Collation (2) protocol.
+ @param ProtocolGuid The pointer to Unicode Collation (2) protocol GUID.
+ @param VariableName The name of the RFC 4646 or ISO 639-2 language variable.
+ @param DefaultLanguage The default language in case the RFC 4646 or ISO 639-2 language is absent.
+
+ @retval EFI_SUCCESS The Unicode Collation (2) protocol has been successfully located.
+ @retval Others The Unicode Collation (2) protocol has not been located.
+
+**/
+EFI_STATUS
+InitializeUnicodeCollationSupportWorker (
+ IN EFI_HANDLE AgentHandle,
+ IN EFI_GUID *ProtocolGuid,
+ IN CONST CHAR16 *VariableName,
+ IN CONST CHAR8 *DefaultLanguage
+ )
+{
+ EFI_STATUS ReturnStatus;
+ EFI_STATUS Status;
+ UINTN NumHandles;
+ UINTN Index;
+ EFI_HANDLE *Handles;
+ EFI_UNICODE_COLLATION_PROTOCOL *Uci;
+ BOOLEAN Iso639Language;
+ CHAR8 *Language;
+ CHAR8 *BestLanguage;
+
+ Status = gBS->LocateHandleBuffer (
+ ByProtocol,
+ ProtocolGuid,
+ NULL,
+ &NumHandles,
+ &Handles
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ Iso639Language = (BOOLEAN) (ProtocolGuid == &gEfiUnicodeCollationProtocolGuid);
+ GetEfiGlobalVariable2 (VariableName, (VOID**) &Language, NULL);
+
+ ReturnStatus = EFI_UNSUPPORTED;
+ for (Index = 0; Index < NumHandles; Index++) {
+ //
+ // Open Unicode Collation Protocol
+ //
+ Status = gBS->OpenProtocol (
+ Handles[Index],
+ ProtocolGuid,
+ (VOID **) &Uci,
+ AgentHandle,
+ NULL,
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL
+ );
+ if (EFI_ERROR (Status)) {
+ continue;
+ }
+
+ //
+ // Find the best matching matching language from the supported languages
+ // of Unicode Collation (2) protocol.
+ //
+ BestLanguage = GetBestLanguage (
+ Uci->SupportedLanguages,
+ Iso639Language,
+ (Language == NULL) ? "" : Language,
+ DefaultLanguage,
+ NULL
+ );
+ if (BestLanguage != NULL) {
+ FreePool (BestLanguage);
+ mUnicodeCollation = Uci;
+ ReturnStatus = EFI_SUCCESS;
+ break;
+ }
+ }
+
+ if (Language != NULL) {
+ FreePool (Language);
+ }
+
+ FreePool (Handles);
+
+ return ReturnStatus;
+}
+
+/**
+ Initialize Unicode Collation support.
+
+ It tries to locate Unicode Collation 2 protocol and matches it with current
+ platform language code. If for any reason the first attempt fails, it then tries to
+ use Unicode Collation Protocol.
+
+ @param AgentHandle The handle used to open Unicode Collation (2) protocol.
+
+ @retval EFI_SUCCESS The Unicode Collation (2) protocol has been successfully located.
+ @retval Others The Unicode Collation (2) protocol has not been located.
+
+**/
+EFI_STATUS
+InitializeUnicodeCollationSupport (
+ IN EFI_HANDLE AgentHandle
+ )
+{
+
+ EFI_STATUS Status;
+
+ Status = EFI_UNSUPPORTED;
+
+ //
+ // First try to use RFC 4646 Unicode Collation 2 Protocol.
+ //
+ Status = InitializeUnicodeCollationSupportWorker (
+ AgentHandle,
+ &gEfiUnicodeCollation2ProtocolGuid,
+ L"PlatformLang",
+ (CONST CHAR8 *) PcdGetPtr (PcdUefiVariableDefaultPlatformLang)
+ );
+ //
+ // If the attempt to use Unicode Collation 2 Protocol fails, then we fall back
+ // on the ISO 639-2 Unicode Collation Protocol.
+ //
+ if (EFI_ERROR (Status)) {
+ Status = InitializeUnicodeCollationSupportWorker (
+ AgentHandle,
+ &gEfiUnicodeCollationProtocolGuid,
+ L"Lang",
+ (CONST CHAR8 *) PcdGetPtr (PcdUefiVariableDefaultLang)
+ );
+ }
+
+ return Status;
+}
+
+/**
+ Test to see if this driver supports ControllerHandle.
+
+ @param DriverBinding Protocol instance pointer.
+ @param ControllerHandle Handle of device to test
+ @param RemainingDevicePath Optional parameter use to pick a specific child
+ device to start.
+
+ @retval EFI_SUCCESS This driver supports this device
+ @retval EFI_ALREADY_STARTED This driver is already running on this device
+ @retval other This driver does not support this device
+
+**/
+EFI_STATUS
+EFIAPI
+FvSimpleFileSystemDriverSupported (
+ IN EFI_DRIVER_BINDING_PROTOCOL *DriverBinding,
+ IN EFI_HANDLE ControllerHandle,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL
+ )
+{
+ return gBS->OpenProtocol (
+ ControllerHandle,
+ &gEfiFirmwareVolume2ProtocolGuid,
+ NULL,
+ gImageHandle,
+ ControllerHandle,
+ EFI_OPEN_PROTOCOL_TEST_PROTOCOL
+ );
+}
+
+/**
+ Start this driver on ControllerHandle by opening a FV protocol and
+ installing a SimpleFileSystem protocol on ControllerHandle.
+
+ @param DriverBinding Protocol instance pointer.
+ @param ControllerHandle Handle of device to bind driver to
+ @param RemainingDevicePath Optional parameter use to pick a specific child
+ device to start.
+
+ @retval EFI_SUCCESS This driver is added to ControllerHandle
+ @retval EFI_ALREADY_STARTED This driver is already running on ControllerHandle
+ @retval other This driver does not support this device
+
+**/
+EFI_STATUS
+EFIAPI
+FvSimpleFileSystemDriverStart (
+ IN EFI_DRIVER_BINDING_PROTOCOL *DriverBinding,
+ IN EFI_HANDLE ControllerHandle,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL
+ )
+{
+ EFI_STATUS Status;
+ EFI_FIRMWARE_VOLUME2_PROTOCOL *FvProtocol;
+ FV_FILESYSTEM_INSTANCE *Instance;
+ EFI_DEVICE_PATH_PROTOCOL *FvDevicePath;
+ EFI_GUID *FvGuid;
+ UINTN NumChars;
+
+ Status = InitializeUnicodeCollationSupport (DriverBinding->DriverBindingHandle);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Open FV protocol
+ //
+ Status = gBS->OpenProtocol (
+ ControllerHandle,
+ &gEfiFirmwareVolume2ProtocolGuid,
+ (VOID **) &FvProtocol,
+ gImageHandle,
+ ControllerHandle,
+ EFI_OPEN_PROTOCOL_BY_DRIVER
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Create an instance
+ //
+ Instance = AllocateZeroPool (sizeof (FV_FILESYSTEM_INSTANCE));
+ if (Instance == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ Instance->Root = NULL;
+ Instance->FvProtocol = FvProtocol;
+ Instance->Signature = FVFS_INSTANCE_SIGNATURE;
+ InitializeListHead (&Instance->FileInfoHead);
+ InitializeListHead (&Instance->FileHead);
+ CopyMem (&Instance->SimpleFs, &mSimpleFsTemplate, sizeof (mSimpleFsTemplate));
+
+ Status = gBS->InstallProtocolInterface(
+ &ControllerHandle,
+ &gEfiSimpleFileSystemProtocolGuid,
+ EFI_NATIVE_INTERFACE,
+ &Instance->SimpleFs
+ );
+
+ //
+ // Decide on a filesystem volume label, which will include the FV's guid.
+ // Get the device path to find the FV's GUID
+ //
+ Instance->VolumeLabel = NULL;
+ Status = gBS->OpenProtocol (
+ ControllerHandle,
+ &gEfiDevicePathProtocolGuid,
+ (VOID **) &FvDevicePath,
+ gImageHandle,
+ ControllerHandle,
+ EFI_OPEN_PROTOCOL_BY_DRIVER
+ );
+ if (!EFI_ERROR (Status)) {
+ //
+ // Iterate over device path until we find a firmware volume node
+ //
+ while (!IsDevicePathEndType (FvDevicePath)) {
+ if (DevicePathType (FvDevicePath) == MEDIA_DEVICE_PATH &&
+ DevicePathSubType (FvDevicePath) == MEDIA_PIWG_FW_VOL_DP) {
+ //
+ // Allocate the volume label
+ //
+ Instance->VolumeLabel = AllocateZeroPool (FVFS_VOLUME_LABEL_SIZE);
+ //
+ // Check the allocation was successful
+ //
+ if (Instance->VolumeLabel != NULL) {
+ //
+ // Extract the FV's guid
+ //
+ FvGuid = &((MEDIA_FW_VOL_DEVICE_PATH *) FvDevicePath)->FvName;
+ //
+ // Build the volume label string
+ //
+ NumChars = UnicodeSPrint (
+ Instance->VolumeLabel,
+ FVFS_VOLUME_LABEL_SIZE,
+ FVFS_VOLUME_LABEL_PREFIX L"%g",
+ FvGuid
+ );
+ ASSERT ((NumChars + 1) * sizeof (CHAR16) == FVFS_VOLUME_LABEL_SIZE);
+ }
+ break;
+ }
+ FvDevicePath = NextDevicePathNode (FvDevicePath);
+ }
+ }
+ //
+ // If we didn't decide on a volume label, set a fallback one
+ //
+ if (Instance->VolumeLabel == NULL) {
+ Instance->VolumeLabel = AllocateCopyPool (
+ sizeof (FVFS_FALLBACK_VOLUME_LABEL),
+ FVFS_FALLBACK_VOLUME_LABEL
+ );
+ }
+
+ return Status;
+}
+
+/**
+ Stop this driver on ControllerHandle by removing SimpleFileSystem protocol and closing
+ the FV protocol on ControllerHandle.
+
+ @param DriverBinding Protocol instance pointer.
+ @param ControllerHandle Handle of device to stop driver on
+ @param NumberOfChildren Number of Handles in ChildHandleBuffer. If number of
+ children is zero stop the entire bus driver.
+ @param ChildHandleBuffer List of Child Handles to Stop.
+
+ @retval EFI_SUCCESS This driver is removed ControllerHandle
+ @retval other This driver was not removed from this device
+
+**/
+EFI_STATUS
+EFIAPI
+FvSimpleFileSystemDriverStop (
+ IN EFI_DRIVER_BINDING_PROTOCOL *DriverBinding,
+ IN EFI_HANDLE ControllerHandle,
+ IN UINTN NumberOfChildren,
+ IN EFI_HANDLE *ChildHandleBuffer OPTIONAL
+ )
+{
+ EFI_STATUS Status;
+ FV_FILESYSTEM_INSTANCE *Instance;
+ FV_FILESYSTEM_FILE_INFO *FvFileInfo;
+ LIST_ENTRY *Entry;
+ LIST_ENTRY *DelEntry;
+ EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *SimpleFile;
+
+ Status = gBS->OpenProtocol (
+ ControllerHandle,
+ &gEfiSimpleFileSystemProtocolGuid,
+ (VOID **) &SimpleFile,
+ DriverBinding->DriverBindingHandle,
+ ControllerHandle,
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ Instance = FVFS_INSTANCE_FROM_SIMPLE_FS_THIS (SimpleFile);
+
+ if (IsListEmpty (&Instance->FileHead) == FALSE) {
+ //
+ // Not all opened files are closed
+ //
+ return EFI_DEVICE_ERROR;
+ }
+
+ //
+ // Close and uninstall protocols.
+ //
+ Status = gBS->CloseProtocol (
+ ControllerHandle,
+ &gEfiFirmwareVolume2ProtocolGuid,
+ gImageHandle,
+ ControllerHandle
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ Status = gBS->UninstallProtocolInterface (
+ ControllerHandle,
+ &gEfiSimpleFileSystemProtocolGuid,
+ &Instance->SimpleFs
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Free file structures
+ //
+ if (!IsListEmpty (&Instance->FileInfoHead)) {
+ //
+ // Free the Subtask list.
+ //
+ for(Entry = Instance->FileInfoHead.ForwardLink;
+ Entry != (&Instance->FileInfoHead);
+ ) {
+ DelEntry = Entry;
+ Entry = Entry->ForwardLink;
+ FvFileInfo = FVFS_FILE_INFO_FROM_LINK (DelEntry);
+
+ RemoveEntryList (DelEntry);
+ FreePool (FvFileInfo);
+ }
+ }
+
+ if (Instance->Root != NULL) {
+ //
+ // Root->Name is statically allocated, no need to free.
+ //
+ if (Instance->Root->FvFileInfo != NULL) {
+ FreePool (Instance->Root->FvFileInfo);
+ }
+ FreePool (Instance->Root);
+ }
+
+ //
+ // Free Instance
+ //
+ if (Instance->VolumeLabel != NULL) {
+ FreePool (Instance->VolumeLabel);
+ }
+ FreePool (Instance);
+
+ return EFI_SUCCESS;
+}
+
+/**
+ The user Entry Point for module FvSimpleFileSystem. The user code starts with this function.
+
+ @param[in] ImageHandle The firmware allocated handle for the EFI image.
+ @param[in] SystemTable A pointer to the EFI System Table.
+
+ @retval EFI_SUCCESS The entry point is executed successfully.
+ @retval other Some error occurs when executing this entry point.
+
+**/
+EFI_STATUS
+EFIAPI
+FvSimpleFileSystemEntryPoint (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+
+ //
+ // Install driver model protocol(s).
+ //
+ Status = EfiLibInstallDriverBindingComponentName2 (
+ ImageHandle,
+ SystemTable,
+ &mDriverBinding,
+ ImageHandle,
+ &gFvSimpleFileSystemComponentName,
+ &gFvSimpleFileSystemComponentName2
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ return Status;
+}
diff --git a/MdeModulePkg/Universal/FvSimpleFileSystemDxe/FvSimpleFileSystemExtra.uni b/MdeModulePkg/Universal/FvSimpleFileSystemDxe/FvSimpleFileSystemExtra.uni
new file mode 100644
index 0000000000..7988ee5297
--- /dev/null
+++ b/MdeModulePkg/Universal/FvSimpleFileSystemDxe/FvSimpleFileSystemExtra.uni
Binary files differ
diff --git a/MdeModulePkg/Universal/FvSimpleFileSystemDxe/FvSimpleFileSystemInternal.h b/MdeModulePkg/Universal/FvSimpleFileSystemDxe/FvSimpleFileSystemInternal.h
new file mode 100644
index 0000000000..c8da5f68fd
--- /dev/null
+++ b/MdeModulePkg/Universal/FvSimpleFileSystemDxe/FvSimpleFileSystemInternal.h
@@ -0,0 +1,622 @@
+/** @file
+ The internal header file of FvSimpleFileSystem driver.
+
+Copyright (c) 2014, ARM Limited. All rights reserved.
+Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>
+
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef __FVFS_INTERNAL_H__
+#define __FVFS_INTERNAL_H__
+
+#include <Uefi.h>
+#include <PiDxe.h>
+
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/DevicePathLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/PrintLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiLib.h>
+
+#include <Protocol/DriverBinding.h>
+#include <Protocol/FirmwareVolume2.h>
+#include <Protocol/SimpleFileSystem.h>
+#include <Protocol/UnicodeCollation.h>
+
+#include <Guid/FileSystemInfo.h>
+#include <Guid/FileInfo.h>
+#include <Guid/FileSystemVolumeLabelInfo.h>
+
+typedef struct _FV_FILESYSTEM_FILE FV_FILESYSTEM_FILE;
+typedef struct _FV_FILESYSTEM_FILE_INFO FV_FILESYSTEM_FILE_INFO;
+typedef struct _FV_FILESYSTEM_INSTANCE FV_FILESYSTEM_INSTANCE;
+
+//
+// Struct representing an instance of the "filesystem". There will be one of
+// these structs per FV.
+//
+struct _FV_FILESYSTEM_INSTANCE {
+ UINT32 Signature;
+ LIST_ENTRY FileInfoHead;
+ LIST_ENTRY FileHead;
+ EFI_DRIVER_BINDING_PROTOCOL *DriverBinding;
+ EFI_FIRMWARE_VOLUME2_PROTOCOL *FvProtocol;
+ EFI_SIMPLE_FILE_SYSTEM_PROTOCOL SimpleFs;
+ FV_FILESYSTEM_FILE *Root;
+ CHAR16 *VolumeLabel;
+};
+
+//
+// Struct representing a opening file. Each opening operation on file will
+// create such an instance except for the "root directory", which will only
+// be created once for each FV.
+//
+struct _FV_FILESYSTEM_FILE {
+ UINT32 Signature;
+ LIST_ENTRY Link;
+ FV_FILESYSTEM_FILE_INFO *DirReadNext;
+ FV_FILESYSTEM_INSTANCE *Instance;
+ EFI_FILE_PROTOCOL FileProtocol;
+ FV_FILESYSTEM_FILE_INFO *FvFileInfo;
+ UINT64 Position;
+};
+
+//
+// Struct representing the info of a file.
+//
+struct _FV_FILESYSTEM_FILE_INFO {
+ UINT32 Signature;
+ LIST_ENTRY Link;
+ EFI_GUID NameGuid;
+ EFI_FV_FILETYPE Type;
+ EFI_FILE_INFO FileInfo;
+};
+
+#define FVFS_FILE_SIGNATURE SIGNATURE_32 ('f', 'v', 'f', 'i')
+#define FVFS_FILE_INFO_SIGNATURE SIGNATURE_32 ('f', 'v', 'i', 'n')
+#define FVFS_INSTANCE_SIGNATURE SIGNATURE_32 ('f', 'v', 'f', 's')
+
+#define FVFS_INSTANCE_FROM_SIMPLE_FS_THIS(This) CR ( \
+ This, \
+ FV_FILESYSTEM_INSTANCE, \
+ SimpleFs, \
+ FVFS_INSTANCE_SIGNATURE \
+ )
+
+#define FVFS_FILE_FROM_FILE_THIS(This) CR ( \
+ This, \
+ FV_FILESYSTEM_FILE, \
+ FileProtocol, \
+ FVFS_FILE_SIGNATURE \
+ )
+
+#define FVFS_FILE_INFO_FROM_LINK(This) CR ( \
+ This, \
+ FV_FILESYSTEM_FILE_INFO, \
+ Link, \
+ FVFS_FILE_INFO_SIGNATURE \
+ )
+
+#define FVFS_FILE_FROM_LINK(FileLink) CR (FileLink, FV_FILESYSTEM_FILE, Link, FVFS_FILE_SIGNATURE)
+
+#define FVFS_GET_FIRST_FILE(Instance) FVFS_FILE_FROM_LINK (GetFirstNode (&Instance->FileHead))
+
+#define FVFS_GET_FIRST_FILE_INFO(Instance) FVFS_FILE_INFO_FROM_LINK (GetFirstNode (&Instance->FileInfoHead))
+
+
+#define FV_FILETYPE_IS_EXECUTABLE(Type) ((Type) == EFI_FV_FILETYPE_PEIM || \
+ (Type) == EFI_FV_FILETYPE_DRIVER || \
+ (Type) == EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER || \
+ (Type) == EFI_FV_FILETYPE_APPLICATION)
+
+/**
+ Open the root directory on a volume.
+
+ @param This A pointer to the volume to open the root directory.
+ @param RootFile A pointer to the location to return the opened file handle for the
+ root directory.
+
+ @retval EFI_SUCCESS The device was opened.
+ @retval EFI_UNSUPPORTED This volume does not support the requested file system type.
+ @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_ACCESS_DENIED The service denied access to the file.
+ @retval EFI_OUT_OF_RESOURCES The volume was not opened due to lack of resources.
+ @retval EFI_MEDIA_CHANGED The device has a different medium in it or the medium is no
+ longer supported. Any existing file handles for this volume are
+ no longer valid. To access the files on the new medium, the
+ volume must be reopened with OpenVolume().
+
+**/
+EFI_STATUS
+EFIAPI
+FvSimpleFileSystemOpenVolume (
+ IN EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *This,
+ OUT EFI_FILE_PROTOCOL **RootFile
+ );
+
+/**
+ Test to see if this driver supports ControllerHandle.
+
+ @param DriverBinding Protocol instance pointer.
+ @param ControllerHandle Handle of device to test
+ @param RemainingDevicePath Optional parameter use to pick a specific child
+ device to start.
+
+ @retval EFI_SUCCESS This driver supports this device
+ @retval EFI_ALREADY_STARTED This driver is already running on this device
+ @retval other This driver does not support this device
+
+**/
+EFI_STATUS
+EFIAPI
+FvSimpleFileSystemDriverSupported (
+ IN EFI_DRIVER_BINDING_PROTOCOL *DriverBinding,
+ IN EFI_HANDLE ControllerHandle,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL
+ );
+
+/**
+ Start this driver on ControllerHandle by opening a FV protocol and
+ installing a SimpleFileSystem protocol on ControllerHandle.
+
+ @param DriverBinding Protocol instance pointer.
+ @param ControllerHandle Handle of device to bind driver to
+ @param RemainingDevicePath Optional parameter use to pick a specific child
+ device to start.
+
+ @retval EFI_SUCCESS This driver is added to ControllerHandle
+ @retval EFI_ALREADY_STARTED This driver is already running on ControllerHandle
+ @retval other This driver does not support this device
+
+**/
+EFI_STATUS
+EFIAPI
+FvSimpleFileSystemDriverStart (
+ IN EFI_DRIVER_BINDING_PROTOCOL *DriverBinding,
+ IN EFI_HANDLE ControllerHandle,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL
+ );
+
+/**
+ Stop this driver on ControllerHandle by removing SimpleFileSystem protocol and closing
+ the FV protocol on ControllerHandle.
+
+ @param DriverBinding Protocol instance pointer.
+ @param ControllerHandle Handle of device to stop driver on
+ @param NumberOfChildren Number of Handles in ChildHandleBuffer. If number of
+ children is zero stop the entire bus driver.
+ @param ChildHandleBuffer List of Child Handles to Stop.
+
+ @retval EFI_SUCCESS This driver is removed ControllerHandle
+ @retval other This driver was not removed from this device
+
+**/
+EFI_STATUS
+EFIAPI
+FvSimpleFileSystemDriverStop (
+ IN EFI_DRIVER_BINDING_PROTOCOL *DriverBinding,
+ IN EFI_HANDLE ControllerHandle,
+ IN UINTN NumberOfChildren,
+ IN EFI_HANDLE *ChildHandleBuffer OPTIONAL
+ );
+
+/**
+ Opens a new file relative to the source file's location.
+
+ @param This A pointer to the EFI_FILE_PROTOCOL instance that is the file
+ handle to the source location. This would typically be an open
+ handle to a directory.
+ @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.
+
+ @retval EFI_SUCCESS The file was opened.
+ @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.
+
+**/
+EFI_STATUS
+EFIAPI
+FvSimpleFileSystemOpen (
+ IN EFI_FILE_PROTOCOL *This,
+ OUT EFI_FILE_PROTOCOL **NewHandle,
+ IN CHAR16 *FileName,
+ IN UINT64 OpenMode,
+ IN UINT64 Attributes
+ );
+
+/**
+ Closes a specified file handle.
+
+ @param This A pointer to the EFI_FILE_PROTOCOL instance that is the file
+ handle to close.
+
+ @retval EFI_SUCCESS The file was closed.
+
+**/
+EFI_STATUS
+EFIAPI
+FvSimpleFileSystemClose (
+ IN EFI_FILE_PROTOCOL *This
+ );
+
+/**
+ 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 BufferSize 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.
+ @param Buffer The buffer into which the data is read.
+
+ @retval EFI_SUCCESS Data was read.
+ @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_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.
+
+**/
+EFI_STATUS
+EFIAPI
+FvSimpleFileSystemRead (
+ IN EFI_FILE_PROTOCOL *This,
+ IN OUT UINTN *BufferSize,
+ OUT VOID *Buffer
+ );
+
+/**
+ 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 BufferSize On input, the size of the Buffer. On output, the amount of data
+ actually written. In both cases, the size is measured in bytes.
+ @param Buffer The buffer of data to write.
+
+ @retval EFI_SUCCESS Data was written.
+ @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.
+
+**/
+EFI_STATUS
+EFIAPI
+FvSimpleFileSystemWrite (
+ IN EFI_FILE_PROTOCOL *This,
+ IN OUT UINTN *BufferSize,
+ IN VOID *Buffer
+ );
+
+/**
+ Returns a file's current position.
+
+ @param This A pointer to the EFI_FILE_PROTOCOL instance that is the file
+ handle to get the current position on.
+ @param Position The address to return the file's current position value.
+
+ @retval EFI_SUCCESS The position was returned.
+ @retval EFI_UNSUPPORTED The request is not valid on open directories.
+ @retval EFI_DEVICE_ERROR An attempt was made to get the position from a deleted file.
+
+**/
+EFI_STATUS
+EFIAPI
+FvSimpleFileSystemGetPosition (
+ IN EFI_FILE_PROTOCOL *This,
+ OUT UINT64 *Position
+ );
+
+/**
+ Sets a file's current position.
+
+ @param This A pointer to the EFI_FILE_PROTOCOL instance that is the
+ file handle to set the requested position on.
+ @param Position The byte position from the start of the file to set.
+
+ @retval EFI_SUCCESS The position was set.
+ @retval EFI_UNSUPPORTED The seek request for nonzero is not valid on open
+ directories.
+ @retval EFI_DEVICE_ERROR An attempt was made to set the position of a deleted file.
+
+**/
+EFI_STATUS
+EFIAPI
+FvSimpleFileSystemSetPosition (
+ IN EFI_FILE_PROTOCOL *This,
+ IN UINT64 Position
+ );
+
+/**
+ 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.
+
+ @retval EFI_SUCCESS The data was flushed.
+ @retval EFI_NO_MEDIA The device has no medium.
+ @retval EFI_DEVICE_ERROR The device reported an error.
+ @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted.
+ @retval EFI_WRITE_PROTECTED The file or medium is write-protected.
+ @retval EFI_ACCESS_DENIED The file was opened read-only.
+ @retval EFI_VOLUME_FULL The volume is full.
+
+**/
+EFI_STATUS
+EFIAPI
+FvSimpleFileSystemFlush (
+ IN EFI_FILE_PROTOCOL *This
+ );
+
+/**
+ Close and delete the file handle.
+
+ @param This A pointer to the EFI_FILE_PROTOCOL instance that is the
+ handle to the file to delete.
+
+ @retval EFI_SUCCESS The file was closed and deleted, and the handle was closed.
+ @retval EFI_WARN_DELETE_FAILURE The handle was closed, but the file was not deleted.
+
+**/
+EFI_STATUS
+EFIAPI
+FvSimpleFileSystemDelete (
+ IN EFI_FILE_PROTOCOL *This
+ );
+
+/**
+ Returns information about a file.
+
+ @param This A pointer to the EFI_FILE_PROTOCOL instance that is the file
+ handle the requested information is for.
+ @param InformationType The type identifier for the information being requested.
+ @param BufferSize On input, the size of Buffer. On output, the amount of data
+ returned in Buffer. In both cases, the size is measured in bytes.
+ @param Buffer A pointer to the data buffer to return. The buffer's type is
+ indicated by InformationType.
+
+ @retval EFI_SUCCESS The information was returned.
+ @retval EFI_UNSUPPORTED The InformationType is not known.
+ @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_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.
+**/
+EFI_STATUS
+EFIAPI
+FvSimpleFileSystemGetInfo (
+ IN EFI_FILE_PROTOCOL *This,
+ IN EFI_GUID *InformationType,
+ IN OUT UINTN *BufferSize,
+ OUT VOID *Buffer
+ );
+
+/**
+ Sets information about a file.
+
+ @param This A pointer to the EFI_FILE_PROTOCOL instance that is the file
+ handle the information is for.
+ @param InformationType The type identifier for the information being set.
+ @param BufferSize The size, in bytes, of Buffer.
+ @param Buffer A pointer to the data buffer to write. The buffer's type is
+ indicated by InformationType.
+
+ @retval EFI_SUCCESS The information was set.
+ @retval EFI_UNSUPPORTED The InformationType is not known.
+ @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 InformationType is EFI_FILE_INFO_ID and the media is
+ read-only.
+ @retval EFI_WRITE_PROTECTED InformationType is EFI_FILE_PROTOCOL_SYSTEM_INFO_ID
+ and the media is read only.
+ @retval EFI_WRITE_PROTECTED InformationType is EFI_FILE_SYSTEM_VOLUME_LABEL_ID
+ and the media is read-only.
+ @retval EFI_ACCESS_DENIED An attempt is made to change the name of a file to a
+ file that is already present.
+ @retval EFI_ACCESS_DENIED An attempt is being made to change the EFI_FILE_DIRECTORY
+ Attribute.
+ @retval EFI_ACCESS_DENIED An attempt is being made to change the size of a directory.
+ @retval EFI_ACCESS_DENIED InformationType is EFI_FILE_INFO_ID and the file was opened
+ read-only and an attempt is being made to modify a field
+ other than Attribute.
+ @retval EFI_VOLUME_FULL The volume is full.
+ @retval EFI_BAD_BUFFER_SIZE BufferSize is smaller than the size of the type indicated
+ by InformationType.
+
+**/
+EFI_STATUS
+EFIAPI
+FvSimpleFileSystemSetInfo (
+ IN EFI_FILE_PROTOCOL *This,
+ IN EFI_GUID *InformationType,
+ IN UINTN BufferSize,
+ IN VOID *Buffer
+ );
+
+/**
+ Get the size of the buffer that will be returned by FvFsReadFile.
+
+ @param FvProtocol A pointer to the EFI_FIRMWARE_VOLUME2_PROTOCOL instance.
+ @param FvFileInfo A pointer to the FV_FILESYSTEM_FILE_INFO instance that is a struct
+ representing a file's info.
+
+ @retval EFI_SUCCESS The file size was gotten correctly.
+ @retval Others The file size wasn't gotten correctly.
+
+**/
+EFI_STATUS
+FvFsGetFileSize (
+ IN EFI_FIRMWARE_VOLUME2_PROTOCOL *FvProtocol,
+ IN OUT FV_FILESYSTEM_FILE_INFO *FvFileInfo
+ );
+
+/**
+ 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
+FvSimpleFileSystemComponentNameGetDriverName (
+ IN EFI_COMPONENT_NAME_PROTOCOL *This,
+ IN CHAR8 *Language,
+ OUT CHAR16 **DriverName
+ );
+
+/**
+ Retrieves a Unicode string that is the user readable name of the controller
+ that is being managed by a driver.
+
+ This function retrieves the user readable name of the controller specified by
+ ControllerHandle and ChildHandle in the form of a Unicode string. If the
+ driver specified by This has a user readable name in the language specified by
+ Language, then a pointer to the controller name is returned in ControllerName,
+ and EFI_SUCCESS is returned. If the driver specified by This is not currently
+ managing the controller specified by ControllerHandle and ChildHandle,
+ then EFI_UNSUPPORTED is returned. If the driver specified by This does not
+ support the language specified by Language, then EFI_UNSUPPORTED is returned.
+
+ @param This[in] A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or
+ EFI_COMPONENT_NAME_PROTOCOL instance.
+
+ @param ControllerHandle[in] The handle of a controller that the driver
+ specified by This is managing. This handle
+ specifies the controller whose name is to be
+ returned.
+
+ @param ChildHandle[in] The handle of the child controller to retrieve
+ the name of. This is an optional parameter that
+ may be NULL. It will be NULL for device
+ drivers. It will also be NULL for a bus drivers
+ that wish to retrieve the name of the bus
+ controller. It will not be NULL for a bus
+ driver that wishes to retrieve the name of a
+ child controller.
+
+ @param Language[in] A pointer to a Null-terminated ASCII string
+ array indicating the language. This is the
+ language of the driver name that the caller is
+ requesting, and it must match one of the
+ languages specified in SupportedLanguages. The
+ number of languages supported by a driver is up
+ to the driver writer. Language is specified in
+ RFC 4646 or ISO 639-2 language code format.
+
+ @param ControllerName[out] A pointer to the Unicode string to return.
+ This Unicode string is the name of the
+ controller specified by ControllerHandle and
+ ChildHandle in the language specified by
+ Language from the point of view of the driver
+ specified by This.
+
+ @retval EFI_SUCCESS The Unicode string for the user readable name in
+ the language specified by Language for the
+ driver specified by This was returned in
+ DriverName.
+
+ @retval EFI_INVALID_PARAMETER ControllerHandle is NULL.
+
+ @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid
+ EFI_HANDLE.
+
+ @retval EFI_INVALID_PARAMETER Language is NULL.
+
+ @retval EFI_INVALID_PARAMETER ControllerName is NULL.
+
+ @retval EFI_UNSUPPORTED The driver specified by This is not currently
+ managing the controller specified by
+ ControllerHandle and ChildHandle.
+
+ @retval EFI_UNSUPPORTED The driver specified by This does not support
+ the language specified by Language.
+
+**/
+EFI_STATUS
+EFIAPI
+FvSimpleFileSystemComponentNameGetControllerName (
+ IN EFI_COMPONENT_NAME_PROTOCOL *This,
+ IN EFI_HANDLE ControllerHandle,
+ IN EFI_HANDLE ChildHandle OPTIONAL,
+ IN CHAR8 *Language,
+ OUT CHAR16 **ControllerName
+ );
+
+extern EFI_UNICODE_COLLATION_PROTOCOL *mUnicodeCollation;
+extern EFI_FILE_PROTOCOL mFileSystemTemplate;
+extern EFI_COMPONENT_NAME_PROTOCOL gFvSimpleFileSystemComponentName;
+extern EFI_COMPONENT_NAME2_PROTOCOL gFvSimpleFileSystemComponentName2;
+
+#endif \ No newline at end of file
diff --git a/MdeModulePkg/Universal/Network/Ip4ConfigDxe/Ip4Config.c b/MdeModulePkg/Universal/Network/Ip4ConfigDxe/Ip4Config.c
index 3eff1882e7..3d2f0a4f9b 100644
--- a/MdeModulePkg/Universal/Network/Ip4ConfigDxe/Ip4Config.c
+++ b/MdeModulePkg/Universal/Network/Ip4ConfigDxe/Ip4Config.c
@@ -1,6 +1,7 @@
/** @file
This code implements the IP4Config and NicIp4Config protocols.
+Copyright (c) 2014, Hewlett-Packard Development Company, L.P.<BR>
Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
@@ -656,7 +657,7 @@ Ip4ConfigCleanDhcp4 (
This->Dhcp4Handle = NULL;
}
- if (This->Dhcp4Event == NULL) {
+ if (This->Dhcp4Event != NULL) {
gBS->CloseEvent (This->Dhcp4Event);
This->Dhcp4Event = NULL;
}
diff --git a/MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Impl.c b/MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Impl.c
index 03b7f28171..7ed2e5250f 100644
--- a/MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Impl.c
+++ b/MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Impl.c
@@ -1,6 +1,7 @@
/** @file
Interface routine for Mtftp4.
+(C) Copyright 2014 Hewlett-Packard Development Company, L.P.<BR>
Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
@@ -305,13 +306,13 @@ Mtftp4ConfigUnicastPort (
UdpConfig.ReceiveTimeout = 0;
UdpConfig.TransmitTimeout = 0;
UdpConfig.UseDefaultAddress = Config->UseDefaultSetting;
- UdpConfig.StationAddress = Config->StationIp;
- UdpConfig.SubnetMask = Config->SubnetMask;
+ IP4_COPY_ADDRESS (&UdpConfig.StationAddress, &Config->StationIp);
+ IP4_COPY_ADDRESS (&UdpConfig.SubnetMask, &Config->SubnetMask);
UdpConfig.StationPort = 0;
UdpConfig.RemotePort = 0;
Ip = HTONL (Instance->ServerIp);
- CopyMem (&UdpConfig.RemoteAddress, &Ip, sizeof (EFI_IPv4_ADDRESS));
+ IP4_COPY_ADDRESS (&UdpConfig.RemoteAddress, &Ip);
Status = UdpIo->Protocol.Udp4->Configure (UdpIo->Protocol.Udp4, &UdpConfig);
diff --git a/MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Rrq.c b/MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Rrq.c
index 21547ee3af..e983d79791 100644
--- a/MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Rrq.c
+++ b/MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Rrq.c
@@ -1,6 +1,7 @@
/** @file
Routines to process Rrq (download).
+(C) Copyright 2014 Hewlett-Packard Development Company, L.P.<BR>
Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
@@ -413,13 +414,13 @@ Mtftp4RrqConfigMcastPort (
UdpConfig.ReceiveTimeout = 0;
UdpConfig.TransmitTimeout = 0;
UdpConfig.UseDefaultAddress = Config->UseDefaultSetting;
- UdpConfig.StationAddress = Config->StationIp;
- UdpConfig.SubnetMask = Config->SubnetMask;
+ IP4_COPY_ADDRESS (&UdpConfig.StationAddress, &Config->StationIp);
+ IP4_COPY_ADDRESS (&UdpConfig.SubnetMask, &Config->SubnetMask);
UdpConfig.StationPort = Instance->McastPort;
UdpConfig.RemotePort = 0;
Ip = HTONL (Instance->ServerIp);
- CopyMem (&UdpConfig.RemoteAddress, &Ip, sizeof (EFI_IPv4_ADDRESS));
+ IP4_COPY_ADDRESS (&UdpConfig.RemoteAddress, &Ip);
Status = McastIo->Protocol.Udp4->Configure (McastIo->Protocol.Udp4, &UdpConfig);
@@ -451,7 +452,7 @@ Mtftp4RrqConfigMcastPort (
// join the multicast group
//
Ip = HTONL (Instance->McastIp);
- CopyMem (&Group, &Ip, sizeof (EFI_IPv4_ADDRESS));
+ IP4_COPY_ADDRESS (&Group, &Ip);
return McastIo->Protocol.Udp4->Groups (McastIo->Protocol.Udp4, TRUE, &Group);
}
diff --git a/MdeModulePkg/Universal/Network/Tcp4Dxe/Tcp4Dispatcher.c b/MdeModulePkg/Universal/Network/Tcp4Dxe/Tcp4Dispatcher.c
index b6d89be2b1..5b327af721 100644
--- a/MdeModulePkg/Universal/Network/Tcp4Dxe/Tcp4Dispatcher.c
+++ b/MdeModulePkg/Universal/Network/Tcp4Dxe/Tcp4Dispatcher.c
@@ -1,6 +1,7 @@
/** @file
Tcp request dispatcher implementation.
+(C) Copyright 2014 Hewlett-Packard Development Company, L.P.<BR>
Copyright (c) 2005 - 2014, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
@@ -101,11 +102,11 @@ Tcp4GetMode (
AccessPoint->UseDefaultAddress = Tcb->UseDefaultAddr;
- CopyMem (&AccessPoint->StationAddress, &Tcb->LocalEnd.Ip, sizeof (EFI_IPv4_ADDRESS));
- AccessPoint->SubnetMask = Tcb->SubnetMask;
+ IP4_COPY_ADDRESS (&AccessPoint->StationAddress, &Tcb->LocalEnd.Ip);
+ IP4_COPY_ADDRESS (&AccessPoint->SubnetMask, &Tcb->SubnetMask);
AccessPoint->StationPort = NTOHS (Tcb->LocalEnd.Port);
- CopyMem (&AccessPoint->RemoteAddress, &Tcb->RemoteEnd.Ip, sizeof (EFI_IPv4_ADDRESS));
+ IP4_COPY_ADDRESS (&AccessPoint->RemoteAddress, &Tcb->RemoteEnd.Ip);
AccessPoint->RemotePort = NTOHS (Tcb->RemoteEnd.Port);
AccessPoint->ActiveFlag = (BOOLEAN) (Tcb->State != TCP_LISTEN);
@@ -458,7 +459,7 @@ Tcp4ConfigurePcb (
CopyMem (&Tcb->LocalEnd.Ip, &CfgData->AccessPoint.StationAddress, sizeof (IP4_ADDR));
Tcb->LocalEnd.Port = HTONS (CfgData->AccessPoint.StationPort);
- Tcb->SubnetMask = CfgData->AccessPoint.SubnetMask;
+ IP4_COPY_ADDRESS (&Tcb->SubnetMask, &CfgData->AccessPoint.SubnetMask);
if (CfgData->AccessPoint.ActiveFlag) {
CopyMem (&Tcb->RemoteEnd.Ip, &CfgData->AccessPoint.RemoteAddress, sizeof (IP4_ADDR));
diff --git a/MdeModulePkg/Universal/Network/Udp4Dxe/Udp4Main.c b/MdeModulePkg/Universal/Network/Udp4Dxe/Udp4Main.c
index d33402078f..5ea22acb14 100644
--- a/MdeModulePkg/Universal/Network/Udp4Dxe/Udp4Main.c
+++ b/MdeModulePkg/Universal/Network/Udp4Dxe/Udp4Main.c
@@ -1,5 +1,6 @@
/** @file
+(C) Copyright 2014 Hewlett-Packard Development Company, L.P.<BR>
Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
@@ -227,8 +228,8 @@ Udp4Configure (
// Save the configuration data.
//
CopyMem (&Instance->ConfigData, UdpConfigData, sizeof (Instance->ConfigData));
- Instance->ConfigData.StationAddress = Ip4ConfigData.StationAddress;
- Instance->ConfigData.SubnetMask = Ip4ConfigData.SubnetMask;
+ IP4_COPY_ADDRESS (&Instance->ConfigData.StationAddress, &Ip4ConfigData.StationAddress);
+ IP4_COPY_ADDRESS (&Instance->ConfigData.SubnetMask, &Ip4ConfigData.SubnetMask);
//
// Try to allocate the required port resource.
@@ -588,7 +589,7 @@ Udp4Transmit (
Udp4Header->Checksum = 0;
UdpSessionData = TxData->UdpSessionData;
- Override.Ip4OverrideData.SourceAddress = ConfigData->StationAddress;
+ IP4_COPY_ADDRESS (&Override.Ip4OverrideData.SourceAddress, &ConfigData->StationAddress);
if (UdpSessionData != NULL) {
//
@@ -596,7 +597,7 @@ Udp4Transmit (
// UdpSessionData.
//
if (!EFI_IP4_EQUAL (&UdpSessionData->SourceAddress, &mZeroIp4Addr)) {
- CopyMem (&Override.Ip4OverrideData.SourceAddress, &UdpSessionData->SourceAddress, sizeof (EFI_IPv4_ADDRESS));
+ IP4_COPY_ADDRESS (&Override.Ip4OverrideData.SourceAddress, &UdpSessionData->SourceAddress);
}
if (UdpSessionData->SourcePort != 0) {
@@ -643,7 +644,7 @@ Udp4Transmit (
// Fill the IpIo Override data.
//
if (TxData->GatewayAddress != NULL) {
- CopyMem (&Override.Ip4OverrideData.GatewayAddress, TxData->GatewayAddress, sizeof (EFI_IPv4_ADDRESS));
+ IP4_COPY_ADDRESS (&Override.Ip4OverrideData.GatewayAddress, TxData->GatewayAddress);
} else {
ZeroMem (&Override.Ip4OverrideData.GatewayAddress, sizeof (EFI_IPv4_ADDRESS));
}
diff --git a/MdeModulePkg/Universal/SetupBrowserDxe/IfrParse.c b/MdeModulePkg/Universal/SetupBrowserDxe/IfrParse.c
index d3b1186427..d82e08ed91 100644
--- a/MdeModulePkg/Universal/SetupBrowserDxe/IfrParse.c
+++ b/MdeModulePkg/Universal/SetupBrowserDxe/IfrParse.c
@@ -452,6 +452,40 @@ IntializeBrowserStorage (
}
/**
+ Check whether exist device path info in the ConfigHdr string.
+
+ @param String UEFI configuration string
+
+ @retval TRUE Device Path exist.
+ @retval FALSE Not exist device path info.
+
+**/
+BOOLEAN
+IsDevicePathExist (
+ IN EFI_STRING String
+ )
+{
+ UINTN Length;
+
+ for (; (*String != 0 && StrnCmp (String, L"PATH=", StrLen (L"PATH=")) != 0); String++);
+ if (*String == 0) {
+ return FALSE;
+ }
+
+ String += StrLen (L"PATH=");
+ if (*String == 0) {
+ return FALSE;
+ }
+
+ for (Length = 0; *String != 0 && *String != L'&'; String++, Length++);
+ if (((Length + 1) / 2) < sizeof (EFI_DEVICE_PATH_PROTOCOL)) {
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+/**
Allocate a FORMSET_STORAGE data structure and insert to FormSet Storage List.
@param FormSet Pointer of the current FormSet
@@ -528,6 +562,17 @@ CreateStorage (
InitializeConfigHdr (FormSet, BrowserStorage);
BrowserStorage->Initialized = FALSE;
+ } else {
+ if ((StorageType == EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER) &&
+ (FormSet->DriverHandle != NULL) &&
+ (!IsDevicePathExist (BrowserStorage->ConfigHdr))) {
+ //
+ // If this storage not has device path info but new formset has,
+ // update the device path info.
+ //
+ FreePool (BrowserStorage->ConfigHdr);
+ InitializeConfigHdr (FormSet, BrowserStorage);
+ }
}
Storage->BrowserStorage = BrowserStorage;
diff --git a/MdeModulePkg/Universal/Variable/RuntimeDxe/VarCheck.c b/MdeModulePkg/Universal/Variable/RuntimeDxe/VarCheck.c
new file mode 100644
index 0000000000..f8173308cf
--- /dev/null
+++ b/MdeModulePkg/Universal/Variable/RuntimeDxe/VarCheck.c
@@ -0,0 +1,1063 @@
+/** @file
+ Implementation functions and structures for var check protocol.
+
+Copyright (c) 2015, 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 "Variable.h"
+#include <Library/DevicePathLib.h>
+
+extern LIST_ENTRY mLockedVariableList;
+extern BOOLEAN mEndOfDxe;
+extern BOOLEAN mEnableLocking;
+
+#define VAR_CHECK_HANDLER_TABLE_SIZE 0x8
+
+UINT32 mNumberOfHandler = 0;
+UINT32 mMaxNumberOfHandler = 0;
+VAR_CHECK_SET_VARIABLE_CHECK_HANDLER *mHandlerTable = NULL;
+
+typedef struct {
+ LIST_ENTRY Link;
+ EFI_GUID Guid;
+ VAR_CHECK_VARIABLE_PROPERTY VariableProperty;
+ //CHAR16 *Name;
+} VAR_CHECK_VARIABLE_ENTRY;
+
+LIST_ENTRY mVarCheckVariableList = INITIALIZE_LIST_HEAD_VARIABLE (mVarCheckVariableList);
+
+typedef
+EFI_STATUS
+(EFIAPI *INTERNAL_VAR_CHECK_FUNCTION) (
+ IN VAR_CHECK_VARIABLE_PROPERTY *Propery,
+ IN UINTN DataSize,
+ IN VOID *Data
+ );
+
+typedef struct {
+ CHAR16 *Name;
+ VAR_CHECK_VARIABLE_PROPERTY VariableProperty;
+ INTERNAL_VAR_CHECK_FUNCTION CheckFunction;
+} UEFI_DEFINED_VARIABLE_ENTRY;
+
+typedef struct _EFI_LOAD_OPTION {
+ UINT32 Attributes;
+ UINT16 FilePathListLength;
+//CHAR16 Description[];
+//EFI_DEVICE_PATH_PROTOCOL FilePathList[];
+//UINT8 OptionalData[];
+} EFI_LOAD_OPTION;
+
+/**
+ Internal check for load option.
+
+ @param[in] VariablePropery Pointer to variable property.
+ @param[in] DataSize Data size.
+ @param[in] Data Pointer to data buffer.
+
+ @retval EFI_SUCCESS The SetVariable check result was success.
+ @retval EFI_INVALID_PARAMETER The data buffer is not a valid load option.
+
+**/
+EFI_STATUS
+EFIAPI
+InternalVarCheckLoadOption (
+ IN VAR_CHECK_VARIABLE_PROPERTY *VariablePropery,
+ IN UINTN DataSize,
+ IN VOID *Data
+ )
+{
+ EFI_LOAD_OPTION *LoadOption;
+ CHAR16 *Description;
+ EFI_DEVICE_PATH_PROTOCOL *FilePathList;
+
+ LoadOption = (EFI_LOAD_OPTION *) Data;
+
+ //
+ // Check Description
+ //
+ Description = (CHAR16 *) ((UINTN) Data + sizeof (EFI_LOAD_OPTION));
+ while (Description < (CHAR16 *) ((UINTN) Data + DataSize)) {
+ if (*Description == L'\0') {
+ break;
+ }
+ Description++;
+ }
+ if ((UINTN) Description >= ((UINTN) Data + DataSize)) {
+ return EFI_INVALID_PARAMETER;
+ }
+ Description++;
+
+ //
+ // Check FilePathList
+ //
+ FilePathList = (EFI_DEVICE_PATH_PROTOCOL *) Description;
+ if ((UINTN) FilePathList > (MAX_ADDRESS - LoadOption->FilePathListLength)) {
+ return EFI_INVALID_PARAMETER;
+ }
+ if (((UINTN) FilePathList + LoadOption->FilePathListLength) > ((UINTN) Data + DataSize)) {
+ return EFI_INVALID_PARAMETER;
+ }
+ if (LoadOption->FilePathListLength < sizeof (EFI_DEVICE_PATH_PROTOCOL)) {
+ return EFI_INVALID_PARAMETER;
+ }
+ if (!IsDevicePathValid (FilePathList, LoadOption->FilePathListLength)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Internal check for key option.
+
+ @param[in] VariablePropery Pointer to variable property.
+ @param[in] DataSize Data size.
+ @param[in] Data Pointer to data buffer.
+
+ @retval EFI_SUCCESS The SetVariable check result was success.
+ @retval EFI_INVALID_PARAMETER The data buffer is not a valid key option.
+
+**/
+EFI_STATUS
+EFIAPI
+InternalVarCheckKeyOption (
+ IN VAR_CHECK_VARIABLE_PROPERTY *VariablePropery,
+ IN UINTN DataSize,
+ IN VOID *Data
+ )
+{
+ if (((DataSize - sizeof (EFI_KEY_OPTION)) % sizeof (EFI_INPUT_KEY)) != 0) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Internal check for device path.
+
+ @param[in] VariablePropery Pointer to variable property.
+ @param[in] DataSize Data size.
+ @param[in] Data Pointer to data buffer.
+
+ @retval EFI_SUCCESS The SetVariable check result was success.
+ @retval EFI_INVALID_PARAMETER The data buffer is not a valid device path.
+
+**/
+EFI_STATUS
+EFIAPI
+InternalVarCheckDevicePath (
+ IN VAR_CHECK_VARIABLE_PROPERTY *VariablePropery,
+ IN UINTN DataSize,
+ IN VOID *Data
+ )
+{
+ if (!IsDevicePathValid ((EFI_DEVICE_PATH_PROTOCOL *) Data, DataSize)) {
+ return EFI_INVALID_PARAMETER;
+ }
+ return EFI_SUCCESS;
+}
+
+/**
+ Internal check for ASCII string.
+
+ @param[in] VariablePropery Pointer to variable property.
+ @param[in] DataSize Data size.
+ @param[in] Data Pointer to data buffer.
+
+ @retval EFI_SUCCESS The SetVariable check result was success.
+ @retval EFI_INVALID_PARAMETER The data buffer is not a Null-terminated ASCII string.
+
+**/
+EFI_STATUS
+EFIAPI
+InternalVarCheckAsciiString (
+ IN VAR_CHECK_VARIABLE_PROPERTY *VariablePropery,
+ IN UINTN DataSize,
+ IN VOID *Data
+ )
+{
+ CHAR8 *String;
+ UINTN Index;
+
+ String = (CHAR8 *) Data;
+ if (String[DataSize - 1] == '\0') {
+ return EFI_SUCCESS;
+ } else {
+ for (Index = 1; Index < DataSize && (String[DataSize - 1 - Index] != '\0'); Index++);
+ if (Index == DataSize) {
+ return EFI_INVALID_PARAMETER;
+ }
+ }
+ return EFI_SUCCESS;
+}
+
+/**
+ Internal check for size array.
+
+ @param[in] VariablePropery Pointer to variable property.
+ @param[in] DataSize Data size.
+ @param[in] Data Pointer to data buffer.
+
+ @retval EFI_SUCCESS The SetVariable check result was success.
+ @retval EFI_INVALID_PARAMETER The DataSize is not size array.
+
+**/
+EFI_STATUS
+EFIAPI
+InternalVarCheckSizeArray (
+ IN VAR_CHECK_VARIABLE_PROPERTY *VariablePropery,
+ IN UINTN DataSize,
+ IN VOID *Data
+ )
+{
+ if ((DataSize % VariablePropery->MinSize) != 0) {
+ return EFI_INVALID_PARAMETER;
+ }
+ return EFI_SUCCESS;
+}
+
+//
+// To prevent name collisions with possible future globally defined variables,
+// other internal firmware data variables that are not defined here must be
+// saved with a unique VendorGuid other than EFI_GLOBAL_VARIABLE or
+// any other GUID defined by the UEFI Specification. Implementations must
+// only permit the creation of variables with a UEFI Specification-defined
+// VendorGuid when these variables are documented in the UEFI Specification.
+//
+UEFI_DEFINED_VARIABLE_ENTRY mGlobalVariableList[] = {
+ {
+ EFI_LANG_CODES_VARIABLE_NAME,
+ {
+ VAR_CHECK_VARIABLE_PROPERTY_REVISION,
+ 0,
+ VARIABLE_ATTRIBUTE_BS_RT,
+ 1,
+ MAX_UINTN
+ },
+ InternalVarCheckAsciiString
+ },
+ {
+ EFI_LANG_VARIABLE_NAME,
+ {
+ VAR_CHECK_VARIABLE_PROPERTY_REVISION,
+ 0,
+ VARIABLE_ATTRIBUTE_NV_BS_RT,
+ 1,
+ MAX_UINTN
+ },
+ InternalVarCheckAsciiString
+ },
+ {
+ EFI_TIME_OUT_VARIABLE_NAME,
+ {
+ VAR_CHECK_VARIABLE_PROPERTY_REVISION,
+ 0,
+ VARIABLE_ATTRIBUTE_NV_BS_RT,
+ sizeof (UINT16),
+ sizeof (UINT16)
+ },
+ NULL
+ },
+ {
+ EFI_PLATFORM_LANG_CODES_VARIABLE_NAME,
+ {
+ VAR_CHECK_VARIABLE_PROPERTY_REVISION,
+ 0,
+ VARIABLE_ATTRIBUTE_BS_RT,
+ 1,
+ MAX_UINTN
+ },
+ InternalVarCheckAsciiString
+ },
+ {
+ EFI_PLATFORM_LANG_VARIABLE_NAME,
+ {
+ VAR_CHECK_VARIABLE_PROPERTY_REVISION,
+ 0,
+ VARIABLE_ATTRIBUTE_NV_BS_RT,
+ 1,
+ MAX_UINTN
+ },
+ InternalVarCheckAsciiString
+ },
+ {
+ EFI_CON_IN_VARIABLE_NAME,
+ {
+ VAR_CHECK_VARIABLE_PROPERTY_REVISION,
+ 0,
+ VARIABLE_ATTRIBUTE_NV_BS_RT,
+ sizeof (EFI_DEVICE_PATH_PROTOCOL),
+ MAX_UINTN
+ },
+ InternalVarCheckDevicePath
+ },
+ {
+ EFI_CON_OUT_VARIABLE_NAME,
+ {
+ VAR_CHECK_VARIABLE_PROPERTY_REVISION,
+ 0,
+ VARIABLE_ATTRIBUTE_NV_BS_RT,
+ sizeof (EFI_DEVICE_PATH_PROTOCOL),
+ MAX_UINTN
+ },
+ InternalVarCheckDevicePath
+ },
+ {
+ EFI_ERR_OUT_VARIABLE_NAME,
+ {
+ VAR_CHECK_VARIABLE_PROPERTY_REVISION,
+ 0,
+ VARIABLE_ATTRIBUTE_NV_BS_RT,
+ sizeof (EFI_DEVICE_PATH_PROTOCOL),
+ MAX_UINTN
+ },
+ InternalVarCheckDevicePath
+ },
+ {
+ EFI_CON_IN_DEV_VARIABLE_NAME,
+ {
+ VAR_CHECK_VARIABLE_PROPERTY_REVISION,
+ 0,
+ VARIABLE_ATTRIBUTE_BS_RT,
+ sizeof (EFI_DEVICE_PATH_PROTOCOL),
+ MAX_UINTN
+ },
+ InternalVarCheckDevicePath
+ },
+ {
+ EFI_CON_OUT_DEV_VARIABLE_NAME,
+ {
+ VAR_CHECK_VARIABLE_PROPERTY_REVISION,
+ 0,
+ VARIABLE_ATTRIBUTE_BS_RT,
+ sizeof (EFI_DEVICE_PATH_PROTOCOL),
+ MAX_UINTN
+ },
+ InternalVarCheckDevicePath
+ },
+ {
+ EFI_ERR_OUT_DEV_VARIABLE_NAME,
+ {
+ VAR_CHECK_VARIABLE_PROPERTY_REVISION,
+ 0,
+ VARIABLE_ATTRIBUTE_BS_RT,
+ sizeof (EFI_DEVICE_PATH_PROTOCOL),
+ MAX_UINTN
+ },
+ InternalVarCheckDevicePath
+ },
+ {
+ EFI_BOOT_ORDER_VARIABLE_NAME,
+ {
+ VAR_CHECK_VARIABLE_PROPERTY_REVISION,
+ 0,
+ VARIABLE_ATTRIBUTE_NV_BS_RT,
+ sizeof (UINT16),
+ MAX_UINTN
+ },
+ InternalVarCheckSizeArray
+ },
+ {
+ EFI_BOOT_NEXT_VARIABLE_NAME,
+ {
+ VAR_CHECK_VARIABLE_PROPERTY_REVISION,
+ 0,
+ VARIABLE_ATTRIBUTE_NV_BS_RT,
+ sizeof (UINT16),
+ sizeof (UINT16)
+ },
+ NULL
+ },
+ {
+ EFI_BOOT_CURRENT_VARIABLE_NAME,
+ {
+ VAR_CHECK_VARIABLE_PROPERTY_REVISION,
+ 0,
+ VARIABLE_ATTRIBUTE_BS_RT,
+ sizeof (UINT16),
+ sizeof (UINT16)
+ },
+ NULL
+ },
+ {
+ EFI_BOOT_OPTION_SUPPORT_VARIABLE_NAME,
+ {
+ VAR_CHECK_VARIABLE_PROPERTY_REVISION,
+ 0,
+ VARIABLE_ATTRIBUTE_BS_RT,
+ sizeof (UINT32),
+ sizeof (UINT32)
+ },
+ NULL
+ },
+ {
+ EFI_DRIVER_ORDER_VARIABLE_NAME,
+ {
+ VAR_CHECK_VARIABLE_PROPERTY_REVISION,
+ 0,
+ VARIABLE_ATTRIBUTE_NV_BS_RT,
+ sizeof (UINT16),
+ MAX_UINTN
+ },
+ InternalVarCheckSizeArray
+ },
+ {
+ EFI_HW_ERR_REC_SUPPORT_VARIABLE_NAME,
+ {
+ VAR_CHECK_VARIABLE_PROPERTY_REVISION,
+ 0,
+ VARIABLE_ATTRIBUTE_NV_BS_RT,
+ sizeof (UINT16),
+ sizeof (UINT16)
+ },
+ NULL
+ },
+ {
+ EFI_SETUP_MODE_NAME,
+ {
+ VAR_CHECK_VARIABLE_PROPERTY_REVISION,
+ VAR_CHECK_VARIABLE_PROPERTY_READ_ONLY,
+ VARIABLE_ATTRIBUTE_BS_RT,
+ sizeof (UINT8),
+ sizeof (UINT8)
+ },
+ NULL
+ },
+ {
+ EFI_KEY_EXCHANGE_KEY_NAME,
+ {
+ VAR_CHECK_VARIABLE_PROPERTY_REVISION,
+ 0,
+ VARIABLE_ATTRIBUTE_NV_BS_RT_AT,
+ 1,
+ MAX_UINTN
+ },
+ NULL
+ },
+ {
+ EFI_PLATFORM_KEY_NAME,
+ {
+ VAR_CHECK_VARIABLE_PROPERTY_REVISION,
+ 0,
+ VARIABLE_ATTRIBUTE_NV_BS_RT_AT,
+ 1,
+ MAX_UINTN
+ },
+ NULL
+ },
+ {
+ EFI_SIGNATURE_SUPPORT_NAME,
+ {
+ VAR_CHECK_VARIABLE_PROPERTY_REVISION,
+ VAR_CHECK_VARIABLE_PROPERTY_READ_ONLY,
+ VARIABLE_ATTRIBUTE_BS_RT,
+ sizeof (EFI_GUID),
+ MAX_UINTN
+ },
+ InternalVarCheckSizeArray
+ },
+ {
+ EFI_SECURE_BOOT_MODE_NAME,
+ {
+ VAR_CHECK_VARIABLE_PROPERTY_REVISION,
+ VAR_CHECK_VARIABLE_PROPERTY_READ_ONLY,
+ VARIABLE_ATTRIBUTE_BS_RT,
+ sizeof (UINT8),
+ sizeof (UINT8)
+ },
+ NULL
+ },
+ {
+ EFI_KEK_DEFAULT_VARIABLE_NAME,
+ {
+ VAR_CHECK_VARIABLE_PROPERTY_REVISION,
+ VAR_CHECK_VARIABLE_PROPERTY_READ_ONLY,
+ VARIABLE_ATTRIBUTE_BS_RT,
+ 1,
+ MAX_UINTN
+ },
+ NULL
+ },
+ {
+ EFI_PK_DEFAULT_VARIABLE_NAME,
+ {
+ VAR_CHECK_VARIABLE_PROPERTY_REVISION,
+ VAR_CHECK_VARIABLE_PROPERTY_READ_ONLY,
+ VARIABLE_ATTRIBUTE_BS_RT,
+ 1,
+ MAX_UINTN
+ },
+ NULL
+ },
+ {
+ EFI_DB_DEFAULT_VARIABLE_NAME,
+ {
+ VAR_CHECK_VARIABLE_PROPERTY_REVISION,
+ VAR_CHECK_VARIABLE_PROPERTY_READ_ONLY,
+ VARIABLE_ATTRIBUTE_BS_RT,
+ 1,
+ MAX_UINTN
+ },
+ NULL
+ },
+ {
+ EFI_DBX_DEFAULT_VARIABLE_NAME,
+ {
+ VAR_CHECK_VARIABLE_PROPERTY_REVISION,
+ VAR_CHECK_VARIABLE_PROPERTY_READ_ONLY,
+ VARIABLE_ATTRIBUTE_BS_RT,
+ 1,
+ MAX_UINTN
+ },
+ NULL
+ },
+ {
+ EFI_DBT_DEFAULT_VARIABLE_NAME,
+ {
+ VAR_CHECK_VARIABLE_PROPERTY_REVISION,
+ VAR_CHECK_VARIABLE_PROPERTY_READ_ONLY,
+ VARIABLE_ATTRIBUTE_BS_RT,
+ 1,
+ MAX_UINTN
+ },
+ NULL
+ },
+ {
+ EFI_OS_INDICATIONS_SUPPORT_VARIABLE_NAME,
+ {
+ VAR_CHECK_VARIABLE_PROPERTY_REVISION,
+ 0,
+ VARIABLE_ATTRIBUTE_BS_RT,
+ sizeof (UINT64),
+ sizeof (UINT64)
+ },
+ NULL
+ },
+ {
+ EFI_OS_INDICATIONS_VARIABLE_NAME,
+ {
+ VAR_CHECK_VARIABLE_PROPERTY_REVISION,
+ 0,
+ VARIABLE_ATTRIBUTE_NV_BS_RT,
+ sizeof (UINT64),
+ sizeof (UINT64)
+ },
+ NULL
+ },
+ {
+ EFI_VENDOR_KEYS_VARIABLE_NAME,
+ {
+ VAR_CHECK_VARIABLE_PROPERTY_REVISION,
+ VAR_CHECK_VARIABLE_PROPERTY_READ_ONLY,
+ VARIABLE_ATTRIBUTE_BS_RT,
+ sizeof (UINT8),
+ sizeof (UINT8)
+ },
+ NULL
+ },
+};
+UEFI_DEFINED_VARIABLE_ENTRY mGlobalVariableList2[] = {
+ {
+ L"Boot####",
+ {
+ VAR_CHECK_VARIABLE_PROPERTY_REVISION,
+ 0,
+ VARIABLE_ATTRIBUTE_NV_BS_RT,
+ sizeof (EFI_LOAD_OPTION),
+ MAX_UINTN
+ },
+ InternalVarCheckLoadOption
+ },
+ {
+ L"Driver####",
+ {
+ VAR_CHECK_VARIABLE_PROPERTY_REVISION,
+ 0,
+ VARIABLE_ATTRIBUTE_NV_BS_RT,
+ sizeof (EFI_LOAD_OPTION),
+ MAX_UINTN
+ },
+ InternalVarCheckLoadOption
+ },
+ {
+ L"Key####",
+ {
+ VAR_CHECK_VARIABLE_PROPERTY_REVISION,
+ 0,
+ VARIABLE_ATTRIBUTE_NV_BS_RT,
+ sizeof (EFI_KEY_OPTION),
+ sizeof (EFI_KEY_OPTION) + 3 * sizeof (EFI_INPUT_KEY)
+ },
+ InternalVarCheckKeyOption
+ },
+};
+
+/**
+ Get UEFI defined global variable property.
+ The code will check if variable guid is global variable guid first.
+ If yes, further check if variable name is in mGlobalVariableList or mGlobalVariableList2.
+
+ @param[in] VariableName Pointer to variable name.
+ @param[in] VendorGuid Variable Vendor Guid.
+ @param[in] WildcardMatch Try wildcard match or not.
+ @param[out] VariableProperty Pointer to variable property.
+ @param[out] VarCheckFunction Pointer to check function.
+
+ @retval EFI_SUCCESS Variable is not global variable.
+ @retval EFI_INVALID_PARAMETER Variable is global variable, but variable name is not in the lists.
+
+**/
+EFI_STATUS
+GetUefiDefinedVariableProperty (
+ IN CHAR16 *VariableName,
+ IN EFI_GUID *VendorGuid,
+ IN BOOLEAN WildcardMatch,
+ OUT VAR_CHECK_VARIABLE_PROPERTY **VariableProperty,
+ OUT INTERNAL_VAR_CHECK_FUNCTION *VarCheckFunction OPTIONAL
+ )
+{
+ UINTN Index;
+ UINTN NameLength;
+
+ if (CompareGuid (VendorGuid, &gEfiGlobalVariableGuid)) {
+ //
+ // Try list 1, exactly match.
+ //
+ for (Index = 0; Index < sizeof (mGlobalVariableList)/sizeof (mGlobalVariableList[0]); Index++) {
+ if (StrCmp (mGlobalVariableList[Index].Name, VariableName) == 0) {
+ if (VarCheckFunction != NULL) {
+ *VarCheckFunction = mGlobalVariableList[Index].CheckFunction;
+ }
+ *VariableProperty = &mGlobalVariableList[Index].VariableProperty;
+ return EFI_SUCCESS;
+ }
+ }
+
+ //
+ // Try list 2.
+ //
+ NameLength = StrLen (VariableName) - 4;
+ for (Index = 0; Index < sizeof (mGlobalVariableList2)/sizeof (mGlobalVariableList2[0]); Index++) {
+ if (WildcardMatch) {
+ if ((StrLen (VariableName) == StrLen (mGlobalVariableList2[Index].Name)) &&
+ (StrnCmp (mGlobalVariableList2[Index].Name, VariableName, NameLength) == 0) &&
+ IsHexaDecimalDigitCharacter (VariableName[NameLength]) &&
+ IsHexaDecimalDigitCharacter (VariableName[NameLength + 1]) &&
+ IsHexaDecimalDigitCharacter (VariableName[NameLength + 2]) &&
+ IsHexaDecimalDigitCharacter (VariableName[NameLength + 3])) {
+ if (VarCheckFunction != NULL) {
+ *VarCheckFunction = mGlobalVariableList2[Index].CheckFunction;
+ }
+ *VariableProperty = &mGlobalVariableList2[Index].VariableProperty;
+ return EFI_SUCCESS;
+ }
+ } else {
+ if (StrCmp (mGlobalVariableList2[Index].Name, VariableName) == 0) {
+ if (VarCheckFunction != NULL) {
+ *VarCheckFunction = mGlobalVariableList2[Index].CheckFunction;
+ }
+ *VariableProperty = &mGlobalVariableList2[Index].VariableProperty;
+ return EFI_SUCCESS;
+ }
+ }
+ }
+
+ //
+ // The variable name is not in the lists.
+ //
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // It is not global variable.
+ //
+ return EFI_SUCCESS;
+}
+
+/**
+ Internal SetVariable check.
+
+ @param[in] VariableName Name of Variable to set.
+ @param[in] VendorGuid Variable vendor GUID.
+ @param[in] Attributes Attribute value of the variable.
+ @param[in] DataSize Size of Data to set.
+ @param[in] Data Data pointer.
+
+ @retval EFI_SUCCESS The SetVariable check result was success.
+ @retval EFI_INVALID_PARAMETER An invalid combination of attribute bits, name, and GUID were supplied,
+ or the DataSize exceeds the minimum or maximum allowed,
+ or the Data value is not following UEFI spec for UEFI defined variables.
+ @retval EFI_WRITE_PROTECTED The variable in question is read-only.
+ @retval Others The return status from check handler.
+
+**/
+EFI_STATUS
+EFIAPI
+InternalVarCheckSetVariableCheck (
+ IN CHAR16 *VariableName,
+ IN EFI_GUID *VendorGuid,
+ IN UINT32 Attributes,
+ IN UINTN DataSize,
+ IN VOID *Data
+ )
+{
+ EFI_STATUS Status;
+ UINTN Index;
+ LIST_ENTRY *Link;
+ VAR_CHECK_VARIABLE_ENTRY *Entry;
+ CHAR16 *Name;
+ VAR_CHECK_VARIABLE_PROPERTY *Property;
+ INTERNAL_VAR_CHECK_FUNCTION VarCheckFunction;
+
+ if (!mEndOfDxe) {
+ //
+ // Only do check after End Of Dxe.
+ //
+ return EFI_SUCCESS;
+ }
+
+ Property = NULL;
+ Status = GetUefiDefinedVariableProperty (VariableName, VendorGuid, TRUE, &Property, &VarCheckFunction);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_INFO, "[Variable]: Var Check UEFI defined variable fail %r - %g:%s\n", Status, VendorGuid, VariableName));
+ return Status;
+ }
+ if (Property == NULL) {
+ VarCheckFunction = NULL;
+ for ( Link = GetFirstNode (&mVarCheckVariableList)
+ ; !IsNull (&mVarCheckVariableList, Link)
+ ; Link = GetNextNode (&mVarCheckVariableList, Link)
+ ) {
+ Entry = BASE_CR (Link, VAR_CHECK_VARIABLE_ENTRY, Link);
+ Name = (CHAR16 *) ((UINTN) Entry + sizeof (*Entry));
+ if (CompareGuid (&Entry->Guid, VendorGuid) && (StrCmp (Name, VariableName) == 0)) {
+ Property = &Entry->VariableProperty;
+ break;
+ }
+ }
+ }
+ if (Property != NULL) {
+ if (mEnableLocking && ((Property->Property & VAR_CHECK_VARIABLE_PROPERTY_READ_ONLY) != 0)) {
+ DEBUG ((EFI_D_INFO, "[Variable]: Var Check ReadOnly variable fail %r - %g:%s\n", EFI_WRITE_PROTECTED, VendorGuid, VariableName));
+ return EFI_WRITE_PROTECTED;
+ }
+ if ((DataSize == 0) || (Attributes == 0)) {
+ //
+ // Do not check delete variable.
+ //
+ return EFI_SUCCESS;
+ }
+ if (Attributes != Property->Attributes) {
+ DEBUG ((EFI_D_INFO, "[Variable]: Var Check Attributes fail %r - %g:%s\n", EFI_INVALID_PARAMETER, VendorGuid, VariableName));
+ return EFI_INVALID_PARAMETER;
+ }
+ if ((DataSize < Property->MinSize) || (DataSize > Property->MaxSize)) {
+ DEBUG ((EFI_D_INFO, "[Variable]: Var Check DataSize fail %r - %g:%s\n", EFI_INVALID_PARAMETER, VendorGuid, VariableName));
+ return EFI_INVALID_PARAMETER;
+ }
+ if (VarCheckFunction != NULL) {
+ Status = VarCheckFunction (
+ Property,
+ DataSize,
+ Data
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_INFO, "[Variable]: Internal Var Check function fail %r - %g:%s\n", Status, VendorGuid, VariableName));
+ return Status;
+ }
+ }
+ }
+
+ for (Index = 0; Index < mNumberOfHandler; Index++) {
+ Status = mHandlerTable[Index] (
+ VariableName,
+ VendorGuid,
+ Attributes,
+ DataSize,
+ Data
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_INFO, "[Variable]: Var Check handler fail %r - %g:%s\n", Status, VendorGuid, VariableName));
+ return Status;
+ }
+ }
+ return EFI_SUCCESS;
+}
+
+/**
+ Reallocates more global memory to store the registered handler list.
+
+ @retval RETURN_SUCCESS Reallocate memory successfully.
+ @retval RETURN_OUT_OF_RESOURCES No enough memory to allocate.
+
+**/
+RETURN_STATUS
+EFIAPI
+ReallocateHandlerTable (
+ VOID
+ )
+{
+ VAR_CHECK_SET_VARIABLE_CHECK_HANDLER *HandlerTable;
+
+ //
+ // Reallocate memory for check handler table.
+ //
+ HandlerTable = ReallocateRuntimePool (
+ mMaxNumberOfHandler * sizeof (VAR_CHECK_SET_VARIABLE_CHECK_HANDLER),
+ (mMaxNumberOfHandler + VAR_CHECK_HANDLER_TABLE_SIZE) * sizeof (VAR_CHECK_SET_VARIABLE_CHECK_HANDLER),
+ mHandlerTable
+ );
+
+ //
+ // No enough resource to allocate.
+ //
+ if (HandlerTable == NULL) {
+ return RETURN_OUT_OF_RESOURCES;
+ }
+
+ mHandlerTable = HandlerTable;
+ //
+ // Increase max handler number.
+ //
+ mMaxNumberOfHandler = mMaxNumberOfHandler + VAR_CHECK_HANDLER_TABLE_SIZE;
+ return RETURN_SUCCESS;
+}
+
+/**
+ Register SetVariable check handler.
+
+ @param[in] Handler Pointer to check handler.
+
+ @retval EFI_SUCCESS The SetVariable check handler was registered successfully.
+ @retval EFI_INVALID_PARAMETER Handler is NULL.
+ @retval EFI_ACCESS_DENIED EFI_END_OF_DXE_EVENT_GROUP_GUID or EFI_EVENT_GROUP_READY_TO_BOOT has
+ already been signaled.
+ @retval EFI_OUT_OF_RESOURCES There is not enough resource for the SetVariable check handler register request.
+ @retval EFI_UNSUPPORTED This interface is not implemented.
+ For example, it is unsupported in VarCheck protocol if both VarCheck and SmmVarCheck protocols are present.
+
+**/
+EFI_STATUS
+EFIAPI
+VarCheckRegisterSetVariableCheckHandler (
+ IN VAR_CHECK_SET_VARIABLE_CHECK_HANDLER Handler
+ )
+{
+ EFI_STATUS Status;
+
+ if (Handler == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (mEndOfDxe) {
+ return EFI_ACCESS_DENIED;
+ }
+
+ DEBUG ((EFI_D_INFO, "RegisterSetVariableCheckHandler - 0x%x\n", Handler));
+
+ //
+ // Check whether the handler list is enough to store new handler.
+ //
+ if (mNumberOfHandler == mMaxNumberOfHandler) {
+ //
+ // Allocate more resources for new handler.
+ //
+ Status = ReallocateHandlerTable();
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ }
+
+ //
+ // Register new handler into the handler list.
+ //
+ mHandlerTable[mNumberOfHandler] = Handler;
+ mNumberOfHandler++;
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Internal variable property get.
+
+ @param[in] Name Pointer to the variable name.
+ @param[in] Guid Pointer to the vendor GUID.
+
+ @return Pointer to the property of variable specified by the Name and Guid.
+
+**/
+VAR_CHECK_VARIABLE_PROPERTY *
+InternalVarCheckVariablePropertyGet (
+ IN CHAR16 *Name,
+ IN EFI_GUID *Guid
+ )
+{
+ LIST_ENTRY *Link;
+ VAR_CHECK_VARIABLE_ENTRY *Entry;
+ CHAR16 *VariableName;
+ VAR_CHECK_VARIABLE_PROPERTY *Property;
+
+ Property = NULL;
+ GetUefiDefinedVariableProperty (Name, Guid, FALSE, &Property, NULL);
+ if (Property != NULL) {
+ return Property;
+ } else {
+ for ( Link = GetFirstNode (&mVarCheckVariableList)
+ ; !IsNull (&mVarCheckVariableList, Link)
+ ; Link = GetNextNode (&mVarCheckVariableList, Link)
+ ) {
+ Entry = BASE_CR (Link, VAR_CHECK_VARIABLE_ENTRY, Link);
+ VariableName = (CHAR16 *) ((UINTN) Entry + sizeof (*Entry));
+ if (CompareGuid (&Entry->Guid, Guid) && (StrCmp (VariableName, Name) == 0)) {
+ return &Entry->VariableProperty;
+ }
+ }
+ }
+
+ return NULL;
+}
+
+/**
+ Variable property set.
+
+ @param[in] Name Pointer to the variable name.
+ @param[in] Guid Pointer to the vendor GUID.
+ @param[in] VariableProperty Pointer to the input variable property.
+
+ @retval EFI_SUCCESS The property of variable specified by the Name and Guid was set successfully.
+ @retval EFI_INVALID_PARAMETER Name, Guid or VariableProperty is NULL, or Name is an empty string,
+ or the fields of VariableProperty are not valid.
+ @retval EFI_ACCESS_DENIED EFI_END_OF_DXE_EVENT_GROUP_GUID or EFI_EVENT_GROUP_READY_TO_BOOT has
+ already been signaled.
+ @retval EFI_OUT_OF_RESOURCES There is not enough resource for the variable property set request.
+
+**/
+EFI_STATUS
+EFIAPI
+VarCheckVariablePropertySet (
+ IN CHAR16 *Name,
+ IN EFI_GUID *Guid,
+ IN VAR_CHECK_VARIABLE_PROPERTY *VariableProperty
+ )
+{
+ EFI_STATUS Status;
+ VAR_CHECK_VARIABLE_ENTRY *Entry;
+ CHAR16 *VariableName;
+ VAR_CHECK_VARIABLE_PROPERTY *Property;
+
+ if (Name == NULL || Name[0] == 0 || Guid == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (VariableProperty == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (VariableProperty->Revision != VAR_CHECK_VARIABLE_PROPERTY_REVISION) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (mEndOfDxe) {
+ return EFI_ACCESS_DENIED;
+ }
+
+ Status = EFI_SUCCESS;
+
+ AcquireLockOnlyAtBootTime (&mVariableModuleGlobal->VariableGlobal.VariableServicesLock);
+
+ Property = InternalVarCheckVariablePropertyGet (Name, Guid);
+ if (Property != NULL) {
+ CopyMem (Property, VariableProperty, sizeof (*VariableProperty));
+ } else {
+ Entry = AllocateRuntimeZeroPool (sizeof (*Entry) + StrSize (Name));
+ if (Entry == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto Done;
+ }
+ VariableName = (CHAR16 *) ((UINTN) Entry + sizeof (*Entry));
+ StrnCpy (VariableName, Name, StrLen (Name));
+ CopyGuid (&Entry->Guid, Guid);
+ CopyMem (&Entry->VariableProperty, VariableProperty, sizeof (*VariableProperty));
+ InsertTailList (&mVarCheckVariableList, &Entry->Link);
+ }
+
+Done:
+ ReleaseLockOnlyAtBootTime (&mVariableModuleGlobal->VariableGlobal.VariableServicesLock);
+
+ return Status;
+}
+
+/**
+ Variable property get.
+
+ @param[in] Name Pointer to the variable name.
+ @param[in] Guid Pointer to the vendor GUID.
+ @param[out] VariableProperty Pointer to the output variable property.
+
+ @retval EFI_SUCCESS The property of variable specified by the Name and Guid was got successfully.
+ @retval EFI_INVALID_PARAMETER Name, Guid or VariableProperty is NULL, or Name is an empty string.
+ @retval EFI_NOT_FOUND The property of variable specified by the Name and Guid was not found.
+
+**/
+EFI_STATUS
+EFIAPI
+VarCheckVariablePropertyGet (
+ IN CHAR16 *Name,
+ IN EFI_GUID *Guid,
+ OUT VAR_CHECK_VARIABLE_PROPERTY *VariableProperty
+ )
+{
+ LIST_ENTRY *Link;
+ VARIABLE_ENTRY *Entry;
+ CHAR16 *VariableName;
+ BOOLEAN Found;
+ VAR_CHECK_VARIABLE_PROPERTY *Property;
+
+ if (Name == NULL || Name[0] == 0 || Guid == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (VariableProperty == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Found = FALSE;
+
+ AcquireLockOnlyAtBootTime (&mVariableModuleGlobal->VariableGlobal.VariableServicesLock);
+
+ Property = InternalVarCheckVariablePropertyGet (Name, Guid);
+ if (Property != NULL) {
+ CopyMem (VariableProperty, Property, sizeof (*VariableProperty));
+ Found = TRUE;
+ }
+
+ for ( Link = GetFirstNode (&mLockedVariableList)
+ ; !IsNull (&mLockedVariableList, Link)
+ ; Link = GetNextNode (&mLockedVariableList, Link)
+ ) {
+ Entry = BASE_CR (Link, VARIABLE_ENTRY, Link);
+ VariableName = (CHAR16 *) ((UINTN) Entry + sizeof (*Entry));
+ if (CompareGuid (&Entry->Guid, Guid) && (StrCmp (VariableName, Name) == 0)) {
+ VariableProperty->Property |= VAR_CHECK_VARIABLE_PROPERTY_READ_ONLY;
+ if (!Found) {
+ VariableProperty->Revision = VAR_CHECK_VARIABLE_PROPERTY_REVISION;
+ Found = TRUE;
+ }
+ }
+ }
+
+ ReleaseLockOnlyAtBootTime (&mVariableModuleGlobal->VariableGlobal.VariableServicesLock);
+
+ return (Found ? EFI_SUCCESS : EFI_NOT_FOUND);
+}
+
diff --git a/MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.c b/MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.c
index b545a05530..e3c06b3962 100644
--- a/MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.c
+++ b/MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.c
@@ -14,7 +14,7 @@
VariableServiceGetVariable() and VariableServiceSetVariable() are external API
to receive datasize and data buffer. The size should be checked carefully.
-Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2006 - 2015, 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
@@ -55,51 +55,6 @@ BOOLEAN mEndOfDxe = FALSE;
///
BOOLEAN mEnableLocking = TRUE;
-//
-// To prevent name collisions with possible future globally defined variables,
-// other internal firmware data variables that are not defined here must be
-// saved with a unique VendorGuid other than EFI_GLOBAL_VARIABLE or
-// any other GUID defined by the UEFI Specification. Implementations must
-// only permit the creation of variables with a UEFI Specification-defined
-// VendorGuid when these variables are documented in the UEFI Specification.
-//
-GLOBAL_VARIABLE_ENTRY mGlobalVariableList[] = {
- {EFI_LANG_CODES_VARIABLE_NAME, VARIABLE_ATTRIBUTE_BS_RT},
- {EFI_LANG_VARIABLE_NAME, VARIABLE_ATTRIBUTE_NV_BS_RT},
- {EFI_TIME_OUT_VARIABLE_NAME, VARIABLE_ATTRIBUTE_NV_BS_RT},
- {EFI_PLATFORM_LANG_CODES_VARIABLE_NAME, VARIABLE_ATTRIBUTE_BS_RT},
- {EFI_PLATFORM_LANG_VARIABLE_NAME, VARIABLE_ATTRIBUTE_NV_BS_RT},
- {EFI_CON_IN_VARIABLE_NAME, VARIABLE_ATTRIBUTE_NV_BS_RT},
- {EFI_CON_OUT_VARIABLE_NAME, VARIABLE_ATTRIBUTE_NV_BS_RT},
- {EFI_ERR_OUT_VARIABLE_NAME, VARIABLE_ATTRIBUTE_NV_BS_RT},
- {EFI_CON_IN_DEV_VARIABLE_NAME, VARIABLE_ATTRIBUTE_BS_RT},
- {EFI_CON_OUT_DEV_VARIABLE_NAME, VARIABLE_ATTRIBUTE_BS_RT},
- {EFI_ERR_OUT_DEV_VARIABLE_NAME, VARIABLE_ATTRIBUTE_BS_RT},
- {EFI_BOOT_ORDER_VARIABLE_NAME, VARIABLE_ATTRIBUTE_NV_BS_RT},
- {EFI_BOOT_NEXT_VARIABLE_NAME, VARIABLE_ATTRIBUTE_NV_BS_RT},
- {EFI_BOOT_CURRENT_VARIABLE_NAME, VARIABLE_ATTRIBUTE_BS_RT},
- {EFI_BOOT_OPTION_SUPPORT_VARIABLE_NAME, VARIABLE_ATTRIBUTE_BS_RT},
- {EFI_DRIVER_ORDER_VARIABLE_NAME, VARIABLE_ATTRIBUTE_NV_BS_RT},
- {EFI_HW_ERR_REC_SUPPORT_VARIABLE_NAME, VARIABLE_ATTRIBUTE_NV_BS_RT},
- {EFI_SETUP_MODE_NAME, VARIABLE_ATTRIBUTE_BS_RT},
- {EFI_KEY_EXCHANGE_KEY_NAME, VARIABLE_ATTRIBUTE_NV_BS_RT_AT},
- {EFI_PLATFORM_KEY_NAME, VARIABLE_ATTRIBUTE_NV_BS_RT_AT},
- {EFI_SIGNATURE_SUPPORT_NAME, VARIABLE_ATTRIBUTE_BS_RT},
- {EFI_SECURE_BOOT_MODE_NAME, VARIABLE_ATTRIBUTE_BS_RT},
- {EFI_KEK_DEFAULT_VARIABLE_NAME, VARIABLE_ATTRIBUTE_BS_RT},
- {EFI_PK_DEFAULT_VARIABLE_NAME, VARIABLE_ATTRIBUTE_BS_RT},
- {EFI_DB_DEFAULT_VARIABLE_NAME, VARIABLE_ATTRIBUTE_BS_RT},
- {EFI_DBX_DEFAULT_VARIABLE_NAME, VARIABLE_ATTRIBUTE_BS_RT},
- {EFI_DBT_DEFAULT_VARIABLE_NAME, VARIABLE_ATTRIBUTE_BS_RT},
- {EFI_OS_INDICATIONS_SUPPORT_VARIABLE_NAME, VARIABLE_ATTRIBUTE_BS_RT},
- {EFI_OS_INDICATIONS_VARIABLE_NAME, VARIABLE_ATTRIBUTE_NV_BS_RT},
- {EFI_VENDOR_KEYS_VARIABLE_NAME, VARIABLE_ATTRIBUTE_BS_RT},
-};
-GLOBAL_VARIABLE_ENTRY mGlobalVariableList2[] = {
- {L"Boot####", VARIABLE_ATTRIBUTE_NV_BS_RT},
- {L"Driver####", VARIABLE_ATTRIBUTE_NV_BS_RT},
- {L"Key####", VARIABLE_ATTRIBUTE_NV_BS_RT},
-};
/**
Routine used to track statistical information about variable usage.
@@ -2175,63 +2130,6 @@ IsHwErrRecVariable (
}
/**
- This code checks if variable guid is global variable guid first.
- If yes, further check if variable name is in mGlobalVariableList or mGlobalVariableList2 and attributes matched.
-
- @param[in] VariableName Pointer to variable name.
- @param[in] VendorGuid Variable Vendor Guid.
- @param[in] Attributes Attributes of the variable.
-
- @retval EFI_SUCCESS Variable is not global variable, or Variable is global variable, variable name is in the lists and attributes matched.
- @retval EFI_INVALID_PARAMETER Variable is global variable, but variable name is not in the lists or attributes unmatched.
-
-**/
-EFI_STATUS
-EFIAPI
-CheckEfiGlobalVariable (
- IN CHAR16 *VariableName,
- IN EFI_GUID *VendorGuid,
- IN UINT32 Attributes
- )
-{
- UINTN Index;
- UINTN NameLength;
-
- if (CompareGuid (VendorGuid, &gEfiGlobalVariableGuid)){
- //
- // Try list 1, exactly match.
- //
- for (Index = 0; Index < sizeof (mGlobalVariableList)/sizeof (mGlobalVariableList[0]); Index++) {
- if ((StrCmp (mGlobalVariableList[Index].Name, VariableName) == 0) &&
- (Attributes == 0 || Attributes == mGlobalVariableList[Index].Attributes)) {
- return EFI_SUCCESS;
- }
- }
-
- //
- // Try list 2.
- //
- NameLength = StrLen (VariableName) - 4;
- for (Index = 0; Index < sizeof (mGlobalVariableList2)/sizeof (mGlobalVariableList2[0]); Index++) {
- if ((StrLen (VariableName) == StrLen (mGlobalVariableList2[Index].Name)) &&
- (StrnCmp (mGlobalVariableList2[Index].Name, VariableName, NameLength) == 0) &&
- IsHexaDecimalDigitCharacter (VariableName[NameLength]) &&
- IsHexaDecimalDigitCharacter (VariableName[NameLength + 1]) &&
- IsHexaDecimalDigitCharacter (VariableName[NameLength + 2]) &&
- IsHexaDecimalDigitCharacter (VariableName[NameLength + 3]) &&
- (Attributes == 0 || Attributes == mGlobalVariableList2[Index].Attributes)) {
- return EFI_SUCCESS;
- }
- }
-
- DEBUG ((EFI_D_INFO, "[Variable]: set global variable with invalid variable name or attributes - %g:%s:%x\n", VendorGuid, VariableName, Attributes));
- return EFI_INVALID_PARAMETER;
- }
-
- return EFI_SUCCESS;
-}
-
-/**
Mark a variable that will become read-only after leaving the DXE phase of execution.
@param[in] This The VARIABLE_LOCK_PROTOCOL instance.
@@ -2255,6 +2153,7 @@ VariableLockRequestToLock (
)
{
VARIABLE_ENTRY *Entry;
+ CHAR16 *Name;
if (VariableName == NULL || VariableName[0] == 0 || VendorGuid == NULL) {
return EFI_INVALID_PARAMETER;
@@ -2273,8 +2172,8 @@ VariableLockRequestToLock (
AcquireLockOnlyAtBootTime(&mVariableModuleGlobal->VariableGlobal.VariableServicesLock);
- Entry->Name = (CHAR16 *) (Entry + 1);
- StrnCpy (Entry->Name, VariableName, StrLen (VariableName));
+ Name = (CHAR16 *) ((UINTN) Entry + sizeof (*Entry));
+ StrnCpy (Name, VariableName, StrLen (VariableName));
CopyGuid (&Entry->Guid, VendorGuid);
InsertTailList (&mLockedVariableList, &Entry->Link);
@@ -2567,6 +2466,7 @@ VariableServiceSetVariable (
EFI_PHYSICAL_ADDRESS Point;
LIST_ENTRY *Link;
VARIABLE_ENTRY *Entry;
+ CHAR16 *Name;
//
// Check input parameters.
@@ -2619,12 +2519,7 @@ VariableServiceSetVariable (
//
if (StrSize (VariableName) + DataSize > PcdGet32 (PcdMaxVariableSize) - sizeof (VARIABLE_HEADER)) {
return EFI_INVALID_PARAMETER;
- }
- }
-
- Status = CheckEfiGlobalVariable (VariableName, VendorGuid, Attributes);
- if (EFI_ERROR (Status)) {
- return Status;
+ }
}
AcquireLockOnlyAtBootTime(&mVariableModuleGlobal->VariableGlobal.VariableServicesLock);
@@ -2653,7 +2548,8 @@ VariableServiceSetVariable (
; Link = GetNextNode (&mLockedVariableList, Link)
) {
Entry = BASE_CR (Link, VARIABLE_ENTRY, Link);
- if (CompareGuid (&Entry->Guid, VendorGuid) && (StrCmp (Entry->Name, VariableName) == 0)) {
+ Name = (CHAR16 *) ((UINTN) Entry + sizeof (*Entry));
+ if (CompareGuid (&Entry->Guid, VendorGuid) && (StrCmp (Name, VariableName) == 0)) {
Status = EFI_WRITE_PROTECTED;
DEBUG ((EFI_D_INFO, "[Variable]: Changing readonly variable after leaving DXE phase - %g:%s\n", VendorGuid, VariableName));
goto Done;
@@ -2661,6 +2557,11 @@ VariableServiceSetVariable (
}
}
+ Status = InternalVarCheckSetVariableCheck (VariableName, VendorGuid, Attributes, DataSize, Data);
+ if (EFI_ERROR (Status)) {
+ goto Done;
+ }
+
//
// Check whether the input variable is already existed.
//
@@ -2678,6 +2579,7 @@ VariableServiceSetVariable (
// 2. The only attribute differing is EFI_VARIABLE_APPEND_WRITE
//
Status = EFI_INVALID_PARAMETER;
+ DEBUG ((EFI_D_INFO, "[Variable]: Rewritten a preexisting variable with different attributes - %g:%s\n", VendorGuid, VariableName));
goto Done;
}
}
@@ -3370,10 +3272,10 @@ GetFvbInfoByAddress (
UINTN Index;
EFI_PHYSICAL_ADDRESS FvbBaseAddress;
EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *Fvb;
- EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader;
EFI_FVB_ATTRIBUTES_2 Attributes;
-
- Fvb = NULL;
+ UINTN BlockSize;
+ UINTN NumberOfBlocks;
+
HandleBuffer = NULL;
//
@@ -3400,9 +3302,9 @@ GetFvbInfoByAddress (
//
Status = Fvb->GetAttributes (Fvb, &Attributes);
if (EFI_ERROR (Status) || ((Attributes & EFI_FVB2_WRITE_STATUS) == 0)) {
- continue;
+ continue;
}
-
+
//
// Compare the address and select the right one.
//
@@ -3411,8 +3313,15 @@ GetFvbInfoByAddress (
continue;
}
- FwVolHeader = (EFI_FIRMWARE_VOLUME_HEADER *) ((UINTN) FvbBaseAddress);
- if ((Address >= FvbBaseAddress) && (Address < (FvbBaseAddress + FwVolHeader->FvLength))) {
+ //
+ // Assume one FVB has one type of BlockSize.
+ //
+ Status = Fvb->GetBlockSize (Fvb, 0, &BlockSize, &NumberOfBlocks);
+ if (EFI_ERROR (Status)) {
+ continue;
+ }
+
+ if ((Address >= FvbBaseAddress) && (Address < (FvbBaseAddress + BlockSize * NumberOfBlocks))) {
if (FvbHandle != NULL) {
*FvbHandle = HandleBuffer[Index];
}
diff --git a/MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.h b/MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.h
index ac71f0c957..eb21cd854b 100644
--- a/MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.h
+++ b/MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.h
@@ -3,7 +3,7 @@
The internal header file includes the common header files, defines
internal structure and functions used by Variable modules.
-Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2006 - 2015, 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
@@ -23,6 +23,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#include <Protocol/FirmwareVolumeBlock.h>
#include <Protocol/Variable.h>
#include <Protocol/VariableLock.h>
+#include <Protocol/VarCheck.h>
#include <Library/PcdLib.h>
#include <Library/HobLib.h>
#include <Library/UefiDriverEntryPoint.h>
@@ -46,11 +47,6 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#define VARIABLE_ATTRIBUTE_NV_BS_RT (VARIABLE_ATTRIBUTE_BS_RT | EFI_VARIABLE_NON_VOLATILE)
#define VARIABLE_ATTRIBUTE_NV_BS_RT_AT (VARIABLE_ATTRIBUTE_NV_BS_RT | EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS)
-typedef struct {
- CHAR16 *Name;
- UINT32 Attributes;
-} GLOBAL_VARIABLE_ENTRY;
-
///
/// The size of a 3 character ISO639 language code.
///
@@ -105,9 +101,9 @@ typedef struct {
} VARIABLE_ENTRY_CONSISTENCY;
typedef struct {
- EFI_GUID Guid;
- CHAR16 *Name;
LIST_ENTRY Link;
+ EFI_GUID Guid;
+ //CHAR16 *Name;
} VARIABLE_ENTRY;
/**
@@ -395,6 +391,9 @@ VariableServiceGetVariable (
This code Finds the Next available variable.
+ Caution: This function may receive untrusted input.
+ This function may be invoked in SMM mode. This function will do basic validation, before parse the data.
+
@param VariableNameSize Size of the variable name.
@param VariableName Pointer to variable name.
@param VendorGuid Variable Vendor Guid.
@@ -417,6 +416,10 @@ VariableServiceGetNextVariableName (
This code sets variable in storage blocks (Volatile or Non-Volatile).
+ Caution: This function may receive untrusted input.
+ This function may be invoked in SMM mode, and datasize and data are external input.
+ This function will do basic validation, before parse the data.
+
@param VariableName Name of Variable to be found.
@param VendorGuid Variable vendor GUID.
@param Attributes Attribute value of the variable found
@@ -445,6 +448,9 @@ VariableServiceSetVariable (
This code returns information about the EFI variables.
+ Caution: This function may receive untrusted input.
+ This function may be invoked in SMM mode. This function will do basic validation, before parse the data.
+
@param Attributes Attributes bitmask to specify the type of variables
on which to return information.
@param MaximumVariableStorageSize Pointer to the maximum size of the storage space available
@@ -470,6 +476,9 @@ VariableServiceQueryVariableInfoInternal (
This code returns information about the EFI variables.
+ Caution: This function may receive untrusted input.
+ This function may be invoked in SMM mode. This function will do basic validation, before parse the data.
+
@param Attributes Attributes bitmask to specify the type of variables
on which to return information.
@param MaximumVariableStorageSize Pointer to the maximum size of the storage space available
@@ -516,6 +525,116 @@ VariableLockRequestToLock (
IN EFI_GUID *VendorGuid
);
+/**
+ Check if a Unicode character is a hexadecimal character.
+
+ This function checks if a Unicode character is a
+ hexadecimal character. The valid hexadecimal character is
+ L'0' to L'9', L'a' to L'f', or L'A' to L'F'.
+
+
+ @param Char The character to check against.
+
+ @retval TRUE If the Char is a hexadecmial character.
+ @retval FALSE If the Char is not a hexadecmial character.
+
+**/
+BOOLEAN
+EFIAPI
+IsHexaDecimalDigitCharacter (
+ IN CHAR16 Char
+ );
+
+/**
+ Internal SetVariable check.
+
+ @param[in] VariableName Name of Variable to set.
+ @param[in] VendorGuid Variable vendor GUID.
+ @param[in] Attributes Attribute value of the variable.
+ @param[in] DataSize Size of Data to set.
+ @param[in] Data Data pointer.
+
+ @retval EFI_SUCCESS The SetVariable check result was success.
+ @retval EFI_INVALID_PARAMETER An invalid combination of attribute bits, name, and GUID were supplied,
+ or the DataSize exceeds the minimum or maximum allowed,
+ or the Data value is not following UEFI spec for UEFI defined variables.
+ @retval EFI_WRITE_PROTECTED The variable in question is read-only.
+ @retval Others The return status from check handler.
+
+**/
+EFI_STATUS
+EFIAPI
+InternalVarCheckSetVariableCheck (
+ IN CHAR16 *VariableName,
+ IN EFI_GUID *VendorGuid,
+ IN UINT32 Attributes,
+ IN UINTN DataSize,
+ IN VOID *Data
+ );
+
+/**
+ Register SetVariable check handler.
+
+ @param[in] Handler Pointer to check handler.
+
+ @retval EFI_SUCCESS The SetVariable check handler was registered successfully.
+ @retval EFI_INVALID_PARAMETER Handler is NULL.
+ @retval EFI_ACCESS_DENIED EFI_END_OF_DXE_EVENT_GROUP_GUID or EFI_EVENT_GROUP_READY_TO_BOOT has
+ already been signaled.
+ @retval EFI_OUT_OF_RESOURCES There is not enough resource for the SetVariable check handler register request.
+ @retval EFI_UNSUPPORTED This interface is not implemented.
+ For example, it is unsupported in VarCheck protocol if both VarCheck and SmmVarCheck protocols are present.
+
+**/
+EFI_STATUS
+EFIAPI
+VarCheckRegisterSetVariableCheckHandler (
+ IN VAR_CHECK_SET_VARIABLE_CHECK_HANDLER Handler
+ );
+
+/**
+ Variable property set.
+
+ @param[in] Name Pointer to the variable name.
+ @param[in] Guid Pointer to the vendor GUID.
+ @param[in] VariableProperty Pointer to the input variable property.
+
+ @retval EFI_SUCCESS The property of variable specified by the Name and Guid was set successfully.
+ @retval EFI_INVALID_PARAMETER Name, Guid or VariableProperty is NULL, or Name is an empty string,
+ or the fields of VariableProperty are not valid.
+ @retval EFI_ACCESS_DENIED EFI_END_OF_DXE_EVENT_GROUP_GUID or EFI_EVENT_GROUP_READY_TO_BOOT has
+ already been signaled.
+ @retval EFI_OUT_OF_RESOURCES There is not enough resource for the variable property set request.
+
+**/
+EFI_STATUS
+EFIAPI
+VarCheckVariablePropertySet (
+ IN CHAR16 *Name,
+ IN EFI_GUID *Guid,
+ IN VAR_CHECK_VARIABLE_PROPERTY *VariableProperty
+ );
+
+/**
+ Variable property get.
+
+ @param[in] Name Pointer to the variable name.
+ @param[in] Guid Pointer to the vendor GUID.
+ @param[out] VariableProperty Pointer to the output variable property.
+
+ @retval EFI_SUCCESS The property of variable specified by the Name and Guid was got successfully.
+ @retval EFI_INVALID_PARAMETER Name, Guid or VariableProperty is NULL, or Name is an empty string.
+ @retval EFI_NOT_FOUND The property of variable specified by the Name and Guid was not found.
+
+**/
+EFI_STATUS
+EFIAPI
+VarCheckVariablePropertyGet (
+ IN CHAR16 *Name,
+ IN EFI_GUID *Guid,
+ OUT VAR_CHECK_VARIABLE_PROPERTY *VariableProperty
+ );
+
extern VARIABLE_MODULE_GLOBAL *mVariableModuleGlobal;
#endif
diff --git a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableDxe.c b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableDxe.c
index 2b7b0ecfb7..2aa04f1fef 100644
--- a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableDxe.c
+++ b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableDxe.c
@@ -4,7 +4,7 @@
and volatile storage space and install variable architecture protocol.
Copyright (C) 2013, Red Hat, Inc.
-Copyright (c) 2006 - 2013, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2006 - 2015, 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
@@ -23,8 +23,14 @@ EFI_HANDLE mHandle = NULL;
EFI_EVENT mVirtualAddressChangeEvent = NULL;
EFI_EVENT mFtwRegistration = NULL;
extern LIST_ENTRY mLockedVariableList;
+extern LIST_ENTRY mVarCheckVariableList;
+extern UINT32 mNumberOfHandler;
+extern VAR_CHECK_SET_VARIABLE_CHECK_HANDLER *mHandlerTable;
extern BOOLEAN mEndOfDxe;
EDKII_VARIABLE_LOCK_PROTOCOL mVariableLock = { VariableLockRequestToLock };
+EDKII_VAR_CHECK_PROTOCOL mVarCheck = { VarCheckRegisterSetVariableCheckHandler,
+ VarCheckVariablePropertySet,
+ VarCheckVariablePropertyGet };
/**
Return TRUE if ExitBootServices () has been called.
@@ -222,9 +228,8 @@ VariableClassAddressChangeEvent (
IN VOID *Context
)
{
- LIST_ENTRY *Link;
- VARIABLE_ENTRY *Entry;
EFI_STATUS Status;
+ UINTN Index;
EfiConvertPointer (0x0, (VOID **) &mVariableModuleGlobal->FvbInstance->GetBlockSize);
EfiConvertPointer (0x0, (VOID **) &mVariableModuleGlobal->FvbInstance->GetPhysicalAddress);
@@ -242,23 +247,16 @@ VariableClassAddressChangeEvent (
EfiConvertPointer (0x0, (VOID **) &mVariableModuleGlobal->VariableGlobal.HobVariableBase);
EfiConvertPointer (0x0, (VOID **) &mVariableModuleGlobal);
EfiConvertPointer (0x0, (VOID **) &mNvVariableCache);
-
- //
- // in the list of locked variables, convert the name pointers first
- //
- for ( Link = GetFirstNode (&mLockedVariableList)
- ; !IsNull (&mLockedVariableList, Link)
- ; Link = GetNextNode (&mLockedVariableList, Link)
- ) {
- Entry = BASE_CR (Link, VARIABLE_ENTRY, Link);
- Status = EfiConvertPointer (0x0, (VOID **) &Entry->Name);
- ASSERT_EFI_ERROR (Status);
+ EfiConvertPointer (0x0, (VOID **) &mHandlerTable);
+ for (Index = 0; Index < mNumberOfHandler; Index++) {
+ EfiConvertPointer (0x0, (VOID **) &mHandlerTable[Index]);
}
- //
- // second, convert the list itself using UefiRuntimeLib
- //
+
Status = EfiConvertList (0x0, &mLockedVariableList);
ASSERT_EFI_ERROR (Status);
+
+ Status = EfiConvertList (0x0, &mVarCheckVariableList);
+ ASSERT_EFI_ERROR (Status);
}
@@ -442,6 +440,14 @@ VariableServiceInitialize (
);
ASSERT_EFI_ERROR (Status);
+ Status = gBS->InstallMultipleProtocolInterfaces (
+ &mHandle,
+ &gEdkiiVarCheckProtocolGuid,
+ &mVarCheck,
+ NULL
+ );
+ ASSERT_EFI_ERROR (Status);
+
SystemTable->RuntimeServices->GetVariable = VariableServiceGetVariable;
SystemTable->RuntimeServices->GetNextVariableName = VariableServiceGetNextVariableName;
SystemTable->RuntimeServices->SetVariable = VariableServiceSetVariable;
diff --git a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf
index f8ee4684e2..007a6dc591 100644
--- a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf
+++ b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf
@@ -8,7 +8,7 @@
# This external input must be validated carefully to avoid security issues such as
# buffer overflow or integer overflow.
#
-# Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.<BR>
+# Copyright (c) 2006 - 2015, 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
@@ -42,6 +42,7 @@
Variable.c
VariableDxe.c
Variable.h
+ VarCheck.c
[Packages]
MdePkg/MdePkg.dec
@@ -60,6 +61,7 @@
UefiDriverEntryPoint
PcdLib
HobLib
+ DevicePathLib
[Protocols]
gEfiFirmwareVolumeBlockProtocolGuid ## CONSUMES
@@ -69,6 +71,7 @@
gEfiVariableWriteArchProtocolGuid ## PRODUCES
gEfiVariableArchProtocolGuid ## PRODUCES
gEdkiiVariableLockProtocolGuid ## PRODUCES
+ gEdkiiVarCheckProtocolGuid ## PRODUCES
[Guids]
## PRODUCES ## GUID # Signature of Variable store header
diff --git a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmm.c b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmm.c
index a80948bce8..6df1660a04 100644
--- a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmm.c
+++ b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmm.c
@@ -15,7 +15,7 @@
VariableServiceSetVariable(), VariableServiceQueryVariableInfo(), ReclaimForOS(),
SmmVariableGetStatistics() should also do validation based on its own knowledge.
-Copyright (c) 2010 - 2013, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2010 - 2015, 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,6 +30,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#include <Protocol/SmmFaultTolerantWrite.h>
#include <Protocol/SmmAccess2.h>
#include <Protocol/SmmEndOfDxe.h>
+#include <Protocol/SmmVarCheck.h>
#include <Library/SmmServicesTableLib.h>
@@ -102,6 +103,10 @@ EFI_SMM_VARIABLE_PROTOCOL gSmmVariable = {
VariableServiceQueryVariableInfo
};
+EDKII_SMM_VAR_CHECK_PROTOCOL mSmmVarCheck = { VarCheckRegisterSetVariableCheckHandler,
+ VarCheckVariablePropertySet,
+ VarCheckVariablePropertyGet };
+
/**
Return TRUE if ExitBootServices () has been called.
@@ -498,6 +503,7 @@ SmmVariableHandler (
SMM_VARIABLE_COMMUNICATE_QUERY_VARIABLE_INFO *QueryVariableInfo;
VARIABLE_INFO_ENTRY *VariableInfo;
SMM_VARIABLE_COMMUNICATE_LOCK_VARIABLE *VariableToLock;
+ SMM_VARIABLE_COMMUNICATE_VAR_CHECK_VARIABLE_PROPERTY *CommVariableProperty;
UINTN InfoSize;
UINTN NameBufferSize;
UINTN CommBufferPayloadSize;
@@ -731,6 +737,61 @@ SmmVariableHandler (
);
}
break;
+ case SMM_VARIABLE_FUNCTION_VAR_CHECK_VARIABLE_PROPERTY_SET:
+ if (mEndOfDxe) {
+ Status = EFI_ACCESS_DENIED;
+ } else {
+ CommVariableProperty = (SMM_VARIABLE_COMMUNICATE_VAR_CHECK_VARIABLE_PROPERTY *) SmmVariableFunctionHeader->Data;
+ Status = VarCheckVariablePropertySet (
+ CommVariableProperty->Name,
+ &CommVariableProperty->Guid,
+ &CommVariableProperty->VariableProperty
+ );
+ }
+ break;
+ case SMM_VARIABLE_FUNCTION_VAR_CHECK_VARIABLE_PROPERTY_GET:
+ if (CommBufferPayloadSize < OFFSET_OF (SMM_VARIABLE_COMMUNICATE_VAR_CHECK_VARIABLE_PROPERTY, Name)) {
+ DEBUG ((EFI_D_ERROR, "VarCheckVariablePropertyGet: SMM communication buffer size invalid!\n"));
+ return EFI_SUCCESS;
+ }
+ //
+ // Copy the input communicate buffer payload to pre-allocated SMM variable buffer payload.
+ //
+ CopyMem (mVariableBufferPayload, SmmVariableFunctionHeader->Data, CommBufferPayloadSize);
+ CommVariableProperty = (SMM_VARIABLE_COMMUNICATE_VAR_CHECK_VARIABLE_PROPERTY *) mVariableBufferPayload;
+ if ((UINTN) (~0) - CommVariableProperty->NameSize < OFFSET_OF (SMM_VARIABLE_COMMUNICATE_VAR_CHECK_VARIABLE_PROPERTY, Name)) {
+ //
+ // Prevent InfoSize overflow happen
+ //
+ Status = EFI_ACCESS_DENIED;
+ goto EXIT;
+ }
+ InfoSize = OFFSET_OF (SMM_VARIABLE_COMMUNICATE_VAR_CHECK_VARIABLE_PROPERTY, Name) + CommVariableProperty->NameSize;
+
+ //
+ // SMRAM range check already covered before
+ //
+ if (InfoSize > CommBufferPayloadSize) {
+ DEBUG ((EFI_D_ERROR, "VarCheckVariablePropertyGet: Data size exceed communication buffer size limit!\n"));
+ Status = EFI_ACCESS_DENIED;
+ goto EXIT;
+ }
+
+ if (CommVariableProperty->NameSize < sizeof (CHAR16) || CommVariableProperty->Name[CommVariableProperty->NameSize/sizeof (CHAR16) - 1] != L'\0') {
+ //
+ // Make sure VariableName is A Null-terminated string.
+ //
+ Status = EFI_ACCESS_DENIED;
+ goto EXIT;
+ }
+
+ Status = VarCheckVariablePropertyGet (
+ CommVariableProperty->Name,
+ &CommVariableProperty->Guid,
+ &CommVariableProperty->VariableProperty
+ );
+ CopyMem (SmmVariableFunctionHeader->Data, mVariableBufferPayload, CommBufferPayloadSize);
+ break;
default:
Status = EFI_UNSUPPORTED;
@@ -887,6 +948,14 @@ VariableServiceInitialize (
);
ASSERT_EFI_ERROR (Status);
+ Status = gSmst->SmmInstallProtocolInterface (
+ &VariableHandle,
+ &gEdkiiSmmVarCheckProtocolGuid,
+ EFI_NATIVE_INTERFACE,
+ &mSmmVarCheck
+ );
+ ASSERT_EFI_ERROR (Status);
+
//
// Get SMRAM information
//
@@ -910,7 +979,7 @@ VariableServiceInitialize (
mSmramRangeCount = Size / sizeof (EFI_SMRAM_DESCRIPTOR);
mVariableBufferPayloadSize = MAX (PcdGet32 (PcdMaxVariableSize), PcdGet32 (PcdMaxHardwareErrorVariableSize)) +
- OFFSET_OF (SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE, Name) - sizeof (VARIABLE_HEADER);
+ OFFSET_OF (SMM_VARIABLE_COMMUNICATE_VAR_CHECK_VARIABLE_PROPERTY, Name) - sizeof (VARIABLE_HEADER);
Status = gSmst->SmmAllocatePool (
EfiRuntimeServicesData,
diff --git a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmm.inf b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmm.inf
index 62361c299a..5e88213449 100644
--- a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmm.inf
+++ b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmm.inf
@@ -12,7 +12,7 @@
# This external input must be validated carefully to avoid security issue like
# buffer overflow, integer overflow.
#
-# Copyright (c) 2010 - 2014, Intel Corporation. All rights reserved.<BR>
+# Copyright (c) 2010 - 2015, 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
@@ -44,6 +44,7 @@
Reclaim.c
Variable.c
VariableSmm.c
+ VarCheck.c
Variable.h
[Packages]
@@ -62,6 +63,7 @@
DxeServicesTableLib
HobLib
PcdLib
+ DevicePathLib
[Protocols]
gEfiSmmFirmwareVolumeBlockProtocolGuid ## CONSUMES
@@ -72,7 +74,8 @@
## UNDEFINED # SmiHandlerRegister
gEfiSmmVariableProtocolGuid
gEfiSmmAccess2ProtocolGuid ## CONSUMES
- gEfiSmmEndOfDxeProtocolGuid ## CONSUMES
+ gEfiSmmEndOfDxeProtocolGuid ## NOTIFY
+ gEdkiiSmmVarCheckProtocolGuid ## PRODUCES
[Guids]
## PRODUCES ## GUID # Signature of Variable store header
diff --git a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmmRuntimeDxe.c b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmmRuntimeDxe.c
index 14e421cb79..873930ce67 100644
--- a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmmRuntimeDxe.c
+++ b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmmRuntimeDxe.c
@@ -14,7 +14,7 @@
InitCommunicateBuffer() is really function to check the variable data size.
-Copyright (c) 2010 - 2014, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2010 - 2015, 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,6 +30,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#include <Protocol/SmmCommunication.h>
#include <Protocol/SmmVariable.h>
#include <Protocol/VariableLock.h>
+#include <Protocol/VarCheck.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Library/UefiRuntimeServicesTableLib.h>
@@ -56,6 +57,7 @@ UINTN mVariableBufferSize;
UINTN mVariableBufferPayloadSize;
EFI_LOCK mVariableServicesLock;
EDKII_VARIABLE_LOCK_PROTOCOL mVariableLock;
+EDKII_VAR_CHECK_PROTOCOL mVarCheck;
/**
Acquires lock only at boot time. Simply returns at runtime.
@@ -245,6 +247,180 @@ Done:
}
/**
+ Register SetVariable check handler.
+
+ @param[in] Handler Pointer to check handler.
+
+ @retval EFI_SUCCESS The SetVariable check handler was registered successfully.
+ @retval EFI_INVALID_PARAMETER Handler is NULL.
+ @retval EFI_ACCESS_DENIED EFI_END_OF_DXE_EVENT_GROUP_GUID or EFI_EVENT_GROUP_READY_TO_BOOT has
+ already been signaled.
+ @retval EFI_OUT_OF_RESOURCES There is not enough resource for the SetVariable check handler register request.
+ @retval EFI_UNSUPPORTED This interface is not implemented.
+ For example, it is unsupported in VarCheck protocol if both VarCheck and SmmVarCheck protocols are present.
+
+**/
+EFI_STATUS
+EFIAPI
+VarCheckRegisterSetVariableCheckHandler (
+ IN VAR_CHECK_SET_VARIABLE_CHECK_HANDLER Handler
+ )
+{
+ return EFI_UNSUPPORTED;
+}
+
+/**
+ Variable property set.
+
+ @param[in] Name Pointer to the variable name.
+ @param[in] Guid Pointer to the vendor GUID.
+ @param[in] VariableProperty Pointer to the input variable property.
+
+ @retval EFI_SUCCESS The property of variable specified by the Name and Guid was set successfully.
+ @retval EFI_INVALID_PARAMETER Name, Guid or VariableProperty is NULL, or Name is an empty string,
+ or the fields of VariableProperty are not valid.
+ @retval EFI_ACCESS_DENIED EFI_END_OF_DXE_EVENT_GROUP_GUID or EFI_EVENT_GROUP_READY_TO_BOOT has
+ already been signaled.
+ @retval EFI_OUT_OF_RESOURCES There is not enough resource for the variable property set request.
+
+**/
+EFI_STATUS
+EFIAPI
+VarCheckVariablePropertySet (
+ IN CHAR16 *Name,
+ IN EFI_GUID *Guid,
+ IN VAR_CHECK_VARIABLE_PROPERTY *VariableProperty
+ )
+{
+ EFI_STATUS Status;
+ UINTN VariableNameSize;
+ UINTN PayloadSize;
+ SMM_VARIABLE_COMMUNICATE_VAR_CHECK_VARIABLE_PROPERTY *CommVariableProperty;
+
+ if (Name == NULL || Name[0] == 0 || Guid == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (VariableProperty == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (VariableProperty->Revision != VAR_CHECK_VARIABLE_PROPERTY_REVISION) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ VariableNameSize = StrSize (Name);
+ CommVariableProperty = NULL;
+
+ //
+ // If VariableName exceeds SMM payload limit. Return failure
+ //
+ if (VariableNameSize > mVariableBufferPayloadSize - OFFSET_OF (SMM_VARIABLE_COMMUNICATE_VAR_CHECK_VARIABLE_PROPERTY, Name)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ AcquireLockOnlyAtBootTime (&mVariableServicesLock);
+
+ //
+ // Init the communicate buffer. The buffer data size is:
+ // SMM_COMMUNICATE_HEADER_SIZE + SMM_VARIABLE_COMMUNICATE_HEADER_SIZE + PayloadSize.
+ //
+ PayloadSize = OFFSET_OF (SMM_VARIABLE_COMMUNICATE_VAR_CHECK_VARIABLE_PROPERTY, Name) + VariableNameSize;
+ Status = InitCommunicateBuffer ((VOID **) &CommVariableProperty, PayloadSize, SMM_VARIABLE_FUNCTION_VAR_CHECK_VARIABLE_PROPERTY_SET);
+ if (EFI_ERROR (Status)) {
+ goto Done;
+ }
+ ASSERT (CommVariableProperty != NULL);
+
+ CopyGuid (&CommVariableProperty->Guid, Guid);
+ CopyMem (&CommVariableProperty->VariableProperty, VariableProperty, sizeof (*VariableProperty));
+ CommVariableProperty->NameSize = VariableNameSize;
+ CopyMem (CommVariableProperty->Name, Name, CommVariableProperty->NameSize);
+
+ //
+ // Send data to SMM.
+ //
+ Status = SendCommunicateBuffer (PayloadSize);
+
+Done:
+ ReleaseLockOnlyAtBootTime (&mVariableServicesLock);
+ return Status;
+}
+
+/**
+ Variable property get.
+
+ @param[in] Name Pointer to the variable name.
+ @param[in] Guid Pointer to the vendor GUID.
+ @param[out] VariableProperty Pointer to the output variable property.
+
+ @retval EFI_SUCCESS The property of variable specified by the Name and Guid was got successfully.
+ @retval EFI_INVALID_PARAMETER Name, Guid or VariableProperty is NULL, or Name is an empty string.
+ @retval EFI_NOT_FOUND The property of variable specified by the Name and Guid was not found.
+
+**/
+EFI_STATUS
+EFIAPI
+VarCheckVariablePropertyGet (
+ IN CHAR16 *Name,
+ IN EFI_GUID *Guid,
+ OUT VAR_CHECK_VARIABLE_PROPERTY *VariableProperty
+ )
+{
+ EFI_STATUS Status;
+ UINTN VariableNameSize;
+ UINTN PayloadSize;
+ SMM_VARIABLE_COMMUNICATE_VAR_CHECK_VARIABLE_PROPERTY *CommVariableProperty;
+
+ if (Name == NULL || Name[0] == 0 || Guid == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (VariableProperty == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ VariableNameSize = StrSize (Name);
+ CommVariableProperty = NULL;
+
+ //
+ // If VariableName exceeds SMM payload limit. Return failure
+ //
+ if (VariableNameSize > mVariableBufferPayloadSize - OFFSET_OF (SMM_VARIABLE_COMMUNICATE_VAR_CHECK_VARIABLE_PROPERTY, Name)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ AcquireLockOnlyAtBootTime (&mVariableServicesLock);
+
+ //
+ // Init the communicate buffer. The buffer data size is:
+ // SMM_COMMUNICATE_HEADER_SIZE + SMM_VARIABLE_COMMUNICATE_HEADER_SIZE + PayloadSize.
+ //
+ PayloadSize = OFFSET_OF (SMM_VARIABLE_COMMUNICATE_VAR_CHECK_VARIABLE_PROPERTY, Name) + VariableNameSize;
+ Status = InitCommunicateBuffer ((VOID **) &CommVariableProperty, PayloadSize, SMM_VARIABLE_FUNCTION_VAR_CHECK_VARIABLE_PROPERTY_GET);
+ if (EFI_ERROR (Status)) {
+ goto Done;
+ }
+ ASSERT (CommVariableProperty != NULL);
+
+ CopyGuid (&CommVariableProperty->Guid, Guid);
+ CommVariableProperty->NameSize = VariableNameSize;
+ CopyMem (CommVariableProperty->Name, Name, CommVariableProperty->NameSize);
+
+ //
+ // Send data to SMM.
+ //
+ Status = SendCommunicateBuffer (PayloadSize);
+ if (Status == EFI_SUCCESS) {
+ CopyMem (VariableProperty, &CommVariableProperty->VariableProperty, sizeof (*VariableProperty));
+ }
+
+Done:
+ ReleaseLockOnlyAtBootTime (&mVariableServicesLock);
+ return Status;
+}
+
+/**
This code finds variable in storage blocks (Volatile or Non-Volatile).
Caution: This function may receive untrusted input.
@@ -734,7 +910,7 @@ SmmVariableReady (
// Allocate memory for variable communicate buffer.
//
mVariableBufferPayloadSize = MAX (PcdGet32 (PcdMaxVariableSize), PcdGet32 (PcdMaxHardwareErrorVariableSize)) +
- OFFSET_OF (SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE, Name) - sizeof (VARIABLE_HEADER);
+ OFFSET_OF (SMM_VARIABLE_COMMUNICATE_VAR_CHECK_VARIABLE_PROPERTY, Name) - sizeof (VARIABLE_HEADER);
mVariableBufferSize = SMM_COMMUNICATE_HEADER_SIZE + SMM_VARIABLE_COMMUNICATE_HEADER_SIZE + mVariableBufferPayloadSize;
mVariableBuffer = AllocateRuntimePool (mVariableBufferSize);
ASSERT (mVariableBuffer != NULL);
@@ -833,6 +1009,17 @@ VariableSmmRuntimeInitialize (
);
ASSERT_EFI_ERROR (Status);
+ mVarCheck.RegisterSetVariableCheckHandler = VarCheckRegisterSetVariableCheckHandler;
+ mVarCheck.VariablePropertySet = VarCheckVariablePropertySet;
+ mVarCheck.VariablePropertyGet = VarCheckVariablePropertyGet;
+ Status = gBS->InstallMultipleProtocolInterfaces (
+ &mHandle,
+ &gEdkiiVarCheckProtocolGuid,
+ &mVarCheck,
+ NULL
+ );
+ ASSERT_EFI_ERROR (Status);
+
//
// Smm variable service is ready
//
diff --git a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmmRuntimeDxe.inf b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmmRuntimeDxe.inf
index 4bd470662f..a72619e002 100644
--- a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmmRuntimeDxe.inf
+++ b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmmRuntimeDxe.inf
@@ -10,7 +10,7 @@
# This external input must be validated carefully to avoid security issues such as
# buffer overflow or integer overflow.
#
-# Copyright (c) 2010 - 2014, Intel Corporation. All rights reserved.<BR>
+# Copyright (c) 2010 - 2015, 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
@@ -65,6 +65,7 @@
## UNDEFINED # Used to do smm communication
gEfiSmmVariableProtocolGuid
gEdkiiVariableLockProtocolGuid ## PRODUCES
+ gEdkiiVarCheckProtocolGuid ## PRODUCES
[Guids]
gEfiEventVirtualAddressChangeGuid ## CONSUMES ## Event
diff --git a/MdePkg/Include/Library/BaseLib.h b/MdePkg/Include/Library/BaseLib.h
index d65b01adf6..bd3f9cfc60 100644
--- a/MdePkg/Include/Library/BaseLib.h
+++ b/MdePkg/Include/Library/BaseLib.h
@@ -481,7 +481,11 @@ AsciiStrnCatS (
);
+#ifndef DISABLE_NEW_DEPRECATED_INTERFACES
+
/**
+ [ATTENTION] This function will be deprecated for security reason.
+
Copies one Null-terminated Unicode string to another Null-terminated Unicode
string and returns the new Unicode string.
@@ -513,6 +517,8 @@ StrCpy (
/**
+ [ATTENTION] This function will be deprecated for security reason.
+
Copies up to a specified length from one Null-terminated Unicode string to
another Null-terminated Unicode string and returns the new Unicode string.
@@ -549,7 +555,7 @@ StrnCpy (
IN CONST CHAR16 *Source,
IN UINTN Length
);
-
+#endif
/**
Returns the length of a Null-terminated Unicode string.
@@ -677,7 +683,11 @@ StrnCmp (
);
+#ifndef DISABLE_NEW_DEPRECATED_INTERFACES
+
/**
+ [ATTENTION] This function will be deprecated for security reason.
+
Concatenates one Null-terminated Unicode string to another Null-terminated
Unicode string, and returns the concatenated Unicode string.
@@ -718,6 +728,8 @@ StrCat (
/**
+ [ATTENTION] This function will be deprecated for security reason.
+
Concatenates up to a specified length one Null-terminated Unicode to the end
of another Null-terminated Unicode string, and returns the concatenated
Unicode string.
@@ -762,6 +774,7 @@ StrnCat (
IN CONST CHAR16 *Source,
IN UINTN Length
);
+#endif
/**
Returns the first occurrence of a Null-terminated Unicode sub-string
@@ -1000,7 +1013,11 @@ UnicodeStrToAsciiStr (
);
+#ifndef DISABLE_NEW_DEPRECATED_INTERFACES
+
/**
+ [ATTENTION] This function will be deprecated for security reason.
+
Copies one Null-terminated ASCII string to another Null-terminated ASCII
string and returns the new ASCII string.
@@ -1030,6 +1047,8 @@ AsciiStrCpy (
/**
+ [ATTENTION] This function will be deprecated for security reason.
+
Copies up to a specified length one Null-terminated ASCII string to another
Null-terminated ASCII string and returns the new ASCII string.
@@ -1063,7 +1082,7 @@ AsciiStrnCpy (
IN CONST CHAR8 *Source,
IN UINTN Length
);
-
+#endif
/**
Returns the length of a Null-terminated ASCII string.
@@ -1223,7 +1242,11 @@ AsciiStrnCmp (
);
+#ifndef DISABLE_NEW_DEPRECATED_INTERFACES
+
/**
+ [ATTENTION] This function will be deprecated for security reason.
+
Concatenates one Null-terminated ASCII string to another Null-terminated
ASCII string, and returns the concatenated ASCII string.
@@ -1259,6 +1282,8 @@ AsciiStrCat (
/**
+ [ATTENTION] This function will be deprecated for security reason.
+
Concatenates up to a specified length one Null-terminated ASCII string to
the end of another Null-terminated ASCII string, and returns the
concatenated ASCII string.
@@ -1301,7 +1326,7 @@ AsciiStrnCat (
IN CONST CHAR8 *Source,
IN UINTN Length
);
-
+#endif
/**
Returns the first occurrence of a Null-terminated ASCII sub-string
diff --git a/MdePkg/Include/Library/HobLib.h b/MdePkg/Include/Library/HobLib.h
index 855a0ece2c..c6b1596171 100644
--- a/MdePkg/Include/Library/HobLib.h
+++ b/MdePkg/Include/Library/HobLib.h
@@ -184,30 +184,30 @@ BuildModuleHob (
IN EFI_PHYSICAL_ADDRESS EntryPoint
);
-/**
+/**
Builds a HOB that describes a chunk of system memory with Owner GUID.
-
- This function builds a HOB that describes a chunk of system memory.
- It can only be invoked during PEI phase;
- for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.
-
- If there is no additional space for HOB creation, then ASSERT().
-
- @param ResourceType The type of resource described by this HOB.
- @param ResourceAttribute The resource attributes of the memory described by this HOB.
- @param PhysicalStart The 64 bit physical address of memory described by this HOB.
- @param NumberOfBytes The length of the memory described by this HOB in bytes.
+
+ This function builds a HOB that describes a chunk of system memory.
+ It can only be invoked during PEI phase;
+ for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.
+
+ If there is no additional space for HOB creation, then ASSERT().
+
+ @param ResourceType The type of resource described by this HOB.
+ @param ResourceAttribute The resource attributes of the memory described by this HOB.
+ @param PhysicalStart The 64 bit physical address of memory described by this HOB.
+ @param NumberOfBytes The length of the memory described by this HOB in bytes.
@param OwnerGUID GUID for the owner of this resource.
-
-**/
-VOID
-EFIAPI
-BuildResourceDescriptorWithOwnerHob (
- IN EFI_RESOURCE_TYPE ResourceType,
- IN EFI_RESOURCE_ATTRIBUTE_TYPE ResourceAttribute,
- IN EFI_PHYSICAL_ADDRESS PhysicalStart,
- IN UINT64 NumberOfBytes,
- IN EFI_GUID *OwnerGUID
+
+**/
+VOID
+EFIAPI
+BuildResourceDescriptorWithOwnerHob (
+ IN EFI_RESOURCE_TYPE ResourceType,
+ IN EFI_RESOURCE_ATTRIBUTE_TYPE ResourceAttribute,
+ IN EFI_PHYSICAL_ADDRESS PhysicalStart,
+ IN UINT64 NumberOfBytes,
+ IN EFI_GUID *OwnerGUID
);
/**
diff --git a/MdePkg/Library/BaseLib/String.c b/MdePkg/Library/BaseLib/String.c
index 9505c5b21e..92992a5d27 100644
--- a/MdePkg/Library/BaseLib/String.c
+++ b/MdePkg/Library/BaseLib/String.c
@@ -14,8 +14,11 @@
#include "BaseLibInternals.h"
+#ifndef DISABLE_NEW_DEPRECATED_INTERFACES
/**
+ [ATTENTION] This function will be deprecated for security reason.
+
Copies one Null-terminated Unicode string to another Null-terminated Unicode
string and returns the new Unicode string.
@@ -68,6 +71,8 @@ StrCpy (
}
/**
+ [ATTENTION] This function will be deprecated for security reason.
+
Copies up to a specified length from one Null-terminated Unicode string to
another Null-terminated Unicode string and returns the new Unicode string.
@@ -137,6 +142,7 @@ StrnCpy (
ZeroMem (Destination, Length * sizeof (*Destination));
return ReturnValue;
}
+#endif
/**
Returns the length of a Null-terminated Unicode string.
@@ -319,7 +325,11 @@ StrnCmp (
return *FirstString - *SecondString;
}
+#ifndef DISABLE_NEW_DEPRECATED_INTERFACES
+
/**
+ [ATTENTION] This function will be deprecated for security reason.
+
Concatenates one Null-terminated Unicode string to another Null-terminated
Unicode string, and returns the concatenated Unicode string.
@@ -369,6 +379,8 @@ StrCat (
}
/**
+ [ATTENTION] This function will be deprecated for security reason.
+
Concatenates up to a specified length one Null-terminated Unicode to the end
of another Null-terminated Unicode string, and returns the concatenated
Unicode string.
@@ -427,6 +439,7 @@ StrnCat (
ASSERT (StrSize (Destination) != 0);
return Destination;
}
+#endif
/**
Returns the first occurrence of a Null-terminated Unicode sub-string
@@ -1065,8 +1078,11 @@ UnicodeStrToAsciiStr (
return ReturnValue;
}
+#ifndef DISABLE_NEW_DEPRECATED_INTERFACES
/**
+ [ATTENTION] This function will be deprecated for security reason.
+
Copies one Null-terminated ASCII string to another Null-terminated ASCII
string and returns the new ASCII string.
@@ -1116,6 +1132,8 @@ AsciiStrCpy (
}
/**
+ [ATTENTION] This function will be deprecated for security reason.
+
Copies up to a specified length one Null-terminated ASCII string to another
Null-terminated ASCII string and returns the new ASCII string.
@@ -1181,6 +1199,7 @@ AsciiStrnCpy (
ZeroMem (Destination, Length * sizeof (*Destination));
return ReturnValue;
}
+#endif
/**
Returns the length of a Null-terminated ASCII string.
@@ -1462,7 +1481,11 @@ AsciiStrnCmp (
return *FirstString - *SecondString;
}
+#ifndef DISABLE_NEW_DEPRECATED_INTERFACES
+
/**
+ [ATTENTION] This function will be deprecated for security reason.
+
Concatenates one Null-terminated ASCII string to another Null-terminated
ASCII string, and returns the concatenated ASCII string.
@@ -1507,6 +1530,8 @@ AsciiStrCat (
}
/**
+ [ATTENTION] This function will be deprecated for security reason.
+
Concatenates up to a specified length one Null-terminated ASCII string to
the end of another Null-terminated ASCII string, and returns the
concatenated ASCII string.
@@ -1563,6 +1588,7 @@ AsciiStrnCat (
ASSERT (AsciiStrSize (Destination) != 0);
return Destination;
}
+#endif
/**
Returns the first occurrence of a Null-terminated ASCII sub-string
diff --git a/MdePkg/Library/DxeCoreHobLib/HobLib.c b/MdePkg/Library/DxeCoreHobLib/HobLib.c
index e483f9c98d..ad66966279 100644
--- a/MdePkg/Library/DxeCoreHobLib/HobLib.c
+++ b/MdePkg/Library/DxeCoreHobLib/HobLib.c
@@ -239,32 +239,32 @@ BuildModuleHob (
ASSERT (FALSE);
}
-/**
+/**
Builds a HOB that describes a chunk of system memory with Owner GUID.
-
- This function builds a HOB that describes a chunk of system memory.
- It can only be invoked during PEI phase;
- for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.
-
- If there is no additional space for HOB creation, then ASSERT().
-
- @param ResourceType The type of resource described by this HOB.
- @param ResourceAttribute The resource attributes of the memory described by this HOB.
- @param PhysicalStart The 64 bit physical address of memory described by this HOB.
- @param NumberOfBytes The length of the memory described by this HOB in bytes.
+
+ This function builds a HOB that describes a chunk of system memory.
+ It can only be invoked during PEI phase;
+ for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.
+
+ If there is no additional space for HOB creation, then ASSERT().
+
+ @param ResourceType The type of resource described by this HOB.
+ @param ResourceAttribute The resource attributes of the memory described by this HOB.
+ @param PhysicalStart The 64 bit physical address of memory described by this HOB.
+ @param NumberOfBytes The length of the memory described by this HOB in bytes.
@param OwnerGUID GUID for the owner of this resource.
-
-**/
-VOID
-EFIAPI
-BuildResourceDescriptorWithOwnerHob (
- IN EFI_RESOURCE_TYPE ResourceType,
- IN EFI_RESOURCE_ATTRIBUTE_TYPE ResourceAttribute,
- IN EFI_PHYSICAL_ADDRESS PhysicalStart,
- IN UINT64 NumberOfBytes,
- IN EFI_GUID *OwnerGUID
- )
-{
+
+**/
+VOID
+EFIAPI
+BuildResourceDescriptorWithOwnerHob (
+ IN EFI_RESOURCE_TYPE ResourceType,
+ IN EFI_RESOURCE_ATTRIBUTE_TYPE ResourceAttribute,
+ IN EFI_PHYSICAL_ADDRESS PhysicalStart,
+ IN UINT64 NumberOfBytes,
+ IN EFI_GUID *OwnerGUID
+ )
+{
//
// PEI HOB is read only for DXE phase
//
diff --git a/MdePkg/Library/DxeHobLib/HobLib.c b/MdePkg/Library/DxeHobLib/HobLib.c
index 3cedc6f6c6..f0861ffcb4 100644
--- a/MdePkg/Library/DxeHobLib/HobLib.c
+++ b/MdePkg/Library/DxeHobLib/HobLib.c
@@ -272,32 +272,32 @@ BuildModuleHob (
ASSERT (FALSE);
}
-/**
+/**
Builds a HOB that describes a chunk of system memory with Owner GUID.
-
- This function builds a HOB that describes a chunk of system memory.
- It can only be invoked during PEI phase;
- for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.
-
- If there is no additional space for HOB creation, then ASSERT().
-
- @param ResourceType The type of resource described by this HOB.
- @param ResourceAttribute The resource attributes of the memory described by this HOB.
- @param PhysicalStart The 64 bit physical address of memory described by this HOB.
- @param NumberOfBytes The length of the memory described by this HOB in bytes.
+
+ This function builds a HOB that describes a chunk of system memory.
+ It can only be invoked during PEI phase;
+ for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.
+
+ If there is no additional space for HOB creation, then ASSERT().
+
+ @param ResourceType The type of resource described by this HOB.
+ @param ResourceAttribute The resource attributes of the memory described by this HOB.
+ @param PhysicalStart The 64 bit physical address of memory described by this HOB.
+ @param NumberOfBytes The length of the memory described by this HOB in bytes.
@param OwnerGUID GUID for the owner of this resource.
-
-**/
-VOID
-EFIAPI
-BuildResourceDescriptorWithOwnerHob (
- IN EFI_RESOURCE_TYPE ResourceType,
- IN EFI_RESOURCE_ATTRIBUTE_TYPE ResourceAttribute,
- IN EFI_PHYSICAL_ADDRESS PhysicalStart,
- IN UINT64 NumberOfBytes,
- IN EFI_GUID *OwnerGUID
- )
-{
+
+**/
+VOID
+EFIAPI
+BuildResourceDescriptorWithOwnerHob (
+ IN EFI_RESOURCE_TYPE ResourceType,
+ IN EFI_RESOURCE_ATTRIBUTE_TYPE ResourceAttribute,
+ IN EFI_PHYSICAL_ADDRESS PhysicalStart,
+ IN UINT64 NumberOfBytes,
+ IN EFI_GUID *OwnerGUID
+ )
+{
//
// PEI HOB is read only for DXE phase
//
diff --git a/MdePkg/Library/PeiHobLib/HobLib.c b/MdePkg/Library/PeiHobLib/HobLib.c
index f853452f56..f3ce93afc6 100644
--- a/MdePkg/Library/PeiHobLib/HobLib.c
+++ b/MdePkg/Library/PeiHobLib/HobLib.c
@@ -300,45 +300,45 @@ BuildModuleHob (
Hob->EntryPoint = EntryPoint;
}
-/**
+/**
Builds a HOB that describes a chunk of system memory with Owner GUID.
-
- This function builds a HOB that describes a chunk of system memory.
- It can only be invoked during PEI phase;
- for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.
-
- If there is no additional space for HOB creation, then ASSERT().
-
- @param ResourceType The type of resource described by this HOB.
- @param ResourceAttribute The resource attributes of the memory described by this HOB.
- @param PhysicalStart The 64 bit physical address of memory described by this HOB.
- @param NumberOfBytes The length of the memory described by this HOB in bytes.
+
+ This function builds a HOB that describes a chunk of system memory.
+ It can only be invoked during PEI phase;
+ for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.
+
+ If there is no additional space for HOB creation, then ASSERT().
+
+ @param ResourceType The type of resource described by this HOB.
+ @param ResourceAttribute The resource attributes of the memory described by this HOB.
+ @param PhysicalStart The 64 bit physical address of memory described by this HOB.
+ @param NumberOfBytes The length of the memory described by this HOB in bytes.
@param OwnerGUID GUID for the owner of this resource.
-
-**/
-VOID
-EFIAPI
-BuildResourceDescriptorWithOwnerHob (
- IN EFI_RESOURCE_TYPE ResourceType,
- IN EFI_RESOURCE_ATTRIBUTE_TYPE ResourceAttribute,
- IN EFI_PHYSICAL_ADDRESS PhysicalStart,
- IN UINT64 NumberOfBytes,
- IN EFI_GUID *OwnerGUID
- )
-{
- EFI_HOB_RESOURCE_DESCRIPTOR *Hob;
+
+**/
+VOID
+EFIAPI
+BuildResourceDescriptorWithOwnerHob (
+ IN EFI_RESOURCE_TYPE ResourceType,
+ IN EFI_RESOURCE_ATTRIBUTE_TYPE ResourceAttribute,
+ IN EFI_PHYSICAL_ADDRESS PhysicalStart,
+ IN UINT64 NumberOfBytes,
+ IN EFI_GUID *OwnerGUID
+ )
+{
+ EFI_HOB_RESOURCE_DESCRIPTOR *Hob;
Hob = InternalPeiCreateHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR, (UINT16) sizeof (EFI_HOB_RESOURCE_DESCRIPTOR));
if (Hob == NULL) {
return;
}
-
- Hob->ResourceType = ResourceType;
- Hob->ResourceAttribute = ResourceAttribute;
- Hob->PhysicalStart = PhysicalStart;
- Hob->ResourceLength = NumberOfBytes;
-
- CopyGuid (&Hob->Owner, OwnerGUID);
+
+ Hob->ResourceType = ResourceType;
+ Hob->ResourceAttribute = ResourceAttribute;
+ Hob->PhysicalStart = PhysicalStart;
+ Hob->ResourceLength = NumberOfBytes;
+
+ CopyGuid (&Hob->Owner, OwnerGUID);
}
/**
diff --git a/MdePkg/Library/UefiDevicePathLibDevicePathProtocol/UefiDevicePathLib.c b/MdePkg/Library/UefiDevicePathLibDevicePathProtocol/UefiDevicePathLib.c
index b73bcce07c..5cc4b35fe4 100644
--- a/MdePkg/Library/UefiDevicePathLibDevicePathProtocol/UefiDevicePathLib.c
+++ b/MdePkg/Library/UefiDevicePathLibDevicePathProtocol/UefiDevicePathLib.c
@@ -2,7 +2,7 @@
Library instance that implement UEFI Device Path Library class based on protocol
gEfiDevicePathUtilitiesProtocolGuid.
- Copyright (c) 2006 - 2013, Intel Corporation. All rights reserved.<BR>
+ Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
@@ -195,12 +195,8 @@ DevicePathNodeLength (
IN CONST VOID *Node
)
{
- UINTN Length;
-
ASSERT (Node != NULL);
- Length = ReadUnaligned16 ((UINT16 *)&((EFI_DEVICE_PATH_PROTOCOL *)(Node))->Length[0]);
- ASSERT (Length >= sizeof (EFI_DEVICE_PATH_PROTOCOL));
- return Length;
+ return ReadUnaligned16 ((UINT16 *)&((EFI_DEVICE_PATH_PROTOCOL *)(Node))->Length[0]);
}
/**
@@ -567,8 +563,7 @@ GetNextDevicePathInstance (
If there is not enough memory to allocate space for the new device path, then
NULL is returned.
The memory is allocated from EFI boot services memory. It is the responsibility
- of the caller to
- free the memory allocated.
+ of the caller to free the memory allocated.
@param NodeType The device node type for the new device node.
@param NodeSubType The device node sub-type for the new device node.
diff --git a/NetworkPkg/Dhcp6Dxe/Dhcp6Io.c b/NetworkPkg/Dhcp6Dxe/Dhcp6Io.c
index e0a2b4b15f..b231479525 100644
--- a/NetworkPkg/Dhcp6Dxe/Dhcp6Io.c
+++ b/NetworkPkg/Dhcp6Dxe/Dhcp6Io.c
@@ -1,6 +1,7 @@
/** @file
Dhcp6 internal functions implementation.
+ (C) Copyright 2014 Hewlett-Packard Development Company, L.P.<BR>
Copyright (c) 2009 - 2014, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
@@ -544,7 +545,6 @@ Dhcp6UpdateIaInfo (
)
{
EFI_STATUS Status;
- EFI_DHCP6_STATE State;
UINT8 *Option;
UINT8 *IaInnerOpt;
UINT16 IaInnerLen;
@@ -565,7 +565,6 @@ Dhcp6UpdateIaInfo (
//
// See details in the section-18.1.8 of rfc-3315.
//
- State = Dhcp6Init;
Option = Dhcp6SeekIaOption (
Packet->Dhcp6.Option,
Packet->Length - sizeof (EFI_DHCP6_HEADER),
@@ -2428,14 +2427,12 @@ Dhcp6HandleAdvertiseMsg (
{
EFI_STATUS Status;
UINT8 *Option;
- UINT16 StsCode;
BOOLEAN Timeout;
ASSERT(Instance->Config);
ASSERT(Instance->IaCb.Ia);
Timeout = FALSE;
- StsCode = Dhcp6StsSuccess;
//
// If the client does receives a valid reply message that includes a rapid
diff --git a/NetworkPkg/IScsiDxe/IScsiMisc.c b/NetworkPkg/IScsiDxe/IScsiMisc.c
index 05f639aaee..aeb99e5f94 100644
--- a/NetworkPkg/IScsiDxe/IScsiMisc.c
+++ b/NetworkPkg/IScsiDxe/IScsiMisc.c
@@ -226,6 +226,7 @@ IScsiLunToUnicodeStr (
//
// Remove the last '-'
//
+ ASSERT (StrLen(Str) >= 1);
Str[StrLen (Str) - 1] = 0;
for (Index = StrLen (Str) - 1; Index > 1; Index = Index - 2) {
diff --git a/NetworkPkg/Ip6Dxe/Ip6Impl.c b/NetworkPkg/Ip6Dxe/Ip6Impl.c
index 621879b1ea..b186c0af20 100644
--- a/NetworkPkg/Ip6Dxe/Ip6Impl.c
+++ b/NetworkPkg/Ip6Dxe/Ip6Impl.c
@@ -1,6 +1,7 @@
/** @file
Implementation of EFI_IP6_PROTOCOL protocol interfaces.
+ (C) Copyright 2014 Hewlett-Packard Development Company, L.P.<BR>
Copyright (c) 2009 - 2014, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
@@ -1761,7 +1762,6 @@ EfiIp6Cancel (
)
{
IP6_PROTOCOL *IpInstance;
- IP6_SERVICE *IpSb;
EFI_STATUS Status;
EFI_TPL OldTpl;
@@ -1770,7 +1770,6 @@ EfiIp6Cancel (
}
IpInstance = IP6_INSTANCE_FROM_PROTOCOL (This);
- IpSb = IpInstance->Service;
OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
diff --git a/NetworkPkg/NetworkPkg.dsc b/NetworkPkg/NetworkPkg.dsc
index 491abd2b8c..80685dd645 100644
--- a/NetworkPkg/NetworkPkg.dsc
+++ b/NetworkPkg/NetworkPkg.dsc
@@ -1,6 +1,7 @@
## @file
# UEFI 2.4 Network Module Package for All Architectures
#
+# (C) Copyright 2014 Hewlett-Packard Development Company, L.P.<BR>
# Copyright (c) 2009 - 2014, Intel Corporation. All rights reserved.<BR>
#
# This program and the accompanying materials
@@ -19,7 +20,7 @@
PLATFORM_VERSION = 0.95
DSC_SPECIFICATION = 0x00010005
OUTPUT_DIRECTORY = Build/NetworkPkg
- SUPPORTED_ARCHITECTURES = IA32|IPF|X64|EBC|ARM
+ SUPPORTED_ARCHITECTURES = IA32|IPF|X64|EBC|ARM|AARCH64
BUILD_TARGETS = DEBUG|RELEASE
SKUID_IDENTIFIER = DEFAULT
@@ -57,6 +58,14 @@
SortLib|ShellPkg/Library/UefiSortLib/UefiSortLib.inf
ShellLib|ShellPkg/Library/UefiShellLib/UefiShellLib.inf
+[LibraryClasses.ARM, LibraryClasses.AARCH64]
+ #
+ # It is not possible to prevent ARM compiler calls to generic intrinsic functions.
+ # This library provides the instrinsic functions generated by a given compiler.
+ # [LibraryClasses.ARM] and NULL mean link this library into all ARM images.
+ #
+ NULL|ArmPkg/Library/CompilerIntrinsicsLib/CompilerIntrinsicsLib.inf
+
[PcdsFeatureFlag]
gEfiMdePkgTokenSpaceGuid.PcdComponentName2Disable|TRUE
gEfiMdePkgTokenSpaceGuid.PcdDriverDiagnostics2Disable|TRUE
diff --git a/NetworkPkg/TcpDxe/TcpDispatcher.c b/NetworkPkg/TcpDxe/TcpDispatcher.c
index 7b3d14dace..d4bc8ace55 100644
--- a/NetworkPkg/TcpDxe/TcpDispatcher.c
+++ b/NetworkPkg/TcpDxe/TcpDispatcher.c
@@ -1,6 +1,7 @@
/** @file
The implementation of a dispatch routine for processing TCP requests.
+ (C) Copyright 2014 Hewlett-Packard Development Company, L.P.<BR>
Copyright (c) 2009 - 2014, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
@@ -98,12 +99,12 @@ Tcp4GetMode (
AccessPoint->UseDefaultAddress = Tcb->UseDefaultAddr;
- CopyMem (&AccessPoint->StationAddress, &Tcb->LocalEnd.Ip, sizeof (EFI_IPv4_ADDRESS));
+ IP4_COPY_ADDRESS (&AccessPoint->StationAddress, &Tcb->LocalEnd.Ip);
- AccessPoint->SubnetMask = Tcb->SubnetMask;
+ IP4_COPY_ADDRESS (&AccessPoint->SubnetMask, &Tcb->SubnetMask);
AccessPoint->StationPort = NTOHS (Tcb->LocalEnd.Port);
- CopyMem (&AccessPoint->RemoteAddress, &Tcb->RemoteEnd.Ip, sizeof (EFI_IPv4_ADDRESS));
+ IP4_COPY_ADDRESS (&AccessPoint->RemoteAddress, &Tcb->RemoteEnd.Ip);
AccessPoint->RemotePort = NTOHS (Tcb->RemoteEnd.Port);
AccessPoint->ActiveFlag = (BOOLEAN) (Tcb->State != TCP_LISTEN);
@@ -239,7 +240,7 @@ TcpBind (
UINT16 *RandomPort;
if (IpVersion == IP_VERSION_4) {
- CopyMem (&Local, &TcpAp->Tcp4Ap.StationAddress, sizeof (EFI_IPv4_ADDRESS));
+ IP4_COPY_ADDRESS (&Local, &TcpAp->Tcp4Ap.StationAddress);
Port = &TcpAp->Tcp4Ap.StationPort;
RandomPort = &mTcp4RandomPort;
} else {
@@ -495,12 +496,14 @@ TcpConfigurePcb (
IpCfgData.Ip4CfgData.TypeOfService = CfgData->Tcp4CfgData.TypeOfService;
IpCfgData.Ip4CfgData.TimeToLive = CfgData->Tcp4CfgData.TimeToLive;
IpCfgData.Ip4CfgData.UseDefaultAddress = CfgData->Tcp4CfgData.AccessPoint.UseDefaultAddress;
- IpCfgData.Ip4CfgData.SubnetMask = CfgData->Tcp4CfgData.AccessPoint.SubnetMask;
+ IP4_COPY_ADDRESS (
+ &IpCfgData.Ip4CfgData.SubnetMask,
+ &CfgData->Tcp4CfgData.AccessPoint.SubnetMask
+ );
IpCfgData.Ip4CfgData.ReceiveTimeout = (UINT32) (-1);
- CopyMem (
+ IP4_COPY_ADDRESS (
&IpCfgData.Ip4CfgData.StationAddress,
- &CfgData->Tcp4CfgData.AccessPoint.StationAddress,
- sizeof (EFI_IPv4_ADDRESS)
+ &CfgData->Tcp4CfgData.AccessPoint.StationAddress
);
} else {
@@ -533,8 +536,14 @@ TcpConfigurePcb (
//
// Get the default address information if the instance is configured to use default address.
//
- CfgData->Tcp4CfgData.AccessPoint.StationAddress = IpCfgData.Ip4CfgData.StationAddress;
- CfgData->Tcp4CfgData.AccessPoint.SubnetMask = IpCfgData.Ip4CfgData.SubnetMask;
+ IP4_COPY_ADDRESS (
+ &CfgData->Tcp4CfgData.AccessPoint.StationAddress,
+ &IpCfgData.Ip4CfgData.StationAddress
+ );
+ IP4_COPY_ADDRESS (
+ &CfgData->Tcp4CfgData.AccessPoint.SubnetMask,
+ &IpCfgData.Ip4CfgData.SubnetMask
+ );
TcpAp = (TCP_ACCESS_POINT *) &CfgData->Tcp4CfgData.AccessPoint;
} else {
@@ -601,7 +610,7 @@ TcpConfigurePcb (
CopyMem (&Tcb->LocalEnd.Ip, &CfgData->Tcp4CfgData.AccessPoint.StationAddress, sizeof (IP4_ADDR));
Tcb->LocalEnd.Port = HTONS (CfgData->Tcp4CfgData.AccessPoint.StationPort);
- Tcb->SubnetMask = CfgData->Tcp4CfgData.AccessPoint.SubnetMask;
+ IP4_COPY_ADDRESS (&Tcb->SubnetMask, &CfgData->Tcp4CfgData.AccessPoint.SubnetMask);
CopyMem (&Tcb->RemoteEnd.Ip, &CfgData->Tcp4CfgData.AccessPoint.RemoteAddress, sizeof (IP4_ADDR));
Tcb->RemoteEnd.Port = HTONS (CfgData->Tcp4CfgData.AccessPoint.RemotePort);
diff --git a/NetworkPkg/TcpDxe/TcpMain.c b/NetworkPkg/TcpDxe/TcpMain.c
index 3c103444bd..66a09c41ea 100644
--- a/NetworkPkg/TcpDxe/TcpMain.c
+++ b/NetworkPkg/TcpDxe/TcpMain.c
@@ -1,6 +1,7 @@
/** @file
Implementation of EFI_TCP4_PROTOCOL and EFI_TCP6_PROTOCOL.
+ (C) Copyright 2014 Hewlett-Packard Development Company, L.P.<BR>
Copyright (c) 2009 - 2011, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
@@ -229,9 +230,9 @@ Tcp4Routes (
Sock = SOCK_FROM_THIS (This);
RouteInfo.DeleteRoute = DeleteRoute;
- RouteInfo.SubnetAddress = SubnetAddress;
- RouteInfo.SubnetMask = SubnetMask;
- RouteInfo.GatewayAddress = GatewayAddress;
+ IP4_COPY_ADDRESS (&RouteInfo.SubnetAddress, &SubnetAddress);
+ IP4_COPY_ADDRESS (&RouteInfo.SubnetMask, &SubnetMask);
+ IP4_COPY_ADDRESS (&RouteInfo.GatewayAddress, &GatewayAddress);
return SockRoute (Sock, &RouteInfo);
}
diff --git a/NetworkPkg/TcpDxe/TcpMisc.c b/NetworkPkg/TcpDxe/TcpMisc.c
index 5394f7d1ca..0a4eda37c8 100644
--- a/NetworkPkg/TcpDxe/TcpMisc.c
+++ b/NetworkPkg/TcpDxe/TcpMisc.c
@@ -1,6 +1,7 @@
/** @file
Misc support routines for TCP driver.
+ (C) Copyright 2014 Hewlett-Packard Development Company, L.P.<BR>
Copyright (c) 2009 - 2014, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
@@ -428,7 +429,6 @@ TcpInsertTcb (
LIST_ENTRY *Entry;
LIST_ENTRY *Head;
TCP_CB *Node;
- TCP_PROTO_DATA *TcpProto;
ASSERT (
(Tcb != NULL) &&
@@ -466,7 +466,6 @@ TcpInsertTcb (
InsertHeadList (Head, &Tcb->List);
- TcpProto = (TCP_PROTO_DATA *) Tcb->Sk->ProtoReserved;
return 0;
}
diff --git a/NetworkPkg/UefiPxeBcDxe/PxeBcDhcp6.c b/NetworkPkg/UefiPxeBcDxe/PxeBcDhcp6.c
index b71998b405..07f1724365 100644
--- a/NetworkPkg/UefiPxeBcDxe/PxeBcDhcp6.c
+++ b/NetworkPkg/UefiPxeBcDxe/PxeBcDhcp6.c
@@ -1,6 +1,7 @@
/** @file
Functions implementation related with DHCPv6 for UefiPxeBc Driver.
+ (C) Copyright 2014 Hewlett-Packard Development Company, L.P.<BR>
Copyright (c) 2009 - 2014, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
@@ -664,7 +665,6 @@ PxeBcRequestBootService (
{
EFI_PXE_BASE_CODE_UDP_PORT SrcPort;
EFI_PXE_BASE_CODE_UDP_PORT DestPort;
- EFI_PXE_BASE_CODE_MODE *Mode;
EFI_PXE_BASE_CODE_PROTOCOL *PxeBc;
EFI_PXE_BASE_CODE_DHCPV6_PACKET *Discover;
UINTN DiscoverLen;
@@ -682,7 +682,6 @@ PxeBcRequestBootService (
UINT8 *Option;
PxeBc = &Private->PxeBc;
- Mode = PxeBc->Mode;
Request = Private->Dhcp6Request;
ProxyOffer = &Private->OfferBuffer[Index].Dhcp6.Packet.Offer;
SrcPort = PXEBC_BS_DISCOVER_PORT;
@@ -1281,7 +1280,7 @@ PxeBcCheckRouteTable (
}
//
- // Find out the gateway address which can route the message whcih send to ServerIp.
+ // Find out the gateway address which can route the message which send to ServerIp.
//
for (Index = 0; Index < Ip6ModeData.RouteCount; Index++) {
if (NetIp6IsNetEqual (&Private->ServerIp.v6, &Ip6ModeData.RouteTable[Index].Destination, Ip6ModeData.RouteTable[Index].PrefixLength)) {
@@ -1382,6 +1381,7 @@ PxeBcRegisterIp6Address (
EFI_STATUS Status;
UINT64 DadTriggerTime;
EFI_IP6_CONFIG_DUP_ADDR_DETECT_TRANSMITS DadXmits;
+ BOOLEAN NoGateway;
Status = EFI_SUCCESS;
TimeOutEvt = NULL;
@@ -1389,6 +1389,7 @@ PxeBcRegisterIp6Address (
DataSize = sizeof (EFI_IP6_CONFIG_POLICY);
Ip6Cfg = Private->Ip6Cfg;
Ip6 = Private->Ip6;
+ NoGateway = FALSE;
ZeroMem (&CfgAddr, sizeof (EFI_IP6_CONFIG_MANUAL_ADDRESS));
CopyMem (&CfgAddr.Address, Address, sizeof (EFI_IPv6_ADDRESS));
@@ -1403,7 +1404,7 @@ PxeBcRegisterIp6Address (
//
Status = PxeBcCheckRouteTable (Private, PXEBC_IP6_ROUTE_TABLE_TIMEOUT, &GatewayAddr);
if (EFI_ERROR (Status)) {
- goto ON_EXIT;
+ NoGateway = TRUE;
}
//
@@ -1504,7 +1505,7 @@ PxeBcRegisterIp6Address (
//
// Set the default gateway address back if needed.
//
- if (!NetIp6IsUnspecifiedAddr (&GatewayAddr)) {
+ if (!NoGateway && !NetIp6IsUnspecifiedAddr (&GatewayAddr)) {
Status = Ip6Cfg->SetData (
Ip6Cfg,
Ip6ConfigDataTypeGateway,
diff --git a/NetworkPkg/UefiPxeBcDxe/PxeBcDriver.c b/NetworkPkg/UefiPxeBcDxe/PxeBcDriver.c
index 8ee831f521..92fd1f19df 100644
--- a/NetworkPkg/UefiPxeBcDxe/PxeBcDriver.c
+++ b/NetworkPkg/UefiPxeBcDxe/PxeBcDriver.c
@@ -1,6 +1,7 @@
/** @file
Driver Binding functions implementationfor for UefiPxeBc Driver.
+ (C) Copyright 2014 Hewlett-Packard Development Company, L.P.<BR>
Copyright (c) 2007 - 2013, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
@@ -1400,7 +1401,6 @@ PxeBcStop (
EFI_LOAD_FILE_PROTOCOL *LoadFile;
EFI_STATUS Status;
EFI_HANDLE NicHandle;
- BOOLEAN IsIpv6;
PXEBC_PRIVATE_PROTOCOL *Id;
Private = NULL;
@@ -1408,7 +1408,6 @@ PxeBcStop (
VirtualNic = NULL;
LoadFile = NULL;
Id = NULL;
- IsIpv6 = FALSE;
Status = gBS->OpenProtocol (
ControllerHandle,
diff --git a/OvmfPkg/Include/Guid/VirtioMmioTransport.h b/OvmfPkg/Include/Guid/VirtioMmioTransport.h
new file mode 100644
index 0000000000..f17d7b1b42
--- /dev/null
+++ b/OvmfPkg/Include/Guid/VirtioMmioTransport.h
@@ -0,0 +1,25 @@
+/** @file
+ Recommended GUID to be used in the Vendor Hardware device path nodes that
+ identify virtio-mmio transports.
+
+ Copyright (C) 2014, Red Hat, Inc.
+
+ 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 __VIRTIO_MMIO_TRANSPORT_H__
+#define __VIRTIO_MMIO_TRANSPORT_H__
+
+#define VIRTIO_MMIO_TRANSPORT_GUID \
+{0x837dca9e, 0xe874, 0x4d82, {0xb2, 0x9a, 0x23, 0xfe, 0x0e, 0x23, 0xd1, 0xe2}}
+
+extern EFI_GUID gVirtioMmioTransportGuid;
+
+#endif
diff --git a/OvmfPkg/Library/PlatformBdsLib/QemuBootOrder.h b/OvmfPkg/Include/Library/QemuBootOrderLib.h
index 8d4ca2b111..12cda6aa91 100644
--- a/OvmfPkg/Library/PlatformBdsLib/QemuBootOrder.h
+++ b/OvmfPkg/Include/Library/QemuBootOrderLib.h
@@ -2,7 +2,7 @@
Rewrite the BootOrder NvVar based on QEMU's "bootorder" fw_cfg file --
include file.
- Copyright (C) 2012, Red Hat, Inc.
+ Copyright (C) 2012-2014, Red Hat, Inc.
This program and the accompanying materials are licensed and made available
under the terms and conditions of the BSD License which accompanies this
@@ -13,6 +13,8 @@
WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
+#ifndef __QEMU_BOOT_ORDER_LIB_H__
+#define __QEMU_BOOT_ORDER_LIB_H__
#include <Uefi/UefiBaseType.h>
#include <Base.h>
@@ -51,3 +53,5 @@ RETURN_STATUS
SetBootOrderFromQemu (
IN CONST LIST_ENTRY *BootOptionList
);
+
+#endif
diff --git a/OvmfPkg/Library/PlatformBdsLib/BdsPlatform.c b/OvmfPkg/Library/PlatformBdsLib/BdsPlatform.c
index df07281448..341f5c1596 100644
--- a/OvmfPkg/Library/PlatformBdsLib/BdsPlatform.c
+++ b/OvmfPkg/Library/PlatformBdsLib/BdsPlatform.c
@@ -13,7 +13,7 @@
**/
#include "BdsPlatform.h"
-#include "QemuBootOrder.h"
+#include <Library/QemuBootOrderLib.h>
//
diff --git a/OvmfPkg/Library/PlatformBdsLib/PlatformBdsLib.inf b/OvmfPkg/Library/PlatformBdsLib/PlatformBdsLib.inf
index 03f5b229cf..1adc28972a 100644
--- a/OvmfPkg/Library/PlatformBdsLib/PlatformBdsLib.inf
+++ b/OvmfPkg/Library/PlatformBdsLib/PlatformBdsLib.inf
@@ -29,10 +29,8 @@
[Sources]
BdsPlatform.c
PlatformData.c
- QemuBootOrder.c
QemuKernel.c
BdsPlatform.h
- QemuBootOrder.h
[Packages]
MdePkg/MdePkg.dec
@@ -52,6 +50,7 @@
NvVarsFileLib
QemuFwCfgLib
LoadLinuxLib
+ QemuBootOrderLib
[Pcd]
gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdPlatformBootTimeOut
diff --git a/OvmfPkg/Library/PlatformBdsLib/QemuBootOrder.c b/OvmfPkg/Library/QemuBootOrderLib/QemuBootOrderLib.c
index bd0fb76877..bc2fb56954 100644
--- a/OvmfPkg/Library/PlatformBdsLib/QemuBootOrder.c
+++ b/OvmfPkg/Library/QemuBootOrderLib/QemuBootOrderLib.c
@@ -1,7 +1,7 @@
/** @file
Rewrite the BootOrder NvVar based on QEMU's "bootorder" fw_cfg file.
- Copyright (C) 2012 - 2013, Red Hat, Inc.
+ Copyright (C) 2012 - 2014, Red Hat, Inc.
Copyright (c) 2013, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials are licensed and made available
@@ -22,7 +22,10 @@
#include <Library/BaseLib.h>
#include <Library/PrintLib.h>
#include <Library/DevicePathLib.h>
+#include <Library/QemuBootOrderLib.h>
+#include <Library/BaseMemoryLib.h>
#include <Guid/GlobalVariable.h>
+#include <Guid/VirtioMmioTransport.h>
/**
@@ -34,8 +37,9 @@
/**
Numbers of nodes in OpenFirmware device paths that are required and examined.
**/
-#define REQUIRED_OFW_NODES 2
-#define EXAMINED_OFW_NODES 4
+#define REQUIRED_PCI_OFW_NODES 2
+#define REQUIRED_MMIO_OFW_NODES 1
+#define EXAMINED_OFW_NODES 4
/**
@@ -127,7 +131,7 @@ SubstringEq (
/**
Parse a comma-separated list of hexadecimal integers into the elements of an
- UINT32 array.
+ UINT64 array.
Whitespace, "0x" prefixes, leading or trailing commas, sequences of commas,
or an empty string are not allowed; they are rejected.
@@ -167,12 +171,12 @@ STATIC
RETURN_STATUS
ParseUnitAddressHexList (
IN SUBSTRING UnitAddress,
- OUT UINT32 *Result,
+ OUT UINT64 *Result,
IN OUT UINTN *NumResults
)
{
UINTN Entry; // number of entry currently being parsed
- UINT32 EntryVal; // value being constructed for current entry
+ UINT64 EntryVal; // value being constructed for current entry
CHAR8 PrevChr; // UnitAddress character previously checked
UINTN Pos; // current position within UnitAddress
RETURN_STATUS Status;
@@ -192,10 +196,10 @@ ParseUnitAddressHexList (
-1;
if (Val >= 0) {
- if (EntryVal > 0xFFFFFFF) {
+ if (EntryVal > 0xFFFFFFFFFFFFFFFull) {
return RETURN_INVALID_PARAMETER;
}
- EntryVal = (EntryVal << 4) | Val;
+ EntryVal = LShiftU64 (EntryVal, 4) | Val;
} else if (Chr == ',') {
if (PrevChr == ',') {
return RETURN_INVALID_PARAMETER;
@@ -538,7 +542,7 @@ ParseOfwNode (
/**
- Translate an array of OpenFirmware device nodes to a UEFI device path
+ Translate a PCI-like array of OpenFirmware device nodes to a UEFI device path
fragment.
@param[in] OfwNode Array of OpenFirmware device nodes to
@@ -570,21 +574,21 @@ ParseOfwNode (
**/
STATIC
RETURN_STATUS
-TranslateOfwNodes (
+TranslatePciOfwNodes (
IN CONST OFW_NODE *OfwNode,
IN UINTN NumNodes,
OUT CHAR16 *Translated,
IN OUT UINTN *TranslatedSize
)
{
- UINT32 PciDevFun[2];
+ UINT64 PciDevFun[2];
UINTN NumEntries;
UINTN Written;
//
// Get PCI device and optional PCI function. Assume a single PCI root.
//
- if (NumNodes < REQUIRED_OFW_NODES ||
+ if (NumNodes < REQUIRED_PCI_OFW_NODES ||
!SubstringEq (OfwNode[0].DriverName, "pci")
) {
return RETURN_UNSUPPORTED;
@@ -621,8 +625,8 @@ TranslateOfwNodes (
// ^
// fixed LUN
//
- UINT32 Secondary;
- UINT32 Slave;
+ UINT64 Secondary;
+ UINT64 Slave;
NumEntries = 1;
if (ParseUnitAddressHexList (
@@ -644,7 +648,7 @@ TranslateOfwNodes (
Written = UnicodeSPrintAsciiFormat (
Translated,
*TranslatedSize * sizeof (*Translated), // BufferSize in bytes
- "PciRoot(0x0)/Pci(0x%x,0x%x)/Ata(%a,%a,0x0)",
+ "PciRoot(0x0)/Pci(0x%Lx,0x%Lx)/Ata(%a,%a,0x0)",
PciDevFun[0],
PciDevFun[1],
Secondary ? "Secondary" : "Primary",
@@ -671,7 +675,7 @@ TranslateOfwNodes (
// ^
// ACPI UID
//
- UINT32 AcpiUid;
+ UINT64 AcpiUid;
NumEntries = 1;
if (ParseUnitAddressHexList (
@@ -687,7 +691,7 @@ TranslateOfwNodes (
Written = UnicodeSPrintAsciiFormat (
Translated,
*TranslatedSize * sizeof (*Translated), // BufferSize in bytes
- "PciRoot(0x0)/Pci(0x%x,0x%x)/Floppy(0x%x)",
+ "PciRoot(0x0)/Pci(0x%Lx,0x%Lx)/Floppy(0x%Lx)",
PciDevFun[0],
PciDevFun[1],
AcpiUid
@@ -714,7 +718,7 @@ TranslateOfwNodes (
Written = UnicodeSPrintAsciiFormat (
Translated,
*TranslatedSize * sizeof (*Translated), // BufferSize in bytes
- "PciRoot(0x0)/Pci(0x%x,0x%x)/HD(",
+ "PciRoot(0x0)/Pci(0x%Lx,0x%Lx)/HD(",
PciDevFun[0],
PciDevFun[1]
);
@@ -741,7 +745,7 @@ TranslateOfwNodes (
// PciRoot(0x0)/Pci(0x7,0x3)/Scsi(0x2,0x3)
// -- if PCI function is present and nonzero
//
- UINT32 TargetLun[2];
+ UINT64 TargetLun[2];
TargetLun[1] = 0;
NumEntries = sizeof (TargetLun) / sizeof (TargetLun[0]);
@@ -757,7 +761,7 @@ TranslateOfwNodes (
Written = UnicodeSPrintAsciiFormat (
Translated,
*TranslatedSize * sizeof (*Translated), // BufferSize in bytes
- "PciRoot(0x0)/Pci(0x%x,0x%x)/Scsi(0x%x,0x%x)",
+ "PciRoot(0x0)/Pci(0x%Lx,0x%Lx)/Scsi(0x%Lx,0x%Lx)",
PciDevFun[0],
PciDevFun[1],
TargetLun[0],
@@ -780,7 +784,7 @@ TranslateOfwNodes (
Written = UnicodeSPrintAsciiFormat (
Translated,
*TranslatedSize * sizeof (*Translated), // BufferSize in bytes
- "PciRoot(0x0)/Pci(0x%x,0x%x)",
+ "PciRoot(0x0)/Pci(0x%Lx,0x%Lx)",
PciDevFun[0],
PciDevFun[1]
);
@@ -800,6 +804,239 @@ TranslateOfwNodes (
}
+//
+// A type providing easy raw access to the base address of a virtio-mmio
+// transport.
+//
+typedef union {
+ UINT64 Uint64;
+ UINT8 Raw[8];
+} VIRTIO_MMIO_BASE_ADDRESS;
+
+
+/**
+
+ Translate an MMIO-like array of OpenFirmware device nodes to a UEFI device
+ path fragment.
+
+ @param[in] OfwNode Array of OpenFirmware device nodes to
+ translate, constituting the beginning of an
+ OpenFirmware device path.
+
+ @param[in] NumNodes Number of elements in OfwNode.
+
+ @param[out] Translated Destination array receiving the UEFI path
+ fragment, allocated by the caller. If the
+ return value differs from RETURN_SUCCESS, its
+ contents is indeterminate.
+
+ @param[in out] TranslatedSize On input, the number of CHAR16's in
+ Translated. On RETURN_SUCCESS this parameter
+ is assigned the number of non-NUL CHAR16's
+ written to Translated. In case of other return
+ values, TranslatedSize is indeterminate.
+
+
+ @retval RETURN_SUCCESS Translation successful.
+
+ @retval RETURN_BUFFER_TOO_SMALL The translation does not fit into the number
+ of bytes provided.
+
+ @retval RETURN_UNSUPPORTED The array of OpenFirmware device nodes can't
+ be translated in the current implementation.
+
+**/
+STATIC
+RETURN_STATUS
+TranslateMmioOfwNodes (
+ IN CONST OFW_NODE *OfwNode,
+ IN UINTN NumNodes,
+ OUT CHAR16 *Translated,
+ IN OUT UINTN *TranslatedSize
+ )
+{
+ VIRTIO_MMIO_BASE_ADDRESS VirtioMmioBase;
+ CHAR16 VenHwString[60 + 1];
+ UINTN NumEntries;
+ UINTN Written;
+
+ //
+ // Get the base address of the virtio-mmio transport.
+ //
+ if (NumNodes < REQUIRED_MMIO_OFW_NODES ||
+ !SubstringEq (OfwNode[0].DriverName, "virtio-mmio")
+ ) {
+ return RETURN_UNSUPPORTED;
+ }
+ NumEntries = 1;
+ if (ParseUnitAddressHexList (
+ OfwNode[0].UnitAddress,
+ &VirtioMmioBase.Uint64,
+ &NumEntries
+ ) != RETURN_SUCCESS
+ ) {
+ return RETURN_UNSUPPORTED;
+ }
+
+ UnicodeSPrintAsciiFormat (VenHwString, sizeof VenHwString,
+ "VenHw(%g,%02X%02X%02X%02X%02X%02X%02X%02X)", &gVirtioMmioTransportGuid,
+ VirtioMmioBase.Raw[0], VirtioMmioBase.Raw[1], VirtioMmioBase.Raw[2],
+ VirtioMmioBase.Raw[3], VirtioMmioBase.Raw[4], VirtioMmioBase.Raw[5],
+ VirtioMmioBase.Raw[6], VirtioMmioBase.Raw[7]);
+
+ if (NumNodes >= 2 &&
+ SubstringEq (OfwNode[1].DriverName, "disk")) {
+ //
+ // OpenFirmware device path (virtio-blk disk):
+ //
+ // /virtio-mmio@000000000a003c00/disk@0,0
+ // ^ ^ ^
+ // | fixed
+ // base address of virtio-mmio register block
+ //
+ // UEFI device path prefix:
+ //
+ // <VenHwString>/HD(
+ //
+ Written = UnicodeSPrintAsciiFormat (
+ Translated,
+ *TranslatedSize * sizeof (*Translated), // BufferSize in bytes
+ "%s/HD(",
+ VenHwString
+ );
+ } else if (NumNodes >= 3 &&
+ SubstringEq (OfwNode[1].DriverName, "channel") &&
+ SubstringEq (OfwNode[2].DriverName, "disk")) {
+ //
+ // OpenFirmware device path (virtio-scsi disk):
+ //
+ // /virtio-mmio@000000000a003a00/channel@0/disk@2,3
+ // ^ ^ ^ ^
+ // | | | LUN
+ // | | target
+ // | channel (unused, fixed 0)
+ // base address of virtio-mmio register block
+ //
+ // UEFI device path prefix:
+ //
+ // <VenHwString>/Scsi(0x2,0x3)
+ //
+ UINT64 TargetLun[2];
+
+ TargetLun[1] = 0;
+ NumEntries = sizeof (TargetLun) / sizeof (TargetLun[0]);
+ if (ParseUnitAddressHexList (
+ OfwNode[2].UnitAddress,
+ TargetLun,
+ &NumEntries
+ ) != RETURN_SUCCESS
+ ) {
+ return RETURN_UNSUPPORTED;
+ }
+
+ Written = UnicodeSPrintAsciiFormat (
+ Translated,
+ *TranslatedSize * sizeof (*Translated), // BufferSize in bytes
+ "%s/Scsi(0x%Lx,0x%Lx)",
+ VenHwString,
+ TargetLun[0],
+ TargetLun[1]
+ );
+ } else if (NumNodes >= 2 &&
+ SubstringEq (OfwNode[1].DriverName, "ethernet-phy")) {
+ //
+ // OpenFirmware device path (virtio-net NIC):
+ //
+ // /virtio-mmio@000000000a003e00/ethernet-phy@0
+ // ^ ^
+ // | fixed
+ // base address of virtio-mmio register block
+ //
+ // UEFI device path prefix (dependent on presence of nonzero PCI function):
+ //
+ // <VenHwString>/MAC(
+ //
+ Written = UnicodeSPrintAsciiFormat (
+ Translated,
+ *TranslatedSize * sizeof (*Translated), // BufferSize in bytes
+ "%s/MAC(",
+ VenHwString
+ );
+ } else {
+ return RETURN_UNSUPPORTED;
+ }
+
+ //
+ // There's no way to differentiate between "completely used up without
+ // truncation" and "truncated", so treat the former as the latter, and return
+ // success only for "some room left unused".
+ //
+ if (Written + 1 < *TranslatedSize) {
+ *TranslatedSize = Written;
+ return RETURN_SUCCESS;
+ }
+
+ return RETURN_BUFFER_TOO_SMALL;
+}
+
+
+/**
+
+ Translate an array of OpenFirmware device nodes to a UEFI device path
+ fragment.
+
+ @param[in] OfwNode Array of OpenFirmware device nodes to
+ translate, constituting the beginning of an
+ OpenFirmware device path.
+
+ @param[in] NumNodes Number of elements in OfwNode.
+
+ @param[out] Translated Destination array receiving the UEFI path
+ fragment, allocated by the caller. If the
+ return value differs from RETURN_SUCCESS, its
+ contents is indeterminate.
+
+ @param[in out] TranslatedSize On input, the number of CHAR16's in
+ Translated. On RETURN_SUCCESS this parameter
+ is assigned the number of non-NUL CHAR16's
+ written to Translated. In case of other return
+ values, TranslatedSize is indeterminate.
+
+
+ @retval RETURN_SUCCESS Translation successful.
+
+ @retval RETURN_BUFFER_TOO_SMALL The translation does not fit into the number
+ of bytes provided.
+
+ @retval RETURN_UNSUPPORTED The array of OpenFirmware device nodes can't
+ be translated in the current implementation.
+
+**/
+STATIC
+RETURN_STATUS
+TranslateOfwNodes (
+ IN CONST OFW_NODE *OfwNode,
+ IN UINTN NumNodes,
+ OUT CHAR16 *Translated,
+ IN OUT UINTN *TranslatedSize
+ )
+{
+ RETURN_STATUS Status;
+
+ Status = RETURN_UNSUPPORTED;
+
+ if (FeaturePcdGet (PcdQemuBootOrderPciTranslation)) {
+ Status = TranslatePciOfwNodes (OfwNode, NumNodes, Translated,
+ TranslatedSize);
+ }
+ if (Status == RETURN_UNSUPPORTED &&
+ FeaturePcdGet (PcdQemuBootOrderMmioTranslation)) {
+ Status = TranslateMmioOfwNodes (OfwNode, NumNodes, Translated,
+ TranslatedSize);
+ }
+ return Status;
+}
+
/**
Translate an OpenFirmware device path fragment to a UEFI device path
@@ -1016,7 +1253,7 @@ Exit:
This function should accommodate any further policy changes in "boot option
survival". Currently we're adding back everything that starts with neither
- PciRoot() nor HD().
+ PciRoot() nor HD() nor a virtio-mmio VenHw() node.
@param[in,out] BootOrder The structure holding the boot order to
complete. The caller is responsible for
@@ -1082,9 +1319,23 @@ BootOrderComplete (
if ((Acpi->HID & PNP_EISA_ID_MASK) == PNP_EISA_ID_CONST &&
EISA_ID_TO_NUM (Acpi->HID) == 0x0a03) {
//
- // drop PciRoot()
+ // drop PciRoot() if we enabled the user to select PCI-like boot
+ // options, by providing translation for such OFW device path
+ // fragments
+ //
+ Keep = !FeaturePcdGet (PcdQemuBootOrderPciTranslation);
+ }
+ } else if (DevicePathType(FirstNode) == HARDWARE_DEVICE_PATH &&
+ DevicePathSubType(FirstNode) == HW_VENDOR_DP) {
+ VENDOR_DEVICE_PATH *VenHw;
+
+ VenHw = (VENDOR_DEVICE_PATH *)FirstNode;
+ if (CompareGuid (&VenHw->Guid, &gVirtioMmioTransportGuid)) {
+ //
+ // drop virtio-mmio if we enabled the user to select boot options
+ // referencing such device paths
//
- Keep = FALSE;
+ Keep = !FeaturePcdGet (PcdQemuBootOrderMmioTranslation);
}
}
diff --git a/OvmfPkg/Library/QemuBootOrderLib/QemuBootOrderLib.inf b/OvmfPkg/Library/QemuBootOrderLib/QemuBootOrderLib.inf
new file mode 100644
index 0000000000..6289e6abe6
--- /dev/null
+++ b/OvmfPkg/Library/QemuBootOrderLib/QemuBootOrderLib.inf
@@ -0,0 +1,59 @@
+## @file
+# Rewrite the BootOrder NvVar based on QEMU's "bootorder" fw_cfg file.
+#
+# Copyright (C) 2012 - 2014, Red Hat, Inc.
+# Copyright (c) 2007 - 2010, Intel Corporation. All rights reserved.<BR>
+#
+# This program and the accompanying materials are licensed and made available
+# under the terms and conditions of the BSD License which accompanies this
+# distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR
+# IMPLIED.
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = QemuBootOrderLib
+ FILE_GUID = 4FFFA9E1-103D-4CF2-9C06-563BDD03050E
+ MODULE_TYPE = DXE_DRIVER
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = QemuBootOrderLib|DXE_DRIVER
+
+#
+# The following information is for reference only and not required by the build
+# tools.
+#
+# VALID_ARCHITECTURES = IA32 X64 IPF EBC ARM AARCH64
+#
+
+[Sources]
+ QemuBootOrderLib.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ IntelFrameworkModulePkg/IntelFrameworkModulePkg.dec
+ OvmfPkg/OvmfPkg.dec
+
+[LibraryClasses]
+ QemuFwCfgLib
+ DebugLib
+ MemoryAllocationLib
+ GenericBdsLib
+ UefiBootServicesTableLib
+ UefiRuntimeServicesTableLib
+ BaseLib
+ PrintLib
+ DevicePathLib
+ BaseMemoryLib
+
+[Guids]
+ gEfiGlobalVariableGuid
+ gVirtioMmioTransportGuid
+
+[FeaturePcd]
+ gUefiOvmfPkgTokenSpaceGuid.PcdQemuBootOrderPciTranslation
+ gUefiOvmfPkgTokenSpaceGuid.PcdQemuBootOrderMmioTranslation
diff --git a/OvmfPkg/OvmfPkg.dec b/OvmfPkg/OvmfPkg.dec
index 33dcb82de2..6eb551a8d4 100644
--- a/OvmfPkg/OvmfPkg.dec
+++ b/OvmfPkg/OvmfPkg.dec
@@ -35,6 +35,11 @@
#
QemuFwCfgLib|Include/Library/QemuFwCfgLib.h
+ ## @libraryclass Rewrite the BootOrder NvVar based on QEMU's "bootorder"
+ # fw_cfg file.
+ #
+ QemuBootOrderLib|Include/Library/QemuBootOrderLib.h
+
## @libraryclass Serialize (and deserialize) variables
#
SerializeVariablesLib|Include/Library/SerializeVariablesLib.h
@@ -43,6 +48,7 @@
gUefiOvmfPkgTokenSpaceGuid = {0x93bb96af, 0xb9f2, 0x4eb8, {0x94, 0x62, 0xe0, 0xba, 0x74, 0x56, 0x42, 0x36}}
gEfiXenInfoGuid = {0xd3b46f3b, 0xd441, 0x1244, {0x9a, 0x12, 0x0, 0x12, 0x27, 0x3f, 0xc1, 0x4d}}
gOvmfPlatformConfigGuid = {0x7235c51c, 0x0c80, 0x4cab, {0x87, 0xac, 0x3b, 0x08, 0x4a, 0x63, 0x04, 0xb1}}
+ gVirtioMmioTransportGuid = {0x837dca9e, 0xe874, 0x4d82, {0xb2, 0x9a, 0x23, 0xfe, 0x0e, 0x23, 0xd1, 0xe2}}
[Protocols]
gVirtioDeviceProtocolGuid = {0xfa920010, 0x6785, 0x4941, {0xb6, 0xec, 0x49, 0x8c, 0x57, 0x9f, 0x16, 0x0a}}
@@ -98,3 +104,5 @@
[PcdsFeatureFlag]
gUefiOvmfPkgTokenSpaceGuid.PcdSecureBootEnable|FALSE|BOOLEAN|3
+ gUefiOvmfPkgTokenSpaceGuid.PcdQemuBootOrderPciTranslation|TRUE|BOOLEAN|0x1c
+ gUefiOvmfPkgTokenSpaceGuid.PcdQemuBootOrderMmioTranslation|FALSE|BOOLEAN|0x1d
diff --git a/OvmfPkg/OvmfPkgIa32.dsc b/OvmfPkg/OvmfPkgIa32.dsc
index 659810248a..d7bf609b32 100644
--- a/OvmfPkg/OvmfPkgIa32.dsc
+++ b/OvmfPkg/OvmfPkgIa32.dsc
@@ -34,6 +34,7 @@
# -D FLAG=VALUE
#
DEFINE SECURE_BOOT_ENABLE = FALSE
+ DEFINE NETWORK_IP6_ENABLE = FALSE
[BuildOptions]
GCC:*_UNIXGCC_*_CC_FLAGS = -DMDEPKG_NDEBUG
@@ -119,6 +120,9 @@
IntrinsicLib|CryptoPkg/Library/IntrinsicLib/IntrinsicLib.inf
OpensslLib|CryptoPkg/Library/OpensslLib/OpensslLib.inf
TpmMeasurementLib|SecurityPkg/Library/DxeTpmMeasurementLib/DxeTpmMeasurementLib.inf
+!if $(NETWORK_IP6_ENABLE) == TRUE
+ TcpIoLib|MdeModulePkg/Library/DxeTcpIoLib/DxeTcpIoLib.inf
+!endif
!endif
S3BootScriptLib|MdeModulePkg/Library/PiDxeS3BootScriptLib/DxeS3BootScriptLib.inf
@@ -255,6 +259,7 @@
!ifdef $(SOURCE_DEBUG_ENABLE)
DebugAgentLib|SourceLevelDebugPkg/Library/DebugAgent/DxeDebugAgentLib.inf
!endif
+ QemuBootOrderLib|OvmfPkg/Library/QemuBootOrderLib/QemuBootOrderLib.inf
[LibraryClasses.common.UEFI_APPLICATION]
PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf
@@ -516,10 +521,24 @@
MdeModulePkg/Universal/Network/Ip4ConfigDxe/Ip4ConfigDxe.inf
MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Dxe.inf
MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Dxe.inf
- MdeModulePkg/Universal/Network/Tcp4Dxe/Tcp4Dxe.inf
MdeModulePkg/Universal/Network/Udp4Dxe/Udp4Dxe.inf
+!if $(NETWORK_IP6_ENABLE) == TRUE
+ NetworkPkg/Ip6Dxe/Ip6Dxe.inf
+ NetworkPkg/TcpDxe/TcpDxe.inf
+ NetworkPkg/Udp6Dxe/Udp6Dxe.inf
+ NetworkPkg/Dhcp6Dxe/Dhcp6Dxe.inf
+ NetworkPkg/Mtftp6Dxe/Mtftp6Dxe.inf
+ NetworkPkg/UefiPxeBcDxe/UefiPxeBcDxe.inf
+!if $(SECURE_BOOT_ENABLE) == TRUE
+ NetworkPkg/IScsiDxe/IScsiDxe.inf
+!else
+ MdeModulePkg/Universal/Network/IScsiDxe/IScsiDxe.inf
+!endif
+!else
+ MdeModulePkg/Universal/Network/Tcp4Dxe/Tcp4Dxe.inf
MdeModulePkg/Universal/Network/UefiPxeBcDxe/UefiPxeBcDxe.inf
MdeModulePkg/Universal/Network/IScsiDxe/IScsiDxe.inf
+!endif
OvmfPkg/VirtioNetDxe/VirtioNet.inf
#
diff --git a/OvmfPkg/OvmfPkgIa32.fdf b/OvmfPkg/OvmfPkgIa32.fdf
index 932aefa22e..f47e7ddc78 100644
--- a/OvmfPkg/OvmfPkgIa32.fdf
+++ b/OvmfPkg/OvmfPkgIa32.fdf
@@ -308,10 +308,24 @@ FILE FREEFORM = PCD(gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdLogoFile) {
INF MdeModulePkg/Universal/Network/Ip4ConfigDxe/Ip4ConfigDxe.inf
INF MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Dxe.inf
INF MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Dxe.inf
- INF MdeModulePkg/Universal/Network/Tcp4Dxe/Tcp4Dxe.inf
INF MdeModulePkg/Universal/Network/Udp4Dxe/Udp4Dxe.inf
+!if $(NETWORK_IP6_ENABLE) == TRUE
+ INF NetworkPkg/Ip6Dxe/Ip6Dxe.inf
+ INF NetworkPkg/TcpDxe/TcpDxe.inf
+ INF NetworkPkg/Udp6Dxe/Udp6Dxe.inf
+ INF NetworkPkg/Dhcp6Dxe/Dhcp6Dxe.inf
+ INF NetworkPkg/Mtftp6Dxe/Mtftp6Dxe.inf
+ INF NetworkPkg/UefiPxeBcDxe/UefiPxeBcDxe.inf
+!if $(SECURE_BOOT_ENABLE) == TRUE
+ INF NetworkPkg/IScsiDxe/IScsiDxe.inf
+!else
+ INF MdeModulePkg/Universal/Network/IScsiDxe/IScsiDxe.inf
+!endif
+!else
+ INF MdeModulePkg/Universal/Network/Tcp4Dxe/Tcp4Dxe.inf
INF MdeModulePkg/Universal/Network/UefiPxeBcDxe/UefiPxeBcDxe.inf
INF MdeModulePkg/Universal/Network/IScsiDxe/IScsiDxe.inf
+!endif
INF OvmfPkg/VirtioNetDxe/VirtioNet.inf
#
diff --git a/OvmfPkg/OvmfPkgIa32X64.dsc b/OvmfPkg/OvmfPkgIa32X64.dsc
index 4de961f1ca..4c921740e8 100644
--- a/OvmfPkg/OvmfPkgIa32X64.dsc
+++ b/OvmfPkg/OvmfPkgIa32X64.dsc
@@ -34,6 +34,7 @@
# -D FLAG=VALUE
#
DEFINE SECURE_BOOT_ENABLE = FALSE
+ DEFINE NETWORK_IP6_ENABLE = FALSE
[BuildOptions]
GCC:*_UNIXGCC_*_CC_FLAGS = -DMDEPKG_NDEBUG
@@ -124,6 +125,9 @@
IntrinsicLib|CryptoPkg/Library/IntrinsicLib/IntrinsicLib.inf
OpensslLib|CryptoPkg/Library/OpensslLib/OpensslLib.inf
TpmMeasurementLib|SecurityPkg/Library/DxeTpmMeasurementLib/DxeTpmMeasurementLib.inf
+!if $(NETWORK_IP6_ENABLE) == TRUE
+ TcpIoLib|MdeModulePkg/Library/DxeTcpIoLib/DxeTcpIoLib.inf
+!endif
!endif
S3BootScriptLib|MdeModulePkg/Library/PiDxeS3BootScriptLib/DxeS3BootScriptLib.inf
@@ -260,6 +264,7 @@
!ifdef $(SOURCE_DEBUG_ENABLE)
DebugAgentLib|SourceLevelDebugPkg/Library/DebugAgent/DxeDebugAgentLib.inf
!endif
+ QemuBootOrderLib|OvmfPkg/Library/QemuBootOrderLib/QemuBootOrderLib.inf
[LibraryClasses.common.UEFI_APPLICATION]
PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf
@@ -523,10 +528,24 @@
MdeModulePkg/Universal/Network/Ip4ConfigDxe/Ip4ConfigDxe.inf
MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Dxe.inf
MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Dxe.inf
- MdeModulePkg/Universal/Network/Tcp4Dxe/Tcp4Dxe.inf
MdeModulePkg/Universal/Network/Udp4Dxe/Udp4Dxe.inf
+!if $(NETWORK_IP6_ENABLE) == TRUE
+ NetworkPkg/Ip6Dxe/Ip6Dxe.inf
+ NetworkPkg/TcpDxe/TcpDxe.inf
+ NetworkPkg/Udp6Dxe/Udp6Dxe.inf
+ NetworkPkg/Dhcp6Dxe/Dhcp6Dxe.inf
+ NetworkPkg/Mtftp6Dxe/Mtftp6Dxe.inf
+ NetworkPkg/UefiPxeBcDxe/UefiPxeBcDxe.inf
+!if $(SECURE_BOOT_ENABLE) == TRUE
+ NetworkPkg/IScsiDxe/IScsiDxe.inf
+!else
+ MdeModulePkg/Universal/Network/IScsiDxe/IScsiDxe.inf
+!endif
+!else
+ MdeModulePkg/Universal/Network/Tcp4Dxe/Tcp4Dxe.inf
MdeModulePkg/Universal/Network/UefiPxeBcDxe/UefiPxeBcDxe.inf
MdeModulePkg/Universal/Network/IScsiDxe/IScsiDxe.inf
+!endif
OvmfPkg/VirtioNetDxe/VirtioNet.inf
#
diff --git a/OvmfPkg/OvmfPkgIa32X64.fdf b/OvmfPkg/OvmfPkgIa32X64.fdf
index 048d8bfc2d..4c034460d5 100644
--- a/OvmfPkg/OvmfPkgIa32X64.fdf
+++ b/OvmfPkg/OvmfPkgIa32X64.fdf
@@ -308,10 +308,24 @@ FILE FREEFORM = PCD(gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdLogoFile) {
INF MdeModulePkg/Universal/Network/Ip4ConfigDxe/Ip4ConfigDxe.inf
INF MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Dxe.inf
INF MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Dxe.inf
- INF MdeModulePkg/Universal/Network/Tcp4Dxe/Tcp4Dxe.inf
INF MdeModulePkg/Universal/Network/Udp4Dxe/Udp4Dxe.inf
+!if $(NETWORK_IP6_ENABLE) == TRUE
+ INF NetworkPkg/Ip6Dxe/Ip6Dxe.inf
+ INF NetworkPkg/TcpDxe/TcpDxe.inf
+ INF NetworkPkg/Udp6Dxe/Udp6Dxe.inf
+ INF NetworkPkg/Dhcp6Dxe/Dhcp6Dxe.inf
+ INF NetworkPkg/Mtftp6Dxe/Mtftp6Dxe.inf
+ INF NetworkPkg/UefiPxeBcDxe/UefiPxeBcDxe.inf
+!if $(SECURE_BOOT_ENABLE) == TRUE
+ INF NetworkPkg/IScsiDxe/IScsiDxe.inf
+!else
+ INF MdeModulePkg/Universal/Network/IScsiDxe/IScsiDxe.inf
+!endif
+!else
+ INF MdeModulePkg/Universal/Network/Tcp4Dxe/Tcp4Dxe.inf
INF MdeModulePkg/Universal/Network/UefiPxeBcDxe/UefiPxeBcDxe.inf
INF MdeModulePkg/Universal/Network/IScsiDxe/IScsiDxe.inf
+!endif
INF OvmfPkg/VirtioNetDxe/VirtioNet.inf
#
diff --git a/OvmfPkg/OvmfPkgX64.dsc b/OvmfPkg/OvmfPkgX64.dsc
index 6c38081de1..457774efcb 100644
--- a/OvmfPkg/OvmfPkgX64.dsc
+++ b/OvmfPkg/OvmfPkgX64.dsc
@@ -34,6 +34,7 @@
# -D FLAG=VALUE
#
DEFINE SECURE_BOOT_ENABLE = FALSE
+ DEFINE NETWORK_IP6_ENABLE = FALSE
[BuildOptions]
GCC:*_UNIXGCC_*_CC_FLAGS = -DMDEPKG_NDEBUG
@@ -124,6 +125,9 @@
IntrinsicLib|CryptoPkg/Library/IntrinsicLib/IntrinsicLib.inf
OpensslLib|CryptoPkg/Library/OpensslLib/OpensslLib.inf
TpmMeasurementLib|SecurityPkg/Library/DxeTpmMeasurementLib/DxeTpmMeasurementLib.inf
+!if $(NETWORK_IP6_ENABLE) == TRUE
+ TcpIoLib|MdeModulePkg/Library/DxeTcpIoLib/DxeTcpIoLib.inf
+!endif
!endif
S3BootScriptLib|MdeModulePkg/Library/PiDxeS3BootScriptLib/DxeS3BootScriptLib.inf
@@ -260,6 +264,7 @@
!ifdef $(SOURCE_DEBUG_ENABLE)
DebugAgentLib|SourceLevelDebugPkg/Library/DebugAgent/DxeDebugAgentLib.inf
!endif
+ QemuBootOrderLib|OvmfPkg/Library/QemuBootOrderLib/QemuBootOrderLib.inf
[LibraryClasses.common.UEFI_APPLICATION]
PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf
@@ -521,10 +526,24 @@
MdeModulePkg/Universal/Network/Ip4ConfigDxe/Ip4ConfigDxe.inf
MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Dxe.inf
MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Dxe.inf
- MdeModulePkg/Universal/Network/Tcp4Dxe/Tcp4Dxe.inf
MdeModulePkg/Universal/Network/Udp4Dxe/Udp4Dxe.inf
+!if $(NETWORK_IP6_ENABLE) == TRUE
+ NetworkPkg/Ip6Dxe/Ip6Dxe.inf
+ NetworkPkg/TcpDxe/TcpDxe.inf
+ NetworkPkg/Udp6Dxe/Udp6Dxe.inf
+ NetworkPkg/Dhcp6Dxe/Dhcp6Dxe.inf
+ NetworkPkg/Mtftp6Dxe/Mtftp6Dxe.inf
+ NetworkPkg/UefiPxeBcDxe/UefiPxeBcDxe.inf
+!if $(SECURE_BOOT_ENABLE) == TRUE
+ NetworkPkg/IScsiDxe/IScsiDxe.inf
+!else
+ MdeModulePkg/Universal/Network/IScsiDxe/IScsiDxe.inf
+!endif
+!else
+ MdeModulePkg/Universal/Network/Tcp4Dxe/Tcp4Dxe.inf
MdeModulePkg/Universal/Network/UefiPxeBcDxe/UefiPxeBcDxe.inf
MdeModulePkg/Universal/Network/IScsiDxe/IScsiDxe.inf
+!endif
OvmfPkg/VirtioNetDxe/VirtioNet.inf
#
diff --git a/OvmfPkg/OvmfPkgX64.fdf b/OvmfPkg/OvmfPkgX64.fdf
index bcf0b9d652..2323eb2edf 100644
--- a/OvmfPkg/OvmfPkgX64.fdf
+++ b/OvmfPkg/OvmfPkgX64.fdf
@@ -308,10 +308,24 @@ FILE FREEFORM = PCD(gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdLogoFile) {
INF MdeModulePkg/Universal/Network/Ip4ConfigDxe/Ip4ConfigDxe.inf
INF MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Dxe.inf
INF MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Dxe.inf
- INF MdeModulePkg/Universal/Network/Tcp4Dxe/Tcp4Dxe.inf
INF MdeModulePkg/Universal/Network/Udp4Dxe/Udp4Dxe.inf
+!if $(NETWORK_IP6_ENABLE) == TRUE
+ INF NetworkPkg/Ip6Dxe/Ip6Dxe.inf
+ INF NetworkPkg/TcpDxe/TcpDxe.inf
+ INF NetworkPkg/Udp6Dxe/Udp6Dxe.inf
+ INF NetworkPkg/Dhcp6Dxe/Dhcp6Dxe.inf
+ INF NetworkPkg/Mtftp6Dxe/Mtftp6Dxe.inf
+ INF NetworkPkg/UefiPxeBcDxe/UefiPxeBcDxe.inf
+!if $(SECURE_BOOT_ENABLE) == TRUE
+ INF NetworkPkg/IScsiDxe/IScsiDxe.inf
+!else
+ INF MdeModulePkg/Universal/Network/IScsiDxe/IScsiDxe.inf
+!endif
+!else
+ INF MdeModulePkg/Universal/Network/Tcp4Dxe/Tcp4Dxe.inf
INF MdeModulePkg/Universal/Network/UefiPxeBcDxe/UefiPxeBcDxe.inf
INF MdeModulePkg/Universal/Network/IScsiDxe/IScsiDxe.inf
+!endif
INF OvmfPkg/VirtioNetDxe/VirtioNet.inf
#
diff --git a/PandaBoardPkg/PandaBoardPkg.dsc b/PandaBoardPkg/PandaBoardPkg.dsc
index c227cb871d..ea41356115 100644
--- a/PandaBoardPkg/PandaBoardPkg.dsc
+++ b/PandaBoardPkg/PandaBoardPkg.dsc
@@ -132,6 +132,7 @@
DebugAgentLib|MdeModulePkg/Library/DebugAgentLibNull/DebugAgentLibNull.inf
DmaLib|ArmPkg/Library/ArmDmaLib/ArmDmaLib.inf
+ ArmBdsHelperLib|ArmPkg/Library/ArmBdsHelperLib/ArmBdsHelperLib.inf
BdsLib|ArmPkg/Library/BdsLib/BdsLib.inf
[LibraryClasses.common.SEC]
diff --git a/SecurityPkg/Include/Library/Tpm2CommandLib.h b/SecurityPkg/Include/Library/Tpm2CommandLib.h
index 5ec3ead05e..c4915496dd 100644
--- a/SecurityPkg/Include/Library/Tpm2CommandLib.h
+++ b/SecurityPkg/Include/Library/Tpm2CommandLib.h
@@ -1,7 +1,7 @@
/** @file
This library is used by other modules to send TPM2 command.
-Copyright (c) 2013, Intel Corporation. All rights reserved. <BR>
+Copyright (c) 2013 - 2014, Intel Corporation. All rights reserved. <BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
@@ -141,6 +141,27 @@ Tpm2SelfTest (
);
/**
+ This command allows setting of the authorization policy for the platform hierarchy (platformPolicy), the
+ storage hierarchy (ownerPolicy), and and the endorsement hierarchy (endorsementPolicy).
+
+ @param[in] AuthHandle TPM_RH_ENDORSEMENT, TPM_RH_OWNER or TPM_RH_PLATFORM+{PP} parameters to be validated
+ @param[in] AuthSession Auth Session context
+ @param[in] AuthPolicy An authorization policy hash
+ @param[in] HashAlg The hash algorithm to use for the policy
+
+ @retval EFI_SUCCESS Operation completed successfully.
+ @retval EFI_DEVICE_ERROR Unexpected device behavior.
+**/
+EFI_STATUS
+EFIAPI
+Tpm2SetPrimaryPolicy (
+ IN TPMI_RH_HIERARCHY_AUTH AuthHandle,
+ IN TPMS_AUTH_COMMAND *AuthSession,
+ IN TPM2B_DIGEST *AuthPolicy,
+ IN TPMI_ALG_HASH HashAlg
+ );
+
+/**
This command removes all TPM context associated with a specific Owner.
@param[in] AuthHandle TPM_RH_LOCKOUT or TPM_RH_PLATFORM+{PP}
@@ -774,6 +795,135 @@ Tpm2SetAlgorithmSet (
IN UINT32 AlgorithmSet
);
+/**
+ This command is used to start an authorization session using alternative methods of
+ establishing the session key (sessionKey) that is used for authorization and encrypting value.
+
+ @param[in] TpmKey Handle of a loaded decrypt key used to encrypt salt.
+ @param[in] Bind Entity providing the authValue.
+ @param[in] NonceCaller Initial nonceCaller, sets nonce size for the session.
+ @param[in] Salt Value encrypted according to the type of tpmKey.
+ @param[in] SessionType Indicates the type of the session.
+ @param[in] Symmetric The algorithm and key size for parameter encryption.
+ @param[in] AuthHash Hash algorithm to use for the session.
+ @param[out] SessionHandle Handle for the newly created session.
+ @param[out] NonceTPM The initial nonce from the TPM, used in the computation of the sessionKey.
+
+ @retval EFI_SUCCESS Operation completed successfully.
+ @retval EFI_DEVICE_ERROR The command was unsuccessful.
+**/
+EFI_STATUS
+EFIAPI
+Tpm2StartAuthSession (
+ IN TPMI_DH_OBJECT TpmKey,
+ IN TPMI_DH_ENTITY Bind,
+ IN TPM2B_NONCE *NonceCaller,
+ IN TPM2B_ENCRYPTED_SECRET *Salt,
+ IN TPM_SE SessionType,
+ IN TPMT_SYM_DEF *Symmetric,
+ IN TPMI_ALG_HASH AuthHash,
+ OUT TPMI_SH_AUTH_SESSION *SessionHandle,
+ OUT TPM2B_NONCE *NonceTPM
+ );
+
+/**
+ This command causes all context associated with a loaded object or session to be removed from TPM memory.
+
+ @param[in] FlushHandle The handle of the item to flush.
+
+ @retval EFI_SUCCESS Operation completed successfully.
+ @retval EFI_DEVICE_ERROR The command was unsuccessful.
+**/
+EFI_STATUS
+EFIAPI
+Tpm2FlushContext (
+ IN TPMI_DH_CONTEXT FlushHandle
+ );
+
+/**
+ This command includes a secret-based authorization to a policy.
+ The caller proves knowledge of the secret value using an authorization
+ session using the authValue associated with authHandle.
+
+ @param[in] AuthHandle Handle for an entity providing the authorization
+ @param[in] PolicySession Handle for the policy session being extended.
+ @param[in] AuthSession Auth Session context
+ @param[in] NonceTPM The policy nonce for the session.
+ @param[in] CpHashA Digest of the command parameters to which this authorization is limited.
+ @param[in] PolicyRef A reference to a policy relating to the authorization.
+ @param[in] Expiration Time when authorization will expire, measured in seconds from the time that nonceTPM was generated.
+ @param[out] Timeout Time value used to indicate to the TPM when the ticket expires.
+ @param[out] PolicyTicket A ticket that includes a value indicating when the authorization expires.
+
+ @retval EFI_SUCCESS Operation completed successfully.
+ @retval EFI_DEVICE_ERROR The command was unsuccessful.
+**/
+EFI_STATUS
+EFIAPI
+Tpm2PolicySecret (
+ IN TPMI_DH_ENTITY AuthHandle,
+ IN TPMI_SH_POLICY PolicySession,
+ IN TPMS_AUTH_COMMAND *AuthSession, OPTIONAL
+ IN TPM2B_NONCE *NonceTPM,
+ IN TPM2B_DIGEST *CpHashA,
+ IN TPM2B_NONCE *PolicyRef,
+ IN INT32 Expiration,
+ OUT TPM2B_TIMEOUT *Timeout,
+ OUT TPMT_TK_AUTH *PolicyTicket
+ );
+
+/**
+ This command allows options in authorizations without requiring that the TPM evaluate all of the options.
+ If a policy may be satisfied by different sets of conditions, the TPM need only evaluate one set that
+ satisfies the policy. This command will indicate that one of the required sets of conditions has been
+ satisfied.
+
+ @param[in] PolicySession Handle for the policy session being extended.
+ @param[in] HashList the list of hashes to check for a match.
+
+ @retval EFI_SUCCESS Operation completed successfully.
+ @retval EFI_DEVICE_ERROR The command was unsuccessful.
+**/
+EFI_STATUS
+EFIAPI
+Tpm2PolicyOR (
+ IN TPMI_SH_POLICY PolicySession,
+ IN TPML_DIGEST *HashList
+ );
+
+/**
+ This command indicates that the authorization will be limited to a specific command code.
+
+ @param[in] PolicySession Handle for the policy session being extended.
+ @param[in] Code The allowed commandCode.
+
+ @retval EFI_SUCCESS Operation completed successfully.
+ @retval EFI_DEVICE_ERROR The command was unsuccessful.
+**/
+EFI_STATUS
+EFIAPI
+Tpm2PolicyCommandCode (
+ IN TPMI_SH_POLICY PolicySession,
+ IN TPM_CC Code
+ );
+
+/**
+ This command returns the current policyDigest of the session. This command allows the TPM
+ to be used to perform the actions required to precompute the authPolicy for an object.
+
+ @param[in] PolicySession Handle for the policy session.
+ @param[out] PolicyHash the current value of the policyHash of policySession.
+
+ @retval EFI_SUCCESS Operation completed successfully.
+ @retval EFI_DEVICE_ERROR The command was unsuccessful.
+**/
+EFI_STATUS
+EFIAPI
+Tpm2PolicyGetDigest (
+ IN TPMI_SH_POLICY PolicySession,
+ OUT TPM2B_DIGEST *PolicyHash
+ );
+
//
// Help function
//
diff --git a/SecurityPkg/Library/DxeImageVerificationLib/DxeImageVerificationLib.c b/SecurityPkg/Library/DxeImageVerificationLib/DxeImageVerificationLib.c
index c3793b9429..959a9b062d 100644
--- a/SecurityPkg/Library/DxeImageVerificationLib/DxeImageVerificationLib.c
+++ b/SecurityPkg/Library/DxeImageVerificationLib/DxeImageVerificationLib.c
@@ -769,7 +769,7 @@ AddImageExeInfo (
}
DevicePathSize = GetDevicePathSize (DevicePath);
- NewImageExeInfoEntrySize = sizeof (EFI_IMAGE_EXECUTION_INFO) + NameStringLen + DevicePathSize + SignatureSize;
+ NewImageExeInfoEntrySize = sizeof (EFI_IMAGE_EXECUTION_INFO) - sizeof (EFI_SIGNATURE_LIST) + NameStringLen + DevicePathSize + SignatureSize;
NewImageExeInfoTable = (EFI_IMAGE_EXECUTION_INFO_TABLE *) AllocateRuntimePool (ImageExeInfoTableSize + NewImageExeInfoEntrySize);
if (NewImageExeInfoTable == NULL) {
return ;
@@ -841,7 +841,7 @@ IsCertHashFoundInDatabase (
)
{
BOOLEAN IsFound;
- EFI_STATUS Status;
+ BOOLEAN Status;
EFI_SIGNATURE_LIST *DbxList;
UINTN DbxSize;
EFI_SIGNATURE_DATA *CertHash;
@@ -852,6 +852,8 @@ IsCertHashFoundInDatabase (
UINT8 CertDigest[MAX_DIGEST_SIZE];
UINT8 *DbxCertHash;
UINTN SiglistHeaderSize;
+ UINT8 *TBSCert;
+ UINTN TBSCertSize;
IsFound = FALSE;
DbxList = SignatureList;
@@ -859,7 +861,16 @@ IsCertHashFoundInDatabase (
HashCtx = NULL;
HashAlg = HASHALG_MAX;
- ASSERT (RevocationTime != NULL);
+ if ((RevocationTime == NULL) || (DbxList == NULL)) {
+ return FALSE;
+ }
+
+ //
+ // Retrieve the TBSCertificate from the X.509 Certificate.
+ //
+ if (!X509GetTBSCert (Certificate, CertSize, &TBSCert, &TBSCertSize)) {
+ return FALSE;
+ }
while ((DbxSize > 0) && (SignatureListSize >= DbxList->SignatureListSize)) {
//
@@ -878,7 +889,7 @@ IsCertHashFoundInDatabase (
}
//
- // Calculate the hash value of current db certificate for comparision.
+ // Calculate the hash value of current TBSCertificate for comparision.
//
if (mHash[HashAlg].GetContextSize == NULL) {
goto Done;
@@ -892,7 +903,7 @@ IsCertHashFoundInDatabase (
if (!Status) {
goto Done;
}
- Status = mHash[HashAlg].HashUpdate (HashCtx, Certificate, CertSize);
+ Status = mHash[HashAlg].HashUpdate (HashCtx, TBSCert, TBSCertSize);
if (!Status) {
goto Done;
}
@@ -1132,15 +1143,16 @@ PassTimestampCheck (
//
DbtDataSize = 0;
Status = gRT->GetVariable (EFI_IMAGE_SECURITY_DATABASE2, &gEfiImageSecurityDatabaseGuid, NULL, &DbtDataSize, NULL);
- if (Status == EFI_BUFFER_TOO_SMALL) {
- DbtData = (UINT8 *) AllocateZeroPool (DbtDataSize);
- if (DbtData == NULL) {
- goto Done;
- }
- Status = gRT->GetVariable (EFI_IMAGE_SECURITY_DATABASE2, &gEfiImageSecurityDatabaseGuid, NULL, &DbtDataSize, (VOID *) DbtData);
- if (EFI_ERROR (Status)) {
- goto Done;
- }
+ if (Status != EFI_BUFFER_TOO_SMALL) {
+ goto Done;
+ }
+ DbtData = (UINT8 *) AllocateZeroPool (DbtDataSize);
+ if (DbtData == NULL) {
+ goto Done;
+ }
+ Status = gRT->GetVariable (EFI_IMAGE_SECURITY_DATABASE2, &gEfiImageSecurityDatabaseGuid, NULL, &DbtDataSize, (VOID *) DbtData);
+ if (EFI_ERROR (Status)) {
+ goto Done;
}
CertList = (EFI_SIGNATURE_LIST *) DbtData;
@@ -1229,14 +1241,15 @@ IsForbiddenByDbx (
//
DataSize = 0;
Status = gRT->GetVariable (EFI_IMAGE_SECURITY_DATABASE1, &gEfiImageSecurityDatabaseGuid, NULL, &DataSize, NULL);
- if (Status == EFI_BUFFER_TOO_SMALL) {
- Data = (UINT8 *) AllocateZeroPool (DataSize);
- if (Data == NULL) {
- return IsForbidden;
- }
-
- Status = gRT->GetVariable (EFI_IMAGE_SECURITY_DATABASE1, &gEfiImageSecurityDatabaseGuid, NULL, &DataSize, (VOID *) Data);
+ if (Status != EFI_BUFFER_TOO_SMALL) {
+ return IsForbidden;
+ }
+ Data = (UINT8 *) AllocateZeroPool (DataSize);
+ if (Data == NULL) {
+ return IsForbidden;
}
+
+ Status = gRT->GetVariable (EFI_IMAGE_SECURITY_DATABASE1, &gEfiImageSecurityDatabaseGuid, NULL, &DataSize, (VOID *) Data);
if (EFI_ERROR (Status)) {
return IsForbidden;
}
@@ -1254,7 +1267,7 @@ IsForbiddenByDbx (
// UINT8 Certn[];
//
Pkcs7GetSigners (AuthData, AuthDataSize, &CertBuffer, &BufferLength, &TrustedCert, &TrustedCertLength);
- if (BufferLength == 0) {
+ if ((BufferLength == 0) || (CertBuffer == NULL)) {
IsForbidden = TRUE;
goto Done;
}
@@ -1472,6 +1485,7 @@ DxeImageVerificationHandler (
UINTN AuthDataSize;
EFI_IMAGE_DATA_DIRECTORY *SecDataDir;
UINT32 OffSet;
+ CHAR16 *NameStr;
SignatureList = NULL;
SignatureListSize = 0;
@@ -1775,7 +1789,12 @@ Done:
//
// Policy decides to defer or reject the image; add its information in image executable information table.
//
- AddImageExeInfo (Action, NULL, File, SignatureList, SignatureListSize);
+ NameStr = ConvertDevicePathToText (File, FALSE, TRUE);
+ AddImageExeInfo (Action, NameStr, File, SignatureList, SignatureListSize);
+ if (NameStr != NULL) {
+ DEBUG((EFI_D_INFO, "The image doesn't pass verification: %s\n", NameStr));
+ FreePool(NameStr);
+ }
Status = EFI_SECURITY_VIOLATION;
}
diff --git a/SecurityPkg/Library/Tpm2CommandLib/Tpm2CommandLib.inf b/SecurityPkg/Library/Tpm2CommandLib/Tpm2CommandLib.inf
index bc95ce7fa6..740af3f72b 100644
--- a/SecurityPkg/Library/Tpm2CommandLib/Tpm2CommandLib.inf
+++ b/SecurityPkg/Library/Tpm2CommandLib/Tpm2CommandLib.inf
@@ -35,6 +35,9 @@
Tpm2Hierarchy.c
Tpm2NVStorage.c
Tpm2Startup.c
+ Tpm2Session.c
+ Tpm2Context.c
+ Tpm2EnhancedAuthorization.c
Tpm2Test.c
Tpm2DictionaryAttack.c
Tpm2Miscellaneous.c
diff --git a/SecurityPkg/Library/Tpm2CommandLib/Tpm2Context.c b/SecurityPkg/Library/Tpm2CommandLib/Tpm2Context.c
new file mode 100644
index 0000000000..02a250127a
--- /dev/null
+++ b/SecurityPkg/Library/Tpm2CommandLib/Tpm2Context.c
@@ -0,0 +1,86 @@
+/** @file
+ Implement TPM2 Context related command.
+
+Copyright (c) 2014, Intel Corporation. All rights reserved. <BR>
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include <IndustryStandard/UefiTcgPlatform.h>
+#include <Library/Tpm2CommandLib.h>
+#include <Library/Tpm2DeviceLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+
+#pragma pack(1)
+
+typedef struct {
+ TPM2_COMMAND_HEADER Header;
+ TPMI_DH_CONTEXT FlushHandle;
+} TPM2_FLUSH_CONTEXT_COMMAND;
+
+typedef struct {
+ TPM2_RESPONSE_HEADER Header;
+} TPM2_FLUSH_CONTEXT_RESPONSE;
+
+#pragma pack()
+
+/**
+ This command causes all context associated with a loaded object or session to be removed from TPM memory.
+
+ @param[in] FlushHandle The handle of the item to flush.
+
+ @retval EFI_SUCCESS Operation completed successfully.
+ @retval EFI_DEVICE_ERROR The command was unsuccessful.
+**/
+EFI_STATUS
+EFIAPI
+Tpm2FlushContext (
+ IN TPMI_DH_CONTEXT FlushHandle
+ )
+{
+ EFI_STATUS Status;
+ TPM2_FLUSH_CONTEXT_COMMAND SendBuffer;
+ TPM2_FLUSH_CONTEXT_RESPONSE RecvBuffer;
+ UINT32 SendBufferSize;
+ UINT32 RecvBufferSize;
+
+ //
+ // Construct command
+ //
+ SendBuffer.Header.tag = SwapBytes16(TPM_ST_NO_SESSIONS);
+ SendBuffer.Header.commandCode = SwapBytes32(TPM_CC_FlushContext);
+
+ SendBuffer.FlushHandle = SwapBytes32 (FlushHandle);
+
+ SendBufferSize = (UINT32) sizeof (SendBuffer);
+ SendBuffer.Header.paramSize = SwapBytes32 (SendBufferSize);
+
+ //
+ // send Tpm command
+ //
+ RecvBufferSize = sizeof (RecvBuffer);
+ Status = Tpm2SubmitCommand (SendBufferSize, (UINT8 *)&SendBuffer, &RecvBufferSize, (UINT8 *)&RecvBuffer);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ if (RecvBufferSize < sizeof (TPM2_RESPONSE_HEADER)) {
+ DEBUG ((EFI_D_ERROR, "Tpm2FlushContext - RecvBufferSize Error - %x\n", RecvBufferSize));
+ return EFI_DEVICE_ERROR;
+ }
+ if (SwapBytes32(RecvBuffer.Header.responseCode) != TPM_RC_SUCCESS) {
+ DEBUG ((EFI_D_ERROR, "Tpm2FlushContext - responseCode - %x\n", SwapBytes32(RecvBuffer.Header.responseCode)));
+ return EFI_DEVICE_ERROR;
+ }
+
+ return EFI_SUCCESS;
+}
+
diff --git a/SecurityPkg/Library/Tpm2CommandLib/Tpm2EnhancedAuthorization.c b/SecurityPkg/Library/Tpm2CommandLib/Tpm2EnhancedAuthorization.c
new file mode 100644
index 0000000000..d11f543463
--- /dev/null
+++ b/SecurityPkg/Library/Tpm2CommandLib/Tpm2EnhancedAuthorization.c
@@ -0,0 +1,377 @@
+/** @file
+ Implement TPM2 EnhancedAuthorization related command.
+
+Copyright (c) 2014, Intel Corporation. All rights reserved. <BR>
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include <IndustryStandard/UefiTcgPlatform.h>
+#include <Library/Tpm2CommandLib.h>
+#include <Library/Tpm2DeviceLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+
+#pragma pack(1)
+
+typedef struct {
+ TPM2_COMMAND_HEADER Header;
+ TPMI_DH_ENTITY AuthHandle;
+ TPMI_SH_POLICY PolicySession;
+ UINT32 AuthSessionSize;
+ TPMS_AUTH_COMMAND AuthSession;
+ TPM2B_NONCE NonceTPM;
+ TPM2B_DIGEST CpHashA;
+ TPM2B_NONCE PolicyRef;
+ INT32 Expiration;
+} TPM2_POLICY_SECRET_COMMAND;
+
+typedef struct {
+ TPM2_RESPONSE_HEADER Header;
+ UINT32 AuthSessionSize;
+ TPM2B_TIMEOUT Timeout;
+ TPMT_TK_AUTH PolicyTicket;
+ TPMS_AUTH_RESPONSE AuthSession;
+} TPM2_POLICY_SECRET_RESPONSE;
+
+typedef struct {
+ TPM2_COMMAND_HEADER Header;
+ TPMI_SH_POLICY PolicySession;
+ TPML_DIGEST HashList;
+} TPM2_POLICY_OR_COMMAND;
+
+typedef struct {
+ TPM2_RESPONSE_HEADER Header;
+} TPM2_POLICY_OR_RESPONSE;
+
+typedef struct {
+ TPM2_COMMAND_HEADER Header;
+ TPMI_SH_POLICY PolicySession;
+ TPM_CC Code;
+} TPM2_POLICY_COMMAND_CODE_COMMAND;
+
+typedef struct {
+ TPM2_RESPONSE_HEADER Header;
+} TPM2_POLICY_COMMAND_CODE_RESPONSE;
+
+typedef struct {
+ TPM2_COMMAND_HEADER Header;
+ TPMI_SH_POLICY PolicySession;
+} TPM2_POLICY_GET_DIGEST_COMMAND;
+
+typedef struct {
+ TPM2_RESPONSE_HEADER Header;
+ TPM2B_DIGEST PolicyHash;
+} TPM2_POLICY_GET_DIGEST_RESPONSE;
+
+#pragma pack()
+
+/**
+ This command includes a secret-based authorization to a policy.
+ The caller proves knowledge of the secret value using an authorization
+ session using the authValue associated with authHandle.
+
+ @param[in] AuthHandle Handle for an entity providing the authorization
+ @param[in] PolicySession Handle for the policy session being extended.
+ @param[in] AuthSession Auth Session context
+ @param[in] NonceTPM The policy nonce for the session.
+ @param[in] CpHashA Digest of the command parameters to which this authorization is limited.
+ @param[in] PolicyRef A reference to a policy relating to the authorization.
+ @param[in] Expiration Time when authorization will expire, measured in seconds from the time that nonceTPM was generated.
+ @param[out] Timeout Time value used to indicate to the TPM when the ticket expires.
+ @param[out] PolicyTicket A ticket that includes a value indicating when the authorization expires.
+
+ @retval EFI_SUCCESS Operation completed successfully.
+ @retval EFI_DEVICE_ERROR The command was unsuccessful.
+**/
+EFI_STATUS
+EFIAPI
+Tpm2PolicySecret (
+ IN TPMI_DH_ENTITY AuthHandle,
+ IN TPMI_SH_POLICY PolicySession,
+ IN TPMS_AUTH_COMMAND *AuthSession, OPTIONAL
+ IN TPM2B_NONCE *NonceTPM,
+ IN TPM2B_DIGEST *CpHashA,
+ IN TPM2B_NONCE *PolicyRef,
+ IN INT32 Expiration,
+ OUT TPM2B_TIMEOUT *Timeout,
+ OUT TPMT_TK_AUTH *PolicyTicket
+ )
+{
+ EFI_STATUS Status;
+ TPM2_POLICY_SECRET_COMMAND SendBuffer;
+ TPM2_POLICY_SECRET_RESPONSE RecvBuffer;
+ UINT32 SendBufferSize;
+ UINT32 RecvBufferSize;
+ UINT8 *Buffer;
+ UINT32 SessionInfoSize;
+
+ //
+ // Construct command
+ //
+ SendBuffer.Header.tag = SwapBytes16(TPM_ST_SESSIONS);
+ SendBuffer.Header.commandCode = SwapBytes32(TPM_CC_PolicySecret);
+ SendBuffer.AuthHandle = SwapBytes32 (AuthHandle);
+ SendBuffer.PolicySession = SwapBytes32 (PolicySession);
+
+ //
+ // Add in Auth session
+ //
+ Buffer = (UINT8 *)&SendBuffer.AuthSession;
+
+ // sessionInfoSize
+ SessionInfoSize = CopyAuthSessionCommand (AuthSession, Buffer);
+ Buffer += SessionInfoSize;
+ SendBuffer.AuthSessionSize = SwapBytes32(SessionInfoSize);
+
+ //
+ // Real data
+ //
+ WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16(NonceTPM->size));
+ Buffer += sizeof(UINT16);
+ CopyMem (Buffer, NonceTPM->buffer, NonceTPM->size);
+ Buffer += NonceTPM->size;
+
+ WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16(CpHashA->size));
+ Buffer += sizeof(UINT16);
+ CopyMem (Buffer, CpHashA->buffer, CpHashA->size);
+ Buffer += CpHashA->size;
+
+ WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16(PolicyRef->size));
+ Buffer += sizeof(UINT16);
+ CopyMem (Buffer, PolicyRef->buffer, PolicyRef->size);
+ Buffer += PolicyRef->size;
+
+ WriteUnaligned32 ((UINT32 *)Buffer, SwapBytes32((UINT32)Expiration));
+ Buffer += sizeof(UINT32);
+
+ SendBufferSize = (UINT32)((UINTN)Buffer - (UINTN)&SendBuffer);
+ SendBuffer.Header.paramSize = SwapBytes32 (SendBufferSize);
+
+ //
+ // send Tpm command
+ //
+ RecvBufferSize = sizeof (RecvBuffer);
+ Status = Tpm2SubmitCommand (SendBufferSize, (UINT8 *)&SendBuffer, &RecvBufferSize, (UINT8 *)&RecvBuffer);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ if (RecvBufferSize < sizeof (TPM2_RESPONSE_HEADER)) {
+ DEBUG ((EFI_D_ERROR, "Tpm2PolicySecret - RecvBufferSize Error - %x\n", RecvBufferSize));
+ return EFI_DEVICE_ERROR;
+ }
+ if (SwapBytes32(RecvBuffer.Header.responseCode) != TPM_RC_SUCCESS) {
+ DEBUG ((EFI_D_ERROR, "Tpm2PolicySecret - responseCode - %x\n", SwapBytes32(RecvBuffer.Header.responseCode)));
+ return EFI_DEVICE_ERROR;
+ }
+
+ //
+ // Return the response
+ //
+ Buffer = (UINT8 *)&RecvBuffer.Timeout;
+ Timeout->size = SwapBytes16(ReadUnaligned16 ((UINT16 *)Buffer));
+ Buffer += sizeof(UINT16);
+ CopyMem (Timeout->buffer, Buffer, Timeout->size);
+
+ PolicyTicket->tag = SwapBytes16(ReadUnaligned16 ((UINT16 *)Buffer));
+ Buffer += sizeof(UINT16);
+ PolicyTicket->hierarchy = SwapBytes32(ReadUnaligned32 ((UINT32 *)Buffer));
+ Buffer += sizeof(UINT32);
+ PolicyTicket->digest.size = SwapBytes16(ReadUnaligned16 ((UINT16 *)Buffer));
+ Buffer += sizeof(UINT16);
+ CopyMem (PolicyTicket->digest.buffer, Buffer, PolicyTicket->digest.size);
+
+ return EFI_SUCCESS;
+}
+
+/**
+ This command allows options in authorizations without requiring that the TPM evaluate all of the options.
+ If a policy may be satisfied by different sets of conditions, the TPM need only evaluate one set that
+ satisfies the policy. This command will indicate that one of the required sets of conditions has been
+ satisfied.
+
+ @param[in] PolicySession Handle for the policy session being extended.
+ @param[in] HashList the list of hashes to check for a match.
+
+ @retval EFI_SUCCESS Operation completed successfully.
+ @retval EFI_DEVICE_ERROR The command was unsuccessful.
+**/
+EFI_STATUS
+EFIAPI
+Tpm2PolicyOR (
+ IN TPMI_SH_POLICY PolicySession,
+ IN TPML_DIGEST *HashList
+ )
+{
+ EFI_STATUS Status;
+ TPM2_POLICY_OR_COMMAND SendBuffer;
+ TPM2_POLICY_OR_RESPONSE RecvBuffer;
+ UINT32 SendBufferSize;
+ UINT32 RecvBufferSize;
+ UINT8 *Buffer;
+ UINTN Index;
+
+ //
+ // Construct command
+ //
+ SendBuffer.Header.tag = SwapBytes16(TPM_ST_NO_SESSIONS);
+ SendBuffer.Header.commandCode = SwapBytes32(TPM_CC_PolicyOR);
+
+ SendBuffer.PolicySession = SwapBytes32 (PolicySession);
+ Buffer = (UINT8 *)&SendBuffer.HashList;
+ WriteUnaligned32 ((UINT32 *)Buffer, SwapBytes32 (HashList->count));
+ Buffer += sizeof(UINT32);
+ for (Index = 0; Index < HashList->count; Index++) {
+ WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (HashList->digests[Index].size));
+ Buffer += sizeof(UINT16);
+ CopyMem (Buffer, HashList->digests[Index].buffer, HashList->digests[Index].size);
+ Buffer += HashList->digests[Index].size;
+ }
+
+ SendBufferSize = (UINT32)((UINTN)Buffer - (UINTN)&SendBuffer);
+ SendBuffer.Header.paramSize = SwapBytes32 (SendBufferSize);
+
+ //
+ // send Tpm command
+ //
+ RecvBufferSize = sizeof (RecvBuffer);
+ Status = Tpm2SubmitCommand (SendBufferSize, (UINT8 *)&SendBuffer, &RecvBufferSize, (UINT8 *)&RecvBuffer);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ if (RecvBufferSize < sizeof (TPM2_RESPONSE_HEADER)) {
+ DEBUG ((EFI_D_ERROR, "Tpm2PolicyOR - RecvBufferSize Error - %x\n", RecvBufferSize));
+ return EFI_DEVICE_ERROR;
+ }
+ if (SwapBytes32(RecvBuffer.Header.responseCode) != TPM_RC_SUCCESS) {
+ DEBUG ((EFI_D_ERROR, "Tpm2PolicyOR - responseCode - %x\n", SwapBytes32(RecvBuffer.Header.responseCode)));
+ return EFI_DEVICE_ERROR;
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ This command indicates that the authorization will be limited to a specific command code.
+
+ @param[in] PolicySession Handle for the policy session being extended.
+ @param[in] Code The allowed commandCode.
+
+ @retval EFI_SUCCESS Operation completed successfully.
+ @retval EFI_DEVICE_ERROR The command was unsuccessful.
+**/
+EFI_STATUS
+EFIAPI
+Tpm2PolicyCommandCode (
+ IN TPMI_SH_POLICY PolicySession,
+ IN TPM_CC Code
+ )
+{
+ EFI_STATUS Status;
+ TPM2_POLICY_COMMAND_CODE_COMMAND SendBuffer;
+ TPM2_POLICY_COMMAND_CODE_RESPONSE RecvBuffer;
+ UINT32 SendBufferSize;
+ UINT32 RecvBufferSize;
+
+ //
+ // Construct command
+ //
+ SendBuffer.Header.tag = SwapBytes16(TPM_ST_NO_SESSIONS);
+ SendBuffer.Header.commandCode = SwapBytes32(TPM_CC_PolicyCommandCode);
+
+ SendBuffer.PolicySession = SwapBytes32 (PolicySession);
+ SendBuffer.Code = SwapBytes32 (Code);
+
+ SendBufferSize = (UINT32) sizeof (SendBuffer);
+ SendBuffer.Header.paramSize = SwapBytes32 (SendBufferSize);
+
+ //
+ // send Tpm command
+ //
+ RecvBufferSize = sizeof (RecvBuffer);
+ Status = Tpm2SubmitCommand (SendBufferSize, (UINT8 *)&SendBuffer, &RecvBufferSize, (UINT8 *)&RecvBuffer);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ if (RecvBufferSize < sizeof (TPM2_RESPONSE_HEADER)) {
+ DEBUG ((EFI_D_ERROR, "Tpm2PolicyCommandCode - RecvBufferSize Error - %x\n", RecvBufferSize));
+ return EFI_DEVICE_ERROR;
+ }
+ if (SwapBytes32(RecvBuffer.Header.responseCode) != TPM_RC_SUCCESS) {
+ DEBUG ((EFI_D_ERROR, "Tpm2PolicyCommandCode - responseCode - %x\n", SwapBytes32(RecvBuffer.Header.responseCode)));
+ return EFI_DEVICE_ERROR;
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ This command returns the current policyDigest of the session. This command allows the TPM
+ to be used to perform the actions required to precompute the authPolicy for an object.
+
+ @param[in] PolicySession Handle for the policy session.
+ @param[out] PolicyHash the current value of the policyHash of policySession.
+
+ @retval EFI_SUCCESS Operation completed successfully.
+ @retval EFI_DEVICE_ERROR The command was unsuccessful.
+**/
+EFI_STATUS
+EFIAPI
+Tpm2PolicyGetDigest (
+ IN TPMI_SH_POLICY PolicySession,
+ OUT TPM2B_DIGEST *PolicyHash
+ )
+{
+ EFI_STATUS Status;
+ TPM2_POLICY_GET_DIGEST_COMMAND SendBuffer;
+ TPM2_POLICY_GET_DIGEST_RESPONSE RecvBuffer;
+ UINT32 SendBufferSize;
+ UINT32 RecvBufferSize;
+
+ //
+ // Construct command
+ //
+ SendBuffer.Header.tag = SwapBytes16(TPM_ST_NO_SESSIONS);
+ SendBuffer.Header.commandCode = SwapBytes32(TPM_CC_PolicyGetDigest);
+
+ SendBuffer.PolicySession = SwapBytes32 (PolicySession);
+
+ SendBufferSize = (UINT32) sizeof (SendBuffer);
+ SendBuffer.Header.paramSize = SwapBytes32 (SendBufferSize);
+
+ //
+ // send Tpm command
+ //
+ RecvBufferSize = sizeof (RecvBuffer);
+ Status = Tpm2SubmitCommand (SendBufferSize, (UINT8 *)&SendBuffer, &RecvBufferSize, (UINT8 *)&RecvBuffer);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ if (RecvBufferSize < sizeof (TPM2_RESPONSE_HEADER)) {
+ DEBUG ((EFI_D_ERROR, "Tpm2PolicyGetDigest - RecvBufferSize Error - %x\n", RecvBufferSize));
+ return EFI_DEVICE_ERROR;
+ }
+ if (SwapBytes32(RecvBuffer.Header.responseCode) != TPM_RC_SUCCESS) {
+ DEBUG ((EFI_D_ERROR, "Tpm2PolicyGetDigest - responseCode - %x\n", SwapBytes32(RecvBuffer.Header.responseCode)));
+ return EFI_DEVICE_ERROR;
+ }
+
+ //
+ // Return the response
+ //
+ PolicyHash->size = SwapBytes16 (RecvBuffer.PolicyHash.size);
+ CopyMem (PolicyHash->buffer, &RecvBuffer.PolicyHash.buffer, PolicyHash->size);
+
+ return EFI_SUCCESS;
+}
diff --git a/SecurityPkg/Library/Tpm2CommandLib/Tpm2Hierarchy.c b/SecurityPkg/Library/Tpm2CommandLib/Tpm2Hierarchy.c
index 9eb4c9c384..11f1229434 100644
--- a/SecurityPkg/Library/Tpm2CommandLib/Tpm2Hierarchy.c
+++ b/SecurityPkg/Library/Tpm2CommandLib/Tpm2Hierarchy.c
@@ -23,6 +23,21 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
typedef struct {
TPM2_COMMAND_HEADER Header;
+ TPMI_RH_HIERARCHY_AUTH AuthHandle;
+ UINT32 AuthSessionSize;
+ TPMS_AUTH_COMMAND AuthSession;
+ TPM2B_DIGEST AuthPolicy;
+ TPMI_ALG_HASH HashAlg;
+} TPM2_SET_PRIMARY_POLICY_COMMAND;
+
+typedef struct {
+ TPM2_RESPONSE_HEADER Header;
+ UINT32 AuthSessionSize;
+ TPMS_AUTH_RESPONSE AuthSession;
+} TPM2_SET_PRIMARY_POLICY_RESPONSE;
+
+typedef struct {
+ TPM2_COMMAND_HEADER Header;
TPMI_RH_CLEAR AuthHandle;
UINT32 AuthorizationSize;
TPMS_AUTH_COMMAND AuthSession;
@@ -106,6 +121,87 @@ typedef struct {
#pragma pack()
/**
+ This command allows setting of the authorization policy for the platform hierarchy (platformPolicy), the
+ storage hierarchy (ownerPolicy), and and the endorsement hierarchy (endorsementPolicy).
+
+ @param[in] AuthHandle TPM_RH_ENDORSEMENT, TPM_RH_OWNER or TPM_RH_PLATFORM+{PP} parameters to be validated
+ @param[in] AuthSession Auth Session context
+ @param[in] AuthPolicy An authorization policy hash
+ @param[in] HashAlg The hash algorithm to use for the policy
+
+ @retval EFI_SUCCESS Operation completed successfully.
+ @retval EFI_DEVICE_ERROR Unexpected device behavior.
+**/
+EFI_STATUS
+EFIAPI
+Tpm2SetPrimaryPolicy (
+ IN TPMI_RH_HIERARCHY_AUTH AuthHandle,
+ IN TPMS_AUTH_COMMAND *AuthSession,
+ IN TPM2B_DIGEST *AuthPolicy,
+ IN TPMI_ALG_HASH HashAlg
+ )
+{
+ EFI_STATUS Status;
+ TPM2_SET_PRIMARY_POLICY_COMMAND SendBuffer;
+ TPM2_SET_PRIMARY_POLICY_RESPONSE RecvBuffer;
+ UINT32 SendBufferSize;
+ UINT32 RecvBufferSize;
+ UINT8 *Buffer;
+ UINT32 SessionInfoSize;
+
+ //
+ // Construct command
+ //
+ SendBuffer.Header.tag = SwapBytes16(TPM_ST_SESSIONS);
+ SendBuffer.Header.commandCode = SwapBytes32(TPM_CC_SetPrimaryPolicy);
+
+ SendBuffer.AuthHandle = SwapBytes32 (AuthHandle);
+
+ //
+ // Add in Auth session
+ //
+ Buffer = (UINT8 *)&SendBuffer.AuthSession;
+
+ // sessionInfoSize
+ SessionInfoSize = CopyAuthSessionCommand (AuthSession, Buffer);
+ Buffer += SessionInfoSize;
+ SendBuffer.AuthSessionSize = SwapBytes32(SessionInfoSize);
+
+ //
+ // Real data
+ //
+ WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16(AuthPolicy->size));
+ Buffer += sizeof(UINT16);
+ CopyMem (Buffer, AuthPolicy->buffer, AuthPolicy->size);
+ Buffer += AuthPolicy->size;
+ WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16(HashAlg));
+ Buffer += sizeof(UINT16);
+
+ SendBufferSize = (UINT32)((UINTN)Buffer - (UINTN)&SendBuffer);
+ SendBuffer.Header.paramSize = SwapBytes32 (SendBufferSize);
+
+ //
+ // send Tpm command
+ //
+ RecvBufferSize = sizeof (RecvBuffer);
+ Status = Tpm2SubmitCommand (SendBufferSize, (UINT8 *)&SendBuffer, &RecvBufferSize, (UINT8 *)&RecvBuffer);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ if (RecvBufferSize < sizeof (TPM2_RESPONSE_HEADER)) {
+ DEBUG ((EFI_D_ERROR, "Tpm2SetPrimaryPolicy - RecvBufferSize Error - %x\n", RecvBufferSize));
+ return EFI_DEVICE_ERROR;
+ }
+ if (SwapBytes32(RecvBuffer.Header.responseCode) != TPM_RC_SUCCESS) {
+ DEBUG ((EFI_D_ERROR, "Tpm2SetPrimaryPolicy - responseCode - %x\n", SwapBytes32(RecvBuffer.Header.responseCode)));
+ return EFI_DEVICE_ERROR;
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
This command removes all TPM context associated with a specific Owner.
@param[in] AuthHandle TPM_RH_LOCKOUT or TPM_RH_PLATFORM+{PP}
diff --git a/SecurityPkg/Library/Tpm2CommandLib/Tpm2Session.c b/SecurityPkg/Library/Tpm2CommandLib/Tpm2Session.c
new file mode 100644
index 0000000000..f03b6689ac
--- /dev/null
+++ b/SecurityPkg/Library/Tpm2CommandLib/Tpm2Session.c
@@ -0,0 +1,169 @@
+/** @file
+ Implement TPM2 Session related command.
+
+Copyright (c) 2014, Intel Corporation. All rights reserved. <BR>
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include <IndustryStandard/UefiTcgPlatform.h>
+#include <Library/Tpm2CommandLib.h>
+#include <Library/Tpm2DeviceLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+
+#pragma pack(1)
+
+typedef struct {
+ TPM2_COMMAND_HEADER Header;
+ TPMI_DH_OBJECT TpmKey;
+ TPMI_DH_ENTITY Bind;
+ TPM2B_NONCE NonceCaller;
+ TPM2B_ENCRYPTED_SECRET Salt;
+ TPM_SE SessionType;
+ TPMT_SYM_DEF Symmetric;
+ TPMI_ALG_HASH AuthHash;
+} TPM2_START_AUTH_SESSION_COMMAND;
+
+typedef struct {
+ TPM2_RESPONSE_HEADER Header;
+ TPMI_SH_AUTH_SESSION SessionHandle;
+ TPM2B_NONCE NonceTPM;
+} TPM2_START_AUTH_SESSION_RESPONSE;
+
+#pragma pack()
+
+/**
+ This command is used to start an authorization session using alternative methods of
+ establishing the session key (sessionKey) that is used for authorization and encrypting value.
+
+ @param[in] TpmKey Handle of a loaded decrypt key used to encrypt salt.
+ @param[in] Bind Entity providing the authValue.
+ @param[in] NonceCaller Initial nonceCaller, sets nonce size for the session.
+ @param[in] Salt Value encrypted according to the type of tpmKey.
+ @param[in] SessionType Indicates the type of the session.
+ @param[in] Symmetric The algorithm and key size for parameter encryption.
+ @param[in] AuthHash Hash algorithm to use for the session.
+ @param[out] SessionHandle Handle for the newly created session.
+ @param[out] NonceTPM The initial nonce from the TPM, used in the computation of the sessionKey.
+
+ @retval EFI_SUCCESS Operation completed successfully.
+ @retval EFI_DEVICE_ERROR The command was unsuccessful.
+**/
+EFI_STATUS
+EFIAPI
+Tpm2StartAuthSession (
+ IN TPMI_DH_OBJECT TpmKey,
+ IN TPMI_DH_ENTITY Bind,
+ IN TPM2B_NONCE *NonceCaller,
+ IN TPM2B_ENCRYPTED_SECRET *Salt,
+ IN TPM_SE SessionType,
+ IN TPMT_SYM_DEF *Symmetric,
+ IN TPMI_ALG_HASH AuthHash,
+ OUT TPMI_SH_AUTH_SESSION *SessionHandle,
+ OUT TPM2B_NONCE *NonceTPM
+ )
+{
+ EFI_STATUS Status;
+ TPM2_START_AUTH_SESSION_COMMAND SendBuffer;
+ TPM2_START_AUTH_SESSION_RESPONSE RecvBuffer;
+ UINT32 SendBufferSize;
+ UINT32 RecvBufferSize;
+ UINT8 *Buffer;
+
+ //
+ // Construct command
+ //
+ SendBuffer.Header.tag = SwapBytes16(TPM_ST_NO_SESSIONS);
+ SendBuffer.Header.commandCode = SwapBytes32(TPM_CC_StartAuthSession);
+
+ SendBuffer.TpmKey = SwapBytes32 (TpmKey);
+ SendBuffer.Bind = SwapBytes32 (Bind);
+ Buffer = (UINT8 *)&SendBuffer.NonceCaller;
+
+ WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (NonceCaller->size));
+ Buffer += sizeof(UINT16);
+ CopyMem (Buffer, NonceCaller->buffer, NonceCaller->size);
+ Buffer += NonceCaller->size;
+
+ WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (Salt->size));
+ Buffer += sizeof(UINT16);
+ CopyMem (Buffer, Salt->secret, Salt->size);
+ Buffer += Salt->size;
+
+ *(TPM_SE *)Buffer = SessionType;
+ Buffer++;
+
+ WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (Symmetric->algorithm));
+ Buffer += sizeof(UINT16);
+ switch (Symmetric->algorithm) {
+ case TPM_ALG_NULL:
+ break;
+ case TPM_ALG_AES:
+ WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (Symmetric->keyBits.aes));
+ Buffer += sizeof(UINT16);
+ WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (Symmetric->mode.aes));
+ Buffer += sizeof(UINT16);
+ break;
+ case TPM_ALG_SM4:
+ WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (Symmetric->keyBits.SM4));
+ Buffer += sizeof(UINT16);
+ WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (Symmetric->mode.SM4));
+ Buffer += sizeof(UINT16);
+ break;
+ case TPM_ALG_SYMCIPHER:
+ WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (Symmetric->keyBits.sym));
+ Buffer += sizeof(UINT16);
+ WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (Symmetric->mode.sym));
+ Buffer += sizeof(UINT16);
+ break;
+ case TPM_ALG_XOR:
+ WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (Symmetric->keyBits.xor));
+ Buffer += sizeof(UINT16);
+ break;
+ default:
+ ASSERT (FALSE);
+ DEBUG ((EFI_D_ERROR, "Tpm2StartAuthSession - Symmetric->algorithm - %x\n", Symmetric->algorithm));
+ return EFI_UNSUPPORTED;
+ }
+
+ WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (AuthHash));
+ Buffer += sizeof(UINT16);
+
+ SendBufferSize = (UINT32) ((UINTN)Buffer - (UINTN)&SendBuffer);
+ SendBuffer.Header.paramSize = SwapBytes32 (SendBufferSize);
+
+ //
+ // send Tpm command
+ //
+ RecvBufferSize = sizeof (RecvBuffer);
+ Status = Tpm2SubmitCommand (SendBufferSize, (UINT8 *)&SendBuffer, &RecvBufferSize, (UINT8 *)&RecvBuffer);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ if (RecvBufferSize < sizeof (TPM2_RESPONSE_HEADER)) {
+ DEBUG ((EFI_D_ERROR, "Tpm2StartAuthSession - RecvBufferSize Error - %x\n", RecvBufferSize));
+ return EFI_DEVICE_ERROR;
+ }
+ if (SwapBytes32(RecvBuffer.Header.responseCode) != TPM_RC_SUCCESS) {
+ DEBUG ((EFI_D_ERROR, "Tpm2StartAuthSession - responseCode - %x\n", SwapBytes32(RecvBuffer.Header.responseCode)));
+ return EFI_DEVICE_ERROR;
+ }
+
+ //
+ // Return the response
+ //
+ *SessionHandle = SwapBytes32 (RecvBuffer.SessionHandle);
+ NonceTPM->size = SwapBytes16 (RecvBuffer.NonceTPM.size);
+ CopyMem (NonceTPM->buffer, &RecvBuffer.NonceTPM.buffer, NonceTPM->size);
+
+ return EFI_SUCCESS;
+}
diff --git a/SecurityPkg/Tcg/TcgDxe/TcgDxe.c b/SecurityPkg/Tcg/TcgDxe/TcgDxe.c
index bf9c7521aa..282505dbc7 100644
--- a/SecurityPkg/Tcg/TcgDxe/TcgDxe.c
+++ b/SecurityPkg/Tcg/TcgDxe/TcgDxe.c
@@ -1021,7 +1021,7 @@ MeasureAllBootVariables (
&BootCount,
(VOID **) &BootOrder
);
- if (Status == EFI_NOT_FOUND) {
+ if (Status == EFI_NOT_FOUND || BootOrder == NULL) {
return EFI_SUCCESS;
}
diff --git a/SecurityPkg/Tcg/TrEEDxe/TrEEDxe.c b/SecurityPkg/Tcg/TrEEDxe/TrEEDxe.c
index 2f159e0c6b..54e505d136 100644
--- a/SecurityPkg/Tcg/TrEEDxe/TrEEDxe.c
+++ b/SecurityPkg/Tcg/TrEEDxe/TrEEDxe.c
@@ -1245,7 +1245,7 @@ MeasureVariable (
VarName,
VarNameLength * sizeof (*VarName)
);
- if (VarSize != 0) {
+ if (VarSize != 0 && VarData != NULL) {
CopyMem (
(CHAR16 *)VarLog->UnicodeName + VarNameLength,
VarData,
@@ -1423,7 +1423,7 @@ MeasureAllBootVariables (
&BootCount,
(VOID **) &BootOrder
);
- if (Status == EFI_NOT_FOUND) {
+ if (Status == EFI_NOT_FOUND || BootOrder == NULL) {
return EFI_SUCCESS;
}
diff --git a/SecurityPkg/VariableAuthenticated/RuntimeDxe/VarCheck.c b/SecurityPkg/VariableAuthenticated/RuntimeDxe/VarCheck.c
new file mode 100644
index 0000000000..76bd7b4d90
--- /dev/null
+++ b/SecurityPkg/VariableAuthenticated/RuntimeDxe/VarCheck.c
@@ -0,0 +1,1225 @@
+/** @file
+ Implementation functions and structures for var check protocol.
+
+Copyright (c) 2015, 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 "Variable.h"
+#include <Library/DevicePathLib.h>
+
+extern LIST_ENTRY mLockedVariableList;
+extern BOOLEAN mEndOfDxe;
+extern BOOLEAN mEnableLocking;
+
+#define VAR_CHECK_HANDLER_TABLE_SIZE 0x8
+
+UINT32 mNumberOfHandler = 0;
+UINT32 mMaxNumberOfHandler = 0;
+VAR_CHECK_SET_VARIABLE_CHECK_HANDLER *mHandlerTable = NULL;
+
+typedef struct {
+ LIST_ENTRY Link;
+ EFI_GUID Guid;
+ VAR_CHECK_VARIABLE_PROPERTY VariableProperty;
+ //CHAR16 *Name;
+} VAR_CHECK_VARIABLE_ENTRY;
+
+LIST_ENTRY mVarCheckVariableList = INITIALIZE_LIST_HEAD_VARIABLE (mVarCheckVariableList);
+
+typedef
+EFI_STATUS
+(EFIAPI *INTERNAL_VAR_CHECK_FUNCTION) (
+ IN VAR_CHECK_VARIABLE_PROPERTY *Propery,
+ IN UINTN DataSize,
+ IN VOID *Data
+ );
+
+typedef struct {
+ CHAR16 *Name;
+ VAR_CHECK_VARIABLE_PROPERTY VariableProperty;
+ INTERNAL_VAR_CHECK_FUNCTION CheckFunction;
+} UEFI_DEFINED_VARIABLE_ENTRY;
+
+typedef struct _EFI_LOAD_OPTION {
+ UINT32 Attributes;
+ UINT16 FilePathListLength;
+//CHAR16 Description[];
+//EFI_DEVICE_PATH_PROTOCOL FilePathList[];
+//UINT8 OptionalData[];
+} EFI_LOAD_OPTION;
+
+/**
+ Internal check for load option.
+
+ @param[in] VariablePropery Pointer to variable property.
+ @param[in] DataSize Data size.
+ @param[in] Data Pointer to data buffer.
+
+ @retval EFI_SUCCESS The SetVariable check result was success.
+ @retval EFI_INVALID_PARAMETER The data buffer is not a valid load option.
+
+**/
+EFI_STATUS
+EFIAPI
+InternalVarCheckLoadOption (
+ IN VAR_CHECK_VARIABLE_PROPERTY *VariablePropery,
+ IN UINTN DataSize,
+ IN VOID *Data
+ )
+{
+ EFI_LOAD_OPTION *LoadOption;
+ CHAR16 *Description;
+ EFI_DEVICE_PATH_PROTOCOL *FilePathList;
+
+ LoadOption = (EFI_LOAD_OPTION *) Data;
+
+ //
+ // Check Description
+ //
+ Description = (CHAR16 *) ((UINTN) Data + sizeof (EFI_LOAD_OPTION));
+ while (Description < (CHAR16 *) ((UINTN) Data + DataSize)) {
+ if (*Description == L'\0') {
+ break;
+ }
+ Description++;
+ }
+ if ((UINTN) Description >= ((UINTN) Data + DataSize)) {
+ return EFI_INVALID_PARAMETER;
+ }
+ Description++;
+
+ //
+ // Check FilePathList
+ //
+ FilePathList = (EFI_DEVICE_PATH_PROTOCOL *) Description;
+ if ((UINTN) FilePathList > (MAX_ADDRESS - LoadOption->FilePathListLength)) {
+ return EFI_INVALID_PARAMETER;
+ }
+ if (((UINTN) FilePathList + LoadOption->FilePathListLength) > ((UINTN) Data + DataSize)) {
+ return EFI_INVALID_PARAMETER;
+ }
+ if (LoadOption->FilePathListLength < sizeof (EFI_DEVICE_PATH_PROTOCOL)) {
+ return EFI_INVALID_PARAMETER;
+ }
+ if (!IsDevicePathValid (FilePathList, LoadOption->FilePathListLength)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Internal check for key option.
+
+ @param[in] VariablePropery Pointer to variable property.
+ @param[in] DataSize Data size.
+ @param[in] Data Pointer to data buffer.
+
+ @retval EFI_SUCCESS The SetVariable check result was success.
+ @retval EFI_INVALID_PARAMETER The data buffer is not a valid key option.
+
+**/
+EFI_STATUS
+EFIAPI
+InternalVarCheckKeyOption (
+ IN VAR_CHECK_VARIABLE_PROPERTY *VariablePropery,
+ IN UINTN DataSize,
+ IN VOID *Data
+ )
+{
+ if (((DataSize - sizeof (EFI_KEY_OPTION)) % sizeof (EFI_INPUT_KEY)) != 0) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Internal check for device path.
+
+ @param[in] VariablePropery Pointer to variable property.
+ @param[in] DataSize Data size.
+ @param[in] Data Pointer to data buffer.
+
+ @retval EFI_SUCCESS The SetVariable check result was success.
+ @retval EFI_INVALID_PARAMETER The data buffer is not a valid device path.
+
+**/
+EFI_STATUS
+EFIAPI
+InternalVarCheckDevicePath (
+ IN VAR_CHECK_VARIABLE_PROPERTY *VariablePropery,
+ IN UINTN DataSize,
+ IN VOID *Data
+ )
+{
+ if (!IsDevicePathValid ((EFI_DEVICE_PATH_PROTOCOL *) Data, DataSize)) {
+ return EFI_INVALID_PARAMETER;
+ }
+ return EFI_SUCCESS;
+}
+
+/**
+ Internal check for ASCII string.
+
+ @param[in] VariablePropery Pointer to variable property.
+ @param[in] DataSize Data size.
+ @param[in] Data Pointer to data buffer.
+
+ @retval EFI_SUCCESS The SetVariable check result was success.
+ @retval EFI_INVALID_PARAMETER The data buffer is not a Null-terminated ASCII string.
+
+**/
+EFI_STATUS
+EFIAPI
+InternalVarCheckAsciiString (
+ IN VAR_CHECK_VARIABLE_PROPERTY *VariablePropery,
+ IN UINTN DataSize,
+ IN VOID *Data
+ )
+{
+ CHAR8 *String;
+ UINTN Index;
+
+ String = (CHAR8 *) Data;
+ if (String[DataSize - 1] == '\0') {
+ return EFI_SUCCESS;
+ } else {
+ for (Index = 1; Index < DataSize && (String[DataSize - 1 - Index] != '\0'); Index++);
+ if (Index == DataSize) {
+ return EFI_INVALID_PARAMETER;
+ }
+ }
+ return EFI_SUCCESS;
+}
+
+/**
+ Internal check for size array.
+
+ @param[in] VariablePropery Pointer to variable property.
+ @param[in] DataSize Data size.
+ @param[in] Data Pointer to data buffer.
+
+ @retval EFI_SUCCESS The SetVariable check result was success.
+ @retval EFI_INVALID_PARAMETER The DataSize is not size array.
+
+**/
+EFI_STATUS
+EFIAPI
+InternalVarCheckSizeArray (
+ IN VAR_CHECK_VARIABLE_PROPERTY *VariablePropery,
+ IN UINTN DataSize,
+ IN VOID *Data
+ )
+{
+ if ((DataSize % VariablePropery->MinSize) != 0) {
+ return EFI_INVALID_PARAMETER;
+ }
+ return EFI_SUCCESS;
+}
+
+//
+// To prevent name collisions with possible future globally defined variables,
+// other internal firmware data variables that are not defined here must be
+// saved with a unique VendorGuid other than EFI_GLOBAL_VARIABLE or
+// any other GUID defined by the UEFI Specification. Implementations must
+// only permit the creation of variables with a UEFI Specification-defined
+// VendorGuid when these variables are documented in the UEFI Specification.
+//
+UEFI_DEFINED_VARIABLE_ENTRY mGlobalVariableList[] = {
+ {
+ EFI_LANG_CODES_VARIABLE_NAME,
+ {
+ VAR_CHECK_VARIABLE_PROPERTY_REVISION,
+ 0,
+ VARIABLE_ATTRIBUTE_BS_RT,
+ 1,
+ MAX_UINTN
+ },
+ InternalVarCheckAsciiString
+ },
+ {
+ EFI_LANG_VARIABLE_NAME,
+ {
+ VAR_CHECK_VARIABLE_PROPERTY_REVISION,
+ 0,
+ VARIABLE_ATTRIBUTE_NV_BS_RT,
+ 1,
+ MAX_UINTN
+ },
+ InternalVarCheckAsciiString
+ },
+ {
+ EFI_TIME_OUT_VARIABLE_NAME,
+ {
+ VAR_CHECK_VARIABLE_PROPERTY_REVISION,
+ 0,
+ VARIABLE_ATTRIBUTE_NV_BS_RT,
+ sizeof (UINT16),
+ sizeof (UINT16)
+ },
+ NULL
+ },
+ {
+ EFI_PLATFORM_LANG_CODES_VARIABLE_NAME,
+ {
+ VAR_CHECK_VARIABLE_PROPERTY_REVISION,
+ 0,
+ VARIABLE_ATTRIBUTE_BS_RT,
+ 1,
+ MAX_UINTN
+ },
+ InternalVarCheckAsciiString
+ },
+ {
+ EFI_PLATFORM_LANG_VARIABLE_NAME,
+ {
+ VAR_CHECK_VARIABLE_PROPERTY_REVISION,
+ 0,
+ VARIABLE_ATTRIBUTE_NV_BS_RT,
+ 1,
+ MAX_UINTN
+ },
+ InternalVarCheckAsciiString
+ },
+ {
+ EFI_CON_IN_VARIABLE_NAME,
+ {
+ VAR_CHECK_VARIABLE_PROPERTY_REVISION,
+ 0,
+ VARIABLE_ATTRIBUTE_NV_BS_RT,
+ sizeof (EFI_DEVICE_PATH_PROTOCOL),
+ MAX_UINTN
+ },
+ InternalVarCheckDevicePath
+ },
+ {
+ EFI_CON_OUT_VARIABLE_NAME,
+ {
+ VAR_CHECK_VARIABLE_PROPERTY_REVISION,
+ 0,
+ VARIABLE_ATTRIBUTE_NV_BS_RT,
+ sizeof (EFI_DEVICE_PATH_PROTOCOL),
+ MAX_UINTN
+ },
+ InternalVarCheckDevicePath
+ },
+ {
+ EFI_ERR_OUT_VARIABLE_NAME,
+ {
+ VAR_CHECK_VARIABLE_PROPERTY_REVISION,
+ 0,
+ VARIABLE_ATTRIBUTE_NV_BS_RT,
+ sizeof (EFI_DEVICE_PATH_PROTOCOL),
+ MAX_UINTN
+ },
+ InternalVarCheckDevicePath
+ },
+ {
+ EFI_CON_IN_DEV_VARIABLE_NAME,
+ {
+ VAR_CHECK_VARIABLE_PROPERTY_REVISION,
+ 0,
+ VARIABLE_ATTRIBUTE_BS_RT,
+ sizeof (EFI_DEVICE_PATH_PROTOCOL),
+ MAX_UINTN
+ },
+ InternalVarCheckDevicePath
+ },
+ {
+ EFI_CON_OUT_DEV_VARIABLE_NAME,
+ {
+ VAR_CHECK_VARIABLE_PROPERTY_REVISION,
+ 0,
+ VARIABLE_ATTRIBUTE_BS_RT,
+ sizeof (EFI_DEVICE_PATH_PROTOCOL),
+ MAX_UINTN
+ },
+ InternalVarCheckDevicePath
+ },
+ {
+ EFI_ERR_OUT_DEV_VARIABLE_NAME,
+ {
+ VAR_CHECK_VARIABLE_PROPERTY_REVISION,
+ 0,
+ VARIABLE_ATTRIBUTE_BS_RT,
+ sizeof (EFI_DEVICE_PATH_PROTOCOL),
+ MAX_UINTN
+ },
+ InternalVarCheckDevicePath
+ },
+ {
+ EFI_BOOT_ORDER_VARIABLE_NAME,
+ {
+ VAR_CHECK_VARIABLE_PROPERTY_REVISION,
+ 0,
+ VARIABLE_ATTRIBUTE_NV_BS_RT,
+ sizeof (UINT16),
+ MAX_UINTN
+ },
+ InternalVarCheckSizeArray
+ },
+ {
+ EFI_BOOT_NEXT_VARIABLE_NAME,
+ {
+ VAR_CHECK_VARIABLE_PROPERTY_REVISION,
+ 0,
+ VARIABLE_ATTRIBUTE_NV_BS_RT,
+ sizeof (UINT16),
+ sizeof (UINT16)
+ },
+ NULL
+ },
+ {
+ EFI_BOOT_CURRENT_VARIABLE_NAME,
+ {
+ VAR_CHECK_VARIABLE_PROPERTY_REVISION,
+ 0,
+ VARIABLE_ATTRIBUTE_BS_RT,
+ sizeof (UINT16),
+ sizeof (UINT16)
+ },
+ NULL
+ },
+ {
+ EFI_BOOT_OPTION_SUPPORT_VARIABLE_NAME,
+ {
+ VAR_CHECK_VARIABLE_PROPERTY_REVISION,
+ 0,
+ VARIABLE_ATTRIBUTE_BS_RT,
+ sizeof (UINT32),
+ sizeof (UINT32)
+ },
+ NULL
+ },
+ {
+ EFI_DRIVER_ORDER_VARIABLE_NAME,
+ {
+ VAR_CHECK_VARIABLE_PROPERTY_REVISION,
+ 0,
+ VARIABLE_ATTRIBUTE_NV_BS_RT,
+ sizeof (UINT16),
+ MAX_UINTN
+ },
+ InternalVarCheckSizeArray
+ },
+ {
+ EFI_HW_ERR_REC_SUPPORT_VARIABLE_NAME,
+ {
+ VAR_CHECK_VARIABLE_PROPERTY_REVISION,
+ 0,
+ VARIABLE_ATTRIBUTE_NV_BS_RT,
+ sizeof (UINT16),
+ sizeof (UINT16)
+ },
+ NULL
+ },
+ {
+ EFI_SETUP_MODE_NAME,
+ {
+ VAR_CHECK_VARIABLE_PROPERTY_REVISION,
+ VAR_CHECK_VARIABLE_PROPERTY_READ_ONLY,
+ VARIABLE_ATTRIBUTE_BS_RT,
+ sizeof (UINT8),
+ sizeof (UINT8)
+ },
+ NULL
+ },
+ {
+ EFI_KEY_EXCHANGE_KEY_NAME,
+ {
+ VAR_CHECK_VARIABLE_PROPERTY_REVISION,
+ 0,
+ VARIABLE_ATTRIBUTE_NV_BS_RT_AT,
+ 1,
+ MAX_UINTN
+ },
+ NULL
+ },
+ {
+ EFI_PLATFORM_KEY_NAME,
+ {
+ VAR_CHECK_VARIABLE_PROPERTY_REVISION,
+ 0,
+ VARIABLE_ATTRIBUTE_NV_BS_RT_AT,
+ 1,
+ MAX_UINTN
+ },
+ NULL
+ },
+ {
+ EFI_SIGNATURE_SUPPORT_NAME,
+ {
+ VAR_CHECK_VARIABLE_PROPERTY_REVISION,
+ VAR_CHECK_VARIABLE_PROPERTY_READ_ONLY,
+ VARIABLE_ATTRIBUTE_BS_RT,
+ sizeof (EFI_GUID),
+ MAX_UINTN
+ },
+ InternalVarCheckSizeArray
+ },
+ {
+ EFI_SECURE_BOOT_MODE_NAME,
+ {
+ VAR_CHECK_VARIABLE_PROPERTY_REVISION,
+ VAR_CHECK_VARIABLE_PROPERTY_READ_ONLY,
+ VARIABLE_ATTRIBUTE_BS_RT,
+ sizeof (UINT8),
+ sizeof (UINT8)
+ },
+ NULL
+ },
+ {
+ EFI_KEK_DEFAULT_VARIABLE_NAME,
+ {
+ VAR_CHECK_VARIABLE_PROPERTY_REVISION,
+ VAR_CHECK_VARIABLE_PROPERTY_READ_ONLY,
+ VARIABLE_ATTRIBUTE_BS_RT,
+ 1,
+ MAX_UINTN
+ },
+ NULL
+ },
+ {
+ EFI_PK_DEFAULT_VARIABLE_NAME,
+ {
+ VAR_CHECK_VARIABLE_PROPERTY_REVISION,
+ VAR_CHECK_VARIABLE_PROPERTY_READ_ONLY,
+ VARIABLE_ATTRIBUTE_BS_RT,
+ 1,
+ MAX_UINTN
+ },
+ NULL
+ },
+ {
+ EFI_DB_DEFAULT_VARIABLE_NAME,
+ {
+ VAR_CHECK_VARIABLE_PROPERTY_REVISION,
+ VAR_CHECK_VARIABLE_PROPERTY_READ_ONLY,
+ VARIABLE_ATTRIBUTE_BS_RT,
+ 1,
+ MAX_UINTN
+ },
+ NULL
+ },
+ {
+ EFI_DBX_DEFAULT_VARIABLE_NAME,
+ {
+ VAR_CHECK_VARIABLE_PROPERTY_REVISION,
+ VAR_CHECK_VARIABLE_PROPERTY_READ_ONLY,
+ VARIABLE_ATTRIBUTE_BS_RT,
+ 1,
+ MAX_UINTN
+ },
+ NULL
+ },
+ {
+ EFI_DBT_DEFAULT_VARIABLE_NAME,
+ {
+ VAR_CHECK_VARIABLE_PROPERTY_REVISION,
+ VAR_CHECK_VARIABLE_PROPERTY_READ_ONLY,
+ VARIABLE_ATTRIBUTE_BS_RT,
+ 1,
+ MAX_UINTN
+ },
+ NULL
+ },
+ {
+ EFI_OS_INDICATIONS_SUPPORT_VARIABLE_NAME,
+ {
+ VAR_CHECK_VARIABLE_PROPERTY_REVISION,
+ 0,
+ VARIABLE_ATTRIBUTE_BS_RT,
+ sizeof (UINT64),
+ sizeof (UINT64)
+ },
+ NULL
+ },
+ {
+ EFI_OS_INDICATIONS_VARIABLE_NAME,
+ {
+ VAR_CHECK_VARIABLE_PROPERTY_REVISION,
+ 0,
+ VARIABLE_ATTRIBUTE_NV_BS_RT,
+ sizeof (UINT64),
+ sizeof (UINT64)
+ },
+ NULL
+ },
+ {
+ EFI_VENDOR_KEYS_VARIABLE_NAME,
+ {
+ VAR_CHECK_VARIABLE_PROPERTY_REVISION,
+ VAR_CHECK_VARIABLE_PROPERTY_READ_ONLY,
+ VARIABLE_ATTRIBUTE_BS_RT,
+ sizeof (UINT8),
+ sizeof (UINT8)
+ },
+ NULL
+ },
+};
+UEFI_DEFINED_VARIABLE_ENTRY mGlobalVariableList2[] = {
+ {
+ L"Boot####",
+ {
+ VAR_CHECK_VARIABLE_PROPERTY_REVISION,
+ 0,
+ VARIABLE_ATTRIBUTE_NV_BS_RT,
+ sizeof (EFI_LOAD_OPTION),
+ MAX_UINTN
+ },
+ InternalVarCheckLoadOption
+ },
+ {
+ L"Driver####",
+ {
+ VAR_CHECK_VARIABLE_PROPERTY_REVISION,
+ 0,
+ VARIABLE_ATTRIBUTE_NV_BS_RT,
+ sizeof (EFI_LOAD_OPTION),
+ MAX_UINTN
+ },
+ InternalVarCheckLoadOption
+ },
+ {
+ L"Key####",
+ {
+ VAR_CHECK_VARIABLE_PROPERTY_REVISION,
+ 0,
+ VARIABLE_ATTRIBUTE_NV_BS_RT,
+ sizeof (EFI_KEY_OPTION),
+ sizeof (EFI_KEY_OPTION) + 3 * sizeof (EFI_INPUT_KEY)
+ },
+ InternalVarCheckKeyOption
+ },
+};
+
+//
+// EFI_IMAGE_SECURITY_DATABASE_GUID
+//
+UEFI_DEFINED_VARIABLE_ENTRY mImageSecurityVariableList[] = {
+ {
+ EFI_IMAGE_SECURITY_DATABASE,
+ {
+ VAR_CHECK_VARIABLE_PROPERTY_REVISION,
+ 0,
+ VARIABLE_ATTRIBUTE_NV_BS_RT_AT,
+ 1,
+ MAX_UINTN
+ },
+ NULL
+ },
+ {
+ EFI_IMAGE_SECURITY_DATABASE1,
+ {
+ VAR_CHECK_VARIABLE_PROPERTY_REVISION,
+ 0,
+ VARIABLE_ATTRIBUTE_NV_BS_RT_AT,
+ 1,
+ MAX_UINTN
+ },
+ NULL
+ },
+ {
+ EFI_IMAGE_SECURITY_DATABASE2,
+ {
+ VAR_CHECK_VARIABLE_PROPERTY_REVISION,
+ 0,
+ VARIABLE_ATTRIBUTE_NV_BS_RT_AT,
+ 1,
+ MAX_UINTN
+ },
+ NULL
+ },
+};
+
+typedef struct {
+ EFI_GUID *Guid;
+ CHAR16 *Name;
+ VAR_CHECK_VARIABLE_PROPERTY VariableProperty;
+ INTERNAL_VAR_CHECK_FUNCTION CheckFunction;
+} VARIABLE_DRIVER_VARIABLE_ENTRY;
+
+VARIABLE_DRIVER_VARIABLE_ENTRY mVariableDriverVariableList[] = {
+ {
+ &gEfiSecureBootEnableDisableGuid,
+ EFI_SECURE_BOOT_ENABLE_NAME,
+ {
+ VAR_CHECK_VARIABLE_PROPERTY_REVISION,
+ 0,
+ VARIABLE_ATTRIBUTE_NV_BS,
+ sizeof (UINT8),
+ sizeof (UINT8)
+ },
+ NULL
+ },
+ {
+ &gEfiCustomModeEnableGuid,
+ EFI_CUSTOM_MODE_NAME,
+ {
+ VAR_CHECK_VARIABLE_PROPERTY_REVISION,
+ 0,
+ VARIABLE_ATTRIBUTE_NV_BS,
+ sizeof (UINT8),
+ sizeof (UINT8)
+ },
+ NULL
+ },
+ {
+ &gEfiVendorKeysNvGuid,
+ EFI_VENDOR_KEYS_NV_VARIABLE_NAME,
+ {
+ VAR_CHECK_VARIABLE_PROPERTY_REVISION,
+ 0,
+ VARIABLE_ATTRIBUTE_NV_BS_RT_AT,
+ sizeof (UINT8),
+ sizeof (UINT8)
+ },
+ NULL
+ },
+ {
+ &gEfiAuthenticatedVariableGuid,
+ L"AuthVarKeyDatabase",
+ {
+ VAR_CHECK_VARIABLE_PROPERTY_REVISION,
+ 0,
+ VARIABLE_ATTRIBUTE_NV_BS_RT_AW,
+ sizeof (UINT8),
+ MAX_UINTN
+ },
+ NULL
+ },
+ {
+ &gEfiCertDbGuid,
+ L"certdb",
+ {
+ VAR_CHECK_VARIABLE_PROPERTY_REVISION,
+ 0,
+ VARIABLE_ATTRIBUTE_NV_BS_RT_AT,
+ sizeof (UINT32),
+ MAX_UINTN
+ },
+ NULL
+ },
+};
+
+/**
+ Get UEFI defined global variable or image security database variable property.
+ The code will check if variable guid is global variable or image security database guid first.
+ If yes, further check if variable name is in mGlobalVariableList, mGlobalVariableList2 or mImageSecurityVariableList.
+
+ @param[in] VariableName Pointer to variable name.
+ @param[in] VendorGuid Variable Vendor Guid.
+ @param[in] WildcardMatch Try wildcard match or not.
+ @param[out] VariableProperty Pointer to variable property.
+ @param[out] VarCheckFunction Pointer to check function.
+
+ @retval EFI_SUCCESS Variable is not global variable or image security database variable.
+ @retval EFI_INVALID_PARAMETER Variable is global variable or image security database variable, but variable name is not in the lists.
+
+**/
+EFI_STATUS
+GetUefiDefinedVariableProperty (
+ IN CHAR16 *VariableName,
+ IN EFI_GUID *VendorGuid,
+ IN BOOLEAN WildcardMatch,
+ OUT VAR_CHECK_VARIABLE_PROPERTY **VariableProperty,
+ OUT INTERNAL_VAR_CHECK_FUNCTION *VarCheckFunction OPTIONAL
+ )
+{
+ UINTN Index;
+ UINTN NameLength;
+
+ if (CompareGuid (VendorGuid, &gEfiGlobalVariableGuid)){
+ //
+ // Try list 1, exactly match.
+ //
+ for (Index = 0; Index < sizeof (mGlobalVariableList)/sizeof (mGlobalVariableList[0]); Index++) {
+ if (StrCmp (mGlobalVariableList[Index].Name, VariableName) == 0) {
+ if (VarCheckFunction != NULL) {
+ *VarCheckFunction = mGlobalVariableList[Index].CheckFunction;
+ }
+ *VariableProperty = &mGlobalVariableList[Index].VariableProperty;
+ return EFI_SUCCESS;
+ }
+ }
+
+ //
+ // Try list 2.
+ //
+ NameLength = StrLen (VariableName) - 4;
+ for (Index = 0; Index < sizeof (mGlobalVariableList2)/sizeof (mGlobalVariableList2[0]); Index++) {
+ if (WildcardMatch) {
+ if ((StrLen (VariableName) == StrLen (mGlobalVariableList2[Index].Name)) &&
+ (StrnCmp (mGlobalVariableList2[Index].Name, VariableName, NameLength) == 0) &&
+ IsHexaDecimalDigitCharacter (VariableName[NameLength]) &&
+ IsHexaDecimalDigitCharacter (VariableName[NameLength + 1]) &&
+ IsHexaDecimalDigitCharacter (VariableName[NameLength + 2]) &&
+ IsHexaDecimalDigitCharacter (VariableName[NameLength + 3])) {
+ if (VarCheckFunction != NULL) {
+ *VarCheckFunction = mGlobalVariableList2[Index].CheckFunction;
+ }
+ *VariableProperty = &mGlobalVariableList2[Index].VariableProperty;
+ return EFI_SUCCESS;
+ }
+ } else {
+ if (StrCmp (mGlobalVariableList2[Index].Name, VariableName) == 0) {
+ if (VarCheckFunction != NULL) {
+ *VarCheckFunction = mGlobalVariableList2[Index].CheckFunction;
+ }
+ *VariableProperty = &mGlobalVariableList2[Index].VariableProperty;
+ return EFI_SUCCESS;
+ }
+ }
+ }
+
+ //
+ // The variable name is not in the lists.
+ //
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (CompareGuid (VendorGuid, &gEfiImageSecurityDatabaseGuid)){
+ for (Index = 0; Index < sizeof (mImageSecurityVariableList)/sizeof (mImageSecurityVariableList[0]); Index++) {
+ if (StrCmp (mImageSecurityVariableList[Index].Name, VariableName) == 0) {
+ if (VarCheckFunction != NULL) {
+ *VarCheckFunction = mImageSecurityVariableList[Index].CheckFunction;
+ }
+ *VariableProperty = &mImageSecurityVariableList[Index].VariableProperty;
+ return EFI_SUCCESS;
+ }
+ }
+
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // It is not global variable or image security database variable.
+ //
+ return EFI_SUCCESS;
+}
+
+/**
+ Get variable property for variables managed by Varaible driver.
+
+ @param[in] VariableName Pointer to variable name.
+ @param[in] VendorGuid Variable Vendor Guid.
+ @param[out] VarCheckFunction Pointer to check function.
+
+ @return Pointer to variable property.
+
+**/
+VAR_CHECK_VARIABLE_PROPERTY *
+GetVariableDriverVariableProperty (
+ IN CHAR16 *VariableName,
+ IN EFI_GUID *VendorGuid,
+ OUT INTERNAL_VAR_CHECK_FUNCTION *VarCheckFunction OPTIONAL
+ )
+{
+ UINTN Index;
+
+ for (Index = 0; Index < sizeof (mVariableDriverVariableList)/sizeof (mVariableDriverVariableList[0]); Index++) {
+ if ((CompareGuid (mVariableDriverVariableList[Index].Guid, VendorGuid)) && (StrCmp (mVariableDriverVariableList[Index].Name, VariableName) == 0)) {
+ if (VarCheckFunction != NULL) {
+ *VarCheckFunction = mVariableDriverVariableList[Index].CheckFunction;
+ }
+ return &mVariableDriverVariableList[Index].VariableProperty;
+ }
+ }
+
+ return NULL;
+}
+
+/**
+ Internal SetVariable check.
+
+ @param[in] VariableName Name of Variable to set.
+ @param[in] VendorGuid Variable vendor GUID.
+ @param[in] Attributes Attribute value of the variable.
+ @param[in] DataSize Size of Data to set.
+ @param[in] Data Data pointer.
+
+ @retval EFI_SUCCESS The SetVariable check result was success.
+ @retval EFI_INVALID_PARAMETER An invalid combination of attribute bits, name, and GUID was supplied,
+ or the DataSize exceeds the minimum or maximum allowed,
+ or the Data value is not following UEFI spec for UEFI defined variables.
+ @retval EFI_WRITE_PROTECTED The variable in question is read-only.
+ @retval Others The return status from check handler.
+
+**/
+EFI_STATUS
+EFIAPI
+InternalVarCheckSetVariableCheck (
+ IN CHAR16 *VariableName,
+ IN EFI_GUID *VendorGuid,
+ IN UINT32 Attributes,
+ IN UINTN DataSize,
+ IN VOID *Data
+ )
+{
+ EFI_STATUS Status;
+ UINTN Index;
+ LIST_ENTRY *Link;
+ VAR_CHECK_VARIABLE_ENTRY *Entry;
+ CHAR16 *Name;
+ VAR_CHECK_VARIABLE_PROPERTY *Property;
+ INTERNAL_VAR_CHECK_FUNCTION VarCheckFunction;
+
+ if (!mEndOfDxe) {
+ //
+ // Only do check after End Of Dxe.
+ //
+ return EFI_SUCCESS;
+ }
+
+ Property = NULL;
+ Status = GetUefiDefinedVariableProperty (VariableName, VendorGuid, TRUE, &Property, &VarCheckFunction);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_INFO, "[Variable]: Var Check UEFI defined variable fail %r - %g:%s\n", Status, VendorGuid, VariableName));
+ return Status;
+ }
+ if (Property == NULL) {
+ Property = GetVariableDriverVariableProperty (VariableName, VendorGuid, &VarCheckFunction);
+ }
+ if (Property == NULL) {
+ VarCheckFunction = NULL;
+ for ( Link = GetFirstNode (&mVarCheckVariableList)
+ ; !IsNull (&mVarCheckVariableList, Link)
+ ; Link = GetNextNode (&mVarCheckVariableList, Link)
+ ) {
+ Entry = BASE_CR (Link, VAR_CHECK_VARIABLE_ENTRY, Link);
+ Name = (CHAR16 *) ((UINTN) Entry + sizeof (*Entry));
+ if (CompareGuid (&Entry->Guid, VendorGuid) && (StrCmp (Name, VariableName) == 0)) {
+ Property = &Entry->VariableProperty;
+ break;
+ }
+ }
+ }
+ if (Property != NULL) {
+ if (mEnableLocking && ((Property->Property & VAR_CHECK_VARIABLE_PROPERTY_READ_ONLY) != 0)) {
+ DEBUG ((EFI_D_INFO, "[Variable]: Var Check ReadOnly variable fail %r - %g:%s\n", EFI_WRITE_PROTECTED, VendorGuid, VariableName));
+ return EFI_WRITE_PROTECTED;
+ }
+ if ((((Attributes & EFI_VARIABLE_APPEND_WRITE) == 0) && (DataSize == 0)) || (Attributes == 0)) {
+ //
+ // Do not check delete variable.
+ //
+ return EFI_SUCCESS;
+ }
+ if ((Attributes & (~EFI_VARIABLE_APPEND_WRITE)) != Property->Attributes) {
+ DEBUG ((EFI_D_INFO, "[Variable]: Var Check Attributes fail %r - %g:%s\n", EFI_INVALID_PARAMETER, VendorGuid, VariableName));
+ return EFI_INVALID_PARAMETER;
+ }
+ if (DataSize != 0) {
+ if ((DataSize < Property->MinSize) || (DataSize > Property->MaxSize)) {
+ DEBUG ((EFI_D_INFO, "[Variable]: Var Check DataSize fail %r - %g:%s\n", EFI_INVALID_PARAMETER, VendorGuid, VariableName));
+ return EFI_INVALID_PARAMETER;
+ }
+ if (VarCheckFunction != NULL) {
+ Status = VarCheckFunction (
+ Property,
+ DataSize,
+ Data
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_INFO, "[Variable]: Internal Var Check function fail %r - %g:%s\n", Status, VendorGuid, VariableName));
+ return Status;
+ }
+ }
+ }
+ }
+
+ for (Index = 0; Index < mNumberOfHandler; Index ++) {
+ Status = mHandlerTable[Index] (
+ VariableName,
+ VendorGuid,
+ Attributes,
+ DataSize,
+ Data
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_INFO, "[Variable]: Var Check handler fail %r - %g:%s\n", Status, VendorGuid, VariableName));
+ return Status;
+ }
+ }
+ return EFI_SUCCESS;
+}
+
+/**
+ Reallocates more global memory to store the registered handler list.
+
+ @retval RETURN_SUCCESS Reallocate memory successfully.
+ @retval RETURN_OUT_OF_RESOURCES No enough memory to allocate.
+
+**/
+RETURN_STATUS
+EFIAPI
+ReallocateHandlerTable (
+ VOID
+ )
+{
+ VAR_CHECK_SET_VARIABLE_CHECK_HANDLER *HandlerTable;
+
+ //
+ // Reallocate memory for check handler table.
+ //
+ HandlerTable = ReallocateRuntimePool (
+ mMaxNumberOfHandler * sizeof (VAR_CHECK_SET_VARIABLE_CHECK_HANDLER),
+ (mMaxNumberOfHandler + VAR_CHECK_HANDLER_TABLE_SIZE) * sizeof (VAR_CHECK_SET_VARIABLE_CHECK_HANDLER),
+ mHandlerTable
+ );
+
+ //
+ // No enough resource to allocate.
+ //
+ if (HandlerTable == NULL) {
+ return RETURN_OUT_OF_RESOURCES;
+ }
+
+ mHandlerTable = HandlerTable;
+ //
+ // Increase max handler number.
+ //
+ mMaxNumberOfHandler = mMaxNumberOfHandler + VAR_CHECK_HANDLER_TABLE_SIZE;
+ return RETURN_SUCCESS;
+}
+
+/**
+ Register SetVariable check handler.
+
+ @param[in] Handler Pointer to check handler.
+
+ @retval EFI_SUCCESS The SetVariable check handler was registered successfully.
+ @retval EFI_INVALID_PARAMETER Handler is NULL.
+ @retval EFI_ACCESS_DENIED EFI_END_OF_DXE_EVENT_GROUP_GUID or EFI_EVENT_GROUP_READY_TO_BOOT has
+ already been signaled.
+ @retval EFI_OUT_OF_RESOURCES There is not enough resource for the SetVariable check handler register request.
+ @retval EFI_UNSUPPORTED This interface is not implemented.
+ For example, it is unsupported in VarCheck protocol if both VarCheck and SmmVarCheck protocols are present.
+
+**/
+EFI_STATUS
+EFIAPI
+VarCheckRegisterSetVariableCheckHandler (
+ IN VAR_CHECK_SET_VARIABLE_CHECK_HANDLER Handler
+ )
+{
+ EFI_STATUS Status;
+
+ if (Handler == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (mEndOfDxe) {
+ return EFI_ACCESS_DENIED;
+ }
+
+ DEBUG ((EFI_D_INFO, "RegisterSetVariableCheckHandler - 0x%x\n", Handler));
+
+ //
+ // Check whether the handler list is enough to store new handler.
+ //
+ if (mNumberOfHandler == mMaxNumberOfHandler) {
+ //
+ // Allocate more resources for new handler.
+ //
+ Status = ReallocateHandlerTable();
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ }
+
+ //
+ // Register new handler into the handler list.
+ //
+ mHandlerTable[mNumberOfHandler] = Handler;
+ mNumberOfHandler ++;
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Internal variable property get.
+
+ @param[in] Name Pointer to the variable name.
+ @param[in] Guid Pointer to the vendor GUID.
+
+ @return Pointer to the property of variable specified by the Name and Guid.
+
+**/
+VAR_CHECK_VARIABLE_PROPERTY *
+InternalVarCheckVariablePropertyGet (
+ IN CHAR16 *Name,
+ IN EFI_GUID *Guid
+ )
+{
+ LIST_ENTRY *Link;
+ VAR_CHECK_VARIABLE_ENTRY *Entry;
+ CHAR16 *VariableName;
+ VAR_CHECK_VARIABLE_PROPERTY *Property;
+
+ Property = NULL;
+ GetUefiDefinedVariableProperty (Name, Guid, FALSE, &Property, NULL);
+ if (Property == NULL) {
+ Property = GetVariableDriverVariableProperty (Name, Guid, NULL);
+ }
+ if (Property != NULL) {
+ return Property;
+ } else {
+ for ( Link = GetFirstNode (&mVarCheckVariableList)
+ ; !IsNull (&mVarCheckVariableList, Link)
+ ; Link = GetNextNode (&mVarCheckVariableList, Link)
+ ) {
+ Entry = BASE_CR (Link, VAR_CHECK_VARIABLE_ENTRY, Link);
+ VariableName = (CHAR16 *) ((UINTN) Entry + sizeof (*Entry));
+ if (CompareGuid (&Entry->Guid, Guid) && (StrCmp (VariableName, Name) == 0)) {
+ return &Entry->VariableProperty;
+ }
+ }
+ }
+
+ return NULL;
+}
+
+/**
+ Variable property set.
+
+ @param[in] Name Pointer to the variable name.
+ @param[in] Guid Pointer to the vendor GUID.
+ @param[in] VariableProperty Pointer to the input variable property.
+
+ @retval EFI_SUCCESS The property of variable specified by the Name and Guid was set successfully.
+ @retval EFI_INVALID_PARAMETER Name, Guid or VariableProperty is NULL, or Name is an empty string,
+ or the fields of VariableProperty are not valid.
+ @retval EFI_ACCESS_DENIED EFI_END_OF_DXE_EVENT_GROUP_GUID or EFI_EVENT_GROUP_READY_TO_BOOT has
+ already been signaled.
+ @retval EFI_OUT_OF_RESOURCES There is not enough resource for the variable property set request.
+
+**/
+EFI_STATUS
+EFIAPI
+VarCheckVariablePropertySet (
+ IN CHAR16 *Name,
+ IN EFI_GUID *Guid,
+ IN VAR_CHECK_VARIABLE_PROPERTY *VariableProperty
+ )
+{
+ EFI_STATUS Status;
+ VAR_CHECK_VARIABLE_ENTRY *Entry;
+ CHAR16 *VariableName;
+ VAR_CHECK_VARIABLE_PROPERTY *Property;
+
+ if (Name == NULL || Name[0] == 0 || Guid == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (VariableProperty == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (VariableProperty->Revision != VAR_CHECK_VARIABLE_PROPERTY_REVISION) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (mEndOfDxe) {
+ return EFI_ACCESS_DENIED;
+ }
+
+ Status = EFI_SUCCESS;
+
+ AcquireLockOnlyAtBootTime (&mVariableModuleGlobal->VariableGlobal.VariableServicesLock);
+
+ Property = InternalVarCheckVariablePropertyGet (Name, Guid);
+ if (Property != NULL) {
+ CopyMem (Property, VariableProperty, sizeof (*VariableProperty));
+ } else {
+ Entry = AllocateRuntimeZeroPool (sizeof (*Entry) + StrSize (Name));
+ if (Entry == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto Done;
+ }
+ VariableName = (CHAR16 *) ((UINTN) Entry + sizeof (*Entry));
+ StrnCpy (VariableName, Name, StrLen (Name));
+ CopyGuid (&Entry->Guid, Guid);
+ CopyMem (&Entry->VariableProperty, VariableProperty, sizeof (*VariableProperty));
+ InsertTailList (&mVarCheckVariableList, &Entry->Link);
+ }
+
+Done:
+ ReleaseLockOnlyAtBootTime (&mVariableModuleGlobal->VariableGlobal.VariableServicesLock);
+
+ return Status;
+}
+
+/**
+ Variable property get.
+
+ @param[in] Name Pointer to the variable name.
+ @param[in] Guid Pointer to the vendor GUID.
+ @param[out] VariableProperty Pointer to the output variable property.
+
+ @retval EFI_SUCCESS The property of variable specified by the Name and Guid was got successfully.
+ @retval EFI_INVALID_PARAMETER Name, Guid or VariableProperty is NULL, or Name is an empty string.
+ @retval EFI_NOT_FOUND The property of variable specified by the Name and Guid was not found.
+
+**/
+EFI_STATUS
+EFIAPI
+VarCheckVariablePropertyGet (
+ IN CHAR16 *Name,
+ IN EFI_GUID *Guid,
+ OUT VAR_CHECK_VARIABLE_PROPERTY *VariableProperty
+ )
+{
+ LIST_ENTRY *Link;
+ VARIABLE_ENTRY *Entry;
+ CHAR16 *VariableName;
+ BOOLEAN Found;
+ VAR_CHECK_VARIABLE_PROPERTY *Property;
+
+ if (Name == NULL || Name[0] == 0 || Guid == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (VariableProperty == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Found = FALSE;
+
+ AcquireLockOnlyAtBootTime (&mVariableModuleGlobal->VariableGlobal.VariableServicesLock);
+
+ Property = InternalVarCheckVariablePropertyGet (Name, Guid);
+ if (Property != NULL) {
+ CopyMem (VariableProperty, Property, sizeof (*VariableProperty));
+ Found = TRUE;
+ }
+
+ for ( Link = GetFirstNode (&mLockedVariableList)
+ ; !IsNull (&mLockedVariableList, Link)
+ ; Link = GetNextNode (&mLockedVariableList, Link)
+ ) {
+ Entry = BASE_CR (Link, VARIABLE_ENTRY, Link);
+ VariableName = (CHAR16 *) ((UINTN) Entry + sizeof (*Entry));
+ if (CompareGuid (&Entry->Guid, Guid) && (StrCmp (VariableName, Name) == 0)) {
+ VariableProperty->Property |= VAR_CHECK_VARIABLE_PROPERTY_READ_ONLY;
+ if (!Found) {
+ VariableProperty->Revision = VAR_CHECK_VARIABLE_PROPERTY_REVISION;
+ Found = TRUE;
+ }
+ }
+ }
+
+ ReleaseLockOnlyAtBootTime (&mVariableModuleGlobal->VariableGlobal.VariableServicesLock);
+
+ return (Found ? EFI_SUCCESS : EFI_NOT_FOUND);
+}
+
diff --git a/SecurityPkg/VariableAuthenticated/RuntimeDxe/Variable.c b/SecurityPkg/VariableAuthenticated/RuntimeDxe/Variable.c
index ac043d9a17..86e3616e30 100644
--- a/SecurityPkg/VariableAuthenticated/RuntimeDxe/Variable.c
+++ b/SecurityPkg/VariableAuthenticated/RuntimeDxe/Variable.c
@@ -16,7 +16,7 @@
VariableServiceSetVariable() should also check authenticate data to avoid buffer overflow,
integer overflow. It should also check attribute to avoid authentication bypass.
-Copyright (c) 2009 - 2014, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2009 - 2015, 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,52 +58,6 @@ BOOLEAN mEndOfDxe = FALSE;
///
BOOLEAN mEnableLocking = TRUE;
-//
-// To prevent name collisions with possible future globally defined variables,
-// other internal firmware data variables that are not defined here must be
-// saved with a unique VendorGuid other than EFI_GLOBAL_VARIABLE or
-// any other GUID defined by the UEFI Specification. Implementations must
-// only permit the creation of variables with a UEFI Specification-defined
-// VendorGuid when these variables are documented in the UEFI Specification.
-//
-GLOBAL_VARIABLE_ENTRY mGlobalVariableList[] = {
- {EFI_LANG_CODES_VARIABLE_NAME, VARIABLE_ATTRIBUTE_BS_RT},
- {EFI_LANG_VARIABLE_NAME, VARIABLE_ATTRIBUTE_NV_BS_RT},
- {EFI_TIME_OUT_VARIABLE_NAME, VARIABLE_ATTRIBUTE_NV_BS_RT},
- {EFI_PLATFORM_LANG_CODES_VARIABLE_NAME, VARIABLE_ATTRIBUTE_BS_RT},
- {EFI_PLATFORM_LANG_VARIABLE_NAME, VARIABLE_ATTRIBUTE_NV_BS_RT},
- {EFI_CON_IN_VARIABLE_NAME, VARIABLE_ATTRIBUTE_NV_BS_RT},
- {EFI_CON_OUT_VARIABLE_NAME, VARIABLE_ATTRIBUTE_NV_BS_RT},
- {EFI_ERR_OUT_VARIABLE_NAME, VARIABLE_ATTRIBUTE_NV_BS_RT},
- {EFI_CON_IN_DEV_VARIABLE_NAME, VARIABLE_ATTRIBUTE_BS_RT},
- {EFI_CON_OUT_DEV_VARIABLE_NAME, VARIABLE_ATTRIBUTE_BS_RT},
- {EFI_ERR_OUT_DEV_VARIABLE_NAME, VARIABLE_ATTRIBUTE_BS_RT},
- {EFI_BOOT_ORDER_VARIABLE_NAME, VARIABLE_ATTRIBUTE_NV_BS_RT},
- {EFI_BOOT_NEXT_VARIABLE_NAME, VARIABLE_ATTRIBUTE_NV_BS_RT},
- {EFI_BOOT_CURRENT_VARIABLE_NAME, VARIABLE_ATTRIBUTE_BS_RT},
- {EFI_BOOT_OPTION_SUPPORT_VARIABLE_NAME, VARIABLE_ATTRIBUTE_BS_RT},
- {EFI_DRIVER_ORDER_VARIABLE_NAME, VARIABLE_ATTRIBUTE_NV_BS_RT},
- {EFI_HW_ERR_REC_SUPPORT_VARIABLE_NAME, VARIABLE_ATTRIBUTE_NV_BS_RT},
- {EFI_SETUP_MODE_NAME, VARIABLE_ATTRIBUTE_BS_RT},
- {EFI_KEY_EXCHANGE_KEY_NAME, VARIABLE_ATTRIBUTE_NV_BS_RT_AT},
- {EFI_PLATFORM_KEY_NAME, VARIABLE_ATTRIBUTE_NV_BS_RT_AT},
- {EFI_SIGNATURE_SUPPORT_NAME, VARIABLE_ATTRIBUTE_BS_RT},
- {EFI_SECURE_BOOT_MODE_NAME, VARIABLE_ATTRIBUTE_BS_RT},
- {EFI_KEK_DEFAULT_VARIABLE_NAME, VARIABLE_ATTRIBUTE_BS_RT},
- {EFI_PK_DEFAULT_VARIABLE_NAME, VARIABLE_ATTRIBUTE_BS_RT},
- {EFI_DB_DEFAULT_VARIABLE_NAME, VARIABLE_ATTRIBUTE_BS_RT},
- {EFI_DBX_DEFAULT_VARIABLE_NAME, VARIABLE_ATTRIBUTE_BS_RT},
- {EFI_DBT_DEFAULT_VARIABLE_NAME, VARIABLE_ATTRIBUTE_BS_RT},
- {EFI_OS_INDICATIONS_SUPPORT_VARIABLE_NAME, VARIABLE_ATTRIBUTE_BS_RT},
- {EFI_OS_INDICATIONS_VARIABLE_NAME, VARIABLE_ATTRIBUTE_NV_BS_RT},
- {EFI_VENDOR_KEYS_VARIABLE_NAME, VARIABLE_ATTRIBUTE_BS_RT},
-};
-GLOBAL_VARIABLE_ENTRY mGlobalVariableList2[] = {
- {L"Boot####", VARIABLE_ATTRIBUTE_NV_BS_RT},
- {L"Driver####", VARIABLE_ATTRIBUTE_NV_BS_RT},
- {L"Key####", VARIABLE_ATTRIBUTE_NV_BS_RT},
-};
-
/**
SecureBoot Hook for auth variable update.
@@ -891,8 +845,8 @@ Reclaim (
HwErrVariableTotalSize += VariableSize;
} else if ((Variable->Attributes & EFI_VARIABLE_HARDWARE_ERROR_RECORD) != EFI_VARIABLE_HARDWARE_ERROR_RECORD) {
CommonVariableTotalSize += VariableSize;
+ }
}
- }
Variable = NextVariable;
}
@@ -926,8 +880,8 @@ Reclaim (
HwErrVariableTotalSize += VariableSize;
} else if ((!IsVolatile) && ((Variable->Attributes & EFI_VARIABLE_HARDWARE_ERROR_RECORD) != EFI_VARIABLE_HARDWARE_ERROR_RECORD)) {
CommonVariableTotalSize += VariableSize;
+ }
}
- }
Variable = NextVariable;
}
@@ -974,9 +928,9 @@ Reclaim (
HwErrVariableTotalSize += VariableSize;
} else if ((!IsVolatile) && ((Variable->Attributes & EFI_VARIABLE_HARDWARE_ERROR_RECORD) != EFI_VARIABLE_HARDWARE_ERROR_RECORD)) {
CommonVariableTotalSize += VariableSize;
+ }
}
}
- }
Variable = NextVariable;
}
@@ -997,7 +951,7 @@ Reclaim (
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))) {
//
@@ -1046,7 +1000,7 @@ Reclaim (
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);
}
@@ -2329,7 +2283,7 @@ UpdateVariable (
}
UpdateVariableInfo (VariableName, VendorGuid, FALSE, FALSE, TRUE, FALSE, FALSE);
FlushHobVariableToFlash (VariableName, VendorGuid);
- }
+ }
goto Done;
}
//
@@ -2414,7 +2368,7 @@ UpdateVariable (
mVariableModuleGlobal->HwErrVariableTotalSize += HEADER_ALIGN (VarSize);
} else {
mVariableModuleGlobal->CommonVariableTotalSize += HEADER_ALIGN (VarSize);
- }
+ }
//
// update the memory copy of Flash region.
//
@@ -2586,63 +2540,6 @@ IsHwErrRecVariable (
}
/**
- This code checks if variable guid is global variable guid first.
- If yes, further check if variable name is in mGlobalVariableList or mGlobalVariableList2 and attributes matched.
-
- @param[in] VariableName Pointer to variable name.
- @param[in] VendorGuid Variable Vendor Guid.
- @param[in] Attributes Attributes of the variable.
-
- @retval EFI_SUCCESS Variable is not global variable, or Variable is global variable, variable name is in the lists and attributes matched.
- @retval EFI_INVALID_PARAMETER Variable is global variable, but variable name is not in the lists or attributes unmatched.
-
-**/
-EFI_STATUS
-EFIAPI
-CheckEfiGlobalVariable (
- IN CHAR16 *VariableName,
- IN EFI_GUID *VendorGuid,
- IN UINT32 Attributes
- )
-{
- UINTN Index;
- UINTN NameLength;
-
- if (CompareGuid (VendorGuid, &gEfiGlobalVariableGuid)){
- //
- // Try list 1, exactly match.
- //
- for (Index = 0; Index < sizeof (mGlobalVariableList)/sizeof (mGlobalVariableList[0]); Index++) {
- if ((StrCmp (mGlobalVariableList[Index].Name, VariableName) == 0) &&
- (Attributes == 0 || (Attributes & (~EFI_VARIABLE_APPEND_WRITE)) == mGlobalVariableList[Index].Attributes)) {
- return EFI_SUCCESS;
- }
- }
-
- //
- // Try list 2.
- //
- NameLength = StrLen (VariableName) - 4;
- for (Index = 0; Index < sizeof (mGlobalVariableList2)/sizeof (mGlobalVariableList2[0]); Index++) {
- if ((StrLen (VariableName) == StrLen (mGlobalVariableList2[Index].Name)) &&
- (StrnCmp (mGlobalVariableList2[Index].Name, VariableName, NameLength) == 0) &&
- IsHexaDecimalDigitCharacter (VariableName[NameLength]) &&
- IsHexaDecimalDigitCharacter (VariableName[NameLength + 1]) &&
- IsHexaDecimalDigitCharacter (VariableName[NameLength + 2]) &&
- IsHexaDecimalDigitCharacter (VariableName[NameLength + 3]) &&
- (Attributes == 0 || (Attributes & (~EFI_VARIABLE_APPEND_WRITE)) == mGlobalVariableList2[Index].Attributes)) {
- return EFI_SUCCESS;
- }
- }
-
- DEBUG ((EFI_D_INFO, "[Variable]: set global variable with invalid variable name or attributes - %g:%s:%x\n", VendorGuid, VariableName, Attributes));
- return EFI_INVALID_PARAMETER;
- }
-
- return EFI_SUCCESS;
-}
-
-/**
Mark a variable that will become read-only after leaving the DXE phase of execution.
@param[in] This The VARIABLE_LOCK_PROTOCOL instance.
@@ -2666,6 +2563,7 @@ VariableLockRequestToLock (
)
{
VARIABLE_ENTRY *Entry;
+ CHAR16 *Name;
if (VariableName == NULL || VariableName[0] == 0 || VendorGuid == NULL) {
return EFI_INVALID_PARAMETER;
@@ -2675,7 +2573,7 @@ VariableLockRequestToLock (
return EFI_ACCESS_DENIED;
}
- Entry = AllocateRuntimePool (sizeof (*Entry) + StrSize (VariableName));
+ Entry = AllocateRuntimeZeroPool (sizeof (*Entry) + StrSize (VariableName));
if (Entry == NULL) {
return EFI_OUT_OF_RESOURCES;
}
@@ -2684,8 +2582,8 @@ VariableLockRequestToLock (
AcquireLockOnlyAtBootTime(&mVariableModuleGlobal->VariableGlobal.VariableServicesLock);
- Entry->Name = (CHAR16 *) (Entry + 1);
- StrCpy (Entry->Name, VariableName);
+ Name = (CHAR16 *) ((UINTN) Entry + sizeof (*Entry));
+ StrnCpy (Name, VariableName, StrLen (VariableName));
CopyGuid (&Entry->Guid, VendorGuid);
InsertTailList (&mLockedVariableList, &Entry->Link);
@@ -2695,39 +2593,6 @@ VariableLockRequestToLock (
}
/**
- This code checks if variable should be treated as read-only variable.
-
- @param[in] VariableName Name of the Variable.
- @param[in] VendorGuid GUID of the Variable.
-
- @retval TRUE This variable is read-only variable.
- @retval FALSE This variable is NOT read-only variable.
-
-**/
-BOOLEAN
-IsReadOnlyVariable (
- IN CHAR16 *VariableName,
- IN EFI_GUID *VendorGuid
- )
-{
- if (CompareGuid (VendorGuid, &gEfiGlobalVariableGuid)) {
- if ((StrCmp (VariableName, EFI_SETUP_MODE_NAME) == 0) ||
- (StrCmp (VariableName, EFI_SIGNATURE_SUPPORT_NAME) == 0) ||
- (StrCmp (VariableName, EFI_SECURE_BOOT_MODE_NAME) == 0) ||
- (StrCmp (VariableName, EFI_VENDOR_KEYS_VARIABLE_NAME) == 0) ||
- (StrCmp (VariableName, EFI_KEK_DEFAULT_VARIABLE_NAME) == 0) ||
- (StrCmp (VariableName, EFI_PK_DEFAULT_VARIABLE_NAME) == 0) ||
- (StrCmp (VariableName, EFI_DB_DEFAULT_VARIABLE_NAME) == 0) ||
- (StrCmp (VariableName, EFI_DBX_DEFAULT_VARIABLE_NAME) == 0) ||
- (StrCmp (VariableName, EFI_DBT_DEFAULT_VARIABLE_NAME) == 0)) {
- return TRUE;
- }
- }
-
- return FALSE;
-}
-
-/**
This code finds variable in storage blocks (Volatile or Non-Volatile).
@@ -3015,6 +2880,7 @@ VariableServiceSetVariable (
UINTN PayloadSize;
LIST_ENTRY *Link;
VARIABLE_ENTRY *Entry;
+ CHAR16 *Name;
//
// Check input parameters.
@@ -3023,10 +2889,6 @@ VariableServiceSetVariable (
return EFI_INVALID_PARAMETER;
}
- if (IsReadOnlyVariable (VariableName, VendorGuid)) {
- return EFI_WRITE_PROTECTED;
- }
-
if (DataSize != 0 && Data == NULL) {
return EFI_INVALID_PARAMETER;
}
@@ -3105,11 +2967,6 @@ VariableServiceSetVariable (
}
}
- Status = CheckEfiGlobalVariable (VariableName, VendorGuid, Attributes);
- if (EFI_ERROR (Status)) {
- return Status;
- }
-
AcquireLockOnlyAtBootTime(&mVariableModuleGlobal->VariableGlobal.VariableServicesLock);
//
@@ -3136,7 +2993,8 @@ VariableServiceSetVariable (
; Link = GetNextNode (&mLockedVariableList, Link)
) {
Entry = BASE_CR (Link, VARIABLE_ENTRY, Link);
- if (CompareGuid (&Entry->Guid, VendorGuid) && (StrCmp (Entry->Name, VariableName) == 0)) {
+ Name = (CHAR16 *) ((UINTN) Entry + sizeof (*Entry));
+ if (CompareGuid (&Entry->Guid, VendorGuid) && (StrCmp (Name, VariableName) == 0)) {
Status = EFI_WRITE_PROTECTED;
DEBUG ((EFI_D_INFO, "[Variable]: Changing readonly variable after leaving DXE phase - %g:%s\n", VendorGuid, VariableName));
goto Done;
@@ -3144,6 +3002,11 @@ VariableServiceSetVariable (
}
}
+ Status = InternalVarCheckSetVariableCheck (VariableName, VendorGuid, Attributes, PayloadSize, (VOID *) ((UINTN) Data + DataSize - PayloadSize));
+ if (EFI_ERROR (Status)) {
+ goto Done;
+ }
+
//
// Check whether the input variable is already existed.
//
@@ -3161,6 +3024,7 @@ VariableServiceSetVariable (
// 2. The only attribute differing is EFI_VARIABLE_APPEND_WRITE
//
Status = EFI_INVALID_PARAMETER;
+ DEBUG ((EFI_D_INFO, "[Variable]: Rewritten a preexisting variable with different attributes - %g:%s\n", VendorGuid, VariableName));
goto Done;
}
}
@@ -3883,8 +3747,9 @@ GetFvbInfoByAddress (
UINTN Index;
EFI_PHYSICAL_ADDRESS FvbBaseAddress;
EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *Fvb;
- EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader;
EFI_FVB_ATTRIBUTES_2 Attributes;
+ UINTN BlockSize;
+ UINTN NumberOfBlocks;
HandleBuffer = NULL;
//
@@ -3922,8 +3787,15 @@ GetFvbInfoByAddress (
continue;
}
- FwVolHeader = (EFI_FIRMWARE_VOLUME_HEADER *) ((UINTN) FvbBaseAddress);
- if ((Address >= FvbBaseAddress) && (Address < (FvbBaseAddress + FwVolHeader->FvLength))) {
+ //
+ // Assume one FVB has one type of BlockSize.
+ //
+ Status = Fvb->GetBlockSize (Fvb, 0, &BlockSize, &NumberOfBlocks);
+ if (EFI_ERROR (Status)) {
+ continue;
+ }
+
+ if ((Address >= FvbBaseAddress) && (Address < (FvbBaseAddress + BlockSize * NumberOfBlocks))) {
if (FvbHandle != NULL) {
*FvbHandle = HandleBuffer[Index];
}
diff --git a/SecurityPkg/VariableAuthenticated/RuntimeDxe/Variable.h b/SecurityPkg/VariableAuthenticated/RuntimeDxe/Variable.h
index c0497afe5e..8591001f8b 100644
--- a/SecurityPkg/VariableAuthenticated/RuntimeDxe/Variable.h
+++ b/SecurityPkg/VariableAuthenticated/RuntimeDxe/Variable.h
@@ -2,7 +2,7 @@
The internal header file includes the common header files, defines
internal structure and functions used by Variable modules.
-Copyright (c) 2009 - 2014, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2009 - 2015, 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 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#include <Protocol/FirmwareVolumeBlock.h>
#include <Protocol/Variable.h>
#include <Protocol/VariableLock.h>
+#include <Protocol/VarCheck.h>
#include <Library/PcdLib.h>
#include <Library/HobLib.h>
#include <Library/UefiDriverEntryPoint.h>
@@ -52,15 +53,13 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS | \
EFI_VARIABLE_APPEND_WRITE)
+#define VARIABLE_ATTRIBUTE_NV_BS (EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS)
#define VARIABLE_ATTRIBUTE_BS_RT (EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS)
#define VARIABLE_ATTRIBUTE_NV_BS_RT (VARIABLE_ATTRIBUTE_BS_RT | EFI_VARIABLE_NON_VOLATILE)
#define VARIABLE_ATTRIBUTE_NV_BS_RT_AT (VARIABLE_ATTRIBUTE_NV_BS_RT | EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS)
-
-typedef struct {
- CHAR16 *Name;
- UINT32 Attributes;
-} GLOBAL_VARIABLE_ENTRY;
-
+#define VARIABLE_ATTRIBUTE_NV_BS_RT_HR (VARIABLE_ATTRIBUTE_NV_BS_RT | EFI_VARIABLE_HARDWARE_ERROR_RECORD)
+#define VARIABLE_ATTRIBUTE_NV_BS_RT_AW (VARIABLE_ATTRIBUTE_NV_BS_RT | EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS)
+
///
/// The size of a 3 character ISO639 language code.
///
@@ -115,9 +114,9 @@ typedef struct {
} VARIABLE_ENTRY_CONSISTENCY;
typedef struct {
- EFI_GUID Guid;
- CHAR16 *Name;
LIST_ENTRY Link;
+ EFI_GUID Guid;
+ //CHAR16 *Name;
} VARIABLE_ENTRY;
/**
@@ -669,6 +668,116 @@ VariableLockRequestToLock (
IN EFI_GUID *VendorGuid
);
+/**
+ Check if a Unicode character is a hexadecimal character.
+
+ This function checks if a Unicode character is a
+ hexadecimal character. The valid hexadecimal character is
+ L'0' to L'9', L'a' to L'f', or L'A' to L'F'.
+
+
+ @param Char The character to check against.
+
+ @retval TRUE If the Char is a hexadecmial character.
+ @retval FALSE If the Char is not a hexadecmial character.
+
+**/
+BOOLEAN
+EFIAPI
+IsHexaDecimalDigitCharacter (
+ IN CHAR16 Char
+ );
+
+/**
+ Internal SetVariable check.
+
+ @param[in] VariableName Name of Variable to set.
+ @param[in] VendorGuid Variable vendor GUID.
+ @param[in] Attributes Attribute value of the variable.
+ @param[in] DataSize Size of Data to set.
+ @param[in] Data Data pointer.
+
+ @retval EFI_SUCCESS The SetVariable check result was success.
+ @retval EFI_INVALID_PARAMETER An invalid combination of attribute bits, name, and GUID were supplied,
+ or the DataSize exceeds the minimum or maximum allowed,
+ or the Data value is not following UEFI spec for UEFI defined variables.
+ @retval EFI_WRITE_PROTECTED The variable in question is read-only.
+ @retval Others The return status from check handler.
+
+**/
+EFI_STATUS
+EFIAPI
+InternalVarCheckSetVariableCheck (
+ IN CHAR16 *VariableName,
+ IN EFI_GUID *VendorGuid,
+ IN UINT32 Attributes,
+ IN UINTN DataSize,
+ IN VOID *Data
+ );
+
+/**
+ Register SetVariable check handler.
+
+ @param[in] Handler Pointer to check handler.
+
+ @retval EFI_SUCCESS The SetVariable check handler was registered successfully.
+ @retval EFI_INVALID_PARAMETER Handler is NULL.
+ @retval EFI_ACCESS_DENIED EFI_END_OF_DXE_EVENT_GROUP_GUID or EFI_EVENT_GROUP_READY_TO_BOOT has
+ already been signaled.
+ @retval EFI_OUT_OF_RESOURCES There is not enough resource for the SetVariable check handler register request.
+ @retval EFI_UNSUPPORTED This interface is not implemented.
+ For example, it is unsupported in VarCheck protocol if both VarCheck and SmmVarCheck protocols are present.
+
+**/
+EFI_STATUS
+EFIAPI
+VarCheckRegisterSetVariableCheckHandler (
+ IN VAR_CHECK_SET_VARIABLE_CHECK_HANDLER Handler
+ );
+
+/**
+ Variable property set.
+
+ @param[in] Name Pointer to the variable name.
+ @param[in] Guid Pointer to the vendor GUID.
+ @param[in] VariableProperty Pointer to the input variable property.
+
+ @retval EFI_SUCCESS The property of variable specified by the Name and Guid was set successfully.
+ @retval EFI_INVALID_PARAMETER Name, Guid or VariableProperty is NULL, or Name is an empty string,
+ or the fields of VariableProperty are not valid.
+ @retval EFI_ACCESS_DENIED EFI_END_OF_DXE_EVENT_GROUP_GUID or EFI_EVENT_GROUP_READY_TO_BOOT has
+ already been signaled.
+ @retval EFI_OUT_OF_RESOURCES There is not enough resource for the variable property set request.
+
+**/
+EFI_STATUS
+EFIAPI
+VarCheckVariablePropertySet (
+ IN CHAR16 *Name,
+ IN EFI_GUID *Guid,
+ IN VAR_CHECK_VARIABLE_PROPERTY *VariableProperty
+ );
+
+/**
+ Variable property get.
+
+ @param[in] Name Pointer to the variable name.
+ @param[in] Guid Pointer to the vendor GUID.
+ @param[out] VariableProperty Pointer to the output variable property.
+
+ @retval EFI_SUCCESS The property of variable specified by the Name and Guid was got successfully.
+ @retval EFI_INVALID_PARAMETER Name, Guid or VariableProperty is NULL, or Name is an empty string.
+ @retval EFI_NOT_FOUND The property of variable specified by the Name and Guid was not found.
+
+**/
+EFI_STATUS
+EFIAPI
+VarCheckVariablePropertyGet (
+ IN CHAR16 *Name,
+ IN EFI_GUID *Guid,
+ OUT VAR_CHECK_VARIABLE_PROPERTY *VariableProperty
+ );
+
extern VARIABLE_MODULE_GLOBAL *mVariableModuleGlobal;
#endif
diff --git a/SecurityPkg/VariableAuthenticated/RuntimeDxe/VariableDxe.c b/SecurityPkg/VariableAuthenticated/RuntimeDxe/VariableDxe.c
index 9d9d6abc52..a1352510eb 100644
--- a/SecurityPkg/VariableAuthenticated/RuntimeDxe/VariableDxe.c
+++ b/SecurityPkg/VariableAuthenticated/RuntimeDxe/VariableDxe.c
@@ -3,7 +3,7 @@
and volatile storage space and install variable architecture protocol.
Copyright (C) 2013, Red Hat, Inc.
-Copyright (c) 2009 - 2014, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2009 - 2015, 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
@@ -23,8 +23,14 @@ EFI_HANDLE mHandle = NULL;
EFI_EVENT mVirtualAddressChangeEvent = NULL;
EFI_EVENT mFtwRegistration = NULL;
extern LIST_ENTRY mLockedVariableList;
+extern LIST_ENTRY mVarCheckVariableList;
+extern UINT32 mNumberOfHandler;
+extern VAR_CHECK_SET_VARIABLE_CHECK_HANDLER *mHandlerTable;
extern BOOLEAN mEndOfDxe;
EDKII_VARIABLE_LOCK_PROTOCOL mVariableLock = { VariableLockRequestToLock };
+EDKII_VAR_CHECK_PROTOCOL mVarCheck = { VarCheckRegisterSetVariableCheckHandler,
+ VarCheckVariablePropertySet,
+ VarCheckVariablePropertyGet };
/**
Return TRUE if ExitBootServices () has been called.
@@ -222,9 +228,8 @@ VariableClassAddressChangeEvent (
IN VOID *Context
)
{
- LIST_ENTRY *Link;
- VARIABLE_ENTRY *Entry;
EFI_STATUS Status;
+ UINTN Index;
EfiConvertPointer (0x0, (VOID **) &mVariableModuleGlobal->FvbInstance->GetBlockSize);
EfiConvertPointer (0x0, (VOID **) &mVariableModuleGlobal->FvbInstance->GetPhysicalAddress);
@@ -239,29 +244,23 @@ VariableClassAddressChangeEvent (
EfiConvertPointer (0x0, (VOID **) &mVariableModuleGlobal->PlatformLang);
EfiConvertPointer (0x0, (VOID **) &mVariableModuleGlobal->VariableGlobal.NonVolatileVariableBase);
EfiConvertPointer (0x0, (VOID **) &mVariableModuleGlobal->VariableGlobal.VolatileVariableBase);
+ EfiConvertPointer (0x0, (VOID **) &mVariableModuleGlobal->VariableGlobal.HobVariableBase);
EfiConvertPointer (0x0, (VOID **) &mVariableModuleGlobal);
EfiConvertPointer (0x0, (VOID **) &mHashCtx);
EfiConvertPointer (0x0, (VOID **) &mSerializationRuntimeBuffer);
EfiConvertPointer (0x0, (VOID **) &mNvVariableCache);
EfiConvertPointer (0x0, (VOID **) &mPubKeyStore);
EfiConvertPointer (0x0, (VOID **) &mCertDbStore);
-
- //
- // in the list of locked variables, convert the name pointers first
- //
- for ( Link = GetFirstNode (&mLockedVariableList)
- ; !IsNull (&mLockedVariableList, Link)
- ; Link = GetNextNode (&mLockedVariableList, Link)
- ) {
- Entry = BASE_CR (Link, VARIABLE_ENTRY, Link);
- Status = EfiConvertPointer (0x0, (VOID **) &Entry->Name);
- ASSERT_EFI_ERROR (Status);
+ EfiConvertPointer (0x0, (VOID **) &mHandlerTable);
+ for (Index = 0; Index < mNumberOfHandler; Index++) {
+ EfiConvertPointer (0x0, (VOID **) &mHandlerTable[Index]);
}
- //
- // second, convert the list itself using UefiRuntimeLib
- //
+
Status = EfiConvertList (0x0, &mLockedVariableList);
ASSERT_EFI_ERROR (Status);
+
+ Status = EfiConvertList (0x0, &mVarCheckVariableList);
+ ASSERT_EFI_ERROR (Status);
}
@@ -447,6 +446,14 @@ VariableServiceInitialize (
);
ASSERT_EFI_ERROR (Status);
+ Status = gBS->InstallMultipleProtocolInterfaces (
+ &mHandle,
+ &gEdkiiVarCheckProtocolGuid,
+ &mVarCheck,
+ NULL
+ );
+ ASSERT_EFI_ERROR (Status);
+
SystemTable->RuntimeServices->GetVariable = VariableServiceGetVariable;
SystemTable->RuntimeServices->GetNextVariableName = VariableServiceGetNextVariableName;
SystemTable->RuntimeServices->SetVariable = VariableServiceSetVariable;
diff --git a/SecurityPkg/VariableAuthenticated/RuntimeDxe/VariableRuntimeDxe.inf b/SecurityPkg/VariableAuthenticated/RuntimeDxe/VariableRuntimeDxe.inf
index 593c906085..8a8d4adef5 100644
--- a/SecurityPkg/VariableAuthenticated/RuntimeDxe/VariableRuntimeDxe.inf
+++ b/SecurityPkg/VariableAuthenticated/RuntimeDxe/VariableRuntimeDxe.inf
@@ -9,7 +9,7 @@
# This external input must be validated carefully to avoid security issues such as
# buffer overflow or integer overflow.
#
-# Copyright (c) 2009 - 2014, Intel Corporation. All rights reserved.<BR>
+# Copyright (c) 2009 - 2015, 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
@@ -44,6 +44,7 @@
AuthService.c
AuthService.h
Measurement.c
+ VarCheck.c
[Packages]
MdePkg/MdePkg.dec
@@ -67,6 +68,7 @@
PlatformSecureLib
HobLib
TpmMeasurementLib
+ DevicePathLib
[Protocols]
gEfiFirmwareVolumeBlockProtocolGuid ## CONSUMES
@@ -76,6 +78,7 @@
gEfiVariableWriteArchProtocolGuid ## PRODUCES
gEfiVariableArchProtocolGuid ## PRODUCES
gEdkiiVariableLockProtocolGuid ## PRODUCES
+ gEdkiiVarCheckProtocolGuid ## PRODUCES
[Guids]
diff --git a/SecurityPkg/VariableAuthenticated/RuntimeDxe/VariableSmm.c b/SecurityPkg/VariableAuthenticated/RuntimeDxe/VariableSmm.c
index 63ac436150..dd1f794cff 100644
--- a/SecurityPkg/VariableAuthenticated/RuntimeDxe/VariableSmm.c
+++ b/SecurityPkg/VariableAuthenticated/RuntimeDxe/VariableSmm.c
@@ -14,7 +14,7 @@
VariableServiceSetVariable(), VariableServiceQueryVariableInfo(), ReclaimForOS(),
SmmVariableGetStatistics() should also do validation based on its own knowledge.
-Copyright (c) 2010 - 2014, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2010 - 2015, 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,6 +30,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#include <Protocol/SmmFaultTolerantWrite.h>
#include <Protocol/SmmAccess2.h>
#include <Protocol/SmmEndOfDxe.h>
+#include <Protocol/SmmVarCheck.h>
#include <Library/SmmServicesTableLib.h>
@@ -119,6 +120,10 @@ EFI_SMM_VARIABLE_PROTOCOL gSmmVariable = {
VariableServiceQueryVariableInfo
};
+EDKII_SMM_VAR_CHECK_PROTOCOL mSmmVarCheck = { VarCheckRegisterSetVariableCheckHandler,
+ VarCheckVariablePropertySet,
+ VarCheckVariablePropertyGet };
+
/**
Return TRUE if ExitBootServices () has been called.
@@ -520,6 +525,7 @@ SmmVariableHandler (
SMM_VARIABLE_COMMUNICATE_QUERY_VARIABLE_INFO *QueryVariableInfo;
VARIABLE_INFO_ENTRY *VariableInfo;
SMM_VARIABLE_COMMUNICATE_LOCK_VARIABLE *VariableToLock;
+ SMM_VARIABLE_COMMUNICATE_VAR_CHECK_VARIABLE_PROPERTY *CommVariableProperty;
UINTN InfoSize;
UINTN NameBufferSize;
UINTN CommBufferPayloadSize;
@@ -754,6 +760,61 @@ SmmVariableHandler (
);
}
break;
+ case SMM_VARIABLE_FUNCTION_VAR_CHECK_VARIABLE_PROPERTY_SET:
+ if (mEndOfDxe) {
+ Status = EFI_ACCESS_DENIED;
+ } else {
+ CommVariableProperty = (SMM_VARIABLE_COMMUNICATE_VAR_CHECK_VARIABLE_PROPERTY *) SmmVariableFunctionHeader->Data;
+ Status = VarCheckVariablePropertySet (
+ CommVariableProperty->Name,
+ &CommVariableProperty->Guid,
+ &CommVariableProperty->VariableProperty
+ );
+ }
+ break;
+ case SMM_VARIABLE_FUNCTION_VAR_CHECK_VARIABLE_PROPERTY_GET:
+ if (CommBufferPayloadSize < OFFSET_OF (SMM_VARIABLE_COMMUNICATE_VAR_CHECK_VARIABLE_PROPERTY, Name)) {
+ DEBUG ((EFI_D_ERROR, "VarCheckVariablePropertyGet: SMM communication buffer size invalid!\n"));
+ return EFI_SUCCESS;
+ }
+ //
+ // Copy the input communicate buffer payload to pre-allocated SMM variable buffer payload.
+ //
+ CopyMem (mVariableBufferPayload, SmmVariableFunctionHeader->Data, CommBufferPayloadSize);
+ CommVariableProperty = (SMM_VARIABLE_COMMUNICATE_VAR_CHECK_VARIABLE_PROPERTY *) mVariableBufferPayload;
+ if ((UINTN) (~0) - CommVariableProperty->NameSize < OFFSET_OF (SMM_VARIABLE_COMMUNICATE_VAR_CHECK_VARIABLE_PROPERTY, Name)) {
+ //
+ // Prevent InfoSize overflow happen
+ //
+ Status = EFI_ACCESS_DENIED;
+ goto EXIT;
+ }
+ InfoSize = OFFSET_OF (SMM_VARIABLE_COMMUNICATE_VAR_CHECK_VARIABLE_PROPERTY, Name) + CommVariableProperty->NameSize;
+
+ //
+ // SMRAM range check already covered before
+ //
+ if (InfoSize > CommBufferPayloadSize) {
+ DEBUG ((EFI_D_ERROR, "VarCheckVariablePropertyGet: Data size exceed communication buffer size limit!\n"));
+ Status = EFI_ACCESS_DENIED;
+ goto EXIT;
+ }
+
+ if (CommVariableProperty->NameSize < sizeof (CHAR16) || CommVariableProperty->Name[CommVariableProperty->NameSize/sizeof (CHAR16) - 1] != L'\0') {
+ //
+ // Make sure VariableName is A Null-terminated string.
+ //
+ Status = EFI_ACCESS_DENIED;
+ goto EXIT;
+ }
+
+ Status = VarCheckVariablePropertyGet (
+ CommVariableProperty->Name,
+ &CommVariableProperty->Guid,
+ &CommVariableProperty->VariableProperty
+ );
+ CopyMem (SmmVariableFunctionHeader->Data, mVariableBufferPayload, CommBufferPayloadSize);
+ break;
default:
Status = EFI_UNSUPPORTED;
@@ -911,6 +972,14 @@ VariableServiceInitialize (
);
ASSERT_EFI_ERROR (Status);
+ Status = gSmst->SmmInstallProtocolInterface (
+ &VariableHandle,
+ &gEdkiiSmmVarCheckProtocolGuid,
+ EFI_NATIVE_INTERFACE,
+ &mSmmVarCheck
+ );
+ ASSERT_EFI_ERROR (Status);
+
//
// Get SMRAM information
//
@@ -934,7 +1003,7 @@ VariableServiceInitialize (
mSmramRangeCount = Size / sizeof (EFI_SMRAM_DESCRIPTOR);
mVariableBufferPayloadSize = MAX (PcdGet32 (PcdMaxVariableSize), PcdGet32 (PcdMaxHardwareErrorVariableSize)) +
- OFFSET_OF (SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE, Name) - sizeof (VARIABLE_HEADER);
+ OFFSET_OF (SMM_VARIABLE_COMMUNICATE_VAR_CHECK_VARIABLE_PROPERTY, Name) - sizeof (VARIABLE_HEADER);
Status = gSmst->SmmAllocatePool (
EfiRuntimeServicesData,
diff --git a/SecurityPkg/VariableAuthenticated/RuntimeDxe/VariableSmm.inf b/SecurityPkg/VariableAuthenticated/RuntimeDxe/VariableSmm.inf
index 1987764d80..a7d0505e21 100644
--- a/SecurityPkg/VariableAuthenticated/RuntimeDxe/VariableSmm.inf
+++ b/SecurityPkg/VariableAuthenticated/RuntimeDxe/VariableSmm.inf
@@ -18,7 +18,7 @@
# may not be modified without authorization. If platform fails to protect these resources,
# the authentication service provided in this driver will be broken, and the behavior is undefined.
#
-# Copyright (c) 2010 - 2014, Intel Corporation. All rights reserved.<BR>
+# Copyright (c) 2010 - 2015, 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
@@ -50,6 +50,7 @@
Variable.c
VariableSmm.c
AuthService.c
+ VarCheck.c
Variable.h
AuthService.h
@@ -72,6 +73,8 @@
BaseCryptLib
PlatformSecureLib
HobLib
+ PcdLib
+ DevicePathLib
[Protocols]
gEfiSmmFirmwareVolumeBlockProtocolGuid ## CONSUMES
@@ -84,7 +87,8 @@
## CONSUMES
## NOTIFY
gEfiSmmFaultTolerantWriteProtocolGuid
- gEfiSmmEndOfDxeProtocolGuid ## NOTIFY
+ gEfiSmmEndOfDxeProtocolGuid ## NOTIFY
+ gEdkiiSmmVarCheckProtocolGuid ## PRODUCES
[Guids]
## PRODUCES ## GUID # Variable store header
diff --git a/SecurityPkg/VariableAuthenticated/RuntimeDxe/VariableSmmRuntimeDxe.c b/SecurityPkg/VariableAuthenticated/RuntimeDxe/VariableSmmRuntimeDxe.c
index 7f4380be42..3e2ed08972 100644
--- a/SecurityPkg/VariableAuthenticated/RuntimeDxe/VariableSmmRuntimeDxe.c
+++ b/SecurityPkg/VariableAuthenticated/RuntimeDxe/VariableSmmRuntimeDxe.c
@@ -13,7 +13,7 @@
InitCommunicateBuffer() is really function to check the variable data size.
-Copyright (c) 2010 - 2014, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2010 - 2015, 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,6 +30,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#include <Protocol/SmmCommunication.h>
#include <Protocol/SmmVariable.h>
#include <Protocol/VariableLock.h>
+#include <Protocol/VarCheck.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Library/UefiRuntimeServicesTableLib.h>
@@ -56,6 +57,7 @@ UINTN mVariableBufferSize;
UINTN mVariableBufferPayloadSize;
EFI_LOCK mVariableServicesLock;
EDKII_VARIABLE_LOCK_PROTOCOL mVariableLock;
+EDKII_VAR_CHECK_PROTOCOL mVarCheck;
/**
SecureBoot Hook for SetVariable.
@@ -259,6 +261,180 @@ Done:
}
/**
+ Register SetVariable check handler.
+
+ @param[in] Handler Pointer to check handler.
+
+ @retval EFI_SUCCESS The SetVariable check handler was registered successfully.
+ @retval EFI_INVALID_PARAMETER Handler is NULL.
+ @retval EFI_ACCESS_DENIED EFI_END_OF_DXE_EVENT_GROUP_GUID or EFI_EVENT_GROUP_READY_TO_BOOT has
+ already been signaled.
+ @retval EFI_OUT_OF_RESOURCES There is not enough resource for the SetVariable check handler register request.
+ @retval EFI_UNSUPPORTED This interface is not implemented.
+ For example, it is unsupported in VarCheck protocol if both VarCheck and SmmVarCheck protocols are present.
+
+**/
+EFI_STATUS
+EFIAPI
+VarCheckRegisterSetVariableCheckHandler (
+ IN VAR_CHECK_SET_VARIABLE_CHECK_HANDLER Handler
+ )
+{
+ return EFI_UNSUPPORTED;
+}
+
+/**
+ Variable property set.
+
+ @param[in] Name Pointer to the variable name.
+ @param[in] Guid Pointer to the vendor GUID.
+ @param[in] VariableProperty Pointer to the input variable property.
+
+ @retval EFI_SUCCESS The property of variable specified by the Name and Guid was set successfully.
+ @retval EFI_INVALID_PARAMETER Name, Guid or VariableProperty is NULL, or Name is an empty string,
+ or the fields of VariableProperty are not valid.
+ @retval EFI_ACCESS_DENIED EFI_END_OF_DXE_EVENT_GROUP_GUID or EFI_EVENT_GROUP_READY_TO_BOOT has
+ already been signaled.
+ @retval EFI_OUT_OF_RESOURCES There is not enough resource for the variable property set request.
+
+**/
+EFI_STATUS
+EFIAPI
+VarCheckVariablePropertySet (
+ IN CHAR16 *Name,
+ IN EFI_GUID *Guid,
+ IN VAR_CHECK_VARIABLE_PROPERTY *VariableProperty
+ )
+{
+ EFI_STATUS Status;
+ UINTN VariableNameSize;
+ UINTN PayloadSize;
+ SMM_VARIABLE_COMMUNICATE_VAR_CHECK_VARIABLE_PROPERTY *CommVariableProperty;
+
+ if (Name == NULL || Name[0] == 0 || Guid == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (VariableProperty == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (VariableProperty->Revision != VAR_CHECK_VARIABLE_PROPERTY_REVISION) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ VariableNameSize = StrSize (Name);
+ CommVariableProperty = NULL;
+
+ //
+ // If VariableName exceeds SMM payload limit. Return failure
+ //
+ if (VariableNameSize > mVariableBufferPayloadSize - OFFSET_OF (SMM_VARIABLE_COMMUNICATE_VAR_CHECK_VARIABLE_PROPERTY, Name)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ AcquireLockOnlyAtBootTime (&mVariableServicesLock);
+
+ //
+ // Init the communicate buffer. The buffer data size is:
+ // SMM_COMMUNICATE_HEADER_SIZE + SMM_VARIABLE_COMMUNICATE_HEADER_SIZE + PayloadSize.
+ //
+ PayloadSize = OFFSET_OF (SMM_VARIABLE_COMMUNICATE_VAR_CHECK_VARIABLE_PROPERTY, Name) + VariableNameSize;
+ Status = InitCommunicateBuffer ((VOID **) &CommVariableProperty, PayloadSize, SMM_VARIABLE_FUNCTION_VAR_CHECK_VARIABLE_PROPERTY_SET);
+ if (EFI_ERROR (Status)) {
+ goto Done;
+ }
+ ASSERT (CommVariableProperty != NULL);
+
+ CopyGuid (&CommVariableProperty->Guid, Guid);
+ CopyMem (&CommVariableProperty->VariableProperty, VariableProperty, sizeof (*VariableProperty));
+ CommVariableProperty->NameSize = VariableNameSize;
+ CopyMem (CommVariableProperty->Name, Name, CommVariableProperty->NameSize);
+
+ //
+ // Send data to SMM.
+ //
+ Status = SendCommunicateBuffer (PayloadSize);
+
+Done:
+ ReleaseLockOnlyAtBootTime (&mVariableServicesLock);
+ return Status;
+}
+
+/**
+ Variable property get.
+
+ @param[in] Name Pointer to the variable name.
+ @param[in] Guid Pointer to the vendor GUID.
+ @param[out] VariableProperty Pointer to the output variable property.
+
+ @retval EFI_SUCCESS The property of variable specified by the Name and Guid was got successfully.
+ @retval EFI_INVALID_PARAMETER Name, Guid or VariableProperty is NULL, or Name is an empty string.
+ @retval EFI_NOT_FOUND The property of variable specified by the Name and Guid was not found.
+
+**/
+EFI_STATUS
+EFIAPI
+VarCheckVariablePropertyGet (
+ IN CHAR16 *Name,
+ IN EFI_GUID *Guid,
+ OUT VAR_CHECK_VARIABLE_PROPERTY *VariableProperty
+ )
+{
+ EFI_STATUS Status;
+ UINTN VariableNameSize;
+ UINTN PayloadSize;
+ SMM_VARIABLE_COMMUNICATE_VAR_CHECK_VARIABLE_PROPERTY *CommVariableProperty;
+
+ if (Name == NULL || Name[0] == 0 || Guid == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (VariableProperty == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ VariableNameSize = StrSize (Name);
+ CommVariableProperty = NULL;
+
+ //
+ // If VariableName exceeds SMM payload limit. Return failure
+ //
+ if (VariableNameSize > mVariableBufferPayloadSize - OFFSET_OF (SMM_VARIABLE_COMMUNICATE_VAR_CHECK_VARIABLE_PROPERTY, Name)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ AcquireLockOnlyAtBootTime (&mVariableServicesLock);
+
+ //
+ // Init the communicate buffer. The buffer data size is:
+ // SMM_COMMUNICATE_HEADER_SIZE + SMM_VARIABLE_COMMUNICATE_HEADER_SIZE + PayloadSize.
+ //
+ PayloadSize = OFFSET_OF (SMM_VARIABLE_COMMUNICATE_VAR_CHECK_VARIABLE_PROPERTY, Name) + VariableNameSize;
+ Status = InitCommunicateBuffer ((VOID **) &CommVariableProperty, PayloadSize, SMM_VARIABLE_FUNCTION_VAR_CHECK_VARIABLE_PROPERTY_GET);
+ if (EFI_ERROR (Status)) {
+ goto Done;
+ }
+ ASSERT (CommVariableProperty != NULL);
+
+ CopyGuid (&CommVariableProperty->Guid, Guid);
+ CommVariableProperty->NameSize = VariableNameSize;
+ CopyMem (CommVariableProperty->Name, Name, CommVariableProperty->NameSize);
+
+ //
+ // Send data to SMM.
+ //
+ Status = SendCommunicateBuffer (PayloadSize);
+ if (Status == EFI_SUCCESS) {
+ CopyMem (VariableProperty, &CommVariableProperty->VariableProperty, sizeof (*VariableProperty));
+ }
+
+Done:
+ ReleaseLockOnlyAtBootTime (&mVariableServicesLock);
+ return Status;
+}
+
+/**
This code finds variable in storage blocks (Volatile or Non-Volatile).
Caution: This function may receive untrusted input.
@@ -756,7 +932,7 @@ SmmVariableReady (
// Allocate memory for variable communicate buffer.
//
mVariableBufferPayloadSize = MAX (PcdGet32 (PcdMaxVariableSize), PcdGet32 (PcdMaxHardwareErrorVariableSize)) +
- OFFSET_OF (SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE, Name) - sizeof (VARIABLE_HEADER);
+ OFFSET_OF (SMM_VARIABLE_COMMUNICATE_VAR_CHECK_VARIABLE_PROPERTY, Name) - sizeof (VARIABLE_HEADER);
mVariableBufferSize = SMM_COMMUNICATE_HEADER_SIZE + SMM_VARIABLE_COMMUNICATE_HEADER_SIZE + mVariableBufferPayloadSize;
mVariableBuffer = AllocateRuntimePool (mVariableBufferSize);
ASSERT (mVariableBuffer != NULL);
@@ -855,6 +1031,17 @@ VariableSmmRuntimeInitialize (
);
ASSERT_EFI_ERROR (Status);
+ mVarCheck.RegisterSetVariableCheckHandler = VarCheckRegisterSetVariableCheckHandler;
+ mVarCheck.VariablePropertySet = VarCheckVariablePropertySet;
+ mVarCheck.VariablePropertyGet = VarCheckVariablePropertyGet;
+ Status = gBS->InstallMultipleProtocolInterfaces (
+ &mHandle,
+ &gEdkiiVarCheckProtocolGuid,
+ &mVarCheck,
+ NULL
+ );
+ ASSERT_EFI_ERROR (Status);
+
//
// Smm variable service is ready
//
diff --git a/SecurityPkg/VariableAuthenticated/RuntimeDxe/VariableSmmRuntimeDxe.inf b/SecurityPkg/VariableAuthenticated/RuntimeDxe/VariableSmmRuntimeDxe.inf
index ca60274339..e48a0f16f6 100644
--- a/SecurityPkg/VariableAuthenticated/RuntimeDxe/VariableSmmRuntimeDxe.inf
+++ b/SecurityPkg/VariableAuthenticated/RuntimeDxe/VariableSmmRuntimeDxe.inf
@@ -13,7 +13,7 @@
# may not be modified without authorization. If platform fails to protect these resources,
# the authentication service provided in this driver will be broken, and the behavior is undefined.
#
-# Copyright (c) 2010 - 2014, Intel Corporation. All rights reserved.<BR>
+# Copyright (c) 2010 - 2015, 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
@@ -70,6 +70,7 @@
## NOTIFY
## UNDEFINED # Used to do smm communication
gEfiSmmVariableProtocolGuid
+ gEdkiiVarCheckProtocolGuid ## PRODUCES
[Guids]
gEfiEventVirtualAddressChangeGuid ## CONSUMES ## Event
@@ -92,7 +93,6 @@
[Pcd]
gEfiMdeModulePkgTokenSpaceGuid.PcdMaxVariableSize ## CONSUMES
gEfiMdeModulePkgTokenSpaceGuid.PcdMaxHardwareErrorVariableSize ## CONSUMES
- gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase ## CONSUMES
[Depex]
gEfiSmmCommunicationProtocolGuid
diff --git a/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigImpl.c b/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigImpl.c
index 517d9d9904..5b8ae7e8d8 100644
--- a/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigImpl.c
+++ b/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigImpl.c
@@ -1073,6 +1073,8 @@ CalculateCertHash (
BOOLEAN Status;
VOID *HashCtx;
UINTN CtxSize;
+ UINT8 *TBSCert;
+ UINTN TBSCertSize;
HashCtx = NULL;
Status = FALSE;
@@ -1082,6 +1084,13 @@ CalculateCertHash (
}
//
+ // Retrieve the TBSCertificate for Hash Calculation.
+ //
+ if (!X509GetTBSCert (CertData, CertSize, &TBSCert, &TBSCertSize)) {
+ return FALSE;
+ }
+
+ //
// 1. Initialize context of hash.
//
CtxSize = mHash[HashAlg].GetContextSize ();
@@ -1099,7 +1108,7 @@ CalculateCertHash (
//
// 3. Calculate the hash.
//
- Status = mHash[HashAlg].HashUpdate (HashCtx, CertData, CertSize);
+ Status = mHash[HashAlg].HashUpdate (HashCtx, TBSCert, TBSCertSize);
if (!Status) {
goto Done;
}
diff --git a/ShellBinPkg/MinUefiShell/Ia32/Shell.efi b/ShellBinPkg/MinUefiShell/Ia32/Shell.efi
index 4a1e80b6eb..83e03eb356 100644
--- a/ShellBinPkg/MinUefiShell/Ia32/Shell.efi
+++ b/ShellBinPkg/MinUefiShell/Ia32/Shell.efi
Binary files differ
diff --git a/ShellBinPkg/MinUefiShell/X64/Shell.efi b/ShellBinPkg/MinUefiShell/X64/Shell.efi
index 8be7c7dfc7..1b8515223a 100644
--- a/ShellBinPkg/MinUefiShell/X64/Shell.efi
+++ b/ShellBinPkg/MinUefiShell/X64/Shell.efi
Binary files differ
diff --git a/ShellBinPkg/ReadMe.txt b/ShellBinPkg/ReadMe.txt
index 1d9767b3f1..2e3355b3e7 100644
--- a/ShellBinPkg/ReadMe.txt
+++ b/ShellBinPkg/ReadMe.txt
@@ -2,7 +2,7 @@
OVERVIEW
============================================================================
The binaries of ShellBinPkg are generated with ShellPkg project and built with
-BaseTools Package (r16163). The binaries are built with no debug information
+BaseTools Package (r16473). The binaries are built with no debug information
by building with "RELEASE" target.
The following steps can help to re-generate these binaries for customization:
diff --git a/ShellBinPkg/UefiShell/Ia32/Shell.efi b/ShellBinPkg/UefiShell/Ia32/Shell.efi
index 26b429a1d0..08693063e1 100644
--- a/ShellBinPkg/UefiShell/Ia32/Shell.efi
+++ b/ShellBinPkg/UefiShell/Ia32/Shell.efi
Binary files differ
diff --git a/ShellBinPkg/UefiShell/X64/Shell.efi b/ShellBinPkg/UefiShell/X64/Shell.efi
index a376265065..50746f14b3 100644
--- a/ShellBinPkg/UefiShell/X64/Shell.efi
+++ b/ShellBinPkg/UefiShell/X64/Shell.efi
Binary files differ
diff --git a/ShellPkg/Application/Shell/Shell.c b/ShellPkg/Application/Shell/Shell.c
index 41fa78004d..695880197b 100644
--- a/ShellPkg/Application/Shell/Shell.c
+++ b/ShellPkg/Application/Shell/Shell.c
@@ -101,6 +101,95 @@ TrimSpaces(
}
/**
+ Parse for the next instance of one string within another string. Can optionally make sure that
+ the string was not escaped (^ character) per the shell specification.
+
+ @param[in] SourceString The string to search within
+ @param[in] FindString The string to look for
+ @param[in] CheckForEscapeCharacter TRUE to skip escaped instances of FinfString, otherwise will return even escaped instances
+**/
+CHAR16*
+EFIAPI
+FindNextInstance(
+ IN CONST CHAR16 *SourceString,
+ IN CONST CHAR16 *FindString,
+ IN CONST BOOLEAN CheckForEscapeCharacter
+ )
+{
+ CHAR16 *Temp;
+ if (SourceString == NULL) {
+ return (NULL);
+ }
+ Temp = StrStr(SourceString, FindString);
+
+ //
+ // If nothing found, or we dont care about escape characters
+ //
+ if (Temp == NULL || !CheckForEscapeCharacter) {
+ return (Temp);
+ }
+
+ //
+ // If we found an escaped character, try again on the remainder of the string
+ //
+ if ((Temp > (SourceString)) && *(Temp-1) == L'^') {
+ return FindNextInstance(Temp+1, FindString, CheckForEscapeCharacter);
+ }
+
+ //
+ // we found the right character
+ //
+ return (Temp);
+}
+
+/**
+ Check whether the string between a pair of % is a valid envifronment variable name.
+
+ @param[in] BeginPercent pointer to the first percent.
+ @param[in] EndPercent pointer to the last percent.
+
+ @retval TRUE is a valid environment variable name.
+ @retval FALSE is NOT a valid environment variable name.
+**/
+BOOLEAN
+IsValidEnvironmentVariableName(
+ IN CONST CHAR16 *BeginPercent,
+ IN CONST CHAR16 *EndPercent
+ )
+{
+ CONST CHAR16 *Walker;
+
+ Walker = NULL;
+
+ ASSERT (BeginPercent != NULL);
+ ASSERT (EndPercent != NULL);
+ ASSERT (BeginPercent < EndPercent);
+
+ if ((BeginPercent + 1) == EndPercent) {
+ return FALSE;
+ }
+
+ for (Walker = BeginPercent + 1; Walker < EndPercent; Walker++) {
+ if (
+ (*Walker >= L'0' && *Walker <= L'9') ||
+ (*Walker >= L'A' && *Walker <= L'Z') ||
+ (*Walker >= L'a' && *Walker <= L'z') ||
+ (*Walker == L'_')
+ ) {
+ if (Walker == BeginPercent + 1 && (*Walker >= L'0' && *Walker <= L'9')) {
+ return FALSE;
+ } else {
+ continue;
+ }
+ } else {
+ return FALSE;
+ }
+ }
+
+ return TRUE;
+}
+
+/**
Find a command line contains a split operation
@param[in] CmdLine The command line to parse.
@@ -142,7 +231,39 @@ ContainsSplit(
)
{
CONST CHAR16 *TempSpot;
- TempSpot = FindSplit(CmdLine);
+ CONST CHAR16 *FirstQuote;
+ CONST CHAR16 *SecondQuote;
+
+ FirstQuote = FindNextInstance (CmdLine, L"\"", TRUE);
+ SecondQuote = NULL;
+ TempSpot = FindSplit(CmdLine);
+
+ if (FirstQuote == NULL ||
+ TempSpot == NULL ||
+ TempSpot == CHAR_NULL ||
+ FirstQuote > TempSpot
+ ) {
+ return (BOOLEAN) ((TempSpot != NULL) && (*TempSpot != CHAR_NULL));
+ }
+
+ while ((TempSpot != NULL) && (*TempSpot != CHAR_NULL)) {
+ if (FirstQuote == NULL || FirstQuote > TempSpot) {
+ break;
+ }
+ SecondQuote = FindNextInstance (FirstQuote + 1, L"\"", TRUE);
+ if (SecondQuote == NULL) {
+ break;
+ }
+ if (SecondQuote < TempSpot) {
+ FirstQuote = FindNextInstance (SecondQuote + 1, L"\"", TRUE);
+ continue;
+ } else {
+ FirstQuote = FindNextInstance (SecondQuote + 1, L"\"", TRUE);
+ TempSpot = FindSplit(TempSpot + 1);
+ continue;
+ }
+ }
+
return (BOOLEAN) ((TempSpot != NULL) && (*TempSpot != CHAR_NULL));
}
@@ -1233,48 +1354,6 @@ ShellConvertAlias(
}
/**
- Parse for the next instance of one string within another string. Can optionally make sure that
- the string was not escaped (^ character) per the shell specification.
-
- @param[in] SourceString The string to search within
- @param[in] FindString The string to look for
- @param[in] CheckForEscapeCharacter TRUE to skip escaped instances of FinfString, otherwise will return even escaped instances
-**/
-CHAR16*
-EFIAPI
-FindNextInstance(
- IN CONST CHAR16 *SourceString,
- IN CONST CHAR16 *FindString,
- IN CONST BOOLEAN CheckForEscapeCharacter
- )
-{
- CHAR16 *Temp;
- if (SourceString == NULL) {
- return (NULL);
- }
- Temp = StrStr(SourceString, FindString);
-
- //
- // If nothing found, or we dont care about escape characters
- //
- if (Temp == NULL || !CheckForEscapeCharacter) {
- return (Temp);
- }
-
- //
- // If we found an escaped character, try again on the remainder of the string
- //
- if ((Temp > (SourceString)) && *(Temp-1) == L'^') {
- return FindNextInstance(Temp+1, FindString, CheckForEscapeCharacter);
- }
-
- //
- // we found the right character
- //
- return (Temp);
-}
-
-/**
This function will eliminate unreplaced (and therefore non-found) environment variables.
@param[in,out] CmdLine The command line to update.
@@ -1323,14 +1402,17 @@ StripUnreplacedEnvironmentVariables(
}
ASSERT(FirstPercent < FirstQuote);
if (SecondPercent < FirstQuote) {
- FirstPercent[0] = L'\"';
- SecondPercent[0] = L'\"';
-
- //
- // We need to remove from FirstPercent to SecondPercent
- //
- CopyMem(FirstPercent + 1, SecondPercent, StrSize(SecondPercent));
- CurrentLocator = FirstPercent + 2;
+ if (IsValidEnvironmentVariableName(FirstPercent, SecondPercent)) {
+ //
+ // We need to remove from FirstPercent to SecondPercent
+ //
+ CopyMem(FirstPercent, SecondPercent + 1, StrSize(SecondPercent + 1));
+ //
+ // dont need to update the locator. both % characters are gone.
+ //
+ } else {
+ CurrentLocator = SecondPercent + 1;
+ }
continue;
}
ASSERT(FirstQuote < SecondPercent);
diff --git a/ShellPkg/Library/UefiHandleParsingLib/UefiHandleParsingLib.c b/ShellPkg/Library/UefiHandleParsingLib/UefiHandleParsingLib.c
index 9c6cf61af5..9a2daa9ca4 100644
--- a/ShellPkg/Library/UefiHandleParsingLib/UefiHandleParsingLib.c
+++ b/ShellPkg/Library/UefiHandleParsingLib/UefiHandleParsingLib.c
@@ -349,14 +349,19 @@ PciRootBridgeIoDumpInformation(
}
Temp = HiiGetString(mHandleParsingHiiHandle, STRING_TOKEN(STR_PCIRB_DUMP_PH), NULL);
- ASSERT (Temp != NULL);
+ if (Temp == NULL) {
+ return NULL;
+ }
Temp2 = CatSPrint(L"\r\n", Temp, PciRootBridgeIo->ParentHandle);
FreePool(Temp);
RetVal = Temp2;
Temp2 = NULL;
Temp = HiiGetString(mHandleParsingHiiHandle, STRING_TOKEN(STR_PCIRB_DUMP_SEG), NULL);
- ASSERT (Temp != NULL);
+ if (Temp == NULL) {
+ SHELL_FREE_NON_NULL(RetVal);
+ return NULL;
+ }
Temp2 = CatSPrint(RetVal, Temp, PciRootBridgeIo->SegmentNumber);
FreePool(Temp);
FreePool(RetVal);
@@ -368,7 +373,10 @@ PciRootBridgeIoDumpInformation(
Status = PciRootBridgeIo->GetAttributes (PciRootBridgeIo, &Supports, &Attributes);
if (!EFI_ERROR(Status)) {
Temp = HiiGetString(mHandleParsingHiiHandle, STRING_TOKEN(STR_PCIRB_DUMP_ATT), NULL);
- ASSERT (Temp != NULL);
+ if (Temp == NULL) {
+ SHELL_FREE_NON_NULL(RetVal);
+ return NULL;
+ }
Temp2 = CatSPrint(RetVal, Temp, Attributes);
FreePool(Temp);
FreePool(RetVal);
@@ -376,7 +384,10 @@ PciRootBridgeIoDumpInformation(
Temp2 = NULL;
Temp = HiiGetString(mHandleParsingHiiHandle, STRING_TOKEN(STR_PCIRB_DUMP_SUPPORTS), NULL);
- ASSERT (Temp != NULL);
+ if (Temp == NULL) {
+ SHELL_FREE_NON_NULL(RetVal);
+ return NULL;
+ }
Temp2 = CatSPrint(RetVal, Temp, Supports);
FreePool(Temp);
FreePool(RetVal);
@@ -388,7 +399,10 @@ PciRootBridgeIoDumpInformation(
Status = PciRootBridgeIo->Configuration (PciRootBridgeIo, (VOID **) &Configuration);
if (!EFI_ERROR(Status) && Configuration != NULL) {
Temp = HiiGetString(mHandleParsingHiiHandle, STRING_TOKEN(STR_PCIRB_DUMP_TITLE), NULL);
- ASSERT (Temp != NULL);
+ if (Temp == NULL) {
+ SHELL_FREE_NON_NULL(RetVal);
+ return NULL;
+ }
Temp2 = CatSPrint(RetVal, Temp, Supports);
FreePool(Temp);
FreePool(RetVal);
@@ -611,6 +625,9 @@ AdapterInformationDumpInformation (
return (CatSPrint(NULL, L"AdapterInfo"));
}
+ InfoTypesBuffer = NULL;
+ InformationBlock = NULL;
+
//
// Allocate print buffer to store data
//
@@ -643,18 +660,31 @@ AdapterInformationDumpInformation (
);
if (EFI_ERROR (Status)) {
TempStr = HiiGetString (mHandleParsingHiiHandle, STRING_TOKEN(STR_GET_SUPP_TYPES_FAILED), NULL);
- RetVal = CatSPrint (RetVal, TempStr, Status);
+ if (TempStr != NULL) {
+ RetVal = CatSPrint (RetVal, TempStr, Status);
+ } else {
+ goto ERROR_EXIT;
+ }
} else {
TempStr = HiiGetString (mHandleParsingHiiHandle, STRING_TOKEN(STR_SUPP_TYPE_HEADER), NULL);
+ if (TempStr == NULL) {
+ goto ERROR_EXIT;
+ }
RetVal = CatSPrint (RetVal, TempStr);
SHELL_FREE_NON_NULL (TempStr);
for (GuidIndex = 0; GuidIndex < InfoTypesBufferCount; GuidIndex++) {
TempStr = HiiGetString (mHandleParsingHiiHandle, STRING_TOKEN(STR_GUID_NUMBER), NULL);
+ if (TempStr == NULL) {
+ goto ERROR_EXIT;
+ }
RetVal = CatSPrint (RetVal, TempStr, (GuidIndex + 1), InfoTypesBuffer[GuidIndex]);
SHELL_FREE_NON_NULL (TempStr);
TempStr = HiiGetString (mHandleParsingHiiHandle, STRING_TOKEN(STR_GUID_STRING), NULL);
+ if (TempStr == NULL) {
+ goto ERROR_EXIT;
+ }
if (CompareGuid (&InfoTypesBuffer[GuidIndex], &gEfiAdapterInfoMediaStateGuid)) {
RetVal = CatSPrint (RetVal, TempStr, L"gEfiAdapterInfoMediaStateGuid");
@@ -694,10 +724,16 @@ AdapterInformationDumpInformation (
if (EFI_ERROR (Status)) {
TempStr = HiiGetString (mHandleParsingHiiHandle, STRING_TOKEN(STR_GETINFO_FAILED), NULL);
+ if (TempStr == NULL) {
+ goto ERROR_EXIT;
+ }
RetVal = CatSPrint (RetVal, TempStr, Status);
} else {
if (CompareGuid (&InfoTypesBuffer[GuidIndex], &gEfiAdapterInfoMediaStateGuid)) {
TempStr = HiiGetString (mHandleParsingHiiHandle, STRING_TOKEN(STR_MEDIA_STATE), NULL);
+ if (TempStr == NULL) {
+ goto ERROR_EXIT;
+ }
RetVal = CatSPrint (
RetVal,
TempStr,
@@ -706,6 +742,9 @@ AdapterInformationDumpInformation (
);
} else if (CompareGuid (&InfoTypesBuffer[GuidIndex], &gEfiAdapterInfoNetworkBootGuid)) {
TempStr = HiiGetString (mHandleParsingHiiHandle, STRING_TOKEN(STR_NETWORK_BOOT_INFO), NULL);
+ if (TempStr == NULL) {
+ goto ERROR_EXIT;
+ }
RetVal = CatSPrint (
RetVal,
TempStr,
@@ -720,6 +759,9 @@ AdapterInformationDumpInformation (
);
} else if (CompareGuid (&InfoTypesBuffer[GuidIndex], &gEfiAdapterInfoSanMacAddressGuid) == TRUE) {
TempStr = HiiGetString (mHandleParsingHiiHandle, STRING_TOKEN(STR_SAN_MAC_ADDRESS_INFO), NULL);
+ if (TempStr == NULL) {
+ goto ERROR_EXIT;
+ }
RetVal = CatSPrint (
RetVal,
TempStr,
@@ -732,6 +774,9 @@ AdapterInformationDumpInformation (
);
} else {
TempStr = HiiGetString (mHandleParsingHiiHandle, STRING_TOKEN(STR_UNKNOWN_INFO_TYPE), NULL);
+ if (TempStr == NULL) {
+ goto ERROR_EXIT;
+ }
RetVal = CatSPrint (RetVal, TempStr, &InfoTypesBuffer[GuidIndex]);
}
}
@@ -740,7 +785,14 @@ AdapterInformationDumpInformation (
}
}
+ SHELL_FREE_NON_NULL (InfoTypesBuffer);
return RetVal;
+
+ERROR_EXIT:
+ SHELL_FREE_NON_NULL (RetVal);
+ SHELL_FREE_NON_NULL (InfoTypesBuffer);
+ SHELL_FREE_NON_NULL (InformationBlock);
+ return NULL;
}
//
// Put the information on the NT32 protocol GUIDs here so we are not dependant on the Nt32Pkg
@@ -763,6 +815,21 @@ STATIC CONST EFI_GUID WinNtThunkProtocolGuid = LOCAL_EFI_WIN_NT_THUNK_PROTOCOL_G
STATIC CONST EFI_GUID WinNtIoProtocolGuid = LOCAL_EFI_WIN_NT_BUS_DRIVER_IO_PROTOCOL_GUID;
STATIC CONST EFI_GUID WinNtSerialPortGuid = LOCAL_EFI_WIN_NT_SERIAL_PORT_GUID;
+//
+// Deprecated protocols we dont want to link from IntelFrameworkModulePkg
+//
+#define LOCAL_EFI_ISA_IO_PROTOCOL_GUID \
+ { \
+ 0x7ee2bd44, 0x3da0, 0x11d4, { 0x9a, 0x38, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d } \
+ }
+#define LOCAL_EFI_ISA_ACPI_PROTOCOL_GUID \
+ { \
+ 0x64a892dc, 0x5561, 0x4536, { 0x92, 0xc7, 0x79, 0x9b, 0xfc, 0x18, 0x33, 0x55 } \
+ }
+STATIC CONST EFI_GUID EfiIsaIoProtocolGuid = LOCAL_EFI_ISA_IO_PROTOCOL_GUID;
+STATIC CONST EFI_GUID EfiIsaAcpiProtocolGuid = LOCAL_EFI_ISA_ACPI_PROTOCOL_GUID;
+
+
STATIC CONST GUID_INFO_BLOCK mGuidStringListNT[] = {
{STRING_TOKEN(STR_WINNT_THUNK), (EFI_GUID*)&WinNtThunkProtocolGuid, NULL},
{STRING_TOKEN(STR_WINNT_DRIVER_IO), (EFI_GUID*)&WinNtIoProtocolGuid, NULL},
@@ -874,8 +941,12 @@ STATIC CONST GUID_INFO_BLOCK mGuidStringList[] = {
{STRING_TOKEN(STR_GPT_NBR), &gEfiPartTypeLegacyMbrGuid, NULL},
{STRING_TOKEN(STR_DRIVER_CONFIG), &gEfiDriverConfigurationProtocolGuid, NULL},
{STRING_TOKEN(STR_DRIVER_CONFIG2), &gEfiDriverConfiguration2ProtocolGuid, NULL},
- {STRING_TOKEN(STR_ISA_IO), &gEfiIsaIoProtocolGuid, NULL},
- {STRING_TOKEN(STR_ISA_ACPI), &gEfiIsaAcpiProtocolGuid, NULL},
+
+//
+// these are using local (non-global) definitions to reduce package dependancy.
+//
+ {STRING_TOKEN(STR_ISA_IO), (EFI_GUID*)&EfiIsaIoProtocolGuid, NULL},
+ {STRING_TOKEN(STR_ISA_ACPI), (EFI_GUID*)&EfiIsaAcpiProtocolGuid, NULL},
//
// the ones under this are GUID identified structs, not protocols
diff --git a/ShellPkg/Library/UefiHandleParsingLib/UefiHandleParsingLib.h b/ShellPkg/Library/UefiHandleParsingLib/UefiHandleParsingLib.h
index ba6e152d3b..b0e27c09c3 100644
--- a/ShellPkg/Library/UefiHandleParsingLib/UefiHandleParsingLib.h
+++ b/ShellPkg/Library/UefiHandleParsingLib/UefiHandleParsingLib.h
@@ -135,8 +135,6 @@
#include <Protocol/DiskIo2.h>
#include <Protocol/AdapterInformation.h>
#include <Protocol/EfiShellDynamicCommand.h>
-#include <Protocol/IsaIo.h>
-#include <Protocol/IsaAcpi.h>
#include <Library/HandleParsingLib.h>
#include <Library/UefiBootServicesTableLib.h>
diff --git a/ShellPkg/Library/UefiHandleParsingLib/UefiHandleParsingLib.inf b/ShellPkg/Library/UefiHandleParsingLib/UefiHandleParsingLib.inf
index dc97876667..c95f41b115 100644
--- a/ShellPkg/Library/UefiHandleParsingLib/UefiHandleParsingLib.inf
+++ b/ShellPkg/Library/UefiHandleParsingLib/UefiHandleParsingLib.inf
@@ -36,7 +36,6 @@
MdePkg/MdePkg.dec
MdeModulePkg/MdeModulePkg.dec
ShellPkg/ShellPkg.dec
- IntelFrameworkModulePkg/IntelFrameworkModulePkg.dec
[LibraryClasses]
UefiBootServicesTableLib
@@ -173,8 +172,6 @@
gEfiIdeControllerInitProtocolGuid ##UNDEFINED
gEfiDiskIo2ProtocolGuid ##UNDEFINED
gEfiAdapterInformationProtocolGuid ##UNDEFINED
- gEfiIsaIoProtocolGuid ##UNDEFINED
- gEfiIsaAcpiProtocolGuid ##UNDEFINED
gEfiShellDynamicCommandProtocolGuid ##UNDEFINED
[Guids]
diff --git a/ShellPkg/Library/UefiShellCommandLib/ConsistMapping.c b/ShellPkg/Library/UefiShellCommandLib/ConsistMapping.c
index 48739e20fd..368d6a487b 100644
--- a/ShellPkg/Library/UefiShellCommandLib/ConsistMapping.c
+++ b/ShellPkg/Library/UefiShellCommandLib/ConsistMapping.c
@@ -42,12 +42,26 @@ typedef struct {
CHAR16 *Name;
} MTD_NAME;
-typedef VOID (EFIAPI *SerialDecodeFucntion) (EFI_DEVICE_PATH_PROTOCOL *DevPath, DEVICE_CONSIST_MAPPING_INFO *MapInfo,EFI_DEVICE_PATH_PROTOCOL *);
+/**
+ Serial Decode function.
+
+ @param DevPath The Device path info.
+ @param MapInfo The map info.
+ @param OrigDevPath The original device path protocol.
+
+**/
+typedef
+VOID
+(EFIAPI *SERIAL_DECODE_FUNCTION) (
+ EFI_DEVICE_PATH_PROTOCOL *DevPath,
+ DEVICE_CONSIST_MAPPING_INFO *MapInfo,
+ EFI_DEVICE_PATH_PROTOCOL *OrigDevPath
+ );
typedef struct {
UINT8 Type;
UINT8 SubType;
- SerialDecodeFucntion SerialFun;
+ SERIAL_DECODE_FUNCTION SerialFun;
INTN (EFIAPI *CompareFun) (EFI_DEVICE_PATH_PROTOCOL *DevPath, EFI_DEVICE_PATH_PROTOCOL *DevPath2);
} DEV_PATH_CONSIST_MAPPING_TABLE;
@@ -426,6 +440,7 @@ DevPathCompareDefault (
@param[in] DevicePathNode The node to get info on.
@param[in] MappingItem The info item to populate.
+ @param[in] DevicePath Ignored.
**/
VOID
EFIAPI
@@ -453,6 +468,7 @@ DevPathSerialHardDrive (
@param[in] DevicePathNode The node to get info on.
@param[in] MappingItem The info item to populate.
+ @param[in] DevicePath Ignored.
**/
VOID
EFIAPI
@@ -476,6 +492,7 @@ DevPathSerialAtapi (
@param[in] DevicePathNode The node to get info on.
@param[in] MappingItem The info item to populate.
+ @param[in] DevicePath Ignored.
**/
VOID
EFIAPI
@@ -500,6 +517,7 @@ DevPathSerialCdRom (
@param[in] DevicePathNode The node to get info on.
@param[in] MappingItem The info item to populate.
+ @param[in] DevicePath Ignored.
**/
VOID
EFIAPI
@@ -524,6 +542,7 @@ DevPathSerialFibre (
@param[in] DevicePathNode The node to get info on.
@param[in] MappingItem The info item to populate.
+ @param[in] DevicePath Ignored.
**/
VOID
EFIAPI
@@ -550,6 +569,7 @@ DevPathSerialUart (
@param[in] DevicePathNode The node to get info on.
@param[in] MappingItem The info item to populate.
+ @param[in] DevicePath Ignored.
**/
VOID
EFIAPI
@@ -608,6 +628,7 @@ DevPathSerialUsb (
@param[in] DevicePathNode The node to get info on.
@param[in] MappingItem The info item to populate.
+ @param[in] DevicePath Ignored.
**/
VOID
@@ -671,6 +692,7 @@ DevPathSerialVendor (
@param[in] DevicePathNode The node to get info on.
@param[in] MappingItem The info item to populate.
+ @param[in] DevicePath Ignored.
**/
VOID
EFIAPI
@@ -694,6 +716,7 @@ DevPathSerialLun (
@param[in] DevicePathNode The node to get info on.
@param[in] MappingItem The info item to populate.
+ @param[in] DevicePath Ignored.
**/
VOID
EFIAPI
@@ -719,6 +742,7 @@ DevPathSerialSata (
@param[in] DevicePathNode The node to get info on.
@param[in] MappingItem The info item to populate.
+ @param[in] DevicePath Ignored.
**/
VOID
EFIAPI
@@ -763,6 +787,7 @@ DevPathSerialIScsi (
@param[in] DevicePathNode The node to get info on.
@param[in] MappingItem The info item to populate.
+ @param[in] DevicePath Ignored.
**/
VOID
EFIAPI
@@ -786,6 +811,7 @@ DevPathSerialI2O (
@param[in] DevicePathNode The node to get info on.
@param[in] MappingItem The info item to populate.
+ @param[in] DevicePath Ignored.
**/
VOID
EFIAPI
@@ -823,6 +849,7 @@ DevPathSerialMacAddr (
@param[in] DevicePathNode The node to get info on.
@param[in] MappingItem The info item to populate.
+ @param[in] DevicePath Ignored.
**/
VOID
EFIAPI
@@ -856,6 +883,7 @@ DevPathSerialInfiniBand (
@param[in] DevicePathNode The node to get info on.
@param[in] MappingItem The info item to populate.
+ @param[in] DevicePath Ignored.
**/
VOID
EFIAPI
@@ -901,6 +929,8 @@ DevPathSerialIPv4 (
@param[in] DevicePathNode The node to get info on.
@param[in] MappingItem The info item to populate.
+ @param[in] DevicePath Ignored.
+
**/
VOID
EFIAPI
@@ -938,6 +968,8 @@ DevPathSerialIPv6 (
@param[in] DevicePathNode The node to get info on.
@param[in] MappingItem The info item to populate.
+ @param[in] DevicePath Ignored.
+
**/
VOID
EFIAPI
@@ -962,6 +994,7 @@ DevPathSerialScsi (
@param[in] DevicePathNode The node to get info on.
@param[in] MappingItem The info item to populate.
+ @param[in] DevicePath Ignored.
**/
VOID
EFIAPI
@@ -987,6 +1020,7 @@ DevPathSerial1394 (
@param[in] DevicePathNode The node to get info on.
@param[in] MappingItem The info item to populate.
+ @param[in] DevicePath Ignored.
**/
VOID
EFIAPI
@@ -1015,6 +1049,7 @@ DevPathSerialAcpi (
@param[in] DevicePathNode Ignored.
@param[in] MappingItem Ignored.
+ @param[in] DevicePath Ignored.
Does nothing.
**/
@@ -1265,7 +1300,7 @@ GetDeviceConsistMappingInfo (
IN EFI_DEVICE_PATH_PROTOCOL *DevicePath
)
{
- SerialDecodeFucntion SerialFun;
+ SERIAL_DECODE_FUNCTION SerialFun;
UINTN Index;
EFI_DEVICE_PATH_PROTOCOL *OriginalDevicePath;
diff --git a/ShellPkg/Library/UefiShellDriver1CommandsLib/Connect.c b/ShellPkg/Library/UefiShellDriver1CommandsLib/Connect.c
index 11b8e91bc5..bd4a374d91 100644
--- a/ShellPkg/Library/UefiShellDriver1CommandsLib/Connect.c
+++ b/ShellPkg/Library/UefiShellDriver1CommandsLib/Connect.c
@@ -93,6 +93,8 @@ ShellConnectPciRootBridge (
for (RootBridgeIndex = 0; RootBridgeIndex < RootBridgeHandleCount; RootBridgeIndex++) {
gBS->ConnectController (RootBridgeHandleBuffer[RootBridgeIndex], NULL, NULL, FALSE);
}
+
+ FreePool (RootBridgeHandleBuffer);
return EFI_SUCCESS;
}
@@ -192,7 +194,7 @@ ConnectControllers (
**/
EFI_STATUS
EFIAPI
-ConnectFromDevPaths (
+ShellConnectFromDevPaths (
IN CONST CHAR16 *Key
)
{
@@ -462,31 +464,31 @@ ShellCommandRunConnect (
// do the conin and conout from EFI variables
// if the first fails dont 'loose' the error
//
- Status = ConnectFromDevPaths(L"ConInDev");
+ Status = ShellConnectFromDevPaths(L"ConInDev");
if (EFI_ERROR(Status)) {
- ConnectFromDevPaths(L"ConOutDev");
+ ShellConnectFromDevPaths(L"ConOutDev");
} else {
- Status = ConnectFromDevPaths(L"ConOutDev");
+ Status = ShellConnectFromDevPaths(L"ConOutDev");
}
if (EFI_ERROR(Status)) {
- ConnectFromDevPaths(L"ErrOutDev");
+ ShellConnectFromDevPaths(L"ErrOutDev");
} else {
- Status = ConnectFromDevPaths(L"ErrOutDev");
+ Status = ShellConnectFromDevPaths(L"ErrOutDev");
}
if (EFI_ERROR(Status)) {
- ConnectFromDevPaths(L"ErrOut");
+ ShellConnectFromDevPaths(L"ErrOut");
} else {
- Status = ConnectFromDevPaths(L"ErrOut");
+ Status = ShellConnectFromDevPaths(L"ErrOut");
}
if (EFI_ERROR(Status)) {
- ConnectFromDevPaths(L"ConIn");
+ ShellConnectFromDevPaths(L"ConIn");
} else {
- Status = ConnectFromDevPaths(L"ConIn");
+ Status = ShellConnectFromDevPaths(L"ConIn");
}
if (EFI_ERROR(Status)) {
- ConnectFromDevPaths(L"ConOut");
+ ShellConnectFromDevPaths(L"ConOut");
} else {
- Status = ConnectFromDevPaths(L"ConOut");
+ Status = ShellConnectFromDevPaths(L"ConOut");
}
if (EFI_ERROR(Status)) {
ShellStatus = SHELL_DEVICE_ERROR;
diff --git a/ShellPkg/Library/UefiShellDriver1CommandsLib/Reconnect.c b/ShellPkg/Library/UefiShellDriver1CommandsLib/Reconnect.c
index e6a0fba20d..e4747e310a 100644
--- a/ShellPkg/Library/UefiShellDriver1CommandsLib/Reconnect.c
+++ b/ShellPkg/Library/UefiShellDriver1CommandsLib/Reconnect.c
@@ -1,7 +1,7 @@
/** @file
Main file for Reconnect shell Driver1 function.
- Copyright (c) 2010 - 2011, Intel Corporation. All rights reserved.<BR>
+ Copyright (c) 2010 - 2014, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
@@ -14,6 +14,30 @@
#include "UefiShellDriver1CommandsLib.h"
+STATIC CONST SHELL_PARAM_ITEM ParamList[] = {
+ {L"-r", TypeFlag},
+ {NULL, TypeMax}
+ };
+
+/**
+ Connect all the possible console devices.
+
+**/
+VOID
+ConnectAllConsoles (
+ VOID
+ )
+{
+ ShellConnectFromDevPaths(L"ConInDev");
+ ShellConnectFromDevPaths(L"ConOutDev");
+ ShellConnectFromDevPaths(L"ErrOutDev");
+
+ ShellConnectFromDevPaths(L"ErrOut");
+ ShellConnectFromDevPaths(L"ConIn");
+ ShellConnectFromDevPaths(L"ConOut");
+}
+
+
/**
Function for 'reconnect' command.
@@ -28,15 +52,46 @@ ShellCommandRunReconnect (
)
{
SHELL_STATUS ShellStatus;
+ LIST_ENTRY *Package;
+ CHAR16 *ProblemParam;
+ EFI_STATUS Status;
gInReconnect = TRUE;
+ ShellStatus = SHELL_SUCCESS;
+
+ //
+ // initialize the shell lib (we must be in non-auto-init...)
+ //
+ Status = ShellInitialize();
+ ASSERT_EFI_ERROR(Status);
- ShellStatus = ShellCommandRunDisconnect(ImageHandle, SystemTable);
- if (ShellStatus == SHELL_SUCCESS) {
- ShellStatus = ShellCommandRunConnect(ImageHandle, SystemTable);
- }
+ Status = CommandInit();
+ ASSERT_EFI_ERROR(Status);
+
+ //
+ // parse the command line
+ //
+ Status = ShellCommandLineParse (ParamList, &Package, &ProblemParam, TRUE);
+ if (EFI_ERROR(Status)) {
+ if (Status == EFI_VOLUME_CORRUPTED && ProblemParam != NULL) {
+ ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellDriver1HiiHandle, ProblemParam);
+ FreePool(ProblemParam);
+ ShellStatus = SHELL_INVALID_PARAMETER;
+ } else {
+ ASSERT(FALSE);
+ }
+ } else {
+ ShellStatus = ShellCommandRunDisconnect(ImageHandle, SystemTable);
+ if (ShellStatus == SHELL_SUCCESS) {
+ if (ShellCommandLineGetFlag(Package, L"-r")) {
+ ConnectAllConsoles();
+ }
+ ShellStatus = ShellCommandRunConnect(ImageHandle, SystemTable);
+ }
+ }
gInReconnect = FALSE;
return (ShellStatus);
}
+
diff --git a/ShellPkg/Library/UefiShellDriver1CommandsLib/UefiShellDriver1CommandsLib.h b/ShellPkg/Library/UefiShellDriver1CommandsLib/UefiShellDriver1CommandsLib.h
index 1b8e56822d..c65d0ed695 100644
--- a/ShellPkg/Library/UefiShellDriver1CommandsLib/UefiShellDriver1CommandsLib.h
+++ b/ShellPkg/Library/UefiShellDriver1CommandsLib/UefiShellDriver1CommandsLib.h
@@ -207,5 +207,20 @@ ShellCommandRunUnload (
IN EFI_SYSTEM_TABLE *SystemTable
);
+/**
+ Do a connect from an EFI variable via it's key name.
+
+ @param[in] Key The name of the EFI Variable.
+
+ @retval EFI_SUCCESS The operation was successful.
+**/
+EFI_STATUS
+EFIAPI
+ShellConnectFromDevPaths (
+ IN CONST CHAR16 *Key
+ );
+
+
+
#endif
diff --git a/ShellPkg/Library/UefiShellLib/UefiShellLib.c b/ShellPkg/Library/UefiShellLib/UefiShellLib.c
index 6cef8b7d4c..b7ca41b984 100644
--- a/ShellPkg/Library/UefiShellLib/UefiShellLib.c
+++ b/ShellPkg/Library/UefiShellLib/UefiShellLib.c
@@ -2079,7 +2079,6 @@ InternalCommandLineParse (
break;
}
} else if (GetItemValue != 0 && CurrentItemPackage != NULL && !InternalIsFlag(Argv[LoopCounter], AlwaysAllowNumbers, (CONST BOOLEAN)(CurrentItemPackage->Type == TypeTimeValue))) {
- ASSERT(CurrentItemPackage != NULL);
//
// get the item VALUE for a previous flag
//
diff --git a/SourceLevelDebugPkg/Library/DebugAgent/DebugAgentCommon/X64/AsmFuncs.S b/SourceLevelDebugPkg/Library/DebugAgent/DebugAgentCommon/X64/AsmFuncs.S
index 276f036a83..cdda41fb27 100644
--- a/SourceLevelDebugPkg/Library/DebugAgent/DebugAgentCommon/X64/AsmFuncs.S
+++ b/SourceLevelDebugPkg/Library/DebugAgent/DebugAgentCommon/X64/AsmFuncs.S
@@ -1,6 +1,6 @@
#------------------------------------------------------------------------------
#
-# Copyright (c) 2006 - 2013, Intel Corporation. All rights reserved.<BR>
+# Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.<BR>
# This program and the accompanying materials
# are licensed and made available under the terms and conditions of the BSD License
# which accompanies this distribution. The full text of the license may be found at
@@ -271,13 +271,13 @@ NoExtrPush:
movzwq 32(%rbp), %rax
# movq %cs, %rax
pushq %rax
- movw %ds, %rax
+ mov %ds, %rax
pushq %rax
- movw %es, %rax
+ mov %es, %rax
pushq %rax
- movw %fs, %rax
+ mov %fs, %rax
pushq %rax
- movw %gs, %rax
+ mov %gs, %rax
pushq %rax
## UINT64 Rip;
@@ -385,9 +385,9 @@ NoExtrPush:
# mov fs, rax ; not for fs
# (X64 will not use fs and gs, so we do not restore it)
popq %rax
- movw %rax, %es
+ mov %rax, %es
popq %rax
- movw %rax, %ds
+ mov %rax, %ds
popq 32(%rbp)
popq 56(%rbp)
diff --git a/StdLib/BsdSocketLib/ns_addr.c b/StdLib/BsdSocketLib/ns_addr.c
index 81fd6253e7..4360b0c637 100644
--- a/StdLib/BsdSocketLib/ns_addr.c
+++ b/StdLib/BsdSocketLib/ns_addr.c
@@ -1,6 +1,6 @@
/*
* Copyright (c) 1986, 1993
- * The Regents of the University of California. All rights reserved.
+ * The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* J.Q. Johnson.
@@ -8,28 +8,28 @@
* Portions copyright (c) 1999, 2000
* Intel Corporation.
* All rights reserved.
- *
+ *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
- *
+ *
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
- *
+ *
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- *
+ *
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
- *
+ *
* This product includes software developed by the University of
* California, Berkeley, Intel Corporation, and its contributors.
- *
+ *
* 4. Neither the name of University, Intel Corporation, or their respective
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
- *
+ *
* THIS SOFTWARE IS PROVIDED BY THE REGENTS, INTEL CORPORATION AND
* CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
* BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
@@ -45,7 +45,7 @@
*/
#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)ns_addr.c 8.1 (Berkeley) 6/7/93";
+static char sccsid[] = "@(#)ns_addr.c 8.1 (Berkeley) 6/7/93";
#endif /* LIBC_SCCS and not lint */
#include <sys/param.h>
@@ -55,186 +55,187 @@ static char sccsid[] = "@(#)ns_addr.c 8.1 (Berkeley) 6/7/93";
static struct ns_addr addr, zero_addr;
-static void Field(), cvtbase();
+static void Field (char *buf, u_char *out, int len);
+static void cvtbase (long oldbase, int newbase, int input[], int inlen, unsigned char result[], int reslen);
struct ns_addr
ns_addr(
- const char *name
- )
+ const char *name
+ )
{
- char separator;
- char *hostname, *socketname, *cp;
- char buf[50];
-
- (void)strncpy(buf, name, sizeof(buf) - 1);
- buf[sizeof(buf) - 1] = '\0';
-
- /*
- * First, figure out what he intends as a field separtor.
- * Despite the way this routine is written, the prefered
- * form 2-272.AA001234H.01777, i.e. XDE standard.
- * Great efforts are made to insure backward compatability.
- */
- if ((hostname = strchr(buf, '#')) != NULL)
- separator = '#';
- else {
- hostname = strchr(buf, '.');
- if ((cp = strchr(buf, ':')) &&
- ((hostname && cp < hostname) || (hostname == 0))) {
- hostname = cp;
- separator = ':';
- } else
- separator = '.';
- }
- if (hostname)
- *hostname++ = 0;
-
- addr = zero_addr;
- Field(buf, addr.x_net.c_net, 4);
- if (hostname == 0)
- return (addr); /* No separator means net only */
-
- socketname = strchr(hostname, separator);
- if (socketname) {
- *socketname++ = 0;
- Field(socketname, (u_char *)&addr.x_port, 2);
- }
-
- Field(hostname, addr.x_host.c_host, 6);
-
- return (addr);
+ char separator;
+ char *hostname, *socketname, *cp;
+ char buf[50];
+
+ (void)strncpy(buf, name, sizeof(buf) - 1);
+ buf[sizeof(buf) - 1] = '\0';
+
+ /*
+ * First, figure out what he intends as a field separtor.
+ * Despite the way this routine is written, the prefered
+ * form 2-272.AA001234H.01777, i.e. XDE standard.
+ * Great efforts are made to insure backward compatability.
+ */
+ if ((hostname = strchr(buf, '#')) != NULL)
+ separator = '#';
+ else {
+ hostname = strchr(buf, '.');
+ if ((cp = strchr(buf, ':')) &&
+ ((hostname && cp < hostname) || (hostname == 0))) {
+ hostname = cp;
+ separator = ':';
+ } else
+ separator = '.';
+ }
+ if (hostname)
+ *hostname++ = 0;
+
+ addr = zero_addr;
+ Field(buf, addr.x_net.c_net, 4);
+ if (hostname == 0)
+ return (addr); /* No separator means net only */
+
+ socketname = strchr(hostname, separator);
+ if (socketname) {
+ *socketname++ = 0;
+ Field(socketname, (u_char *)&addr.x_port, 2);
+ }
+
+ Field(hostname, addr.x_host.c_host, 6);
+
+ return (addr);
}
static void
Field(
- char *buf,
- u_char *out,
- int len
- )
+ char *buf,
+ u_char *out,
+ int len
+ )
{
- register char *bp = buf;
- int i, ibase, base16 = 0, base10 = 0, clen = 0;
- int hb[6], *hp;
- char *fmt;
-
- /*
- * first try 2-273#2-852-151-014#socket
- */
- if ((*buf != '-') &&
- (1 < (i = sscanf(buf, "%d-%d-%d-%d-%d",
- &hb[0], &hb[1], &hb[2], &hb[3], &hb[4])))) {
- cvtbase(1000L, 256, hb, i, out, len);
- return;
- }
- /*
- * try form 8E1#0.0.AA.0.5E.E6#socket
- */
- if (1 < (i = sscanf(buf,"%x.%x.%x.%x.%x.%x",
- &hb[0], &hb[1], &hb[2], &hb[3], &hb[4], &hb[5]))) {
- cvtbase(256L, 256, hb, i, out, len);
- return;
- }
- /*
- * try form 8E1#0:0:AA:0:5E:E6#socket
- */
- if (1 < (i = sscanf(buf,"%x:%x:%x:%x:%x:%x",
- &hb[0], &hb[1], &hb[2], &hb[3], &hb[4], &hb[5]))) {
- cvtbase(256L, 256, hb, i, out, len);
- return;
- }
- /*
- * This is REALLY stretching it but there was a
- * comma notation separting shorts -- definitely non standard
- */
- if (1 < (i = sscanf(buf,"%x,%x,%x",
- &hb[0], &hb[1], &hb[2]))) {
- hb[0] = htons(hb[0]); hb[1] = htons(hb[1]);
- hb[2] = htons(hb[2]);
- cvtbase(65536L, 256, hb, i, out, len);
- return;
- }
-
- /* Need to decide if base 10, 16 or 8 */
- while (*bp) switch (*bp++) {
-
- case '0': case '1': case '2': case '3': case '4': case '5':
- case '6': case '7': case '-':
- break;
-
- case '8': case '9':
- base10 = 1;
- break;
-
- case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
- case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
- base16 = 1;
- break;
-
- case 'x': case 'X':
- *--bp = '0';
- base16 = 1;
- break;
-
- case 'h': case 'H':
- base16 = 1;
- /* fall into */
-
- default:
- *--bp = 0; /* Ends Loop */
- }
- if (base16) {
- fmt = "%3x";
- ibase = 4096;
- } else if (base10 == 0 && *buf == '0') {
- fmt = "%3o";
- ibase = 512;
- } else {
- fmt = "%3d";
- ibase = 1000;
- }
-
- for (bp = buf; *bp++; ) clen++;
- if (clen == 0) clen++;
- if (clen > 18) clen = 18;
- i = ((clen - 1) / 3) + 1;
- bp = clen + buf - 3;
- hp = hb + i - 1;
-
- while (hp > hb) {
- (void)sscanf(bp, fmt, hp);
- bp[0] = 0;
- hp--;
- bp -= 3;
- }
- (void)sscanf(buf, fmt, hp);
- cvtbase((long)ibase, 256, hb, i, out, len);
+ register char *bp = buf;
+ int i, ibase, base16 = 0, base10 = 0, clen = 0;
+ int hb[6], *hp;
+ char *fmt;
+
+ /*
+ * first try 2-273#2-852-151-014#socket
+ */
+ if ((*buf != '-') &&
+ (1 < (i = sscanf(buf, "%d-%d-%d-%d-%d",
+ &hb[0], &hb[1], &hb[2], &hb[3], &hb[4])))) {
+ cvtbase(1000L, 256, hb, i, out, len);
+ return;
+ }
+ /*
+ * try form 8E1#0.0.AA.0.5E.E6#socket
+ */
+ if (1 < (i = sscanf(buf,"%x.%x.%x.%x.%x.%x",
+ &hb[0], &hb[1], &hb[2], &hb[3], &hb[4], &hb[5]))) {
+ cvtbase(256L, 256, hb, i, out, len);
+ return;
+ }
+ /*
+ * try form 8E1#0:0:AA:0:5E:E6#socket
+ */
+ if (1 < (i = sscanf(buf,"%x:%x:%x:%x:%x:%x",
+ &hb[0], &hb[1], &hb[2], &hb[3], &hb[4], &hb[5]))) {
+ cvtbase(256L, 256, hb, i, out, len);
+ return;
+ }
+ /*
+ * This is REALLY stretching it but there was a
+ * comma notation separting shorts -- definitely non standard
+ */
+ if (1 < (i = sscanf(buf,"%x,%x,%x",
+ &hb[0], &hb[1], &hb[2]))) {
+ hb[0] = htons(hb[0]); hb[1] = htons(hb[1]);
+ hb[2] = htons(hb[2]);
+ cvtbase(65536L, 256, hb, i, out, len);
+ return;
+ }
+
+ /* Need to decide if base 10, 16 or 8 */
+ while (*bp) switch (*bp++) {
+
+ case '0': case '1': case '2': case '3': case '4': case '5':
+ case '6': case '7': case '-':
+ break;
+
+ case '8': case '9':
+ base10 = 1;
+ break;
+
+ case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
+ case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
+ base16 = 1;
+ break;
+
+ case 'x': case 'X':
+ *--bp = '0';
+ base16 = 1;
+ break;
+
+ case 'h': case 'H':
+ base16 = 1;
+ /* fall into */
+
+ default:
+ *--bp = 0; /* Ends Loop */
+ }
+ if (base16) {
+ fmt = "%3x";
+ ibase = 4096;
+ } else if (base10 == 0 && *buf == '0') {
+ fmt = "%3o";
+ ibase = 512;
+ } else {
+ fmt = "%3d";
+ ibase = 1000;
+ }
+
+ for (bp = buf; *bp++; ) clen++;
+ if (clen == 0) clen++;
+ if (clen > 18) clen = 18;
+ i = ((clen - 1) / 3) + 1;
+ bp = clen + buf - 3;
+ hp = hb + i - 1;
+
+ while (hp > hb) {
+ (void)sscanf(bp, fmt, hp);
+ bp[0] = 0;
+ hp--;
+ bp -= 3;
+ }
+ (void)sscanf(buf, fmt, hp);
+ cvtbase((long)ibase, 256, hb, i, out, len);
}
static void
cvtbase(
- long oldbase,
- int newbase,
- int input[],
- int inlen,
- unsigned char result[],
- int reslen
- )
+ long oldbase,
+ int newbase,
+ int input[],
+ int inlen,
+ unsigned char result[],
+ int reslen
+ )
{
- int d, e;
- long sum;
-
- e = 1;
- while (e > 0 && reslen > 0) {
- d = 0; e = 0; sum = 0;
- /* long division: input=input/newbase */
- while (d < inlen) {
- sum = sum*oldbase + (long) input[d];
- e += (sum > 0);
- input[d++] = sum / newbase;
- sum %= newbase;
- }
- result[--reslen] = (u_char)sum; /* accumulate remainder */
- }
- for (d=0; d < reslen; d++)
- result[d] = 0;
+ int d, e;
+ long sum;
+
+ e = 1;
+ while (e > 0 && reslen > 0) {
+ d = 0; e = 0; sum = 0;
+ /* long division: input=input/newbase */
+ while (d < inlen) {
+ sum = sum*oldbase + (long) input[d];
+ e += (sum > 0);
+ input[d++] = sum / newbase;
+ sum %= newbase;
+ }
+ result[--reslen] = (u_char)sum; /* accumulate remainder */
+ }
+ for (d=0; d < reslen; d++)
+ result[d] = 0;
}
diff --git a/StdLib/BsdSocketLib/ns_ntoa.c b/StdLib/BsdSocketLib/ns_ntoa.c
index 5195d4ec94..bc7e0142ee 100644
--- a/StdLib/BsdSocketLib/ns_ntoa.c
+++ b/StdLib/BsdSocketLib/ns_ntoa.c
@@ -1,6 +1,6 @@
/*
* Copyright (c) 1986, 1993
- * The Regents of the University of California. All rights reserved.
+ * The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -12,8 +12,8 @@
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
@@ -32,72 +32,72 @@
*/
#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)ns_ntoa.c 8.1 (Berkeley) 6/4/93";
+static char sccsid[] = "@(#)ns_ntoa.c 8.1 (Berkeley) 6/4/93";
#endif /* LIBC_SCCS and not lint */
#include <sys/param.h>
#include <netns/ns.h>
#include <stdio.h>
-static char *spectHex();
+static char *spectHex(char *p0);
char *
ns_ntoa(
- struct ns_addr addr
- )
+ struct ns_addr addr
+ )
{
- static char obuf[40];
- union { union ns_net net_e; u_long long_e; } net;
- u_short port = htons(addr.x_port);
- register char *cp;
- char *cp2;
- register u_char *up = addr.x_host.c_host;
- u_char *uplim = up + 6;
+ static char obuf[40];
+ union { union ns_net net_e; u_long long_e; } net;
+ u_short port = htons(addr.x_port);
+ register char *cp;
+ char *cp2;
+ register u_char *up = addr.x_host.c_host;
+ u_char *uplim = up + 6;
- net.net_e = addr.x_net;
- sprintf(obuf, "%x", (UINT32)ntohl(net.long_e));
- cp = spectHex(obuf);
- cp2 = cp + 1;
- while (*up==0 && up < uplim) up++;
- if (up == uplim) {
- if (port) {
- sprintf(cp, ".0");
- cp += 2;
- }
- } else {
- sprintf(cp, ".%x", *up++);
- while (up < uplim) {
- while (*cp) cp++;
- sprintf(cp, "%02x", *up++);
- }
- cp = spectHex(cp2);
- }
- if (port) {
- sprintf(cp, ".%x", port);
- spectHex(cp + 1);
- }
- return (obuf);
+ net.net_e = addr.x_net;
+ sprintf(obuf, "%x", (UINT32)ntohl(net.long_e));
+ cp = spectHex(obuf);
+ cp2 = cp + 1;
+ while (*up==0 && up < uplim) up++;
+ if (up == uplim) {
+ if (port) {
+ sprintf(cp, ".0");
+ cp += 2;
+ }
+ } else {
+ sprintf(cp, ".%x", *up++);
+ while (up < uplim) {
+ while (*cp) cp++;
+ sprintf(cp, "%02x", *up++);
+ }
+ cp = spectHex(cp2);
+ }
+ if (port) {
+ sprintf(cp, ".%x", port);
+ spectHex(cp + 1);
+ }
+ return (obuf);
}
static char *
spectHex(
- char *p0
- )
+ char *p0
+ )
{
- int ok = 0;
- int nonzero = 0;
- register char *p = p0;
- for (; *p; p++) switch (*p) {
+ int ok = 0;
+ int nonzero = 0;
+ register char *p = p0;
+ for (; *p; p++) switch (*p) {
- case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
- *p += ('A' - 'a');
- /* fall into . . . */
- case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
- ok = 1;
- case '1': case '2': case '3': case '4': case '5':
- case '6': case '7': case '8': case '9':
- nonzero = 1;
- }
- if (nonzero && !ok) { *p++ = 'H'; *p = 0; }
- return (p);
+ case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
+ *p += ('A' - 'a');
+ /* fall into . . . */
+ case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
+ ok = 1;
+ case '1': case '2': case '3': case '4': case '5':
+ case '6': case '7': case '8': case '9':
+ nonzero = 1;
+ }
+ if (nonzero && !ok) { *p++ = 'H'; *p = 0; }
+ return (p);
}
diff --git a/TexasInstrumentsPkg/BeagleBoneBlackPkg/BeagleBoneBlackPkg.dsc b/TexasInstrumentsPkg/BeagleBoneBlackPkg/BeagleBoneBlackPkg.dsc
index eba51abecd..f838d8eda1 100644
--- a/TexasInstrumentsPkg/BeagleBoneBlackPkg/BeagleBoneBlackPkg.dsc
+++ b/TexasInstrumentsPkg/BeagleBoneBlackPkg/BeagleBoneBlackPkg.dsc
@@ -101,7 +101,7 @@
SemihostLib|ArmPkg/Library/SemihostLib/SemihostLib.inf
# BDS Libraries
- BdsLib|ArmPkg/Library/BdsLib/BdsLib.inf
+ ArmBdsHelperLib|ArmPkg/Library/ArmBdsHelperLib/ArmBdsHelperLib.inf
FdtLib|EmbeddedPkg/Library/FdtLib/FdtLib.inf
CapsuleLib|MdeModulePkg/Library/DxeCapsuleLibNull/DxeCapsuleLibNull.inf
diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ExceptionHandlerAsm.S b/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ExceptionHandlerAsm.S
index 49ef7b1968..6b62f095bd 100644
--- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ExceptionHandlerAsm.S
+++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ExceptionHandlerAsm.S
@@ -188,13 +188,13 @@ CommonInterruptEntry_al_0000:
pushq %rax # for ss
movzwq 32(%rbp), %rax
pushq %rax # for cs
- movl %ds, %eax
+ mov %ds, %rax
pushq %rax
- movl %es, %eax
+ mov %es, %rax
pushq %rax
- movl %fs, %eax
+ mov %fs, %rax
pushq %rax
- movl %gs, %eax
+ mov %gs, %rax
pushq %rax
movq %rcx, 8(%rbp) # save vector number
@@ -327,9 +327,9 @@ CommonInterruptEntry_al_0000:
# mov %rax, %fs ; not for fs
# (X64 will not use fs and gs, so we do not restore it)
popq %rax
- movl %eax, %es
+ mov %rax, %es
popq %rax
- movl %eax, %ds
+ mov %rax, %ds
popq 32(%rbp) # for cs
popq 56(%rbp) # for ss