summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSteven Kinney <steven.kinney@amd.com>2014-04-17 13:42:47 -0500
committerSteven Kinney <steven.kinney@amd.com>2014-04-17 13:42:47 -0500
commit5261f4659a94e49046d26c6d6d2b2f75d7aca289 (patch)
treec85e326534133066ae301b48525d034a4735b2a6
parent4533f02a98912c745b036d8e6e836e942f244d12 (diff)
parent48c8a38e05b73fc8b8eb72dbbdafa02a81b97818 (diff)
Fix merge conflicts.linaro-edk2-2014.04
Merge branch 'release-prep' Conflicts: ArmPlatformPkg/ArmVExpressPkg/ArmVExpress-CTA15-A7.dsc ArmPlatformPkg/ArmVExpressPkg/ArmVExpress-CTA15-A7.fdf ArmPlatformPkg/ArmVExpressPkg/ArmVExpress-CTA9x4.dsc ArmPlatformPkg/ArmVExpressPkg/ArmVExpress-CTA9x4.fdf ArmPlatformPkg/ArmVExpressPkg/ArmVExpress.dsc.inc Signed-off-by: Steven Kinney <steven.kinney@amd.com>
-rw-r--r--ArmPkg/ArmPkg.dec30
-rw-r--r--ArmPkg/Drivers/ArmCpuLib/ArmCortexA5xLib/AArch64/ArmCortexA5xHelper.S32
-rw-r--r--ArmPkg/Drivers/ArmCpuLib/ArmCortexA5xLib/ArmCortexA5xLib.c36
-rw-r--r--ArmPkg/Drivers/ArmCpuLib/ArmCortexA5xLib/ArmCortexA5xLib.inf5
-rw-r--r--ArmPkg/Drivers/ArmCpuLib/ArmCortexAEMv8Lib/ArmCortexAEMv8Lib.c3
-rw-r--r--ArmPkg/Filesystem/SemihostFs/Arm/SemihostFs.c6
-rw-r--r--ArmPkg/Include/Chipset/AArch64.h8
-rw-r--r--ArmPkg/Include/Chipset/ArmCortexA5x.h29
-rw-r--r--ArmPkg/Include/Chipset/ArmV7.h8
-rw-r--r--ArmPkg/Include/Library/ArmLib.h45
-rw-r--r--ArmPkg/Include/Library/BdsLib.h34
-rw-r--r--ArmPkg/Library/ArmLib/AArch64/AArch64Lib.inf6
-rw-r--r--ArmPkg/Library/ArmLib/AArch64/AArch64LibSec.inf4
-rw-r--r--ArmPkg/Library/ArmLib/AArch64/AArch64Mmu.c28
-rw-r--r--ArmPkg/Library/ArmLib/AArch64/ArmLib.c53
-rw-r--r--ArmPkg/Library/ArmLib/AArch64/ArmLibPrivate.h82
-rw-r--r--ArmPkg/Library/ArmLib/Arm9/Arm9CacheInformation.c23
-rw-r--r--ArmPkg/Library/ArmLib/Common/AArch64/ArmLibSupport.S11
-rw-r--r--ArmPkg/Library/ArmLib/Common/Arm/ArmLibSupport.S21
-rw-r--r--ArmPkg/Library/ArmLib/Common/Arm/ArmLibSupport.asm19
-rw-r--r--ArmPkg/Library/ArmLib/Common/ArmLib.c47
-rw-r--r--ArmPkg/Library/BdsLib/BdsHelper.c4
-rw-r--r--ArmPkg/Library/CompilerIntrinsicsLib/AArch64/memset.c25
-rw-r--r--ArmPkg/Library/CompilerIntrinsicsLib/CompilerIntrinsicsLib.inf1
-rw-r--r--ArmPkg/Library/SemihostLib/SemihostLib.c25
-rw-r--r--ArmPkg/Library/SemihostLib/SemihostPrivate.h17
-rwxr-xr-xArmPlatformPkg/ArmJunoPkg/ArmJuno.dec40
-rwxr-xr-xArmPlatformPkg/ArmJunoPkg/ArmJuno.dsc230
-rwxr-xr-xArmPlatformPkg/ArmJunoPkg/ArmJuno.fdf287
-rwxr-xr-xArmPlatformPkg/ArmJunoPkg/Drivers/ArmJunoDxe/ArmJunoDxe.c34
-rwxr-xr-xArmPlatformPkg/ArmJunoPkg/Drivers/ArmJunoDxe/ArmJunoDxe.inf54
-rwxr-xr-xArmPlatformPkg/ArmJunoPkg/Drivers/ArmJunoDxe/PciEmulation.c489
-rwxr-xr-xArmPlatformPkg/ArmJunoPkg/Drivers/ArmJunoDxe/PciEmulation.h285
-rwxr-xr-xArmPlatformPkg/ArmJunoPkg/Drivers/ArmJunoDxe/PciRootBridgeIo.c299
-rwxr-xr-xArmPlatformPkg/ArmJunoPkg/Drivers/GenericWatchdogDxe/GenericWatchdogDxe.c354
-rwxr-xr-xArmPlatformPkg/ArmJunoPkg/Drivers/GenericWatchdogDxe/GenericWatchdogDxe.inf54
-rwxr-xr-xArmPlatformPkg/ArmJunoPkg/Include/ArmJunoSmc.h25
-rwxr-xr-xArmPlatformPkg/ArmJunoPkg/Include/ArmPlatform.h51
-rwxr-xr-xArmPlatformPkg/ArmJunoPkg/Include/Drivers/GenericWatchdog.h29
-rwxr-xr-xArmPlatformPkg/ArmJunoPkg/Library/ArmJunoLib/ArmJuno.c163
-rwxr-xr-xArmPlatformPkg/ArmJunoPkg/Library/ArmJunoLib/ArmJunoHelper.S75
-rwxr-xr-xArmPlatformPkg/ArmJunoPkg/Library/ArmJunoLib/ArmJunoLib.inf48
-rwxr-xr-xArmPlatformPkg/ArmJunoPkg/Library/ArmJunoLib/ArmJunoMem.c118
-rwxr-xr-xArmPlatformPkg/ArmJunoPkg/Library/NorFlashJunoLib/NorFlashJuno.c68
-rwxr-xr-xArmPlatformPkg/ArmJunoPkg/Library/NorFlashJunoLib/NorFlashJunoLib.inf32
-rwxr-xr-xArmPlatformPkg/ArmJunoPkg/Library/ResetSystemLib/ResetSystemLib.c87
-rwxr-xr-xArmPlatformPkg/ArmJunoPkg/Library/ResetSystemLib/ResetSystemLib.inf32
-rwxr-xr-xArmPlatformPkg/ArmJunoPkg/Makefile89
-rw-r--r--ArmPlatformPkg/ArmVExpressPkg/ArmVExpress-CTA15-A7.dsc5
-rw-r--r--ArmPlatformPkg/ArmVExpressPkg/ArmVExpress-CTA15-A7.fdf20
-rw-r--r--ArmPlatformPkg/ArmVExpressPkg/ArmVExpress-CTA9x4.dsc3
-rw-r--r--ArmPlatformPkg/ArmVExpressPkg/ArmVExpress-CTA9x4.fdf13
-rw-r--r--ArmPlatformPkg/ArmVExpressPkg/ArmVExpress.dsc.inc18
-rw-r--r--ArmPlatformPkg/ArmVExpressPkg/ArmVExpressFastBootDxe/ArmVExpressFastBoot.c451
-rw-r--r--ArmPlatformPkg/ArmVExpressPkg/ArmVExpressFastBootDxe/ArmVExpressFastBootDxe.inf54
-rw-r--r--ArmPlatformPkg/ArmVExpressPkg/ArmVExpressPkg.dec5
-rw-r--r--ArmPlatformPkg/ArmVExpressPkg/Include/VExpressMotherBoard.h4
-rw-r--r--ArmPlatformPkg/Bds/BdsHelper.c4
-rw-r--r--ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashDxe.c114
-rw-r--r--ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashDxe.h6
-rw-r--r--ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashDxe.inf7
-rw-r--r--ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashFvbDxe.c111
-rw-r--r--ArmPlatformPkg/FileSystem/BootMonFs/BootMonFsHw.h4
-rw-r--r--ArmPlatformPkg/FileSystem/BootMonFs/BootMonFsImages.c14
-rw-r--r--ArmPlatformPkg/FileSystem/BootMonFs/BootMonFsOpenClose.c5
-rw-r--r--ArmPlatformPkg/Include/Drivers/PL031RealTimeClock.h34
-rw-r--r--ArmPlatformPkg/Library/PL031RealTimeClockLib/PL031RealTimeClockLib.c122
-rw-r--r--ArmPlatformPkg/Library/PL031RealTimeClockLib/PL031RealTimeClockLib.inf7
-rwxr-xr-xArmPlatformPkg/PrePi/PeiMPCore.inf3
-rwxr-xr-xArmPlatformPkg/PrePi/PeiUniCore.inf3
-rwxr-xr-xArmPlatformPkg/PrePi/PrePi.c5
-rw-r--r--EmbeddedPkg/Application/AndroidFastboot/AndroidBootImg.c90
-rw-r--r--EmbeddedPkg/Application/AndroidFastboot/AndroidFastbootApp.c524
-rw-r--r--EmbeddedPkg/Application/AndroidFastboot/AndroidFastbootApp.h42
-rw-r--r--EmbeddedPkg/Application/AndroidFastboot/AndroidFastbootApp.inf60
-rw-r--r--EmbeddedPkg/Application/AndroidFastboot/Arm/BootAndroidBootImg.c125
-rw-r--r--EmbeddedPkg/Drivers/AndroidFastbootTransportUsbDxe/FastbootTransportUsb.c278
-rw-r--r--EmbeddedPkg/Drivers/AndroidFastbootTransportUsbDxe/FastbootTransportUsbDxe.inf46
-rw-r--r--EmbeddedPkg/Drivers/Isp1761UsbDxe/Isp1761UsbDxe.c636
-rw-r--r--EmbeddedPkg/Drivers/Isp1761UsbDxe/Isp1761UsbDxe.h122
-rw-r--r--EmbeddedPkg/Drivers/Isp1761UsbDxe/Isp1761UsbDxe.inf44
-rw-r--r--EmbeddedPkg/EmbeddedPkg.dec22
-rw-r--r--EmbeddedPkg/EmbeddedPkg.dsc22
-rw-r--r--EmbeddedPkg/Include/Protocol/AndroidFastbootPlatform.h145
-rw-r--r--EmbeddedPkg/Include/Protocol/AndroidFastbootTransport.h131
-rw-r--r--EmbeddedPkg/Include/Protocol/UsbDevice.h118
-rw-r--r--IntelFrameworkModulePkg/Csm/LegacyBiosDxe/LegacyBootSupport.c4
-rw-r--r--IntelFrameworkModulePkg/Library/GenericBdsLib/BdsBoot.c59
-rw-r--r--IntelFrameworkModulePkg/Library/GenericBdsLib/BdsConsole.c17
-rw-r--r--IntelFrameworkModulePkg/Library/GenericBdsLib/BdsMisc.c125
-rw-r--r--IntelFrameworkModulePkg/Library/GenericBdsLib/GenericBdsLib.inf4
-rw-r--r--IntelFrameworkModulePkg/Library/GenericBdsLib/InternalBdsLib.h47
-rw-r--r--IntelFrameworkModulePkg/Universal/Acpi/AcpiS3SaveDxe/AcpiS3SaveDxe.inf3
-rw-r--r--IntelFrameworkModulePkg/Universal/Acpi/AcpiS3SaveDxe/AcpiVariableThunkPlatform.c66
-rw-r--r--IntelFrameworkModulePkg/Universal/BdsDxe/Bds.h47
-rw-r--r--IntelFrameworkModulePkg/Universal/BdsDxe/BdsDxe.inf4
-rw-r--r--IntelFrameworkModulePkg/Universal/BdsDxe/BdsEntry.c153
-rw-r--r--IntelFrameworkModulePkg/Universal/BdsDxe/BootMaint/BBSsupport.c24
-rw-r--r--IntelFrameworkModulePkg/Universal/BdsDxe/BootMaint/BmLib.c7
-rw-r--r--IntelFrameworkModulePkg/Universal/BdsDxe/BootMaint/BootMaint.c17
-rw-r--r--IntelFrameworkModulePkg/Universal/BdsDxe/BootMaint/Variable.c172
-rw-r--r--IntelFrameworkModulePkg/Universal/BdsDxe/FrontPage.c9
-rw-r--r--IntelFrameworkModulePkg/Universal/BdsDxe/Hotkey.c5
-rw-r--r--IntelFrameworkModulePkg/Universal/BdsDxe/Language.c21
-rw-r--r--MdeModulePkg/Bus/I2c/I2cDxe/I2cHost.c1
-rw-r--r--MdeModulePkg/Core/Dxe/Hand/DriverSupport.c3
-rw-r--r--MdeModulePkg/Include/Guid/StatusCodeDataTypeVariable.h40
-rw-r--r--MdeModulePkg/MdeModulePkg.dec7
-rw-r--r--MdeModulePkg/Universal/Acpi/FirmwarePerformanceDataTableDxe/FirmwarePerformanceDxe.c20
-rw-r--r--MdeModulePkg/Universal/Console/TerminalDxe/Terminal.c36
-rw-r--r--MdeModulePkg/Universal/Console/TerminalDxe/Terminal.h1
-rw-r--r--MdeModulePkg/Universal/Console/TerminalDxe/TerminalDxe.inf4
-rw-r--r--MdeModulePkg/Universal/DriverSampleDxe/DriverSample.c42
-rw-r--r--MdeModulePkg/Universal/Network/MnpDxe/MnpVlan.c4
-rw-r--r--MdeModulePkg/Universal/Network/SnpDxe/Station_address.c7
-rw-r--r--MdeModulePkg/Universal/PCD/Dxe/Service.c32
-rw-r--r--MdeModulePkg/Universal/PCD/Pei/Service.c40
-rw-r--r--MdeModulePkg/Universal/PlatformDriOverrideDxe/PlatDriOverrideDxe.c10
-rw-r--r--MdeModulePkg/Universal/PlatformDriOverrideDxe/PlatDriOverrideLib.c68
-rw-r--r--MdeModulePkg/Universal/PlatformDriOverrideDxe/PlatformDriOverrideDxe.inf4
-rw-r--r--MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.c365
-rw-r--r--MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.h33
-rw-r--r--MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf5
-rw-r--r--MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmm.inf5
-rw-r--r--MdePkg/Include/Protocol/Ip4Config.h5
-rw-r--r--MdePkg/Library/BasePeCoffLib/BasePeCoff.c31
-rw-r--r--MdePkg/MdePkg.dec3
-rw-r--r--NetworkPkg/Dhcp6Dxe/Dhcp6Utility.c7
-rw-r--r--NetworkPkg/IScsiDxe/IScsiConfig.c9
-rw-r--r--NetworkPkg/IScsiDxe/IScsiDriver.c8
-rw-r--r--OvmfPkg/AcpiPlatformDxe/AcpiPlatform.c10
-rw-r--r--OvmfPkg/AcpiPlatformDxe/AcpiPlatform.h7
-rw-r--r--OvmfPkg/AcpiPlatformDxe/Qemu.c153
-rw-r--r--OvmfPkg/AcpiS3SaveDxe/AcpiS3Save.c611
-rw-r--r--OvmfPkg/AcpiS3SaveDxe/AcpiS3Save.h59
-rw-r--r--OvmfPkg/AcpiS3SaveDxe/AcpiS3SaveDxe.inf81
-rw-r--r--OvmfPkg/Include/Guid/OvmfPlatformConfig.h24
-rw-r--r--OvmfPkg/Include/Library/QemuFwCfgLib.h14
-rw-r--r--OvmfPkg/Library/LockBoxLib/LockBoxBase.c42
-rw-r--r--OvmfPkg/Library/LockBoxLib/LockBoxBaseLib.inf44
-rw-r--r--OvmfPkg/Library/LockBoxLib/LockBoxDxe.c119
-rw-r--r--OvmfPkg/Library/LockBoxLib/LockBoxDxeLib.inf45
-rw-r--r--OvmfPkg/Library/LockBoxLib/LockBoxLib.c376
-rw-r--r--OvmfPkg/Library/LockBoxLib/LockBoxLib.h60
-rw-r--r--OvmfPkg/Library/PlatformBdsLib/BdsPlatform.c20
-rw-r--r--OvmfPkg/Library/PlatformBdsLib/QemuBootOrder.c78
-rw-r--r--OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgLib.c28
-rw-r--r--OvmfPkg/OvmfPkg.dec4
-rw-r--r--OvmfPkg/OvmfPkgIa32.dsc32
-rw-r--r--OvmfPkg/OvmfPkgIa32.fdf17
-rw-r--r--OvmfPkg/OvmfPkgIa32X64.dsc32
-rw-r--r--OvmfPkg/OvmfPkgIa32X64.fdf17
-rw-r--r--OvmfPkg/OvmfPkgX64.dsc32
-rw-r--r--OvmfPkg/OvmfPkgX64.fdf17
-rw-r--r--OvmfPkg/PlatformDxe/Platform.c871
-rw-r--r--OvmfPkg/PlatformDxe/Platform.h43
-rw-r--r--OvmfPkg/PlatformDxe/Platform.inf69
-rw-r--r--OvmfPkg/PlatformDxe/Platform.unibin0 -> 3298 bytes
-rw-r--r--OvmfPkg/PlatformDxe/PlatformConfig.c131
-rw-r--r--OvmfPkg/PlatformDxe/PlatformConfig.h59
-rw-r--r--OvmfPkg/PlatformDxe/PlatformForms.vfr74
-rw-r--r--OvmfPkg/PlatformPei/Fv.c5
-rw-r--r--OvmfPkg/PlatformPei/MemDetect.c100
-rw-r--r--OvmfPkg/PlatformPei/Platform.c28
-rw-r--r--OvmfPkg/PlatformPei/Platform.h4
-rw-r--r--OvmfPkg/PlatformPei/PlatformPei.inf12
-rw-r--r--OvmfPkg/QemuVideoDxe/Driver.c10
-rw-r--r--OvmfPkg/Sec/SecMain.c54
-rw-r--r--PcAtChipsetPkg/PcatRealTimeClockRuntimeDxe/PcRtc.c84
-rw-r--r--PerformancePkg/Dp_App/DpInternal.h3
-rw-r--r--PerformancePkg/Dp_App/DpUtilities.c3
-rw-r--r--SecurityPkg/Library/DxeTcgPhysicalPresenceLib/DxeTcgPhysicalPresenceLib.c51
-rw-r--r--SecurityPkg/Library/DxeTpm2MeasureBootLib/DxeTpm2MeasureBootLib.c6
-rw-r--r--SecurityPkg/Library/DxeTpmMeasureBootLib/DxeTpmMeasureBootLib.c6
-rw-r--r--SecurityPkg/Library/DxeTrEEPhysicalPresenceLib/DxeTrEEPhysicalPresenceLib.c52
-rw-r--r--SecurityPkg/SecurityPkg.dec8
-rw-r--r--SecurityPkg/SecurityPkg.dsc10
-rw-r--r--SecurityPkg/Tcg/MemoryOverwriteControl/TcgMor.c25
-rw-r--r--SecurityPkg/Tcg/TcgConfigDxe/TcgConfig.vfr23
-rw-r--r--SecurityPkg/Tcg/TcgConfigDxe/TcgConfigDriver.c3
-rw-r--r--SecurityPkg/Tcg/TcgConfigDxe/TcgConfigDxe.inf6
-rw-r--r--SecurityPkg/Tcg/TcgConfigDxe/TcgConfigImpl.c47
-rw-r--r--SecurityPkg/Tcg/TcgConfigDxe/TcgConfigImpl.h4
-rw-r--r--SecurityPkg/Tcg/TcgConfigDxe/TcgConfigNvData.h12
-rw-r--r--SecurityPkg/Tcg/TcgPei/TcgPei.c6
-rw-r--r--SecurityPkg/Tcg/TcgPei/TcgPei.inf4
-rw-r--r--SecurityPkg/Tcg/TcgSmm/TcgSmm.c8
-rw-r--r--SecurityPkg/Tcg/TrEEConfig/TpmDetection.c40
-rw-r--r--SecurityPkg/Tcg/TrEEConfig/TrEEConfig.vfr9
-rw-r--r--SecurityPkg/Tcg/TrEEConfig/TrEEConfigDriver.c65
-rw-r--r--SecurityPkg/Tcg/TrEEConfig/TrEEConfigDxe.inf1
-rw-r--r--SecurityPkg/Tcg/TrEEConfig/TrEEConfigImpl.c177
-rw-r--r--SecurityPkg/Tcg/TrEEConfig/TrEEConfigImpl.h2
-rw-r--r--SecurityPkg/Tcg/TrEEConfig/TrEEConfigNvData.h14
-rw-r--r--SecurityPkg/Tcg/TrEEConfig/TrEEConfigPei.inf6
-rw-r--r--SecurityPkg/Tcg/TrEEConfig/TrEEConfigPeim.c19
-rw-r--r--SecurityPkg/Tcg/TrEEPei/TrEEPei.c6
-rw-r--r--SecurityPkg/Tcg/TrEEPei/TrEEPei.inf4
-rw-r--r--SecurityPkg/Tcg/TrEESmm/TrEESmm.c9
-rw-r--r--SecurityPkg/UserIdentification/PwdCredentialProviderDxe/PwdCredentialProvider.c7
-rw-r--r--SecurityPkg/UserIdentification/UsbCredentialProviderDxe/UsbCredentialProvider.c7
-rw-r--r--SecurityPkg/UserIdentification/UserIdentifyManagerDxe/UserIdentifyManager.c7
-rw-r--r--SecurityPkg/VariableAuthenticated/RuntimeDxe/AuthService.c55
-rw-r--r--SecurityPkg/VariableAuthenticated/RuntimeDxe/Variable.c362
-rw-r--r--SecurityPkg/VariableAuthenticated/RuntimeDxe/Variable.h62
-rw-r--r--SecurityPkg/VariableAuthenticated/RuntimeDxe/VariableDxe.c6
-rw-r--r--SecurityPkg/VariableAuthenticated/RuntimeDxe/VariableRuntimeDxe.inf5
-rw-r--r--SecurityPkg/VariableAuthenticated/RuntimeDxe/VariableSmm.c6
-rw-r--r--SecurityPkg/VariableAuthenticated/RuntimeDxe/VariableSmm.inf3
-rw-r--r--ShellPkg/Application/Shell/Shell.c4
-rw-r--r--ShellPkg/Application/Shell/ShellProtocol.c87
-rw-r--r--ShellPkg/Library/UefiHandleParsingLib/UefiHandleParsingLib.c175
-rw-r--r--ShellPkg/Library/UefiHandleParsingLib/UefiHandleParsingLib.unibin24454 -> 26552 bytes
-rw-r--r--ShellPkg/Library/UefiShellDebug1CommandsLib/SetVar.c3
-rw-r--r--ShellPkg/Library/UefiShellDriver1CommandsLib/UefiShellDriver1CommandsLib.c2
-rw-r--r--ShellPkg/Library/UefiShellDriver1CommandsLib/UefiShellDriver1CommandsLib.h2
-rw-r--r--ShellPkg/Library/UefiShellDriver1CommandsLib/Unload.c79
-rw-r--r--ShellPkg/Library/UefiShellLevel2CommandsLib/Ls.c7
-rw-r--r--SourceLevelDebugPkg/Library/DebugAgent/DxeDebugAgent/DxeDebugAgentLib.c29
-rw-r--r--StdLib/EfiSocketLib/Socket.c5
-rw-r--r--StdLib/LibC/StdLib/Malloc.c121
221 files changed, 12127 insertions, 1538 deletions
diff --git a/ArmPkg/ArmPkg.dec b/ArmPkg/ArmPkg.dec
index f11243f23..5efef7c9d 100644
--- a/ArmPkg/ArmPkg.dec
+++ b/ArmPkg/ArmPkg.dec
@@ -2,7 +2,7 @@
# ARM processor package.
#
# Copyright (c) 2009 - 2010, Apple Inc. All rights reserved.<BR>
-# Copyright (c) 2011 - 2013, ARM Limited. All rights reserved.
+# 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
@@ -38,7 +38,7 @@
UncachedMemoryAllocationLib|Include/Library/UncachedMemoryAllocationLib.h
DefaultExceptionHandlerLib|Include/Library/DefaultExceptionHandlerLib.h
ArmDisassemblerLib|Include/Library/ArmDisassemblerLib.h
-
+
[Guids.common]
gArmTokenSpaceGuid = { 0xBB11ECFE, 0x820F, 0x4968, { 0xBB, 0xA6, 0xF7, 0x6A, 0xFE, 0x30, 0x25, 0x96 } }
@@ -64,10 +64,10 @@
# Set this PCD to TRUE if the Exception Vector is changed to add debugger support before
# it has been configured by the CPU DXE
gArmTokenSpaceGuid.PcdDebuggerExceptionSupport|FALSE|BOOLEAN|0x00000032
-
+
# Define if the Power State Coordination Interface (PSCI) is supported by the Platform Trusted Firmware
gArmTokenSpaceGuid.PcdArmPsciSupport|FALSE|BOOLEAN|0x00000033
-
+
[PcdsFixedAtBuild.common]
gArmTokenSpaceGuid.PcdTrustzoneSupport|FALSE|BOOLEAN|0x00000006
@@ -79,9 +79,9 @@
gArmTokenSpaceGuid.PcdArmCacheOperationThreshold|1024|UINT32|0x00000003
gArmTokenSpaceGuid.PcdCpuVectorBaseAddress|0xffff0000|UINT32|0x00000004
gArmTokenSpaceGuid.PcdCpuResetAddress|0x00000000|UINT32|0x00000005
-
+
#
- # ARM General Interrupt Controller
+ # ARM Generic Interrupt Controller
#
gArmTokenSpaceGuid.PcdGicDistributorBase|0|UINT32|0x0000000C
gArmTokenSpaceGuid.PcdGicInterruptInterfaceBase|0|UINT32|0x0000000D
@@ -102,10 +102,10 @@
gArmTokenSpaceGuid.PcdFdSize|0|UINT32|0x0000002C
gArmTokenSpaceGuid.PcdFvBaseAddress|0|UINT32|0x0000002D
gArmTokenSpaceGuid.PcdFvSize|0|UINT32|0x0000002E
-
+
#
# ARM Hypervisor Firmware PCDs
- #
+ #
gArmTokenSpaceGuid.PcdHypFdBaseAddress|0|UINT32|0x0000003A
gArmTokenSpaceGuid.PcdHypFdSize|0|UINT32|0x0000003B
gArmTokenSpaceGuid.PcdHypFvBaseAddress|0|UINT32|0x0000003C
@@ -113,21 +113,21 @@
# System Memory (DRAM): These PCDs define the region of in-built system memory
# Some platforms can get DRAM extensions, these additional regions will be declared
- # to UEFI by ArmPLatformPlib
+ # to UEFI by ArmPlatformLib
gArmTokenSpaceGuid.PcdSystemMemoryBase|0|UINT64|0x00000029
gArmTokenSpaceGuid.PcdSystemMemorySize|0|UINT64|0x0000002A
# Use ClusterId + CoreId to identify the PrimaryCore
gArmTokenSpaceGuid.PcdArmPrimaryCoreMask|0xF03|UINT32|0x00000031
- # The Primary Core is ClusterId[0] & CoreId[0]
+ # The Primary Core is ClusterId[0] & CoreId[0]
gArmTokenSpaceGuid.PcdArmPrimaryCore|0|UINT32|0x00000037
#
# ARM L2x0 PCDs
#
gArmTokenSpaceGuid.PcdL2x0ControllerBase|0|UINT32|0x0000001B
-
- #
+
+ #
# BdsLib
#
gArmTokenSpaceGuid.PcdArmMachineType|0|UINT32|0x0000001E
@@ -139,7 +139,7 @@
#
gArmTokenSpaceGuid.PcdArmArchTimerFreqInHz|0|UINT32|0x00000034
# ARM Architectural Timer Interrupt(GIC PPI) number
- gArmTokenSpaceGuid.PcdArmArchTimerSecIntrNum|29|UINT32|0x00000035
+ gArmTokenSpaceGuid.PcdArmArchTimerSecIntrNum|29|UINT32|0x00000035
gArmTokenSpaceGuid.PcdArmArchTimerIntrNum|30|UINT32|0x00000036
[PcdsFixedAtBuild.ARM]
@@ -207,8 +207,8 @@
# By default we do transition to EL2 non-secure mode with Stack for EL2.
# Mode Description Bits
- # NS EL2 SP2 all interupts disabled = 0x3c9
- # NS EL1 SP1 all interupts disabled = 0x3c5
+ # NS EL2 SP2 all interrupts disabled = 0x3c9
+ # NS EL1 SP1 all interrupts disabled = 0x3c5
# Other modes include using SP0 or switching to Aarch32, but these are
# not currently supported.
gArmTokenSpaceGuid.PcdArmNonSecModeTransition|0x3c9|UINT32|0x0000003E
diff --git a/ArmPkg/Drivers/ArmCpuLib/ArmCortexA5xLib/AArch64/ArmCortexA5xHelper.S b/ArmPkg/Drivers/ArmCpuLib/ArmCortexA5xLib/AArch64/ArmCortexA5xHelper.S
new file mode 100644
index 000000000..e5fbc86bc
--- /dev/null
+++ b/ArmPkg/Drivers/ArmCpuLib/ArmCortexA5xLib/AArch64/ArmCortexA5xHelper.S
@@ -0,0 +1,32 @@
+#------------------------------------------------------------------------------
+#
+# Copyright (c) 2013 - 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.
+#
+#------------------------------------------------------------------------------
+
+#include <AsmMacroIoLibV8.h>
+
+.text
+.align 3
+GCC_ASM_EXPORT (ArmReadCpuExCr)
+GCC_ASM_EXPORT (ArmWriteCpuExCr)
+
+ASM_PFX(ArmReadCpuExCr):
+ mrs x0, S3_1_c15_c2_1
+ ret
+
+ASM_PFX(ArmWriteCpuExCr):
+ msr S3_1_c15_c2_1, x0
+ dsb sy
+ isb
+ ret
+
+ASM_FUNCTION_REMOVE_IF_UNREFERENCED
diff --git a/ArmPkg/Drivers/ArmCpuLib/ArmCortexA5xLib/ArmCortexA5xLib.c b/ArmPkg/Drivers/ArmCpuLib/ArmCortexA5xLib/ArmCortexA5xLib.c
index d13c7fd6f..99ee51fb6 100644
--- a/ArmPkg/Drivers/ArmCpuLib/ArmCortexA5xLib/ArmCortexA5xLib.c
+++ b/ArmPkg/Drivers/ArmCpuLib/ArmCortexA5xLib/ArmCortexA5xLib.c
@@ -1,6 +1,6 @@
/** @file
- Copyright (c) 2011-2013, ARM Limited. All rights reserved.
+ 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
@@ -37,9 +37,17 @@ ArmCpuSetup (
if (ArmIsMpCore ()) {
// Turn on SMP coherency
- ArmSetAuxCrBit (A5X_FEATURE_SMP);
+ ArmSetCpuExCrBit (A5X_FEATURE_SMP);
}
+ //
+ // If CPU is CortexA57 r0p0 apply Errata: 806969
+ //
+ if ((ArmReadMidr () & ((ARM_CPU_TYPE_MASK << 4) | ARM_CPU_REV_MASK)) ==
+ ((ARM_CPU_TYPE_A57 << 4) | ARM_CPU_REV(0,0))) {
+ // DisableLoadStoreWB
+ ArmSetCpuActlrBit (1ULL << 49);
+ }
}
VOID
@@ -48,3 +56,27 @@ ArmCpuSetupSmpNonSecure (
)
{
}
+
+VOID
+EFIAPI
+ArmSetCpuExCrBit (
+ IN UINT64 Bits
+ )
+{
+ UINT64 Value;
+ Value = ArmReadCpuExCr ();
+ Value |= Bits;
+ ArmWriteCpuExCr (Value);
+}
+
+VOID
+EFIAPI
+ArmUnsetCpuExCrBit (
+ IN UINT64 Bits
+ )
+{
+ UINT64 Value;
+ Value = ArmReadCpuExCr ();
+ Value &= ~Bits;
+ ArmWriteCpuExCr (Value);
+}
diff --git a/ArmPkg/Drivers/ArmCpuLib/ArmCortexA5xLib/ArmCortexA5xLib.inf b/ArmPkg/Drivers/ArmCpuLib/ArmCortexA5xLib/ArmCortexA5xLib.inf
index 486aba74a..acfa98d41 100644
--- a/ArmPkg/Drivers/ArmCpuLib/ArmCortexA5xLib/ArmCortexA5xLib.inf
+++ b/ArmPkg/Drivers/ArmCpuLib/ArmCortexA5xLib/ArmCortexA5xLib.inf
@@ -1,5 +1,5 @@
#/* @file
-# Copyright (c) 2011-2013, ARM Limited. All rights reserved.
+# 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
@@ -31,5 +31,8 @@
[Sources.common]
ArmCortexA5xLib.c
+[Sources.AARCH64]
+ AArch64/ArmCortexA5xHelper.S | GCC
+
[FixedPcd]
gArmTokenSpaceGuid.PcdArmArchTimerFreqInHz
diff --git a/ArmPkg/Drivers/ArmCpuLib/ArmCortexAEMv8Lib/ArmCortexAEMv8Lib.c b/ArmPkg/Drivers/ArmCpuLib/ArmCortexAEMv8Lib/ArmCortexAEMv8Lib.c
index d38723f4b..3c85da616 100644
--- a/ArmPkg/Drivers/ArmCpuLib/ArmCortexAEMv8Lib/ArmCortexAEMv8Lib.c
+++ b/ArmPkg/Drivers/ArmCpuLib/ArmCortexAEMv8Lib/ArmCortexAEMv8Lib.c
@@ -13,11 +13,8 @@
**/
#include <Base.h>
-#include <Library/ArmLib.h>
#include <Library/ArmCpuLib.h>
-#include <Library/ArmGicLib.h>
#include <Library/ArmArchTimerLib.h>
-#include <Library/IoLib.h>
#include <Library/PcdLib.h>
#include <Chipset/ArmAemV8.h>
diff --git a/ArmPkg/Filesystem/SemihostFs/Arm/SemihostFs.c b/ArmPkg/Filesystem/SemihostFs/Arm/SemihostFs.c
index 447ab5631..aae9582a6 100644
--- a/ArmPkg/Filesystem/SemihostFs/Arm/SemihostFs.c
+++ b/ArmPkg/Filesystem/SemihostFs/Arm/SemihostFs.c
@@ -2,7 +2,7 @@
Support a Semi Host file system over a debuggers JTAG
Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
- Portions copyright (c) 2011 - 2013, ARM Ltd. All rights reserved.<BR>
+ Portions copyright (c) 2011 - 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
@@ -544,7 +544,9 @@ FileSetInfo (
if (CompareGuid (InformationType, &gEfiFileSystemInfoGuid) != 0) {
//Status = SetFilesystemInfo (Fcb, BufferSize, Buffer);
} else if (CompareGuid (InformationType, &gEfiFileInfoGuid) != 0) {
- //Status = SetFileInfo (Fcb, BufferSize, Buffer);
+ // Semihosting does not give us access to setting file info, but
+ // if we fail here we cannot create new files.
+ Status = EFI_SUCCESS;
} else if (CompareGuid (InformationType, &gEfiFileSystemVolumeLabelInfoIdGuid) != 0) {
if (StrSize (Buffer) > 0) {
FreePool (mSemihostFsLabel);
diff --git a/ArmPkg/Include/Chipset/AArch64.h b/ArmPkg/Include/Chipset/AArch64.h
index e01158850..3e5b55bfd 100644
--- a/ArmPkg/Include/Chipset/AArch64.h
+++ b/ArmPkg/Include/Chipset/AArch64.h
@@ -1,7 +1,7 @@
/** @file
Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
- Copyright (c) 2011 - 2013, ARM Ltd. All rights reserved.<BR>
+ Copyright (c) 2011 - 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
@@ -45,10 +45,15 @@
// MIDR - Main ID Register definitions
#define ARM_CPU_TYPE_MASK 0xFFF
#define ARM_CPU_TYPE_AEMv8 0xD0F
+#define ARM_CPU_TYPE_A53 0xD03
+#define ARM_CPU_TYPE_A57 0xD07
#define ARM_CPU_TYPE_A15 0xC0F
#define ARM_CPU_TYPE_A9 0xC09
#define ARM_CPU_TYPE_A5 0xC05
+#define ARM_CPU_REV_MASK ((0xF << 20) | (0xF) )
+#define ARM_CPU_REV(rn, pn) ((((rn) & 0xF) << 20) | ((pn) & 0xF))
+
// Hypervisor Configuration Register
#define ARM_HCR_FMO BIT3
#define ARM_HCR_IMO BIT4
@@ -116,7 +121,6 @@ ArmDisableAlignmentCheck (
VOID
);
-
VOID
EFIAPI
ArmEnableAlignmentCheck (
diff --git a/ArmPkg/Include/Chipset/ArmCortexA5x.h b/ArmPkg/Include/Chipset/ArmCortexA5x.h
index e2217e3f3..ba3d5197e 100644
--- a/ArmPkg/Include/Chipset/ArmCortexA5x.h
+++ b/ArmPkg/Include/Chipset/ArmCortexA5x.h
@@ -1,6 +1,6 @@
/** @file
- Copyright (c) 2012-2013, ARM Limited. All rights reserved.
+ Copyright (c) 2012-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
@@ -20,4 +20,31 @@
//
#define A5X_FEATURE_SMP (1 << 6)
+//
+// Helper functions to access CPU Extended Control Register
+//
+UINT64
+EFIAPI
+ArmReadCpuExCr (
+ VOID
+ );
+
+VOID
+EFIAPI
+ArmWriteCpuExCr (
+ IN UINT64 Val
+ );
+
+VOID
+EFIAPI
+ArmSetCpuExCrBit (
+ IN UINT64 Bits
+ );
+
+VOID
+EFIAPI
+ArmUnsetCpuExCrBit (
+ IN UINT64 Bits
+ );
+
#endif
diff --git a/ArmPkg/Include/Chipset/ArmV7.h b/ArmPkg/Include/Chipset/ArmV7.h
index 3fcc4264f..345554eb2 100644
--- a/ArmPkg/Include/Chipset/ArmV7.h
+++ b/ArmPkg/Include/Chipset/ArmV7.h
@@ -1,7 +1,7 @@
/** @file
Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
- Copyright (c) 2011-2013, ARM Ltd. All rights reserved.<BR>
+ Copyright (c) 2011-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
@@ -71,10 +71,16 @@
// MIDR - Main ID Register definitions
#define ARM_CPU_TYPE_MASK 0xFFF
+#define ARM_CPU_TYPE_AEMv8 0xD0F
+#define ARM_CPU_TYPE_A53 0xD03
+#define ARM_CPU_TYPE_A57 0xD07
#define ARM_CPU_TYPE_A15 0xC0F
#define ARM_CPU_TYPE_A9 0xC09
#define ARM_CPU_TYPE_A5 0xC05
+#define ARM_CPU_REV_MASK ((0xF << 20) | (0xF) )
+#define ARM_CPU_REV(rn, pn) ((((rn) & 0xF) << 20) | ((pn) & 0xF))
+
#define ARM_VECTOR_TABLE_ALIGNMENT ((1 << 5)-1)
VOID
diff --git a/ArmPkg/Include/Library/ArmLib.h b/ArmPkg/Include/Library/ArmLib.h
index 82f0c4b39..a338f7790 100644
--- a/ArmPkg/Include/Library/ArmLib.h
+++ b/ArmPkg/Include/Library/ArmLib.h
@@ -212,9 +212,9 @@ ArmReadIdPfr1 (
VOID
);
-UINT32
+UINTN
EFIAPI
-Cp15CacheInfo (
+ArmCacheInfo (
VOID
);
@@ -452,18 +452,6 @@ ArmMmuEnabled (
VOID
EFIAPI
-ArmSwitchProcessorMode (
- IN ARM_PROCESSOR_MODE Mode
- );
-
-ARM_PROCESSOR_MODE
-EFIAPI
-ArmProcessorMode (
- VOID
- );
-
-VOID
-EFIAPI
ArmEnableBranchPrediction (
VOID
);
@@ -637,4 +625,33 @@ ArmWriteHVBar (
IN UINTN HypModeVectorBase
);
+
+//
+// Helper functions for accessing CPU ACTLR
+//
+
+UINTN
+EFIAPI
+ArmReadCpuActlr (
+ VOID
+ );
+
+VOID
+EFIAPI
+ArmWriteCpuActlr (
+ IN UINTN Val
+ );
+
+VOID
+EFIAPI
+ArmSetCpuActlrBit (
+ IN UINTN Bits
+ );
+
+VOID
+EFIAPI
+ArmUnsetCpuActlrBit (
+ IN UINTN Bits
+ );
+
#endif // __ARM_LIB__
diff --git a/ArmPkg/Include/Library/BdsLib.h b/ArmPkg/Include/Library/BdsLib.h
index d16748da4..9fa687041 100644
--- a/ArmPkg/Include/Library/BdsLib.h
+++ b/ArmPkg/Include/Library/BdsLib.h
@@ -66,6 +66,23 @@ BdsConnectAllDrivers (
VOID
);
+/**
+ 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,
@@ -74,6 +91,23 @@ GetGlobalEnvironmentVariable (
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,
diff --git a/ArmPkg/Library/ArmLib/AArch64/AArch64Lib.inf b/ArmPkg/Library/ArmLib/AArch64/AArch64Lib.inf
index dca0b22dd..06824e5e7 100644
--- a/ArmPkg/Library/ArmLib/AArch64/AArch64Lib.inf
+++ b/ArmPkg/Library/ArmLib/AArch64/AArch64Lib.inf
@@ -1,7 +1,7 @@
#/** @file
#
# Copyright (c) 2008 - 2010, Apple Inc. All rights reserved.<BR>
-# Portions copyright (c) 2011-2013, ARM Limited. All rights reserved.
+# Portions 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
@@ -26,10 +26,12 @@
AArch64Mmu.c
AArch64ArchTimer.c
ArmLibSupportV8.S | GCC
- ../Common/AArch64/ArmLibSupport.S | GCC
AArch64Support.S | GCC
AArch64ArchTimerSupport.S | GCC
+ ../Common/AArch64/ArmLibSupport.S | GCC
+ ../Common/ArmLib.c
+
[Packages]
ArmPkg/ArmPkg.dec
MdePkg/MdePkg.dec
diff --git a/ArmPkg/Library/ArmLib/AArch64/AArch64LibSec.inf b/ArmPkg/Library/ArmLib/AArch64/AArch64LibSec.inf
index 9bb0bd21d..c273718b3 100644
--- a/ArmPkg/Library/ArmLib/AArch64/AArch64LibSec.inf
+++ b/ArmPkg/Library/ArmLib/AArch64/AArch64LibSec.inf
@@ -1,6 +1,6 @@
#/* @file
#
-# Copyright (c) 2011-2013, ARM Limited. All rights reserved.
+# 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
@@ -23,9 +23,9 @@
[Sources.common]
ArmLibSupportV8.S | GCC
AArch64Support.S | GCC
- ArmLib.c
../Common/AArch64/ArmLibSupport.S | GCC
+ ../Common/ArmLib.c
AArch64Lib.c
diff --git a/ArmPkg/Library/ArmLib/AArch64/AArch64Mmu.c b/ArmPkg/Library/ArmLib/AArch64/AArch64Mmu.c
index 9bc984f0b..bababab88 100644
--- a/ArmPkg/Library/ArmLib/AArch64/AArch64Mmu.c
+++ b/ArmPkg/Library/ArmLib/AArch64/AArch64Mmu.c
@@ -1,7 +1,7 @@
/** @file
* File managing the MMU for ARMv8 architecture
*
-* Copyright (c) 2011-2013, ARM Limited. All rights reserved.
+* 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
@@ -264,13 +264,22 @@ GetBlockEntryListFromAddress (
BlockEntry = NULL;
// Ensure the parameters are valid
- ASSERT (TableLevel && BlockEntrySize && LastBlockEntry);
+ if (!(TableLevel && BlockEntrySize && LastBlockEntry)) {
+ ASSERT_EFI_ERROR (EFI_INVALID_PARAMETER);
+ return NULL;
+ }
// Ensure the Region is aligned on 4KB boundary
- ASSERT ((RegionStart & (SIZE_4KB - 1)) == 0);
+ if ((RegionStart & (SIZE_4KB - 1)) != 0) {
+ ASSERT_EFI_ERROR (EFI_INVALID_PARAMETER);
+ return NULL;
+ }
// Ensure the required size is aligned on 4KB boundary
- ASSERT ((*BlockEntrySize & (SIZE_4KB - 1)) == 0);
+ if ((*BlockEntrySize & (SIZE_4KB - 1)) != 0) {
+ ASSERT_EFI_ERROR (EFI_INVALID_PARAMETER);
+ return NULL;
+ }
//
// Calculate LastBlockEntry from T0SZ - this is the last block entry of the root Translation table
@@ -427,7 +436,10 @@ FillTranslationTable (
UINTN TableLevel;
// Ensure the Length is aligned on 4KB boundary
- ASSERT ((MemoryRegion->Length > 0) && ((MemoryRegion->Length & (SIZE_4KB - 1)) == 0));
+ if ((MemoryRegion->Length == 0) || ((MemoryRegion->Length & (SIZE_4KB - 1)) != 0)) {
+ ASSERT_EFI_ERROR (EFI_INVALID_PARAMETER);
+ return RETURN_INVALID_PARAMETER;
+ }
// Variable initialization
Attributes = ArmMemoryAttributeToPageAttribute (MemoryRegion->Attributes) | TT_AF;
@@ -519,7 +531,11 @@ ArmConfigureMmu (
UINT64 TCR;
RETURN_STATUS Status;
- ASSERT (MemoryTable != NULL);
+ if(MemoryTable == NULL)
+ {
+ ASSERT (MemoryTable != NULL);
+ return RETURN_INVALID_PARAMETER;
+ }
// Identify the highest address of the memory table
MaxAddress = MemoryTable->PhysicalBase + MemoryTable->Length - 1;
diff --git a/ArmPkg/Library/ArmLib/AArch64/ArmLib.c b/ArmPkg/Library/ArmLib/AArch64/ArmLib.c
deleted file mode 100644
index fa95d352d..000000000
--- a/ArmPkg/Library/ArmLib/AArch64/ArmLib.c
+++ /dev/null
@@ -1,53 +0,0 @@
-/** @file
-
- Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
- portions copyright (c) 2011 - 2013, ARM Ltd. All rights reserved.<BR>
-
- This program and the accompanying materials
- are licensed and made available under the terms and conditions of the BSD License
- which accompanies this distribution. The full text of the license may be found at
- http://opensource.org/licenses/bsd-license.php
-
- THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
- WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
-
-**/
-
-#include <Base.h>
-
-#include <Library/ArmLib.h>
-#include <Library/DebugLib.h>
-#include <Library/PcdLib.h>
-
-#include "ArmLibPrivate.h"
-
-VOID
-EFIAPI
-ArmCacheInformation (
- OUT ARM_CACHE_INFO *CacheInfo
- )
-{
- if (CacheInfo != NULL) {
- CacheInfo->Type = ArmCacheType();
- CacheInfo->Architecture = ArmCacheArchitecture();
- CacheInfo->DataCachePresent = ArmDataCachePresent();
- CacheInfo->DataCacheSize = ArmDataCacheSize();
- CacheInfo->DataCacheAssociativity = ArmDataCacheAssociativity();
- CacheInfo->DataCacheLineLength = ArmDataCacheLineLength();
- CacheInfo->InstructionCachePresent = ArmInstructionCachePresent();
- CacheInfo->InstructionCacheSize = ArmInstructionCacheSize();
- CacheInfo->InstructionCacheAssociativity = ArmInstructionCacheAssociativity();
- CacheInfo->InstructionCacheLineLength = ArmInstructionCacheLineLength();
- }
-}
-
-VOID
-EFIAPI
-ArmSetAuxCrBit (
- IN UINT32 Bits
- )
-{
- UINT32 val = ArmReadAuxCr();
- val |= Bits;
- ArmWriteAuxCr(val);
-}
diff --git a/ArmPkg/Library/ArmLib/AArch64/ArmLibPrivate.h b/ArmPkg/Library/ArmLib/AArch64/ArmLibPrivate.h
deleted file mode 100644
index d2804fc10..000000000
--- a/ArmPkg/Library/ArmLib/AArch64/ArmLibPrivate.h
+++ /dev/null
@@ -1,82 +0,0 @@
-/** @file
-
- Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
- Copyright (c) 2011 - 2013, ARM Ltd. All rights reserved.<BR>
-
- This program and the accompanying materials
- are licensed and made available under the terms and conditions of the BSD License
- 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 __ARM_LIB_PRIVATE_H__
-#define __ARM_LIB_PRIVATE_H__
-
-#define CACHE_SIZE_4_KB (3UL)
-#define CACHE_SIZE_8_KB (4UL)
-#define CACHE_SIZE_16_KB (5UL)
-#define CACHE_SIZE_32_KB (6UL)
-#define CACHE_SIZE_64_KB (7UL)
-#define CACHE_SIZE_128_KB (8UL)
-
-#define CACHE_ASSOCIATIVITY_DIRECT (0UL)
-#define CACHE_ASSOCIATIVITY_4_WAY (2UL)
-#define CACHE_ASSOCIATIVITY_8_WAY (3UL)
-
-#define CACHE_PRESENT (0UL)
-#define CACHE_NOT_PRESENT (1UL)
-
-#define CACHE_LINE_LENGTH_32_BYTES (2UL)
-
-#define SIZE_FIELD_TO_CACHE_SIZE(x) (((x) >> 6) & 0x0F)
-#define SIZE_FIELD_TO_CACHE_ASSOCIATIVITY(x) (((x) >> 3) & 0x07)
-#define SIZE_FIELD_TO_CACHE_PRESENCE(x) (((x) >> 2) & 0x01)
-#define SIZE_FIELD_TO_CACHE_LINE_LENGTH(x) (((x) >> 0) & 0x03)
-
-#define DATA_CACHE_SIZE_FIELD(x) (((x) >> 12) & 0x0FFF)
-#define INSTRUCTION_CACHE_SIZE_FIELD(x) (((x) >> 0) & 0x0FFF)
-
-#define DATA_CACHE_SIZE(x) (SIZE_FIELD_TO_CACHE_SIZE(DATA_CACHE_SIZE_FIELD(x)))
-#define DATA_CACHE_ASSOCIATIVITY(x) (SIZE_FIELD_TO_CACHE_ASSOCIATIVITY(DATA_CACHE_SIZE_FIELD(x)))
-#define DATA_CACHE_PRESENT(x) (SIZE_FIELD_TO_CACHE_PRESENCE(DATA_CACHE_SIZE_FIELD(x)))
-#define DATA_CACHE_LINE_LENGTH(x) (SIZE_FIELD_TO_CACHE_LINE_LENGTH(DATA_CACHE_SIZE_FIELD(x)))
-
-#define INSTRUCTION_CACHE_SIZE(x) (SIZE_FIELD_TO_CACHE_SIZE(INSTRUCTION_CACHE_SIZE_FIELD(x)))
-#define INSTRUCTION_CACHE_ASSOCIATIVITY(x) (SIZE_FIELD_TO_CACHE_ASSOCIATIVITY(INSTRUCTION_CACHE_SIZE_FIELD(x)))
-#define INSTRUCTION_CACHE_PRESENT(x) (SIZE_FIELD_TO_CACHE_PRESENCE(INSTRUCTION_CACHE_SIZE_FIELD(x)))
-#define INSTRUCTION_CACHE_LINE_LENGTH(x) (SIZE_FIELD_TO_CACHE_LINE_LENGTH(INSTRUCTION_CACHE_SIZE_FIELD(x)))
-
-#define CACHE_TYPE(x) (((x) >> 25) & 0x0F)
-#define CACHE_TYPE_WRITE_BACK (0x0EUL)
-
-#define CACHE_ARCHITECTURE(x) (((x) >> 24) & 0x01)
-#define CACHE_ARCHITECTURE_UNIFIED (0UL)
-#define CACHE_ARCHITECTURE_SEPARATE (1UL)
-
-
-VOID
-CPSRMaskInsert (
- IN UINT32 Mask,
- IN UINT32 Value
- );
-
-UINT32
-CPSRRead (
- VOID
- );
-
-UINT32
-ReadCCSIDR (
- IN UINT32 CSSELR
- );
-
-UINT32
-ReadCLIDR (
- VOID
- );
-
-#endif // __ARM_LIB_PRIVATE_H__
diff --git a/ArmPkg/Library/ArmLib/Arm9/Arm9CacheInformation.c b/ArmPkg/Library/ArmLib/Arm9/Arm9CacheInformation.c
index 6180a47de..19da4db25 100644
--- a/ArmPkg/Library/ArmLib/Arm9/Arm9CacheInformation.c
+++ b/ArmPkg/Library/ArmLib/Arm9/Arm9CacheInformation.c
@@ -1,7 +1,8 @@
/** @file
Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
-
+ Copyright (c) 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
@@ -21,7 +22,7 @@ ArmCacheType (
VOID
)
{
- switch (CACHE_TYPE(Cp15CacheInfo()))
+ switch (CACHE_TYPE (ArmCacheInfo ()))
{
case CACHE_TYPE_WRITE_BACK: return ARM_CACHE_TYPE_WRITE_BACK;
default: return ARM_CACHE_TYPE_UNKNOWN;
@@ -34,7 +35,7 @@ ArmCacheArchitecture (
VOID
)
{
- switch (CACHE_ARCHITECTURE(Cp15CacheInfo()))
+ switch (CACHE_ARCHITECTURE (ArmCacheInfo ()))
{
case CACHE_ARCHITECTURE_UNIFIED: return ARM_CACHE_ARCHITECTURE_UNIFIED;
case CACHE_ARCHITECTURE_SEPARATE: return ARM_CACHE_ARCHITECTURE_SEPARATE;
@@ -48,7 +49,7 @@ ArmDataCachePresent (
VOID
)
{
- switch (DATA_CACHE_PRESENT(Cp15CacheInfo()))
+ switch (DATA_CACHE_PRESENT (ArmCacheInfo ()))
{
case CACHE_PRESENT: return TRUE;
case CACHE_NOT_PRESENT: return FALSE;
@@ -62,7 +63,7 @@ ArmDataCacheSize (
VOID
)
{
- switch (DATA_CACHE_SIZE(Cp15CacheInfo()))
+ switch (DATA_CACHE_SIZE (ArmCacheInfo ()))
{
case CACHE_SIZE_4_KB: return 4 * 1024;
case CACHE_SIZE_8_KB: return 8 * 1024;
@@ -80,7 +81,7 @@ ArmDataCacheAssociativity (
VOID
)
{
- switch (DATA_CACHE_ASSOCIATIVITY(Cp15CacheInfo()))
+ switch (DATA_CACHE_ASSOCIATIVITY (ArmCacheInfo ()))
{
case CACHE_ASSOCIATIVITY_4_WAY: return 4;
case CACHE_ASSOCIATIVITY_DIRECT: return 1;
@@ -94,7 +95,7 @@ ArmDataCacheLineLength (
VOID
)
{
- switch (DATA_CACHE_LINE_LENGTH(Cp15CacheInfo()))
+ switch (DATA_CACHE_LINE_LENGTH (ArmCacheInfo ()))
{
case CACHE_LINE_LENGTH_32_BYTES: return 32;
default: return 0;
@@ -107,7 +108,7 @@ ArmInstructionCachePresent (
VOID
)
{
- switch (INSTRUCTION_CACHE_PRESENT(Cp15CacheInfo()))
+ switch (INSTRUCTION_CACHE_PRESENT (ArmCacheInfo ()))
{
case CACHE_PRESENT: return TRUE;
case CACHE_NOT_PRESENT: return FALSE;
@@ -121,7 +122,7 @@ ArmInstructionCacheSize (
VOID
)
{
- switch (INSTRUCTION_CACHE_SIZE(Cp15CacheInfo()))
+ switch (INSTRUCTION_CACHE_SIZE (ArmCacheInfo ()))
{
case CACHE_SIZE_4_KB: return 4 * 1024;
case CACHE_SIZE_8_KB: return 8 * 1024;
@@ -139,7 +140,7 @@ ArmInstructionCacheAssociativity (
VOID
)
{
- switch (INSTRUCTION_CACHE_ASSOCIATIVITY(Cp15CacheInfo()))
+ switch (INSTRUCTION_CACHE_ASSOCIATIVITY (ArmCacheInfo ()))
{
case CACHE_ASSOCIATIVITY_8_WAY: return 8;
case CACHE_ASSOCIATIVITY_4_WAY: return 4;
@@ -154,7 +155,7 @@ ArmInstructionCacheLineLength (
VOID
)
{
- switch (INSTRUCTION_CACHE_LINE_LENGTH(Cp15CacheInfo()))
+ switch (INSTRUCTION_CACHE_LINE_LENGTH (ArmCacheInfo ()))
{
case CACHE_LINE_LENGTH_32_BYTES: return 32;
default: return 0;
diff --git a/ArmPkg/Library/ArmLib/Common/AArch64/ArmLibSupport.S b/ArmPkg/Library/ArmLib/Common/AArch64/ArmLibSupport.S
index 12e6d0c82..28db98b41 100644
--- a/ArmPkg/Library/ArmLib/Common/AArch64/ArmLibSupport.S
+++ b/ArmPkg/Library/ArmLib/Common/AArch64/ArmLibSupport.S
@@ -37,6 +37,8 @@ GCC_ASM_EXPORT (ArmWriteScr)
GCC_ASM_EXPORT (ArmWriteMVBar)
GCC_ASM_EXPORT (ArmCallWFE)
GCC_ASM_EXPORT (ArmCallSEV)
+GCC_ASM_EXPORT (ArmReadCpuActlr)
+GCC_ASM_EXPORT (ArmWriteCpuActlr)
#------------------------------------------------------------------------------
@@ -196,5 +198,14 @@ ASM_PFX(ArmCallSEV):
sev
ret
+ASM_PFX(ArmReadCpuActlr):
+ mrs x0, S3_1_c15_c2_0
+ ret
+
+ASM_PFX(ArmWriteCpuActlr):
+ msr S3_1_c15_c2_0, x0
+ dsb sy
+ isb
+ ret
ASM_FUNCTION_REMOVE_IF_UNREFERENCED
diff --git a/ArmPkg/Library/ArmLib/Common/Arm/ArmLibSupport.S b/ArmPkg/Library/ArmLib/Common/Arm/ArmLibSupport.S
index a3de902cc..08a433cc8 100644
--- a/ArmPkg/Library/ArmLib/Common/Arm/ArmLibSupport.S
+++ b/ArmPkg/Library/ArmLib/Common/Arm/ArmLibSupport.S
@@ -24,7 +24,7 @@
.text
.align 2
GCC_ASM_EXPORT(ArmReadMidr)
-GCC_ASM_EXPORT(Cp15CacheInfo)
+GCC_ASM_EXPORT(ArmCacheInfo)
GCC_ASM_EXPORT(ArmGetInterruptState)
GCC_ASM_EXPORT(ArmGetFiqState)
GCC_ASM_EXPORT(ArmGetTTBR0BaseAddress)
@@ -47,6 +47,8 @@ GCC_ASM_EXPORT(ArmWriteHVBar)
GCC_ASM_EXPORT(ArmCallWFE)
GCC_ASM_EXPORT(ArmCallSEV)
GCC_ASM_EXPORT(ArmReadSctlr)
+GCC_ASM_EXPORT(ArmReadCpuActlr)
+GCC_ASM_EXPORT(ArmWriteCpuActlr)
#------------------------------------------------------------------------------
@@ -54,7 +56,7 @@ ASM_PFX(ArmReadMidr):
mrc p15,0,R0,c0,c0,0
bx LR
-ASM_PFX(Cp15CacheInfo):
+ASM_PFX(ArmCacheInfo):
mrc p15,0,R0,c0,c0,1
bx LR
@@ -161,7 +163,6 @@ ASM_PFX(ArmWriteHVBar):
mcr p15, 4, r0, c12, c0, 0
bx lr
-
ASM_PFX(ArmReadMVBar):
mrc p15, 0, r0, c12, c0, 1
bx lr
@@ -179,7 +180,17 @@ ASM_PFX(ArmCallSEV):
bx lr
ASM_PFX(ArmReadSctlr):
- mrc p15, 0, R0, c1, c0, 0 @ Read SCTLR into R0 (Read control register configuration data)
- bx lr
+ mrc p15, 0, r0, c1, c0, 0 @ Read SCTLR into R0 (Read control register configuration data)
+ bx lr
+
+ASM_PFX(ArmReadCpuActlr):
+ mrc p15, 0, r0, c1, c0, 1
+ bx lr
+
+ASM_PFX(ArmWriteCpuActlr):
+ mcr p15, 0, r0, c1, c0, 1
+ dsb
+ isb
+ bx lr
ASM_FUNCTION_REMOVE_IF_UNREFERENCED
diff --git a/ArmPkg/Library/ArmLib/Common/Arm/ArmLibSupport.asm b/ArmPkg/Library/ArmLib/Common/Arm/ArmLibSupport.asm
index cb69f71bc..9e6d57ef6 100644
--- a/ArmPkg/Library/ArmLib/Common/Arm/ArmLibSupport.asm
+++ b/ArmPkg/Library/ArmLib/Common/Arm/ArmLibSupport.asm
@@ -24,7 +24,7 @@
#endif
EXPORT ArmReadMidr
- EXPORT Cp15CacheInfo
+ EXPORT ArmCacheInfo
EXPORT ArmGetInterruptState
EXPORT ArmGetFiqState
EXPORT ArmGetTTBR0BaseAddress
@@ -47,6 +47,8 @@
EXPORT ArmCallWFE
EXPORT ArmCallSEV
EXPORT ArmReadSctlr
+ EXPORT ArmReadCpuActlr
+ EXPORT ArmWriteCpuActlr
AREA ArmLibSupport, CODE, READONLY
@@ -54,7 +56,7 @@ ArmReadMidr
mrc p15,0,R0,c0,c0,0
bx LR
-Cp15CacheInfo
+ArmCacheInfo
mrc p15,0,R0,c0,c0,1
bx LR
@@ -179,6 +181,17 @@ ArmCallSEV
ArmReadSctlr
mrc p15, 0, r0, c1, c0, 0 // Read SCTLR into R0 (Read control register configuration data)
- bx lr
+ bx lr
+
+
+ArmReadCpuActlr
+ mrc p15, 0, r0, c1, c0, 1
+ bx lr
+
+ArmWriteCpuActlr
+ mcr p15, 0, r0, c1, c0, 1
+ dsb
+ isb
+ bx lr
END
diff --git a/ArmPkg/Library/ArmLib/Common/ArmLib.c b/ArmPkg/Library/ArmLib/Common/ArmLib.c
index a7b9551ba..72d5af4a5 100644
--- a/ArmPkg/Library/ArmLib/Common/ArmLib.c
+++ b/ArmPkg/Library/ArmLib/Common/ArmLib.c
@@ -1,7 +1,7 @@
/** @file
Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
- Copyright (c) 2011 - 2012, ARM Ltd. All rights reserved.<BR>
+ Copyright (c) 2011 - 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
@@ -43,41 +43,50 @@ ArmCacheInformation (
VOID
EFIAPI
-ArmSwitchProcessorMode (
- IN ARM_PROCESSOR_MODE Mode
+ArmSetAuxCrBit (
+ IN UINT32 Bits
)
{
- CPSRMaskInsert(ARM_PROCESSOR_MODE_MASK, Mode);
+ UINT32 val = ArmReadAuxCr();
+ val |= Bits;
+ ArmWriteAuxCr(val);
}
-
-ARM_PROCESSOR_MODE
+VOID
EFIAPI
-ArmProcessorMode (
- VOID
+ArmUnsetAuxCrBit (
+ IN UINT32 Bits
)
{
- return (ARM_PROCESSOR_MODE)(CPSRRead() & (UINT32)ARM_PROCESSOR_MODE_MASK);
+ UINT32 val = ArmReadAuxCr();
+ val &= ~Bits;
+ ArmWriteAuxCr(val);
}
+//
+// Helper functions for accessing CPUACTLR
+//
+
VOID
EFIAPI
-ArmSetAuxCrBit (
- IN UINT32 Bits
+ArmSetCpuActlrBit (
+ IN UINTN Bits
)
{
- UINT32 val = ArmReadAuxCr();
- val |= Bits;
- ArmWriteAuxCr(val);
+ UINTN Value;
+ Value = ArmReadCpuActlr ();
+ Value |= Bits;
+ ArmWriteCpuActlr (Value);
}
VOID
EFIAPI
-ArmUnsetAuxCrBit (
- IN UINT32 Bits
+ArmUnsetCpuActlrBit (
+ IN UINTN Bits
)
{
- UINT32 val = ArmReadAuxCr();
- val &= ~Bits;
- ArmWriteAuxCr(val);
+ UINTN Value;
+ Value = ArmReadCpuActlr ();
+ Value &= ~Bits;
+ ArmWriteCpuActlr (Value);
}
diff --git a/ArmPkg/Library/BdsLib/BdsHelper.c b/ArmPkg/Library/BdsLib/BdsHelper.c
index fb2ac9b80..1d4aa3572 100644
--- a/ArmPkg/Library/BdsLib/BdsHelper.c
+++ b/ArmPkg/Library/BdsLib/BdsHelper.c
@@ -331,7 +331,7 @@ GetEnvironmentVariable (
*Size,
DefaultValue
);
- *Value = DefaultValue;
+ *Value = AllocateCopyPool (*Size, DefaultValue);
} else {
return EFI_NOT_FOUND;
}
@@ -352,7 +352,7 @@ GetEnvironmentVariable (
*Size = VariableSize;
}
} else {
- *Value = DefaultValue;
+ *Value = AllocateCopyPool (*Size, DefaultValue);
return Status;
}
diff --git a/ArmPkg/Library/CompilerIntrinsicsLib/AArch64/memset.c b/ArmPkg/Library/CompilerIntrinsicsLib/AArch64/memset.c
new file mode 100644
index 000000000..069c932a6
--- /dev/null
+++ b/ArmPkg/Library/CompilerIntrinsicsLib/AArch64/memset.c
@@ -0,0 +1,25 @@
+/** @file
+
+ 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 <Base.h>
+
+void *memset(void *Destination, int Value, int Count)
+{
+ CHAR8 *Ptr = Destination;
+
+ while (Count--)
+ *Ptr++ = Value;
+
+ return Destination;
+}
diff --git a/ArmPkg/Library/CompilerIntrinsicsLib/CompilerIntrinsicsLib.inf b/ArmPkg/Library/CompilerIntrinsicsLib/CompilerIntrinsicsLib.inf
index 3e95105cd..d230da296 100644
--- a/ArmPkg/Library/CompilerIntrinsicsLib/CompilerIntrinsicsLib.inf
+++ b/ArmPkg/Library/CompilerIntrinsicsLib/CompilerIntrinsicsLib.inf
@@ -24,6 +24,7 @@
[Sources.AARCH64]
AArch64/memcpy.S | GCC
+ AArch64/memset.c
[Sources.ARM]
Arm/mullu.asm | RVCT
diff --git a/ArmPkg/Library/SemihostLib/SemihostLib.c b/ArmPkg/Library/SemihostLib/SemihostLib.c
index 87c0379d6..53405edd7 100644
--- a/ArmPkg/Library/SemihostLib/SemihostLib.c
+++ b/ArmPkg/Library/SemihostLib/SemihostLib.c
@@ -1,7 +1,8 @@
/** @file
Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
-
+ Copyright (c) 2013 - 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
@@ -73,10 +74,12 @@ SemihostFileSeek (
Result = Semihost_SYS_SEEK(&SeekBlock);
- if (Result == 0) {
- return RETURN_SUCCESS;
- } else {
+ // Semihosting does not behave as documented. It returns the offset on
+ // success.
+ if (Result < 0) {
return RETURN_ABORTED;
+ } else {
+ return RETURN_SUCCESS;
}
}
@@ -100,7 +103,7 @@ SemihostFileRead (
Result = Semihost_SYS_READ(&ReadBlock);
- if (Result == *Length) {
+ if ((*Length != 0) && (Result == *Length)) {
return RETURN_ABORTED;
} else {
*Length -= Result;
@@ -126,8 +129,11 @@ SemihostFileWrite (
WriteBlock.Length = *Length;
*Length = Semihost_SYS_WRITE(&WriteBlock);
-
- return RETURN_SUCCESS;
+
+ if (*Length != 0)
+ return RETURN_ABORTED;
+ else
+ return RETURN_SUCCESS;
}
RETURN_STATUS
@@ -174,6 +180,11 @@ SemihostFileRemove (
SEMIHOST_FILE_REMOVE_BLOCK RemoveBlock;
UINT32 Result;
+ // Remove any leading separator (e.g.: '\'). EFI Shell adds one.
+ if (*FileName == '\\') {
+ FileName++;
+ }
+
RemoveBlock.FileName = FileName;
RemoveBlock.NameLength = AsciiStrLen(FileName);
diff --git a/ArmPkg/Library/SemihostLib/SemihostPrivate.h b/ArmPkg/Library/SemihostLib/SemihostPrivate.h
index 02836ca28..c4bc4c0ec 100644
--- a/ArmPkg/Library/SemihostLib/SemihostPrivate.h
+++ b/ArmPkg/Library/SemihostLib/SemihostPrivate.h
@@ -1,6 +1,7 @@
/** @file
Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
+ Copyright (c) 2013 - 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
@@ -17,29 +18,29 @@
typedef struct {
CHAR8 *FileName;
- UINT32 Mode;
- UINT32 NameLength;
+ UINTN Mode;
+ UINTN NameLength;
} SEMIHOST_FILE_OPEN_BLOCK;
typedef struct {
- UINT32 Handle;
+ UINTN Handle;
VOID *Buffer;
- UINT32 Length;
+ UINTN Length;
} SEMIHOST_FILE_READ_WRITE_BLOCK;
typedef struct {
- UINT32 Handle;
- UINT32 Location;
+ UINTN Handle;
+ UINTN Location;
} SEMIHOST_FILE_SEEK_BLOCK;
typedef struct {
CHAR8 *FileName;
- UINT32 NameLength;
+ UINTN NameLength;
} SEMIHOST_FILE_REMOVE_BLOCK;
typedef struct {
CHAR8 *CommandLine;
- UINT32 CommandLength;
+ UINTN CommandLength;
} SEMIHOST_SYSTEM_BLOCK;
#if defined(__CC_ARM)
diff --git a/ArmPlatformPkg/ArmJunoPkg/ArmJuno.dec b/ArmPlatformPkg/ArmJunoPkg/ArmJuno.dec
new file mode 100755
index 000000000..ac23bcd36
--- /dev/null
+++ b/ArmPlatformPkg/ArmJunoPkg/ArmJuno.dec
@@ -0,0 +1,40 @@
+#
+# Copyright (c) 2013-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]
+ DEC_SPECIFICATION = 0x00010005
+ PACKAGE_NAME = ArmJunoPkg
+ PACKAGE_GUID = a1147a20-3144-4f8d-8295-b48311c8e4a4
+ PACKAGE_VERSION = 0.1
+
+################################################################################
+#
+# Include Section - list of Include Paths that are provided by this package.
+# Comments are used for Keywords and Module Types.
+#
+# Supported Module Types:
+# BASE SEC PEI_CORE PEIM DXE_CORE DXE_DRIVER DXE_RUNTIME_DRIVER DXE_SMM_DRIVER DXE_SAL_DRIVER UEFI_DRIVER UEFI_APPLICATION
+#
+################################################################################
+[Includes.common]
+ Include # Root include for the package
+
+[Guids.common]
+ 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
new file mode 100755
index 000000000..80148dc7e
--- /dev/null
+++ b/ArmPlatformPkg/ArmJunoPkg/ArmJuno.dsc
@@ -0,0 +1,230 @@
+#
+# Copyright (c) 2013-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 Section - statements that will be processed to create a Makefile.
+#
+################################################################################
+[Defines]
+ PLATFORM_NAME = ArmJuno
+ PLATFORM_GUID = ca0722fd-7d3d-45ea-948c-d62b2199807d
+ PLATFORM_VERSION = 0.1
+ DSC_SPECIFICATION = 0x00010005
+ OUTPUT_DIRECTORY = Build/ArmJuno
+ SUPPORTED_ARCHITECTURES = AARCH64
+ BUILD_TARGETS = DEBUG|RELEASE
+ SKUID_IDENTIFIER = DEFAULT
+ FLASH_DEFINITION = ArmPlatformPkg/ArmJunoPkg/ArmJuno.fdf
+
+# On RTSM, most peripherals are VExpress Motherboard peripherals
+!include ArmPlatformPkg/ArmVExpressPkg/ArmVExpress.dsc.inc
+
+[LibraryClasses.common]
+ ArmLib|ArmPkg/Library/ArmLib/AArch64/AArch64Lib.inf
+ ArmPlatformLib|ArmPlatformPkg/ArmJunoPkg/Library/ArmJunoLib/ArmJunoLib.inf
+ ArmSmcLib|ArmPkg/Library/ArmSmcLib/ArmSmcLib.inf
+
+ ArmPlatformSysConfigLib|ArmPlatformPkg/ArmVExpressPkg/Library/ArmVExpressSysConfigLib/ArmVExpressSysConfigLib.inf
+ NorFlashPlatformLib|ArmPlatformPkg/ArmJunoPkg/Library/NorFlashJunoLib/NorFlashJunoLib.inf
+ EfiResetSystemLib|ArmPlatformPkg/ArmJunoPkg/Library/ResetSystemLib/ResetSystemLib.inf
+
+ TimerLib|ArmPkg/Library/ArmArchTimerLib/ArmArchTimerLib.inf
+
+ # USB Requirements
+ UefiUsbLib|MdePkg/Library/UefiUsbLib/UefiUsbLib.inf
+
+[LibraryClasses.common.SEC]
+ PrePiLib|EmbeddedPkg/Library/PrePiLib/PrePiLib.inf
+ ExtractGuidedSectionLib|EmbeddedPkg/Library/PrePiExtractGuidedSectionLib/PrePiExtractGuidedSectionLib.inf
+ LzmaDecompressLib|IntelFrameworkModulePkg/Library/LzmaCustomDecompressLib/LzmaCustomDecompressLib.inf
+ MemoryAllocationLib|EmbeddedPkg/Library/PrePiMemoryAllocationLib/PrePiMemoryAllocationLib.inf
+ HobLib|EmbeddedPkg/Library/PrePiHobLib/PrePiHobLib.inf
+ PrePiHobListPointerLib|ArmPlatformPkg/Library/PrePiHobListPointerLib/PrePiHobListPointerLib.inf
+ PerformanceLib|MdeModulePkg/Library/PeiPerformanceLib/PeiPerformanceLib.inf
+ PlatformPeiLib|ArmPlatformPkg/PlatformPei/PlatformPeiLib.inf
+ MemoryInitPeiLib|ArmPlatformPkg/MemoryInitPei/MemoryInitPeiLib.inf
+
+[BuildOptions]
+ GCC:*_*_AARCH64_PLATFORM_FLAGS == -I$(WORKSPACE)/ArmPlatformPkg/ArmVExpressPkg/Include -I$(WORKSPACE)/ArmPlatformPkg/ArmJunoPkg/Include
+
+################################################################################
+#
+# Pcd Section - list of all EDK II PCD Entries defined by this Platform
+#
+################################################################################
+
+[PcdsFeatureFlag.common]
+ gArmPlatformTokenSpaceGuid.PcdSystemMemoryInitializeInSec|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|TRUE
+
+ gArmTokenSpaceGuid.PcdArmPsciSupport|TRUE
+
+ gEfiMdeModulePkgTokenSpaceGuid.PcdTurnOffUsbLegacySupport|TRUE
+
+[PcdsFixedAtBuild.common]
+ gArmPlatformTokenSpaceGuid.PcdFirmwareVendor|"ARM Juno"
+ gEfiMdeModulePkgTokenSpaceGuid.PcdFirmwareVersionString|L"0.1"
+ gEmbeddedTokenSpaceGuid.PcdEmbeddedPrompt|"ArmJuno"
+
+ #
+ # NV Storage PCDs. Use base of 0x08000000 for NOR0
+ #
+ gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase|0x0BFC0000
+ gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize|0x00010000
+ gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingBase|0x0BFD0000
+ gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingSize|0x00010000
+ gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareBase|0x0BFE0000
+ gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize|0x00010000
+
+ # System Memory (2GB)
+ gArmTokenSpaceGuid.PcdSystemMemoryBase|0x80000000
+ gArmTokenSpaceGuid.PcdSystemMemorySize|0x80000000
+
+ # Juno Dual-Cluster profile
+ gArmPlatformTokenSpaceGuid.PcdCoreCount|6
+ gArmPlatformTokenSpaceGuid.PcdClusterCount|2
+
+ gArmTokenSpaceGuid.PcdVFPEnabled|1
+
+ #
+ # ARM PrimeCell
+ #
+
+ ## PL011 - Serial Terminal
+ gEfiMdeModulePkgTokenSpaceGuid.PcdSerialRegisterBase|0x7FF80000
+ gEfiMdePkgTokenSpaceGuid.PcdUartDefaultBaudRate|115200
+ gArmPlatformTokenSpaceGuid.PL011UartInteger|4
+ gArmPlatformTokenSpaceGuid.PL011UartFractional|0
+
+ ## PL031 RealTimeClock
+ gArmPlatformTokenSpaceGuid.PcdPL031RtcBase|0x1C170000
+
+ #
+ # ARM General Interrupt Controller
+ #
+ gArmTokenSpaceGuid.PcdGicDistributorBase|0x2C010000
+ gArmTokenSpaceGuid.PcdGicInterruptInterfaceBase|0x2C02F000
+
+ # List of Device Paths that support BootMonFs
+ gArmPlatformTokenSpaceGuid.PcdBootMonFsSupportedDevicePaths|L"VenHw(E7223039-5836-41E1-B542-D7EC736C5E59)"
+
+ #
+ # ARM OS Loader
+ #
+ gArmPlatformTokenSpaceGuid.PcdDefaultBootDescription|L"Linux from NOR Flash"
+ gArmPlatformTokenSpaceGuid.PcdDefaultBootDevicePath|L"VenHw(E7223039-5836-41E1-B542-D7EC736C5E59)/Image"
+ gArmPlatformTokenSpaceGuid.PcdFdtDevicePath|L"VenHw(E7223039-5836-41E1-B542-D7EC736C5E59)/juno"
+ gArmPlatformTokenSpaceGuid.PcdDefaultBootArgument|"console=ttyAMA0,115200 earlyprintk=pl011,0x7ff80000 root=/dev/sda1 rootwait verbose debug"
+ gArmPlatformTokenSpaceGuid.PcdDefaultBootType|2
+
+ # 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(CE660500-824D-11E0-AC72-0002A5D5C51B)"
+ gArmPlatformTokenSpaceGuid.PcdDefaultConInPaths|L"VenHw(D3987D4B-971A-435F-8CAF-4967EB627241)/Uart(115200,8,N,1)/VenPcAnsi()"
+
+ #
+ # ARM Architectural Timer Frequency
+ #
+ gArmTokenSpaceGuid.PcdArmArchTimerFreqInHz|50000000
+ gEmbeddedTokenSpaceGuid.PcdMetronomeTickPeriod|1000
+
+[PcdsPatchableInModule]
+ # Console Resolution (Full HD)
+ gEfiMdeModulePkgTokenSpaceGuid.PcdVideoHorizontalResolution|1920
+ gEfiMdeModulePkgTokenSpaceGuid.PcdVideoVerticalResolution|1080
+
+
+################################################################################
+#
+# Components Section - list of all EDK II Modules needed by this Platform
+#
+################################################################################
+[Components.common]
+ #
+ # PEI Phase modules
+ #
+ ArmPlatformPkg/PrePi/PeiMPCore.inf {
+ <LibraryClasses>
+ ArmPlatformGlobalVariableLib|ArmPlatformPkg/Library/ArmPlatformGlobalVariableLib/PrePi/PrePiArmPlatformGlobalVariableLib.inf
+ }
+
+ #
+ # DXE
+ #
+ MdeModulePkg/Core/Dxe/DxeMain.inf {
+ <LibraryClasses>
+ PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
+ NULL|MdeModulePkg/Library/DxeCrc32GuidedSectionExtractLib/DxeCrc32GuidedSectionExtractLib.inf
+ }
+
+ #
+ # Architectural Protocols
+ #
+ ArmPkg/Drivers/CpuDxe/CpuDxe.inf
+ MdeModulePkg/Core/RuntimeDxe/RuntimeDxe.inf
+ MdeModulePkg/Universal/SecurityStubDxe/SecurityStubDxe.inf
+ MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleRuntimeDxe.inf
+ MdeModulePkg/Universal/MonotonicCounterRuntimeDxe/MonotonicCounterRuntimeDxe.inf
+ EmbeddedPkg/ResetRuntimeDxe/ResetRuntimeDxe.inf
+ EmbeddedPkg/RealTimeClockRuntimeDxe/RealTimeClockRuntimeDxe.inf
+ EmbeddedPkg/MetronomeDxe/MetronomeDxe.inf
+
+ MdeModulePkg/Universal/Console/ConPlatformDxe/ConPlatformDxe.inf
+ MdeModulePkg/Universal/Console/ConSplitterDxe/ConSplitterDxe.inf
+ MdeModulePkg/Universal/Console/GraphicsConsoleDxe/GraphicsConsoleDxe.inf
+ MdeModulePkg/Universal/Console/TerminalDxe/TerminalDxe.inf
+ EmbeddedPkg/SerialDxe/SerialDxe.inf
+
+ MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf
+ MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteDxe.inf
+
+ MdeModulePkg/Universal/HiiDatabaseDxe/HiiDatabaseDxe.inf
+
+ ArmPkg/Drivers/ArmGic/ArmGicDxe.inf
+ ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashDxe.inf
+ ArmPkg/Drivers/TimerDxe/TimerDxe.inf
+ ArmPlatformPkg/ArmJunoPkg/Drivers/GenericWatchdogDxe/GenericWatchdogDxe.inf
+
+ #
+ # Semi-hosting filesystem
+ #
+ ArmPkg/Filesystem/SemihostFs/SemihostFs.inf
+
+ #
+ # FAT filesystem + GPT/MBR partitioning
+ #
+ MdeModulePkg/Universal/Disk/DiskIoDxe/DiskIoDxe.inf
+ MdeModulePkg/Universal/Disk/PartitionDxe/PartitionDxe.inf
+ MdeModulePkg/Universal/Disk/UnicodeCollation/EnglishDxe/EnglishDxe.inf
+
+ #
+ # Usb Support
+ #
+ MdeModulePkg/Bus/Pci/EhciDxe/EhciDxe.inf
+ MdeModulePkg/Bus/Usb/UsbBusDxe/UsbBusDxe.inf
+ MdeModulePkg/Bus/Usb/UsbKbDxe/UsbKbDxe.inf
+ MdeModulePkg/Bus/Usb/UsbMouseDxe/UsbMouseDxe.inf
+ MdeModulePkg/Bus/Usb/UsbMassStorageDxe/UsbMassStorageDxe.inf
+
+ #
+ # Juno platform driver
+ #
+ ArmPlatformPkg/ArmJunoPkg/Drivers/ArmJunoDxe/ArmJunoDxe.inf
+
+ #
+ # Bds
+ #
+ MdeModulePkg/Universal/DevicePathDxe/DevicePathDxe.inf
+ ArmPlatformPkg/Bds/Bds.inf
diff --git a/ArmPlatformPkg/ArmJunoPkg/ArmJuno.fdf b/ArmPlatformPkg/ArmJunoPkg/ArmJuno.fdf
new file mode 100755
index 000000000..64835d4a5
--- /dev/null
+++ b/ArmPlatformPkg/ArmJunoPkg/ArmJuno.fdf
@@ -0,0 +1,287 @@
+#
+# Copyright (c) 2013-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.
+#
+
+################################################################################
+#
+# FD Section
+# The [FD] Section is made up of the definition statements and a
+# description of what goes into the Flash Device Image. Each FD section
+# defines one flash "device" image. A flash device image may be one of
+# the following: Removable media bootable image (like a boot floppy
+# image,) an Option ROM image (that would be "flashed" into an add-in
+# card,) a System "Flash" image (that would be burned into a system's
+# flash) or an Update ("Capsule") image that will be used to update and
+# existing system flash.
+#
+################################################################################
+
+[FD.BL32_AP_UEFI]
+BaseAddress = 0xE0000000|gArmTokenSpaceGuid.PcdFdBaseAddress # The base address of the Firmware in NOR Flash.
+Size = 0x000F0000|gArmTokenSpaceGuid.PcdFdSize # The size in bytes of the FLASH Device
+ErasePolarity = 1
+
+# This one is tricky, it must be: BlockSize * NumBlocks = Size
+BlockSize = 0x00001000
+NumBlocks = 0xF0
+
+################################################################################
+#
+# Following are lists of FD Region layout which correspond to the locations of different
+# images within the flash device.
+#
+# Regions must be defined in ascending order and may not overlap.
+#
+# A Layout Region start with a eight digit hex offset (leading "0x" required) followed by
+# the pipe "|" character, followed by the size of the region, also in hex with the leading
+# "0x" characters. Like:
+# Offset|Size
+# PcdOffsetCName|PcdSizeCName
+# RegionType <FV, DATA, or FILE>
+#
+################################################################################
+
+0x00000000|0x000F0000
+gArmTokenSpaceGuid.PcdFvBaseAddress|gArmTokenSpaceGuid.PcdFvSize
+FV = FVMAIN_COMPACT
+
+
+################################################################################
+#
+# FV Section
+#
+# [FV] section is used to define what components or modules are placed within a flash
+# device file. This section also defines order the components and modules are positioned
+# within the image. The [FV] section consists of define statements, set statements and
+# module statements.
+#
+################################################################################
+
+[FV.FvMain]
+BlockSize = 0x40
+NumBlocks = 0 # This FV gets compressed so make it just big enough
+FvAlignment = 8 # FV alignment and FV attributes setting.
+ERASE_POLARITY = 1
+MEMORY_MAPPED = TRUE
+STICKY_WRITE = TRUE
+LOCK_CAP = TRUE
+LOCK_STATUS = TRUE
+WRITE_DISABLED_CAP = TRUE
+WRITE_ENABLED_CAP = TRUE
+WRITE_STATUS = TRUE
+WRITE_LOCK_CAP = TRUE
+WRITE_LOCK_STATUS = TRUE
+READ_DISABLED_CAP = TRUE
+READ_ENABLED_CAP = TRUE
+READ_STATUS = TRUE
+READ_LOCK_CAP = TRUE
+READ_LOCK_STATUS = TRUE
+
+ INF MdeModulePkg/Core/Dxe/DxeMain.inf
+
+ #
+ # PI DXE Drivers producing Architectural Protocols (EFI Services)
+ #
+ INF ArmPkg/Drivers/CpuDxe/CpuDxe.inf
+ INF MdeModulePkg/Core/RuntimeDxe/RuntimeDxe.inf
+ INF MdeModulePkg/Universal/SecurityStubDxe/SecurityStubDxe.inf
+ INF MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleRuntimeDxe.inf
+ INF MdeModulePkg/Universal/MonotonicCounterRuntimeDxe/MonotonicCounterRuntimeDxe.inf
+ INF EmbeddedPkg/ResetRuntimeDxe/ResetRuntimeDxe.inf
+ INF EmbeddedPkg/RealTimeClockRuntimeDxe/RealTimeClockRuntimeDxe.inf
+ INF EmbeddedPkg/MetronomeDxe/MetronomeDxe.inf
+
+ INF MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf
+ INF MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteDxe.inf
+
+ INF MdeModulePkg/Universal/HiiDatabaseDxe/HiiDatabaseDxe.inf
+
+ #
+ # Multiple Console IO support
+ #
+ INF MdeModulePkg/Universal/Console/ConPlatformDxe/ConPlatformDxe.inf
+ INF MdeModulePkg/Universal/Console/ConSplitterDxe/ConSplitterDxe.inf
+ INF MdeModulePkg/Universal/Console/GraphicsConsoleDxe/GraphicsConsoleDxe.inf
+ INF MdeModulePkg/Universal/Console/TerminalDxe/TerminalDxe.inf
+ INF EmbeddedPkg/SerialDxe/SerialDxe.inf
+
+ INF ArmPkg/Drivers/ArmGic/ArmGicDxe.inf
+ INF ArmPkg/Drivers/TimerDxe/TimerDxe.inf
+ INF ArmPlatformPkg/ArmJunoPkg/Drivers/GenericWatchdogDxe/GenericWatchdogDxe.inf
+
+ # NOR Flash driver
+ INF ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashDxe.inf
+
+ # Versatile Express FileSystem
+ INF ArmPlatformPkg/FileSystem/BootMonFs/BootMonFs.inf
+
+ #
+ # FAT filesystem + GPT/MBR partitioning
+ #
+ INF MdeModulePkg/Universal/Disk/DiskIoDxe/DiskIoDxe.inf
+ INF MdeModulePkg/Universal/Disk/PartitionDxe/PartitionDxe.inf
+ INF FatBinPkg/EnhancedFatDxe/Fat.inf
+ INF MdeModulePkg/Universal/Disk/UnicodeCollation/EnglishDxe/EnglishDxe.inf
+
+ #
+ # Usb Support
+ #
+ INF MdeModulePkg/Bus/Pci/EhciDxe/EhciDxe.inf
+ INF MdeModulePkg/Bus/Usb/UsbBusDxe/UsbBusDxe.inf
+ INF MdeModulePkg/Bus/Usb/UsbKbDxe/UsbKbDxe.inf
+ INF MdeModulePkg/Bus/Usb/UsbMassStorageDxe/UsbMassStorageDxe.inf
+ INF MdeModulePkg/Bus/Usb/UsbMouseDxe/UsbMouseDxe.inf
+
+ #
+ # UEFI applications
+ #
+ INF ShellBinPkg/UefiShell/UefiShell.inf
+
+ #
+ # Juno platform driver
+ #
+ INF ArmPlatformPkg/ArmJunoPkg/Drivers/ArmJunoDxe/ArmJunoDxe.inf
+
+ #
+ # Bds
+ #
+ INF MdeModulePkg/Universal/DevicePathDxe/DevicePathDxe.inf
+ INF ArmPlatformPkg/Bds/Bds.inf
+
+[FV.FVMAIN_COMPACT]
+FvAlignment = 8
+ERASE_POLARITY = 1
+MEMORY_MAPPED = TRUE
+STICKY_WRITE = TRUE
+LOCK_CAP = TRUE
+LOCK_STATUS = TRUE
+WRITE_DISABLED_CAP = TRUE
+WRITE_ENABLED_CAP = TRUE
+WRITE_STATUS = TRUE
+WRITE_LOCK_CAP = TRUE
+WRITE_LOCK_STATUS = TRUE
+READ_DISABLED_CAP = TRUE
+READ_ENABLED_CAP = TRUE
+READ_STATUS = TRUE
+READ_LOCK_CAP = TRUE
+READ_LOCK_STATUS = TRUE
+
+ INF ArmPlatformPkg/PrePi/PeiMPCore.inf
+
+ FILE FV_IMAGE = 9E21FD93-9C72-4c15-8C4B-E77F1DB2D792 {
+ SECTION GUIDED EE4E5898-3914-4259-9D6E-DC7BD79403CF PROCESSING_REQUIRED = TRUE {
+ SECTION FV_IMAGE = FVMAIN
+ }
+ }
+
+
+################################################################################
+#
+# Rules are use with the [FV] section's module INF type to define
+# how an FFS file is created for a given INF file. The following Rule are the default
+# rules for the different module type. User can add the customized rules to define the
+# content of the FFS file.
+#
+################################################################################
+
+
+############################################################################
+# Example of a DXE_DRIVER FFS file with a Checksum encapsulation section #
+############################################################################
+#
+#[Rule.Common.DXE_DRIVER]
+# FILE DRIVER = $(NAMED_GUID) {
+# DXE_DEPEX DXE_DEPEX Optional $(INF_OUTPUT)/$(MODULE_NAME).depex
+# COMPRESS PI_STD {
+# GUIDED {
+# PE32 PE32 $(INF_OUTPUT)/$(MODULE_NAME).efi
+# UI STRING="$(MODULE_NAME)" Optional
+# VERSION STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
+# }
+# }
+# }
+#
+############################################################################
+
+[Rule.Common.SEC]
+ FILE SEC = $(NAMED_GUID) RELOCS_STRIPPED {
+ TE TE Align = 1K $(INF_OUTPUT)/$(MODULE_NAME).efi
+ }
+
+[Rule.Common.PEI_CORE]
+ FILE PEI_CORE = $(NAMED_GUID) {
+ TE TE $(INF_OUTPUT)/$(MODULE_NAME).efi
+ UI STRING ="$(MODULE_NAME)" Optional
+ }
+
+[Rule.Common.PEIM]
+ FILE PEIM = $(NAMED_GUID) {
+ PEI_DEPEX PEI_DEPEX Optional $(INF_OUTPUT)/$(MODULE_NAME).depex
+ TE TE $(INF_OUTPUT)/$(MODULE_NAME).efi
+ UI STRING="$(MODULE_NAME)" Optional
+ }
+
+[Rule.Common.PEIM.TIANOCOMPRESSED]
+ FILE PEIM = $(NAMED_GUID) DEBUG_MYTOOLS_IA32 {
+ PEI_DEPEX PEI_DEPEX Optional $(INF_OUTPUT)/$(MODULE_NAME).depex
+ GUIDED A31280AD-481E-41B6-95E8-127F4C984779 PROCESSING_REQUIRED = TRUE {
+ PE32 PE32 $(INF_OUTPUT)/$(MODULE_NAME).efi
+ UI STRING="$(MODULE_NAME)" Optional
+ }
+ }
+
+[Rule.Common.DXE_CORE]
+ FILE DXE_CORE = $(NAMED_GUID) {
+ PE32 PE32 $(INF_OUTPUT)/$(MODULE_NAME).efi
+ UI STRING="$(MODULE_NAME)" Optional
+ }
+
+[Rule.Common.UEFI_DRIVER]
+ FILE DRIVER = $(NAMED_GUID) {
+ DXE_DEPEX DXE_DEPEX Optional $(INF_OUTPUT)/$(MODULE_NAME).depex
+ PE32 PE32 $(INF_OUTPUT)/$(MODULE_NAME).efi
+ UI STRING="$(MODULE_NAME)" Optional
+ }
+
+[Rule.Common.DXE_DRIVER]
+ FILE DRIVER = $(NAMED_GUID) {
+ DXE_DEPEX DXE_DEPEX Optional $(INF_OUTPUT)/$(MODULE_NAME).depex
+ PE32 PE32 $(INF_OUTPUT)/$(MODULE_NAME).efi
+ UI STRING="$(MODULE_NAME)" Optional
+ }
+
+[Rule.Common.DXE_RUNTIME_DRIVER]
+ FILE DRIVER = $(NAMED_GUID) {
+ DXE_DEPEX DXE_DEPEX Optional $(INF_OUTPUT)/$(MODULE_NAME).depex
+ PE32 PE32 $(INF_OUTPUT)/$(MODULE_NAME).efi
+ UI STRING="$(MODULE_NAME)" Optional
+ }
+
+[Rule.Common.UEFI_APPLICATION]
+ FILE APPLICATION = $(NAMED_GUID) {
+ UI STRING ="$(MODULE_NAME)" Optional
+ PE32 PE32 $(INF_OUTPUT)/$(MODULE_NAME).efi
+ }
+
+[Rule.Common.UEFI_DRIVER.BINARY]
+ FILE DRIVER = $(NAMED_GUID) {
+ DXE_DEPEX DXE_DEPEX Optional |.depex
+ PE32 PE32 |.efi
+ UI STRING="$(MODULE_NAME)" Optional
+ VERSION STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
+ }
+
+[Rule.Common.UEFI_APPLICATION.BINARY]
+ FILE APPLICATION = $(NAMED_GUID) {
+ PE32 PE32 |.efi
+ UI STRING="$(MODULE_NAME)" Optional
+ VERSION STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
+ }
diff --git a/ArmPlatformPkg/ArmJunoPkg/Drivers/ArmJunoDxe/ArmJunoDxe.c b/ArmPlatformPkg/ArmJunoPkg/Drivers/ArmJunoDxe/ArmJunoDxe.c
new file mode 100755
index 000000000..6555b0e1e
--- /dev/null
+++ b/ArmPlatformPkg/ArmJunoPkg/Drivers/ArmJunoDxe/ArmJunoDxe.c
@@ -0,0 +1,34 @@
+/** @file
+*
+* Copyright (c) 2013-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.
+*
+**/
+
+#include <Uefi.h>
+
+EFI_STATUS
+PciEmulationEntryPoint (
+ VOID
+ );
+
+EFI_STATUS
+EFIAPI
+ArmJunoEntryPoint (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+
+ Status = PciEmulationEntryPoint ();
+
+ return Status;
+}
diff --git a/ArmPlatformPkg/ArmJunoPkg/Drivers/ArmJunoDxe/ArmJunoDxe.inf b/ArmPlatformPkg/ArmJunoPkg/Drivers/ArmJunoDxe/ArmJunoDxe.inf
new file mode 100755
index 000000000..3c83e2ed5
--- /dev/null
+++ b/ArmPlatformPkg/ArmJunoPkg/Drivers/ArmJunoDxe/ArmJunoDxe.inf
@@ -0,0 +1,54 @@
+#
+# Copyright (c) 2013-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 = ArmJunoDxe
+ FILE_GUID = 1484ebe8-2681-45f1-a2e5-12ecad893b62
+ MODULE_TYPE = DXE_DRIVER
+ VERSION_STRING = 1.0
+ ENTRY_POINT = ArmJunoEntryPoint
+
+[Sources.common]
+ ArmJunoDxe.c
+ PciEmulation.c
+ PciRootBridgeIo.c
+
+[Packages]
+ ArmPkg/ArmPkg.dec
+ ArmPlatformPkg/ArmJunoPkg/ArmJuno.dec
+ EmbeddedPkg/EmbeddedPkg.dec
+ MdePkg/MdePkg.dec
+
+[LibraryClasses]
+ BaseMemoryLib
+ DebugLib
+ DmaLib
+ IoLib
+ PcdLib
+ UefiBootServicesTableLib
+ UefiLib
+ UefiDriverEntryPoint
+
+[Protocols]
+ gEfiBlockIoProtocolGuid
+ gEfiPciIoProtocolGuid
+
+[FixedPcd]
+ gArmTokenSpaceGuid.PcdSystemMemoryBase
+ gArmTokenSpaceGuid.PcdSystemMemorySize
+
+ gArmJunoTokenSpaceGuid.PcdSynopsysUsbEhciBaseAddress
+ gArmJunoTokenSpaceGuid.PcdSynopsysUsbOhciBaseAddress
+
+[Depex]
+ TRUE
diff --git a/ArmPlatformPkg/ArmJunoPkg/Drivers/ArmJunoDxe/PciEmulation.c b/ArmPlatformPkg/ArmJunoPkg/Drivers/ArmJunoDxe/PciEmulation.c
new file mode 100755
index 000000000..71e81d57d
--- /dev/null
+++ b/ArmPlatformPkg/ArmJunoPkg/Drivers/ArmJunoDxe/PciEmulation.c
@@ -0,0 +1,489 @@
+/** @file
+
+ Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
+ Copyright (c) 2013 - 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 "PciEmulation.h"
+
+#define HOST_CONTROLLER_OPERATION_REG_SIZE 0x44
+
+typedef struct {
+ ACPI_HID_DEVICE_PATH AcpiDevicePath;
+ PCI_DEVICE_PATH PciDevicePath;
+ EFI_DEVICE_PATH_PROTOCOL EndDevicePath;
+} EFI_PCI_IO_DEVICE_PATH;
+
+typedef struct {
+ UINT32 Signature;
+ EFI_PCI_IO_DEVICE_PATH DevicePath;
+ EFI_PCI_IO_PROTOCOL PciIoProtocol;
+ PCI_TYPE00 *ConfigSpace;
+ PCI_ROOT_BRIDGE RootBridge;
+ UINTN Segment;
+} EFI_PCI_IO_PRIVATE_DATA;
+
+#define EFI_PCI_IO_PRIVATE_DATA_SIGNATURE SIGNATURE_32('p', 'c', 'i', 'o')
+#define EFI_PCI_IO_PRIVATE_DATA_FROM_THIS(a) CR (a, EFI_PCI_IO_PRIVATE_DATA, PciIoProtocol, EFI_PCI_IO_PRIVATE_DATA_SIGNATURE)
+
+EFI_PCI_IO_DEVICE_PATH PciIoDevicePathTemplate =
+{
+ {
+ { ACPI_DEVICE_PATH, ACPI_DP, sizeof (ACPI_HID_DEVICE_PATH), 0},
+ EISA_PNP_ID(0x0A03), // HID
+ 0 // UID
+ },
+ {
+ { HARDWARE_DEVICE_PATH, HW_PCI_DP, sizeof (PCI_DEVICE_PATH), 0},
+ 0,
+ 0
+ },
+ { END_DEVICE_PATH_TYPE, END_ENTIRE_DEVICE_PATH_SUBTYPE, sizeof (EFI_DEVICE_PATH_PROTOCOL), 0}
+};
+
+STATIC
+VOID
+ConfigureUSBHost (
+ VOID
+ )
+{
+}
+
+
+EFI_STATUS
+PciIoPollMem (
+ IN EFI_PCI_IO_PROTOCOL *This,
+ IN EFI_PCI_IO_PROTOCOL_WIDTH Width,
+ IN UINT8 BarIndex,
+ IN UINT64 Offset,
+ IN UINT64 Mask,
+ IN UINT64 Value,
+ IN UINT64 Delay,
+ OUT UINT64 *Result
+ )
+{
+ ASSERT (FALSE);
+ return EFI_UNSUPPORTED;
+}
+
+EFI_STATUS
+PciIoPollIo (
+ IN EFI_PCI_IO_PROTOCOL *This,
+ IN EFI_PCI_IO_PROTOCOL_WIDTH Width,
+ IN UINT8 BarIndex,
+ IN UINT64 Offset,
+ IN UINT64 Mask,
+ IN UINT64 Value,
+ IN UINT64 Delay,
+ OUT UINT64 *Result
+ )
+{
+ ASSERT (FALSE);
+ return EFI_UNSUPPORTED;
+}
+
+EFI_STATUS
+PciIoMemRead (
+ IN EFI_PCI_IO_PROTOCOL *This,
+ IN EFI_PCI_IO_PROTOCOL_WIDTH Width,
+ IN UINT8 BarIndex,
+ IN UINT64 Offset,
+ IN UINTN Count,
+ IN OUT VOID *Buffer
+ )
+{
+ EFI_PCI_IO_PRIVATE_DATA *Private = EFI_PCI_IO_PRIVATE_DATA_FROM_THIS (This);
+
+ return PciRootBridgeIoMemRead (&Private->RootBridge.Io,
+ (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width,
+ Private->ConfigSpace->Device.Bar[BarIndex] + Offset, //Fix me ConfigSpace
+ Count,
+ Buffer
+ );
+}
+
+EFI_STATUS
+PciIoMemWrite (
+ IN EFI_PCI_IO_PROTOCOL *This,
+ IN EFI_PCI_IO_PROTOCOL_WIDTH Width,
+ IN UINT8 BarIndex,
+ IN UINT64 Offset,
+ IN UINTN Count,
+ IN OUT VOID *Buffer
+ )
+{
+ EFI_PCI_IO_PRIVATE_DATA *Private = EFI_PCI_IO_PRIVATE_DATA_FROM_THIS (This);
+
+ return PciRootBridgeIoMemWrite (&Private->RootBridge.Io,
+ (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width,
+ Private->ConfigSpace->Device.Bar[BarIndex] + Offset, //Fix me ConfigSpace
+ Count,
+ Buffer
+ );
+}
+
+EFI_STATUS
+PciIoIoRead (
+ IN EFI_PCI_IO_PROTOCOL *This,
+ IN EFI_PCI_IO_PROTOCOL_WIDTH Width,
+ IN UINT8 BarIndex,
+ IN UINT64 Offset,
+ IN UINTN Count,
+ IN OUT VOID *Buffer
+ )
+{
+ ASSERT (FALSE);
+ return EFI_UNSUPPORTED;
+}
+
+EFI_STATUS
+PciIoIoWrite (
+ IN EFI_PCI_IO_PROTOCOL *This,
+ IN EFI_PCI_IO_PROTOCOL_WIDTH Width,
+ IN UINT8 BarIndex,
+ IN UINT64 Offset,
+ IN UINTN Count,
+ IN OUT VOID *Buffer
+ )
+{
+ ASSERT (FALSE);
+ return EFI_UNSUPPORTED;
+}
+
+EFI_STATUS
+PciIoPciRead (
+ IN EFI_PCI_IO_PROTOCOL *This,
+ IN EFI_PCI_IO_PROTOCOL_WIDTH Width,
+ IN UINT32 Offset,
+ IN UINTN Count,
+ IN OUT VOID *Buffer
+ )
+{
+ EFI_PCI_IO_PRIVATE_DATA *Private = EFI_PCI_IO_PRIVATE_DATA_FROM_THIS (This);
+ EFI_STATUS Status;
+
+ Status = PciRootBridgeIoMemRW ((EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH)Width,
+ Count,
+ TRUE,
+ (PTR)(UINTN)Buffer,
+ TRUE,
+ (PTR)(UINTN)(((UINT8 *)Private->ConfigSpace) + Offset) //Fix me ConfigSpace
+ );
+ return Status;
+}
+
+EFI_STATUS
+PciIoPciWrite (
+ IN EFI_PCI_IO_PROTOCOL *This,
+ IN EFI_PCI_IO_PROTOCOL_WIDTH Width,
+ IN UINT32 Offset,
+ IN UINTN Count,
+ IN OUT VOID *Buffer
+ )
+{
+ EFI_PCI_IO_PRIVATE_DATA *Private = EFI_PCI_IO_PRIVATE_DATA_FROM_THIS (This);
+
+ return PciRootBridgeIoMemRW ((EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width,
+ Count,
+ TRUE,
+ (PTR)(UINTN)(((UINT8 *)Private->ConfigSpace) + Offset), //Fix me ConfigSpace
+ TRUE,
+ (PTR)(UINTN)Buffer
+ );
+}
+
+EFI_STATUS
+PciIoCopyMem (
+ IN EFI_PCI_IO_PROTOCOL *This,
+ IN EFI_PCI_IO_PROTOCOL_WIDTH Width,
+ IN UINT8 DestBarIndex,
+ IN UINT64 DestOffset,
+ IN UINT8 SrcBarIndex,
+ IN UINT64 SrcOffset,
+ IN UINTN Count
+ )
+{
+ ASSERT (FALSE);
+ return EFI_UNSUPPORTED;
+}
+
+EFI_STATUS
+PciIoMap (
+ IN EFI_PCI_IO_PROTOCOL *This,
+ IN EFI_PCI_IO_PROTOCOL_OPERATION Operation,
+ IN VOID *HostAddress,
+ IN OUT UINTN *NumberOfBytes,
+ OUT EFI_PHYSICAL_ADDRESS *DeviceAddress,
+ OUT VOID **Mapping
+ )
+{
+ DMA_MAP_OPERATION DmaOperation;
+
+ if (Operation == EfiPciIoOperationBusMasterRead) {
+ DmaOperation = MapOperationBusMasterRead;
+ } else if (Operation == EfiPciIoOperationBusMasterWrite) {
+ DmaOperation = MapOperationBusMasterWrite;
+ } else if (Operation == EfiPciIoOperationBusMasterCommonBuffer) {
+ DmaOperation = MapOperationBusMasterCommonBuffer;
+ } else {
+ return EFI_INVALID_PARAMETER;
+ }
+ return DmaMap (DmaOperation, HostAddress, NumberOfBytes, DeviceAddress, Mapping);
+}
+
+EFI_STATUS
+PciIoUnmap (
+ IN EFI_PCI_IO_PROTOCOL *This,
+ IN VOID *Mapping
+ )
+{
+ return DmaUnmap (Mapping);
+}
+
+EFI_STATUS
+PciIoAllocateBuffer (
+ IN EFI_PCI_IO_PROTOCOL *This,
+ IN EFI_ALLOCATE_TYPE Type,
+ IN EFI_MEMORY_TYPE MemoryType,
+ IN UINTN Pages,
+ OUT VOID **HostAddress,
+ IN UINT64 Attributes
+ )
+{
+ if (Attributes & EFI_PCI_ATTRIBUTE_INVALID_FOR_ALLOCATE_BUFFER) {
+ // Check this
+ return EFI_UNSUPPORTED;
+ }
+
+ return DmaAllocateBuffer (MemoryType, Pages, HostAddress);
+}
+
+
+EFI_STATUS
+PciIoFreeBuffer (
+ IN EFI_PCI_IO_PROTOCOL *This,
+ IN UINTN Pages,
+ IN VOID *HostAddress
+ )
+{
+ return DmaFreeBuffer (Pages, HostAddress);
+}
+
+
+EFI_STATUS
+PciIoFlush (
+ IN EFI_PCI_IO_PROTOCOL *This
+ )
+{
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+PciIoGetLocation (
+ IN EFI_PCI_IO_PROTOCOL *This,
+ OUT UINTN *SegmentNumber,
+ OUT UINTN *BusNumber,
+ OUT UINTN *DeviceNumber,
+ OUT UINTN *FunctionNumber
+ )
+{
+ EFI_PCI_IO_PRIVATE_DATA *Private = EFI_PCI_IO_PRIVATE_DATA_FROM_THIS (This);
+
+ if (SegmentNumber != NULL) {
+ *SegmentNumber = Private->Segment;
+ }
+
+ if (BusNumber != NULL) {
+ *BusNumber = 0xff;
+ }
+
+ if (DeviceNumber != NULL) {
+ *DeviceNumber = 0;
+ }
+
+ if (FunctionNumber != NULL) {
+ *FunctionNumber = 0;
+ }
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+PciIoAttributes (
+ IN EFI_PCI_IO_PROTOCOL *This,
+ IN EFI_PCI_IO_PROTOCOL_ATTRIBUTE_OPERATION Operation,
+ IN UINT64 Attributes,
+ OUT UINT64 *Result OPTIONAL
+ )
+{
+ switch (Operation) {
+ case EfiPciIoAttributeOperationGet:
+ case EfiPciIoAttributeOperationSupported:
+ if (Result == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+ // We are not a real PCI device so just say things we kind of do
+ *Result = EFI_PCI_IO_ATTRIBUTE_MEMORY | EFI_PCI_IO_ATTRIBUTE_BUS_MASTER | EFI_PCI_DEVICE_ENABLE;
+ break;
+
+ case EfiPciIoAttributeOperationSet:
+ case EfiPciIoAttributeOperationEnable:
+ case EfiPciIoAttributeOperationDisable:
+ // Since we are not a real PCI device no enable/set or disable operations exist.
+ return EFI_SUCCESS;
+
+ default:
+ ASSERT (FALSE);
+ return EFI_INVALID_PARAMETER;
+ };
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+PciIoGetBarAttributes (
+ IN EFI_PCI_IO_PROTOCOL *This,
+ IN UINT8 BarIndex,
+ OUT UINT64 *Supports, OPTIONAL
+ OUT VOID **Resources OPTIONAL
+ )
+{
+ ASSERT (FALSE);
+ return EFI_UNSUPPORTED;
+}
+
+EFI_STATUS
+PciIoSetBarAttributes (
+ IN EFI_PCI_IO_PROTOCOL *This,
+ IN UINT64 Attributes,
+ IN UINT8 BarIndex,
+ IN OUT UINT64 *Offset,
+ IN OUT UINT64 *Length
+ )
+{
+ ASSERT (FALSE);
+ return EFI_UNSUPPORTED;
+}
+
+EFI_PCI_IO_PROTOCOL PciIoTemplate =
+{
+ PciIoPollMem,
+ PciIoPollIo,
+ PciIoMemRead,
+ PciIoMemWrite,
+ PciIoIoRead,
+ PciIoIoWrite,
+ PciIoPciRead,
+ PciIoPciWrite,
+ PciIoCopyMem,
+ PciIoMap,
+ PciIoUnmap,
+ PciIoAllocateBuffer,
+ PciIoFreeBuffer,
+ PciIoFlush,
+ PciIoGetLocation,
+ PciIoAttributes,
+ PciIoGetBarAttributes,
+ PciIoSetBarAttributes,
+ 0,
+ 0
+};
+
+EFI_STATUS
+PciInstallDevice (
+ IN UINTN DeviceId,
+ IN PHYSICAL_ADDRESS MemoryStart,
+ IN UINT64 MemorySize,
+ IN UINTN ClassCode1,
+ IN UINTN ClassCode2,
+ IN UINTN ClassCode3
+ )
+{
+ EFI_STATUS Status;
+ EFI_HANDLE Handle;
+ EFI_PCI_IO_PRIVATE_DATA *Private;
+
+ // Configure USB host
+ ConfigureUSBHost ();
+
+ // Create a private structure
+ Private = AllocatePool (sizeof (EFI_PCI_IO_PRIVATE_DATA));
+ if (Private == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ return Status;
+ }
+
+ Private->Signature = EFI_PCI_IO_PRIVATE_DATA_SIGNATURE; // Fill in signature
+ Private->RootBridge.Signature = PCI_ROOT_BRIDGE_SIGNATURE; // Fake Root Bridge structure needs a signature too
+ Private->RootBridge.MemoryStart = MemoryStart; // Get the USB capability register base
+ Private->Segment = 0; // Default to segment zero
+
+ // Calculate the total size of the USB controller (OHCI + EHCI).
+ Private->RootBridge.MemorySize = MemorySize; //CapabilityLength + (HOST_CONTROLLER_OPERATION_REG_SIZE + ((4 * PhysicalPorts) - 1));
+
+ // Create fake PCI config space: OHCI + EHCI
+ Private->ConfigSpace = AllocateZeroPool (sizeof (PCI_TYPE00));
+ if (Private->ConfigSpace == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ FreePool (Private);
+ return Status;
+ }
+
+ //
+ // Configure PCI config space: OHCI + EHCI
+ //
+ Private->ConfigSpace->Hdr.VendorId = 0x3530; //TODO: Define one
+ Private->ConfigSpace->Hdr.DeviceId = 0x3530; //TODO: Define one
+ Private->ConfigSpace->Hdr.ClassCode[0] = ClassCode1;
+ Private->ConfigSpace->Hdr.ClassCode[1] = ClassCode2;
+ Private->ConfigSpace->Hdr.ClassCode[2] = ClassCode3;
+ Private->ConfigSpace->Device.Bar[0] = MemoryStart;
+
+ Handle = NULL;
+
+ // Unique device path.
+ CopyMem (&Private->DevicePath, &PciIoDevicePathTemplate, sizeof (PciIoDevicePathTemplate));
+ Private->DevicePath.AcpiDevicePath.UID = 0;
+ Private->DevicePath.PciDevicePath.Device = DeviceId;
+
+ // Copy protocol structure
+ CopyMem (&Private->PciIoProtocol, &PciIoTemplate, sizeof (PciIoTemplate));
+
+ Status = gBS->InstallMultipleProtocolInterfaces (&Handle,
+ &gEfiPciIoProtocolGuid, &Private->PciIoProtocol,
+ &gEfiDevicePathProtocolGuid, &Private->DevicePath,
+ NULL);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR, "PciEmulationEntryPoint InstallMultipleProtocolInterfaces () failed.\n"));
+ }
+
+ return Status;
+}
+
+EFI_STATUS
+PciEmulationEntryPoint (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+
+ Status = PciInstallDevice (0, FixedPcdGet32 (PcdSynopsysUsbOhciBaseAddress), SIZE_64KB, PCI_IF_OHCI, PCI_CLASS_SERIAL_USB, PCI_CLASS_SERIAL);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR, "PciEmulation: failed to install OHCI device.\n"));
+ }
+
+ Status = PciInstallDevice (1, FixedPcdGet32 (PcdSynopsysUsbEhciBaseAddress), SIZE_64KB, PCI_IF_EHCI, PCI_CLASS_SERIAL_USB, PCI_CLASS_SERIAL);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR, "PciEmulation: failed to install EHCI device.\n"));
+ }
+
+ return Status;
+}
diff --git a/ArmPlatformPkg/ArmJunoPkg/Drivers/ArmJunoDxe/PciEmulation.h b/ArmPlatformPkg/ArmJunoPkg/Drivers/ArmJunoDxe/PciEmulation.h
new file mode 100755
index 000000000..1066839b8
--- /dev/null
+++ b/ArmPlatformPkg/ArmJunoPkg/Drivers/ArmJunoDxe/PciEmulation.h
@@ -0,0 +1,285 @@
+/** @file
+
+ Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
+ Copyright (c) 2013 - 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.
+
+**/
+
+#ifndef _PCI_ROOT_BRIDGE_H_
+#define _PCI_ROOT_BRIDGE_H_
+
+#include <PiDxe.h>
+
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/DxeServicesTableLib.h>
+#include <Library/IoLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/PciLib.h>
+#include <Library/UefiLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/DmaLib.h>
+
+#include <Protocol/EmbeddedExternalDevice.h>
+#include <Protocol/DevicePath.h>
+#include <Protocol/PciIo.h>
+#include <Protocol/PciRootBridgeIo.h>
+#include <Protocol/PciHostBridgeResourceAllocation.h>
+
+#include <IndustryStandard/Pci23.h>
+#include <IndustryStandard/Acpi.h>
+
+#define EFI_RESOURCE_NONEXISTENT 0xFFFFFFFFFFFFFFFFULL
+#define EFI_RESOURCE_LESS 0xFFFFFFFFFFFFFFFEULL
+#define EFI_RESOURCE_SATISFIED 0x0000000000000000ULL
+
+
+typedef struct {
+ ACPI_HID_DEVICE_PATH AcpiDevicePath;
+ EFI_DEVICE_PATH_PROTOCOL EndDevicePath;
+} EFI_PCI_ROOT_BRIDGE_DEVICE_PATH;
+
+
+#define ACPI_CONFIG_IO 0
+#define ACPI_CONFIG_MMIO 1
+#define ACPI_CONFIG_BUS 2
+
+typedef struct {
+ EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR Desc[3];
+ EFI_ACPI_END_TAG_DESCRIPTOR EndDesc;
+} ACPI_CONFIG_INFO;
+
+
+#define PCI_ROOT_BRIDGE_SIGNATURE SIGNATURE_32 ('P', 'c', 'i', 'F')
+
+typedef struct {
+ UINT32 Signature;
+ EFI_HANDLE Handle;
+ EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL Io;
+ EFI_PCI_ROOT_BRIDGE_DEVICE_PATH DevicePath;
+
+ UINT8 StartBus;
+ UINT8 EndBus;
+ UINT16 Type;
+ UINT32 MemoryStart;
+ UINT32 MemorySize;
+ UINTN IoOffset;
+ UINT32 IoStart;
+ UINT32 IoSize;
+ UINT64 PciAttributes;
+
+ ACPI_CONFIG_INFO *Config;
+
+} PCI_ROOT_BRIDGE;
+
+
+#define INSTANCE_FROM_PCI_ROOT_BRIDGE_IO_THIS(a) CR (a, PCI_ROOT_BRIDGE, Io, PCI_ROOT_BRIDGE_SIGNATURE)
+
+
+typedef union {
+ UINT8 volatile *Buffer;
+ UINT8 volatile *Ui8;
+ UINT16 volatile *Ui16;
+ UINT32 volatile *Ui32;
+ UINT64 volatile *Ui64;
+ UINTN volatile Ui;
+} PTR;
+
+
+
+EFI_STATUS
+EFIAPI
+PciRootBridgeIoPollMem (
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,
+ IN UINT64 Address,
+ IN UINT64 Mask,
+ IN UINT64 Value,
+ IN UINT64 Delay,
+ OUT UINT64 *Result
+ );
+
+EFI_STATUS
+EFIAPI
+PciRootBridgeIoPollIo (
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,
+ IN UINT64 Address,
+ IN UINT64 Mask,
+ IN UINT64 Value,
+ IN UINT64 Delay,
+ OUT UINT64 *Result
+ );
+
+EFI_STATUS
+EFIAPI
+PciRootBridgeIoMemRead (
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,
+ IN UINT64 Address,
+ IN UINTN Count,
+ IN OUT VOID *Buffer
+ );
+
+EFI_STATUS
+EFIAPI
+PciRootBridgeIoMemWrite (
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,
+ IN UINT64 Address,
+ IN UINTN Count,
+ IN OUT VOID *Buffer
+ );
+
+EFI_STATUS
+EFIAPI
+PciRootBridgeIoIoRead (
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,
+ IN UINT64 UserAddress,
+ IN UINTN Count,
+ IN OUT VOID *UserBuffer
+ );
+
+EFI_STATUS
+EFIAPI
+PciRootBridgeIoIoWrite (
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,
+ IN UINT64 UserAddress,
+ IN UINTN Count,
+ IN OUT VOID *UserBuffer
+ );
+
+EFI_STATUS
+EFIAPI
+PciRootBridgeIoCopyMem (
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,
+ IN UINT64 DestAddress,
+ IN UINT64 SrcAddress,
+ IN UINTN Count
+ );
+
+EFI_STATUS
+EFIAPI
+PciRootBridgeIoPciRead (
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,
+ IN UINT64 Address,
+ IN UINTN Count,
+ IN OUT VOID *Buffer
+ );
+
+EFI_STATUS
+EFIAPI
+PciRootBridgeIoPciWrite (
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,
+ IN UINT64 Address,
+ IN UINTN Count,
+ IN OUT VOID *Buffer
+ );
+
+EFI_STATUS
+EFIAPI
+PciRootBridgeIoMap (
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_OPERATION Operation,
+ IN VOID *HostAddress,
+ IN OUT UINTN *NumberOfBytes,
+ OUT EFI_PHYSICAL_ADDRESS *DeviceAddress,
+ OUT VOID **Mapping
+ );
+
+EFI_STATUS
+EFIAPI
+PciRootBridgeIoUnmap (
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
+ IN VOID *Mapping
+ );
+
+EFI_STATUS
+EFIAPI
+PciRootBridgeIoAllocateBuffer (
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
+ IN EFI_ALLOCATE_TYPE Type,
+ IN EFI_MEMORY_TYPE MemoryType,
+ IN UINTN Pages,
+ OUT VOID **HostAddress,
+ IN UINT64 Attributes
+ );
+
+EFI_STATUS
+EFIAPI
+PciRootBridgeIoFreeBuffer (
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
+ IN UINTN Pages,
+ OUT VOID *HostAddress
+ );
+
+EFI_STATUS
+EFIAPI
+PciRootBridgeIoFlush (
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This
+ );
+
+EFI_STATUS
+EFIAPI
+PciRootBridgeIoGetAttributes (
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
+ OUT UINT64 *Supported,
+ OUT UINT64 *Attributes
+ );
+
+EFI_STATUS
+EFIAPI
+PciRootBridgeIoSetAttributes (
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
+ IN UINT64 Attributes,
+ IN OUT UINT64 *ResourceBase,
+ IN OUT UINT64 *ResourceLength
+ );
+
+EFI_STATUS
+EFIAPI
+PciRootBridgeIoConfiguration (
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
+ OUT VOID **Resources
+ );
+
+//
+// Private Function Prototypes
+//
+EFI_STATUS
+EFIAPI
+PciRootBridgeIoMemRW (
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,
+ IN UINTN Count,
+ IN BOOLEAN InStrideFlag,
+ IN PTR In,
+ IN BOOLEAN OutStrideFlag,
+ OUT PTR Out
+ );
+
+BOOLEAN
+PciIoMemAddressValid (
+ IN EFI_PCI_IO_PROTOCOL *This,
+ IN UINT64 Address
+ );
+
+EFI_STATUS
+EmulatePciIoForEhci (
+ INTN MvPciIfMaxIf
+ );
+
+#endif
diff --git a/ArmPlatformPkg/ArmJunoPkg/Drivers/ArmJunoDxe/PciRootBridgeIo.c b/ArmPlatformPkg/ArmJunoPkg/Drivers/ArmJunoDxe/PciRootBridgeIo.c
new file mode 100755
index 000000000..2a4706501
--- /dev/null
+++ b/ArmPlatformPkg/ArmJunoPkg/Drivers/ArmJunoDxe/PciRootBridgeIo.c
@@ -0,0 +1,299 @@
+/** @file
+
+ Copyright (c) 2008 - 2009, Apple Inc. 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 "PciEmulation.h"
+
+BOOLEAN
+PciRootBridgeMemAddressValid (
+ IN PCI_ROOT_BRIDGE *Private,
+ IN UINT64 Address
+ )
+{
+ if ((Address >= Private->MemoryStart) && (Address < (Private->MemoryStart + Private->MemorySize))) {
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+
+EFI_STATUS
+PciRootBridgeIoMemRW (
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,
+ IN UINTN Count,
+ IN BOOLEAN InStrideFlag,
+ IN PTR In,
+ IN BOOLEAN OutStrideFlag,
+ OUT PTR Out
+ )
+{
+ UINTN Stride;
+ UINTN InStride;
+ UINTN OutStride;
+
+ Width = (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) (Width & 0x03);
+ Stride = (UINTN)1 << Width;
+ InStride = InStrideFlag ? Stride : 0;
+ OutStride = OutStrideFlag ? Stride : 0;
+
+ //
+ // Loop for each iteration and move the data
+ //
+ switch (Width) {
+ case EfiPciWidthUint8:
+ for (;Count > 0; Count--, In.Buffer += InStride, Out.Buffer += OutStride) {
+ *In.Ui8 = *Out.Ui8;
+ }
+ break;
+ case EfiPciWidthUint16:
+ for (;Count > 0; Count--, In.Buffer += InStride, Out.Buffer += OutStride) {
+ *In.Ui16 = *Out.Ui16;
+ }
+ break;
+ case EfiPciWidthUint32:
+ for (;Count > 0; Count--, In.Buffer += InStride, Out.Buffer += OutStride) {
+ *In.Ui32 = *Out.Ui32;
+ }
+ break;
+ default:
+ return EFI_INVALID_PARAMETER;
+ }
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+PciRootBridgeIoPciRW (
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
+ IN BOOLEAN Write,
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,
+ IN UINT64 UserAddress,
+ IN UINTN Count,
+ IN OUT VOID *UserBuffer
+ )
+{
+ return EFI_SUCCESS;
+}
+
+/**
+ Enables a PCI driver to access PCI controller registers in the PCI root bridge memory space.
+
+ @param This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
+ @param Width Signifies the width of the memory operations.
+ @param Address The base address of the memory operations.
+ @param Count The number of memory operations to perform.
+ @param Buffer For read operations, the destination buffer to store the results. For write
+ operations, the source buffer to write data from.
+
+ @retval EFI_SUCCESS The data was read from or written to the PCI root bridge.
+ @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.
+ @retval EFI_INVALID_PARAMETER One or more parameters are invalid.
+
+**/
+EFI_STATUS
+EFIAPI
+PciRootBridgeIoMemRead (
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,
+ IN UINT64 Address,
+ IN UINTN Count,
+ IN OUT VOID *Buffer
+ )
+{
+ PCI_ROOT_BRIDGE *Private;
+ UINTN AlignMask;
+ PTR In;
+ PTR Out;
+
+ if ( Buffer == NULL ) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Private = INSTANCE_FROM_PCI_ROOT_BRIDGE_IO_THIS (This);
+
+ if (!PciRootBridgeMemAddressValid (Private, Address)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ AlignMask = (1 << (Width & 0x03)) - 1;
+ if (Address & AlignMask) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ In.Buffer = Buffer;
+ Out.Buffer = (VOID *)(UINTN) Address;
+
+ switch (Width) {
+ case EfiPciWidthUint8:
+ case EfiPciWidthUint16:
+ case EfiPciWidthUint32:
+ case EfiPciWidthUint64:
+ return PciRootBridgeIoMemRW (Width, Count, TRUE, In, TRUE, Out);
+
+ case EfiPciWidthFifoUint8:
+ case EfiPciWidthFifoUint16:
+ case EfiPciWidthFifoUint32:
+ case EfiPciWidthFifoUint64:
+ return PciRootBridgeIoMemRW (Width, Count, TRUE, In, FALSE, Out);
+
+ case EfiPciWidthFillUint8:
+ case EfiPciWidthFillUint16:
+ case EfiPciWidthFillUint32:
+ case EfiPciWidthFillUint64:
+ return PciRootBridgeIoMemRW (Width, Count, FALSE, In, TRUE, Out);
+
+ default:
+ break;
+ }
+
+ return EFI_INVALID_PARAMETER;
+}
+
+/**
+ Enables a PCI driver to access PCI controller registers in the PCI root bridge memory space.
+
+ @param This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
+ @param Width Signifies the width of the memory operations.
+ @param Address The base address of the memory operations.
+ @param Count The number of memory operations to perform.
+ @param Buffer For read operations, the destination buffer to store the results. For write
+ operations, the source buffer to write data from.
+
+ @retval EFI_SUCCESS The data was read from or written to the PCI root bridge.
+ @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.
+ @retval EFI_INVALID_PARAMETER One or more parameters are invalid.
+
+**/
+EFI_STATUS
+EFIAPI
+PciRootBridgeIoMemWrite (
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,
+ IN UINT64 Address,
+ IN UINTN Count,
+ IN OUT VOID *Buffer
+ )
+{
+ PCI_ROOT_BRIDGE *Private;
+ UINTN AlignMask;
+ PTR In;
+ PTR Out;
+
+ if ( Buffer == NULL ) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Private = INSTANCE_FROM_PCI_ROOT_BRIDGE_IO_THIS (This);
+
+ if (!PciRootBridgeMemAddressValid (Private, Address)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ AlignMask = (1 << (Width & 0x03)) - 1;
+ if (Address & AlignMask) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ In.Buffer = (VOID *)(UINTN) Address;
+ Out.Buffer = Buffer;
+
+ switch (Width) {
+ case EfiPciWidthUint8:
+ case EfiPciWidthUint16:
+ case EfiPciWidthUint32:
+ case EfiPciWidthUint64:
+ return PciRootBridgeIoMemRW (Width, Count, TRUE, In, TRUE, Out);
+
+ case EfiPciWidthFifoUint8:
+ case EfiPciWidthFifoUint16:
+ case EfiPciWidthFifoUint32:
+ case EfiPciWidthFifoUint64:
+ return PciRootBridgeIoMemRW (Width, Count, FALSE, In, TRUE, Out);
+
+ case EfiPciWidthFillUint8:
+ case EfiPciWidthFillUint16:
+ case EfiPciWidthFillUint32:
+ case EfiPciWidthFillUint64:
+ return PciRootBridgeIoMemRW (Width, Count, TRUE, In, FALSE, Out);
+
+ default:
+ break;
+ }
+
+ return EFI_INVALID_PARAMETER;
+}
+
+/**
+ Enables a PCI driver to access PCI controller registers in the PCI root bridge memory space.
+
+ @param This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
+ @param Width Signifies the width of the memory operations.
+ @param Address The base address of the memory operations.
+ @param Count The number of memory operations to perform.
+ @param Buffer For read operations, the destination buffer to store the results. For write
+ operations, the source buffer to write data from.
+
+ @retval EFI_SUCCESS The data was read from or written to the PCI root bridge.
+ @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.
+ @retval EFI_INVALID_PARAMETER One or more parameters are invalid.
+
+**/
+EFI_STATUS
+EFIAPI
+PciRootBridgeIoPciRead (
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,
+ IN UINT64 Address,
+ IN UINTN Count,
+ IN OUT VOID *Buffer
+ )
+{
+ if (Buffer == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ return PciRootBridgeIoPciRW (This, FALSE, Width, Address, Count, Buffer);
+}
+
+/**
+ Enables a PCI driver to access PCI controller registers in the PCI root bridge memory space.
+
+ @param This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
+ @param Width Signifies the width of the memory operations.
+ @param Address The base address of the memory operations.
+ @param Count The number of memory operations to perform.
+ @param Buffer For read operations, the destination buffer to store the results. For write
+ operations, the source buffer to write data from.
+
+ @retval EFI_SUCCESS The data was read from or written to the PCI root bridge.
+ @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.
+ @retval EFI_INVALID_PARAMETER One or more parameters are invalid.
+
+**/
+EFI_STATUS
+EFIAPI
+PciRootBridgeIoPciWrite (
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,
+ IN UINT64 Address,
+ IN UINTN Count,
+ IN OUT VOID *Buffer
+ )
+{
+ if (Buffer == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ return PciRootBridgeIoPciRW (This, TRUE, Width, Address, Count, Buffer);
+}
diff --git a/ArmPlatformPkg/ArmJunoPkg/Drivers/GenericWatchdogDxe/GenericWatchdogDxe.c b/ArmPlatformPkg/ArmJunoPkg/Drivers/GenericWatchdogDxe/GenericWatchdogDxe.c
new file mode 100755
index 000000000..959a453d4
--- /dev/null
+++ b/ArmPlatformPkg/ArmJunoPkg/Drivers/GenericWatchdogDxe/GenericWatchdogDxe.c
@@ -0,0 +1,354 @@
+/** @file
+*
+* Copyright (c) 2013-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.
+*
+**/
+
+#include <PiDxe.h>
+
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/IoLib.h>
+#include <Library/PcdLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+#include <Library/UefiLib.h>
+#include <Library/ArmArchTimerLib.h>
+
+#include <Protocol/WatchdogTimer.h>
+#include <Protocol/HardwareInterrupt.h>
+
+#include <Drivers/GenericWatchdog.h>
+
+// The number of 100ns periods (the unit of time passed to these functions)
+// in a second
+#define TIME_UNITS_PER_SECOND 10000000
+
+// Tick frequency of the generic timer that is the basis of the generic watchdog
+UINTN mTimerFrequencyHz = 0;
+
+// In cases where the compare register was set manually, information about
+// how long the watchdog was asked to wait cannot be retrieved from hardware.
+// It is therefore stored here. 0 means the timer is not running.
+UINT64 mNumTimerTicks = 0;
+
+EFI_HARDWARE_INTERRUPT_PROTOCOL *mInterruptProtocol;
+
+EFI_STATUS
+WatchdogWriteOffsetRegister (
+ UINT32 Value
+ )
+{
+ return MmioWrite32 (GENERIC_WDOG_OFFSET_REG, Value);
+}
+
+EFI_STATUS
+WatchdogWriteCompareRegister (
+ UINT64 Value
+ )
+{
+ return MmioWrite64 (GENERIC_WDOG_COMPARE_VALUE_REG, Value);
+}
+
+EFI_STATUS
+WatchdogEnable (
+ VOID
+ )
+{
+ return MmioWrite32 (GENERIC_WDOG_CONTROL_STATUS_REG, GENERIC_WDOG_ENABLED);
+}
+
+EFI_STATUS
+WatchdogDisable (
+ VOID
+ )
+{
+ return MmioWrite32 (GENERIC_WDOG_CONTROL_STATUS_REG, GENERIC_WDOG_DISABLED);
+}
+
+/**
+ On exiting boot services we must make sure the Watchdog Timer
+ is stopped.
+**/
+VOID
+EFIAPI
+WatchdogExitBootServicesEvent (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+{
+ WatchdogDisable ();
+ mNumTimerTicks = 0;
+}
+
+/*
+ This function is called when the watchdog's first signal (WS0) goes high.
+ It uses the ResetSystem Runtime Service to reset the board.
+*/
+VOID
+EFIAPI
+WatchdogInterruptHandler (
+ IN HARDWARE_INTERRUPT_SOURCE Source,
+ IN EFI_SYSTEM_CONTEXT SystemContext
+ )
+{
+ STATIC CONST CHAR16 ResetString[] = L"The generic watchdog timer ran out.";
+
+ WatchdogDisable ();
+
+ mInterruptProtocol->EndOfInterrupt (mInterruptProtocol, Source);
+
+ gRT->ResetSystem (
+ EfiResetCold,
+ EFI_TIMEOUT,
+ StrSize (ResetString),
+ &ResetString
+ );
+
+ // If we got here then the reset didn't work
+ ASSERT (FALSE);
+}
+
+/**
+ This function registers the handler NotifyFunction so it is called every time
+ the watchdog timer expires. It also passes the amount of time since the last
+ handler call to the NotifyFunction.
+ If NotifyFunction is not NULL and a handler is not already registered,
+ then the new handler is registered and EFI_SUCCESS is returned.
+ If NotifyFunction is NULL, and a handler is already registered,
+ then that handler is unregistered.
+ If an attempt is made to register a handler when a handler is already registered,
+ then EFI_ALREADY_STARTED is returned.
+ If an attempt is made to unregister a handler when a handler is not registered,
+ then EFI_INVALID_PARAMETER is returned.
+
+ @param This The EFI_TIMER_ARCH_PROTOCOL instance.
+ @param NotifyFunction The function to call when a timer interrupt fires.
+ This function executes at TPL_HIGH_LEVEL. The DXE
+ Core will register a handler for the timer interrupt,
+ so it can know how much time has passed. This
+ information is used to signal timer based events.
+ NULL will unregister the handler.
+
+ @retval EFI_SUCCESS The watchdog timer handler was registered.
+ @retval EFI_ALREADY_STARTED NotifyFunction is not NULL, and a handler is already
+ registered.
+ @retval EFI_INVALID_PARAMETER NotifyFunction is NULL, and a handler was not
+ previously registered.
+
+**/
+EFI_STATUS
+EFIAPI
+WatchdogRegisterHandler (
+ IN CONST EFI_WATCHDOG_TIMER_ARCH_PROTOCOL *This,
+ IN EFI_WATCHDOG_TIMER_NOTIFY NotifyFunction
+ )
+{
+ // ERROR: This function is not supported.
+ // The watchdog will reset the board
+ return EFI_UNSUPPORTED;
+}
+
+/**
+ This function sets the amount of time to wait before firing the watchdog
+ timer to TimerPeriod 100 nS units. If TimerPeriod is 0, then the watchdog
+ timer is disabled.
+
+ @param This The EFI_WATCHDOG_TIMER_ARCH_PROTOCOL instance.
+ @param TimerPeriod The amount of time in 100 nS units to wait before the watchdog
+ timer is fired. If TimerPeriod is zero, then the watchdog
+ timer is disabled.
+
+ @retval EFI_SUCCESS The watchdog timer has been programmed to fire in Time
+ 100 nS units.
+ @retval EFI_DEVICE_ERROR A watchdog timer could not be programmed due to a device
+ error.
+
+**/
+EFI_STATUS
+EFIAPI
+WatchdogSetTimerPeriod (
+ IN CONST EFI_WATCHDOG_TIMER_ARCH_PROTOCOL *This,
+ IN UINT64 TimerPeriod // In 100ns units
+ )
+{
+ UINTN TimerVal;
+ EFI_STATUS Status;
+
+ // if TimerPerdiod is 0, this is a request to stop the watchdog.
+ if (TimerPeriod == 0) {
+ mNumTimerTicks = 0;
+ return WatchdogDisable ();
+ }
+
+ // Work out how many timer ticks will equate to TimerPeriod
+ mNumTimerTicks = (mTimerFrequencyHz * TimerPeriod) / TIME_UNITS_PER_SECOND;
+
+ //
+ // If the number of required ticks is greater than the max number the
+ // watchdog's offset register (WOR) can hold, we need to manually compute and
+ // set the compare register (WCV)
+ //
+ if (mNumTimerTicks > MAX_UINT32) {
+ //
+ // We need to enable the watchdog *before* writing to the compare register,
+ // because enabling the watchdog causes an "explicit refresh", which
+ // clobbers the compare register (WCV). In order to make sure this doesn't
+ // trigger an interrupt, set the offset to max.
+ //
+ Status = WatchdogWriteOffsetRegister (MAX_UINT32);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ WatchdogEnable ();
+ TimerVal = ArmArchTimerGetTimerVal ();
+ Status = WatchdogWriteCompareRegister (TimerVal + mNumTimerTicks);
+ } else {
+ Status = WatchdogWriteOffsetRegister ((UINT32)mNumTimerTicks);
+ WatchdogEnable ();
+ }
+
+ return Status;
+}
+
+/**
+ This function retrieves the period of timer interrupts in 100 ns units,
+ returns that value in TimerPeriod, and returns EFI_SUCCESS. If TimerPeriod
+ is NULL, then EFI_INVALID_PARAMETER is returned. If a TimerPeriod of 0 is
+ returned, then the timer is currently disabled.
+
+ @param This The EFI_TIMER_ARCH_PROTOCOL instance.
+ @param TimerPeriod A pointer to the timer period to retrieve in 100
+ ns units. If 0 is returned, then the timer is
+ currently disabled.
+
+
+ @retval EFI_SUCCESS The timer period was returned in TimerPeriod.
+ @retval EFI_INVALID_PARAMETER TimerPeriod is NULL.
+
+**/
+EFI_STATUS
+EFIAPI
+WatchdogGetTimerPeriod (
+ IN CONST EFI_WATCHDOG_TIMER_ARCH_PROTOCOL *This,
+ OUT UINT64 *TimerPeriod
+ )
+{
+ if (TimerPeriod == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ *TimerPeriod = ((TIME_UNITS_PER_SECOND / mTimerFrequencyHz) * mNumTimerTicks);
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Interface structure for the Watchdog Architectural Protocol.
+
+ @par Protocol Description:
+ This protocol provides a service to set the amount of time to wait
+ before firing the watchdog timer, and it also provides a service to
+ register a handler that is invoked when the watchdog timer fires.
+
+ @par When the watchdog timer fires, control will be passed to a handler
+ if one has been registered. If no handler has been registered,
+ or the registered handler returns, then the system will be
+ reset by calling the Runtime Service ResetSystem().
+
+ @param RegisterHandler
+ Registers a handler that will be called each time the
+ watchdogtimer interrupt fires. TimerPeriod defines the minimum
+ time between timer interrupts, so TimerPeriod will also
+ be the minimum time between calls to the registered
+ handler.
+ NOTE: If the watchdog resets the system in hardware, then
+ this function will not have any chance of executing.
+
+ @param SetTimerPeriod
+ Sets the period of the timer interrupt in 100 nS units.
+ This function is optional, and may return EFI_UNSUPPORTED.
+ If this function is supported, then the timer period will
+ be rounded up to the nearest supported timer period.
+
+ @param GetTimerPeriod
+ Retrieves the period of the timer interrupt in 100 nS units.
+
+**/
+EFI_WATCHDOG_TIMER_ARCH_PROTOCOL gWatchdogTimer = {
+ (EFI_WATCHDOG_TIMER_REGISTER_HANDLER) WatchdogRegisterHandler,
+ (EFI_WATCHDOG_TIMER_SET_TIMER_PERIOD) WatchdogSetTimerPeriod,
+ (EFI_WATCHDOG_TIMER_GET_TIMER_PERIOD) WatchdogGetTimerPeriod
+};
+
+EFI_EVENT EfiExitBootServicesEvent = (EFI_EVENT)NULL;
+
+EFI_STATUS
+EFIAPI
+GenericWatchdogEntry (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+ EFI_HANDLE Handle;
+
+ //
+ // Make sure the Watchdog Timer Architectural Protocol has not been installed
+ // in the system yet.
+ // This will avoid conflicts with the universal watchdog
+ //
+ ASSERT_PROTOCOL_ALREADY_INSTALLED (NULL, &gEfiWatchdogTimerArchProtocolGuid);
+
+ mTimerFrequencyHz = ArmArchTimerGetTimerFreq ();
+ ASSERT (mTimerFrequencyHz != 0);
+
+ // Register for an ExitBootServicesEvent
+ Status = gBS->CreateEvent (
+ EVT_SIGNAL_EXIT_BOOT_SERVICES, TPL_NOTIFY,
+ WatchdogExitBootServicesEvent, NULL, &EfiExitBootServicesEvent
+ );
+ if (!EFI_ERROR (Status)) {
+ // Install interrupt handler
+ Status = gBS->LocateProtocol (
+ &gHardwareInterruptProtocolGuid,
+ NULL,
+ (VOID **)&mInterruptProtocol
+ );
+ if (!EFI_ERROR (Status)) {
+ Status = mInterruptProtocol->RegisterInterruptSource (
+ mInterruptProtocol,
+ FixedPcdGet32 (PcdGenericWatchdogEl2IntrNum),
+ WatchdogInterruptHandler
+ );
+ if (!EFI_ERROR (Status)) {
+ // Install the Timer Architectural Protocol onto a new handle
+ Handle = NULL;
+ Status = gBS->InstallMultipleProtocolInterfaces (
+ &Handle,
+ &gEfiWatchdogTimerArchProtocolGuid, &gWatchdogTimer,
+ NULL
+ );
+ }
+ }
+ }
+
+ if (EFI_ERROR (Status)) {
+ // The watchdog failed to initialize
+ ASSERT (FALSE);
+ }
+
+ mNumTimerTicks = 0;
+ WatchdogDisable ();
+
+ return Status;
+}
diff --git a/ArmPlatformPkg/ArmJunoPkg/Drivers/GenericWatchdogDxe/GenericWatchdogDxe.inf b/ArmPlatformPkg/ArmJunoPkg/Drivers/GenericWatchdogDxe/GenericWatchdogDxe.inf
new file mode 100755
index 000000000..6cc84a1ea
--- /dev/null
+++ b/ArmPlatformPkg/ArmJunoPkg/Drivers/GenericWatchdogDxe/GenericWatchdogDxe.inf
@@ -0,0 +1,54 @@
+#
+# Copyright (c) 2013-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 = 0x00010016
+ BASE_NAME = GenericWatchdogDxe
+ FILE_GUID = 0619f5c2-4858-4caa-a86a-73a21a18df6b
+ MODULE_TYPE = DXE_DRIVER
+ VERSION_STRING = 1.0
+
+ ENTRY_POINT = GenericWatchdogEntry
+
+[Sources.common]
+ GenericWatchdogDxe.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ EmbeddedPkg/EmbeddedPkg.dec
+ ArmPkg/ArmPkg.dec
+ ArmPlatformPkg/ArmPlatformPkg.dec
+ ArmPlatformPkg/ArmJunoPkg/ArmJuno.dec
+
+[LibraryClasses]
+ BaseLib
+ BaseMemoryLib
+ DebugLib
+ IoLib
+ PcdLib
+ UefiLib
+ UefiBootServicesTableLib
+ UefiDriverEntryPoint
+ UefiRuntimeServicesTableLib
+ ArmLib
+
+[FixedPcd]
+ gArmJunoTokenSpaceGuid.PcdGenericWatchdogControlBase
+ gArmJunoTokenSpaceGuid.PcdGenericWatchdogRefreshBase
+ gArmJunoTokenSpaceGuid.PcdGenericWatchdogEl2IntrNum
+
+[Protocols]
+ gEfiWatchdogTimerArchProtocolGuid
+ gHardwareInterruptProtocolGuid
+
+[Depex]
+ gHardwareInterruptProtocolGuid
diff --git a/ArmPlatformPkg/ArmJunoPkg/Include/ArmJunoSmc.h b/ArmPlatformPkg/ArmJunoPkg/Include/ArmJunoSmc.h
new file mode 100755
index 000000000..ee6ae5eb0
--- /dev/null
+++ b/ArmPlatformPkg/ArmJunoPkg/Include/ArmJunoSmc.h
@@ -0,0 +1,25 @@
+/** @file
+*
+* Copyright (c) 2013-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.
+*
+**/
+
+#ifndef __ARM_JUNO_SMC_H__
+#define __ARM_JUNO_SMC_H__
+
+// System Management Trusted Interface
+#define ARM_JUNO_ARM_FAST_SMC_SET_SYSTEM_POWER_STATE 0x81000000
+
+// SMC System Power States
+#define ARM_JUNO_ARM_FAST_SMC_SYSTEM_POWER_STATE_REBOOT 0x0
+#define ARM_JUNO_ARM_FAST_SMC_SYSTEM_POWER_STATE_SHUTDOWN 0x1
+
+#endif
diff --git a/ArmPlatformPkg/ArmJunoPkg/Include/ArmPlatform.h b/ArmPlatformPkg/ArmJunoPkg/Include/ArmPlatform.h
new file mode 100755
index 000000000..be9b07b7a
--- /dev/null
+++ b/ArmPlatformPkg/ArmJunoPkg/Include/ArmPlatform.h
@@ -0,0 +1,51 @@
+/** @file
+*
+* Copyright (c) 2013-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.
+*
+**/
+
+#ifndef __ARM_JUNO_H__
+#define __ARM_JUNO_H__
+
+#include <VExpressMotherBoard.h>
+
+/***********************************************************************************
+// Platform Memory Map
+************************************************************************************/
+
+// Motherboard Peripheral and On-chip peripheral
+#define ARM_VE_BOARD_PERIPH_BASE 0x1C010000
+
+// NOR Flash 0
+#define ARM_VE_SMB_NOR0_BASE 0x08000000
+#define ARM_VE_SMB_NOR0_SZ SIZE_64MB
+
+// Off-Chip peripherals (USB, Ethernet, VRAM)
+#define ARM_VE_SMB_PERIPH_BASE 0x18000000
+#define ARM_VE_SMB_PERIPH_SZ (SIZE_64MB + SIZE_2MB)
+
+// On-Chip non-secure ROM
+#define ARM_JUNO_NON_SECURE_ROM_BASE 0x1F000000
+#define ARM_JUNO_NON_SECURE_ROM_SZ SIZE_16MB
+
+// On-Chip Peripherals
+#define ARM_JUNO_PERIPHERALS_BASE 0x20000000
+#define ARM_JUNO_PERIPHERALS_SZ 0x0E000000
+
+// On-Chip non-secure SRAM
+#define ARM_JUNO_NON_SECURE_SRAM_BASE 0x2E000000
+#define ARM_JUNO_NON_SECURE_SRAM_SZ SIZE_16MB
+
+// SOC peripherals (HDLCD, UART, I2C, I2S, USB, SMC-PL354, etc)
+#define ARM_JUNO_SOC_PERIPHERALS_BASE 0x7FF50000
+#define ARM_JUNO_SOC_PERIPHERALS_SZ (SIZE_64KB * 9)
+
+#endif
diff --git a/ArmPlatformPkg/ArmJunoPkg/Include/Drivers/GenericWatchdog.h b/ArmPlatformPkg/ArmJunoPkg/Include/Drivers/GenericWatchdog.h
new file mode 100755
index 000000000..578fd1e85
--- /dev/null
+++ b/ArmPlatformPkg/ArmJunoPkg/Include/Drivers/GenericWatchdog.h
@@ -0,0 +1,29 @@
+/** @file
+*
+* Copyright (c) 2013-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.
+*
+**/
+#ifndef __GENERIC_WATCHDOG_H__
+#define __GENERIC_WATCHDOG_H__
+
+// Refresh Frame:
+#define GENERIC_WDOG_REFRESH_REG ((UINT32)FixedPcdGet32 (PcdGenericWatchdogRefreshBase) + 0x000)
+
+// Control Frame:
+#define GENERIC_WDOG_CONTROL_STATUS_REG ((UINT32)FixedPcdGet32 (PcdGenericWatchdogControlBase) + 0x000)
+#define GENERIC_WDOG_OFFSET_REG ((UINT32)FixedPcdGet32 (PcdGenericWatchdogControlBase) + 0x008)
+#define GENERIC_WDOG_COMPARE_VALUE_REG ((UINT32)FixedPcdGet32 (PcdGenericWatchdogControlBase) + 0x010)
+
+// Values of bit 0 of the Control/Status Register
+#define GENERIC_WDOG_ENABLED 1
+#define GENERIC_WDOG_DISABLED 0
+
+#endif // __GENERIC_WATCHDOG_H__
diff --git a/ArmPlatformPkg/ArmJunoPkg/Library/ArmJunoLib/ArmJuno.c b/ArmPlatformPkg/ArmJunoPkg/Library/ArmJunoLib/ArmJuno.c
new file mode 100755
index 000000000..3be26d3ed
--- /dev/null
+++ b/ArmPlatformPkg/ArmJunoPkg/Library/ArmJunoLib/ArmJuno.c
@@ -0,0 +1,163 @@
+/** @file
+*
+* Copyright (c) 2013-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.
+*
+**/
+
+#include <Library/IoLib.h>
+#include <Library/ArmPlatformLib.h>
+#include <Library/DebugLib.h>
+#include <Library/PcdLib.h>
+
+#include <Ppi/ArmMpCoreInfo.h>
+
+#include <ArmPlatform.h>
+
+ARM_CORE_INFO mJunoInfoTable[] = {
+ {
+ // Cluster 0, Core 0
+ 0x0, 0x0,
+
+ // MP Core MailBox Set/Get/Clear Addresses and Clear Value
+ (EFI_PHYSICAL_ADDRESS)ARM_VE_SYS_FLAGS_REG,
+ (EFI_PHYSICAL_ADDRESS)ARM_VE_SYS_FLAGS_SET_REG,
+ (EFI_PHYSICAL_ADDRESS)ARM_VE_SYS_FLAGS_CLR_REG,
+ (UINT64)0xFFFFFFFF
+ },
+ {
+ // Cluster 0, Core 1
+ 0x0, 0x1,
+
+ // MP Core MailBox Set/Get/Clear Addresses and Clear Value
+ (EFI_PHYSICAL_ADDRESS)ARM_VE_SYS_FLAGS_REG,
+ (EFI_PHYSICAL_ADDRESS)ARM_VE_SYS_FLAGS_SET_REG,
+ (EFI_PHYSICAL_ADDRESS)ARM_VE_SYS_FLAGS_CLR_REG,
+ (UINT64)0xFFFFFFFF
+ },
+ {
+ // Cluster 1, Core 0
+ 0x1, 0x0,
+
+ // MP Core MailBox Set/Get/Clear Addresses and Clear Value
+ (EFI_PHYSICAL_ADDRESS)ARM_VE_SYS_FLAGS_REG,
+ (EFI_PHYSICAL_ADDRESS)ARM_VE_SYS_FLAGS_SET_REG,
+ (EFI_PHYSICAL_ADDRESS)ARM_VE_SYS_FLAGS_CLR_REG,
+ (UINT64)0xFFFFFFFF
+ },
+ {
+ // Cluster 1, Core 1
+ 0x1, 0x1,
+
+ // MP Core MailBox Set/Get/Clear Addresses and Clear Value
+ (EFI_PHYSICAL_ADDRESS)ARM_VE_SYS_FLAGS_REG,
+ (EFI_PHYSICAL_ADDRESS)ARM_VE_SYS_FLAGS_SET_REG,
+ (EFI_PHYSICAL_ADDRESS)ARM_VE_SYS_FLAGS_CLR_REG,
+ (UINT64)0xFFFFFFFF
+ },
+ {
+ // Cluster 1, Core 2
+ 0x1, 0x2,
+
+ // MP Core MailBox Set/Get/Clear Addresses and Clear Value
+ (EFI_PHYSICAL_ADDRESS)ARM_VE_SYS_FLAGS_REG,
+ (EFI_PHYSICAL_ADDRESS)ARM_VE_SYS_FLAGS_SET_REG,
+ (EFI_PHYSICAL_ADDRESS)ARM_VE_SYS_FLAGS_CLR_REG,
+ (UINT64)0xFFFFFFFF
+ },
+ {
+ // Cluster 1, Core 3
+ 0x1, 0x3,
+
+ // MP Core MailBox Set/Get/Clear Addresses and Clear Value
+ (EFI_PHYSICAL_ADDRESS)ARM_VE_SYS_FLAGS_REG,
+ (EFI_PHYSICAL_ADDRESS)ARM_VE_SYS_FLAGS_SET_REG,
+ (EFI_PHYSICAL_ADDRESS)ARM_VE_SYS_FLAGS_CLR_REG,
+ (UINT64)0xFFFFFFFF
+ }
+};
+
+/**
+ Return the current Boot Mode
+
+ This function returns the boot reason on the platform
+
+ @return Return the current Boot Mode of the platform
+
+**/
+EFI_BOOT_MODE
+ArmPlatformGetBootMode (
+ VOID
+ )
+{
+ return BOOT_WITH_FULL_CONFIGURATION;
+}
+
+/**
+ Initialize controllers that must setup in the normal world
+
+ This function is called by the ArmPlatformPkg/Pei or ArmPlatformPkg/Pei/PlatformPeim
+ in the PEI phase.
+
+**/
+RETURN_STATUS
+ArmPlatformInitialize (
+ IN UINTN MpId
+ )
+{
+ return RETURN_SUCCESS;
+}
+
+/**
+ Initialize the system (or sometimes called permanent) memory
+
+ This memory is generally represented by the DRAM.
+
+**/
+VOID
+ArmPlatformInitializeSystemMemory (
+ VOID
+ )
+{
+}
+
+EFI_STATUS
+PrePeiCoreGetMpCoreInfo (
+ OUT UINTN *CoreCount,
+ OUT ARM_CORE_INFO **ArmCoreTable
+ )
+{
+ // Only support one cluster
+ *CoreCount = sizeof(mJunoInfoTable) / sizeof(ARM_CORE_INFO);
+ *ArmCoreTable = mJunoInfoTable;
+ return EFI_SUCCESS;
+}
+
+// Needs to be declared in the file. Otherwise gArmMpCoreInfoPpiGuid is undefined in the contect of PrePeiCore
+EFI_GUID mArmMpCoreInfoPpiGuid = ARM_MP_CORE_INFO_PPI_GUID;
+ARM_MP_CORE_INFO_PPI mMpCoreInfoPpi = { PrePeiCoreGetMpCoreInfo };
+
+EFI_PEI_PPI_DESCRIPTOR gPlatformPpiTable[] = {
+ {
+ EFI_PEI_PPI_DESCRIPTOR_PPI,
+ &mArmMpCoreInfoPpiGuid,
+ &mMpCoreInfoPpi
+ }
+};
+
+VOID
+ArmPlatformGetPlatformPpiList (
+ OUT UINTN *PpiListSize,
+ OUT EFI_PEI_PPI_DESCRIPTOR **PpiList
+ )
+{
+ *PpiListSize = sizeof(gPlatformPpiTable);
+ *PpiList = gPlatformPpiTable;
+}
diff --git a/ArmPlatformPkg/ArmJunoPkg/Library/ArmJunoLib/ArmJunoHelper.S b/ArmPlatformPkg/ArmJunoPkg/Library/ArmJunoLib/ArmJunoHelper.S
new file mode 100755
index 000000000..fb5584f66
--- /dev/null
+++ b/ArmPlatformPkg/ArmJunoPkg/Library/ArmJunoLib/ArmJunoHelper.S
@@ -0,0 +1,75 @@
+/** @file
+*
+* Copyright (c) 2013-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.
+*
+**/
+
+#include <AsmMacroIoLibV8.h>
+#include <Library/ArmLib.h>
+
+.text
+.align 3
+
+GCC_ASM_EXPORT(ArmPlatformPeiBootAction)
+GCC_ASM_EXPORT(ArmPlatformGetCorePosition)
+GCC_ASM_EXPORT(ArmPlatformGetPrimaryCoreMpId)
+GCC_ASM_EXPORT(ArmPlatformIsPrimaryCore)
+
+GCC_ASM_IMPORT(_gPcd_FixedAtBuild_PcdArmPrimaryCoreMask)
+
+
+PrimaryCoreMpid: .word
+
+//UINTN
+//ArmPlatformGetCorePosition (
+// IN UINTN MpId
+// );
+// With this function: CorePos = (ClusterId * 2) + CoreId
+ASM_PFX(ArmPlatformGetCorePosition):
+ and x1, x0, #ARM_CORE_MASK
+ and x0, x0, #ARM_CLUSTER_MASK
+ add x0, x1, x0, LSR #7
+ ret
+
+//UINTN
+//ArmPlatformGetPrimaryCoreMpId (
+// VOID
+// );
+ASM_PFX(ArmPlatformGetPrimaryCoreMpId):
+ ldr x0, =PrimaryCoreMpid
+ ldrh w0, [x0]
+ ret
+
+//UINTN
+//ArmPlatformIsPrimaryCore (
+// IN UINTN MpId
+// );
+ASM_PFX(ArmPlatformIsPrimaryCore):
+ LoadConstantToReg (_gPcd_FixedAtBuild_PcdArmPrimaryCoreMask, x1)
+ ldrh w1, [x1]
+ and x0, x0, x1
+
+ ldr x1, =PrimaryCoreMpid
+ ldrh w1, [x1]
+
+ cmp w0, w1
+ mov x0, #1
+ mov x1, #0
+ csel x0, x0, x1, eq
+ ret
+
+ASM_PFX(ArmPlatformPeiBootAction):
+ // The trusted firmware passes the primary CPU MPID through x0 register.
+ // Save it in a variable.
+ ldr x1, =PrimaryCoreMpid
+ str w0, [x1]
+ ret
+
diff --git a/ArmPlatformPkg/ArmJunoPkg/Library/ArmJunoLib/ArmJunoLib.inf b/ArmPlatformPkg/ArmJunoPkg/Library/ArmJunoLib/ArmJunoLib.inf
new file mode 100755
index 000000000..b05d65890
--- /dev/null
+++ b/ArmPlatformPkg/ArmJunoPkg/Library/ArmJunoLib/ArmJunoLib.inf
@@ -0,0 +1,48 @@
+#
+# Copyright (c) 2013-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 = ArmJunoLib
+ FILE_GUID = 87c525cd-e1a2-469e-994c-c28cd0c7bd0d
+ MODULE_TYPE = BASE
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = ArmPlatformLib
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ EmbeddedPkg/EmbeddedPkg.dec
+ ArmPkg/ArmPkg.dec
+ ArmPlatformPkg/ArmPlatformPkg.dec
+ ArmPlatformPkg/ArmJunoPkg/ArmJuno.dec
+
+[LibraryClasses]
+ IoLib
+ ArmLib
+ MemoryAllocationLib
+ SerialPortLib
+
+[Sources.common]
+ ArmJuno.c
+ ArmJunoMem.c
+ ArmJunoHelper.S | GCC
+
+[FeaturePcd]
+ gEmbeddedTokenSpaceGuid.PcdCacheEnable
+
+[FixedPcd]
+ gArmTokenSpaceGuid.PcdSystemMemoryBase
+ gArmTokenSpaceGuid.PcdSystemMemorySize
+ gArmTokenSpaceGuid.PcdFvBaseAddress
+
+ gArmTokenSpaceGuid.PcdArmPrimaryCoreMask
diff --git a/ArmPlatformPkg/ArmJunoPkg/Library/ArmJunoLib/ArmJunoMem.c b/ArmPlatformPkg/ArmJunoPkg/Library/ArmJunoLib/ArmJunoMem.c
new file mode 100755
index 000000000..426bba682
--- /dev/null
+++ b/ArmPlatformPkg/ArmJunoPkg/Library/ArmJunoLib/ArmJunoMem.c
@@ -0,0 +1,118 @@
+/** @file
+*
+* Copyright (c) 2013-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.
+*
+**/
+
+#include <Library/ArmPlatformLib.h>
+#include <Library/DebugLib.h>
+#include <Library/PcdLib.h>
+#include <Library/IoLib.h>
+#include <Library/MemoryAllocationLib.h>
+
+#include <ArmPlatform.h>
+
+// The total number of descriptors, including the final "end-of-table" descriptor.
+#define MAX_VIRTUAL_MEMORY_MAP_DESCRIPTORS 11
+
+// DDR attributes
+#define DDR_ATTRIBUTES_CACHED ARM_MEMORY_REGION_ATTRIBUTE_WRITE_BACK
+#define DDR_ATTRIBUTES_UNCACHED ARM_MEMORY_REGION_ATTRIBUTE_UNCACHED_UNBUFFERED
+
+/**
+ Return the Virtual Memory Map of your platform
+
+ This Virtual Memory Map is used by MemoryInitPei Module to initialize the MMU on your platform.
+
+ @param[out] VirtualMemoryMap Array of ARM_MEMORY_REGION_DESCRIPTOR describing a Physical-to-
+ Virtual Memory mapping. This array must be ended by a zero-filled
+ entry
+
+**/
+VOID
+ArmPlatformGetVirtualMemoryMap (
+ IN ARM_MEMORY_REGION_DESCRIPTOR** VirtualMemoryMap
+ )
+{
+ ARM_MEMORY_REGION_ATTRIBUTES CacheAttributes;
+ UINTN Index = 0;
+ ARM_MEMORY_REGION_DESCRIPTOR *VirtualMemoryTable;
+
+ ASSERT (VirtualMemoryMap != NULL);
+
+ VirtualMemoryTable = (ARM_MEMORY_REGION_DESCRIPTOR*)AllocatePages(EFI_SIZE_TO_PAGES (sizeof(ARM_MEMORY_REGION_DESCRIPTOR) * MAX_VIRTUAL_MEMORY_MAP_DESCRIPTORS));
+ if (VirtualMemoryTable == NULL) {
+ return;
+ }
+
+ if (FeaturePcdGet(PcdCacheEnable) == TRUE) {
+ CacheAttributes = DDR_ATTRIBUTES_CACHED;
+ } else {
+ CacheAttributes = DDR_ATTRIBUTES_UNCACHED;
+ }
+
+ // SMB CS0 - NOR0 Flash
+ VirtualMemoryTable[Index].PhysicalBase = ARM_VE_SMB_NOR0_BASE;
+ VirtualMemoryTable[Index].VirtualBase = ARM_VE_SMB_NOR0_BASE;
+ VirtualMemoryTable[Index].Length = SIZE_256KB * 255;
+ VirtualMemoryTable[Index].Attributes = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE;
+ // Environment Variables region
+ VirtualMemoryTable[++Index].PhysicalBase = ARM_VE_SMB_NOR0_BASE + (SIZE_256KB * 255);
+ VirtualMemoryTable[Index].VirtualBase = ARM_VE_SMB_NOR0_BASE + (SIZE_256KB * 255);
+ VirtualMemoryTable[Index].Length = SIZE_64KB * 4;
+ VirtualMemoryTable[Index].Attributes = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE;
+
+ // SMB CS2 & CS3 - Off-chip (motherboard) peripherals
+ VirtualMemoryTable[++Index].PhysicalBase = ARM_VE_SMB_PERIPH_BASE;
+ VirtualMemoryTable[Index].VirtualBase = ARM_VE_SMB_PERIPH_BASE;
+ VirtualMemoryTable[Index].Length = ARM_VE_SMB_PERIPH_SZ;
+ VirtualMemoryTable[Index].Attributes = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE;
+
+ // Juno OnChip non-secure ROM
+ VirtualMemoryTable[++Index].PhysicalBase = ARM_JUNO_NON_SECURE_ROM_BASE;
+ VirtualMemoryTable[Index].VirtualBase = ARM_JUNO_NON_SECURE_ROM_BASE;
+ VirtualMemoryTable[Index].Length = ARM_JUNO_NON_SECURE_ROM_SZ;
+ VirtualMemoryTable[Index].Attributes = CacheAttributes;
+
+ // Juno OnChip peripherals
+ VirtualMemoryTable[++Index].PhysicalBase = ARM_JUNO_PERIPHERALS_BASE;
+ VirtualMemoryTable[Index].VirtualBase = ARM_JUNO_PERIPHERALS_BASE;
+ VirtualMemoryTable[Index].Length = ARM_JUNO_PERIPHERALS_SZ;
+ VirtualMemoryTable[Index].Attributes = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE;
+
+ // Juno OnChip non-secure SRAM
+ VirtualMemoryTable[++Index].PhysicalBase = ARM_JUNO_NON_SECURE_SRAM_BASE;
+ VirtualMemoryTable[Index].VirtualBase = ARM_JUNO_NON_SECURE_SRAM_BASE;
+ VirtualMemoryTable[Index].Length = ARM_JUNO_NON_SECURE_SRAM_SZ;
+ VirtualMemoryTable[Index].Attributes = CacheAttributes;
+
+ // Juno SOC peripherals
+ VirtualMemoryTable[++Index].PhysicalBase = ARM_JUNO_SOC_PERIPHERALS_BASE;
+ VirtualMemoryTable[Index].VirtualBase = ARM_JUNO_SOC_PERIPHERALS_BASE;
+ VirtualMemoryTable[Index].Length = ARM_JUNO_SOC_PERIPHERALS_SZ;
+ VirtualMemoryTable[Index].Attributes = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE;
+
+ // DDR
+ VirtualMemoryTable[++Index].PhysicalBase = PcdGet64 (PcdSystemMemoryBase);
+ VirtualMemoryTable[Index].VirtualBase = PcdGet64 (PcdSystemMemoryBase);
+ VirtualMemoryTable[Index].Length = PcdGet64 (PcdSystemMemorySize);
+ VirtualMemoryTable[Index].Attributes = CacheAttributes;
+
+ // End of Table
+ VirtualMemoryTable[++Index].PhysicalBase = 0;
+ VirtualMemoryTable[Index].VirtualBase = 0;
+ VirtualMemoryTable[Index].Length = 0;
+ VirtualMemoryTable[Index].Attributes = (ARM_MEMORY_REGION_ATTRIBUTES)0;
+
+ ASSERT((Index + 1) <= MAX_VIRTUAL_MEMORY_MAP_DESCRIPTORS);
+
+ *VirtualMemoryMap = VirtualMemoryTable;
+}
diff --git a/ArmPlatformPkg/ArmJunoPkg/Library/NorFlashJunoLib/NorFlashJuno.c b/ArmPlatformPkg/ArmJunoPkg/Library/NorFlashJunoLib/NorFlashJuno.c
new file mode 100755
index 000000000..480ff5886
--- /dev/null
+++ b/ArmPlatformPkg/ArmJunoPkg/Library/NorFlashJunoLib/NorFlashJuno.c
@@ -0,0 +1,68 @@
+/** @file
+
+ Copyright (c) 2011-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 <PiDxe.h>
+#include <Library/DebugLib.h>
+#include <Library/IoLib.h>
+#include <Library/NorFlashPlatformLib.h>
+#include <ArmPlatform.h>
+
+NOR_FLASH_DESCRIPTION mNorFlashDevices[] = {
+ {
+ ARM_VE_SMB_NOR0_BASE,
+ ARM_VE_SMB_NOR0_BASE,
+ SIZE_256KB * 255,
+ SIZE_256KB,
+ {0xE7223039, 0x5836, 0x41E1, 0xB5, 0x42, 0xD7, 0xEC, 0x73, 0x6C, 0x5E, 0x59}
+ },
+ {
+ ARM_VE_SMB_NOR0_BASE,
+ ARM_VE_SMB_NOR0_BASE + SIZE_256KB * 255,
+ SIZE_64KB * 4,
+ SIZE_64KB,
+ {0x02118005, 0x9DA7, 0x443A, 0x92, 0xD5, 0x78, 0x1F, 0x02, 0x2A, 0xED, 0xBB}
+ },
+};
+
+EFI_STATUS
+NorFlashPlatformInitialization (
+ VOID
+ )
+{
+ // Everything seems ok so far, so now we need to disable the platform-specific
+ // flash write protection for Versatile Express
+ if ((MmioRead32 (ARM_VE_SYS_FLASH) & 0x1) == 0) {
+ // Writing to NOR FLASH is disabled, so enable it
+ MmioWrite32 (ARM_VE_SYS_FLASH, 1);
+ DEBUG((DEBUG_BLKIO, "NorFlashWriteBlocks: informational - Had to enable HSYS_FLASH flag.\n" ));
+ }
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+NorFlashPlatformGetDevices (
+ OUT NOR_FLASH_DESCRIPTION **NorFlashDevices,
+ OUT UINT32 *Count
+ )
+{
+ if ((NorFlashDevices == NULL) || (Count == NULL)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ *NorFlashDevices = mNorFlashDevices;
+ *Count = sizeof (mNorFlashDevices) / sizeof (NOR_FLASH_DESCRIPTION);
+
+ return EFI_SUCCESS;
+}
diff --git a/ArmPlatformPkg/ArmJunoPkg/Library/NorFlashJunoLib/NorFlashJunoLib.inf b/ArmPlatformPkg/ArmJunoPkg/Library/NorFlashJunoLib/NorFlashJunoLib.inf
new file mode 100755
index 000000000..6b1363508
--- /dev/null
+++ b/ArmPlatformPkg/ArmJunoPkg/Library/NorFlashJunoLib/NorFlashJunoLib.inf
@@ -0,0 +1,32 @@
+#/** @file
+#
+# Copyright (c) 2011 - 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 = NorFlashJunoLib
+ FILE_GUID = 3eb6cbc4-ce95-11e2-b1bd-00241d0c1ba8
+ MODULE_TYPE = DXE_DRIVER
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = NorFlashPlatformLib
+
+[Sources.common]
+ NorFlashJuno.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ ArmPlatformPkg/ArmPlatformPkg.dec
+
+[LibraryClasses]
+ BaseLib
+ DebugLib
+ IoLib
diff --git a/ArmPlatformPkg/ArmJunoPkg/Library/ResetSystemLib/ResetSystemLib.c b/ArmPlatformPkg/ArmJunoPkg/Library/ResetSystemLib/ResetSystemLib.c
new file mode 100755
index 000000000..2297318b2
--- /dev/null
+++ b/ArmPlatformPkg/ArmJunoPkg/Library/ResetSystemLib/ResetSystemLib.c
@@ -0,0 +1,87 @@
+/** @file
+*
+* Copyright (c) 2013-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.
+*
+**/
+
+#include <PiDxe.h>
+
+#include <Library/DebugLib.h>
+#include <Library/EfiResetSystemLib.h>
+#include <Library/ArmSmcLib.h>
+#include <ArmJunoSmc.h>
+
+/**
+ Resets the entire platform.
+
+ @param ResetType The type of reset to perform.
+ @param ResetStatus The status code for the reset.
+ @param DataSize The size, in bytes, of WatchdogData.
+ @param ResetData For a ResetType of EfiResetCold, EfiResetWarm, or
+ EfiResetShutdown the data buffer starts with a Null-terminated
+ Unicode string, optionally followed by additional binary data.
+
+**/
+EFI_STATUS
+EFIAPI
+LibResetSystem (
+ IN EFI_RESET_TYPE ResetType,
+ IN EFI_STATUS ResetStatus,
+ IN UINTN DataSize,
+ IN CHAR16 *ResetData OPTIONAL
+ )
+{
+ UINTN Rx;
+ UINTN SystemState;
+
+ switch (ResetType) {
+ case EfiResetWarm:
+ case EfiResetCold:
+ // Map a warm reset into a cold reset
+ Rx = ARM_JUNO_ARM_FAST_SMC_SET_SYSTEM_POWER_STATE;
+ SystemState = ARM_JUNO_ARM_FAST_SMC_SYSTEM_POWER_STATE_REBOOT;
+ break;
+ case EfiResetShutdown:
+ Rx = ARM_JUNO_ARM_FAST_SMC_SET_SYSTEM_POWER_STATE;
+ SystemState = ARM_JUNO_ARM_FAST_SMC_SYSTEM_POWER_STATE_SHUTDOWN;
+ break;
+ default:
+ Rx = 0;
+ ASSERT(FALSE);
+ }
+
+ if (Rx != 0) {
+ ArmCallSmcArg1 (&Rx, &SystemState);
+ // We should never be here
+ while(1);
+ }
+
+ return EFI_UNSUPPORTED;
+}
+
+/**
+ Initialize any infrastructure required for LibResetSystem () to function.
+
+ @param ImageHandle The firmware allocated handle for the EFI image.
+ @param SystemTable A pointer to the EFI System Table.
+
+ @retval EFI_SUCCESS The constructor always returns EFI_SUCCESS.
+
+**/
+EFI_STATUS
+EFIAPI
+LibInitializeResetSystem (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ return EFI_SUCCESS;
+}
diff --git a/ArmPlatformPkg/ArmJunoPkg/Library/ResetSystemLib/ResetSystemLib.inf b/ArmPlatformPkg/ArmJunoPkg/Library/ResetSystemLib/ResetSystemLib.inf
new file mode 100755
index 000000000..1cf9654f8
--- /dev/null
+++ b/ArmPlatformPkg/ArmJunoPkg/Library/ResetSystemLib/ResetSystemLib.inf
@@ -0,0 +1,32 @@
+#
+# Copyright (c) 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 = ArmJunoResetSystemLib
+ FILE_GUID = b5b8e984-c8a2-4df4-b5ac-026204124aa0
+ MODULE_TYPE = BASE
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = EfiResetSystemLib
+
+[Sources.common]
+ ResetSystemLib.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ EmbeddedPkg/EmbeddedPkg.dec
+ ArmPkg/ArmPkg.dec
+ ArmPlatformPkg/ArmJunoPkg/ArmJuno.dec
+
+[LibraryClasses]
+ DebugLib
+ ArmSmcLib
diff --git a/ArmPlatformPkg/ArmJunoPkg/Makefile b/ArmPlatformPkg/ArmJunoPkg/Makefile
new file mode 100755
index 000000000..9548629f1
--- /dev/null
+++ b/ArmPlatformPkg/ArmJunoPkg/Makefile
@@ -0,0 +1,89 @@
+#
+# Copyright (c) 2013-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.
+#
+
+# Define the following variables to specify an alternative toolchain to the one located in your PATH:
+# - RVCT_TOOLS_PATH: for RVCT and RVCTLINUX toolchains
+# - ARMGCC_TOOLS_PATH: for ARMGCC toolchain
+# - ARMLINUXGCC_TOOLS_PATH: for ARMLINUXGCC
+
+EDK2_TOOLCHAIN ?= GCC48
+GCC48_AARCH64_PREFIX ?= aarch64-linux-gnu-
+EDK2_ARCH ?= AARCH64
+EDK2_BUILD ?= DEBUG
+EDK2_DSC = ArmPlatformPkg/ArmJunoPkg/ArmJuno.dsc
+DEST_BIN_ROOT ?=
+
+ifeq ($(EDK2_DSC),"")
+ $(error The Makefile macro 'EDK2_DSC' must be defined with an EDK2 DSC file.)
+endif
+
+ifeq ("$(OS)","Windows_NT")
+export WORKSPACE?=$(PWD)
+export EDK_TOOLS_PATH ?= $(WORKSPACE)\BaseTools
+else
+export WORKSPACE?=$(PWD)
+endif
+
+# Define the destination of the Firmware Image Package (FIP) if not defined
+ifndef JUNO_FIP
+ ifdef DEST_BIN_ROOT
+ JUNO_FIP=$(DEST_BIN_ROOT)/fip.bin
+ else
+ JUNO_FIP=fip.bin
+ endif
+endif
+
+SHELL := /bin/bash
+SILENT ?= @
+ECHO ?= echo
+MAKE ?= make -i -k
+RM ?= rm -f
+CP ?= cp
+
+.PHONY: all clean
+
+EDK2_CONF = Conf/BuildEnv.sh Conf/build_rule.txt Conf/target.txt Conf/tools_def.txt
+
+all: $(EDK2_CONF)
+ifeq ("$(OS)","Windows_NT")
+ build -a $(EDK2_ARCH) -p $(EDK2_DSC) -t $(EDK2_TOOLCHAIN) -b $(EDK2_BUILD) $(EDK2_MACROS)
+else
+ . ./edksetup.sh; GCC47_AARCH64_PREFIX=$(GCC47_AARCH64_PREFIX) build -a $(EDK2_ARCH) -p $(EDK2_DSC) -t $(EDK2_TOOLCHAIN) -b $(EDK2_BUILD) $(EDK2_MACROS)
+endif
+ifeq ("$(OS)","Windows_NT")
+ $(SILENT)$(ECHO) "Warning: The UEFI Firmware must be added to the Firmware Image Package (FIP)."
+else
+ $(SILENT)which fip_create ; \
+ if [ $$? -ne 0 ]; then \
+ $(ECHO) "Warning: 'fip_create' tool is not in the PATH. The UEFI binary will not be added in the Firmware Image Package (FIP)."; \
+ else \
+ fip_create --bl33 $(WORKSPACE)/Build/ArmJuno/$(EDK2_BUILD)_$(EDK2_TOOLCHAIN)/FV/BL32_AP_UEFI.fd --dump $(JUNO_FIP); \
+ fi
+endif
+
+$(EDK2_CONF):
+ifeq ("$(OS)","Windows_NT")
+ copy $(EDK_TOOLS_PATH)\Conf\build_rule.template Conf\build_rule.txt
+ copy $(EDK_TOOLS_PATH)\Conf\FrameworkDatabase.template Conf\FrameworkDatabase.txt
+ copy $(EDK_TOOLS_PATH)\Conf\target.template Conf\target.txt
+ copy $(EDK_TOOLS_PATH)\Conf\tools_def.template Conf\tools_def.txt
+else
+ . ./edksetup.sh; $(MAKE) -C BaseTools
+endif
+
+clean:
+ifeq ("$(OS)","Windows_NT")
+ build -a $(EDK2_ARCH) -p $(EDK2_DSC) -t $(EDK2_TOOLCHAIN) -b $(EDK2_BUILD) $(EDK2_MACROS) cleanall
+else
+ . ./edksetup.sh; build -a $(EDK2_ARCH) -p $(EDK2_DSC) -t $(EDK2_TOOLCHAIN) -b $(EDK2_BUILD) $(EDK2_MACROS) cleanall; \
+ rm -Rf $(EDK2_CONF) Conf/.cache
+endif
diff --git a/ArmPlatformPkg/ArmVExpressPkg/ArmVExpress-CTA15-A7.dsc b/ArmPlatformPkg/ArmVExpressPkg/ArmVExpress-CTA15-A7.dsc
index ad94f5451..5cba19952 100644
--- a/ArmPlatformPkg/ArmVExpressPkg/ArmVExpress-CTA15-A7.dsc
+++ b/ArmPlatformPkg/ArmVExpressPkg/ArmVExpress-CTA15-A7.dsc
@@ -171,7 +171,10 @@
#
gArmTokenSpaceGuid.PcdGicDistributorBase|0x2C001000
gArmTokenSpaceGuid.PcdGicInterruptInterfaceBase|0x2C002000
-
+
+ # ISP1761 USB OTG Controller
+ gEmbeddedTokenSpaceGuid.PcdIsp1761BaseAddress|0x1B000000
+
# Ethernet (SMSC 91C111)
gArmPlatformTokenSpaceGuid.PcdLan9118DxeBaseAddress|0x1A000000
diff --git a/ArmPlatformPkg/ArmVExpressPkg/ArmVExpress-CTA15-A7.fdf b/ArmPlatformPkg/ArmVExpressPkg/ArmVExpress-CTA15-A7.fdf
index 2b42322f2..a686c5185 100644
--- a/ArmPlatformPkg/ArmVExpressPkg/ArmVExpress-CTA15-A7.fdf
+++ b/ArmPlatformPkg/ArmVExpressPkg/ArmVExpress-CTA15-A7.fdf
@@ -25,13 +25,13 @@
################################################################################
[FD.ARM_VEXPRESS_CTA15A7_EFI]
-BaseAddress = 0x81000000|gArmTokenSpaceGuid.PcdFdBaseAddress # The base address of the Firmware in remapped DRAM.
-Size = 0x000D5000|gArmTokenSpaceGuid.PcdFdSize # The size in bytes of the FLASH Device
+BaseAddress = 0xB0000000|gArmTokenSpaceGuid.PcdFdBaseAddress # The base address of the Firmware in remapped DRAM.
+Size = 0x000B0000|gArmTokenSpaceGuid.PcdFdSize # The size in bytes of the FLASH Device
ErasePolarity = 1
BlockSize = 0x00001000
-NumBlocks = 0xD5
+NumBlocks = 0xB0
-0x00000000|0x000D5000
+0x00000000|0x000B0000
gArmTokenSpaceGuid.PcdFvBaseAddress|gArmTokenSpaceGuid.PcdFvSize
FV = FVMAIN_COMPACT
@@ -134,6 +134,18 @@ READ_LOCK_STATUS = TRUE
# Versatile Express FileSystem
INF ArmPlatformPkg/FileSystem/BootMonFs/BootMonFs.inf
+ #
+ # USB support
+ #
+ INF EmbeddedPkg/Drivers/Isp1761UsbDxe/Isp1761UsbDxe.inf
+
+ #
+ # Android Fastboot
+ #
+ INF EmbeddedPkg/Application/AndroidFastboot/AndroidFastbootApp.inf
+ INF EmbeddedPkg/Drivers/AndroidFastbootTransportUsbDxe/FastbootTransportUsbDxe.inf
+ INF ArmPlatformPkg/ArmVExpressPkg/ArmVExpressFastBootDxe/ArmVExpressFastBootDxe.inf
+
# ACPI Support
INF MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableDxe.inf
diff --git a/ArmPlatformPkg/ArmVExpressPkg/ArmVExpress-CTA9x4.dsc b/ArmPlatformPkg/ArmVExpressPkg/ArmVExpress-CTA9x4.dsc
index 397e6be3a..8b6bc41d5 100644
--- a/ArmPlatformPkg/ArmVExpressPkg/ArmVExpress-CTA9x4.dsc
+++ b/ArmPlatformPkg/ArmVExpressPkg/ArmVExpress-CTA9x4.dsc
@@ -205,6 +205,9 @@
#
gArmTokenSpaceGuid.PcdL2x0ControllerBase|0x1E00A000
+ # ISP1761 USB OTG Controller
+ gEmbeddedTokenSpaceGuid.PcdIsp1761BaseAddress|0x4f000000
+
#
# LAN9118 Ethernet Driver PCDs
#
diff --git a/ArmPlatformPkg/ArmVExpressPkg/ArmVExpress-CTA9x4.fdf b/ArmPlatformPkg/ArmVExpressPkg/ArmVExpress-CTA9x4.fdf
index ab6a70917..5e854b227 100644
--- a/ArmPlatformPkg/ArmVExpressPkg/ArmVExpress-CTA9x4.fdf
+++ b/ArmPlatformPkg/ArmVExpressPkg/ArmVExpress-CTA9x4.fdf
@@ -220,8 +220,19 @@ READ_LOCK_STATUS = TRUE
#
INF EmbeddedPkg/Universal/MmcDxe/MmcDxe.inf
INF ArmPlatformPkg/Drivers/PL180MciDxe/PL180MciDxe.inf
-
+
+ #
+ # USB support
#
+ INF EmbeddedPkg/Drivers/Isp1761UsbDxe/Isp1761UsbDxe.inf
+
+ #
+ # Android Fastboot
+ #
+ INF EmbeddedPkg/Application/AndroidFastboot/AndroidFastbootApp.inf
+ INF EmbeddedPkg/Drivers/AndroidFastbootTransportUsbDxe/FastbootTransportUsbDxe.inf
+ INF ArmPlatformPkg/ArmVExpressPkg/ArmVExpressFastBootDxe/ArmVExpressFastBootDxe.inf
+
# Networking stack
#
INF MdeModulePkg/Universal/Network/DpcDxe/DpcDxe.inf
diff --git a/ArmPlatformPkg/ArmVExpressPkg/ArmVExpress.dsc.inc b/ArmPlatformPkg/ArmVExpressPkg/ArmVExpress.dsc.inc
index 79d6ea054..a3708b521 100644
--- a/ArmPlatformPkg/ArmVExpressPkg/ArmVExpress.dsc.inc
+++ b/ArmPlatformPkg/ArmVExpressPkg/ArmVExpress.dsc.inc
@@ -323,12 +323,16 @@
gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiBootServicesData|20000
gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiLoaderCode|20
gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiLoaderData|0
-
+
+ # 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)"
+
#
# ARM Pcds
#
gArmTokenSpaceGuid.PcdArmUncachedMemoryMask|0x0000000000000000
-
+
#
# ARM PrimeCell
#
@@ -374,5 +378,15 @@
MdeModulePkg/Universal/Network/Udp4Dxe/Udp4Dxe.inf
MdeModulePkg/Universal/Network/UefiPxeBcDxe/UefiPxeBcDxe.inf
MdeModulePkg/Universal/Network/IScsiDxe/IScsiDxe.inf
+
+ # ISP1761 USB OTG Controller
+ EmbeddedPkg/Drivers/Isp1761UsbDxe/Isp1761UsbDxe.inf
+
+ #
+ # Android Fastboot
+ #
+ EmbeddedPkg/Application/AndroidFastboot/AndroidFastbootApp.inf
+ EmbeddedPkg/Drivers/AndroidFastbootTransportUsbDxe/FastbootTransportUsbDxe.inf
+ ArmPlatformPkg/ArmVExpressPkg/ArmVExpressFastBootDxe/ArmVExpressFastBootDxe.inf
ArmPlatformPkg/Drivers/LAN9118Dxe/LAN9118Dxe.inf
ArmPlatformPkg/Drivers/LAN91xDxe/LAN91xDxe.inf
diff --git a/ArmPlatformPkg/ArmVExpressPkg/ArmVExpressFastBootDxe/ArmVExpressFastBoot.c b/ArmPlatformPkg/ArmVExpressPkg/ArmVExpressFastBootDxe/ArmVExpressFastBoot.c
new file mode 100644
index 000000000..7312cfbc1
--- /dev/null
+++ b/ArmPlatformPkg/ArmVExpressPkg/ArmVExpressFastBootDxe/ArmVExpressFastBoot.c
@@ -0,0 +1,451 @@
+/** @file
+
+ 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.
+
+**/
+
+/*
+ Implementation of the Android Fastboot Platform protocol, to be used by the
+ Fastboot UEFI application, for ARM Versatile Express platforms.
+*/
+
+#include <Protocol/AndroidFastbootPlatform.h>
+#include <Protocol/BlockIo.h>
+#include <Protocol/DiskIo.h>
+
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/DevicePathLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+
+#define FLASH_DEVICE_PATH_SIZE(DevPath) ( GetDevicePathSize (DevPath) - \
+ sizeof (EFI_DEVICE_PATH_PROTOCOL))
+
+#define PARTITION_NAME_MAX_LENGTH 72/2
+
+#define IS_ALPHA(Char) (((Char) <= L'z' && (Char) >= L'a') || \
+ ((Char) <= L'Z' && (Char) >= L'Z'))
+
+typedef struct _FASTBOOT_PARTITION_LIST {
+ LIST_ENTRY Link;
+ CHAR16 PartitionName[PARTITION_NAME_MAX_LENGTH];
+ EFI_HANDLE PartitionHandle;
+} FASTBOOT_PARTITION_LIST;
+
+STATIC LIST_ENTRY mPartitionListHead;
+
+/*
+ Helper to free the partition list
+*/
+STATIC
+VOID
+FreePartitionList (
+ VOID
+ )
+{
+ FASTBOOT_PARTITION_LIST *Entry;
+ FASTBOOT_PARTITION_LIST *NextEntry;
+
+ Entry = (FASTBOOT_PARTITION_LIST *) GetFirstNode (&mPartitionListHead);
+ while (!IsNull (&mPartitionListHead, &Entry->Link)) {
+ NextEntry = (FASTBOOT_PARTITION_LIST *) GetNextNode (&mPartitionListHead, &Entry->Link);
+
+ RemoveEntryList (&Entry->Link);
+ FreePool (Entry);
+
+ Entry = NextEntry;
+ }
+}
+/*
+ Read the PartitionName fields from the GPT partition entries, putting them
+ into an allocated array that should later be freed.
+*/
+STATIC
+EFI_STATUS
+ReadPartitionEntries (
+ IN EFI_BLOCK_IO_PROTOCOL *BlockIo,
+ OUT EFI_PARTITION_ENTRY **PartitionEntries
+ )
+{
+ UINTN EntrySize;
+ UINTN NumEntries;
+ UINTN BufferSize;
+ UINT32 MediaId;
+ EFI_PARTITION_TABLE_HEADER *GptHeader;
+ EFI_STATUS Status;
+
+ MediaId = BlockIo->Media->MediaId;
+
+ //
+ // Read size of Partition entry and number of entries from GPT header
+ //
+
+ GptHeader = AllocatePool (BlockIo->Media->BlockSize);
+ if (GptHeader == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ Status = BlockIo->ReadBlocks (BlockIo, MediaId, 1, BlockIo->Media->BlockSize, (VOID *) GptHeader);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ // Check there is a GPT on the media
+ if (GptHeader->Header.Signature != EFI_PTAB_HEADER_ID ||
+ GptHeader->MyLBA != 1) {
+ DEBUG ((EFI_D_ERROR,
+ "Fastboot platform: No GPT on flash. "
+ "Fastboot on Versatile Express does not support MBR.\n"
+ ));
+ return EFI_DEVICE_ERROR;
+ }
+
+ EntrySize = GptHeader->SizeOfPartitionEntry;
+ NumEntries = GptHeader->NumberOfPartitionEntries;
+
+ FreePool (GptHeader);
+
+ ASSERT (EntrySize != 0);
+ ASSERT (NumEntries != 0);
+
+ BufferSize = ALIGN_VALUE (EntrySize * NumEntries, BlockIo->Media->BlockSize);
+ *PartitionEntries = AllocatePool (BufferSize);
+ if (PartitionEntries == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ Status = BlockIo->ReadBlocks (BlockIo, MediaId, 2, BufferSize, (VOID *) *PartitionEntries);
+ if (EFI_ERROR (Status)) {
+ FreePool (PartitionEntries);
+ return Status;
+ }
+
+ return Status;
+}
+
+
+/*
+ Initialise: Open the Android NVM device and find the partitions on it. Save them in
+ a list along with the "PartitionName" fields for their GPT entries.
+ We will use these partition names as the key in
+ ArmFastbootPlatformFlashPartition.
+*/
+EFI_STATUS
+ArmFastbootPlatformInit (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+ EFI_DEVICE_PATH_PROTOCOL *FlashDevicePath;
+ EFI_DEVICE_PATH_PROTOCOL *FlashDevicePathDup;
+ EFI_DEVICE_PATH_PROTOCOL *DevicePath;
+ EFI_DEVICE_PATH_PROTOCOL *NextNode;
+ HARDDRIVE_DEVICE_PATH *PartitionNode;
+ UINTN NumHandles;
+ EFI_HANDLE *AllHandles;
+ UINTN LoopIndex;
+ EFI_HANDLE FlashHandle;
+ EFI_BLOCK_IO_PROTOCOL *FlashBlockIo;
+ EFI_PARTITION_ENTRY *PartitionEntries;
+ FASTBOOT_PARTITION_LIST *Entry;
+
+ InitializeListHead (&mPartitionListHead);
+
+ //
+ // Get EFI_HANDLES for all the partitions on the block devices pointed to by
+ // PcdFastbootFlashDevicePath, also saving their GPT partition labels.
+ // There's no way to find all of a device's children, so we get every handle
+ // in the system supporting EFI_BLOCK_IO_PROTOCOL and then filter out ones
+ // that don't represent partitions on the flash device.
+ //
+
+ FlashDevicePath = ConvertTextToDevicePath ((CHAR16*)FixedPcdGetPtr (PcdAndroidFastbootNvmDevicePath));
+
+ //
+ // Open the Disk IO protocol on the flash device - this will be used to read
+ // partition names out of the GPT entries
+ //
+ // Create another device path pointer because LocateDevicePath will modify it.
+ FlashDevicePathDup = FlashDevicePath;
+ Status = gBS->LocateDevicePath (&gEfiBlockIoProtocolGuid, &FlashDevicePathDup, &FlashHandle);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR, "Warning: Couldn't locate Android NVM device (status: %r)\n", Status));
+ // Failing to locate partitions should not prevent to do other Android FastBoot actions
+ return EFI_SUCCESS;
+ }
+
+ Status = gBS->OpenProtocol (
+ FlashHandle,
+ &gEfiBlockIoProtocolGuid,
+ (VOID **) &FlashBlockIo,
+ gImageHandle,
+ NULL,
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR, "Fastboot platform: Couldn't open Android NVM device (status: %r)\n", Status));
+ return EFI_DEVICE_ERROR;
+ }
+
+ // Read the GPT partition entry array into memory so we can get the partition names
+ Status = ReadPartitionEntries (FlashBlockIo, &PartitionEntries);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR, "Warning: Failed to read partitions from Android NVM device (status: %r)\n", Status));
+ // Failing to locate partitions should not prevent to do other Android FastBoot actions
+ return EFI_SUCCESS;
+ }
+
+ // Get every Block IO protocol instance installed in the system
+ Status = gBS->LocateHandleBuffer (
+ ByProtocol,
+ &gEfiBlockIoProtocolGuid,
+ NULL,
+ &NumHandles,
+ &AllHandles
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ // Filter out handles that aren't children of the flash device
+ for (LoopIndex = 0; LoopIndex < NumHandles; LoopIndex++) {
+ // Get the device path for the handle
+ Status = gBS->OpenProtocol (
+ AllHandles[LoopIndex],
+ &gEfiDevicePathProtocolGuid,
+ (VOID **) &DevicePath,
+ gImageHandle,
+ NULL,
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ // Check if it is a sub-device of the flash device
+ if (!CompareMem (DevicePath, FlashDevicePath, FLASH_DEVICE_PATH_SIZE (FlashDevicePath))) {
+ // Device path starts with path of flash device. Check it isn't the flash
+ // device itself.
+ NextNode = NextDevicePathNode (DevicePath);
+ if (IsDevicePathEndType (NextNode)) {
+ continue;
+ }
+
+ // Assert that this device path node represents a partition.
+ ASSERT (NextNode->Type == MEDIA_DEVICE_PATH &&
+ NextNode->SubType == MEDIA_HARDDRIVE_DP);
+
+ PartitionNode = (HARDDRIVE_DEVICE_PATH *) NextNode;
+
+ // Assert that the partition type is GPT. ReadPartitionEntries checks for
+ // presence of a GPT, so we should never find MBR partitions.
+ // ("MBRType" is a misnomer - this field is actually called "Partition
+ // Format")
+ ASSERT (PartitionNode->MBRType == MBR_TYPE_EFI_PARTITION_TABLE_HEADER);
+
+ // The firmware may install a handle for "partition 0", representing the
+ // whole device. Ignore it.
+ if (PartitionNode->PartitionNumber == 0) {
+ continue;
+ }
+
+ //
+ // Add the partition handle to the list
+ //
+
+ // Create entry
+ Entry = AllocatePool (sizeof (FASTBOOT_PARTITION_LIST));
+ if (Entry == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ FreePartitionList ();
+ goto Exit;
+ }
+
+ // Copy handle and partition name
+ Entry->PartitionHandle = AllHandles[LoopIndex];
+ StrnCpy (
+ Entry->PartitionName,
+ PartitionEntries[PartitionNode->PartitionNumber - 1].PartitionName, // Partition numbers start from 1.
+ PARTITION_NAME_MAX_LENGTH
+ );
+ InsertTailList (&mPartitionListHead, &Entry->Link);
+
+ // Print a debug message if the partition label is empty or looks like
+ // garbage.
+ if (!IS_ALPHA (Entry->PartitionName[0])) {
+ DEBUG ((EFI_D_ERROR,
+ "Warning: Partition %d doesn't seem to have a GPT partition label. "
+ "You won't be able to flash it with Fastboot.\n",
+ PartitionNode->PartitionNumber
+ ));
+ }
+ }
+ }
+
+Exit:
+ FreePool (PartitionEntries);
+ FreePool (FlashDevicePath);
+ FreePool (AllHandles);
+ return Status;
+
+}
+
+VOID
+ArmFastbootPlatformUnInit (
+ VOID
+ )
+{
+ FreePartitionList ();
+}
+
+EFI_STATUS
+ArmFastbootPlatformFlashPartition (
+ IN CHAR8 *PartitionName,
+ IN UINTN Size,
+ IN VOID *Image
+ )
+{
+ EFI_STATUS Status;
+ EFI_BLOCK_IO_PROTOCOL *BlockIo;
+ EFI_DISK_IO_PROTOCOL *DiskIo;
+ UINT32 MediaId;
+ UINTN PartitionSize;
+ FASTBOOT_PARTITION_LIST *Entry;
+ CHAR16 PartitionNameUnicode[60];
+ BOOLEAN PartitionFound;
+
+ AsciiStrToUnicodeStr (PartitionName, PartitionNameUnicode);
+
+ PartitionFound = FALSE;
+ Entry = (FASTBOOT_PARTITION_LIST *) GetFirstNode (&(mPartitionListHead));
+ while (!IsNull (&mPartitionListHead, &Entry->Link)) {
+ // Search the partition list for the partition named by PartitionName
+ if (StrCmp (Entry->PartitionName, PartitionNameUnicode) == 0) {
+ PartitionFound = TRUE;
+ break;
+ }
+
+ Entry = (FASTBOOT_PARTITION_LIST *) GetNextNode (&mPartitionListHead, &(Entry)->Link);
+ }
+ if (!PartitionFound) {
+ return EFI_NOT_FOUND;
+ }
+
+ Status = gBS->OpenProtocol (
+ Entry->PartitionHandle,
+ &gEfiBlockIoProtocolGuid,
+ (VOID **) &BlockIo,
+ gImageHandle,
+ NULL,
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR, "Fastboot platform: couldn't open Block IO for flash: %r\n", Status));
+ return EFI_NOT_FOUND;
+ }
+
+ // Check image will fit on device
+ PartitionSize = (BlockIo->Media->LastBlock + 1) * BlockIo->Media->BlockSize;
+ if (PartitionSize < Size) {
+ DEBUG ((EFI_D_ERROR, "Partition not big enough.\n"));
+ DEBUG ((EFI_D_ERROR, "Partition Size:\t%d\nImage Size:\t%d\n", PartitionSize, Size));
+
+ return EFI_VOLUME_FULL;
+ }
+
+ MediaId = BlockIo->Media->MediaId;
+
+ Status = gBS->OpenProtocol (
+ Entry->PartitionHandle,
+ &gEfiDiskIoProtocolGuid,
+ (VOID **) &DiskIo,
+ gImageHandle,
+ NULL,
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ Status = DiskIo->WriteDisk (DiskIo, MediaId, 0, Size, Image);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ BlockIo->FlushBlocks(BlockIo);
+
+ return Status;
+}
+
+EFI_STATUS
+ArmFastbootPlatformErasePartition (
+ IN CHAR8 *Partition
+ )
+{
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+ArmFastbootPlatformGetVar (
+ IN CHAR8 *Name,
+ OUT CHAR8 *Value
+ )
+{
+ if (AsciiStrCmp (Name, "product")) {
+ AsciiStrCpy (Value, FixedPcdGetPtr (PcdFirmwareVendor));
+ } else {
+ *Value = '\0';
+ }
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+ArmFastbootPlatformOemCommand (
+ IN CHAR8 *Command
+ )
+{
+ CHAR16 CommandUnicode[65];
+
+ AsciiStrToUnicodeStr (Command, CommandUnicode);
+
+ if (AsciiStrCmp (Command, "Demonstrate") == 0) {
+ DEBUG ((EFI_D_ERROR, "ARM OEM Fastboot command 'Demonstrate' received.\n"));
+ return EFI_SUCCESS;
+ } else {
+ DEBUG ((EFI_D_ERROR,
+ "VExpress: Unrecognised Fastboot OEM command: %s\n",
+ CommandUnicode
+ ));
+ return EFI_NOT_FOUND;
+ }
+}
+
+FASTBOOT_PLATFORM_PROTOCOL mPlatformProtocol = {
+ ArmFastbootPlatformInit,
+ ArmFastbootPlatformUnInit,
+ ArmFastbootPlatformFlashPartition,
+ ArmFastbootPlatformErasePartition,
+ ArmFastbootPlatformGetVar,
+ ArmFastbootPlatformOemCommand
+};
+
+EFI_STATUS
+EFIAPI
+ArmAndroidFastbootPlatformEntryPoint (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ gImageHandle = ImageHandle;
+
+ return gBS->InstallProtocolInterface (
+ &ImageHandle,
+ &gAndroidFastbootPlatformProtocolGuid,
+ EFI_NATIVE_INTERFACE,
+ &mPlatformProtocol
+ );
+}
diff --git a/ArmPlatformPkg/ArmVExpressPkg/ArmVExpressFastBootDxe/ArmVExpressFastBootDxe.inf b/ArmPlatformPkg/ArmVExpressPkg/ArmVExpressFastBootDxe/ArmVExpressFastBootDxe.inf
new file mode 100644
index 000000000..468f5a479
--- /dev/null
+++ b/ArmPlatformPkg/ArmVExpressPkg/ArmVExpressFastBootDxe/ArmVExpressFastBootDxe.inf
@@ -0,0 +1,54 @@
+#/** @file
+#
+# 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 = ArmVExpressFastBootDxe
+ FILE_GUID = 4004e454-89a0-11e3-89aa-97ef9d942abc
+ MODULE_TYPE = UEFI_DRIVER
+ VERSION_STRING = 1.0
+ ENTRY_POINT = ArmAndroidFastbootPlatformEntryPoint
+
+[Sources.common]
+ ArmVExpressFastBoot.c
+
+[LibraryClasses]
+ BaseLib
+ BaseMemoryLib
+ DebugLib
+ DevicePathLib
+ MemoryAllocationLib
+ PcdLib
+ UefiBootServicesTableLib
+ UefiDriverEntryPoint
+
+[Protocols]
+ gAndroidFastbootPlatformProtocolGuid
+ gEfiBlockIoProtocolGuid
+ gEfiDiskIoProtocolGuid
+
+[Packages]
+ EmbeddedPkg/EmbeddedPkg.dec
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ ArmPlatformPkg/ArmPlatformPkg.dec
+ ArmPlatformPkg/ArmVExpressPkg/ArmVExpressPkg.dec
+ ArmPkg/ArmPkg.dec
+
+[Guids]
+ gArmGlobalVariableGuid
+
+[Pcd]
+ gArmVExpressTokenSpaceGuid.PcdAndroidFastbootNvmDevicePath
+ gArmPlatformTokenSpaceGuid.PcdFirmwareVendor
diff --git a/ArmPlatformPkg/ArmVExpressPkg/ArmVExpressPkg.dec b/ArmPlatformPkg/ArmVExpressPkg/ArmVExpressPkg.dec
index 85433f67a..2f4e351f5 100644
--- a/ArmPlatformPkg/ArmVExpressPkg/ArmVExpressPkg.dec
+++ b/ArmPlatformPkg/ArmVExpressPkg/ArmVExpressPkg.dec
@@ -50,3 +50,8 @@
gArmVExpressTokenSpaceGuid.PcdPL111LcdMaxMode|3|UINT32|0x00000003
gArmVExpressTokenSpaceGuid.PcdPL111LcdVideoModeOscId|1|UINT32|0x00000004
gArmVExpressTokenSpaceGuid.PcdHdLcdVideoModeOscId|0|UINT32|0x00000009
+
+ #
+ # Device path of block device on which Fastboot will flash partitions
+ #
+ gArmVExpressTokenSpaceGuid.PcdAndroidFastbootNvmDevicePath|""|VOID*|0x00000001
diff --git a/ArmPlatformPkg/ArmVExpressPkg/Include/VExpressMotherBoard.h b/ArmPlatformPkg/ArmVExpressPkg/Include/VExpressMotherBoard.h
index 2ac0034aa..dd16b9368 100644
--- a/ArmPlatformPkg/ArmVExpressPkg/Include/VExpressMotherBoard.h
+++ b/ArmPlatformPkg/ArmVExpressPkg/Include/VExpressMotherBoard.h
@@ -1,7 +1,7 @@
/** @file
* Header defining Versatile Express constants (Base addresses, sizes, flags)
*
-* Copyright (c) 2011-2013, ARM Limited. All rights reserved.
+* 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
@@ -59,6 +59,8 @@
#define ARM_VE_SYS_PROC_ID_CORTEX_A9 (UINT32)(0x0CU << 24)
#define ARM_VE_SYS_PROC_ID_CORTEX_A5 (UINT32)(0x12U << 24)
#define ARM_VE_SYS_PROC_ID_CORTEX_A15 (UINT32)(0x14U << 24)
+#define ARM_VE_SYS_PROC_ID_CORTEX_A7 (UINT32)(0x18U << 24)
+#define ARM_VE_SYS_PROC_ID_CORTEX_A12 (UINT32)(0x1CU << 24)
// Boot Master Select:
// 0 = Site 1 boot master
diff --git a/ArmPlatformPkg/Bds/BdsHelper.c b/ArmPlatformPkg/Bds/BdsHelper.c
index d55404619..1c233d76c 100644
--- a/ArmPlatformPkg/Bds/BdsHelper.c
+++ b/ArmPlatformPkg/Bds/BdsHelper.c
@@ -187,9 +187,7 @@ GetHIInputBoolean (
while(1) {
Print (L"[y/n] ");
- // Set MaxCmdLine to 3 to give space for carriage return (when the user
- // hits enter) and terminal '\0'.
- Status = GetHIInputStr (CmdBoolean, 3);
+ Status = GetHIInputStr (CmdBoolean, 2);
if (EFI_ERROR(Status)) {
return Status;
} else if ((CmdBoolean[0] == L'y') || (CmdBoolean[0] == L'Y')) {
diff --git a/ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashDxe.c b/ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashDxe.c
index 7953b6c9f..a03bf5749 100644
--- a/ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashDxe.c
+++ b/ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashDxe.c
@@ -1,6 +1,6 @@
/** @file NorFlashDxe.c
- Copyright (c) 2011-2013, ARM Ltd. All rights reserved.<BR>
+ Copyright (c) 2011 - 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
@@ -20,11 +20,13 @@
#include "NorFlashDxe.h"
+STATIC EFI_EVENT mNorFlashVirtualAddrChangeEvent;
//
// Global variable declarations
//
NOR_FLASH_INSTANCE **mNorFlashInstances;
+UINT32 mNorFlashDeviceCount;
NOR_FLASH_INSTANCE mNorFlashInstanceTemplate = {
NOR_FLASH_SIGNATURE, // Signature
@@ -72,7 +74,7 @@ NOR_FLASH_INSTANCE mNorFlashInstanceTemplate = {
FvbEraseBlocks, // EraseBlocks
NULL, //ParentHandle
}, // FvbProtoccol;
-
+ NULL, // FvbBuffer
{
{
{
@@ -109,7 +111,7 @@ NorFlashCreateInstance (
ASSERT(NorFlashInstance != NULL);
- Instance = AllocateCopyPool (sizeof(NOR_FLASH_INSTANCE),&mNorFlashInstanceTemplate);
+ Instance = AllocateRuntimeCopyPool (sizeof(NOR_FLASH_INSTANCE),&mNorFlashInstanceTemplate);
if (Instance == NULL) {
return EFI_OUT_OF_RESOURCES;
}
@@ -123,11 +125,15 @@ NorFlashCreateInstance (
Instance->Media.BlockSize = BlockSize;
Instance->Media.LastBlock = (NorFlashSize / BlockSize)-1;
- CopyGuid (&Instance->DevicePath.Vendor.Guid,NorFlashGuid);
+ CopyGuid (&Instance->DevicePath.Vendor.Guid, NorFlashGuid);
if (SupportFvb) {
Instance->SupportFvb = TRUE;
Instance->Initialize = NorFlashFvbInitialize;
+ Instance->FvbBuffer = AllocateRuntimePool (BlockSize);;
+ if (Instance->FvbBuffer == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
Status = gBS->InstallMultipleProtocolInterfaces (
&Instance->Handle,
@@ -137,7 +143,7 @@ NorFlashCreateInstance (
NULL
);
if (EFI_ERROR(Status)) {
- FreePool(Instance);
+ FreePool (Instance);
return Status;
}
} else {
@@ -150,7 +156,7 @@ NorFlashCreateInstance (
NULL
);
if (EFI_ERROR(Status)) {
- FreePool(Instance);
+ FreePool (Instance);
return Status;
}
}
@@ -340,8 +346,14 @@ NorFlashUnlockAndEraseSingleBlock (
UINTN Index;
EFI_TPL OriginalTPL;
- // Raise TPL to TPL_HIGH to stop anyone from interrupting us.
- OriginalTPL = gBS->RaiseTPL (TPL_HIGH_LEVEL);
+ if (!EfiAtRuntime ()) {
+ // Raise TPL to TPL_HIGH to stop anyone from interrupting us.
+ OriginalTPL = gBS->RaiseTPL (TPL_HIGH_LEVEL);
+ } else {
+ // This initialization is only to prevent the compiler to complain about the
+ // use of uninitialized variables
+ OriginalTPL = TPL_HIGH_LEVEL;
+ }
Index = 0;
// The block erase might fail a first time (SW bug ?). Retry it ...
@@ -358,8 +370,10 @@ NorFlashUnlockAndEraseSingleBlock (
DEBUG((EFI_D_ERROR,"EraseSingleBlock(BlockAddress=0x%08x: Block Locked Error (try to erase %d times)\n", BlockAddress,Index));
}
- // Interruptions can resume.
- gBS->RestoreTPL (OriginalTPL);
+ if (!EfiAtRuntime ()) {
+ // Interruptions can resume.
+ gBS->RestoreTPL (OriginalTPL);
+ }
return Status;
}
@@ -581,8 +595,14 @@ NorFlashWriteSingleBlock (
// Start writing from the first address at the start of the block
WordAddress = BlockAddress;
- // Raise TPL to TPL_HIGH to stop anyone from interrupting us.
- OriginalTPL = gBS->RaiseTPL (TPL_HIGH_LEVEL);
+ if (!EfiAtRuntime ()) {
+ // Raise TPL to TPL_HIGH to stop anyone from interrupting us.
+ OriginalTPL = gBS->RaiseTPL (TPL_HIGH_LEVEL);
+ } else {
+ // This initialization is only to prevent the compiler to complain about the
+ // use of uninitialized variables
+ OriginalTPL = TPL_HIGH_LEVEL;
+ }
Status = NorFlashUnlockAndEraseSingleBlock (Instance, BlockAddress);
if (EFI_ERROR(Status)) {
@@ -632,8 +652,10 @@ NorFlashWriteSingleBlock (
}
EXIT:
- // Interruptions can resume.
- gBS->RestoreTPL (OriginalTPL);
+ if (!EfiAtRuntime ()) {
+ // Interruptions can resume.
+ gBS->RestoreTPL (OriginalTPL);
+ }
if (EFI_ERROR(Status)) {
DEBUG((EFI_D_ERROR, "NOR FLASH Programming [WriteSingleBlock] failed at address 0x%08x. Exit Status = \"%r\".\n", WordAddress, Status));
@@ -772,6 +794,50 @@ NorFlashReset (
return EFI_SUCCESS;
}
+/**
+ Fixup internal data so that EFI can be call in virtual mode.
+ Call the passed in Child Notify event and convert any pointers in
+ lib to virtual mode.
+
+ @param[in] Event The Event that is being processed
+ @param[in] Context Event Context
+**/
+VOID
+EFIAPI
+NorFlashVirtualNotifyEvent (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+{
+ UINTN Index;
+
+ for (Index = 0; Index < mNorFlashDeviceCount; Index++) {
+ EfiConvertPointer (0x0, (VOID**)&mNorFlashInstances[Index]->DeviceBaseAddress);
+ EfiConvertPointer (0x0, (VOID**)&mNorFlashInstances[Index]->RegionBaseAddress);
+
+ // Convert BlockIo protocol
+ EfiConvertPointer (0x0, (VOID**)&mNorFlashInstances[Index]->BlockIoProtocol.FlushBlocks);
+ EfiConvertPointer (0x0, (VOID**)&mNorFlashInstances[Index]->BlockIoProtocol.ReadBlocks);
+ EfiConvertPointer (0x0, (VOID**)&mNorFlashInstances[Index]->BlockIoProtocol.Reset);
+ EfiConvertPointer (0x0, (VOID**)&mNorFlashInstances[Index]->BlockIoProtocol.WriteBlocks);
+
+ // Convert Fvb
+ EfiConvertPointer (0x0, (VOID**)&mNorFlashInstances[Index]->FvbProtocol.EraseBlocks);
+ EfiConvertPointer (0x0, (VOID**)&mNorFlashInstances[Index]->FvbProtocol.GetAttributes);
+ EfiConvertPointer (0x0, (VOID**)&mNorFlashInstances[Index]->FvbProtocol.GetBlockSize);
+ EfiConvertPointer (0x0, (VOID**)&mNorFlashInstances[Index]->FvbProtocol.GetPhysicalAddress);
+ EfiConvertPointer (0x0, (VOID**)&mNorFlashInstances[Index]->FvbProtocol.Read);
+ EfiConvertPointer (0x0, (VOID**)&mNorFlashInstances[Index]->FvbProtocol.SetAttributes);
+ EfiConvertPointer (0x0, (VOID**)&mNorFlashInstances[Index]->FvbProtocol.Write);
+
+ if (mNorFlashInstances[Index]->FvbBuffer != NULL) {
+ EfiConvertPointer (0x0, (VOID**)&mNorFlashInstances[Index]->FvbBuffer);
+ }
+ }
+
+ return;
+}
+
EFI_STATUS
EFIAPI
NorFlashInitialise (
@@ -782,7 +848,6 @@ NorFlashInitialise (
EFI_STATUS Status;
UINT32 Index;
NOR_FLASH_DESCRIPTION* NorFlashDevices;
- UINT32 NorFlashDeviceCount;
BOOLEAN ContainVariableStorage;
Status = NorFlashPlatformInitialization ();
@@ -791,15 +856,15 @@ NorFlashInitialise (
return Status;
}
- Status = NorFlashPlatformGetDevices (&NorFlashDevices,&NorFlashDeviceCount);
+ Status = NorFlashPlatformGetDevices (&NorFlashDevices, &mNorFlashDeviceCount);
if (EFI_ERROR(Status)) {
DEBUG((EFI_D_ERROR,"NorFlashInitialise: Fail to get Nor Flash devices\n"));
return Status;
}
- mNorFlashInstances = AllocatePool (sizeof(NOR_FLASH_INSTANCE*) * NorFlashDeviceCount);
+ mNorFlashInstances = AllocateRuntimePool (sizeof(NOR_FLASH_INSTANCE*) * mNorFlashDeviceCount);
- for (Index = 0; Index < NorFlashDeviceCount; Index++) {
+ for (Index = 0; Index < mNorFlashDeviceCount; Index++) {
// Check if this NOR Flash device contain the variable storage region
ContainVariableStorage =
(NorFlashDevices[Index].RegionBaseAddress <= PcdGet32 (PcdFlashNvStorageVariableBase)) &&
@@ -820,5 +885,18 @@ NorFlashInitialise (
}
}
+ //
+ // Register for the virtual address change event
+ //
+ Status = gBS->CreateEventEx (
+ EVT_NOTIFY_SIGNAL,
+ TPL_NOTIFY,
+ NorFlashVirtualNotifyEvent,
+ NULL,
+ &gEfiEventVirtualAddressChangeGuid,
+ &mNorFlashVirtualAddrChangeEvent
+ );
+ ASSERT_EFI_ERROR (Status);
+
return Status;
}
diff --git a/ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashDxe.h b/ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashDxe.h
index 959c0c190..e4d767bf9 100644
--- a/ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashDxe.h
+++ b/ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashDxe.h
@@ -1,6 +1,6 @@
/** @file NorFlashDxe.h
- Copyright (c) 2011-2012, ARM Ltd. All rights reserved.<BR>
+ Copyright (c) 2011 - 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
@@ -19,6 +19,8 @@
#include <Base.h>
#include <PiDxe.h>
+#include <Guid/EventGroup.h>
+
#include <Protocol/BlockIo.h>
#include <Protocol/FirmwareVolumeBlock.h>
@@ -26,6 +28,7 @@
#include <Library/IoLib.h>
#include <Library/NorFlashPlatformLib.h>
#include <Library/UefiLib.h>
+#include <Library/UefiRuntimeLib.h>
#define NOR_FLASH_ERASE_RETRY 10
@@ -141,6 +144,7 @@ struct _NOR_FLASH_INSTANCE {
BOOLEAN SupportFvb;
EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL FvbProtocol;
+ VOID* FvbBuffer;
NOR_FLASH_DEVICE_PATH DevicePath;
};
diff --git a/ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashDxe.inf b/ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashDxe.inf
index 97c66008f..a2eb27e8f 100644
--- a/ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashDxe.inf
+++ b/ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashDxe.inf
@@ -2,7 +2,7 @@
#
# Component description file for NorFlashDxe module
#
-# Copyright (c) 2011-2012, ARM Ltd. All rights reserved.<BR>
+# Copyright (c) 2011 - 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
@@ -18,7 +18,7 @@
INF_VERSION = 0x00010005
BASE_NAME = ArmVeNorFlashDxe
FILE_GUID = 93E34C7E-B50E-11DF-9223-2443DFD72085
- MODULE_TYPE = DXE_DRIVER
+ MODULE_TYPE = DXE_RUNTIME_DRIVER
VERSION_STRING = 1.0
ENTRY_POINT = NorFlashInitialise
@@ -41,10 +41,13 @@
UefiLib
UefiDriverEntryPoint
UefiBootServicesTableLib
+ UefiRuntimeLib
+ DxeServicesTableLib
[Guids]
gEfiSystemNvDataFvGuid
gEfiVariableGuid
+ gEfiEventVirtualAddressChangeGuid
[Protocols]
gEfiBlockIoProtocolGuid
diff --git a/ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashFvbDxe.c b/ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashFvbDxe.c
index 4b56f2a40..84890cbfc 100644
--- a/ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashFvbDxe.c
+++ b/ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashFvbDxe.c
@@ -1,6 +1,6 @@
/*++ @file NorFlashFvbDxe.c
- Copyright (c) 2011-201333, ARM Ltd. All rights reserved.<BR>
+ Copyright (c) 2011 - 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
@@ -20,6 +20,7 @@
#include <Library/UefiLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/MemoryAllocationLib.h>
+#include <Library/DxeServicesTableLib.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Guid/VariableFormat.h>
@@ -27,6 +28,8 @@
#include "NorFlashDxe.h"
+STATIC EFI_EVENT mFvbVirtualAddrChangeEvent;
+STATIC UINTN mFlashNvStorageVariableBase;
///
/// The Firmware Volume Block Protocol is the low-level interface
@@ -301,7 +304,7 @@ FvbGetPhysicalAddress (
ASSERT(Address != NULL);
- *Address = PcdGet32 (PcdFlashNvStorageVariableBase);
+ *Address = mFlashNvStorageVariableBase;
return EFI_SUCCESS;
}
@@ -417,7 +420,6 @@ FvbRead (
EFI_STATUS Status;
EFI_STATUS TempStatus;
UINTN BlockSize;
- UINT8 *BlockBuffer;
NOR_FLASH_INSTANCE *Instance;
Instance = INSTANCE_FROM_FVB_THIS(This);
@@ -450,32 +452,24 @@ FvbRead (
return EFI_BAD_BUFFER_SIZE;
}
- // FixMe: Allow an arbitrary number of bytes to be read out, not just a multiple of block size.
-
- // Allocate runtime memory to read in the NOR Flash data. Variable Services are runtime.
- BlockBuffer = AllocateRuntimePool (BlockSize);
-
- // Check if the memory allocation was successful
- if (BlockBuffer == NULL) {
- DEBUG ((EFI_D_ERROR, "FvbRead: ERROR - Could not allocate BlockBuffer @ 0x%08x.\n", BlockBuffer));
+ // Check we did get some memory
+ if (Instance->FvbBuffer == NULL) {
+ DEBUG ((EFI_D_ERROR, "FvbRead: ERROR - Buffer not ready\n"));
return EFI_DEVICE_ERROR;
}
// Read NOR Flash data into shadow buffer
- TempStatus = NorFlashReadBlocks (Instance, Instance->StartLba + Lba, BlockSize, BlockBuffer);
+ TempStatus = NorFlashReadBlocks (Instance, Instance->StartLba + Lba, BlockSize, Instance->FvbBuffer);
if (EFI_ERROR (TempStatus)) {
// Return one of the pre-approved error statuses
- Status = EFI_DEVICE_ERROR;
- goto FREE_MEMORY;
+ return EFI_DEVICE_ERROR;
}
// Put the data at the appropriate location inside the buffer area
- DEBUG ((DEBUG_BLKIO, "FvbRead: CopyMem( Dst=0x%08x, Src=0x%08x, Size=0x%x ).\n", Buffer, BlockBuffer + Offset, *NumBytes));
+ DEBUG ((DEBUG_BLKIO, "FvbRead: CopyMem( Dst=0x%08x, Src=0x%08x, Size=0x%x ).\n", Buffer, (UINTN)Instance->FvbBuffer + Offset, *NumBytes));
- CopyMem(Buffer, BlockBuffer + Offset, *NumBytes);
+ CopyMem (Buffer, (VOID*)((UINTN)Instance->FvbBuffer + Offset), *NumBytes);
-FREE_MEMORY:
- FreePool(BlockBuffer);
return Status;
}
@@ -546,7 +540,6 @@ FvbWrite (
EFI_STATUS Status;
EFI_STATUS TempStatus;
UINTN BlockSize;
- UINT8 *BlockBuffer;
NOR_FLASH_INSTANCE *Instance;
Instance = INSTANCE_FROM_FVB_THIS(This);
@@ -585,38 +578,29 @@ FvbWrite (
return EFI_BAD_BUFFER_SIZE;
}
- // Allocate runtime memory to read in the NOR Flash data.
- // Since the intention is to use this with Variable Services and since these are runtime,
- // allocate the memory from the runtime pool.
- BlockBuffer = AllocateRuntimePool (BlockSize);
-
// Check we did get some memory
- if( BlockBuffer == NULL ) {
- DEBUG ((EFI_D_ERROR, "FvbWrite: ERROR - Can not allocate BlockBuffer @ 0x%08x.\n", BlockBuffer));
+ if (Instance->FvbBuffer == NULL) {
+ DEBUG ((EFI_D_ERROR, "FvbWrite: ERROR - Buffer not ready\n"));
return EFI_DEVICE_ERROR;
}
// Read NOR Flash data into shadow buffer
- TempStatus = NorFlashReadBlocks (Instance, Instance->StartLba + Lba, BlockSize, BlockBuffer);
+ TempStatus = NorFlashReadBlocks (Instance, Instance->StartLba + Lba, BlockSize, Instance->FvbBuffer);
if (EFI_ERROR (TempStatus)) {
// Return one of the pre-approved error statuses
- Status = EFI_DEVICE_ERROR;
- goto FREE_MEMORY;
+ return EFI_DEVICE_ERROR;
}
// Put the data at the appropriate location inside the buffer area
- CopyMem((BlockBuffer + Offset), Buffer, *NumBytes);
+ CopyMem ((VOID*)((UINTN)Instance->FvbBuffer + Offset), Buffer, *NumBytes);
// Write the modified buffer back to the NorFlash
- TempStatus = NorFlashWriteBlocks (Instance, Instance->StartLba + Lba, BlockSize, BlockBuffer);
+ TempStatus = NorFlashWriteBlocks (Instance, Instance->StartLba + Lba, BlockSize, Instance->FvbBuffer);
if (EFI_ERROR (TempStatus)) {
// Return one of the pre-approved error statuses
- Status = EFI_DEVICE_ERROR;
- goto FREE_MEMORY;
+ return EFI_DEVICE_ERROR;
}
-FREE_MEMORY:
- FreePool(BlockBuffer);
return Status;
}
@@ -764,6 +748,25 @@ EXIT:
return Status;
}
+/**
+ Fixup internal data so that EFI can be call in virtual mode.
+ Call the passed in Child Notify event and convert any pointers in
+ lib to virtual mode.
+
+ @param[in] Event The Event that is being processed
+ @param[in] Context Event Context
+**/
+VOID
+EFIAPI
+FvbVirtualNotifyEvent (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+{
+ EfiConvertPointer (0x0, (VOID**)&mFlashNvStorageVariableBase);
+ return;
+}
+
EFI_STATUS
EFIAPI
NorFlashFvbInitialize (
@@ -773,10 +776,12 @@ NorFlashFvbInitialize (
EFI_STATUS Status;
UINT32 FvbNumLba;
EFI_BOOT_MODE BootMode;
+ UINTN RuntimeMmioRegionSize;
DEBUG((DEBUG_BLKIO,"NorFlashFvbInitialize\n"));
Instance->Initialized = TRUE;
+ mFlashNvStorageVariableBase = FixedPcdGet32 (PcdFlashNvStorageVariableBase);
// Set the index of the first LBA for the FVB
Instance->StartLba = (PcdGet32 (PcdFlashNvStorageVariableBase) - Instance->RegionBaseAddress) / Instance->Media.BlockSize;
@@ -808,5 +813,41 @@ NorFlashFvbInitialize (
return Status;
}
}
+
+ //
+ // Declare the Non-Volatile storage as EFI_MEMORY_RUNTIME
+ //
+
+ // Note: all the NOR Flash region needs to be reserved into the UEFI Runtime memory;
+ // even if we only use the small block region at the top of the NOR Flash.
+ // The reason is when the NOR Flash memory is set into program mode, the command
+ // is written as the base of the flash region (ie: Instance->DeviceBaseAddress)
+ RuntimeMmioRegionSize = (Instance->RegionBaseAddress - Instance->DeviceBaseAddress) + Instance->Size;
+
+ Status = gDS->AddMemorySpace (
+ EfiGcdMemoryTypeMemoryMappedIo,
+ Instance->DeviceBaseAddress, RuntimeMmioRegionSize,
+ EFI_MEMORY_UC | EFI_MEMORY_RUNTIME
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ Status = gDS->SetMemorySpaceAttributes (
+ Instance->DeviceBaseAddress, RuntimeMmioRegionSize,
+ EFI_MEMORY_UC | EFI_MEMORY_RUNTIME);
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Register for the virtual address change event
+ //
+ Status = gBS->CreateEventEx (
+ EVT_NOTIFY_SIGNAL,
+ TPL_NOTIFY,
+ FvbVirtualNotifyEvent,
+ NULL,
+ &gEfiEventVirtualAddressChangeGuid,
+ &mFvbVirtualAddrChangeEvent
+ );
+ ASSERT_EFI_ERROR (Status);
+
return Status;
}
diff --git a/ArmPlatformPkg/FileSystem/BootMonFs/BootMonFsHw.h b/ArmPlatformPkg/FileSystem/BootMonFs/BootMonFsHw.h
index 3ebb5ba54..c1bef755a 100644
--- a/ArmPlatformPkg/FileSystem/BootMonFs/BootMonFsHw.h
+++ b/ArmPlatformPkg/FileSystem/BootMonFs/BootMonFsHw.h
@@ -19,9 +19,13 @@
#define HW_IMAGE_FOOTER_SIGNATURE_1 0x464C5348
#define HW_IMAGE_FOOTER_SIGNATURE_2 0x464F4F54
+
#define HW_IMAGE_FOOTER_VERSION 1
#define HW_IMAGE_FOOTER_OFFSET 92
+#define HW_IMAGE_FOOTER_VERSION2 2
+#define HW_IMAGE_FOOTER_OFFSET2 96
+
typedef struct {
CHAR8 Filename[MAX_NAME_LENGTH];
UINT32 Offset;
diff --git a/ArmPlatformPkg/FileSystem/BootMonFs/BootMonFsImages.c b/ArmPlatformPkg/FileSystem/BootMonFs/BootMonFsImages.c
index 7d3e90190..aadc0c7f9 100644
--- a/ArmPlatformPkg/FileSystem/BootMonFs/BootMonFsImages.c
+++ b/ArmPlatformPkg/FileSystem/BootMonFs/BootMonFsImages.c
@@ -109,11 +109,15 @@ BootMonFsImageInThisBlock (
return FALSE;
}
- if (Ptr->Version != HW_IMAGE_FOOTER_VERSION) {
- return FALSE;
- }
-
- if (Ptr->Offset != HW_IMAGE_FOOTER_OFFSET) {
+ if (Ptr->Version == HW_IMAGE_FOOTER_VERSION) {
+ if (Ptr->Offset != HW_IMAGE_FOOTER_OFFSET) {
+ return FALSE;
+ }
+ } else if (Ptr->Version == HW_IMAGE_FOOTER_VERSION2) {
+ if (Ptr->Offset != HW_IMAGE_FOOTER_OFFSET2) {
+ return FALSE;
+ }
+ } else {
return FALSE;
}
diff --git a/ArmPlatformPkg/FileSystem/BootMonFs/BootMonFsOpenClose.c b/ArmPlatformPkg/FileSystem/BootMonFs/BootMonFsOpenClose.c
index 908393fa5..778af389a 100644
--- a/ArmPlatformPkg/FileSystem/BootMonFs/BootMonFsOpenClose.c
+++ b/ArmPlatformPkg/FileSystem/BootMonFs/BootMonFsOpenClose.c
@@ -100,8 +100,13 @@ FlushAppendRegion (
Description->BlockEnd = Description->BlockStart + (NewFileSize / BlockSize);
Description->Footer.FooterSignature1 = HW_IMAGE_FOOTER_SIGNATURE_1;
Description->Footer.FooterSignature2 = HW_IMAGE_FOOTER_SIGNATURE_2;
+#ifdef MDE_CPU_ARM
Description->Footer.Version = HW_IMAGE_FOOTER_VERSION;
Description->Footer.Offset = HW_IMAGE_FOOTER_OFFSET;
+#else
+ Description->Footer.Version = HW_IMAGE_FOOTER_VERSION2;
+ Description->Footer.Offset = HW_IMAGE_FOOTER_OFFSET2;
+#endif
Description->RegionCount = 1;
Description->Region[0].Checksum = 0;
Description->Region[0].Offset = Description->BlockStart * BlockSize;
diff --git a/ArmPlatformPkg/Include/Drivers/PL031RealTimeClock.h b/ArmPlatformPkg/Include/Drivers/PL031RealTimeClock.h
index 4c559c0c9..76fbd0eb8 100644
--- a/ArmPlatformPkg/Include/Drivers/PL031RealTimeClock.h
+++ b/ArmPlatformPkg/Include/Drivers/PL031RealTimeClock.h
@@ -1,6 +1,6 @@
/** @file
*
-* Copyright (c) 2011, ARM Limited. All rights reserved.
+* 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
@@ -17,22 +17,22 @@
#define __PL031_REAL_TIME_CLOCK_H__
// PL031 Registers
-#define PL031_RTC_DR_DATA_REGISTER ((UINT32)PcdGet32(PcdPL031RtcBase) + 0x000)
-#define PL031_RTC_MR_MATCH_REGISTER ((UINT32)PcdGet32(PcdPL031RtcBase) + 0x004)
-#define PL031_RTC_LR_LOAD_REGISTER ((UINT32)PcdGet32(PcdPL031RtcBase) + 0x008)
-#define PL031_RTC_CR_CONTROL_REGISTER ((UINT32)PcdGet32(PcdPL031RtcBase) + 0x00C)
-#define PL031_RTC_IMSC_IRQ_MASK_SET_CLEAR_REGISTER ((UINT32)PcdGet32(PcdPL031RtcBase) + 0x010)
-#define PL031_RTC_RIS_RAW_IRQ_STATUS_REGISTER ((UINT32)PcdGet32(PcdPL031RtcBase) + 0x014)
-#define PL031_RTC_MIS_MASKED_IRQ_STATUS_REGISTER ((UINT32)PcdGet32(PcdPL031RtcBase) + 0x018)
-#define PL031_RTC_ICR_IRQ_CLEAR_REGISTER ((UINT32)PcdGet32(PcdPL031RtcBase) + 0x01C)
-#define PL031_RTC_PERIPH_ID0 ((UINT32)PcdGet32(PcdPL031RtcBase) + 0xFE0)
-#define PL031_RTC_PERIPH_ID1 ((UINT32)PcdGet32(PcdPL031RtcBase) + 0xFE4)
-#define PL031_RTC_PERIPH_ID2 ((UINT32)PcdGet32(PcdPL031RtcBase) + 0xFE8)
-#define PL031_RTC_PERIPH_ID3 ((UINT32)PcdGet32(PcdPL031RtcBase) + 0xFEC)
-#define PL031_RTC_PCELL_ID0 ((UINT32)PcdGet32(PcdPL031RtcBase) + 0xFF0)
-#define PL031_RTC_PCELL_ID1 ((UINT32)PcdGet32(PcdPL031RtcBase) + 0xFF4)
-#define PL031_RTC_PCELL_ID2 ((UINT32)PcdGet32(PcdPL031RtcBase) + 0xFF8)
-#define PL031_RTC_PCELL_ID3 ((UINT32)PcdGet32(PcdPL031RtcBase) + 0xFFC)
+#define PL031_RTC_DR_DATA_REGISTER 0x000
+#define PL031_RTC_MR_MATCH_REGISTER 0x004
+#define PL031_RTC_LR_LOAD_REGISTER 0x008
+#define PL031_RTC_CR_CONTROL_REGISTER 0x00C
+#define PL031_RTC_IMSC_IRQ_MASK_SET_CLEAR_REGISTER 0x010
+#define PL031_RTC_RIS_RAW_IRQ_STATUS_REGISTER 0x014
+#define PL031_RTC_MIS_MASKED_IRQ_STATUS_REGISTER 0x018
+#define PL031_RTC_ICR_IRQ_CLEAR_REGISTER 0x01C
+#define PL031_RTC_PERIPH_ID0 0xFE0
+#define PL031_RTC_PERIPH_ID1 0xFE4
+#define PL031_RTC_PERIPH_ID2 0xFE8
+#define PL031_RTC_PERIPH_ID3 0xFEC
+#define PL031_RTC_PCELL_ID0 0xFF0
+#define PL031_RTC_PCELL_ID1 0xFF4
+#define PL031_RTC_PCELL_ID2 0xFF8
+#define PL031_RTC_PCELL_ID3 0xFFC
// PL031 Values
#define PL031_RTC_ENABLED 0x00000001
diff --git a/ArmPlatformPkg/Library/PL031RealTimeClockLib/PL031RealTimeClockLib.c b/ArmPlatformPkg/Library/PL031RealTimeClockLib/PL031RealTimeClockLib.c
index 980f809b2..b43d8dc4b 100644
--- a/ArmPlatformPkg/Library/PL031RealTimeClockLib/PL031RealTimeClockLib.c
+++ b/ArmPlatformPkg/Library/PL031RealTimeClockLib/PL031RealTimeClockLib.c
@@ -4,7 +4,7 @@
Currently this driver does not support runtime virtual calling.
Copyright (c) 2008 - 2010, Apple Inc. All rights reserved.<BR>
- Copyright (c) 2011-2013, ARM Ltd. All rights reserved.<BR>
+ Copyright (c) 2011 - 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
@@ -26,10 +26,16 @@
#include <Library/MemoryAllocationLib.h>
#include <Library/PcdLib.h>
#include <Library/ArmPlatformSysConfigLib.h>
+#include <Library/DxeServicesTableLib.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Library/UefiRuntimeServicesTableLib.h>
+#include <Library/UefiRuntimeLib.h>
+
#include <Protocol/RealTimeClock.h>
+
#include <Guid/GlobalVariable.h>
+#include <Guid/EventGroup.h>
+
#include <Drivers/PL031RealTimeClock.h>
#include <ArmPlatform.h>
@@ -37,6 +43,8 @@
STATIC CONST CHAR16 mTimeZoneVariableName[] = L"PL031RtcTimeZone";
STATIC CONST CHAR16 mDaylightVariableName[] = L"PL031RtcDaylight";
STATIC BOOLEAN mPL031Initialized = FALSE;
+STATIC EFI_EVENT mRtcVirtualAddrChangeEvent;
+STATIC UINTN mPL031RtcBase;
EFI_STATUS
IdentifyPL031 (
@@ -46,19 +54,19 @@ IdentifyPL031 (
EFI_STATUS Status;
// Check if this is a PrimeCell Peripheral
- if ( (MmioRead8 (PL031_RTC_PCELL_ID0) != 0x0D)
- || (MmioRead8 (PL031_RTC_PCELL_ID1) != 0xF0)
- || (MmioRead8 (PL031_RTC_PCELL_ID2) != 0x05)
- || (MmioRead8 (PL031_RTC_PCELL_ID3) != 0xB1)) {
+ if ( (MmioRead8 (mPL031RtcBase + PL031_RTC_PCELL_ID0) != 0x0D)
+ || (MmioRead8 (mPL031RtcBase + PL031_RTC_PCELL_ID1) != 0xF0)
+ || (MmioRead8 (mPL031RtcBase + PL031_RTC_PCELL_ID2) != 0x05)
+ || (MmioRead8 (mPL031RtcBase + PL031_RTC_PCELL_ID3) != 0xB1)) {
Status = EFI_NOT_FOUND;
goto EXIT;
}
// Check if this PrimeCell Peripheral is the PL031 Real Time Clock
- if ( (MmioRead8 (PL031_RTC_PERIPH_ID0) != 0x31)
- || (MmioRead8 (PL031_RTC_PERIPH_ID1) != 0x10)
- || ((MmioRead8 (PL031_RTC_PERIPH_ID2) & 0xF) != 0x04)
- || (MmioRead8 (PL031_RTC_PERIPH_ID3) != 0x00)) {
+ if ( (MmioRead8 (mPL031RtcBase + PL031_RTC_PERIPH_ID0) != 0x31)
+ || (MmioRead8 (mPL031RtcBase + PL031_RTC_PERIPH_ID1) != 0x10)
+ || ((MmioRead8 (mPL031RtcBase + PL031_RTC_PERIPH_ID2) & 0xF) != 0x04)
+ || (MmioRead8 (mPL031RtcBase + PL031_RTC_PERIPH_ID3) != 0x00)) {
Status = EFI_NOT_FOUND;
goto EXIT;
}
@@ -83,18 +91,18 @@ InitializePL031 (
}
// Ensure interrupts are masked. We do not want RTC interrupts in UEFI
- if ((MmioRead32 (PL031_RTC_IMSC_IRQ_MASK_SET_CLEAR_REGISTER) & PL031_SET_IRQ_MASK) != PL031_SET_IRQ_MASK) {
- MmioOr32 (PL031_RTC_IMSC_IRQ_MASK_SET_CLEAR_REGISTER, PL031_SET_IRQ_MASK);
+ if ((MmioRead32 (mPL031RtcBase + PL031_RTC_IMSC_IRQ_MASK_SET_CLEAR_REGISTER) & PL031_SET_IRQ_MASK) != PL031_SET_IRQ_MASK) {
+ MmioOr32 (mPL031RtcBase + PL031_RTC_IMSC_IRQ_MASK_SET_CLEAR_REGISTER, PL031_SET_IRQ_MASK);
}
// Clear any existing interrupts
- if ((MmioRead32 (PL031_RTC_RIS_RAW_IRQ_STATUS_REGISTER) & PL031_IRQ_TRIGGERED) == PL031_IRQ_TRIGGERED) {
- MmioOr32 (PL031_RTC_ICR_IRQ_CLEAR_REGISTER, PL031_CLEAR_IRQ);
+ if ((MmioRead32 (mPL031RtcBase + PL031_RTC_RIS_RAW_IRQ_STATUS_REGISTER) & PL031_IRQ_TRIGGERED) == PL031_IRQ_TRIGGERED) {
+ MmioOr32 (mPL031RtcBase + PL031_RTC_ICR_IRQ_CLEAR_REGISTER, PL031_CLEAR_IRQ);
}
// Start the clock counter
- if ((MmioRead32 (PL031_RTC_CR_CONTROL_REGISTER) & PL031_RTC_ENABLED) != PL031_RTC_ENABLED) {
- MmioOr32 (PL031_RTC_CR_CONTROL_REGISTER, PL031_RTC_ENABLED);
+ if ((MmioRead32 (mPL031RtcBase + PL031_RTC_CR_CONTROL_REGISTER) & PL031_RTC_ENABLED) != PL031_RTC_ENABLED) {
+ MmioOr32 (mPL031RtcBase + PL031_RTC_CR_CONTROL_REGISTER, PL031_RTC_ENABLED);
}
mPL031Initialized = TRUE;
@@ -267,7 +275,7 @@ LibGetTime (
Status = ArmPlatformSysConfigGet (SYS_CFG_RTC, &EpochSeconds);
if (Status == EFI_UNSUPPORTED) {
// Battery backed up hardware RTC does not exist, revert to PL031
- EpochSeconds = MmioRead32 (PL031_RTC_DR_DATA_REGISTER);
+ EpochSeconds = MmioRead32 (mPL031RtcBase + PL031_RTC_DR_DATA_REGISTER);
Status = EFI_SUCCESS;
} else if (EFI_ERROR (Status)) {
// Battery backed up hardware RTC exists but could not be read due to error. Abort.
@@ -275,7 +283,7 @@ LibGetTime (
} else {
// Battery backed up hardware RTC exists and we read the time correctly from it.
// Now sync the PL031 to the new time.
- MmioWrite32 (PL031_RTC_LR_LOAD_REGISTER, EpochSeconds);
+ MmioWrite32 (mPL031RtcBase + PL031_RTC_LR_LOAD_REGISTER, EpochSeconds);
}
// Ensure Time is a valid pointer
@@ -484,7 +492,7 @@ LibSetTime (
// Set the PL031
- MmioWrite32 (PL031_RTC_LR_LOAD_REGISTER, EpochSeconds);
+ MmioWrite32 (mPL031RtcBase + PL031_RTC_LR_LOAD_REGISTER, EpochSeconds);
// The accesses to Variable Services can be very slow, because we may be writing to Flash.
// Do this after having set the RTC.
@@ -579,7 +587,30 @@ LibSetWakeupTime (
return EFI_UNSUPPORTED;
}
+/**
+ Fixup internal data so that EFI can be call in virtual mode.
+ Call the passed in Child Notify event and convert any pointers in
+ lib to virtual mode.
+ @param[in] Event The Event that is being processed
+ @param[in] Context Event Context
+**/
+VOID
+EFIAPI
+LibRtcVirtualNotifyEvent (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+{
+ //
+ // Only needed if you are going to support the OS calling RTC functions in virtual mode.
+ // You will need to call EfiConvertPointer (). To convert any stored physical addresses
+ // to virtual address. After the OS transitions to calling in virtual mode, all future
+ // runtime calls will be made in virtual mode.
+ //
+ EfiConvertPointer (0x0, (VOID**)&mPL031RtcBase);
+ return;
+}
/**
This is the declaration of an EFI image entry point. This can be the entry point to an application
@@ -601,6 +632,24 @@ LibRtcInitialize (
EFI_STATUS Status;
EFI_HANDLE Handle;
+ // Initialize RTC Base Address
+ mPL031RtcBase = PcdGet32 (PcdPL031RtcBase);
+
+ // Declare the controller as EFI_MEMORY_RUNTIME
+ Status = gDS->AddMemorySpace (
+ EfiGcdMemoryTypeMemoryMappedIo,
+ mPL031RtcBase, SIZE_4KB,
+ EFI_MEMORY_UC | EFI_MEMORY_RUNTIME
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ Status = gDS->SetMemorySpaceAttributes (mPL031RtcBase, SIZE_4KB, EFI_MEMORY_UC | EFI_MEMORY_RUNTIME);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
// Setup the setters and getters
gRT->GetTime = LibGetTime;
gRT->SetTime = LibSetTime;
@@ -614,31 +663,20 @@ LibRtcInitialize (
&gEfiRealTimeClockArchProtocolGuid, NULL,
NULL
);
+ ASSERT_EFI_ERROR (Status);
- return Status;
-}
-
-
-/**
- Fixup internal data so that EFI can be call in virtual mode.
- Call the passed in Child Notify event and convert any pointers in
- lib to virtual mode.
-
- @param[in] Event The Event that is being processed
- @param[in] Context Event Context
-**/
-VOID
-EFIAPI
-LibRtcVirtualNotifyEvent (
- IN EFI_EVENT Event,
- IN VOID *Context
- )
-{
//
- // Only needed if you are going to support the OS calling RTC functions in virtual mode.
- // You will need to call EfiConvertPointer (). To convert any stored physical addresses
- // to virtual address. After the OS transitions to calling in virtual mode, all future
- // runtime calls will be made in virtual mode.
+ // Register for the virtual address change event
//
- return;
+ Status = gBS->CreateEventEx (
+ EVT_NOTIFY_SIGNAL,
+ TPL_NOTIFY,
+ LibRtcVirtualNotifyEvent,
+ NULL,
+ &gEfiEventVirtualAddressChangeGuid,
+ &mRtcVirtualAddrChangeEvent
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ return Status;
}
diff --git a/ArmPlatformPkg/Library/PL031RealTimeClockLib/PL031RealTimeClockLib.inf b/ArmPlatformPkg/Library/PL031RealTimeClockLib/PL031RealTimeClockLib.inf
index add982ce8..3a98fc757 100644
--- a/ArmPlatformPkg/Library/PL031RealTimeClockLib/PL031RealTimeClockLib.inf
+++ b/ArmPlatformPkg/Library/PL031RealTimeClockLib/PL031RealTimeClockLib.inf
@@ -1,7 +1,7 @@
#/** @file
#
# Copyright (c) 2006, Intel Corporation. All rights reserved.<BR>
-# Copyright (c) 2011-2013, ARM Ltd. All rights reserved.<BR>
+# Copyright (c) 2011 - 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
@@ -35,6 +35,11 @@
DebugLib
PcdLib
ArmPlatformSysConfigLib
+ DxeServicesTableLib
+ UefiRuntimeLib
+
+[Guids]
+ gEfiEventVirtualAddressChangeGuid
[Pcd]
gArmPlatformTokenSpaceGuid.PcdPL031RtcBase
diff --git a/ArmPlatformPkg/PrePi/PeiMPCore.inf b/ArmPlatformPkg/PrePi/PeiMPCore.inf
index 276a37226..45c00b8df 100755
--- a/ArmPlatformPkg/PrePi/PeiMPCore.inf
+++ b/ArmPlatformPkg/PrePi/PeiMPCore.inf
@@ -1,6 +1,6 @@
#/** @file
#
-# Copyright (c) 2011-2012, ARM Ltd. All rights reserved.<BR>
+# Copyright (c) 2011-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
@@ -98,7 +98,6 @@
gArmPlatformTokenSpaceGuid.PcdSystemMemoryUefiRegionSize
gArmPlatformTokenSpaceGuid.PcdCoreCount
- gArmPlatformTokenSpaceGuid.PcdClusterCount
gArmTokenSpaceGuid.PcdArmPrimaryCore
gEmbeddedTokenSpaceGuid.PcdPrePiCpuMemorySize
diff --git a/ArmPlatformPkg/PrePi/PeiUniCore.inf b/ArmPlatformPkg/PrePi/PeiUniCore.inf
index 160374eab..6079ec506 100755
--- a/ArmPlatformPkg/PrePi/PeiUniCore.inf
+++ b/ArmPlatformPkg/PrePi/PeiUniCore.inf
@@ -1,6 +1,6 @@
#/** @file
#
-# Copyright (c) 2011-2012, ARM Ltd. All rights reserved.<BR>
+# Copyright (c) 2011-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
@@ -93,7 +93,6 @@
gArmPlatformTokenSpaceGuid.PcdSystemMemoryUefiRegionSize
gArmPlatformTokenSpaceGuid.PcdCoreCount
- gArmPlatformTokenSpaceGuid.PcdClusterCount
gEmbeddedTokenSpaceGuid.PcdPrePiCpuMemorySize
gEmbeddedTokenSpaceGuid.PcdPrePiCpuIoSize
diff --git a/ArmPlatformPkg/PrePi/PrePi.c b/ArmPlatformPkg/PrePi/PrePi.c
index d54ebf933..84b01b3fb 100755
--- a/ArmPlatformPkg/PrePi/PrePi.c
+++ b/ArmPlatformPkg/PrePi/PrePi.c
@@ -1,6 +1,6 @@
/** @file
*
-* Copyright (c) 2011-2013, ARM Limited. All rights reserved.
+* 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
@@ -139,7 +139,8 @@ PrePiMain (
// Create the Stacks HOB (reserve the memory for all stacks)
if (ArmIsMpCore ()) {
- StacksSize = PcdGet32 (PcdCPUCorePrimaryStackSize) + (FixedPcdGet32(PcdClusterCount) * 4 * FixedPcdGet32(PcdCPUCoreSecondaryStackSize));
+ StacksSize = PcdGet32 (PcdCPUCorePrimaryStackSize) +
+ ((FixedPcdGet32 (PcdCoreCount) - 1) * FixedPcdGet32 (PcdCPUCoreSecondaryStackSize));
} else {
StacksSize = PcdGet32 (PcdCPUCorePrimaryStackSize);
}
diff --git a/EmbeddedPkg/Application/AndroidFastboot/AndroidBootImg.c b/EmbeddedPkg/Application/AndroidFastboot/AndroidBootImg.c
new file mode 100644
index 000000000..bbca90fc0
--- /dev/null
+++ b/EmbeddedPkg/Application/AndroidFastboot/AndroidBootImg.c
@@ -0,0 +1,90 @@
+/** @file
+
+ Copyright (c) 2013-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 "AndroidFastbootApp.h"
+
+#define BOOT_MAGIC "ANDROID!"
+#define BOOT_MAGIC_LENGTH sizeof (BOOT_MAGIC) - 1
+
+// Check Val (unsigned) is a power of 2 (has only one bit set)
+#define IS_POWER_OF_2(Val) (Val != 0 && ((Val & (Val - 1)) == 0))
+
+// No documentation for this really - sizes of fields has been determined
+// empirically.
+#pragma pack(1)
+typedef struct {
+ CHAR8 BootMagic[BOOT_MAGIC_LENGTH];
+ UINT32 KernelSize;
+ UINT32 KernelAddress;
+ UINT32 RamdiskSize;
+ UINT32 RamdiskAddress;
+ UINT32 SecondStageBootloaderSize;
+ UINT32 SecondStageBootloaderAddress;
+ UINT32 KernelTaggsAddress;
+ UINT32 PageSize;
+ UINT32 Reserved[2];
+ CHAR8 ProductName[16];
+ CHAR8 KernelArgs[BOOTIMG_KERNEL_ARGS_SIZE];
+ UINT32 Id[32];
+} ANDROID_BOOTIMG_HEADER;
+#pragma pack()
+
+// Find the kernel and ramdisk in an Android boot.img.
+// return EFI_INVALID_PARAMTER if the boot.img is invalid (i.e. doesn't have the
+// right magic value),
+// return EFI_NOT_FOUND if there was no kernel in the boot.img.
+// Note that the Ramdisk is optional - *Ramdisk won't be touched if it isn't
+// present, but RamdiskSize will be set to 0.
+EFI_STATUS
+ParseAndroidBootImg (
+ IN VOID *BootImg,
+ OUT VOID **Kernel,
+ OUT UINTN *KernelSize,
+ OUT VOID **Ramdisk,
+ OUT UINTN *RamdiskSize,
+ OUT CHAR8 *KernelArgs
+ )
+{
+ ANDROID_BOOTIMG_HEADER *Header;
+ UINT8 *BootImgBytePtr;
+
+ // Cast to UINT8 so we can do pointer arithmetic
+ BootImgBytePtr = (UINT8 *) BootImg;
+
+ Header = (ANDROID_BOOTIMG_HEADER *) BootImg;
+
+ if (AsciiStrnCmp (Header->BootMagic, BOOT_MAGIC, BOOT_MAGIC_LENGTH) != 0) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (Header->KernelSize == 0) {
+ return EFI_NOT_FOUND;
+ }
+
+ ASSERT (IS_POWER_OF_2 (Header->PageSize));
+
+ *KernelSize = Header->KernelSize;
+ *Kernel = BootImgBytePtr + Header->PageSize;
+ *RamdiskSize = Header->RamdiskSize;
+
+ if (Header->RamdiskSize != 0) {
+ *Ramdisk = (VOID *) (BootImgBytePtr
+ + Header->PageSize
+ + ALIGN_VALUE (Header->KernelSize, Header->PageSize));
+ }
+
+ AsciiStrnCpy (KernelArgs, Header->KernelArgs, BOOTIMG_KERNEL_ARGS_SIZE);
+
+ return EFI_SUCCESS;
+}
diff --git a/EmbeddedPkg/Application/AndroidFastboot/AndroidFastbootApp.c b/EmbeddedPkg/Application/AndroidFastboot/AndroidFastbootApp.c
new file mode 100644
index 000000000..f38081704
--- /dev/null
+++ b/EmbeddedPkg/Application/AndroidFastboot/AndroidFastbootApp.c
@@ -0,0 +1,524 @@
+/** @file
+
+ Copyright (c) 2013-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 "AndroidFastbootApp.h"
+
+#include <Protocol/AndroidFastbootTransport.h>
+#include <Protocol/AndroidFastbootPlatform.h>
+#include <Protocol/SimpleTextOut.h>
+#include <Protocol/SimpleTextIn.h>
+
+#include <Library/PcdLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiApplicationEntryPoint.h>
+#include <Library/PrintLib.h>
+
+/*
+ * UEFI Application using the FASTBOOT_TRANSPORT_PROTOCOL and
+ * FASTBOOT_PLATFORM_PROTOCOL to implement the Android Fastboot protocol.
+ */
+
+STATIC FASTBOOT_TRANSPORT_PROTOCOL *mTransport;
+STATIC FASTBOOT_PLATFORM_PROTOCOL *mPlatform;
+
+STATIC EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *mTextOut;
+
+typedef enum {
+ ExpectCmdState,
+ ExpectDataState,
+ FastbootStateMax
+} ANDROID_FASTBOOT_STATE;
+
+STATIC ANDROID_FASTBOOT_STATE mState = ExpectCmdState;
+
+// When in ExpectDataState, the number of bytes of data to expect:
+STATIC UINT32 mNumDataBytes;
+// .. and the number of bytes so far received this data phase
+STATIC UINT32 mBytesReceivedSoFar;
+// .. and the buffer to save data into
+STATIC UINT8 *mDataBuffer = NULL;
+
+// Event notify functions, from which gBS->Exit shouldn't be called, can signal
+// this event when the application should exit
+STATIC EFI_EVENT mFinishedEvent;
+
+STATIC EFI_EVENT mFatalSendErrorEvent;
+
+// This macro uses sizeof - only use it on arrays (i.e. string literals)
+#define SEND_LITERAL(Str) mTransport->Send ( \
+ sizeof (Str) - 1, \
+ Str, \
+ &mFatalSendErrorEvent \
+ )
+#define MATCH_CMD_LITERAL(Cmd, Buf) !AsciiStrnCmp (Cmd, Buf, sizeof (Cmd) - 1)
+
+#define IS_LOWERCASE_ASCII(Char) (Char >= 'a' && Char <= 'z')
+
+#define FASTBOOT_STRING_MAX_LENGTH 256
+#define FASTBOOT_COMMAND_MAX_LENGTH 64
+
+STATIC
+VOID
+HandleGetVar (
+ IN CHAR8 *CmdArg
+ )
+{
+ CHAR8 Response[FASTBOOT_COMMAND_MAX_LENGTH + 1] = "OKAY";
+ EFI_STATUS Status;
+
+ // Respond to getvar:version with 0.4 (version of Fastboot protocol)
+ if (!AsciiStrnCmp ("version", CmdArg, sizeof ("version") - 1 )) {
+ SEND_LITERAL ("OKAY" ANDROID_FASTBOOT_VERSION);
+ } else {
+ // All other variables are assumed to be platform specific
+ Status = mPlatform->GetVar (CmdArg, Response + 4);
+ if (EFI_ERROR (Status)) {
+ SEND_LITERAL ("FAILSomething went wrong when looking up the variable");
+ } else {
+ mTransport->Send (AsciiStrLen (Response), Response, &mFatalSendErrorEvent);
+ }
+ }
+}
+
+STATIC
+VOID
+HandleDownload (
+ IN CHAR8 *NumBytesString
+ )
+{
+ CHAR8 Response[12] = "DATA";
+ CHAR16 OutputString[FASTBOOT_STRING_MAX_LENGTH];
+
+ // Argument is 8-character ASCII string hex representation of number of bytes
+ // that will be sent in the data phase.
+ // Response is "DATA" + that same 8-character string.
+
+ // Replace any previously downloaded data
+ if (mDataBuffer != NULL) {
+ FreePool (mDataBuffer);
+ mDataBuffer = NULL;
+ }
+
+ // Parse out number of data bytes to expect
+ mNumDataBytes = AsciiStrHexToUint64 (NumBytesString);
+ if (mNumDataBytes == 0) {
+ mTextOut->OutputString (mTextOut, L"ERROR: Fail to get the number of bytes to download.\r\n");
+ SEND_LITERAL ("FAILFailed to get the number of bytes to download");
+ return;
+ }
+
+ UnicodeSPrint (OutputString, sizeof (OutputString), L"Downloading %d bytes\r\n", mNumDataBytes);
+ mTextOut->OutputString (mTextOut, OutputString);
+
+ mDataBuffer = AllocatePool (mNumDataBytes);
+ if (mDataBuffer == NULL) {
+ SEND_LITERAL ("FAILNot enough memory");
+ } else {
+ AsciiStrnCpy (Response + 4, NumBytesString, 8);
+ mTransport->Send (sizeof(Response), Response, &mFatalSendErrorEvent);
+
+ mState = ExpectDataState;
+ mBytesReceivedSoFar = 0;
+ }
+}
+
+STATIC
+VOID
+HandleFlash (
+ IN CHAR8 *PartitionName
+ )
+{
+ EFI_STATUS Status;
+ CHAR16 OutputString[FASTBOOT_STRING_MAX_LENGTH];
+
+ // Build output string
+ UnicodeSPrint (OutputString, sizeof (OutputString), L"Flashing partition %a\r\n", PartitionName);
+ mTextOut->OutputString (mTextOut, OutputString);
+
+ if (mDataBuffer == NULL) {
+ // Doesn't look like we were sent any data
+ SEND_LITERAL ("FAILNo data to flash");
+ return;
+ }
+
+ Status = mPlatform->FlashPartition (
+ PartitionName,
+ mNumDataBytes,
+ mDataBuffer
+ );
+ if (Status == EFI_NOT_FOUND) {
+ SEND_LITERAL ("FAILNo such partition.");
+ mTextOut->OutputString (mTextOut, L"No such partition.\r\n");
+ } else if (EFI_ERROR (Status)) {
+ SEND_LITERAL ("FAILError flashing partition.");
+ mTextOut->OutputString (mTextOut, L"Error flashing partition.\r\n");
+ DEBUG ((EFI_D_ERROR, "Couldn't flash image: %r\n", Status));
+ } else {
+ mTextOut->OutputString (mTextOut, L"Done.\r\n");
+ SEND_LITERAL ("OKAY");
+ }
+}
+
+STATIC
+VOID
+HandleErase (
+ IN CHAR8 *PartitionName
+ )
+{
+ EFI_STATUS Status;
+ CHAR16 OutputString[FASTBOOT_STRING_MAX_LENGTH];
+
+ // Build output string
+ UnicodeSPrint (OutputString, sizeof (OutputString), L"Erasing partition %a\r\n", PartitionName);
+ mTextOut->OutputString (mTextOut, OutputString);
+
+ Status = mPlatform->ErasePartition (PartitionName);
+ if (EFI_ERROR (Status)) {
+ SEND_LITERAL ("FAILCheck device console.");
+ DEBUG ((EFI_D_ERROR, "Couldn't erase image: %r\n", Status));
+ } else {
+ SEND_LITERAL ("OKAY");
+ }
+}
+
+STATIC
+VOID
+HandleBoot (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+
+ mTextOut->OutputString (mTextOut, L"Booting downloaded image\r\n");
+
+ if (mDataBuffer == NULL) {
+ // Doesn't look like we were sent any data
+ SEND_LITERAL ("FAILNo image in memory");
+ return;
+ }
+
+ // We don't really have any choice but to report success, because once we
+ // boot we lose control of the system.
+ SEND_LITERAL ("OKAY");
+
+ Status = BootAndroidBootImg (mNumDataBytes, mDataBuffer);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR, "Failed to boot downloaded image: %r\n", Status));
+ }
+ // We shouldn't get here
+}
+
+STATIC
+VOID
+HandleOemCommand (
+ IN CHAR8 *Command
+ )
+{
+ EFI_STATUS Status;
+
+ Status = mPlatform->DoOemCommand (Command);
+ if (Status == EFI_NOT_FOUND) {
+ SEND_LITERAL ("FAILOEM Command not recognised.");
+ } else if (Status == EFI_DEVICE_ERROR) {
+ SEND_LITERAL ("FAILError while executing command");
+ } else if (EFI_ERROR (Status)) {
+ SEND_LITERAL ("FAIL");
+ } else {
+ SEND_LITERAL ("OKAY");
+ }
+}
+
+STATIC
+VOID
+AcceptCmd (
+ IN UINTN Size,
+ IN CONST CHAR8 *Data
+ )
+{
+ CHAR8 Command[FASTBOOT_COMMAND_MAX_LENGTH + 1];
+
+ // Max command size is 64 bytes
+ if (Size > FASTBOOT_COMMAND_MAX_LENGTH) {
+ SEND_LITERAL ("FAILCommand too large");
+ return;
+ }
+
+ // Commands aren't null-terminated. Let's get a null-terminated version.
+ AsciiStrnCpy (Command, Data, Size);
+ Command[Size] = '\0';
+
+ // Parse command
+ if (MATCH_CMD_LITERAL ("getvar", Command)) {
+ HandleGetVar (Command + sizeof ("getvar"));
+ } else if (MATCH_CMD_LITERAL ("download", Command)) {
+ HandleDownload (Command + sizeof ("download"));
+ } else if (MATCH_CMD_LITERAL ("verify", Command)) {
+ SEND_LITERAL ("FAILNot supported");
+ } else if (MATCH_CMD_LITERAL ("flash", Command)) {
+ HandleFlash (Command + sizeof ("flash"));
+ } else if (MATCH_CMD_LITERAL ("erase", Command)) {
+ HandleErase (Command + sizeof ("erase"));
+ } else if (MATCH_CMD_LITERAL ("boot", Command)) {
+ HandleBoot ();
+ } else if (MATCH_CMD_LITERAL ("continue", Command)) {
+ SEND_LITERAL ("OKAY");
+ mTextOut->OutputString (mTextOut, L"Received 'continue' command. Exiting Fastboot mode\r\n");
+
+ gBS->SignalEvent (mFinishedEvent);
+ } else if (MATCH_CMD_LITERAL ("reboot", Command)) {
+ if (MATCH_CMD_LITERAL ("reboot-booloader", Command)) {
+ // fastboot_protocol.txt:
+ // "reboot-bootloader Reboot back into the bootloader."
+ // I guess this means reboot back into fastboot mode to save the user
+ // having to do whatever they did to get here again.
+ // Here we just reboot normally.
+ SEND_LITERAL ("INFOreboot-bootloader not supported, rebooting normally.");
+ }
+ SEND_LITERAL ("OKAY");
+ gRT->ResetSystem (EfiResetCold, EFI_SUCCESS, 0, NULL);
+
+ // Shouldn't get here
+ DEBUG ((EFI_D_ERROR, "Fastboot: gRT->ResetSystem didn't work\n"));
+ } else if (MATCH_CMD_LITERAL ("powerdown", Command)) {
+ SEND_LITERAL ("OKAY");
+ gRT->ResetSystem (EfiResetShutdown, EFI_SUCCESS, 0, NULL);
+
+ // Shouldn't get here
+ DEBUG ((EFI_D_ERROR, "Fastboot: gRT->ResetSystem didn't work\n"));
+ } else if (MATCH_CMD_LITERAL ("oem", Command)) {
+ // The "oem" command isn't in the specification, but it was observed in the
+ // wild, followed by a space, followed by the actual command.
+ HandleOemCommand (Command + sizeof ("oem"));
+ } else if (IS_LOWERCASE_ASCII (Command[0])) {
+ // Commands starting with lowercase ASCII characters are reserved for the
+ // Fastboot protocol. If we don't recognise it, it's probably the future
+ // and there are new commmands in the protocol.
+ // (By the way, the "oem" command mentioned above makes this reservation
+ // redundant, but we handle it here to be spec-compliant)
+ SEND_LITERAL ("FAILCommand not recognised. Check Fastboot version.");
+ } else {
+ HandleOemCommand (Command);
+ }
+}
+
+STATIC
+VOID
+AcceptData (
+ IN UINTN Size,
+ IN VOID *Data
+ )
+{
+ UINT32 RemainingBytes = mNumDataBytes - mBytesReceivedSoFar;
+ CHAR16 OutputString[FASTBOOT_STRING_MAX_LENGTH];
+ STATIC UINTN Count = 0;
+
+ // Protocol doesn't say anything about sending extra data so just ignore it.
+ if (Size > RemainingBytes) {
+ Size = RemainingBytes;
+ }
+
+ CopyMem (&mDataBuffer[mBytesReceivedSoFar], Data, Size);
+
+ mBytesReceivedSoFar += Size;
+
+ // Show download progress. Don't do it for every packet as outputting text
+ // might be time consuming - do it on the last packet and on every 32nd packet
+ if ((Count++ % 32) == 0 || Size == RemainingBytes) {
+ // (Note no newline in format string - it will overwrite the line each time)
+ UnicodeSPrint (
+ OutputString,
+ sizeof (OutputString),
+ L"\r%8d / %8d bytes downloaded (%d%%)",
+ mBytesReceivedSoFar,
+ mNumDataBytes,
+ (mBytesReceivedSoFar * 100) / mNumDataBytes // percentage
+ );
+ mTextOut->OutputString (mTextOut, OutputString);
+ }
+
+ if (mBytesReceivedSoFar == mNumDataBytes) {
+ // Download finished.
+
+ mTextOut->OutputString (mTextOut, L"\r\n");
+ SEND_LITERAL ("OKAY");
+ mState = ExpectCmdState;
+ }
+}
+
+/*
+ This is the NotifyFunction passed to CreateEvent in the FastbootAppEntryPoint
+ It will be called by the UEFI event framework when the transport protocol
+ implementation signals that data has been received from the Fastboot host.
+ The parameters are ignored.
+*/
+STATIC
+VOID
+DataReady (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+{
+ UINTN Size;
+ VOID *Data;
+ EFI_STATUS Status;
+
+ do {
+ Status = mTransport->Receive (&Size, &Data);
+ if (!EFI_ERROR (Status)) {
+ if (mState == ExpectCmdState) {
+ AcceptCmd (Size, (CHAR8 *) Data);
+ } else if (mState == ExpectDataState) {
+ AcceptData (Size, Data);
+ } else {
+ ASSERT (FALSE);
+ }
+ FreePool (Data);
+ }
+ } while (!EFI_ERROR (Status));
+
+ // Quit if there was a fatal error
+ if (Status != EFI_NOT_READY) {
+ ASSERT (Status == EFI_DEVICE_ERROR);
+ // (Put a newline at the beginning as we are probably in the data phase,
+ // so the download progress line, with no '\n' is probably on the console)
+ mTextOut->OutputString (mTextOut, L"\r\nFatal error receiving data. Exiting.\r\n");
+ gBS->SignalEvent (mFinishedEvent);
+ }
+}
+
+/*
+ Event notify for a fatal error in transmission.
+*/
+STATIC
+VOID
+FatalErrorNotify (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+{
+ mTextOut->OutputString (mTextOut, L"Fatal error sending command response. Exiting.\r\n");
+ gBS->SignalEvent (mFinishedEvent);
+}
+
+EFI_STATUS
+EFIAPI
+FastbootAppEntryPoint (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+ EFI_EVENT ReceiveEvent;
+ EFI_EVENT WaitEventArray[2];
+ UINTN EventIndex;
+ EFI_SIMPLE_TEXT_INPUT_PROTOCOL *TextIn;
+
+ mDataBuffer = NULL;
+
+ Status = gBS->LocateProtocol (
+ &gAndroidFastbootTransportProtocolGuid,
+ NULL,
+ (VOID **) &mTransport
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR, "Fastboot: Couldn't open Fastboot Transport Protocol: %r\n", Status));
+ return Status;
+ }
+
+ Status = gBS->LocateProtocol (&gAndroidFastbootPlatformProtocolGuid, NULL, (VOID **) &mPlatform);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR, "Fastboot: Couldn't open Fastboot Platform Protocol: %r\n", Status));
+ return Status;
+ }
+
+ Status = mPlatform->Init ();
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR, "Fastboot: Couldn't initialise Fastboot Platform Protocol: %r\n", Status));
+ return Status;
+ }
+
+ Status = gBS->LocateProtocol (&gEfiSimpleTextOutProtocolGuid, NULL, (VOID **) &mTextOut);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR,
+ "Fastboot: Couldn't open Text Output Protocol: %r\n", Status
+ ));
+ return Status;
+ }
+
+ Status = gBS->LocateProtocol (&gEfiSimpleTextInProtocolGuid, NULL, (VOID **) &TextIn);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR, "Fastboot: Couldn't open Text Input Protocol: %r\n", Status));
+ return Status;
+ }
+
+ // Disable watchdog
+ Status = gBS->SetWatchdogTimer (0, 0x10000, 0, NULL);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR, "Fastboot: Couldn't disable watchdog timer: %r\n", Status));
+ }
+
+ // Create event for receipt of data from the host
+ Status = gBS->CreateEvent (
+ EVT_NOTIFY_SIGNAL,
+ TPL_CALLBACK,
+ DataReady,
+ NULL,
+ &ReceiveEvent
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ // Create event for exiting application when "continue" command is received
+ Status = gBS->CreateEvent (0, TPL_CALLBACK, NULL, NULL, &mFinishedEvent);
+ ASSERT_EFI_ERROR (Status);
+
+ // Create event to pass to FASTBOOT_TRANSPORT_PROTOCOL.Send, signalling a
+ // fatal error
+ Status = gBS->CreateEvent (
+ EVT_NOTIFY_SIGNAL,
+ TPL_CALLBACK,
+ FatalErrorNotify,
+ NULL,
+ &mFatalSendErrorEvent
+ );
+ ASSERT_EFI_ERROR (Status);
+
+
+ // Start listening for data
+ Status = mTransport->Start (
+ ReceiveEvent
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR, "Fastboot: Couldn't start transport: %r\n", Status));
+ return Status;
+ }
+
+ // Talk to the user
+ mTextOut->OutputString (mTextOut,
+ L"Android Fastboot mode - version " ANDROID_FASTBOOT_VERSION ". Press any key to quit.\r\n");
+
+ // Quit when the user presses any key, or mFinishedEvent is signalled
+ WaitEventArray[0] = mFinishedEvent;
+ WaitEventArray[1] = TextIn->WaitForKey;
+ gBS->WaitForEvent (2, WaitEventArray, &EventIndex);
+
+ mTransport->Stop ();
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR, "Warning: Fastboot Transport Stop: %r\n", Status));
+ }
+ mPlatform->UnInit ();
+
+ return EFI_SUCCESS;
+}
diff --git a/EmbeddedPkg/Application/AndroidFastboot/AndroidFastbootApp.h b/EmbeddedPkg/Application/AndroidFastboot/AndroidFastbootApp.h
new file mode 100644
index 000000000..f62660feb
--- /dev/null
+++ b/EmbeddedPkg/Application/AndroidFastboot/AndroidFastbootApp.h
@@ -0,0 +1,42 @@
+/** @file
+
+ Copyright (c) 2013-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.
+
+**/
+
+#ifndef __ANDROID_FASTBOOT_APP_H__
+#define __ANDROID_FASTBOOT_APP_H__
+
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+#include <Library/MemoryAllocationLib.h>
+
+#define BOOTIMG_KERNEL_ARGS_SIZE 512
+
+#define ANDROID_FASTBOOT_VERSION "0.4"
+
+EFI_STATUS
+BootAndroidBootImg (
+ IN UINTN BufferSize,
+ IN VOID *Buffer
+ );
+
+EFI_STATUS
+ParseAndroidBootImg (
+ IN VOID *BootImg,
+ OUT VOID **Kernel,
+ OUT UINTN *KernelSize,
+ OUT VOID **Ramdisk,
+ OUT UINTN *RamdiskSize,
+ OUT CHAR8 *KernelArgs
+ );
+
+#endif //ifdef __ANDROID_FASTBOOT_APP_H__
diff --git a/EmbeddedPkg/Application/AndroidFastboot/AndroidFastbootApp.inf b/EmbeddedPkg/Application/AndroidFastboot/AndroidFastbootApp.inf
new file mode 100644
index 000000000..ab9354c39
--- /dev/null
+++ b/EmbeddedPkg/Application/AndroidFastboot/AndroidFastbootApp.inf
@@ -0,0 +1,60 @@
+#/** @file
+#
+# Copyright (c) 2013-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 = AndroidFastbootApp
+ FILE_GUID = 9588502a-5370-11e3-8631-d7c5951364c8
+ MODULE_TYPE = UEFI_APPLICATION
+ VERSION_STRING = 1.0
+ ENTRY_POINT = FastbootAppEntryPoint
+
+[Sources.common]
+ AndroidFastbootApp.c
+ AndroidBootImg.c
+
+[Sources.ARM, Sources.AARCH64]
+ Arm/BootAndroidBootImg.c
+
+[LibraryClasses]
+ BaseLib
+ BaseMemoryLib
+ BdsLib
+ DebugLib
+ DevicePathLib
+ DxeServicesTableLib
+ MemoryAllocationLib
+ PcdLib
+ PrintLib
+ UefiApplicationEntryPoint
+ UefiBootServicesTableLib
+ UefiRuntimeServicesTableLib
+
+[Protocols]
+ gAndroidFastbootTransportProtocolGuid
+ gAndroidFastbootPlatformProtocolGuid
+ gEfiSimpleTextOutProtocolGuid
+ gEfiSimpleTextInProtocolGuid
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ EmbeddedPkg/EmbeddedPkg.dec
+
+[Packages.ARM, Packages.AARCH64]
+ ArmPkg/ArmPkg.dec
+ ArmPlatformPkg/ArmPlatformPkg.dec
+
+[Guids.ARM, Guids.AARCH64]
+ gArmGlobalVariableGuid
diff --git a/EmbeddedPkg/Application/AndroidFastboot/Arm/BootAndroidBootImg.c b/EmbeddedPkg/Application/AndroidFastboot/Arm/BootAndroidBootImg.c
new file mode 100644
index 000000000..6f4b66bee
--- /dev/null
+++ b/EmbeddedPkg/Application/AndroidFastboot/Arm/BootAndroidBootImg.c
@@ -0,0 +1,125 @@
+/** @file
+
+ Copyright (c) 2013-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 "AndroidFastbootApp.h"
+
+#include <Protocol/DevicePath.h>
+
+#include <Library/BdsLib.h>
+#include <Library/DevicePathLib.h>
+
+#include <Guid/ArmGlobalVariableHob.h>
+
+// Device Path representing an image in memory
+#pragma pack(1)
+typedef struct {
+ MEMMAP_DEVICE_PATH Node1;
+ EFI_DEVICE_PATH_PROTOCOL End;
+} MEMORY_DEVICE_PATH;
+#pragma pack()
+
+STATIC CONST MEMORY_DEVICE_PATH MemoryDevicePathTemplate =
+{
+ {
+ {
+ HARDWARE_DEVICE_PATH,
+ HW_MEMMAP_DP,
+ {
+ (UINT8)(sizeof (MEMMAP_DEVICE_PATH)),
+ (UINT8)((sizeof (MEMMAP_DEVICE_PATH)) >> 8),
+ },
+ }, // Header
+ 0, // StartingAddress (set at runtime)
+ 0 // EndingAddress (set at runtime)
+ }, // Node1
+ {
+ END_DEVICE_PATH_TYPE,
+ END_ENTIRE_DEVICE_PATH_SUBTYPE,
+ sizeof (EFI_DEVICE_PATH_PROTOCOL),
+ 0
+ } // End
+};
+
+EFI_STATUS
+BootAndroidBootImg (
+ IN UINTN BufferSize,
+ IN VOID *Buffer
+ )
+{
+ EFI_DEVICE_PATH_PROTOCOL *FdtDevicePath;
+ EFI_STATUS Status;
+ CHAR8 KernelArgs[BOOTIMG_KERNEL_ARGS_SIZE];
+ VOID *Kernel;
+ UINTN KernelSize;
+ VOID *Ramdisk;
+ UINTN RamdiskSize;
+ MEMORY_DEVICE_PATH KernelDevicePath;
+ MEMORY_DEVICE_PATH* RamdiskDevicePath;
+
+ Status = ParseAndroidBootImg (
+ Buffer,
+ &Kernel,
+ &KernelSize,
+ &Ramdisk,
+ &RamdiskSize,
+ KernelArgs
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ KernelDevicePath = MemoryDevicePathTemplate;
+
+ // Have to cast to UINTN before casting to EFI_PHYSICAL_ADDRESS in order to
+ // appease GCC.
+ KernelDevicePath.Node1.StartingAddress = (EFI_PHYSICAL_ADDRESS)(UINTN) Kernel;
+ KernelDevicePath.Node1.EndingAddress = (EFI_PHYSICAL_ADDRESS)(UINTN) Kernel + KernelSize;
+
+ RamdiskDevicePath = NULL;
+ if (RamdiskSize != 0) {
+ RamdiskDevicePath = (MEMORY_DEVICE_PATH*)DuplicateDevicePath ((EFI_DEVICE_PATH_PROTOCOL*) &MemoryDevicePathTemplate);
+
+ RamdiskDevicePath->Node1.StartingAddress = (EFI_PHYSICAL_ADDRESS)(UINTN) Ramdisk;
+ RamdiskDevicePath->Node1.EndingAddress = ((EFI_PHYSICAL_ADDRESS)(UINTN) Ramdisk) + RamdiskSize;
+ }
+
+ // Get the default FDT device path
+ Status = GetEnvironmentVariable ((CHAR16 *)L"Fdt", &gArmGlobalVariableGuid,
+ NULL, 0, (VOID **)&FdtDevicePath);
+ if (Status == EFI_NOT_FOUND) {
+ DEBUG ((EFI_D_ERROR, "Error: Please update FDT path in boot manager\n"));
+ return EFI_DEVICE_ERROR;
+ }
+ ASSERT_EFI_ERROR (Status);
+
+ Status = BdsBootLinuxFdt (
+ (EFI_DEVICE_PATH_PROTOCOL *) &KernelDevicePath,
+ (EFI_DEVICE_PATH_PROTOCOL *) RamdiskDevicePath,
+ KernelArgs,
+ FdtDevicePath
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR, "Couldn't Boot Linux: %d\n", Status));
+ return EFI_DEVICE_ERROR;
+ }
+
+ if (RamdiskDevicePath) {
+ FreePool (RamdiskDevicePath);
+ }
+
+ // If we got here we do a confused face because BootLinuxFdt returned,
+ // reporting success.
+ DEBUG ((EFI_D_ERROR, "WARNING: BdsBootLinuxFdt returned EFI_SUCCESS.\n"));
+ return EFI_SUCCESS;
+}
diff --git a/EmbeddedPkg/Drivers/AndroidFastbootTransportUsbDxe/FastbootTransportUsb.c b/EmbeddedPkg/Drivers/AndroidFastbootTransportUsbDxe/FastbootTransportUsb.c
new file mode 100644
index 000000000..e7da1fa5f
--- /dev/null
+++ b/EmbeddedPkg/Drivers/AndroidFastbootTransportUsbDxe/FastbootTransportUsb.c
@@ -0,0 +1,278 @@
+/** @file
+
+ 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.
+
+**/
+
+/*
+ * Implementation of the FASTBOOT_TRANSPORT_PROTOCOL using the USB_DEVICE_PROTOCOL
+ */
+
+#include <Protocol/UsbDevice.h>
+#include <Protocol/AndroidFastbootTransport.h>
+#include <Protocol/SimpleTextOut.h>
+
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiDriverEntryPoint.h>
+
+STATIC USB_DEVICE_PROTOCOL *mUsbDevice;
+
+// Configuration attributes:
+// bit 7 reserved and must be 1, bit 6 means self-powered.
+#define CONFIG_DESC_ATTRIBUTES (BIT7 | BIT6)
+
+#define MAX_PACKET_SIZE_BULK 512
+
+STATIC USB_DEVICE_PROTOCOL *mUsbDevice;
+STATIC EFI_EVENT mReceiveEvent = NULL;
+STATIC LIST_ENTRY mPacketList;
+
+// List type for queued received packets
+typedef struct _FASTBOOT_USB_PACKET_LIST {
+ LIST_ENTRY Link;
+ VOID *Buffer;
+ UINTN BufferSize;
+} FASTBOOT_USB_PACKET_LIST;
+
+
+/*
+ No string descriptors - all string descriptor members are set to 0
+*/
+
+STATIC USB_DEVICE_DESCRIPTOR mDeviceDescriptor = {
+ sizeof (USB_DEVICE_DESCRIPTOR), //Length
+ USB_DESC_TYPE_DEVICE, //DescriptorType
+ 0x0200, //BcdUSB
+ 0xFF, //DeviceClass
+ 0, //DeviceSubClass
+ 0, //DeviceProtocol
+ 64, //MaxPacketSize0
+ FixedPcdGet32 (PcdAndroidFastbootUsbVendorId), //IdVendor
+ FixedPcdGet32 (PcdAndroidFastbootUsbProductId), //IdProduct
+ 0, //BcdDevice
+ 0, //StrManufacturer
+ 0, //StrProduct
+ 0, //StrSerialNumber
+ 1 //NumConfigurations
+};
+
+/*
+ We have one configuration, one interface, and two endpoints (one IN, one OUT)
+*/
+
+// Lazy (compile-time) way to concatenate descriptors to pass to the USB device
+// protocol
+
+#pragma pack(1)
+typedef struct {
+ USB_CONFIG_DESCRIPTOR ConfigDescriptor;
+ USB_INTERFACE_DESCRIPTOR InterfaceDescriptor;
+ USB_ENDPOINT_DESCRIPTOR EndpointDescriptor1;
+ USB_ENDPOINT_DESCRIPTOR EndpointDescriptor2;
+} GET_CONFIG_DESCRIPTOR_RESPONSE;
+#pragma pack()
+
+STATIC GET_CONFIG_DESCRIPTOR_RESPONSE mGetConfigDescriptorResponse = {
+ { // USB_CONFIG_DESCRIPTOR
+ sizeof (USB_CONFIG_DESCRIPTOR), //Length;
+ USB_DESC_TYPE_CONFIG, //DescriptorType;
+ sizeof (GET_CONFIG_DESCRIPTOR_RESPONSE), //TotalLength;
+ 1, //NumInterfaces;
+ 1, //ConfigurationValue;
+ 0, //Configuration;
+ CONFIG_DESC_ATTRIBUTES, //Attributes;
+ 0 //MaxPower;
+ },
+ { // USB_INTERFACE_DESCRIPTOR
+ sizeof (USB_INTERFACE_DESCRIPTOR), //Length;
+ USB_DESC_TYPE_INTERFACE, //DescriptorType;
+ 0, //InterfaceNumber;
+ 0, //AlternateSetting;
+ 2, //NumEndpoints;
+ 0xFF, //InterfaceClass;
+ // Vendor specific interface subclass and protocol codes.
+ // I found these values in the Fastboot code
+ // (in match_fastboot_with_serial in fastboot.c).
+ 0x42, //InterfaceSubClass;
+ 0x03, //InterfaceProtocol;
+ 0 //Interface;
+ },
+ { // USB_ENDPOINT_DESCRIPTOR (In Endpoint)
+ sizeof (USB_ENDPOINT_DESCRIPTOR), //Length;
+ USB_DESC_TYPE_ENDPOINT, //DescriptorType;
+ 1 | BIT7, //EndpointAddress;
+ 0x2, //Attributes;
+ MAX_PACKET_SIZE_BULK, //MaxPacketSize;
+ 16 //Interval;
+ },
+ { // STATIC USB_ENDPOINT_DESCRIPTOR (Out Endpoint)
+ sizeof (USB_ENDPOINT_DESCRIPTOR), //Length;
+ USB_DESC_TYPE_ENDPOINT, //DescriptorType;
+ 1, //EndpointAddress;
+ 0x2, //Attributes;
+ MAX_PACKET_SIZE_BULK, //MaxPacketSize;
+ 16 //Interval;
+ }
+};
+
+STATIC
+VOID
+DataReceived (
+ IN UINTN Size,
+ IN VOID *Buffer
+ )
+{
+ FASTBOOT_USB_PACKET_LIST *NewEntry;
+
+ NewEntry = AllocatePool (sizeof (*NewEntry));
+ ASSERT (NewEntry != NULL);
+
+ NewEntry->Buffer = Buffer;
+ NewEntry->BufferSize = Size;
+
+ InsertTailList (&mPacketList, &NewEntry->Link);
+
+ if (mReceiveEvent) {
+ gBS->SignalEvent (mReceiveEvent);
+ }
+}
+
+STATIC
+VOID
+DataSent (
+ IN UINT8 EndpointIndex
+ )
+{
+ // Don't care.
+}
+
+/*
+ Set up the transport system for use by Fastboot.
+ e.g. For USB this probably means making the device enumerable.
+*/
+EFI_STATUS
+FastbootTransportUsbStart (
+ EFI_EVENT ReceiveEvent
+ )
+{
+ GET_CONFIG_DESCRIPTOR_RESPONSE *Responses;
+
+ mReceiveEvent = ReceiveEvent;
+
+ mGetConfigDescriptorResponse.ConfigDescriptor.TotalLength = sizeof (GET_CONFIG_DESCRIPTOR_RESPONSE);
+ Responses = &mGetConfigDescriptorResponse;
+
+ InitializeListHead (&mPacketList);
+
+ return mUsbDevice->Start (&mDeviceDescriptor, (VOID **) &Responses, DataReceived, DataSent);
+}
+
+/*
+ Function to be called when all Fastboot transactions are finished, to
+ de-initialise the transport system.
+ e.g. A USB OTG system might want to get out of peripheral mode so it can be
+ a USB host.
+*/
+EFI_STATUS
+FastbootTransportUsbStop (
+ VOID
+ )
+{
+ // not yet implemented in USB
+ return EFI_SUCCESS;
+}
+
+/*
+ Send data. This function can be used both for command responses like "OKAY"
+ and for the data phase (the protocol doesn't describe any situation when the
+ latter might be necessary, but does allow it)
+ */
+EFI_STATUS
+FastbootTransportUsbSend (
+ IN UINTN BufferSize,
+ IN CONST VOID *Buffer,
+ IN EFI_EVENT *FatalErrorEvent
+ )
+{
+ // Current USB protocol is blocking, so ignore FatalErrorEvent
+ return mUsbDevice->Send(1, BufferSize, Buffer);
+}
+
+/*
+ When the event has been Signalled to say data is available from the host,
+ this function is used to get data. In order to handle the case where several
+ packets are received before ReceiveEvent's notify function is called, packets
+ received are queued, and each call to this function returns the next packet in
+ the queue. It should therefore be called in a loop, the exit condition being a
+ return of EFI_NOT_READY.
+
+ Parameters:
+ Buffer - The buffer in which to place data
+ BufferSize - The size of Buffer in bytes
+
+ Return EFI_NOT_READY if there is no data available
+*/
+EFI_STATUS
+FastbootTransportUsbReceive (
+ OUT UINTN *BufferSize,
+ OUT VOID **Buffer
+ )
+{
+ FASTBOOT_USB_PACKET_LIST *Entry;
+
+ if (IsListEmpty (&mPacketList)) {
+ return EFI_NOT_READY;
+ }
+
+ Entry = (FASTBOOT_USB_PACKET_LIST *) GetFirstNode (&mPacketList);
+
+ *BufferSize = Entry->BufferSize;
+ *Buffer = Entry->Buffer;
+
+ RemoveEntryList (&Entry->Link);
+ FreePool (Entry);
+
+ return EFI_SUCCESS;
+}
+
+STATIC FASTBOOT_TRANSPORT_PROTOCOL mTransportProtocol = {
+ FastbootTransportUsbStart,
+ FastbootTransportUsbStop,
+ FastbootTransportUsbSend,
+ FastbootTransportUsbReceive
+};
+
+EFI_STATUS
+FastbootTransportUsbEntryPoint (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+
+ // Assume there's only one USB peripheral controller.
+ Status = gBS->LocateProtocol (&gUsbDeviceProtocolGuid, NULL, (VOID **) &mUsbDevice);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ Status = gBS->InstallProtocolInterface (
+ &ImageHandle,
+ &gAndroidFastbootTransportProtocolGuid,
+ EFI_NATIVE_INTERFACE,
+ &mTransportProtocol
+ );
+ return Status;
+}
diff --git a/EmbeddedPkg/Drivers/AndroidFastbootTransportUsbDxe/FastbootTransportUsbDxe.inf b/EmbeddedPkg/Drivers/AndroidFastbootTransportUsbDxe/FastbootTransportUsbDxe.inf
new file mode 100644
index 000000000..c5ada1a0b
--- /dev/null
+++ b/EmbeddedPkg/Drivers/AndroidFastbootTransportUsbDxe/FastbootTransportUsbDxe.inf
@@ -0,0 +1,46 @@
+#/** @file
+#
+# Copyright (c) 2013-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 = FastbootTransportUsbDxe
+ FILE_GUID = f6bec3fe-88fb-11e3-ae84-e73b77561c35
+ MODULE_TYPE = UEFI_DRIVER
+ VERSION_STRING = 1.0
+ ENTRY_POINT = FastbootTransportUsbEntryPoint
+
+[Sources.common]
+ FastbootTransportUsb.c
+
+[LibraryClasses]
+ BaseLib
+ BaseMemoryLib
+ MemoryAllocationLib
+ UefiBootServicesTableLib
+ UefiDriverEntryPoint
+
+[Protocols]
+ gEfiDriverBindingProtocolGuid
+ gUsbDeviceProtocolGuid
+ gAndroidFastbootTransportProtocolGuid
+ gEfiSimpleTextOutProtocolGuid
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ EmbeddedPkg/EmbeddedPkg.dec
+
+[FixedPcd]
+ gEmbeddedTokenSpaceGuid.PcdAndroidFastbootUsbVendorId
+ gEmbeddedTokenSpaceGuid.PcdAndroidFastbootUsbProductId
diff --git a/EmbeddedPkg/Drivers/Isp1761UsbDxe/Isp1761UsbDxe.c b/EmbeddedPkg/Drivers/Isp1761UsbDxe/Isp1761UsbDxe.c
new file mode 100644
index 000000000..77d4f2a83
--- /dev/null
+++ b/EmbeddedPkg/Drivers/Isp1761UsbDxe/Isp1761UsbDxe.c
@@ -0,0 +1,636 @@
+/** @file
+
+ Copyright (c) 2013-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 <Library/TimerLib.h>
+#include <Library/DebugLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiDriverEntryPoint.h>
+#include <Library/IoLib.h>
+#include <Library/MemoryAllocationLib.h>
+
+#include <IndustryStandard/Usb.h>
+
+#include <Protocol/UsbDevice.h>
+
+#include "Isp1761UsbDxe.h"
+
+/*
+ Driver for using the NXP ISP1761 as a USB Peripheral controller.
+ Doesn't use USB OTG - just sets it in Pure Peripheral mode.
+
+ The ISP1582 datasheet has a little more info on the Peripheral controller
+ registers than the ISP1761 datasheet
+
+ We don't do string descriptors. They're optional.
+ We currently assume the device has one configuration, one interface, one IN
+ endpoint, and one OUT endpoint (plus the default control endpoint).
+
+ In fact, this driver is the minimum required to implement fastboot.
+*/
+
+// TODO Make sure the controller isn't sending empty packets when it shouldn't
+// (check behaviour in cases when Buffer Length isn't explcitly set)
+
+// ISP1582 Datasheet:
+// "Data transfers preceding the status stage must first be fully
+// completed before the STATUS bit can be set."
+// This variable stores whether some control data has been pended in the EP0TX
+// Tx buffer, so that when an EP0TX interrupt is received we can set the STATUS
+// bit to go to the Status stage of the control transfer.
+STATIC BOOLEAN mControlTxPending = FALSE;
+
+STATIC USB_DEVICE_DESCRIPTOR *mDeviceDescriptor;
+
+// The config descriptor, interface descriptor, and endpoint descriptors in a
+// buffer (in that order)
+STATIC VOID *mDescriptors;
+// Convenience pointers to those descriptors inside the buffer:
+STATIC USB_INTERFACE_DESCRIPTOR *mInterfaceDescriptor;
+STATIC USB_CONFIG_DESCRIPTOR *mConfigDescriptor;
+STATIC USB_ENDPOINT_DESCRIPTOR *mEndpointDescriptors;
+
+STATIC USB_DEVICE_RX_CALLBACK mDataReceivedCallback;
+STATIC USB_DEVICE_TX_CALLBACK mDataSentCallback;
+
+// The time between interrupt polls, in units of 100 nanoseconds
+// 10 Microseconds
+#define ISP1761_INTERRUPT_POLL_PERIOD 10000
+
+STATIC
+VOID
+SelectEndpoint (
+ IN UINT8 Endpoint
+ )
+{
+ // The DMA Endpoint Index must not point to the same as the
+ // Endpoint Index Register.
+ WRITE_REG32 (ISP1761_DMA_ENDPOINT_INDEX, ((Endpoint + 2) % ISP1761_NUM_ENDPOINTS));
+ WRITE_REG32 (ISP1761_ENDPOINT_INDEX, Endpoint);
+}
+
+// Enable going to the Data stage of a control transfer
+STATIC
+VOID
+DataStageEnable (
+ IN UINT8 Endpoint
+ )
+{
+ SelectEndpoint (Endpoint);
+ WRITE_REG32 (ISP1761_CTRL_FUNCTION, ISP1761_CTRL_FUNCTION_DSEN);
+}
+
+// Go to the Status stage of a successful control transfer
+STATIC
+VOID
+StatusAcknowledge (
+ IN UINT8 Endpoint
+)
+{
+ SelectEndpoint (Endpoint);
+ WRITE_REG32 (ISP1761_CTRL_FUNCTION, ISP1761_CTRL_FUNCTION_STATUS);
+}
+
+// Read the FIFO for the endpoint indexed by Endpoint, into the buffer pointed
+// at by Buffer, whose size is *Size bytes.
+//
+// If *Size is less than the number of bytes in the FIFO, return EFI_BUFFER_TOO_SMALL
+//
+// Update *Size with the number of bytes of data in the FIFO.
+STATIC
+EFI_STATUS
+ReadEndpointBuffer (
+ IN UINT8 Endpoint,
+ IN OUT UINTN *Size,
+ IN OUT VOID *Buffer
+ )
+{
+ UINT16 NumBytesAvailable;
+ UINT32 Val32;
+ UINTN Index;
+ UINTN NumBytesRead;
+
+ SelectEndpoint (Endpoint);
+
+ NumBytesAvailable = READ_REG16 (ISP1761_BUFFER_LENGTH);
+
+ if (NumBytesAvailable > *Size) {
+ *Size = NumBytesAvailable;
+ return EFI_BUFFER_TOO_SMALL;
+ }
+ *Size = NumBytesAvailable;
+
+ /* -- NB! --
+ The datasheet says the Data Port is 16 bits but it actually appears to
+ be 32 bits.
+ */
+
+ // Read 32-bit chunks
+ for (Index = 0; Index < NumBytesAvailable / 4; Index++) {
+ ((UINT32 *) Buffer)[Index] = READ_REG32 (ISP1761_DATA_PORT);
+ }
+
+ // Read remaining bytes
+
+ // Round NumBytesAvailable down to nearest power of 4
+ NumBytesRead = NumBytesAvailable & (~0x3);
+ if (NumBytesRead != NumBytesAvailable) {
+ Val32 = READ_REG32 (ISP1761_DATA_PORT);
+ // Copy each required byte of 32-bit word into buffer
+ for (Index = 0; Index < NumBytesAvailable % 4; Index++) {
+ ((UINT8 *) Buffer)[NumBytesRead + Index] = Val32 >> (Index * 8);
+ }
+ }
+ return EFI_SUCCESS;
+}
+
+/*
+ Write an endpoint buffer. Parameters:
+ Endpoint Endpoint index (see Endpoint Index Register in datasheet)
+ MaxPacketSize The MaxPacketSize this endpoint is configured for
+ Size The size of the Buffer
+ Buffer The data
+
+ Assumes MaxPacketSize is a multiple of 4.
+ (It seems that all valid values for MaxPacketSize _are_ multiples of 4)
+*/
+STATIC
+EFI_STATUS
+WriteEndpointBuffer (
+ IN UINT8 Endpoint,
+ IN UINTN MaxPacketSize,
+ IN UINTN Size,
+ IN CONST VOID *Buffer
+ )
+{
+ UINTN Index;
+ UINT32 *DwordBuffer;
+
+ DwordBuffer = (UINT32 *) Buffer;
+ SelectEndpoint (Endpoint);
+
+ /* -- NB! --
+ The datasheet says the Data Port is 16 bits but it actually appears to
+ be 32 bits.
+ */
+
+ // Write packets of size MaxPacketSize
+ while (Size > MaxPacketSize) {
+ for (Index = 0; Index < MaxPacketSize / 4; Index++) {
+ WRITE_REG32 (ISP1761_DATA_PORT, DwordBuffer[Index]);
+ }
+ Size -= MaxPacketSize;
+ DwordBuffer += (MaxPacketSize / sizeof (UINT32));
+ }
+
+ // Write remaining data
+
+ if (Size > 0) {
+ WRITE_REG32 (ISP1761_BUFFER_LENGTH, Size);
+
+ while (Size > 4) {
+ WRITE_REG32 (ISP1761_DATA_PORT, DwordBuffer[0]);
+ Size -= 4;
+ DwordBuffer++;
+ }
+
+ if (Size > 0) {
+ WRITE_REG32 (ISP1761_DATA_PORT, DwordBuffer[0]);
+ }
+ }
+
+ return EFI_SUCCESS;
+}
+
+STATIC
+EFI_STATUS
+HandleGetDescriptor (
+ IN USB_DEVICE_REQUEST *Request
+ )
+{
+ EFI_STATUS Status;
+ UINT8 DescriptorType;
+ UINTN ResponseSize;
+ VOID *ResponseData;
+
+ ResponseSize = 0;
+ ResponseData = NULL;
+ Status = EFI_SUCCESS;
+
+ // Pretty confused if bmRequestType is anything but this:
+ ASSERT (Request->RequestType == USB_DEV_GET_DESCRIPTOR_REQ_TYPE);
+
+ // Choose the response
+ DescriptorType = Request->Value >> 8;
+ switch (DescriptorType) {
+ case USB_DESC_TYPE_DEVICE:
+ DEBUG ((EFI_D_INFO, "USB: Got a request for device descriptor\n"));
+ ResponseSize = sizeof (USB_DEVICE_DESCRIPTOR);
+ ResponseData = mDeviceDescriptor;
+ break;
+ case USB_DESC_TYPE_CONFIG:
+ DEBUG ((EFI_D_INFO, "USB: Got a request for config descriptor\n"));
+ ResponseSize = mConfigDescriptor->TotalLength;
+ ResponseData = mDescriptors;
+ break;
+ case USB_DESC_TYPE_STRING:
+ DEBUG ((EFI_D_INFO, "USB: Got a request for String descriptor %d\n", Request->Value & 0xFF));
+ break;
+ default:
+ DEBUG ((EFI_D_INFO, "USB: Didn't understand request for descriptor 0x%04x\n", Request->Value));
+ Status = EFI_NOT_FOUND;
+ break;
+ }
+
+ // Send the response
+ if (ResponseData) {
+ ASSERT (ResponseSize != 0);
+
+ if (Request->Length < ResponseSize) {
+ // Truncate response
+ ResponseSize = Request->Length;
+ } else if (Request->Length > ResponseSize) {
+ DEBUG ((EFI_D_INFO, "USB: Info: ResponseSize < wLength\n"));
+ }
+
+ DataStageEnable (ISP1761_EP0TX);
+ Status = WriteEndpointBuffer (
+ ISP1761_EP0TX,
+ MAX_PACKET_SIZE_CONTROL,
+ ResponseSize,
+ ResponseData
+ );
+ if (!EFI_ERROR (Status)) {
+ // Setting this value should cause us to go to the Status stage on the
+ // next EP0TX interrupt
+ mControlTxPending = TRUE;
+ }
+ }
+
+ return EFI_SUCCESS;
+}
+
+STATIC
+EFI_STATUS
+HandleSetAddress (
+ IN USB_DEVICE_REQUEST *Request
+ )
+{
+ // Pretty confused if bmRequestType is anything but this:
+ ASSERT (Request->RequestType == USB_DEV_SET_ADDRESS_REQ_TYPE);
+ // USB Spec: "The USB device does not change its device address until after
+ // the Status stage of this request is completed successfully."
+ // ISP1582 datasheet: "The new device address is activated when the
+ // device receives an acknowledgment from the host for the empty packet
+ // token". (StatusAcknowledge causes an empty packet to be sent).
+ // So, we write the Address register _before_ acking the SET_ADDRESS.
+ DEBUG ((EFI_D_INFO, "USB: Setting address to %d\n", Request->Value));
+ WRITE_REG32 (ISP1761_ADDRESS, Request->Value | ISP1761_ADDRESS_DEVEN);
+ StatusAcknowledge (ISP1761_EP0TX);
+
+ return EFI_SUCCESS;
+}
+
+// Move the device to the Configured state.
+// (This code only supports one configuration for a device, so the configuration
+// index is ignored)
+STATIC
+EFI_STATUS
+HandleSetConfiguration (
+ IN USB_DEVICE_REQUEST *Request
+ )
+{
+ USB_ENDPOINT_DESCRIPTOR *EPDesc;
+ UINTN Index;
+ UINT8 EndpointIndex;
+
+ ASSERT (Request->RequestType == USB_DEV_SET_CONFIGURATION_REQ_TYPE);
+ DEBUG ((EFI_D_INFO, "USB: Setting configuration.\n"));
+
+ // Configure endpoints
+ for (Index = 0; Index < mInterfaceDescriptor->NumEndpoints; Index++) {
+ EPDesc = &mEndpointDescriptors[Index];
+
+ // To simplify for now, assume endpoints aren't "sparse", and are in order.
+ ASSERT ((EPDesc->EndpointAddress & 0xF) == ((Index / 2) + 1));
+
+ // Convert from USB endpoint index to ISP1761 endpoint Index
+ // USB: Endpoint number is bits [3:0], IN/OUT is bit [7]
+ // ISP1761: Endpoint number is bits [4:1], IN/OUT is bit [0]
+ EndpointIndex = ((EPDesc->EndpointAddress & 0xF) << 1) |
+ ((EPDesc->EndpointAddress & BIT7) >> 7);
+ SelectEndpoint (EndpointIndex);
+ // Set endpoint type (Bulk/Isochronous/Interrupt)
+ WRITE_REG32 (ISP1761_ENDPOINT_MAX_PACKET_SIZE, EPDesc->MaxPacketSize);
+ // Hardware foible (bug?): Although the datasheet seems to suggest it should
+ // automatically be set to MaxPacketSize, the Buffer Length register appears
+ // to be reset to 0, which causes an empty packet to be sent in response to
+ // the first IN token of the session. The NOEMPKT field of the Endpoint Type
+ // register sounds like it might fix this problem, but it doesn't
+ // (it's "applicable only in the DMA mode").
+ WRITE_REG32 (ISP1761_BUFFER_LENGTH, EPDesc->MaxPacketSize);
+ WRITE_REG32 (ISP1761_ENDPOINT_TYPE, (EPDesc->Attributes & 0x3) |
+ ISP1761_ENDPOINT_TYPE_ENABLE);
+ }
+
+ StatusAcknowledge (ISP1761_EP0TX);
+ return EFI_SUCCESS;
+}
+
+STATIC
+EFI_STATUS
+HandleDeviceRequest (
+ IN USB_DEVICE_REQUEST *Request
+ )
+{
+ EFI_STATUS Status;
+
+ Status = EFI_SUCCESS;
+
+ switch (Request->Request) {
+ case USB_DEV_GET_DESCRIPTOR:
+ Status = HandleGetDescriptor (Request);
+ break;
+ case USB_DEV_SET_ADDRESS:
+ Status = HandleSetAddress (Request);
+ break;
+ case USB_DEV_SET_CONFIGURATION:
+ Status = HandleSetConfiguration (Request);
+ break;
+ default:
+ DEBUG ((EFI_D_ERROR,
+ "Didn't understand RequestType 0x%x Request 0x%x\n",
+ Request->RequestType, Request->Request));
+ Status = EFI_INVALID_PARAMETER;
+ break;
+ }
+
+ return Status;
+}
+
+// Instead of actually registering interrupt handlers, we poll the controller's
+// interrupt source register in this function.
+STATIC
+VOID
+CheckInterrupts (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+{
+ UINT32 DcInterrupts;
+ UINTN NumBytes;
+ UINTN MoreBytes;
+ UINT8 Packet[512];
+ VOID *DataPacket;
+ UINT32 HandledInterrupts;
+ UINT32 UnhandledInterrupts;
+ EFI_STATUS Status;
+
+ // Set bits in HandledInterrupts to mark the interrupt source handled.
+ HandledInterrupts = 0;
+
+ WRITE_REG32 (ISP1761_DEVICE_UNLOCK, ISP1761_DEVICE_UNLOCK_MAGIC);
+
+ DcInterrupts = READ_REG32 (ISP1761_DC_INTERRUPT);
+ if (DcInterrupts & ISP1761_DC_INTERRUPT_SUSP) {
+ DEBUG ((EFI_D_INFO, "USB: Suspend\n"));
+ HandledInterrupts |= ISP1761_DC_INTERRUPT_SUSP;
+ }
+ if (DcInterrupts & ISP1761_DC_INTERRUPT_RESUME) {
+ DEBUG ((EFI_D_INFO, "USB: Resume\n"));
+ HandledInterrupts |= ISP1761_DC_INTERRUPT_RESUME;
+ }
+ if (DcInterrupts & ISP1761_DC_INTERRUPT_EP0SETUP) {
+ NumBytes = 512;
+ ReadEndpointBuffer (0x20, &NumBytes, &Packet);
+ ASSERT (NumBytes == 8);
+ HandleDeviceRequest ((USB_DEVICE_REQUEST *) Packet);
+ HandledInterrupts |= ISP1761_DC_INTERRUPT_EP0SETUP;
+ }
+ if (DcInterrupts & ISP1761_DC_INTERRUPT_EP0RX) {
+ HandledInterrupts |= ISP1761_DC_INTERRUPT_EP0RX;
+ }
+ if (DcInterrupts & ISP1761_DC_INTERRUPT_EP0TX) {
+ if (mControlTxPending) {
+ // We previously put some data in the Control Endpoint's IN (Tx) FIFO.
+ // We assume that that data has now been sent in response to the IN token
+ // that triggered this interrupt. We can therefore go to the Status stage
+ // of the control transfer.
+ StatusAcknowledge (ISP1761_EP0TX);
+ mControlTxPending = FALSE;
+ }
+ HandledInterrupts |= ISP1761_DC_INTERRUPT_EP0TX;
+ }
+ if (DcInterrupts & ISP1761_DC_INTERRUPT_EP1RX) {
+ NumBytes = 512;
+ DataPacket = AllocatePool (NumBytes);
+ Status = ReadEndpointBuffer (ISP1761_EP1RX, &NumBytes, DataPacket);
+ if (EFI_ERROR (Status) || NumBytes == 0) {
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR, "Couldn't read EP1RX data: %r\n", Status));
+ }
+ FreePool (DataPacket);
+ } else {
+ // Signal this event again so we poll again ASAP
+ gBS->SignalEvent (Event);
+ mDataReceivedCallback (NumBytes, DataPacket);
+ }
+ HandledInterrupts |= ISP1761_DC_INTERRUPT_EP1RX;
+ }
+ if (DcInterrupts & ISP1761_DC_INTERRUPT_EP1TX) {
+ mDataSentCallback (1);
+ HandledInterrupts |= ISP1761_DC_INTERRUPT_EP1TX;
+ }
+ if (DcInterrupts & (ISP1761_DC_INTERRUPT_SOF | ISP1761_DC_INTERRUPT_PSOF)) {
+ // Don't care about SOFs or pseudo-SOFs
+ HandledInterrupts |= (ISP1761_DC_INTERRUPT_SOF | ISP1761_DC_INTERRUPT_PSOF);
+ }
+ if (ISP1761_DC_INTERRUPT_BRESET) {
+ HandledInterrupts |= ISP1761_DC_INTERRUPT_BRESET;
+ }
+ if (ISP1761_DC_INTERRUPT_HS_STAT) {
+ HandledInterrupts |= ISP1761_DC_INTERRUPT_HS_STAT;
+ }
+ if (ISP1761_DC_INTERRUPT_VBUS) {
+ HandledInterrupts |= ISP1761_DC_INTERRUPT_VBUS;
+ }
+
+ UnhandledInterrupts = DcInterrupts & (~HandledInterrupts) & ISP1761_DC_INTERRUPT_MASK;
+ if (UnhandledInterrupts) {
+ DEBUG ((EFI_D_ERROR, "USB: Unhandled DC Interrupts: 0x%08x\n",
+ UnhandledInterrupts));
+ }
+
+ // Check if we received any more data while we were handling the interrupt.
+ SelectEndpoint (ISP1761_EP1RX);
+ MoreBytes = READ_REG16 (ISP1761_BUFFER_LENGTH);
+ if (MoreBytes) {
+ HandledInterrupts &= ~ISP1761_DC_INTERRUPT_EP1RX;
+ }
+
+ WRITE_REG32 (ISP1761_DC_INTERRUPT, HandledInterrupts);
+}
+
+EFI_STATUS
+Isp1761PeriphSend (
+ IN UINT8 EndpointIndex,
+ IN UINTN Size,
+ IN CONST VOID *Buffer
+ )
+{
+ return WriteEndpointBuffer (
+ (EndpointIndex << 1) | 0x1, //Convert to ISP1761 endpoint index, Tx
+ MAX_PACKET_SIZE_BULK,
+ Size,
+ Buffer
+ );
+}
+
+EFI_STATUS
+EFIAPI
+Isp1761PeriphStart (
+ IN USB_DEVICE_DESCRIPTOR *DeviceDescriptor,
+ IN VOID **Descriptors,
+ IN USB_DEVICE_RX_CALLBACK RxCallback,
+ IN USB_DEVICE_TX_CALLBACK TxCallback
+ )
+{
+ UINT16 OtgStatus;
+ UINT8 *Ptr;
+ EFI_STATUS Status;
+ EFI_EVENT TimerEvent;
+
+ ASSERT (DeviceDescriptor != NULL);
+ ASSERT (Descriptors[0] != NULL);
+ ASSERT (RxCallback != NULL);
+ ASSERT (TxCallback != NULL);
+
+ WRITE_REG32 (ISP1761_DEVICE_UNLOCK, ISP1761_DEVICE_UNLOCK_MAGIC);
+
+ WRITE_REG32 (ISP1761_SW_RESET_REG, ISP1761_SW_RESET_ALL);
+ while (READ_REG32 (ISP1761_SW_RESET_REG) & ISP1761_SW_RESET_ALL) {
+ //busy wait
+ }
+ WRITE_REG32 (ISP1761_MODE, ISP1761_MODE_SFRESET);
+ while (READ_REG32 (ISP1761_MODE) & ISP1761_MODE_SFRESET) {
+ //busy wait
+ }
+ DEBUG ((EFI_D_INFO, "USB: Software reset done\n"));
+
+ WRITE_REG32 (ISP1761_DC_INTERRUPT_ENABLE, 0x03FFFFFF);
+ WRITE_REG32 (ISP1761_OTG_INTERRUPT_ENABLE_RISE, 0x07FF);
+
+ WRITE_REG8 (ISP1761_ADDRESS, ISP1761_ADDRESS_DEVEN);
+ WRITE_REG8 (ISP1761_MODE, ISP1761_MODE_WKUPCS | ISP1761_MODE_CLKAON);
+
+ // Use port 1 as peripheral controller (magic - disagrees with datasheet)
+ WRITE_REG32 (ISP1761_OTG_CTRL_SET, 0xffff0000);
+ WRITE_REG32 (ISP1761_OTG_CTRL_SET, 0x000014d1);
+
+ OtgStatus = READ_REG16 (ISP1761_OTG_STATUS);
+ if ((OtgStatus & ISP1761_OTG_STATUS_B_SESS_END) != 0) {
+ DEBUG ((EFI_D_ERROR, "USB: Vbus not powered.\n"));
+ }
+ if ((OtgStatus & ISP1761_OTG_STATUS_A_B_SESS_VLD) == 0) {
+ DEBUG ((EFI_D_ERROR, "USB: Session not valid.\n"));
+ }
+
+ // Configure Control endpoints
+ SelectEndpoint (0x20);
+ WRITE_REG32 (ISP1761_ENDPOINT_MAX_PACKET_SIZE, MAX_PACKET_SIZE_CONTROL);
+ WRITE_REG32 (ISP1761_ENDPOINT_TYPE, ISP1761_ENDPOINT_TYPE_ENABLE);
+ SelectEndpoint (0x0);
+ WRITE_REG32 (ISP1761_ENDPOINT_MAX_PACKET_SIZE, MAX_PACKET_SIZE_CONTROL);
+ WRITE_REG32 (ISP1761_ENDPOINT_TYPE, ISP1761_ENDPOINT_TYPE_ENABLE);
+ SelectEndpoint (0x1);
+ WRITE_REG32 (ISP1761_ENDPOINT_MAX_PACKET_SIZE, MAX_PACKET_SIZE_CONTROL);
+ WRITE_REG32 (ISP1761_ENDPOINT_TYPE, ISP1761_ENDPOINT_TYPE_ENABLE);
+
+ // Interrupt on all ACK and NAK
+ WRITE_REG32 (ISP1761_INTERRUPT_CONFIG, ISP1761_INTERRUPT_CONFIG_ACK_ONLY);
+
+ mDeviceDescriptor = DeviceDescriptor;
+ mDescriptors = Descriptors[0];
+
+ // Right now we just support one configuration
+ ASSERT (mDeviceDescriptor->NumConfigurations == 1);
+ // ... and one interface
+ mConfigDescriptor = (USB_CONFIG_DESCRIPTOR *)mDescriptors;
+ ASSERT (mConfigDescriptor->NumInterfaces == 1);
+
+ Ptr = ((UINT8 *) mDescriptors) + sizeof (USB_CONFIG_DESCRIPTOR);
+ mInterfaceDescriptor = (USB_INTERFACE_DESCRIPTOR *) Ptr;
+ Ptr += sizeof (USB_INTERFACE_DESCRIPTOR);
+
+ mEndpointDescriptors = (USB_ENDPOINT_DESCRIPTOR *) Ptr;
+
+ mDataReceivedCallback = RxCallback;
+ mDataSentCallback = TxCallback;
+
+ // Register a timer event so CheckInterupts gets called periodically
+ Status = gBS->CreateEvent (
+ EVT_TIMER | EVT_NOTIFY_SIGNAL,
+ TPL_CALLBACK,
+ CheckInterrupts,
+ NULL,
+ &TimerEvent
+ );
+ ASSERT_EFI_ERROR (Status);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ Status = gBS->SetTimer (
+ TimerEvent,
+ TimerPeriodic,
+ ISP1761_INTERRUPT_POLL_PERIOD
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ return Status;
+}
+
+USB_DEVICE_PROTOCOL mUsbDevice = {
+ Isp1761PeriphStart,
+ Isp1761PeriphSend
+};
+
+
+EFI_STATUS
+EFIAPI
+Isp1761PeriphEntryPoint (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ UINT32 DeviceId;
+ EFI_HANDLE Handle;
+
+ DeviceId = READ_REG32 (ISP1761_DEVICE_ID);
+
+ if (DeviceId != ISP1761_DEVICE_ID_VAL) {
+ DEBUG ((EFI_D_ERROR,
+ "ERROR: Read incorrect device ID for ISP1761: 0x%08x, expected 0x%08x\n",
+ DeviceId , ISP1761_DEVICE_ID_VAL
+ ));
+ return EFI_DEVICE_ERROR;
+ }
+
+ Handle = NULL;
+ return gBS->InstallProtocolInterface (
+ &Handle,
+ &gUsbDeviceProtocolGuid,
+ EFI_NATIVE_INTERFACE,
+ &mUsbDevice
+ );
+}
diff --git a/EmbeddedPkg/Drivers/Isp1761UsbDxe/Isp1761UsbDxe.h b/EmbeddedPkg/Drivers/Isp1761UsbDxe/Isp1761UsbDxe.h
new file mode 100644
index 000000000..9e60e155d
--- /dev/null
+++ b/EmbeddedPkg/Drivers/Isp1761UsbDxe/Isp1761UsbDxe.h
@@ -0,0 +1,122 @@
+/** @file
+
+ Copyright (c) 2013-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.
+
+**/
+
+#ifndef __ISP1761_USB_DXE_H__
+#define __ISP1761_USB_DXE_H__
+
+#define ISP1761_USB_BASE FixedPcdGet32 (PcdIsp1761BaseAddress)
+
+#define READ_REG32(Offset) MmioRead32 (ISP1761_USB_BASE + Offset)
+#define READ_REG16(Offset) (UINT16) READ_REG32 (Offset)
+#define WRITE_REG32(Offset, Val) MmioWrite32 (ISP1761_USB_BASE + Offset, Val)
+#define WRITE_REG16(Offset, Val) MmioWrite32 (ISP1761_USB_BASE + Offset, (UINT32) Val)
+#define WRITE_REG8(Offset, Val) MmioWrite32 (ISP1761_USB_BASE + Offset, (UINT32) Val)
+
+// Max packet size in bytes (For Full Speed USB 64 is the only valid value)
+#define MAX_PACKET_SIZE_CONTROL 64
+
+#define MAX_PACKET_SIZE_BULK 512
+
+// 8 Endpoints, in and out. Don't count the Endpoint 0 setup buffer
+#define ISP1761_NUM_ENDPOINTS 16
+
+// Endpoint Indexes
+#define ISP1761_EP0SETUP 0x20
+#define ISP1761_EP0RX 0x00
+#define ISP1761_EP0TX 0x01
+#define ISP1761_EP1RX 0x02
+#define ISP1761_EP1TX 0x03
+
+// DcInterrupt bits
+#define ISP1761_DC_INTERRUPT_BRESET BIT0
+#define ISP1761_DC_INTERRUPT_SOF BIT1
+#define ISP1761_DC_INTERRUPT_PSOF BIT2
+#define ISP1761_DC_INTERRUPT_SUSP BIT3
+#define ISP1761_DC_INTERRUPT_RESUME BIT4
+#define ISP1761_DC_INTERRUPT_HS_STAT BIT5
+#define ISP1761_DC_INTERRUPT_DMA BIT6
+#define ISP1761_DC_INTERRUPT_VBUS BIT7
+#define ISP1761_DC_INTERRUPT_EP0SETUP BIT8
+#define ISP1761_DC_INTERRUPT_EP0RX BIT10
+#define ISP1761_DC_INTERRUPT_EP0TX BIT11
+#define ISP1761_DC_INTERRUPT_EP1RX BIT12
+#define ISP1761_DC_INTERRUPT_EP1TX BIT13
+// All valid peripheral controller interrupts
+#define ISP1761_DC_INTERRUPT_MASK 0x003FFFDFF
+
+#define ISP1761_ADDRESS 0x200
+#define ISP1761_ADDRESS_DEVEN BIT7
+
+#define ISP1761_MODE 0x20C
+#define ISP1761_MODE_DATA_BUS_WIDTH BIT8
+#define ISP1761_MODE_CLKAON BIT7
+#define ISP1761_MODE_SFRESET BIT4
+#define ISP1761_MODE_WKUPCS BIT2
+
+#define ISP1761_ENDPOINT_MAX_PACKET_SIZE 0x204
+
+#define ISP1761_ENDPOINT_TYPE 0x208
+#define ISP1761_ENDPOINT_TYPE_NOEMPKT BIT4
+#define ISP1761_ENDPOINT_TYPE_ENABLE BIT3
+
+#define ISP1761_INTERRUPT_CONFIG 0x210
+// Interrupt config value to only interrupt on ACK of IN and OUT tokens
+#define ISP1761_INTERRUPT_CONFIG_ACK_ONLY BIT2 | BIT5 | BIT6
+
+#define ISP1761_DC_INTERRUPT 0x218
+#define ISP1761_DC_INTERRUPT_ENABLE 0x214
+
+#define ISP1761_CTRL_FUNCTION 0x228
+#define ISP1761_CTRL_FUNCTION_VENDP BIT3
+#define ISP1761_CTRL_FUNCTION_DSEN BIT2
+#define ISP1761_CTRL_FUNCTION_STATUS BIT1
+
+#define ISP1761_DEVICE_UNLOCK 0x27C
+#define ISP1761_DEVICE_UNLOCK_MAGIC 0xAA37
+
+#define ISP1761_SW_RESET_REG 0x30C
+#define ISP1761_SW_RESET_ALL BIT0
+
+#define ISP1761_DEVICE_ID 0x370
+
+#define ISP1761_OTG_CTRL_SET 0x374
+#define ISP1761_OTG_CTRL_CLR OTG_CTRL_SET + 2
+#define ISP1761_OTG_CTRL_OTG_DISABLE BIT10
+#define ISP1761_OTG_CTRL_VBUS_CHRG BIT6
+#define ISP1761_OTG_CTRL_VBUS_DISCHRG BIT5
+#define ISP1761_OTG_CTRL_DM_PULLDOWN BIT2
+#define ISP1761_OTG_CTRL_DP_PULLDOWN BIT1
+#define ISP1761_OTG_CTRL_DP_PULLUP BIT0
+
+#define ISP1761_OTG_STATUS 0x378
+#define ISP1761_OTG_STATUS_B_SESS_END BIT7
+#define ISP1761_OTG_STATUS_A_B_SESS_VLD BIT1
+
+#define ISP1761_OTG_INTERRUPT_LATCH_SET 0x37C
+#define ISP1761_OTG_INTERRUPT_LATCH_CLR 0x37E
+#define ISP1761_OTG_INTERRUPT_ENABLE_RISE 0x384
+
+#define ISP1761_DMA_ENDPOINT_INDEX 0x258
+
+#define ISP1761_ENDPOINT_INDEX 0x22c
+#define ISP1761_DATA_PORT 0x220
+#define ISP1761_BUFFER_LENGTH 0x21c
+
+// Device ID Values
+#define PHILLIPS_VENDOR_ID_VAL 0x04cc
+#define ISP1761_PRODUCT_ID_VAL 0x1761
+#define ISP1761_DEVICE_ID_VAL ((ISP1761_PRODUCT_ID_VAL << 16) |\
+ PHILLIPS_VENDOR_ID_VAL)
+
+#endif //ifndef __ISP1761_USB_DXE_H__
diff --git a/EmbeddedPkg/Drivers/Isp1761UsbDxe/Isp1761UsbDxe.inf b/EmbeddedPkg/Drivers/Isp1761UsbDxe/Isp1761UsbDxe.inf
new file mode 100644
index 000000000..28a41b5d5
--- /dev/null
+++ b/EmbeddedPkg/Drivers/Isp1761UsbDxe/Isp1761UsbDxe.inf
@@ -0,0 +1,44 @@
+#/** @file
+#
+# Copyright (c) 2013-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 = Isp1761PeriphDxe
+ FILE_GUID = 72d78ea6-4dee-11e3-8100-f3842a48d0a0
+ MODULE_TYPE = UEFI_DRIVER
+ VERSION_STRING = 1.0
+ ENTRY_POINT = Isp1761PeriphEntryPoint
+
+[Sources.common]
+ Isp1761UsbDxe.c
+
+[LibraryClasses]
+ DebugLib
+ IoLib
+ MemoryAllocationLib
+ TimerLib
+ UefiBootServicesTableLib
+ UefiDriverEntryPoint
+
+[Protocols]
+ gEfiDriverBindingProtocolGuid
+ gUsbDeviceProtocolGuid
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ EmbeddedPkg/EmbeddedPkg.dec
+
+[Pcd]
+ gEmbeddedTokenSpaceGuid.PcdIsp1761BaseAddress \ No newline at end of file
diff --git a/EmbeddedPkg/EmbeddedPkg.dec b/EmbeddedPkg/EmbeddedPkg.dec
index 1b8ef158a..c219befc3 100644
--- a/EmbeddedPkg/EmbeddedPkg.dec
+++ b/EmbeddedPkg/EmbeddedPkg.dec
@@ -3,6 +3,7 @@
#
# This Package provides headers and libraries that conform to EFI/PI Industry standards.
# Copyright (c) 2007, Intel Corporation. All rights reserved.<BR>
+# Copyright (c) 2012-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.
@@ -57,7 +58,10 @@
gEmbeddedGpioProtocolGuid = { 0x17a0a3d7, 0xc0a5, 0x4635, { 0xbb, 0xd5, 0x07, 0x21, 0x87, 0xdf, 0xe2, 0xee }}
gPeCoffLoaderProtocolGuid = { 0xB323179B, 0x97FB, 0x477E, { 0xB0, 0xFE, 0xD8, 0x85, 0x91, 0xFA, 0x11, 0xAB } }
gEfiMmcHostProtocolGuid = { 0x3e591c00, 0x9e4a, 0x11df, {0x92, 0x44, 0x00, 0x02, 0xA5, 0xD5, 0xC5, 0x1B }}
-
+ gAndroidFastbootTransportProtocolGuid = { 0x74bd9fe0, 0x8902, 0x11e3, {0xb9, 0xd3, 0xf7, 0x22, 0x38, 0xfc, 0x9a, 0x31}}
+ gAndroidFastbootPlatformProtocolGuid = { 0x524685a0, 0x89a0, 0x11e3, {0x9d, 0x4d, 0xbf, 0xa9, 0xf6, 0xa4, 0x03, 0x08}}
+ gUsbDeviceProtocolGuid = { 0x021bd2ca, 0x51d2, 0x11e3, {0x8e, 0x56, 0xb7, 0x54, 0x17, 0xc7, 0x0b, 0x44 }}
+
[PcdsFeatureFlag.common]
gEmbeddedTokenSpaceGuid.PcdEmbeddedMacBoot|FALSE|BOOLEAN|0x00000001
gEmbeddedTokenSpaceGuid.PcdEmbeddedDirCmd|TRUE|BOOLEAN|0x00000002
@@ -125,14 +129,30 @@
gEmbeddedTokenSpaceGuid.PcdGdbMaxPacketRetryCount|10000000|UINT32|0x0000004c
gEmbeddedTokenSpaceGuid.PcdGdbTimerPeriodMilliseconds|250|UINT32|0x0000004d
+ #
+ # Android FastBoot
+ #
+
+ # The Android FastBoot utility has hard-coded USB Vendor IDs that it recognises
+ # (and 0xf00d isn't one of them!).
+ # You'll need to pass it "-i 0xf00d" to get it to recognise this device.
+ gEmbeddedTokenSpaceGuid.PcdAndroidFastbootUsbVendorId|0xf00d|UINT32|0x00000022
+ gEmbeddedTokenSpaceGuid.PcdAndroidFastbootUsbProductId|0xbeef|UINT32|0x00000023
+
[PcdsFixedAtBuild.ARM]
gEmbeddedTokenSpaceGuid.PcdPrePiCpuMemorySize|32|UINT8|0x00000010
gEmbeddedTokenSpaceGuid.PcdPrePiCpuIoSize|0|UINT8|0x00000011
+ # ISP1761 USB OTG Controller
+ gEmbeddedTokenSpaceGuid.PcdIsp1761BaseAddress|0|UINT32|0x00000021
+
[PcdsFixedAtBuild.AARCH64]
gEmbeddedTokenSpaceGuid.PcdPrePiCpuMemorySize|48|UINT8|0x00000010
gEmbeddedTokenSpaceGuid.PcdPrePiCpuIoSize|0|UINT8|0x00000011
+ # ISP1761 USB OTG Controller
+ gEmbeddedTokenSpaceGuid.PcdIsp1761BaseAddress|0|UINT64|0x00000021
+
[PcdsFixedAtBuild.IA32]
gEmbeddedTokenSpaceGuid.PcdPrePiCpuMemorySize|36|UINT8|0x00000010
gEmbeddedTokenSpaceGuid.PcdPrePiCpuIoSize|16|UINT8|0x00000011
diff --git a/EmbeddedPkg/EmbeddedPkg.dsc b/EmbeddedPkg/EmbeddedPkg.dsc
index 9eaf7dc97..fadcec0f5 100644
--- a/EmbeddedPkg/EmbeddedPkg.dsc
+++ b/EmbeddedPkg/EmbeddedPkg.dsc
@@ -93,12 +93,12 @@
UefiDriverEntryPoint|MdePkg/Library/UefiDriverEntryPoint/UefiDriverEntryPoint.inf
UefiApplicationEntryPoint|MdePkg/Library/UefiApplicationEntryPoint/UefiApplicationEntryPoint.inf
-
PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
EblCmdLib|EmbeddedPkg/Library/EblCmdLibNull/EblCmdLibNull.inf
EblNetworkLib|EmbeddedPkg/Library/EblNetworkLib/EblNetworkLib.inf
-
+
+ FdtLib|EmbeddedPkg/Library/FdtLib/FdtLib.inf
[LibraryClasses.common.DXE_DRIVER]
PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf
@@ -117,9 +117,18 @@
ExtractGuidedSectionLib|EmbeddedPkg/Library/PrePiExtractGuidedSectionLib/PrePiExtractGuidedSectionLib.inf
[LibraryClasses.ARM, LibraryClasses.AARCH64]
+ ArmGicLib|ArmPkg/Drivers/ArmGic/ArmGicLib.inf
+ ArmSmcLib|ArmPkg/Library/ArmSmcLib/ArmSmcLib.inf
+ BdsLib|ArmPkg/Library/BdsLib/BdsLib.inf
SemihostLib|ArmPkg/Library/SemihostLib/SemihostLib.inf
NULL|ArmPkg/Library/CompilerIntrinsicsLib/CompilerIntrinsicsLib.inf
+[LibraryClasses.ARM]
+ ArmLib|ArmPkg/Library/ArmLib/ArmV7/ArmV7Lib.inf
+
+[LibraryClasses.AARCH64]
+ ArmLib|ArmPkg/Library/ArmLib/AArch64/AArch64Lib.inf
+
################################################################################
#
@@ -211,6 +220,9 @@
# RELEASE_*_IA32_DLINK_FLAGS = /ALIGN:4096
# *_*_IA32_CC_FLAGS = /D EFI_SPECIFICATION_VERSION=0x0002000A /D TIANO_RELEASE_VERSION=0x00080006
+[BuildOptions]
+ RVCT:*_*_ARM_PLATFORM_FLAGS == --cpu=7-A.security
+
################################################################################
#
@@ -242,5 +254,11 @@
EmbeddedPkg/Universal/MmcDxe/MmcDxe.inf
+ EmbeddedPkg/Application/AndroidFastboot/AndroidFastbootApp.inf
+ EmbeddedPkg/Drivers/AndroidFastbootTransportUsbDxe/FastbootTransportUsbDxe.inf
+
+ # Drivers
+ EmbeddedPkg/Drivers/Isp1761UsbDxe/Isp1761UsbDxe.inf
+
[Components.IA32, Components.X64, Components.IPF, Components.ARM]
EmbeddedPkg/GdbStub/GdbStub.inf
diff --git a/EmbeddedPkg/Include/Protocol/AndroidFastbootPlatform.h b/EmbeddedPkg/Include/Protocol/AndroidFastbootPlatform.h
new file mode 100644
index 000000000..a9b4aac48
--- /dev/null
+++ b/EmbeddedPkg/Include/Protocol/AndroidFastbootPlatform.h
@@ -0,0 +1,145 @@
+/** @file
+
+ 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.
+
+**/
+
+#ifndef __ANDROID_FASTBOOT_PLATFORM_H__
+#define __ANDROID_FASTBOOT_PLATFORM_H__
+
+extern EFI_GUID gAndroidFastbootPlatformProtocolGuid;
+
+/*
+ Protocol for platform-specific operations initiated by Android Fastboot.
+
+ Based on Fastboot Protocol version 0.4. See
+ system/core/fastboot/fastboot_protocol.txt in the AOSP source tree for more
+ info.
+
+ Doesn't support image verification.
+*/
+
+/*
+ Do any initialisation that needs to be done in order to be able to respond to
+ commands.
+
+ @retval EFI_SUCCESS Initialised successfully.
+ @retval !EFI_SUCCESS Error in initialisation.
+*/
+typedef
+EFI_STATUS
+(*FASTBOOT_PLATFORM_INIT) (
+ VOID
+ );
+
+/*
+ To be called when Fastboot is finished and we aren't rebooting or booting an
+ image. Undo initialisation, free resrouces.
+*/
+typedef
+VOID
+(*FASTBOOT_PLATFORM_UN_INIT) (
+ VOID
+ );
+
+/*
+ Flash the partition named (according to a platform-specific scheme)
+ PartitionName, with the image pointed to by Buffer, whose size is BufferSize.
+
+ @param[in] PartitionName Null-terminated name of partition to write.
+ @param[in] BufferSize Size of Buffer in byets.
+ @param[in] Buffer Data to write to partition.
+
+ @retval EFI_NOT_FOUND No such partition.
+ @retval EFI_DEVICE_ERROR Flashing failed.
+*/
+typedef
+EFI_STATUS
+(*FASTBOOT_PLATFORM_FLASH) (
+ IN CHAR8 *PartitionName,
+ IN UINTN BufferSize,
+ IN VOID *Buffer
+ );
+
+/*
+ Erase the partition named PartitionName.
+
+ @param[in] PartitionName Null-terminated name of partition to erase.
+
+ @retval EFI_NOT_FOUND No such partition.
+ @retval EFI_DEVICE_ERROR Erasing failed.
+*/
+typedef
+EFI_STATUS
+(*FASTBOOT_PLATFORM_ERASE) (
+ IN CHAR8 *PartitionName
+ );
+
+/*
+ If the variable referred to by Name exists, copy it (as a null-terminated
+ string) into Value. If it doesn't exist, put the Empty string in Value.
+
+ Variable names and values may not be larger than 60 bytes, excluding the
+ terminal null character. This is a limitation of the Fastboot protocol.
+
+ The Fastboot application will handle platform-nonspecific variables
+ (Currently "version" is the only one of these.)
+
+ @param[in] Name Null-terminated name of Fastboot variable to retrieve.
+ @param[out] Value Caller-allocated buffer for null-terminated value of
+ variable.
+
+ @retval EFI_SUCCESS The variable was retrieved, or it doesn't exist.
+ @retval EFI_DEVICE_ERROR There was an error looking up the variable. This
+ does _not_ include the variable not existing.
+*/
+typedef
+EFI_STATUS
+(*FASTBOOT_PLATFORM_GETVAR) (
+ IN CHAR8 *Name,
+ OUT CHAR8 *Value
+ );
+
+/*
+ React to an OEM-specific command.
+
+ Future versions of this function might want to allow the platform to do some
+ extra communication with the host. A way to do this would be to add a function
+ to the FASTBOOT_TRANSPORT_PROTOCOL that allows the implementation of
+ DoOemCommand to replace the ReceiveEvent with its own, and to restore the old
+ one when it's finished.
+
+ However at the moment although the specification allows it, the AOSP fastboot
+ host application doesn't handle receiving any data from the client, and it
+ doesn't support a data phase for OEM commands.
+
+ @param[in] Command Null-terminated command string.
+
+ @retval EFI_SUCCESS The command executed successfully.
+ @retval EFI_NOT_FOUND The command wasn't recognised.
+ @retval EFI_DEVICE_ERROR There was an error executing the command.
+*/
+typedef
+EFI_STATUS
+(*FASTBOOT_PLATFORM_OEM_COMMAND) (
+ IN CHAR8 *Command
+ );
+
+typedef struct _FASTBOOT_PLATFORM_PROTOCOL {
+ FASTBOOT_PLATFORM_INIT Init;
+ FASTBOOT_PLATFORM_UN_INIT UnInit;
+ FASTBOOT_PLATFORM_FLASH FlashPartition;
+ FASTBOOT_PLATFORM_ERASE ErasePartition;
+ FASTBOOT_PLATFORM_GETVAR GetVar;
+ FASTBOOT_PLATFORM_OEM_COMMAND DoOemCommand;
+} FASTBOOT_PLATFORM_PROTOCOL;
+
+#endif
diff --git a/EmbeddedPkg/Include/Protocol/AndroidFastbootTransport.h b/EmbeddedPkg/Include/Protocol/AndroidFastbootTransport.h
new file mode 100644
index 000000000..807068717
--- /dev/null
+++ b/EmbeddedPkg/Include/Protocol/AndroidFastbootTransport.h
@@ -0,0 +1,131 @@
+/** @file
+
+ 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.
+
+**/
+
+/*
+ Transport protocol over which Android Fastboot transactions can be made.
+ Fastboot is designed for USB, but this protocol is intended as an abstraction
+ so that it can be implemented over any transport mechanism.
+*/
+
+#ifndef __ANDROID_FASTBOOT_TRANSPORT_H__
+#define __ANDROID_FASTBOOT_TRANSPORT_H__
+
+extern EFI_GUID gAndroidFastbootTransportProtocolGuid;
+
+/*
+ Set up the transport system for use by Fastboot.
+ e.g. For USB this probably means making the device enumerable. For TCP,
+ preparing to accept incoming connections.
+
+ It is _not_ the responsibility of this protocol's implementer to unite the
+ data phase into a single buffer - that is handled by the Fastboot UEFI
+ application. As the Fastboot protocol spec says: "Short packets are always
+ acceptable and zero-length packets are ignored."
+ However the commands and responses must be in a single packet, and the order
+ of the packets must of course be maintained.
+
+ If there is a fatal error in the receive channel, ReceiveEvent will be
+ signalled, and a subsequent call to Receive() will return an error. This
+ allows data transported prior to the error to be received.
+
+ @param[in] ReceiveEvent Event to be Signalled when a packet has been received
+ and is ready to be retrieved via Receive().
+
+ @retval EFI_SUCCESS Initialised successfully.
+ @retval EFI_DEVICE_ERROR Error in initialising hardware
+ @retval (other) Error return from LocateProtocol functions.
+*/
+typedef
+EFI_STATUS
+(*FASTBOOT_TRANSPORT_START) (
+ IN EFI_EVENT ReceiveEvent
+ );
+
+/*
+ Function to be called when all Fastboot transactions are finished, to
+ de-initialise the transport system.
+ e.g. A USB OTG system might want to get out of peripheral mode so it can be
+ a USB host.
+
+ Note that this function will be called after an error is reported by Send or
+ Receive
+
+ @retval EFI_SUCCESS De-initialised successfully.
+ @retval EFI_DEVICE_ERROR Error de-initialising hardware.
+*/
+typedef
+EFI_STATUS
+(* FASTBOOT_TRANSPORT_STOP) (
+ VOID
+ );
+
+/*
+ Send data. This function can be used both for command responses like "OKAY"
+ and for the data phase (the protocol doesn't describe any situation when the
+ latter might be necessary, but does allow it)
+
+ Transmission need not finish before the function returns.
+ If there is an error in transmission from which the transport system cannot
+ recover, FatalErrorEvent will be signalled. Otherwise, it is assumed that all
+ data was delivered successfully.
+
+ @param[in] BufferSize Size in bytes of data to send.
+ @param[in] Buffer Data to send.
+ @param[in] FatalErrorEvent Event to signal if there was an error in
+ transmission from which the transport system
+ cannot recover.
+
+ @retval EFI_SUCCESS The data was sent or queued for send.
+ @retval EFI_DEVICE_ERROR There was an error preparing to send the data.
+ */
+typedef
+EFI_STATUS
+(*FASTBOOT_TRANSPORT_SEND) (
+ IN UINTN BufferSize,
+ IN CONST VOID *Buffer,
+ IN EFI_EVENT *FatalErrorEvent
+ );
+
+/*
+ When the event has been Signalled to say data is available from the host,
+ this function is used to get data. In order to handle the case where several
+ packets are received before ReceiveEvent's notify function is called, packets
+ received are queued, and each call to this function returns the next packet in
+ the queue. It should therefore be called in a loop, the exit condition being a
+ return of EFI_NOT_READY.
+
+ @param[out] Buffer Pointer to received data. Callee allocated - the
+ caller must free it with FreePool.
+ @param[out] BufferSize The size of received data in bytes
+
+ @retval EFI_NOT_READY There is no data available
+ @retval EFI_DEVICE_ERROR There was a fatal error in the receive channel.
+ e.g. for USB the cable was unplugged or for TCP the
+ connection was closed by the remote host..
+*/
+typedef
+EFI_STATUS
+(*FASTBOOT_TRANSPORT_RECEIVE) (
+ OUT UINTN *BufferSize,
+ OUT VOID **Buffer
+ );
+
+typedef struct _FASTBOOT_TRANSPORT_PROTOCOL {
+ FASTBOOT_TRANSPORT_START Start;
+ FASTBOOT_TRANSPORT_STOP Stop;
+ FASTBOOT_TRANSPORT_SEND Send;
+ FASTBOOT_TRANSPORT_RECEIVE Receive;
+} FASTBOOT_TRANSPORT_PROTOCOL;
+
+#endif
diff --git a/EmbeddedPkg/Include/Protocol/UsbDevice.h b/EmbeddedPkg/Include/Protocol/UsbDevice.h
new file mode 100644
index 000000000..13a48dda0
--- /dev/null
+++ b/EmbeddedPkg/Include/Protocol/UsbDevice.h
@@ -0,0 +1,118 @@
+/** @file
+
+ Copyright (c) 2013-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.
+
+**/
+
+#ifndef __USB_DEVICE_PROTOCOL_H__
+#define __USB_DEVICE_PROTOCOL_H__
+
+#include <IndustryStandard/Usb.h>
+
+extern EFI_GUID gUsbDeviceProtocolGuid;
+
+/*
+ * Note: This Protocol is just the bare minimum for Android Fastboot. It
+ * only makes sense for devices that only do Bulk Transfers and only have one
+ * endpoint.
+ */
+
+/*
+ Callback to be called when data is received.
+ Buffer is callee-allocated and it's the caller's responsibility to free it with
+ FreePool.
+
+ @param[in] Size Size in bytes of data.
+ @param[in] Buffer Pointer to data.
+*/
+typedef
+VOID
+(*USB_DEVICE_RX_CALLBACK) (
+ IN UINTN Size,
+ IN VOID *Buffer
+ );
+
+/*
+ Callback to be called when the host asks for data by sending an IN token
+ (excluding during the data stage of a control transfer).
+ When this function is called, data previously buffered by calling Send() has
+ been sent.
+
+ @param[in]Endpoint Endpoint index, as specified in endpoint descriptors, of
+ the endpoint the IN token was sent to.
+*/
+typedef
+VOID
+(*USB_DEVICE_TX_CALLBACK) (
+ IN UINT8 EndpointIndex
+ );
+
+/*
+ Put data in the Tx buffer to be sent on the next IN token.
+ Don't call this function again until the TxCallback has been called.
+
+ @param[in]Endpoint Endpoint index, as specified in endpoint descriptors, of
+ the endpoint to send the data from.
+ @param[in]Size Size in bytes of data.
+ @param[in]Buffer Pointer to data.
+
+ @retval EFI_SUCCESS The data was queued successfully.
+ @retval EFI_INVALID_PARAMETER There was an error sending the data.
+*/
+typedef
+EFI_STATUS
+(*USB_DEVICE_SEND) (
+ IN UINT8 EndpointIndex,
+ IN UINTN Size,
+ IN CONST VOID *Buffer
+ );
+
+/*
+ Restart the USB peripheral controller and respond to enumeration.
+
+ @param[in] DeviceDescriptor pointer to device descriptor
+ @param[in] Descriptors Array of pointers to buffers, where
+ Descriptors[n] contains the response to a
+ GET_DESCRIPTOR request for configuration n. From
+ USB Spec section 9.4.3:
+ "The first interface descriptor follows the
+ configuration descriptor. The endpoint
+ descriptors for the first interface follow the
+ first interface descriptor. If there are
+ additional interfaces, their interface
+ descriptor and endpoint descriptors follow the
+ first interface’s endpoint descriptors".
+
+ The size of each buffer is the TotalLength
+ member of the Configuration Descriptor.
+
+ The size of the array is
+ DeviceDescriptor->NumConfigurations.
+ @param[in]RxCallback See USB_DEVICE_RX_CALLBACK
+ @param[in]TxCallback See USB_DEVICE_TX_CALLBACK
+*/
+typedef
+EFI_STATUS
+(*USB_DEVICE_START) (
+ IN USB_DEVICE_DESCRIPTOR *DeviceDescriptor,
+ IN VOID **Descriptors,
+ IN USB_DEVICE_RX_CALLBACK RxCallback,
+ IN USB_DEVICE_TX_CALLBACK TxCallback
+ );
+
+struct _USB_DEVICE_PROTOCOL {
+ USB_DEVICE_START Start;
+ USB_DEVICE_SEND Send;
+};
+
+typedef struct _USB_DEVICE_PROTOCOL USB_DEVICE_PROTOCOL;
+
+#endif //ifndef __USB_DEVICE_PROTOCOL_H__
diff --git a/IntelFrameworkModulePkg/Csm/LegacyBiosDxe/LegacyBootSupport.c b/IntelFrameworkModulePkg/Csm/LegacyBiosDxe/LegacyBootSupport.c
index bf2760550..8120ef765 100644
--- a/IntelFrameworkModulePkg/Csm/LegacyBiosDxe/LegacyBootSupport.c
+++ b/IntelFrameworkModulePkg/Csm/LegacyBiosDxe/LegacyBootSupport.c
@@ -1,6 +1,6 @@
/** @file
-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
@@ -2101,7 +2101,7 @@ LegacyBiosCompleteStandardCmosBeforeBoot (
//
// redo memory size since it can change
//
- Size = 15 * SIZE_1MB;
+ Size = (15 * SIZE_1MB) >> 10;
if (Private->IntThunk->EfiToLegacy16InitTable.OsMemoryAbove1Mb < (15 * SIZE_1MB)) {
Size = Private->IntThunk->EfiToLegacy16InitTable.OsMemoryAbove1Mb >> 10;
}
diff --git a/IntelFrameworkModulePkg/Library/GenericBdsLib/BdsBoot.c b/IntelFrameworkModulePkg/Library/GenericBdsLib/BdsBoot.c
index 3701434ef..134833286 100644
--- a/IntelFrameworkModulePkg/Library/GenericBdsLib/BdsBoot.c
+++ b/IntelFrameworkModulePkg/Library/GenericBdsLib/BdsBoot.c
@@ -1,7 +1,7 @@
/** @file
BDS Lib functions which relate with create or process the boot option.
-Copyright (c) 2004 - 2013, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2004 - 2014, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
@@ -82,6 +82,10 @@ BdsDeleteBootOption (
0,
NULL
);
+ //
+ // Deleting variable with existing variable implementation shouldn't fail.
+ //
+ ASSERT_EFI_ERROR (Status);
//
// adjust boot order array
@@ -626,6 +630,10 @@ BdsDeleteAllInvalidLegacyBootOptions (
BootOrderSize,
BootOrder
);
+ //
+ // Shrinking variable with existing variable implementation shouldn't fail.
+ //
+ ASSERT_EFI_ERROR (Status);
if (BootOrder != NULL) {
FreePool (BootOrder);
}
@@ -857,11 +865,10 @@ BdsAddNonExistingLegacyBootOptions (
&BootOrder,
&BootOrderSize
);
- if (EFI_ERROR (Status)) {
- break;
+ if (!EFI_ERROR (Status)) {
+ BbsIndex = Index;
+ OptionNumber = BootOrder[BootOrderSize / sizeof (UINT16) - 1];
}
- BbsIndex = Index;
- OptionNumber = BootOrder[BootOrderSize / sizeof (UINT16) - 1];
}
ASSERT (BbsIndex == Index);
@@ -2265,7 +2272,7 @@ BdsLibBootViaBootOption (
// In this case, "BootCurrent" is not created.
// Only create the BootCurrent variable when it points to a valid Boot#### variable.
//
- gRT->SetVariable (
+ SetVariableAndReportStatusCodeOnError (
L"BootCurrent",
&gEfiGlobalVariableGuid,
EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
@@ -2463,13 +2470,14 @@ Done:
//
// Clear Boot Current
+ // Deleting variable with current implementation shouldn't fail.
//
gRT->SetVariable (
L"BootCurrent",
&gEfiGlobalVariableGuid,
EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
0,
- &Option->BootCurrent
+ NULL
);
return Status;
@@ -2580,6 +2588,7 @@ BdsExpandPartitionPartialDevicePathToFull (
FreePool (TempNewDevicePath);
//
// Save the matching Device Path so we don't need to do a connect all next time
+ // Failure to set the variable only impacts the performance when next time expanding the short-form device path.
//
Status = gRT->SetVariable (
HD_BOOT_DEVICE_PATH_VARIABLE_NAME,
@@ -2678,6 +2687,7 @@ BdsExpandPartitionPartialDevicePathToFull (
//
// Save the matching Device Path so we don't need to do a connect all next time
+ // Failure to set the variable only impacts the performance when next time expanding the short-form device path.
//
Status = gRT->SetVariable (
HD_BOOT_DEVICE_PATH_VARIABLE_NAME,
@@ -2887,6 +2897,10 @@ BdsLibDeleteOptionFromHandle (
BootOrderSize,
BootOrder
);
+ //
+ // Shrinking variable with existing variable implementation shouldn't fail.
+ //
+ ASSERT_EFI_ERROR (Status);
FreePool (BootOrder);
@@ -2985,6 +2999,10 @@ BdsDeleteAllInvalidEfiBootOption (
NULL
);
//
+ // Deleting variable with current variable implementation shouldn't fail.
+ //
+ ASSERT_EFI_ERROR (Status);
+ //
// Mark this boot option in boot order as deleted
//
BootOrder[Index] = 0xffff;
@@ -3012,6 +3030,10 @@ BdsDeleteAllInvalidEfiBootOption (
Index2 * sizeof (UINT16),
BootOrder
);
+ //
+ // Shrinking variable with current variable implementation shouldn't fail.
+ //
+ ASSERT_EFI_ERROR (Status);
FreePool (BootOrder);
@@ -3135,7 +3157,9 @@ BdsLibEnumerateAllBootOption (
AsciiStrSize (PlatLang),
PlatLang
);
- ASSERT_EFI_ERROR (Status);
+ //
+ // Failure to set the variable only impacts the performance next time enumerating the boot options.
+ //
if (LastLang != NULL) {
FreePool (LastLang);
@@ -3478,6 +3502,7 @@ BdsLibBootNext (
VOID
)
{
+ EFI_STATUS Status;
UINT16 *BootNext;
UINTN BootNextSize;
CHAR16 Buffer[20];
@@ -3502,13 +3527,17 @@ BdsLibBootNext (
// Clear the boot next variable first
//
if (BootNext != NULL) {
- gRT->SetVariable (
- L"BootNext",
- &gEfiGlobalVariableGuid,
- EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
- 0,
- BootNext
- );
+ Status = gRT->SetVariable (
+ L"BootNext",
+ &gEfiGlobalVariableGuid,
+ EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
+ 0,
+ NULL
+ );
+ //
+ // Deleting variable with current variable implementation shouldn't fail.
+ //
+ ASSERT_EFI_ERROR (Status);
//
// Start to build the boot option and try to boot
diff --git a/IntelFrameworkModulePkg/Library/GenericBdsLib/BdsConsole.c b/IntelFrameworkModulePkg/Library/GenericBdsLib/BdsConsole.c
index 84e4a0e6b..271093eec 100644
--- a/IntelFrameworkModulePkg/Library/GenericBdsLib/BdsConsole.c
+++ b/IntelFrameworkModulePkg/Library/GenericBdsLib/BdsConsole.c
@@ -1,7 +1,7 @@
/** @file
BDS Lib functions which contain all the code to connect console device
-Copyright (c) 2004 - 2013, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2004 - 2014, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
@@ -285,17 +285,16 @@ BdsLibUpdateConsoleVariable (
// Finally, Update the variable of the default console by NewDevicePath
//
DevicePathSize = GetDevicePathSize (NewDevicePath);
- Status = gRT->SetVariable (
- ConVarName,
- &gEfiGlobalVariableGuid,
- Attributes,
- DevicePathSize,
- NewDevicePath
- );
+ Status = SetVariableAndReportStatusCodeOnError (
+ ConVarName,
+ &gEfiGlobalVariableGuid,
+ Attributes,
+ DevicePathSize,
+ NewDevicePath
+ );
if ((DevicePathSize == 0) && (Status == EFI_NOT_FOUND)) {
Status = EFI_SUCCESS;
}
- ASSERT_EFI_ERROR (Status);
if (VarConsole == NewDevicePath) {
if (VarConsole != NULL) {
diff --git a/IntelFrameworkModulePkg/Library/GenericBdsLib/BdsMisc.c b/IntelFrameworkModulePkg/Library/GenericBdsLib/BdsMisc.c
index 971188bd0..7b3f2050a 100644
--- a/IntelFrameworkModulePkg/Library/GenericBdsLib/BdsMisc.c
+++ b/IntelFrameworkModulePkg/Library/GenericBdsLib/BdsMisc.c
@@ -1,7 +1,7 @@
/** @file
Misc BDS library function
-Copyright (c) 2004 - 2012, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2004 - 2014, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
@@ -217,6 +217,9 @@ BdsLibRegisterNewOption (
UINT16 BootOrderEntry;
UINTN OrderItemNum;
+ if (DevicePath == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
OptionPtr = NULL;
OptionSize = 0;
@@ -1419,22 +1422,26 @@ BdsSetMemoryTypeInformationVariable (
// Or create the variable in first boot.
//
if (MemoryTypeInformationModified || !MemoryTypeInformationVariableExists) {
- Status = gRT->SetVariable (
- EFI_MEMORY_TYPE_INFORMATION_VARIABLE_NAME,
- &gEfiMemoryTypeInformationGuid,
- EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
- VariableSize,
- PreviousMemoryTypeInformation
- );
+ Status = SetVariableAndReportStatusCodeOnError (
+ EFI_MEMORY_TYPE_INFORMATION_VARIABLE_NAME,
+ &gEfiMemoryTypeInformationGuid,
+ EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,
+ VariableSize,
+ PreviousMemoryTypeInformation
+ );
- //
- // If the Memory Type Information settings have been modified, then reset the platform
- // so the new Memory Type Information setting will be used to guarantee that an S4
- // entry/resume cycle will not fail.
- //
- if (MemoryTypeInformationModified && PcdGetBool (PcdResetOnMemoryTypeInformationChange)) {
- DEBUG ((EFI_D_INFO, "Memory Type Information settings change. Warm Reset!!!\n"));
- gRT->ResetSystem (EfiResetWarm, EFI_SUCCESS, 0, NULL);
+ if (!EFI_ERROR (Status)) {
+ //
+ // If the Memory Type Information settings have been modified, then reset the platform
+ // so the new Memory Type Information setting will be used to guarantee that an S4
+ // entry/resume cycle will not fail.
+ //
+ if (MemoryTypeInformationModified && PcdGetBool (PcdResetOnMemoryTypeInformationChange)) {
+ DEBUG ((EFI_D_INFO, "Memory Type Information settings change. Warm Reset!!!\n"));
+ gRT->ResetSystem (EfiResetWarm, EFI_SUCCESS, 0, NULL);
+ }
+ } else {
+ DEBUG ((EFI_D_ERROR, "Memory Type Information settings cannot be saved. OS S4 may fail!\n"));
}
}
}
@@ -1482,3 +1489,89 @@ BdsLibUserIdentify (
return Manager->Identify (Manager, User);
}
+/**
+ Set the variable and report the error through status code upon failure.
+
+ @param VariableName A Null-terminated string that is the name of the vendor's variable.
+ Each VariableName is unique for each VendorGuid. VariableName must
+ contain 1 or more characters. If VariableName is an empty string,
+ then EFI_INVALID_PARAMETER is returned.
+ @param VendorGuid A unique identifier for the vendor.
+ @param Attributes Attributes bitmask to set for the variable.
+ @param DataSize The size in bytes of the Data buffer. Unless the EFI_VARIABLE_APPEND_WRITE,
+ EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS, or
+ EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS attribute is set, a size of zero
+ causes the variable to be deleted. When the EFI_VARIABLE_APPEND_WRITE attribute is
+ set, then a SetVariable() call with a DataSize of zero will not cause any change to
+ the variable value (the timestamp associated with the variable may be updated however
+ even if no new data value is provided,see the description of the
+ EFI_VARIABLE_AUTHENTICATION_2 descriptor below. In this case the DataSize will not
+ be zero since the EFI_VARIABLE_AUTHENTICATION_2 descriptor will be populated).
+ @param Data The contents for the variable.
+
+ @retval EFI_SUCCESS The firmware has successfully stored the variable and its data as
+ defined by the Attributes.
+ @retval EFI_INVALID_PARAMETER An invalid combination of attribute bits, name, and GUID was supplied, or the
+ DataSize exceeds the maximum allowed.
+ @retval EFI_INVALID_PARAMETER VariableName is an empty string.
+ @retval EFI_OUT_OF_RESOURCES Not enough storage is available to hold the variable and its data.
+ @retval EFI_DEVICE_ERROR The variable could not be retrieved due to a hardware error.
+ @retval EFI_WRITE_PROTECTED The variable in question is read-only.
+ @retval EFI_WRITE_PROTECTED The variable in question cannot be deleted.
+ @retval EFI_SECURITY_VIOLATION The variable could not be written due to EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS
+ or EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACESS being set, but the AuthInfo
+ does NOT pass the validation check carried out by the firmware.
+
+ @retval EFI_NOT_FOUND The variable trying to be updated or deleted was not found.
+**/
+EFI_STATUS
+SetVariableAndReportStatusCodeOnError (
+ IN CHAR16 *VariableName,
+ IN EFI_GUID *VendorGuid,
+ IN UINT32 Attributes,
+ IN UINTN DataSize,
+ IN VOID *Data
+ )
+{
+ EFI_STATUS Status;
+ EDKII_SET_VARIABLE_STATUS *SetVariableStatus;
+ UINTN NameSize;
+
+ Status = gRT->SetVariable (
+ VariableName,
+ VendorGuid,
+ Attributes,
+ DataSize,
+ Data
+ );
+ if (EFI_ERROR (Status)) {
+ NameSize = StrSize (VariableName);
+ SetVariableStatus = AllocatePool (sizeof (EDKII_SET_VARIABLE_STATUS) + NameSize + DataSize);
+ if (SetVariableStatus != NULL) {
+ CopyGuid (&SetVariableStatus->Guid, VendorGuid);
+ SetVariableStatus->NameSize = NameSize;
+ SetVariableStatus->DataSize = DataSize;
+ SetVariableStatus->SetStatus = Status;
+ SetVariableStatus->Attributes = Attributes;
+ CopyMem (SetVariableStatus + 1, VariableName, NameSize);
+ if ((Data != NULL) && (DataSize != 0)) {
+ CopyMem (((UINT8 *) (SetVariableStatus + 1)) + NameSize, Data, DataSize);
+ }
+
+ REPORT_STATUS_CODE_EX (
+ EFI_ERROR_CODE,
+ PcdGet32 (PcdErrorCodeSetVariable),
+ 0,
+ NULL,
+ &gEdkiiStatusCodeDataTypeVariableGuid,
+ SetVariableStatus,
+ sizeof (EDKII_SET_VARIABLE_STATUS) + NameSize + DataSize
+ );
+
+ FreePool (SetVariableStatus);
+ }
+ }
+
+ return Status;
+}
+
diff --git a/IntelFrameworkModulePkg/Library/GenericBdsLib/GenericBdsLib.inf b/IntelFrameworkModulePkg/Library/GenericBdsLib/GenericBdsLib.inf
index 2fb9916aa..041afc4e1 100644
--- a/IntelFrameworkModulePkg/Library/GenericBdsLib/GenericBdsLib.inf
+++ b/IntelFrameworkModulePkg/Library/GenericBdsLib/GenericBdsLib.inf
@@ -5,7 +5,7 @@
# 2) BDS boot device connect interface;
# 3) BDS Misc interfaces for mainting boot variable, ouput string, etc.
#
-# Copyright (c) 2007 - 2013, Intel Corporation. All rights reserved.<BR>
+# Copyright (c) 2007 - 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
@@ -79,6 +79,7 @@
gHdBootDevicePathVariablGuid ## SOMETIMES_PRODUCES ## Variable:L"HDDP" (The device path of Boot file on Hard device.)
gBdsLibStringPackageGuid ## PRODUCES ## GUID (HII String PackageList Guid)
gEfiLegacyDevOrderVariableGuid ## CONSUMES ## GUID
+ gEdkiiStatusCodeDataTypeVariableGuid ## SOMETIMES_CONSUMES
[Protocols]
gEfiSimpleFileSystemProtocolGuid # PROTOCOL CONSUMES
@@ -111,4 +112,5 @@
gEfiMdeModulePkgTokenSpaceGuid.PcdResetOnMemoryTypeInformationChange
gEfiMdeModulePkgTokenSpaceGuid.PcdProgressCodeOsLoaderLoad
gEfiMdeModulePkgTokenSpaceGuid.PcdProgressCodeOsLoaderStart
+ gEfiMdeModulePkgTokenSpaceGuid.PcdErrorCodeSetVariable
gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdShellFile
diff --git a/IntelFrameworkModulePkg/Library/GenericBdsLib/InternalBdsLib.h b/IntelFrameworkModulePkg/Library/GenericBdsLib/InternalBdsLib.h
index 80b1f49a9..c32579bfc 100644
--- a/IntelFrameworkModulePkg/Library/GenericBdsLib/InternalBdsLib.h
+++ b/IntelFrameworkModulePkg/Library/GenericBdsLib/InternalBdsLib.h
@@ -1,7 +1,7 @@
/** @file
BDS library definition, include the file and data structure
-Copyright (c) 2004 - 2013, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2004 - 2014, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
@@ -51,6 +51,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#include <Guid/HdBootVariable.h>
#include <Guid/LastEnumLang.h>
#include <Guid/LegacyDevOrder.h>
+#include <Guid/StatusCodeDataTypeVariable.h>
#include <Library/PrintLib.h>
#include <Library/DebugLib.h>
@@ -147,4 +148,48 @@ ValidateOption (
UINTN VariableSize
);
+/**
+ Set the variable and report the error through status code upon failure.
+
+ @param VariableName A Null-terminated string that is the name of the vendor's variable.
+ Each VariableName is unique for each VendorGuid. VariableName must
+ contain 1 or more characters. If VariableName is an empty string,
+ then EFI_INVALID_PARAMETER is returned.
+ @param VendorGuid A unique identifier for the vendor.
+ @param Attributes Attributes bitmask to set for the variable.
+ @param DataSize The size in bytes of the Data buffer. Unless the EFI_VARIABLE_APPEND_WRITE,
+ EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS, or
+ EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS attribute is set, a size of zero
+ causes the variable to be deleted. When the EFI_VARIABLE_APPEND_WRITE attribute is
+ set, then a SetVariable() call with a DataSize of zero will not cause any change to
+ the variable value (the timestamp associated with the variable may be updated however
+ even if no new data value is provided,see the description of the
+ EFI_VARIABLE_AUTHENTICATION_2 descriptor below. In this case the DataSize will not
+ be zero since the EFI_VARIABLE_AUTHENTICATION_2 descriptor will be populated).
+ @param Data The contents for the variable.
+
+ @retval EFI_SUCCESS The firmware has successfully stored the variable and its data as
+ defined by the Attributes.
+ @retval EFI_INVALID_PARAMETER An invalid combination of attribute bits, name, and GUID was supplied, or the
+ DataSize exceeds the maximum allowed.
+ @retval EFI_INVALID_PARAMETER VariableName is an empty string.
+ @retval EFI_OUT_OF_RESOURCES Not enough storage is available to hold the variable and its data.
+ @retval EFI_DEVICE_ERROR The variable could not be retrieved due to a hardware error.
+ @retval EFI_WRITE_PROTECTED The variable in question is read-only.
+ @retval EFI_WRITE_PROTECTED The variable in question cannot be deleted.
+ @retval EFI_SECURITY_VIOLATION The variable could not be written due to EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS
+ or EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACESS being set, but the AuthInfo
+ does NOT pass the validation check carried out by the firmware.
+
+ @retval EFI_NOT_FOUND The variable trying to be updated or deleted was not found.
+**/
+EFI_STATUS
+SetVariableAndReportStatusCodeOnError (
+ IN CHAR16 *VariableName,
+ IN EFI_GUID *VendorGuid,
+ IN UINT32 Attributes,
+ IN UINTN DataSize,
+ IN VOID *Data
+ );
+
#endif // _BDS_LIB_H_
diff --git a/IntelFrameworkModulePkg/Universal/Acpi/AcpiS3SaveDxe/AcpiS3SaveDxe.inf b/IntelFrameworkModulePkg/Universal/Acpi/AcpiS3SaveDxe/AcpiS3SaveDxe.inf
index eb3ade991..dc6da58f9 100644
--- a/IntelFrameworkModulePkg/Universal/Acpi/AcpiS3SaveDxe/AcpiS3SaveDxe.inf
+++ b/IntelFrameworkModulePkg/Universal/Acpi/AcpiS3SaveDxe/AcpiS3SaveDxe.inf
@@ -2,7 +2,7 @@
# Component description file for AcpiS3Save module.
#
# This is an implementation of the ACPI S3 Save protocol.
-# Copyright (c) 2006 - 2011, 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
@@ -64,6 +64,7 @@
gEfiLegacyBiosProtocolGuid # PROTOCOL ALWAYS_CONSUMED
gEfiLegacyRegion2ProtocolGuid # PROTOCOL SOMETIMES_CONSUMED
gFrameworkEfiMpServiceProtocolGuid # PROTOCOL SOMETIMES_CONSUMED
+ gEdkiiVariableLockProtocolGuid ## SOMETIMES_CONSUMES
[FeaturePcd]
gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdPlatformCsmSupport ## CONSUMES
diff --git a/IntelFrameworkModulePkg/Universal/Acpi/AcpiS3SaveDxe/AcpiVariableThunkPlatform.c b/IntelFrameworkModulePkg/Universal/Acpi/AcpiS3SaveDxe/AcpiVariableThunkPlatform.c
index 641a0ae0c..7ad9eb433 100644
--- a/IntelFrameworkModulePkg/Universal/Acpi/AcpiS3SaveDxe/AcpiVariableThunkPlatform.c
+++ b/IntelFrameworkModulePkg/Universal/Acpi/AcpiS3SaveDxe/AcpiVariableThunkPlatform.c
@@ -1,7 +1,7 @@
/** @file
This is an implementation of the AcpiVariable platform field for ECP platform.
-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
@@ -39,7 +39,9 @@ typedef struct {
#include <Library/HobLib.h>
#include <Library/PcdLib.h>
#include <Library/DebugLib.h>
+#include <Library/UefiLib.h>
#include <Protocol/FrameworkMpService.h>
+#include <Protocol/VariableLock.h>
#include <Guid/AcpiVariableCompatibility.h>
#include <Guid/AcpiS3Context.h>
@@ -80,6 +82,10 @@ S3ReadyThunkPlatform (
DEBUG ((EFI_D_INFO, "S3ReadyThunkPlatform\n"));
+ if (mAcpiVariableSetCompatibility == NULL) {
+ return;
+ }
+
//
// Allocate ACPI reserved memory under 4G
//
@@ -118,6 +124,32 @@ S3ReadyThunkPlatform (
}
/**
+ Register callback function upon VariableLockProtocol
+ to lock ACPI_GLOBAL_VARIABLE variable to avoid malicious code to update it.
+
+ @param[in] Event Event whose notification function is being invoked.
+ @param[in] Context Pointer to the notification function's context.
+**/
+VOID
+EFIAPI
+VariableLockAcpiGlobalVariable (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+{
+ EFI_STATUS Status;
+ EDKII_VARIABLE_LOCK_PROTOCOL *VariableLock;
+ //
+ // Mark ACPI_GLOBAL_VARIABLE variable to read-only if the Variable Lock protocol exists
+ //
+ Status = gBS->LocateProtocol (&gEdkiiVariableLockProtocolGuid, NULL, (VOID **) &VariableLock);
+ if (!EFI_ERROR (Status)) {
+ Status = VariableLock->RequestToLock (VariableLock, ACPI_GLOBAL_VARIABLE, &gEfiAcpiVariableCompatiblityGuid);
+ ASSERT_EFI_ERROR (Status);
+ }
+}
+
+/**
Hook point for AcpiVariableThunkPlatform for InstallAcpiS3Save.
**/
VOID
@@ -128,6 +160,7 @@ InstallAcpiS3SaveThunk (
EFI_STATUS Status;
FRAMEWORK_EFI_MP_SERVICES_PROTOCOL *FrameworkMpService;
UINTN VarSize;
+ VOID *Registration;
Status = gBS->LocateProtocol (
&gFrameworkEfiMpServiceProtocolGuid,
@@ -147,21 +180,44 @@ InstallAcpiS3SaveThunk (
&VarSize,
&mAcpiVariableSetCompatibility
);
- ASSERT_EFI_ERROR (Status);
+ if (EFI_ERROR (Status) || (VarSize != sizeof (mAcpiVariableSetCompatibility))) {
+ DEBUG ((EFI_D_ERROR, "FATAL ERROR: AcpiVariableSetCompatibility was not saved by CPU driver correctly. OS S3 may fail!\n"));
+ mAcpiVariableSetCompatibility = NULL;
+ }
} else {
//
// Allocate/initialize the compatible version of Acpi Variable Set since Framework chipset/platform
- // driver need this variable
+ // driver need this variable. ACPI_GLOBAL_VARIABLE variable is not used in runtime phase,
+ // so RT attribute is not needed for it.
//
mAcpiVariableSetCompatibility = AllocateMemoryBelow4G (EfiACPIMemoryNVS, sizeof(ACPI_VARIABLE_SET_COMPATIBILITY));
Status = gRT->SetVariable (
ACPI_GLOBAL_VARIABLE,
&gEfiAcpiVariableCompatiblityGuid,
- EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
+ EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE,
sizeof(mAcpiVariableSetCompatibility),
&mAcpiVariableSetCompatibility
);
- ASSERT_EFI_ERROR (Status);
+ if (!EFI_ERROR (Status)) {
+ //
+ // Register callback function upon VariableLockProtocol
+ // to lock ACPI_GLOBAL_VARIABLE variable to avoid malicious code to update it.
+ //
+ EfiCreateProtocolNotifyEvent (
+ &gEdkiiVariableLockProtocolGuid,
+ TPL_CALLBACK,
+ VariableLockAcpiGlobalVariable,
+ NULL,
+ &Registration
+ );
+ } else {
+ DEBUG ((EFI_D_ERROR, "FATAL ERROR: AcpiVariableSetCompatibility cannot be saved: %r. OS S3 may fail!\n", Status));
+ gBS->FreePages (
+ (EFI_PHYSICAL_ADDRESS) (UINTN) mAcpiVariableSetCompatibility,
+ EFI_SIZE_TO_PAGES (sizeof (ACPI_VARIABLE_SET_COMPATIBILITY))
+ );
+ mAcpiVariableSetCompatibility = NULL;
+ }
}
DEBUG((EFI_D_INFO, "AcpiVariableSetCompatibility is 0x%8x\n", mAcpiVariableSetCompatibility));
diff --git a/IntelFrameworkModulePkg/Universal/BdsDxe/Bds.h b/IntelFrameworkModulePkg/Universal/BdsDxe/Bds.h
index e535bc21d..93bafd2dd 100644
--- a/IntelFrameworkModulePkg/Universal/BdsDxe/Bds.h
+++ b/IntelFrameworkModulePkg/Universal/BdsDxe/Bds.h
@@ -1,7 +1,7 @@
/** @file
Head file for BDS Architectural Protocol implementation
-Copyright (c) 2004 - 2013, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2004 - 2014, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
@@ -20,6 +20,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#include <Guid/MdeModuleHii.h>
#include <Guid/FileSystemVolumeLabelInfo.h>
#include <Guid/HiiPlatformSetupFormset.h>
+#include <Guid/StatusCodeDataTypeVariable.h>
#include <Protocol/DevicePath.h>
#include <IndustryStandard/SmBios.h>
#include <Protocol/LoadFile.h>
@@ -189,4 +190,48 @@ BdsProcessCapsules (
EFI_BOOT_MODE BootMode
);
+/**
+ Set the variable and report the error through status code upon failure.
+
+ @param VariableName A Null-terminated string that is the name of the vendor's variable.
+ Each VariableName is unique for each VendorGuid. VariableName must
+ contain 1 or more characters. If VariableName is an empty string,
+ then EFI_INVALID_PARAMETER is returned.
+ @param VendorGuid A unique identifier for the vendor.
+ @param Attributes Attributes bitmask to set for the variable.
+ @param DataSize The size in bytes of the Data buffer. Unless the EFI_VARIABLE_APPEND_WRITE,
+ EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS, or
+ EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS attribute is set, a size of zero
+ causes the variable to be deleted. When the EFI_VARIABLE_APPEND_WRITE attribute is
+ set, then a SetVariable() call with a DataSize of zero will not cause any change to
+ the variable value (the timestamp associated with the variable may be updated however
+ even if no new data value is provided,see the description of the
+ EFI_VARIABLE_AUTHENTICATION_2 descriptor below. In this case the DataSize will not
+ be zero since the EFI_VARIABLE_AUTHENTICATION_2 descriptor will be populated).
+ @param Data The contents for the variable.
+
+ @retval EFI_SUCCESS The firmware has successfully stored the variable and its data as
+ defined by the Attributes.
+ @retval EFI_INVALID_PARAMETER An invalid combination of attribute bits, name, and GUID was supplied, or the
+ DataSize exceeds the maximum allowed.
+ @retval EFI_INVALID_PARAMETER VariableName is an empty string.
+ @retval EFI_OUT_OF_RESOURCES Not enough storage is available to hold the variable and its data.
+ @retval EFI_DEVICE_ERROR The variable could not be retrieved due to a hardware error.
+ @retval EFI_WRITE_PROTECTED The variable in question is read-only.
+ @retval EFI_WRITE_PROTECTED The variable in question cannot be deleted.
+ @retval EFI_SECURITY_VIOLATION The variable could not be written due to EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS
+ or EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACESS being set, but the AuthInfo
+ does NOT pass the validation check carried out by the firmware.
+
+ @retval EFI_NOT_FOUND The variable trying to be updated or deleted was not found.
+**/
+EFI_STATUS
+BdsDxeSetVariableAndReportStatusCodeOnError (
+ IN CHAR16 *VariableName,
+ IN EFI_GUID *VendorGuid,
+ IN UINT32 Attributes,
+ IN UINTN DataSize,
+ IN VOID *Data
+ );
+
#endif
diff --git a/IntelFrameworkModulePkg/Universal/BdsDxe/BdsDxe.inf b/IntelFrameworkModulePkg/Universal/BdsDxe/BdsDxe.inf
index b10056491..6796adc43 100644
--- a/IntelFrameworkModulePkg/Universal/BdsDxe/BdsDxe.inf
+++ b/IntelFrameworkModulePkg/Universal/BdsDxe/BdsDxe.inf
@@ -14,7 +14,7 @@
# BDSDxe also maintain the UI for "Boot Manager, Boot Maintaince Manager, Device Manager" which
# is used for user to configure boot option or maintain hardware device.
#
-# Copyright (c) 2008 - 2013, Intel Corporation. All rights reserved.<BR>
+# Copyright (c) 2008 - 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
@@ -142,6 +142,7 @@
gDriverHealthFormSetGuid ## SOMETIMES_PRODUCES ## DriverHealth HII Package
gConnectConInEventGuid ## CONSUMES ## GUID (Connect ConIn Event)
gEfiFmpCapsuleGuid ## CONSUMES ## GUID (FMP Capsule)
+ gEdkiiStatusCodeDataTypeVariableGuid ## SOMETIMES_CONSUMES
[Protocols]
gEfiSimpleFileSystemProtocolGuid ## PROTOCOL CONSUMES
@@ -188,6 +189,7 @@
gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdSetupVideoHorizontalResolution
gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdSetupVideoVerticalResolution
gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdShellFile
+ gEfiMdeModulePkgTokenSpaceGuid.PcdErrorCodeSetVariable
[Depex]
TRUE
diff --git a/IntelFrameworkModulePkg/Universal/BdsDxe/BdsEntry.c b/IntelFrameworkModulePkg/Universal/BdsDxe/BdsEntry.c
index 33b3cc2dc..ae7ad2153 100644
--- a/IntelFrameworkModulePkg/Universal/BdsDxe/BdsEntry.c
+++ b/IntelFrameworkModulePkg/Universal/BdsDxe/BdsEntry.c
@@ -5,7 +5,7 @@
After DxeCore finish DXE phase, gEfiBdsArchProtocolGuid->BdsEntry will be invoked
to enter BDS phase.
-Copyright (c) 2004 - 2013, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2004 - 2014, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
@@ -164,13 +164,17 @@ BdsBootDeviceSelect (
//
// Clear the this variable so it's only exist in this time boot
//
- gRT->SetVariable (
- L"BootNext",
- &gEfiGlobalVariableGuid,
- EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
- 0,
- mBootNext
- );
+ Status = gRT->SetVariable (
+ L"BootNext",
+ &gEfiGlobalVariableGuid,
+ EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
+ 0,
+ NULL
+ );
+ //
+ // Deleting variable with current variable implementation shouldn't fail.
+ //
+ ASSERT_EFI_ERROR (Status);
//
// Add the boot next boot option
@@ -368,6 +372,9 @@ BdsFormalizeConsoleVariable (
0,
NULL
);
+ //
+ // Deleting variable with current variable implementation shouldn't fail.
+ //
ASSERT_EFI_ERROR (Status);
}
}
@@ -406,14 +413,13 @@ BdsFormalizeEfiGlobalVariable (
OsIndicationSupport = EFI_OS_INDICATIONS_BOOT_TO_FW_UI \
| EFI_OS_INDICATIONS_FMP_CAPSULE_SUPPORTED;
- Status = gRT->SetVariable (
- L"OsIndicationsSupported",
- &gEfiGlobalVariableGuid,
- EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
- sizeof(UINT64),
- &OsIndicationSupport
- );
- ASSERT_EFI_ERROR (Status);
+ BdsDxeSetVariableAndReportStatusCodeOnError (
+ L"OsIndicationsSupported",
+ &gEfiGlobalVariableGuid,
+ EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
+ sizeof(UINT64),
+ &OsIndicationSupport
+ );
//
// If OsIndications is invalid, remove it.
@@ -442,10 +448,13 @@ BdsFormalizeEfiGlobalVariable (
Status = gRT->SetVariable (
L"OsIndications",
&gEfiGlobalVariableGuid,
- Attributes,
0,
- &OsIndication
+ 0,
+ NULL
);
+ //
+ // Deleting variable with current variable implementation shouldn't fail.
+ //
ASSERT_EFI_ERROR (Status);
}
}
@@ -481,16 +490,19 @@ BdsAllocateMemoryForPerformanceData (
//
// Save the pointer to variable for use in S3 resume.
//
- Status = gRT->SetVariable (
- L"PerfDataMemAddr",
- &gPerformanceProtocolGuid,
- EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
- sizeof (EFI_PHYSICAL_ADDRESS),
- &AcpiLowMemoryBase
- );
- ASSERT_EFI_ERROR (Status);
+ BdsDxeSetVariableAndReportStatusCodeOnError (
+ L"PerfDataMemAddr",
+ &gPerformanceProtocolGuid,
+ EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
+ sizeof (EFI_PHYSICAL_ADDRESS),
+ &AcpiLowMemoryBase
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR, "[Bds] PerfDataMemAddr (%08x) cannot be saved to NV storage.\n", AcpiLowMemoryBase));
+ }
//
// Mark L"PerfDataMemAddr" variable to read-only if the Variable Lock protocol exists
+ // Still lock it even the variable cannot be saved to prevent it's set by 3rd party code.
//
Status = gBS->LocateProtocol (&gEdkiiVariableLockProtocolGuid, NULL, (VOID **) &VariableLock);
if (!EFI_ERROR (Status)) {
@@ -594,14 +606,13 @@ BdsEntry (
// If time out value equal 0xFFFF, no need set to 0xFFFF to variable area because UEFI specification
// define same behavior between no value or 0xFFFF value for L"Timeout".
//
- Status = gRT->SetVariable (
+ BdsDxeSetVariableAndReportStatusCodeOnError (
L"Timeout",
&gEfiGlobalVariableGuid,
EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
sizeof (UINT16),
&BootTimeOut
);
- ASSERT_EFI_ERROR(Status);
}
//
@@ -655,3 +666,89 @@ BdsEntry (
return ;
}
+
+
+/**
+ Set the variable and report the error through status code upon failure.
+
+ @param VariableName A Null-terminated string that is the name of the vendor's variable.
+ Each VariableName is unique for each VendorGuid. VariableName must
+ contain 1 or more characters. If VariableName is an empty string,
+ then EFI_INVALID_PARAMETER is returned.
+ @param VendorGuid A unique identifier for the vendor.
+ @param Attributes Attributes bitmask to set for the variable.
+ @param DataSize The size in bytes of the Data buffer. Unless the EFI_VARIABLE_APPEND_WRITE,
+ EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS, or
+ EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS attribute is set, a size of zero
+ causes the variable to be deleted. When the EFI_VARIABLE_APPEND_WRITE attribute is
+ set, then a SetVariable() call with a DataSize of zero will not cause any change to
+ the variable value (the timestamp associated with the variable may be updated however
+ even if no new data value is provided,see the description of the
+ EFI_VARIABLE_AUTHENTICATION_2 descriptor below. In this case the DataSize will not
+ be zero since the EFI_VARIABLE_AUTHENTICATION_2 descriptor will be populated).
+ @param Data The contents for the variable.
+
+ @retval EFI_SUCCESS The firmware has successfully stored the variable and its data as
+ defined by the Attributes.
+ @retval EFI_INVALID_PARAMETER An invalid combination of attribute bits, name, and GUID was supplied, or the
+ DataSize exceeds the maximum allowed.
+ @retval EFI_INVALID_PARAMETER VariableName is an empty string.
+ @retval EFI_OUT_OF_RESOURCES Not enough storage is available to hold the variable and its data.
+ @retval EFI_DEVICE_ERROR The variable could not be retrieved due to a hardware error.
+ @retval EFI_WRITE_PROTECTED The variable in question is read-only.
+ @retval EFI_WRITE_PROTECTED The variable in question cannot be deleted.
+ @retval EFI_SECURITY_VIOLATION The variable could not be written due to EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS
+ or EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACESS being set, but the AuthInfo
+ does NOT pass the validation check carried out by the firmware.
+
+ @retval EFI_NOT_FOUND The variable trying to be updated or deleted was not found.
+**/
+EFI_STATUS
+BdsDxeSetVariableAndReportStatusCodeOnError (
+ IN CHAR16 *VariableName,
+ IN EFI_GUID *VendorGuid,
+ IN UINT32 Attributes,
+ IN UINTN DataSize,
+ IN VOID *Data
+ )
+{
+ EFI_STATUS Status;
+ EDKII_SET_VARIABLE_STATUS *SetVariableStatus;
+ UINTN NameSize;
+
+ Status = gRT->SetVariable (
+ VariableName,
+ VendorGuid,
+ Attributes,
+ DataSize,
+ Data
+ );
+ if (EFI_ERROR (Status)) {
+ NameSize = StrSize (VariableName);
+ SetVariableStatus = AllocatePool (sizeof (EDKII_SET_VARIABLE_STATUS) + NameSize + DataSize);
+ if (SetVariableStatus != NULL) {
+ CopyGuid (&SetVariableStatus->Guid, VendorGuid);
+ SetVariableStatus->NameSize = NameSize;
+ SetVariableStatus->DataSize = DataSize;
+ SetVariableStatus->SetStatus = Status;
+ SetVariableStatus->Attributes = Attributes;
+ CopyMem (SetVariableStatus + 1, VariableName, NameSize);
+ CopyMem (((UINT8 *) (SetVariableStatus + 1)) + NameSize, Data, DataSize);
+
+ REPORT_STATUS_CODE_EX (
+ EFI_ERROR_CODE,
+ PcdGet32 (PcdErrorCodeSetVariable),
+ 0,
+ NULL,
+ &gEdkiiStatusCodeDataTypeVariableGuid,
+ SetVariableStatus,
+ sizeof (EDKII_SET_VARIABLE_STATUS) + NameSize + DataSize
+ );
+
+ FreePool (SetVariableStatus);
+ }
+ }
+
+ return Status;
+}
+
diff --git a/IntelFrameworkModulePkg/Universal/BdsDxe/BootMaint/BBSsupport.c b/IntelFrameworkModulePkg/Universal/BdsDxe/BootMaint/BBSsupport.c
index db0fed583..adf84f42f 100644
--- a/IntelFrameworkModulePkg/Universal/BdsDxe/BootMaint/BBSsupport.c
+++ b/IntelFrameworkModulePkg/Universal/BdsDxe/BootMaint/BBSsupport.c
@@ -3,7 +3,7 @@
and manage the legacy boot option, all legacy boot option is getting from
the legacy BBS table.
-Copyright (c) 2004 - 2012, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2004 - 2014, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
@@ -143,6 +143,9 @@ OrderLegacyBootOption4SameType (
BootOrderSize,
BootOrder
);
+ //
+ // Changing content without increasing its size with current variable implementation shouldn't fail.
+ //
ASSERT_EFI_ERROR (Status);
FreePool (NewBootOption);
@@ -171,6 +174,7 @@ GroupMultipleLegacyBootOption4SameType (
VOID
)
{
+ EFI_STATUS Status;
UINTN Index;
UINTN DeviceIndex;
UINTN DeviceTypeIndex[7];
@@ -233,13 +237,17 @@ GroupMultipleLegacyBootOption4SameType (
FreePool (BootOption);
}
- gRT->SetVariable (
- L"BootOrder",
- &gEfiGlobalVariableGuid,
- EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
- BootOrderSize,
- BootOrder
- );
+ Status = gRT->SetVariable (
+ L"BootOrder",
+ &gEfiGlobalVariableGuid,
+ EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
+ BootOrderSize,
+ BootOrder
+ );
+ //
+ // Changing content without increasing its size with current variable implementation shouldn't fail.
+ //
+ ASSERT_EFI_ERROR (Status);
FreePool (BootOrder);
}
diff --git a/IntelFrameworkModulePkg/Universal/BdsDxe/BootMaint/BmLib.c b/IntelFrameworkModulePkg/Universal/BdsDxe/BootMaint/BmLib.c
index c83b7dded..5fe5388f9 100644
--- a/IntelFrameworkModulePkg/Universal/BdsDxe/BootMaint/BmLib.c
+++ b/IntelFrameworkModulePkg/Universal/BdsDxe/BootMaint/BmLib.c
@@ -1,7 +1,7 @@
/** @file
Utility routines used by boot maintenance modules.
-Copyright (c) 2004 - 2012, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2004 - 2014, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
@@ -178,7 +178,10 @@ EfiLibDeleteVariable (
0,
NULL
);
- ASSERT (!EFI_ERROR (Status));
+ //
+ // Deleting variable with current variable implementation shouldn't fail.
+ //
+ ASSERT_EFI_ERROR (Status);
FreePool (VarBuf);
}
diff --git a/IntelFrameworkModulePkg/Universal/BdsDxe/BootMaint/BootMaint.c b/IntelFrameworkModulePkg/Universal/BdsDxe/BootMaint/BootMaint.c
index 5f200e2e1..b974a67ea 100644
--- a/IntelFrameworkModulePkg/Universal/BdsDxe/BootMaint/BootMaint.c
+++ b/IntelFrameworkModulePkg/Universal/BdsDxe/BootMaint/BootMaint.c
@@ -1,7 +1,7 @@
/** @file
The functions for Boot Maintainence Main menu.
-Copyright (c) 2004 - 2013, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2004 - 2014, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
@@ -672,14 +672,13 @@ ApplyChangeHandler (
break;
case FORM_TIME_OUT_ID:
- Status = gRT->SetVariable (
- L"Timeout",
- &gEfiGlobalVariableGuid,
- EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
- sizeof (UINT16),
- &(CurrentFakeNVMap->BootTimeOut)
- );
- ASSERT_EFI_ERROR(Status);
+ BdsDxeSetVariableAndReportStatusCodeOnError (
+ L"Timeout",
+ &gEfiGlobalVariableGuid,
+ EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
+ sizeof (UINT16),
+ &(CurrentFakeNVMap->BootTimeOut)
+ );
Private->BmmOldFakeNVData.BootTimeOut = CurrentFakeNVMap->BootTimeOut;
break;
diff --git a/IntelFrameworkModulePkg/Universal/BdsDxe/BootMaint/Variable.c b/IntelFrameworkModulePkg/Universal/BdsDxe/BootMaint/Variable.c
index ef36ae2dc..529fdaea2 100644
--- a/IntelFrameworkModulePkg/Universal/BdsDxe/BootMaint/Variable.c
+++ b/IntelFrameworkModulePkg/Universal/BdsDxe/BootMaint/Variable.c
@@ -1,7 +1,7 @@
/** @file
Variable operation that will be used by bootmaint
-Copyright (c) 2004 - 2012, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2004 - 2014, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
@@ -165,9 +165,10 @@ Var_ChangeBootOrder (
BootOrderListSize * sizeof (UINT16),
BootOrderList
);
- if (EFI_ERROR (Status)) {
- return Status;
- }
+ //
+ // Changing variable without increasing its size with current variable implementation shouldn't fail.
+ //
+ ASSERT_EFI_ERROR (Status);
}
return EFI_SUCCESS;
}
@@ -303,9 +304,10 @@ Var_ChangeDriverOrder (
DriverOrderListSize * sizeof (UINT16),
DriverOrderList
);
- if (EFI_ERROR (Status)) {
- return Status;
- }
+ //
+ // Changing variable without increasing its size with current variable implementation shouldn't fail.
+ //
+ ASSERT_EFI_ERROR (Status);
}
return EFI_SUCCESS;
}
@@ -338,7 +340,10 @@ Var_UpdateAllConsoleOption (
GetDevicePathSize (OutDevicePath),
OutDevicePath
);
- ASSERT (!EFI_ERROR (Status));
+ //
+ // Changing variable without increasing its size with current variable implementation shouldn't fail.
+ //
+ ASSERT_EFI_ERROR (Status);
}
if (InpDevicePath != NULL) {
@@ -350,7 +355,10 @@ Var_UpdateAllConsoleOption (
GetDevicePathSize (InpDevicePath),
InpDevicePath
);
- ASSERT (!EFI_ERROR (Status));
+ //
+ // Changing variable without increasing its size with current variable implementation shouldn't fail.
+ //
+ ASSERT_EFI_ERROR (Status);
}
if (ErrDevicePath != NULL) {
@@ -362,7 +370,10 @@ Var_UpdateAllConsoleOption (
GetDevicePathSize (ErrDevicePath),
ErrDevicePath
);
- ASSERT (!EFI_ERROR (Status));
+ //
+ // Changing variable without increasing its size with current variable implementation shouldn't fail.
+ //
+ ASSERT_EFI_ERROR (Status);
}
}
@@ -667,38 +678,40 @@ Var_UpdateDriverOption (
BufferSize,
Buffer
);
- ASSERT_EFI_ERROR (Status);
- DriverOrderList = BdsLibGetVariableAndSize (
- L"DriverOrder",
- &gEfiGlobalVariableGuid,
- &DriverOrderListSize
- );
- NewDriverOrderList = AllocateZeroPool (DriverOrderListSize + sizeof (UINT16));
- ASSERT (NewDriverOrderList != NULL);
- if (DriverOrderList != NULL) {
- CopyMem (NewDriverOrderList, DriverOrderList, DriverOrderListSize);
- EfiLibDeleteVariable (L"DriverOrder", &gEfiGlobalVariableGuid);
- }
- NewDriverOrderList[DriverOrderListSize / sizeof (UINT16)] = Index;
+ if (!EFI_ERROR (Status)) {
+ DriverOrderList = BdsLibGetVariableAndSize (
+ L"DriverOrder",
+ &gEfiGlobalVariableGuid,
+ &DriverOrderListSize
+ );
+ NewDriverOrderList = AllocateZeroPool (DriverOrderListSize + sizeof (UINT16));
+ ASSERT (NewDriverOrderList != NULL);
+ if (DriverOrderList != NULL) {
+ CopyMem (NewDriverOrderList, DriverOrderList, DriverOrderListSize);
+ EfiLibDeleteVariable (L"DriverOrder", &gEfiGlobalVariableGuid);
+ }
+ NewDriverOrderList[DriverOrderListSize / sizeof (UINT16)] = Index;
- Status = gRT->SetVariable (
- L"DriverOrder",
- &gEfiGlobalVariableGuid,
- EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
- DriverOrderListSize + sizeof (UINT16),
- NewDriverOrderList
- );
- ASSERT_EFI_ERROR (Status);
- if (DriverOrderList != NULL) {
- FreePool (DriverOrderList);
- }
- DriverOrderList = NULL;
- FreePool (NewDriverOrderList);
- InsertTailList (&DriverOptionMenu.Head, &NewMenuEntry->Link);
- DriverOptionMenu.MenuNumber++;
+ Status = gRT->SetVariable (
+ L"DriverOrder",
+ &gEfiGlobalVariableGuid,
+ EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
+ DriverOrderListSize + sizeof (UINT16),
+ NewDriverOrderList
+ );
+ if (DriverOrderList != NULL) {
+ FreePool (DriverOrderList);
+ }
+ DriverOrderList = NULL;
+ FreePool (NewDriverOrderList);
+ if (!EFI_ERROR (Status)) {
+ InsertTailList (&DriverOptionMenu.Head, &NewMenuEntry->Link);
+ DriverOptionMenu.MenuNumber++;
- *DescriptionData = 0x0000;
- *OptionalData = 0x0000;
+ *DescriptionData = 0x0000;
+ *OptionalData = 0x0000;
+ }
+ }
return EFI_SUCCESS;
}
@@ -835,39 +848,41 @@ Var_UpdateBootOption (
BufferSize,
Buffer
);
- ASSERT_EFI_ERROR (Status);
+ if (!EFI_ERROR (Status)) {
- BootOrderList = BdsLibGetVariableAndSize (
+ BootOrderList = BdsLibGetVariableAndSize (
+ L"BootOrder",
+ &gEfiGlobalVariableGuid,
+ &BootOrderListSize
+ );
+ ASSERT (BootOrderList != NULL);
+ NewBootOrderList = AllocateZeroPool (BootOrderListSize + sizeof (UINT16));
+ ASSERT (NewBootOrderList != NULL);
+ CopyMem (NewBootOrderList, BootOrderList, BootOrderListSize);
+ NewBootOrderList[BootOrderListSize / sizeof (UINT16)] = Index;
+
+ if (BootOrderList != NULL) {
+ FreePool (BootOrderList);
+ }
+
+ Status = gRT->SetVariable (
L"BootOrder",
&gEfiGlobalVariableGuid,
- &BootOrderListSize
+ EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
+ BootOrderListSize + sizeof (UINT16),
+ NewBootOrderList
);
- ASSERT (BootOrderList != NULL);
- NewBootOrderList = AllocateZeroPool (BootOrderListSize + sizeof (UINT16));
- ASSERT (NewBootOrderList != NULL);
- CopyMem (NewBootOrderList, BootOrderList, BootOrderListSize);
- NewBootOrderList[BootOrderListSize / sizeof (UINT16)] = Index;
-
- if (BootOrderList != NULL) {
- FreePool (BootOrderList);
- }
-
- Status = gRT->SetVariable (
- L"BootOrder",
- &gEfiGlobalVariableGuid,
- EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
- BootOrderListSize + sizeof (UINT16),
- NewBootOrderList
- );
- ASSERT_EFI_ERROR (Status);
+ if (!EFI_ERROR (Status)) {
- FreePool (NewBootOrderList);
- NewBootOrderList = NULL;
- InsertTailList (&BootOptionMenu.Head, &NewMenuEntry->Link);
- BootOptionMenu.MenuNumber++;
+ FreePool (NewBootOrderList);
+ NewBootOrderList = NULL;
+ InsertTailList (&BootOptionMenu.Head, &NewMenuEntry->Link);
+ BootOptionMenu.MenuNumber++;
- NvRamMap->DescriptionData[0] = 0x0000;
- NvRamMap->OptionalData[0] = 0x0000;
+ NvRamMap->DescriptionData[0] = 0x0000;
+ NvRamMap->OptionalData[0] = 0x0000;
+ }
+ }
return EFI_SUCCESS;
}
@@ -987,6 +1002,10 @@ Var_UpdateBootOrder (
BootOrderListSize,
BootOrderList
);
+ //
+ // Changing the content without increasing its size with current variable implementation shouldn't fail.
+ //
+ ASSERT_EFI_ERROR (Status);
FreePool (BootOrderList);
GroupMultipleLegacyBootOption4SameType ();
@@ -1058,10 +1077,11 @@ Var_UpdateDriverOrder (
DriverOrderListSize,
NewDriverOrderList
);
- if (EFI_ERROR (Status)) {
- return Status;
- }
-
+ //
+ // Changing the content without increasing its size with current variable implementation shouldn't fail.
+ //
+ ASSERT_EFI_ERROR (Status);
+
BOpt_FreeMenu (&DriverOptionMenu);
BOpt_GetDriverOptions (CallbackData);
return EFI_SUCCESS;
@@ -1215,7 +1235,7 @@ Var_UpdateBBSOption (
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,
VarSize,
OriginalPtr
);
@@ -1258,6 +1278,10 @@ Var_UpdateBBSOption (
OptionSize,
BootOptionVar
);
+ //
+ // Changing the content without increasing its size with current variable implementation shouldn't fail.
+ //
+ ASSERT_EFI_ERROR (Status);
FreePool (BootOptionVar);
}
@@ -1281,6 +1305,10 @@ Var_UpdateBBSOption (
OptionSize,
BootOptionVar
);
+ //
+ // Changing the content without increasing its size with current variable implementation shouldn't fail.
+ //
+ ASSERT_EFI_ERROR (Status);
FreePool (BootOptionVar);
}
diff --git a/IntelFrameworkModulePkg/Universal/BdsDxe/FrontPage.c b/IntelFrameworkModulePkg/Universal/BdsDxe/FrontPage.c
index 432b22469..3bbe71a8f 100644
--- a/IntelFrameworkModulePkg/Universal/BdsDxe/FrontPage.c
+++ b/IntelFrameworkModulePkg/Universal/BdsDxe/FrontPage.c
@@ -1,7 +1,7 @@
/** @file
FrontPage routines to handle the callbacks and browser calls
-Copyright (c) 2004 - 2013, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2004 - 2014, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
@@ -182,7 +182,6 @@ FrontPageCallback (
CHAR8 *LangCode;
CHAR8 *Lang;
UINTN Index;
- EFI_STATUS Status;
if (Action != EFI_BROWSER_ACTION_CHANGING && Action != EFI_BROWSER_ACTION_CHANGED) {
//
@@ -226,14 +225,13 @@ FrontPageCallback (
}
if (Index == Value->u8) {
- Status = gRT->SetVariable (
+ BdsDxeSetVariableAndReportStatusCodeOnError (
L"PlatformLang",
&gEfiGlobalVariableGuid,
EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
AsciiStrSize (Lang),
Lang
);
- ASSERT_EFI_ERROR(Status);
} else {
ASSERT (FALSE);
}
@@ -1095,6 +1093,9 @@ PlatformBdsEnterFrontPage (
sizeof(UINT64),
&OsIndication
);
+ //
+ // Changing the content without increasing its size with current variable implementation shouldn't fail.
+ //
ASSERT_EFI_ERROR (Status);
//
diff --git a/IntelFrameworkModulePkg/Universal/BdsDxe/Hotkey.c b/IntelFrameworkModulePkg/Universal/BdsDxe/Hotkey.c
index 477411377..63de0d5f5 100644
--- a/IntelFrameworkModulePkg/Universal/BdsDxe/Hotkey.c
+++ b/IntelFrameworkModulePkg/Universal/BdsDxe/Hotkey.c
@@ -2,7 +2,7 @@
Provides a way for 3rd party applications to register themselves for launch by the
Boot Manager based on hot key
-Copyright (c) 2007 - 2013, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2007 - 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
@@ -550,6 +550,9 @@ InitializeHotkeyService (
sizeof (UINT32),
&BootOptionSupport
);
+ //
+ // Platform needs to make sure setting volatile variable before calling 3rd party code shouldn't fail.
+ //
ASSERT_EFI_ERROR (Status);
KeyOptionNumbers = HotkeyGetOptionNumbers (&KeyOptionCount);
diff --git a/IntelFrameworkModulePkg/Universal/BdsDxe/Language.c b/IntelFrameworkModulePkg/Universal/BdsDxe/Language.c
index 6d25bfe23..39455e44d 100644
--- a/IntelFrameworkModulePkg/Universal/BdsDxe/Language.c
+++ b/IntelFrameworkModulePkg/Universal/BdsDxe/Language.c
@@ -1,7 +1,7 @@
/** @file
Language settings
-Copyright (c) 2004 - 2013, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2004 - 2014, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
@@ -408,24 +408,23 @@ InitializeLangVariable (
IN BOOLEAN Iso639Language
)
{
- EFI_STATUS Status;
CHAR8 *Lang;
//
// Find current Lang or PlatformLang from EFI Variable.
//
- Status = GetEfiGlobalVariable2 (LangName, (VOID **) &Lang, NULL);
+ GetEfiGlobalVariable2 (LangName, (VOID **) &Lang, NULL);
//
// If Lang or PlatformLang variable is not found,
// or it has been set to an unsupported value(not one of the supported language codes),
// set the default language code to it.
//
- if (EFI_ERROR (Status) || !IsLangInSupportedLangCodes (SupportedLang, Lang, Iso639Language)) {
+ if ((Lang == NULL) || !IsLangInSupportedLangCodes (SupportedLang, Lang, Iso639Language)) {
//
// The default language code should be one of the supported language codes.
//
ASSERT (IsLangInSupportedLangCodes (SupportedLang, DefaultLang, Iso639Language));
- Status = gRT->SetVariable (
+ BdsDxeSetVariableAndReportStatusCodeOnError (
LangName,
&gEfiGlobalVariableGuid,
EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
@@ -462,7 +461,7 @@ InitializeLanguage (
if (LangCodesSettingRequired) {
if (!FeaturePcdGet (PcdUefiVariableDefaultLangDeprecate)) {
//
- // UEFI 2.1 depricated this variable so we support turning it off
+ // UEFI 2.0 depricated this variable so we support turning it off
//
Status = gRT->SetVariable (
L"LangCodes",
@@ -471,6 +470,10 @@ InitializeLanguage (
AsciiStrSize (LangCodes),
LangCodes
);
+ //
+ // Platform needs to make sure setting volatile variable before calling 3rd party code shouldn't fail.
+ //
+ ASSERT_EFI_ERROR (Status);
}
Status = gRT->SetVariable (
@@ -480,11 +483,15 @@ InitializeLanguage (
AsciiStrSize (PlatformLangCodes),
PlatformLangCodes
);
+ //
+ // Platform needs to make sure setting volatile variable before calling 3rd party code shouldn't fail.
+ //
+ ASSERT_EFI_ERROR (Status);
}
if (!FeaturePcdGet (PcdUefiVariableDefaultLangDeprecate)) {
//
- // UEFI 2.1 depricated this variable so we support turning it off
+ // UEFI 2.0 depricated this variable so we support turning it off
//
InitializeLangVariable (L"Lang", LangCodes, (CHAR8 *) PcdGetPtr (PcdUefiVariableDefaultLang), TRUE);
}
diff --git a/MdeModulePkg/Bus/I2c/I2cDxe/I2cHost.c b/MdeModulePkg/Bus/I2c/I2cDxe/I2cHost.c
index 0cc8e3384..ff99fe446 100644
--- a/MdeModulePkg/Bus/I2c/I2cDxe/I2cHost.c
+++ b/MdeModulePkg/Bus/I2c/I2cDxe/I2cHost.c
@@ -1012,6 +1012,7 @@ I2cHostQueueRequest (
//
RequestPacketSize = sizeof (UINTN) + RequestPacket->OperationCount * sizeof (EFI_I2C_OPERATION);
I2cRequest->RequestPacket = AllocateZeroPool (RequestPacketSize);
+ ASSERT (I2cRequest->RequestPacket != NULL);
CopyMem (I2cRequest->RequestPacket, RequestPacket, RequestPacketSize);
//
diff --git a/MdeModulePkg/Core/Dxe/Hand/DriverSupport.c b/MdeModulePkg/Core/Dxe/Hand/DriverSupport.c
index ded635632..92218ee7a 100644
--- a/MdeModulePkg/Core/Dxe/Hand/DriverSupport.c
+++ b/MdeModulePkg/Core/Dxe/Hand/DriverSupport.c
@@ -1,7 +1,7 @@
/** @file
Support functions to connect/disconnect UEFI Driver model Protocol
-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 of the BSD License
which accompanies this distribution. The full text of the license may be found at
@@ -85,6 +85,7 @@ CoreConnectController (
//
Status = CoreHandleProtocol (ControllerHandle, &gEfiDevicePathProtocolGuid, (VOID **)&HandleFilePath);
if (!EFI_ERROR (Status)) {
+ ASSERT (HandleFilePath != NULL);
FilePath = HandleFilePath;
TempFilePath = NULL;
if (RemainingDevicePath != NULL && !Recursive) {
diff --git a/MdeModulePkg/Include/Guid/StatusCodeDataTypeVariable.h b/MdeModulePkg/Include/Guid/StatusCodeDataTypeVariable.h
new file mode 100644
index 000000000..9ea85f809
--- /dev/null
+++ b/MdeModulePkg/Include/Guid/StatusCodeDataTypeVariable.h
@@ -0,0 +1,40 @@
+/** @file
+ This file defines the GUID and data structure used to pass variable setting
+ failure information to the Status Code Protocol.
+
+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 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 _STATUS_CODE_DATA_TYPE_VARIABLE_H_
+#define _STATUS_CODE_DATA_TYPE_VARIABLE_H_
+
+///
+/// The Global ID used to identify a structure of type EDKII_SET_VARIABLE_STATUS.
+/// The status code value is PcdGet32 (PcdErrorCodeSetVariable).
+///
+#define EDKII_STATUS_CODE_DATA_TYPE_VARIABLE_GUID \
+ { \
+ 0xf6ee6dbb, 0xd67f, 0x4ea0, { 0x8b, 0x96, 0x6a, 0x71, 0xb1, 0x9d, 0x84, 0xad } \
+ }
+
+typedef struct {
+ EFI_GUID Guid;
+ UINTN NameSize;
+ UINTN DataSize;
+ EFI_STATUS SetStatus;
+ UINT32 Attributes;
+ // CHAR16 Name[];
+ // UINT8 Data[];
+} EDKII_SET_VARIABLE_STATUS;
+
+extern EFI_GUID gEdkiiStatusCodeDataTypeVariableGuid;
+
+#endif // _STATUS_CODE_DATA_TYPE_VARIABLE_H_
diff --git a/MdeModulePkg/MdeModulePkg.dec b/MdeModulePkg/MdeModulePkg.dec
index 9084af7b8..e04246a2f 100644
--- a/MdeModulePkg/MdeModulePkg.dec
+++ b/MdeModulePkg/MdeModulePkg.dec
@@ -270,6 +270,9 @@
## Include/Guid/ConnectConInEvent.h
gConnectConInEventGuid = { 0xdb4e8151, 0x57ed, 0x4bed, { 0x88, 0x33, 0x67, 0x51, 0xb5, 0xd1, 0xa8, 0xd7 }}
+ ## Include/Guid/StatusCodeDataTypeVariable.h
+ gEdkiiStatusCodeDataTypeVariableGuid = { 0xf6ee6dbb, 0xd67f, 0x4ea0, { 0x8b, 0x96, 0x6a, 0x71, 0xb1, 0x9d, 0x84, 0xad }}
+
[Ppis]
## Include/Ppi/AtaController.h
gPeiAtaControllerPpiGuid = { 0xa45e60d1, 0xc719, 0x44aa, { 0xb0, 0x7a, 0xaa, 0x77, 0x7f, 0x85, 0x90, 0x6d }}
@@ -603,6 +606,10 @@
# PROGRESS_CODE_S3_SUSPEND_END = (EFI_SOFTWARE_SMM_DRIVER | (EFI_OEM_SPECIFIC | 0x00000001)) = 0x03078001
gEfiMdeModulePkgTokenSpaceGuid.PcdProgressCodeS3SuspendEnd|0x03078001|UINT32|0x30001033
+ ## Error Code for SetVariable failure.
+ # EDKII_ERROR_CODE_SET_VARIABLE = (EFI_SOFTWARE_DXE_BS_DRIVER | (EFI_OEM_SPECIFIC | 0x00000002)) = 0x03058002
+ gEfiMdeModulePkgTokenSpaceGuid.PcdErrorCodeSetVariable|0x03058002|UINT32|0x30001040
+
[PcdsFixedAtBuild,PcdsPatchableInModule]
## VPD type PCD allow developer point an absoluted physical address PcdVpdBaseAddress
# to store PCD value.
diff --git a/MdeModulePkg/Universal/Acpi/FirmwarePerformanceDataTableDxe/FirmwarePerformanceDxe.c b/MdeModulePkg/Universal/Acpi/FirmwarePerformanceDataTableDxe/FirmwarePerformanceDxe.c
index 9ea8f5c6b..caf924ccf 100644
--- a/MdeModulePkg/Universal/Acpi/FirmwarePerformanceDataTableDxe/FirmwarePerformanceDxe.c
+++ b/MdeModulePkg/Universal/Acpi/FirmwarePerformanceDataTableDxe/FirmwarePerformanceDxe.c
@@ -5,7 +5,7 @@
for Firmware Basic Boot Performance Record and other boot performance records,
and install FPDT to ACPI table.
- Copyright (c) 2011 - 2013, Intel Corporation. All rights reserved.<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
which accompanies this distribution. The full text of the license may be found at
@@ -488,15 +488,15 @@ InstallFirmwarePerformanceDataTable (
mFirmwarePerformanceTableTemplate.S3PointerRecord.S3PerformanceTablePointer = (UINT64) (UINTN) mAcpiS3PerformanceTable;
//
// Save Runtime Performance Table pointers to Variable.
- //
- Status = gRT->SetVariable (
- EFI_FIRMWARE_PERFORMANCE_VARIABLE_NAME,
- &gEfiFirmwarePerformanceGuid,
- EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,
- sizeof (PerformanceVariable),
- &PerformanceVariable
- );
- ASSERT_EFI_ERROR (Status);
+ // Don't check SetVariable return status. It doesn't impact FPDT table generation.
+ //
+ gRT->SetVariable (
+ EFI_FIRMWARE_PERFORMANCE_VARIABLE_NAME,
+ &gEfiFirmwarePerformanceGuid,
+ EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,
+ sizeof (PerformanceVariable),
+ &PerformanceVariable
+ );
//
// Publish Firmware Performance Data Table.
diff --git a/MdeModulePkg/Universal/Console/TerminalDxe/Terminal.c b/MdeModulePkg/Universal/Console/TerminalDxe/Terminal.c
index 14f49ee75..966fb79ce 100644
--- a/MdeModulePkg/Universal/Console/TerminalDxe/Terminal.c
+++ b/MdeModulePkg/Universal/Console/TerminalDxe/Terminal.c
@@ -2,7 +2,7 @@
Produces Simple Text Input Protocol, Simple Text Input Extended Protocol and
Simple Text Output Protocol upon Serial IO Protocol.
-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 of the BSD License
which accompanies this distribution. The full text of the license may be found at
@@ -1422,11 +1422,13 @@ TerminalUpdateConsoleDevVariable (
)
{
EFI_STATUS Status;
+ UINTN NameSize;
UINTN VariableSize;
UINT8 TerminalType;
EFI_DEVICE_PATH_PROTOCOL *Variable;
EFI_DEVICE_PATH_PROTOCOL *NewVariable;
EFI_DEVICE_PATH_PROTOCOL *TempDevicePath;
+ EDKII_SET_VARIABLE_STATUS *SetVariableStatus;
//
// Get global variable and its size according to the name given.
@@ -1442,6 +1444,7 @@ TerminalUpdateConsoleDevVariable (
for (TerminalType = PCANSITYPE; TerminalType <= VTUTF8TYPE; TerminalType++) {
SetTerminalDevicePath (TerminalType, ParentDevicePath, &TempDevicePath);
NewVariable = AppendDevicePathInstance (Variable, TempDevicePath);
+ ASSERT (NewVariable != NULL);
if (Variable != NULL) {
FreePool (Variable);
}
@@ -1462,7 +1465,33 @@ TerminalUpdateConsoleDevVariable (
VariableSize,
Variable
);
- ASSERT_EFI_ERROR (Status);
+
+ if (EFI_ERROR (Status)) {
+ NameSize = StrSize (VariableName);
+ SetVariableStatus = AllocatePool (sizeof (EDKII_SET_VARIABLE_STATUS) + NameSize + VariableSize);
+ if (SetVariableStatus != NULL) {
+ CopyGuid (&SetVariableStatus->Guid, &gEfiGlobalVariableGuid);
+ SetVariableStatus->NameSize = NameSize;
+ SetVariableStatus->DataSize = VariableSize;
+ SetVariableStatus->SetStatus = Status;
+ SetVariableStatus->Attributes = EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS;
+ CopyMem (SetVariableStatus + 1, VariableName, NameSize);
+ CopyMem (((UINT8 *) (SetVariableStatus + 1)) + NameSize, Variable, VariableSize);
+
+ REPORT_STATUS_CODE_EX (
+ EFI_ERROR_CODE,
+ PcdGet32 (PcdErrorCodeSetVariable),
+ 0,
+ NULL,
+ &gEdkiiStatusCodeDataTypeVariableGuid,
+ SetVariableStatus,
+ sizeof (EDKII_SET_VARIABLE_STATUS) + NameSize + VariableSize
+ );
+
+ FreePool (SetVariableStatus);
+ }
+ }
+
FreePool (Variable);
return ;
@@ -1570,6 +1599,9 @@ TerminalRemoveConsoleDevVariable (
VariableSize,
NewVariable
);
+ //
+ // Shrinking variable with existing variable driver implementation shouldn't fail.
+ //
ASSERT_EFI_ERROR (Status);
}
diff --git a/MdeModulePkg/Universal/Console/TerminalDxe/Terminal.h b/MdeModulePkg/Universal/Console/TerminalDxe/Terminal.h
index 0f285eb28..d393acbc2 100644
--- a/MdeModulePkg/Universal/Console/TerminalDxe/Terminal.h
+++ b/MdeModulePkg/Universal/Console/TerminalDxe/Terminal.h
@@ -20,6 +20,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#include <Guid/GlobalVariable.h>
#include <Guid/PcAnsi.h>
+#include <Guid/StatusCodeDataTypeVariable.h>
#include <Protocol/SimpleTextOut.h>
#include <Protocol/SerialIo.h>
diff --git a/MdeModulePkg/Universal/Console/TerminalDxe/TerminalDxe.inf b/MdeModulePkg/Universal/Console/TerminalDxe/TerminalDxe.inf
index d4bd55b4a..661175185 100644
--- a/MdeModulePkg/Universal/Console/TerminalDxe/TerminalDxe.inf
+++ b/MdeModulePkg/Universal/Console/TerminalDxe/TerminalDxe.inf
@@ -4,7 +4,7 @@
#
# This driver installs Simple Text In/Out protocol for terminal devices (serial devices or hotplug devices).
#
-# Copyright (c) 2006 - 2010, 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
@@ -65,6 +65,7 @@
gEfiVT100Guid ## SOMETIMES_CONSUMES ## GUID
gEfiVT100PlusGuid ## SOMETIMES_CONSUMES ## GUID
gEfiPcAnsiGuid ## SOMETIMES_CONSUMES ## GUID
+ gEdkiiStatusCodeDataTypeVariableGuid ## SOMETIMES_CONSUMES ## GUID
[Protocols]
gEfiSerialIoProtocolGuid ## TO_START
@@ -75,6 +76,7 @@
[Pcd]
gEfiMdePkgTokenSpaceGuid.PcdDefaultTerminalType
+ gEfiMdeModulePkgTokenSpaceGuid.PcdErrorCodeSetVariable
# [Event]
# ##
diff --git a/MdeModulePkg/Universal/DriverSampleDxe/DriverSample.c b/MdeModulePkg/Universal/DriverSampleDxe/DriverSample.c
index d79a81a6d..10eef0509 100644
--- a/MdeModulePkg/Universal/DriverSampleDxe/DriverSample.c
+++ b/MdeModulePkg/Universal/DriverSampleDxe/DriverSample.c
@@ -2,7 +2,7 @@
This is an example of how a driver might export data to the HII protocol to be
later utilized by the Setup Protocol
-Copyright (c) 2004 - 2013, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2004 - 2014, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
@@ -1981,25 +1981,40 @@ DriverSampleInit (
sizeof (DRIVER_SAMPLE_CONFIGURATION),
Configuration
);
- ASSERT (Status == EFI_SUCCESS);
+ if (EFI_ERROR (Status)) {
+ DriverSampleUnload (ImageHandle);
+ return Status;
+ }
//
// EFI variable for NV config doesn't exit, we should build this variable
// based on default values stored in IFR
//
ActionFlag = HiiSetToDefaults (NameRequestHdr, EFI_HII_DEFAULT_CLASS_STANDARD);
- ASSERT (ActionFlag);
+ if (!ActionFlag) {
+ DriverSampleUnload (ImageHandle);
+ return EFI_INVALID_PARAMETER;
+ }
ActionFlag = HiiSetToDefaults (ConfigRequestHdr, EFI_HII_DEFAULT_CLASS_STANDARD);
- ASSERT (ActionFlag);
+ if (!ActionFlag) {
+ DriverSampleUnload (ImageHandle);
+ return EFI_INVALID_PARAMETER;
+ }
} else {
//
// EFI variable does exist and Validate Current Setting
//
ActionFlag = HiiValidateSettings (NameRequestHdr);
- ASSERT (ActionFlag);
+ if (!ActionFlag) {
+ DriverSampleUnload (ImageHandle);
+ return EFI_INVALID_PARAMETER;
+ }
ActionFlag = HiiValidateSettings (ConfigRequestHdr);
- ASSERT (ActionFlag);
+ if (!ActionFlag) {
+ DriverSampleUnload (ImageHandle);
+ return EFI_INVALID_PARAMETER;
+ }
}
FreePool (ConfigRequestHdr);
@@ -2025,19 +2040,28 @@ DriverSampleInit (
sizeof (MY_EFI_VARSTORE_DATA),
VarStoreConfig
);
- ASSERT (Status == EFI_SUCCESS);
+ if (EFI_ERROR (Status)) {
+ DriverSampleUnload (ImageHandle);
+ return Status;
+ }
//
// EFI variable for NV config doesn't exit, we should build this variable
// based on default values stored in IFR
//
ActionFlag = HiiSetToDefaults (ConfigRequestHdr, EFI_HII_DEFAULT_CLASS_STANDARD);
- ASSERT (ActionFlag);
+ if (!ActionFlag) {
+ DriverSampleUnload (ImageHandle);
+ return EFI_INVALID_PARAMETER;
+ }
} else {
//
// EFI variable does exist and Validate Current Setting
//
ActionFlag = HiiValidateSettings (ConfigRequestHdr);
- ASSERT (ActionFlag);
+ if (!ActionFlag) {
+ DriverSampleUnload (ImageHandle);
+ return EFI_INVALID_PARAMETER;
+ }
}
FreePool (ConfigRequestHdr);
diff --git a/MdeModulePkg/Universal/Network/MnpDxe/MnpVlan.c b/MdeModulePkg/Universal/Network/MnpDxe/MnpVlan.c
index aa7da980d..6e14c1f37 100644
--- a/MdeModulePkg/Universal/Network/MnpDxe/MnpVlan.c
+++ b/MdeModulePkg/Universal/Network/MnpDxe/MnpVlan.c
@@ -1,7 +1,7 @@
/** @file
VLAN Config Protocol implementation and VLAN packet process routine.
-Copyright (c) 2009 - 2013, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2009 - 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
@@ -320,7 +320,7 @@ MnpSetVlanVariable (
return gRT->SetVariable (
MnpDeviceData->MacString,
&gEfiVlanConfigProtocolGuid,
- EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
+ EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,
NumberOfVlan * sizeof (VLAN_TCI),
VlanVariable
);
diff --git a/MdeModulePkg/Universal/Network/SnpDxe/Station_address.c b/MdeModulePkg/Universal/Network/SnpDxe/Station_address.c
index 380718868..0917baf67 100644
--- a/MdeModulePkg/Universal/Network/SnpDxe/Station_address.c
+++ b/MdeModulePkg/Universal/Network/SnpDxe/Station_address.c
@@ -1,7 +1,7 @@
/** @file
Implementation of reading the MAC address of a network adapter.
-Copyright (c) 2004 - 2007, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2004 - 2014, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials are licensed
and made available under the terms and conditions of the BSD License which
accompanies this distribution. The full text of the license may be found at
@@ -117,10 +117,9 @@ PxeSetStnAddr (
Snp->Cdb.CPBsize = PXE_CPBSIZE_NOT_USED;
Snp->Cdb.CPBaddr = PXE_CPBADDR_NOT_USED;
} else {
- Snp->Cdb.OpFlags = PXE_OPFLAGS_STATION_ADDRESS_READ;
+ Snp->Cdb.OpFlags = PXE_OPFLAGS_STATION_ADDRESS_WRITE;
//
- // even though the OPFLAGS are set to READ, supplying a new address
- // in the CPB will make undi change the mac address to the new one.
+ // Supplying a new address in the CPB will make undi change the mac address to the new one.
//
CopyMem (&Cpb->StationAddr, NewMacAddr, Snp->Mode.HwAddressSize);
diff --git a/MdeModulePkg/Universal/PCD/Dxe/Service.c b/MdeModulePkg/Universal/PCD/Dxe/Service.c
index a9e1ca49a..4cbf6dd20 100644
--- a/MdeModulePkg/Universal/PCD/Dxe/Service.c
+++ b/MdeModulePkg/Universal/PCD/Dxe/Service.c
@@ -1,7 +1,7 @@
/** @file
Help functions used by PCD DXE driver.
-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
@@ -457,25 +457,33 @@ GetWorker (
// string array in string table.
//
StringTableIdx = *(STRING_HEAD*)((UINT8 *) PcdDb + VariableHead->DefaultValueOffset);
- VaraiableDefaultBuffer = (VOID *) (StringTable + StringTableIdx);
+ VaraiableDefaultBuffer = (UINT8 *) (StringTable + StringTableIdx);
} else {
VaraiableDefaultBuffer = (UINT8 *) PcdDb + VariableHead->DefaultValueOffset;
}
Status = GetHiiVariable (Guid, Name, &Data, &DataSize);
if (Status == EFI_SUCCESS) {
- if (GetSize == 0) {
+ if (DataSize >= (VariableHead->Offset + GetSize)) {
+ if (GetSize == 0) {
+ //
+ // It is a pointer type. So get the MaxSize reserved for
+ // this PCD entry.
+ //
+ GetPtrTypeSize (TmpTokenNumber, &GetSize);
+ if (GetSize > (DataSize - VariableHead->Offset)) {
+ //
+ // Use actual valid size.
+ //
+ GetSize = DataSize - VariableHead->Offset;
+ }
+ }
//
- // It is a pointer type. So get the MaxSize reserved for
- // this PCD entry.
+ // If the operation is successful, we copy the data
+ // to the default value buffer in the PCD Database.
+ // So that we can free the Data allocated in GetHiiVariable.
//
- GetPtrTypeSize (TmpTokenNumber, &GetSize);
+ CopyMem (VaraiableDefaultBuffer, Data + VariableHead->Offset, GetSize);
}
- //
- // If the operation is successful, we copy the data
- // to the default value buffer in the PCD Database.
- // So that we can free the Data allocated in GetHiiVariable.
- //
- CopyMem (VaraiableDefaultBuffer, Data + VariableHead->Offset, GetSize);
FreePool (Data);
}
RetPtr = (VOID *) VaraiableDefaultBuffer;
diff --git a/MdeModulePkg/Universal/PCD/Pei/Service.c b/MdeModulePkg/Universal/PCD/Pei/Service.c
index 4fb8b4a68..af40db831 100644
--- a/MdeModulePkg/Universal/PCD/Pei/Service.c
+++ b/MdeModulePkg/Universal/PCD/Pei/Service.c
@@ -2,7 +2,7 @@
The driver internal functions are implmented here.
They build Pei PCD database, and provide access service to PCD database.
-Copyright (c) 2006 - 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
@@ -947,6 +947,7 @@ GetWorker (
PEI_PCD_DATABASE *PeiPcdDb;
UINT32 LocalTokenNumber;
UINT32 LocalTokenCount;
+ UINT8 *VaraiableDefaultBuffer;
//
// TokenNumber Zero is reserved as PCD_INVALID_TOKEN_NUMBER.
@@ -986,20 +987,37 @@ GetWorker (
Guid = (EFI_GUID *) ((UINT8 *)PeiPcdDb + PeiPcdDb->GuidTableOffset) + VariableHead->GuidTableIndex;
Name = (UINT16*)&StringTable[VariableHead->StringIndex];
- Status = GetHiiVariable (Guid, Name, &Data, &DataSize);
-
- if (Status == EFI_SUCCESS) {
- return (VOID *) ((UINT8 *) Data + VariableHead->Offset);
- } else {
+ if ((LocalTokenNumber & PCD_TYPE_ALL_SET) == (PCD_TYPE_HII|PCD_TYPE_STRING)) {
//
- // Return the default value specified by Platform Integrator
+ // If a HII type PCD's datum type is VOID*, the DefaultValueOffset is the index of
+ // string array in string table.
//
- if ((LocalTokenNumber & PCD_TYPE_ALL_SET) == (PCD_TYPE_HII|PCD_TYPE_STRING)) {
- return (VOID*)&StringTable[*(STRING_HEAD*)((UINT8*)PeiPcdDb + VariableHead->DefaultValueOffset)];
- } else {
- return (VOID *) ((UINT8 *) PeiPcdDb + VariableHead->DefaultValueOffset);
+ VaraiableDefaultBuffer = (UINT8 *) &StringTable[*(STRING_HEAD*)((UINT8*) PeiPcdDb + VariableHead->DefaultValueOffset)];
+ } else {
+ VaraiableDefaultBuffer = (UINT8 *) PeiPcdDb + VariableHead->DefaultValueOffset;
+ }
+ Status = GetHiiVariable (Guid, Name, &Data, &DataSize);
+ if ((Status == EFI_SUCCESS) && (DataSize >= (VariableHead->Offset + GetSize))) {
+ if (GetSize == 0) {
+ //
+ // It is a pointer type. So get the MaxSize reserved for
+ // this PCD entry.
+ //
+ GetPtrTypeSize (TokenNumber, &GetSize, PeiPcdDb);
+ if (GetSize > (DataSize - VariableHead->Offset)) {
+ //
+ // Use actual valid size.
+ //
+ GetSize = DataSize - VariableHead->Offset;
+ }
}
+ //
+ // If the operation is successful, we copy the data
+ // to the default value buffer in the PCD Database.
+ //
+ CopyMem (VaraiableDefaultBuffer, (UINT8 *) Data + VariableHead->Offset, GetSize);
}
+ return (VOID *) VaraiableDefaultBuffer;
}
case PCD_TYPE_DATA:
diff --git a/MdeModulePkg/Universal/PlatformDriOverrideDxe/PlatDriOverrideDxe.c b/MdeModulePkg/Universal/PlatformDriOverrideDxe/PlatDriOverrideDxe.c
index ab254a0b4..3c55a785f 100644
--- a/MdeModulePkg/Universal/PlatformDriOverrideDxe/PlatDriOverrideDxe.c
+++ b/MdeModulePkg/Universal/PlatformDriOverrideDxe/PlatDriOverrideDxe.c
@@ -13,7 +13,7 @@
4. It save all the mapping info in NV variables which will be consumed
by platform override protocol driver to publish the platform override protocol.
-Copyright (c) 2007 - 2013, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2007 - 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
@@ -1240,6 +1240,7 @@ PlatOverMngrRouteConfig (
EFI_CALLBACK_INFO *Private;
UINT16 KeyValue;
PLAT_OVER_MNGR_DATA *FakeNvData;
+ EFI_STATUS Status;
if (Configuration == NULL || Progress == NULL) {
return EFI_INVALID_PARAMETER;
@@ -1260,11 +1261,12 @@ PlatOverMngrRouteConfig (
return EFI_SUCCESS;
}
+ Status = EFI_SUCCESS;
if (mCurrentPage == FORM_ID_DRIVER) {
KeyValue = KEY_VALUE_DRIVER_GOTO_ORDER;
UpdatePrioritySelectPage (Private, KeyValue, FakeNvData);
KeyValue = KEY_VALUE_ORDER_SAVE_AND_EXIT;
- CommintChanges (Private, KeyValue, FakeNvData);
+ Status = CommintChanges (Private, KeyValue, FakeNvData);
//
// Since UpdatePrioritySelectPage will change mCurrentPage,
// should ensure the mCurrentPage still indicate the second page here
@@ -1274,10 +1276,10 @@ PlatOverMngrRouteConfig (
if (mCurrentPage == FORM_ID_ORDER) {
KeyValue = KEY_VALUE_ORDER_SAVE_AND_EXIT;
- CommintChanges (Private, KeyValue, FakeNvData);
+ Status = CommintChanges (Private, KeyValue, FakeNvData);
}
- return EFI_SUCCESS;
+ return Status;
}
/**
diff --git a/MdeModulePkg/Universal/PlatformDriOverrideDxe/PlatDriOverrideLib.c b/MdeModulePkg/Universal/PlatformDriOverrideDxe/PlatDriOverrideLib.c
index 2391ade21..bad8ecc35 100644
--- a/MdeModulePkg/Universal/PlatformDriOverrideDxe/PlatDriOverrideLib.c
+++ b/MdeModulePkg/Universal/PlatformDriOverrideDxe/PlatDriOverrideLib.c
@@ -1,7 +1,7 @@
/** @file
Implementation of the shared functions to do the platform driver vverride mapping.
- Copyright (c) 2007 - 2009, Intel Corporation. All rights reserved.<BR>
+ Copyright (c) 2007 - 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
@@ -691,12 +691,17 @@ InitOverridesMapping (
//
VariableNum = 1;
Corrupted = FALSE;
+ NotEnd = 0;
do {
VariableIndex = VariableBuffer;
- //
- // End flag
- //
- NotEnd = *(UINT32*) VariableIndex;
+ if (VariableIndex + sizeof (UINT32) > (UINT8 *) VariableBuffer + BufferSize) {
+ Corrupted = TRUE;
+ } else {
+ //
+ // End flag
+ //
+ NotEnd = *(UINT32*) VariableIndex;
+ }
//
// Traverse the entries containing the mapping that Controller Device Path
// to a set of Driver Device Paths within this variable.
@@ -706,6 +711,10 @@ InitOverridesMapping (
//
// Check signature of this entry
//
+ if (VariableIndex + sizeof (UINT32) > (UINT8 *) VariableBuffer + BufferSize) {
+ Corrupted = TRUE;
+ break;
+ }
Signature = *(UINT32 *) VariableIndex;
if (Signature != PLATFORM_OVERRIDE_ITEM_SIGNATURE) {
Corrupted = TRUE;
@@ -722,6 +731,10 @@ InitOverridesMapping (
//
// Get DriverNum
//
+ if (VariableIndex + sizeof (UINT32) >= (UINT8 *) VariableBuffer + BufferSize) {
+ Corrupted = TRUE;
+ break;
+ }
DriverNumber = *(UINT32*) VariableIndex;
OverrideItem->DriverInfoNum = DriverNumber;
VariableIndex = VariableIndex + sizeof (UINT32);
@@ -735,6 +748,14 @@ InitOverridesMapping (
// Align the VariableIndex since the controller device path may not be aligned, refer to the SaveOverridesMapping()
//
VariableIndex += ((sizeof(UINT32) - ((UINTN) (VariableIndex))) & (sizeof(UINT32) - 1));
+ //
+ // Check buffer overflow.
+ //
+ if ((OverrideItem->ControllerDevicePath == NULL) || (VariableIndex < (UINT8 *) ControllerDevicePath) ||
+ (VariableIndex > (UINT8 *) VariableBuffer + BufferSize)) {
+ Corrupted = TRUE;
+ break;
+ }
//
// Get all DriverImageDevicePath[]
@@ -756,8 +777,20 @@ InitOverridesMapping (
VariableIndex += ((sizeof(UINT32) - ((UINTN) (VariableIndex))) & (sizeof(UINT32) - 1));
InsertTailList (&OverrideItem->DriverInfoList, &DriverImageInfo->Link);
+
+ //
+ // Check buffer overflow
+ //
+ if ((DriverImageInfo->DriverImagePath == NULL) || (VariableIndex < (UINT8 *) DriverDevicePath) ||
+ (VariableIndex < (UINT8 *) VariableBuffer + BufferSize)) {
+ Corrupted = TRUE;
+ break;
+ }
}
InsertTailList (MappingDataBase, &OverrideItem->Link);
+ if (Corrupted) {
+ break;
+ }
}
FreePool (VariableBuffer);
@@ -866,11 +899,11 @@ DeleteOverridesVariables (
//
// Check NotEnd to get all PlatDriOverX variable(s)
//
- while ((*(UINT32*)VariableBuffer) != 0) {
+ while ((VariableBuffer != NULL) && ((*(UINT32*)VariableBuffer) != 0)) {
+ FreePool (VariableBuffer);
UnicodeSPrint (OverrideVariableName, sizeof (OverrideVariableName), L"PlatDriOver%d", VariableNum);
VariableBuffer = GetVariableAndSize (OverrideVariableName, &gEfiCallerIdGuid, &BufferSize);
VariableNum++;
- ASSERT (VariableBuffer != NULL);
}
//
@@ -879,7 +912,7 @@ DeleteOverridesVariables (
Status = gRT->SetVariable (
L"PlatDriOver",
&gEfiCallerIdGuid,
- EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
+ EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE,
0,
NULL
);
@@ -889,7 +922,7 @@ DeleteOverridesVariables (
Status = gRT->SetVariable (
OverrideVariableName,
&gEfiCallerIdGuid,
- EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
+ EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE,
0,
NULL
);
@@ -944,7 +977,7 @@ SaveOverridesMapping (
// Get the the maximum size of an individual EFI variable in current system
//
gRT->QueryVariableInfo (
- EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
+ EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE,
&MaximumVariableStorageSize,
&RemainingVariableStorageSize,
&MaximumVariableSize
@@ -1053,14 +1086,23 @@ SaveOverridesMapping (
Status = gRT->SetVariable (
OverrideVariableName,
&gEfiCallerIdGuid,
- EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
+ EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE,
VariableNeededSize,
VariableBuffer
);
- ASSERT (!EFI_ERROR(Status));
+ FreePool (VariableBuffer);
+
+ if (EFI_ERROR (Status)) {
+ if (NumIndex > 0) {
+ //
+ // Delete all PlatDriOver variables when full mapping can't be set.
+ //
+ DeleteOverridesVariables ();
+ }
+ return Status;
+ }
NumIndex ++;
- FreePool (VariableBuffer);
}
return EFI_SUCCESS;
diff --git a/MdeModulePkg/Universal/PlatformDriOverrideDxe/PlatformDriOverrideDxe.inf b/MdeModulePkg/Universal/PlatformDriOverrideDxe/PlatformDriOverrideDxe.inf
index 9702f249b..2a59f65c4 100644
--- a/MdeModulePkg/Universal/PlatformDriOverrideDxe/PlatformDriOverrideDxe.inf
+++ b/MdeModulePkg/Universal/PlatformDriOverrideDxe/PlatformDriOverrideDxe.inf
@@ -16,7 +16,9 @@
# 4. It save all the mapping info in NV variables for the following boot,
# which will be consumed by GetDriver API of the produced the platform override protocol.
#
-# Copyright (c) 2007 - 2013, Intel Corporation. All rights reserved.<BR>
+# Caution: This module is a sample implementation for the test purpose.
+#
+# Copyright (c) 2007 - 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
diff --git a/MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.c b/MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.c
index c66eb8750..7bd9ffb6c 100644
--- a/MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.c
+++ b/MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.c
@@ -3,7 +3,7 @@
The common variable operation routines shared by DXE_RUNTIME variable
module and DXE_SMM variable module.
-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
@@ -1259,6 +1259,134 @@ VariableGetBestLanguage (
}
/**
+ This function is to check if the remaining variable space is enough to set
+ all Variables from argument list successfully. The purpose of the check
+ is to keep the consistency of the Variables to be in variable storage.
+
+ Note: Variables are assumed to be in same storage.
+ The set sequence of Variables will be same with the sequence of VariableEntry from argument list,
+ so follow the argument sequence to check the Variables.
+
+ @param[in] Attributes Variable attributes for Variable entries.
+ @param ... The variable argument list with type VARIABLE_ENTRY_CONSISTENCY *.
+ A NULL terminates the list. The VariableSize of
+ VARIABLE_ENTRY_CONSISTENCY is the variable data size as input.
+ It will be changed to variable total size as output.
+
+ @retval TRUE Have enough variable space to set the Variables successfully.
+ @retval FALSE No enough variable space to set the Variables successfully.
+
+**/
+BOOLEAN
+EFIAPI
+CheckRemainingSpaceForConsistency (
+ IN UINT32 Attributes,
+ ...
+ )
+{
+ EFI_STATUS Status;
+ VA_LIST Args;
+ VARIABLE_ENTRY_CONSISTENCY *VariableEntry;
+ UINT64 MaximumVariableStorageSize;
+ UINT64 RemainingVariableStorageSize;
+ UINT64 MaximumVariableSize;
+ UINTN TotalNeededSize;
+ UINTN OriginalVarSize;
+ VARIABLE_STORE_HEADER *VariableStoreHeader;
+ VARIABLE_POINTER_TRACK VariablePtrTrack;
+ VARIABLE_HEADER *NextVariable;
+ UINTN VarNameSize;
+ UINTN VarDataSize;
+
+ //
+ // Non-Volatile related.
+ //
+ VariableStoreHeader = mNvVariableCache;
+
+ Status = VariableServiceQueryVariableInfoInternal (
+ Attributes,
+ &MaximumVariableStorageSize,
+ &RemainingVariableStorageSize,
+ &MaximumVariableSize
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ TotalNeededSize = 0;
+ VA_START (Args, Attributes);
+ VariableEntry = VA_ARG (Args, VARIABLE_ENTRY_CONSISTENCY *);
+ while (VariableEntry != NULL) {
+ //
+ // Calculate variable total size.
+ //
+ VarNameSize = StrSize (VariableEntry->Name);
+ VarNameSize += GET_PAD_SIZE (VarNameSize);
+ VarDataSize = VariableEntry->VariableSize;
+ VarDataSize += GET_PAD_SIZE (VarDataSize);
+ VariableEntry->VariableSize = HEADER_ALIGN (sizeof (VARIABLE_HEADER) + VarNameSize + VarDataSize);
+
+ TotalNeededSize += VariableEntry->VariableSize;
+ VariableEntry = VA_ARG (Args, VARIABLE_ENTRY_CONSISTENCY *);
+ }
+ VA_END (Args);
+
+ if (RemainingVariableStorageSize >= TotalNeededSize) {
+ //
+ // Already have enough space.
+ //
+ return TRUE;
+ } else if (AtRuntime ()) {
+ //
+ // At runtime, no reclaim.
+ // The original variable space of Variables can't be reused.
+ //
+ return FALSE;
+ }
+
+ VA_START (Args, Attributes);
+ VariableEntry = VA_ARG (Args, VARIABLE_ENTRY_CONSISTENCY *);
+ while (VariableEntry != NULL) {
+ //
+ // Check if Variable[Index] has been present and get its size.
+ //
+ OriginalVarSize = 0;
+ VariablePtrTrack.StartPtr = GetStartPointer (VariableStoreHeader);
+ VariablePtrTrack.EndPtr = GetEndPointer (VariableStoreHeader);
+ Status = FindVariableEx (
+ VariableEntry->Name,
+ VariableEntry->Guid,
+ FALSE,
+ &VariablePtrTrack
+ );
+ if (!EFI_ERROR (Status)) {
+ //
+ // Get size of Variable[Index].
+ //
+ NextVariable = GetNextVariablePtr (VariablePtrTrack.CurrPtr);
+ OriginalVarSize = (UINTN) NextVariable - (UINTN) VariablePtrTrack.CurrPtr;
+ //
+ // Add the original size of Variable[Index] to remaining variable storage size.
+ //
+ RemainingVariableStorageSize += OriginalVarSize;
+ }
+ if (VariableEntry->VariableSize > RemainingVariableStorageSize) {
+ //
+ // No enough space for Variable[Index].
+ //
+ VA_END (Args);
+ return FALSE;
+ }
+ //
+ // Sub the (new) size of Variable[Index] from remaining variable storage size.
+ //
+ RemainingVariableStorageSize -= VariableEntry->VariableSize;
+ VariableEntry = VA_ARG (Args, VARIABLE_ENTRY_CONSISTENCY *);
+ }
+ VA_END (Args);
+
+ return TRUE;
+}
+
+/**
Hook the operations in PlatformLangCodes, LangCodes, PlatformLang and Lang.
When setting Lang/LangCodes, simultaneously update PlatformLang/PlatformLangCodes.
@@ -1272,8 +1400,13 @@ VariableGetBestLanguage (
@param[in] DataSize Size of data. 0 means delete.
+ @retval EFI_SUCCESS The update operation is successful or ignored.
+ @retval EFI_WRITE_PROTECTED Update PlatformLangCodes/LangCodes at runtime.
+ @retval EFI_OUT_OF_RESOURCES No enough variable space to do the update operation.
+ @retval Others Other errors happened during the update operation.
+
**/
-VOID
+EFI_STATUS
AutoUpdateLangVariable (
IN CHAR16 *VariableName,
IN VOID *Data,
@@ -1287,12 +1420,13 @@ AutoUpdateLangVariable (
UINT32 Attributes;
VARIABLE_POINTER_TRACK Variable;
BOOLEAN SetLanguageCodes;
+ VARIABLE_ENTRY_CONSISTENCY VariableEntry[2];
//
// Don't do updates for delete operation
//
if (DataSize == 0) {
- return;
+ return EFI_SUCCESS;
}
SetLanguageCodes = FALSE;
@@ -1302,7 +1436,7 @@ AutoUpdateLangVariable (
// PlatformLangCodes is a volatile variable, so it can not be updated at runtime.
//
if (AtRuntime ()) {
- return;
+ return EFI_WRITE_PROTECTED;
}
SetLanguageCodes = TRUE;
@@ -1332,7 +1466,7 @@ AutoUpdateLangVariable (
// LangCodes is a volatile variable, so it can not be updated at runtime.
//
if (AtRuntime ()) {
- return;
+ return EFI_WRITE_PROTECTED;
}
SetLanguageCodes = TRUE;
@@ -1376,11 +1510,13 @@ AutoUpdateLangVariable (
//
// Neither PlatformLang nor Lang is set, directly return
//
- return;
+ return EFI_SUCCESS;
}
}
}
-
+
+ Status = EFI_SUCCESS;
+
//
// According to UEFI spec, "Lang" and "PlatformLang" is NV|BS|RT attributions.
//
@@ -1407,16 +1543,31 @@ AutoUpdateLangVariable (
BestLang = GetLangFromSupportedLangCodes (mVariableModuleGlobal->LangCodes, Index, TRUE);
//
- // Successfully convert PlatformLang to Lang, and set the BestLang value into Lang variable simultaneously.
+ // Check the variable space for both Lang and PlatformLang variable.
//
- FindVariable (EFI_LANG_VARIABLE_NAME, &gEfiGlobalVariableGuid, &Variable, &mVariableModuleGlobal->VariableGlobal, FALSE);
-
- Status = UpdateVariable (EFI_LANG_VARIABLE_NAME, &gEfiGlobalVariableGuid, BestLang,
- ISO_639_2_ENTRY_SIZE + 1, Attributes, &Variable);
+ VariableEntry[0].VariableSize = ISO_639_2_ENTRY_SIZE + 1;
+ VariableEntry[0].Guid = &gEfiGlobalVariableGuid;
+ VariableEntry[0].Name = EFI_LANG_VARIABLE_NAME;
+
+ VariableEntry[1].VariableSize = AsciiStrSize (BestPlatformLang);
+ VariableEntry[1].Guid = &gEfiGlobalVariableGuid;
+ VariableEntry[1].Name = EFI_PLATFORM_LANG_VARIABLE_NAME;
+ if (!CheckRemainingSpaceForConsistency (VARIABLE_ATTRIBUTE_NV_BS_RT, &VariableEntry[0], &VariableEntry[1], NULL)) {
+ //
+ // No enough variable space to set both Lang and PlatformLang successfully.
+ //
+ Status = EFI_OUT_OF_RESOURCES;
+ } else {
+ //
+ // Successfully convert PlatformLang to Lang, and set the BestLang value into Lang variable simultaneously.
+ //
+ FindVariable (EFI_LANG_VARIABLE_NAME, &gEfiGlobalVariableGuid, &Variable, &mVariableModuleGlobal->VariableGlobal, FALSE);
- DEBUG ((EFI_D_INFO, "Variable Driver Auto Update PlatformLang, PlatformLang:%a, Lang:%a\n", BestPlatformLang, BestLang));
+ Status = UpdateVariable (EFI_LANG_VARIABLE_NAME, &gEfiGlobalVariableGuid, BestLang,
+ ISO_639_2_ENTRY_SIZE + 1, Attributes, &Variable);
+ }
- ASSERT_EFI_ERROR(Status);
+ DEBUG ((EFI_D_INFO, "Variable Driver Auto Update PlatformLang, PlatformLang:%a, Lang:%a Status: %r\n", BestPlatformLang, BestLang, Status));
}
}
@@ -1441,18 +1592,43 @@ AutoUpdateLangVariable (
BestPlatformLang = GetLangFromSupportedLangCodes (mVariableModuleGlobal->PlatformLangCodes, Index, FALSE);
//
- // Successfully convert Lang to PlatformLang, and set the BestPlatformLang value into PlatformLang variable simultaneously.
+ // Check the variable space for both PlatformLang and Lang variable.
//
- FindVariable (EFI_PLATFORM_LANG_VARIABLE_NAME, &gEfiGlobalVariableGuid, &Variable, &mVariableModuleGlobal->VariableGlobal, FALSE);
+ VariableEntry[0].VariableSize = AsciiStrSize (BestPlatformLang);
+ VariableEntry[0].Guid = &gEfiGlobalVariableGuid;
+ VariableEntry[0].Name = EFI_PLATFORM_LANG_VARIABLE_NAME;
+
+ VariableEntry[1].VariableSize = ISO_639_2_ENTRY_SIZE + 1;
+ VariableEntry[1].Guid = &gEfiGlobalVariableGuid;
+ VariableEntry[1].Name = EFI_LANG_VARIABLE_NAME;
+ if (!CheckRemainingSpaceForConsistency (VARIABLE_ATTRIBUTE_NV_BS_RT, &VariableEntry[0], &VariableEntry[1], NULL)) {
+ //
+ // No enough variable space to set both PlatformLang and Lang successfully.
+ //
+ Status = EFI_OUT_OF_RESOURCES;
+ } else {
+ //
+ // Successfully convert Lang to PlatformLang, and set the BestPlatformLang value into PlatformLang variable simultaneously.
+ //
+ FindVariable (EFI_PLATFORM_LANG_VARIABLE_NAME, &gEfiGlobalVariableGuid, &Variable, &mVariableModuleGlobal->VariableGlobal, FALSE);
- Status = UpdateVariable (EFI_PLATFORM_LANG_VARIABLE_NAME, &gEfiGlobalVariableGuid, BestPlatformLang,
- AsciiStrSize (BestPlatformLang), Attributes, &Variable);
+ Status = UpdateVariable (EFI_PLATFORM_LANG_VARIABLE_NAME, &gEfiGlobalVariableGuid, BestPlatformLang,
+ AsciiStrSize (BestPlatformLang), Attributes, &Variable);
+ }
- DEBUG ((EFI_D_INFO, "Variable Driver Auto Update Lang, Lang:%a, PlatformLang:%a\n", BestLang, BestPlatformLang));
- ASSERT_EFI_ERROR (Status);
+ DEBUG ((EFI_D_INFO, "Variable Driver Auto Update Lang, Lang:%a, PlatformLang:%a Status: %r\n", BestLang, BestPlatformLang, Status));
}
}
}
+
+ if (SetLanguageCodes) {
+ //
+ // Continue to set PlatformLangCodes or LangCodes.
+ //
+ return EFI_SUCCESS;
+ } else {
+ return Status;
+ }
}
/**
@@ -2486,10 +2662,18 @@ VariableServiceSetVariable (
}
}
- //
- // Hook the operation of setting PlatformLangCodes/PlatformLang and LangCodes/Lang.
- //
- AutoUpdateLangVariable (VariableName, Data, DataSize);
+ if (!FeaturePcdGet (PcdUefiVariableDefaultLangDeprecate)) {
+ //
+ // Hook the operation of setting PlatformLangCodes/PlatformLang and LangCodes/Lang.
+ //
+ Status = AutoUpdateLangVariable (VariableName, Data, DataSize);
+ if (EFI_ERROR (Status)) {
+ //
+ // The auto update operation failed, directly return to avoid inconsistency between PlatformLang and Lang.
+ //
+ goto Done;
+ }
+ }
Status = UpdateVariable (VariableName, VendorGuid, Data, DataSize, Attributes, &Variable);
@@ -2513,14 +2697,12 @@ Done:
@param MaximumVariableSize Pointer to the maximum size of an individual EFI variables
associated with the attributes specified.
- @return EFI_INVALID_PARAMETER An invalid combination of attribute bits was supplied.
@return EFI_SUCCESS Query successfully.
- @return EFI_UNSUPPORTED The attribute is not supported on this platform.
**/
EFI_STATUS
EFIAPI
-VariableServiceQueryVariableInfo (
+VariableServiceQueryVariableInfoInternal (
IN UINT32 Attributes,
OUT UINT64 *MaximumVariableStorageSize,
OUT UINT64 *RemainingVariableStorageSize,
@@ -2533,43 +2715,12 @@ VariableServiceQueryVariableInfo (
VARIABLE_STORE_HEADER *VariableStoreHeader;
UINT64 CommonVariableTotalSize;
UINT64 HwErrVariableTotalSize;
+ EFI_STATUS Status;
+ VARIABLE_POINTER_TRACK VariablePtrTrack;
CommonVariableTotalSize = 0;
HwErrVariableTotalSize = 0;
- if(MaximumVariableStorageSize == NULL || RemainingVariableStorageSize == NULL || MaximumVariableSize == NULL || Attributes == 0) {
- return EFI_INVALID_PARAMETER;
- }
-
- if((Attributes & (EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_HARDWARE_ERROR_RECORD)) == 0) {
- //
- // Make sure the Attributes combination is supported by the platform.
- //
- return EFI_UNSUPPORTED;
- } else if ((Attributes & (EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS)) == EFI_VARIABLE_RUNTIME_ACCESS) {
- //
- // Make sure if runtime bit is set, boot service bit is set also.
- //
- return EFI_INVALID_PARAMETER;
- } else if (AtRuntime () && ((Attributes & EFI_VARIABLE_RUNTIME_ACCESS) == 0)) {
- //
- // Make sure RT Attribute is set if we are in Runtime phase.
- //
- return EFI_INVALID_PARAMETER;
- } else if ((Attributes & (EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_HARDWARE_ERROR_RECORD)) == EFI_VARIABLE_HARDWARE_ERROR_RECORD) {
- //
- // Make sure Hw Attribute is set with NV.
- //
- return EFI_INVALID_PARAMETER;
- } else if ((Attributes & EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS) != 0) {
- //
- // Not support authentiated variable write yet.
- //
- return EFI_UNSUPPORTED;
- }
-
- AcquireLockOnlyAtBootTime(&mVariableModuleGlobal->VariableGlobal.VariableServicesLock);
-
if((Attributes & EFI_VARIABLE_NON_VOLATILE) == 0) {
//
// Query is Volatile related.
@@ -2641,6 +2792,27 @@ VariableServiceQueryVariableInfo (
} else {
CommonVariableTotalSize += VariableSize;
}
+ } else if (Variable->State == (VAR_IN_DELETED_TRANSITION & VAR_ADDED)) {
+ //
+ // If it is a IN_DELETED_TRANSITION variable,
+ // and there is not also a same ADDED one at the same time,
+ // this IN_DELETED_TRANSITION variable is valid.
+ //
+ VariablePtrTrack.StartPtr = GetStartPointer (VariableStoreHeader);
+ VariablePtrTrack.EndPtr = GetEndPointer (VariableStoreHeader);
+ Status = FindVariableEx (
+ GetVariableNamePtr (Variable),
+ &Variable->VendorGuid,
+ FALSE,
+ &VariablePtrTrack
+ );
+ if (!EFI_ERROR (Status) && VariablePtrTrack.CurrPtr->State != VAR_ADDED) {
+ if ((Variable->Attributes & EFI_VARIABLE_HARDWARE_ERROR_RECORD) == EFI_VARIABLE_HARDWARE_ERROR_RECORD) {
+ HwErrVariableTotalSize += VariableSize;
+ } else {
+ CommonVariableTotalSize += VariableSize;
+ }
+ }
}
}
@@ -2662,10 +2834,81 @@ VariableServiceQueryVariableInfo (
*MaximumVariableSize = *RemainingVariableStorageSize - sizeof (VARIABLE_HEADER);
}
- ReleaseLockOnlyAtBootTime (&mVariableModuleGlobal->VariableGlobal.VariableServicesLock);
return EFI_SUCCESS;
}
+/**
+
+ This code returns information about the EFI variables.
+
+ @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
+ for the EFI variables associated with the attributes specified.
+ @param RemainingVariableStorageSize Pointer to the remaining size of the storage space available
+ for EFI variables associated with the attributes specified.
+ @param MaximumVariableSize Pointer to the maximum size of an individual EFI variables
+ associated with the attributes specified.
+
+ @return EFI_INVALID_PARAMETER An invalid combination of attribute bits was supplied.
+ @return EFI_SUCCESS Query successfully.
+ @return EFI_UNSUPPORTED The attribute is not supported on this platform.
+
+**/
+EFI_STATUS
+EFIAPI
+VariableServiceQueryVariableInfo (
+ IN UINT32 Attributes,
+ OUT UINT64 *MaximumVariableStorageSize,
+ OUT UINT64 *RemainingVariableStorageSize,
+ OUT UINT64 *MaximumVariableSize
+ )
+{
+ EFI_STATUS Status;
+
+ if(MaximumVariableStorageSize == NULL || RemainingVariableStorageSize == NULL || MaximumVariableSize == NULL || Attributes == 0) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if((Attributes & (EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_HARDWARE_ERROR_RECORD)) == 0) {
+ //
+ // Make sure the Attributes combination is supported by the platform.
+ //
+ return EFI_UNSUPPORTED;
+ } else if ((Attributes & (EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS)) == EFI_VARIABLE_RUNTIME_ACCESS) {
+ //
+ // Make sure if runtime bit is set, boot service bit is set also.
+ //
+ return EFI_INVALID_PARAMETER;
+ } else if (AtRuntime () && ((Attributes & EFI_VARIABLE_RUNTIME_ACCESS) == 0)) {
+ //
+ // Make sure RT Attribute is set if we are in Runtime phase.
+ //
+ return EFI_INVALID_PARAMETER;
+ } else if ((Attributes & (EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_HARDWARE_ERROR_RECORD)) == EFI_VARIABLE_HARDWARE_ERROR_RECORD) {
+ //
+ // Make sure Hw Attribute is set with NV.
+ //
+ return EFI_INVALID_PARAMETER;
+ } else if ((Attributes & (EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS | EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS | EFI_VARIABLE_APPEND_WRITE)) != 0) {
+ //
+ // Not support authenticated or append variable write yet.
+ //
+ return EFI_UNSUPPORTED;
+ }
+
+ AcquireLockOnlyAtBootTime(&mVariableModuleGlobal->VariableGlobal.VariableServicesLock);
+
+ Status = VariableServiceQueryVariableInfoInternal (
+ Attributes,
+ MaximumVariableStorageSize,
+ RemainingVariableStorageSize,
+ MaximumVariableSize
+ );
+
+ ReleaseLockOnlyAtBootTime (&mVariableModuleGlobal->VariableGlobal.VariableServicesLock);
+ return Status;
+}
/**
This function reclaims variable storage if free size is below the threshold.
diff --git a/MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.h b/MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.h
index 9c8626cdc..ac71f0c95 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 - 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
@@ -101,10 +101,8 @@ typedef struct {
typedef struct {
EFI_GUID *Guid;
CHAR16 *Name;
- UINT32 Attributes;
- UINTN DataSize;
- VOID *Data;
-} VARIABLE_CACHE_ENTRY;
+ UINTN VariableSize;
+} VARIABLE_ENTRY_CONSISTENCY;
typedef struct {
EFI_GUID Guid;
@@ -456,6 +454,31 @@ VariableServiceSetVariable (
@param MaximumVariableSize Pointer to the maximum size of an individual EFI variables
associated with the attributes specified.
+ @return EFI_SUCCESS Query successfully.
+
+**/
+EFI_STATUS
+EFIAPI
+VariableServiceQueryVariableInfoInternal (
+ IN UINT32 Attributes,
+ OUT UINT64 *MaximumVariableStorageSize,
+ OUT UINT64 *RemainingVariableStorageSize,
+ OUT UINT64 *MaximumVariableSize
+ );
+
+/**
+
+ This code returns information about the EFI variables.
+
+ @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
+ for the EFI variables associated with the attributes specified.
+ @param RemainingVariableStorageSize Pointer to the remaining size of the storage space available
+ for EFI variables associated with the attributes specified.
+ @param MaximumVariableSize Pointer to the maximum size of an individual EFI variables
+ associated with the attributes specified.
+
@return EFI_INVALID_PARAMETER An invalid combination of attribute bits was supplied.
@return EFI_SUCCESS Query successfully.
@return EFI_UNSUPPORTED The attribute is not supported on this platform.
diff --git a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf
index c712ba020..297a6da5a 100644
--- a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf
+++ b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf
@@ -2,7 +2,7 @@
# Component description file for Variable module.
#
# This module installs three EFI_RUNTIME_SERVICES: SetVariable, GetVariable, GetNextVariableName.
-# 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
@@ -80,7 +80,8 @@
gEfiMdeModulePkgTokenSpaceGuid.PcdHwErrStorageSize
[FeaturePcd]
- gEfiMdeModulePkgTokenSpaceGuid.PcdVariableCollectStatistics ## SOMETIME_CONSUMES (statistic the information of variable.)
+ gEfiMdeModulePkgTokenSpaceGuid.PcdVariableCollectStatistics ## CONSUMES # statistic the information of variable.
+ gEfiMdePkgTokenSpaceGuid.PcdUefiVariableDefaultLangDeprecate ## CONSUMES
[Depex]
TRUE
diff --git a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmm.inf b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmm.inf
index 36436b6db..1448240d1 100644
--- a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmm.inf
+++ b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmm.inf
@@ -14,7 +14,7 @@
# This external input must be validated carefully to avoid security issue like
# buffer overflow, integer overflow.
#
-# Copyright (c) 2010 - 2013, 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
@@ -89,7 +89,8 @@
gEfiMdeModulePkgTokenSpaceGuid.PcdHwErrStorageSize
[FeaturePcd]
- gEfiMdeModulePkgTokenSpaceGuid.PcdVariableCollectStatistics ## SOMETIME_CONSUMES (statistic the information of variable.)
+ gEfiMdeModulePkgTokenSpaceGuid.PcdVariableCollectStatistics ## CONSUMES # statistic the information of variable.
+ gEfiMdePkgTokenSpaceGuid.PcdUefiVariableDefaultLangDeprecate ## CONSUMES
[Depex]
TRUE
diff --git a/MdePkg/Include/Protocol/Ip4Config.h b/MdePkg/Include/Protocol/Ip4Config.h
index cfd82f1f1..1c91d2f70 100644
--- a/MdePkg/Include/Protocol/Ip4Config.h
+++ b/MdePkg/Include/Protocol/Ip4Config.h
@@ -2,7 +2,7 @@
This file provides a definition of the EFI IPv4 Configuration
Protocol.
-Copyright (c) 2006 - 2010, 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 that accompanies this distribution.
The full text of the license may be found at
@@ -28,8 +28,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
typedef struct _EFI_IP4_CONFIG_PROTOCOL EFI_IP4_CONFIG_PROTOCOL;
#define IP4_CONFIG_VARIABLE_ATTRIBUTES \
- (EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | \
- EFI_VARIABLE_RUNTIME_ACCESS)
+ (EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS)
///
/// EFI_IP4_IPCONFIG_DATA contains the minimum IPv4 configuration data
diff --git a/MdePkg/Library/BasePeCoffLib/BasePeCoff.c b/MdePkg/Library/BasePeCoffLib/BasePeCoff.c
index d9e8809e5..33cad23a0 100644
--- a/MdePkg/Library/BasePeCoffLib/BasePeCoff.c
+++ b/MdePkg/Library/BasePeCoffLib/BasePeCoff.c
@@ -941,6 +941,7 @@ PeCoffLoaderRelocateImage (
EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION Hdr;
EFI_IMAGE_DATA_DIRECTORY *RelocDir;
UINT64 Adjust;
+ EFI_IMAGE_BASE_RELOCATION *RelocBaseOrg;
EFI_IMAGE_BASE_RELOCATION *RelocBase;
EFI_IMAGE_BASE_RELOCATION *RelocBaseEnd;
UINT16 *Reloc;
@@ -1041,7 +1042,8 @@ PeCoffLoaderRelocateImage (
RelocDir->VirtualAddress + RelocDir->Size - 1,
TeStrippedOffset
);
- if (RelocBase == NULL || RelocBaseEnd == NULL) {
+ if (RelocBase == NULL || RelocBaseEnd == NULL || RelocBaseEnd < RelocBase) {
+ ImageContext->ImageError = IMAGE_ERROR_FAILED_RELOCATION;
return RETURN_LOAD_ERROR;
}
} else {
@@ -1050,6 +1052,7 @@ PeCoffLoaderRelocateImage (
//
RelocBase = RelocBaseEnd = NULL;
}
+ RelocBaseOrg = RelocBase;
//
// If Adjust is not zero, then apply fix ups to the image
@@ -1065,14 +1068,23 @@ PeCoffLoaderRelocateImage (
//
// Add check for RelocBase->SizeOfBlock field.
//
- if ((RelocBase->SizeOfBlock == 0) || (RelocBase->SizeOfBlock > RelocDir->Size)) {
+ if (RelocBase->SizeOfBlock == 0) {
+ ImageContext->ImageError = IMAGE_ERROR_FAILED_RELOCATION;
+ return RETURN_LOAD_ERROR;
+ }
+ if ((UINTN)RelocBase > MAX_ADDRESS - RelocBase->SizeOfBlock) {
ImageContext->ImageError = IMAGE_ERROR_FAILED_RELOCATION;
return RETURN_LOAD_ERROR;
}
RelocEnd = (UINT16 *) ((CHAR8 *) RelocBase + RelocBase->SizeOfBlock);
+ if ((UINTN)RelocEnd > (UINTN)RelocBaseOrg + RelocDir->Size) {
+ ImageContext->ImageError = IMAGE_ERROR_FAILED_RELOCATION;
+ return RETURN_LOAD_ERROR;
+ }
FixupBase = PeCoffLoaderImageAddress (ImageContext, RelocBase->VirtualAddress, TeStrippedOffset);
if (FixupBase == NULL) {
+ ImageContext->ImageError = IMAGE_ERROR_FAILED_RELOCATION;
return RETURN_LOAD_ERROR;
}
@@ -1080,8 +1092,11 @@ PeCoffLoaderRelocateImage (
// Run this relocation record
//
while (Reloc < RelocEnd) {
-
- Fixup = FixupBase + (*Reloc & 0xFFF);
+ Fixup = PeCoffLoaderImageAddress (ImageContext, RelocBase->VirtualAddress + (*Reloc & 0xFFF), TeStrippedOffset);
+ if (Fixup == NULL) {
+ ImageContext->ImageError = IMAGE_ERROR_FAILED_RELOCATION;
+ return RETURN_LOAD_ERROR;
+ }
switch ((*Reloc) >> 12) {
case EFI_IMAGE_REL_BASED_ABSOLUTE:
break;
@@ -1148,6 +1163,7 @@ PeCoffLoaderRelocateImage (
//
RelocBase = (EFI_IMAGE_BASE_RELOCATION *) RelocEnd;
}
+ ASSERT ((UINTN)FixupData <= (UINTN)ImageContext->FixupData + ImageContext->FixupDataSize);
//
// Adjust the EntryPoint to match the linked-to address
@@ -1444,14 +1460,17 @@ PeCoffLoaderLoadImage (
DirectoryEntry = (EFI_IMAGE_DATA_DIRECTORY *)&Hdr.Pe32Plus->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC];
}
+ //
+ // Must use UINT64 here, because there might a case that 32bit loader to load 64bit image.
+ //
if (NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC) {
- ImageContext->FixupDataSize = DirectoryEntry->Size / sizeof (UINT16) * sizeof (UINTN);
+ ImageContext->FixupDataSize = DirectoryEntry->Size / sizeof (UINT16) * sizeof (UINT64);
} else {
ImageContext->FixupDataSize = 0;
}
} else {
DirectoryEntry = &Hdr.Te->DataDirectory[0];
- ImageContext->FixupDataSize = DirectoryEntry->Size / sizeof (UINT16) * sizeof (UINTN);
+ ImageContext->FixupDataSize = DirectoryEntry->Size / sizeof (UINT16) * sizeof (UINT64);
}
//
// Consumer must allocate a buffer for the relocation fixup log.
diff --git a/MdePkg/MdePkg.dec b/MdePkg/MdePkg.dec
index affff516e..4daf3e6a7 100644
--- a/MdePkg/MdePkg.dec
+++ b/MdePkg/MdePkg.dec
@@ -1375,7 +1375,8 @@
## If TRUE, the driver diagnostics2 protocol will not be installed.
gEfiMdePkgTokenSpaceGuid.PcdDriverDiagnostics2Disable|FALSE|BOOLEAN|0x00000011
- ## Indicates whether EFI 1.1 ISO 639-2 language supports are obsolete
+ ## Indicates whether EFI 1.1 ISO 639-2 language supports are obsolete.
+ # If TRUE, Variable driver will be also not to auto update between PlatformLang and Lang variables.
gEfiMdePkgTokenSpaceGuid.PcdUefiVariableDefaultLangDeprecate|FALSE|BOOLEAN|0x00000012
## If TRUE, UGA Draw Protocol is still consumed.
diff --git a/NetworkPkg/Dhcp6Dxe/Dhcp6Utility.c b/NetworkPkg/Dhcp6Dxe/Dhcp6Utility.c
index 32247c927..7591bf56b 100644
--- a/NetworkPkg/Dhcp6Dxe/Dhcp6Utility.c
+++ b/NetworkPkg/Dhcp6Dxe/Dhcp6Utility.c
@@ -1,7 +1,7 @@
/** @file
Dhcp6 support functions implementation.
- Copyright (c) 2009 - 2012, Intel Corporation. All rights reserved.<BR>
+ Copyright (c) 2009 - 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
@@ -157,7 +157,10 @@ Dhcp6GenerateClientId (
Duid->Length + 2,
(VOID *) Duid
);
- ASSERT_EFI_ERROR (Status);
+ if (EFI_ERROR (Status)) {
+ FreePool (Duid);
+ return NULL;
+ }
return Duid;
}
diff --git a/NetworkPkg/IScsiDxe/IScsiConfig.c b/NetworkPkg/IScsiDxe/IScsiConfig.c
index 2073f3319..1d648f78b 100644
--- a/NetworkPkg/IScsiDxe/IScsiConfig.c
+++ b/NetworkPkg/IScsiDxe/IScsiConfig.c
@@ -1,7 +1,7 @@
/** @file
Helper functions for configuring or getting the parameters relating to iSCSI.
-Copyright (c) 2004 - 2012, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2004 - 2014, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
@@ -784,7 +784,7 @@ IScsiConvertIfrNvDataToAttemptConfigData (
Status = gRT->SetVariable (
L"AttemptOrder",
&gIScsiConfigGuid,
- EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
+ EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE,
AttemptConfigOrderSize,
AttemptConfigOrder
);
@@ -1246,8 +1246,7 @@ IScsiConfigDeleteAttempts (
}
}
- Attribute = EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS
- | EFI_VARIABLE_NON_VOLATILE;
+ Attribute = EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE;
//
// Update AttemptOrder in NVR.
@@ -1558,7 +1557,7 @@ IScsiConfigOrderAttempts (
Status = gRT->SetVariable (
L"AttemptOrder",
&gIScsiConfigGuid,
- EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
+ EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE,
AttemptConfigOrderSize,
AttemptConfigOrderTmp
);
diff --git a/NetworkPkg/IScsiDxe/IScsiDriver.c b/NetworkPkg/IScsiDxe/IScsiDriver.c
index 42ac8f0fe..8d1742455 100644
--- a/NetworkPkg/IScsiDxe/IScsiDriver.c
+++ b/NetworkPkg/IScsiDxe/IScsiDriver.c
@@ -651,7 +651,9 @@ IScsiStart (
&gIScsiConfigGuid,
&AttemptConfigOrderSize
);
- ASSERT (AttemptConfigOrder != NULL);
+ if (AttemptConfigOrder == NULL) {
+ goto ON_ERROR;
+ }
for (Index = 0; Index < AttemptConfigOrderSize / sizeof (UINT8); Index++) {
if (AttemptConfigOrder[Index] == mPrivate->BootSelectedIndex ||
AttemptConfigOrder[Index] == BootSelected) {
@@ -689,7 +691,9 @@ IScsiStart (
goto ON_EXIT;
} else {
- ASSERT (AttemptConfigOrder[Index] == BootSelected);
+ if (AttemptConfigOrder[Index] != BootSelected) {
+ goto ON_ERROR;
+ }
mPrivate->BootSelectedIndex = BootSelected;
//
// Clear the resource in ExistPrivate.
diff --git a/OvmfPkg/AcpiPlatformDxe/AcpiPlatform.c b/OvmfPkg/AcpiPlatformDxe/AcpiPlatform.c
index 6e0b6100b..084c3931d 100644
--- a/OvmfPkg/AcpiPlatformDxe/AcpiPlatform.c
+++ b/OvmfPkg/AcpiPlatformDxe/AcpiPlatform.c
@@ -256,16 +256,14 @@ AcpiPlatformEntryPoint (
if (XenDetected ()) {
Status = InstallXenTables (AcpiTable);
- if (EFI_ERROR (Status)) {
- Status = FindAcpiTablesInFv (AcpiTable);
- }
} else {
- Status = FindAcpiTablesInFv (AcpiTable);
+ Status = InstallQemuLinkedTables (AcpiTable);
}
+
if (EFI_ERROR (Status)) {
- return Status;
+ Status = FindAcpiTablesInFv (AcpiTable);
}
- return EFI_SUCCESS;
+ return Status;
}
diff --git a/OvmfPkg/AcpiPlatformDxe/AcpiPlatform.h b/OvmfPkg/AcpiPlatformDxe/AcpiPlatform.h
index 21107cd4d..c643fa13d 100644
--- a/OvmfPkg/AcpiPlatformDxe/AcpiPlatform.h
+++ b/OvmfPkg/AcpiPlatformDxe/AcpiPlatform.h
@@ -10,7 +10,7 @@
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 _ACPI_PLATFORM_H_INCLUDED_
#define _ACPI_PLATFORM_H_INCLUDED_
@@ -61,5 +61,10 @@ InstallXenTables (
IN EFI_ACPI_TABLE_PROTOCOL *AcpiProtocol
);
+EFI_STATUS
+EFIAPI
+InstallQemuLinkedTables (
+ IN EFI_ACPI_TABLE_PROTOCOL *AcpiProtocol
+ );
#endif
diff --git a/OvmfPkg/AcpiPlatformDxe/Qemu.c b/OvmfPkg/AcpiPlatformDxe/Qemu.c
index 06bd46370..e62467a5b 100644
--- a/OvmfPkg/AcpiPlatformDxe/Qemu.c
+++ b/OvmfPkg/AcpiPlatformDxe/Qemu.c
@@ -515,3 +515,156 @@ QemuInstallAcpiTable (
);
}
+
+/**
+ Download the ACPI table data file from QEMU and interpret it.
+
+ @param[in] AcpiProtocol The ACPI table protocol used to install tables.
+
+ @retval EFI_UNSUPPORTED Firmware configuration is unavailable.
+
+ @retval EFI_NOT_FOUND The host doesn't export the required fw_cfg
+ files.
+
+ @retval EFI_OUT_OF_RESOURCES Memory allocation failed.
+
+ @retval EFI_PROTOCOL_ERROR Found truncated or invalid ACPI table header
+ in the fw_cfg contents.
+
+ @return Status codes returned by
+ AcpiProtocol->InstallAcpiTable().
+
+**/
+
+//
+// We'll be saving the keys of installed tables so that we can roll them back
+// in case of failure. 128 tables should be enough for anyone (TM).
+//
+#define INSTALLED_TABLES_MAX 128
+
+EFI_STATUS
+EFIAPI
+InstallQemuLinkedTables (
+ IN EFI_ACPI_TABLE_PROTOCOL *AcpiProtocol
+ )
+{
+ EFI_STATUS Status;
+ FIRMWARE_CONFIG_ITEM TablesFile;
+ UINTN TablesFileSize;
+ UINT8 *Tables;
+ UINTN *InstalledKey;
+ UINTN Processed;
+ INT32 Installed;
+
+ Status = QemuFwCfgFindFile ("etc/acpi/tables", &TablesFile, &TablesFileSize);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_INFO, "%a: \"etc/acpi/tables\" interface unavailable: %r\n",
+ __FUNCTION__, Status));
+ return Status;
+ }
+
+ Tables = AllocatePool (TablesFileSize);
+ if (Tables == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ QemuFwCfgSelectItem (TablesFile);
+ QemuFwCfgReadBytes (TablesFileSize, Tables);
+
+ InstalledKey = AllocatePool (INSTALLED_TABLES_MAX * sizeof *InstalledKey);
+ if (InstalledKey == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto FreeTables;
+ }
+
+ Processed = 0;
+ Installed = 0;
+ while (Processed < TablesFileSize) {
+ UINTN Remaining;
+ EFI_ACPI_DESCRIPTION_HEADER *Probe;
+
+ Remaining = TablesFileSize - Processed;
+ if (Remaining < sizeof *Probe) {
+ Status = EFI_PROTOCOL_ERROR;
+ break;
+ }
+
+ Probe = (EFI_ACPI_DESCRIPTION_HEADER *) (Tables + Processed);
+ if (Remaining < Probe->Length || Probe->Length < sizeof *Probe) {
+ Status = EFI_PROTOCOL_ERROR;
+ break;
+ }
+
+ DEBUG ((EFI_D_VERBOSE, "%a: offset 0x%016Lx:"
+ " Signature=\"%-4.4a\" Length=0x%08x\n",
+ __FUNCTION__, (UINT64) Processed,
+ (CONST CHAR8 *) &Probe->Signature, Probe->Length));
+
+ //
+ // skip automatically handled "root" tables: RSDT, XSDT
+ //
+ if (Probe->Signature !=
+ EFI_ACPI_1_0_ROOT_SYSTEM_DESCRIPTION_TABLE_SIGNATURE &&
+ Probe->Signature !=
+ EFI_ACPI_2_0_EXTENDED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE) {
+ if (Installed == INSTALLED_TABLES_MAX) {
+ DEBUG ((EFI_D_ERROR, "%a: can't install more than %d tables\n",
+ __FUNCTION__, INSTALLED_TABLES_MAX));
+ Status = EFI_OUT_OF_RESOURCES;
+ break;
+ }
+
+ Status = AcpiProtocol->InstallAcpiTable (AcpiProtocol, Probe,
+ Probe->Length, &InstalledKey[Installed]);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR,
+ "%a: failed to install table \"%-4.4a\" at offset 0x%Lx: %r\n",
+ __FUNCTION__, (CONST CHAR8 *) &Probe->Signature, (UINT64) Processed,
+ Status));
+ break;
+ }
+
+ ++Installed;
+ }
+
+ Processed += Probe->Length;
+ }
+
+ //
+ // NUL-padding at the end is accepted
+ //
+ if (Status == EFI_PROTOCOL_ERROR) {
+ UINTN ErrorLocation;
+
+ ErrorLocation = Processed;
+ while (Processed < TablesFileSize && Tables[Processed] == '\0') {
+ ++Processed;
+ }
+ if (Processed < TablesFileSize) {
+ DEBUG ((EFI_D_ERROR, "%a: truncated or invalid ACPI table header at "
+ "offset 0x%Lx\n", __FUNCTION__, (UINT64) ErrorLocation));
+ }
+ }
+
+ if (Processed == TablesFileSize) {
+ DEBUG ((EFI_D_INFO, "%a: installed %d tables\n", __FUNCTION__, Installed));
+ Status = EFI_SUCCESS;
+ } else {
+ ASSERT (EFI_ERROR (Status));
+
+ //
+ // Roll back partial installation.
+ //
+ while (Installed > 0) {
+ --Installed;
+ AcpiProtocol->UninstallAcpiTable (AcpiProtocol, InstalledKey[Installed]);
+ }
+ }
+
+ FreePool (InstalledKey);
+
+FreeTables:
+ FreePool (Tables);
+
+ return Status;
+}
diff --git a/OvmfPkg/AcpiS3SaveDxe/AcpiS3Save.c b/OvmfPkg/AcpiS3SaveDxe/AcpiS3Save.c
new file mode 100644
index 000000000..f322981b5
--- /dev/null
+++ b/OvmfPkg/AcpiS3SaveDxe/AcpiS3Save.c
@@ -0,0 +1,611 @@
+/** @file
+ This is an implementation of the ACPI S3 Save protocol. This is defined in
+ S3 boot path specification 0.9.
+
+Copyright (c) 2006 - 2013, Intel Corporation. All rights reserved.<BR>
+
+This program and the accompanying materials
+are licensed and made available under the terms and conditions
+of the BSD License which accompanies this distribution. The
+full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include <PiDxe.h>
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+#include <Library/HobLib.h>
+#include <Library/LockBoxLib.h>
+#include <Library/PcdLib.h>
+#include <Library/DebugLib.h>
+#include <Library/QemuFwCfgLib.h>
+#include <Guid/AcpiVariableCompatibility.h>
+#include <Guid/AcpiS3Context.h>
+#include <Guid/Acpi.h>
+#include <Protocol/AcpiS3Save.h>
+#include <Protocol/S3SaveState.h>
+#include <Protocol/DxeSmmReadyToLock.h>
+#include <Protocol/LockBox.h>
+#include <IndustryStandard/Acpi.h>
+
+#include "AcpiS3Save.h"
+
+UINTN mLegacyRegionSize;
+
+EFI_ACPI_S3_SAVE_PROTOCOL mS3Save = {
+ LegacyGetS3MemorySize,
+ S3Ready,
+};
+
+EFI_GUID mAcpiS3IdtrProfileGuid = {
+ 0xdea652b0, 0xd587, 0x4c54, { 0xb5, 0xb4, 0xc6, 0x82, 0xe7, 0xa0, 0xaa, 0x3d }
+};
+
+/**
+ Allocate memory below 4G memory address.
+
+ This function allocates memory below 4G memory address.
+
+ @param MemoryType Memory type of memory to allocate.
+ @param Size Size of memory to allocate.
+
+ @return Allocated address for output.
+
+**/
+VOID*
+AllocateMemoryBelow4G (
+ IN EFI_MEMORY_TYPE MemoryType,
+ IN UINTN Size
+ )
+{
+ UINTN Pages;
+ EFI_PHYSICAL_ADDRESS Address;
+ EFI_STATUS Status;
+ VOID* Buffer;
+
+ Pages = EFI_SIZE_TO_PAGES (Size);
+ Address = 0xffffffff;
+
+ Status = gBS->AllocatePages (
+ AllocateMaxAddress,
+ MemoryType,
+ Pages,
+ &Address
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ Buffer = (VOID *) (UINTN) Address;
+ ZeroMem (Buffer, Size);
+
+ return Buffer;
+}
+
+/**
+
+ This function scan ACPI table in RSDT.
+
+ @param Rsdt ACPI RSDT
+ @param Signature ACPI table signature
+
+ @return ACPI table
+
+**/
+VOID *
+ScanTableInRSDT (
+ IN EFI_ACPI_DESCRIPTION_HEADER *Rsdt,
+ IN UINT32 Signature
+ )
+{
+ UINTN Index;
+ UINT32 EntryCount;
+ UINT32 *EntryPtr;
+ EFI_ACPI_DESCRIPTION_HEADER *Table;
+
+ if (Rsdt == NULL) {
+ return NULL;
+ }
+
+ EntryCount = (Rsdt->Length - sizeof (EFI_ACPI_DESCRIPTION_HEADER)) / sizeof(UINT32);
+
+ EntryPtr = (UINT32 *)(Rsdt + 1);
+ for (Index = 0; Index < EntryCount; Index ++, EntryPtr ++) {
+ Table = (EFI_ACPI_DESCRIPTION_HEADER *)((UINTN)(*EntryPtr));
+ if (Table->Signature == Signature) {
+ return Table;
+ }
+ }
+
+ return NULL;
+}
+
+/**
+
+ This function scan ACPI table in XSDT.
+
+ @param Xsdt ACPI XSDT
+ @param Signature ACPI table signature
+
+ @return ACPI table
+
+**/
+VOID *
+ScanTableInXSDT (
+ IN EFI_ACPI_DESCRIPTION_HEADER *Xsdt,
+ IN UINT32 Signature
+ )
+{
+ UINTN Index;
+ UINT32 EntryCount;
+ UINT64 EntryPtr;
+ UINTN BasePtr;
+ EFI_ACPI_DESCRIPTION_HEADER *Table;
+
+ if (Xsdt == NULL) {
+ return NULL;
+ }
+
+ EntryCount = (Xsdt->Length - sizeof (EFI_ACPI_DESCRIPTION_HEADER)) / sizeof(UINT64);
+
+ BasePtr = (UINTN)(Xsdt + 1);
+ for (Index = 0; Index < EntryCount; Index ++) {
+ CopyMem (&EntryPtr, (VOID *)(BasePtr + Index * sizeof(UINT64)), sizeof(UINT64));
+ Table = (EFI_ACPI_DESCRIPTION_HEADER *)((UINTN)(EntryPtr));
+ if (Table->Signature == Signature) {
+ return Table;
+ }
+ }
+
+ return NULL;
+}
+
+/**
+ To find Facs in FADT.
+
+ @param Fadt FADT table pointer
+
+ @return Facs table pointer.
+**/
+EFI_ACPI_2_0_FIRMWARE_ACPI_CONTROL_STRUCTURE *
+FindAcpiFacsFromFadt (
+ IN EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE *Fadt
+ )
+{
+ EFI_ACPI_2_0_FIRMWARE_ACPI_CONTROL_STRUCTURE *Facs;
+ UINT64 Data64;
+
+ if (Fadt == NULL) {
+ return NULL;
+ }
+
+ if (Fadt->Header.Revision < EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE_REVISION) {
+ Facs = (EFI_ACPI_2_0_FIRMWARE_ACPI_CONTROL_STRUCTURE *)(UINTN)Fadt->FirmwareCtrl;
+ } else {
+ if (Fadt->FirmwareCtrl != 0) {
+ Facs = (EFI_ACPI_2_0_FIRMWARE_ACPI_CONTROL_STRUCTURE *)(UINTN)Fadt->FirmwareCtrl;
+ } else {
+ CopyMem (&Data64, &Fadt->XFirmwareCtrl, sizeof(UINT64));
+ Facs = (EFI_ACPI_2_0_FIRMWARE_ACPI_CONTROL_STRUCTURE *)(UINTN)Data64;
+ }
+ }
+ return Facs;
+}
+
+/**
+ To find Facs in Acpi tables.
+
+ To find Firmware ACPI control strutcure in Acpi Tables since the S3 waking vector is stored
+ in the table.
+
+ @param AcpiTableGuid The guid used to find ACPI table in UEFI ConfigurationTable.
+
+ @return Facs table pointer.
+**/
+EFI_ACPI_2_0_FIRMWARE_ACPI_CONTROL_STRUCTURE *
+FindAcpiFacsTableByAcpiGuid (
+ IN EFI_GUID *AcpiTableGuid
+ )
+{
+ EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER *Rsdp;
+ EFI_ACPI_DESCRIPTION_HEADER *Rsdt;
+ EFI_ACPI_DESCRIPTION_HEADER *Xsdt;
+ EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE *Fadt;
+ EFI_ACPI_2_0_FIRMWARE_ACPI_CONTROL_STRUCTURE *Facs;
+ UINTN Index;
+
+ Rsdp = NULL;
+ //
+ // found ACPI table RSD_PTR from system table
+ //
+ for (Index = 0; Index < gST->NumberOfTableEntries; Index++) {
+ if (CompareGuid (&(gST->ConfigurationTable[Index].VendorGuid), AcpiTableGuid)) {
+ //
+ // A match was found.
+ //
+ Rsdp = gST->ConfigurationTable[Index].VendorTable;
+ break;
+ }
+ }
+
+ if (Rsdp == NULL) {
+ return NULL;
+ }
+
+ //
+ // Search XSDT
+ //
+ if (Rsdp->Revision >= EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER_REVISION) {
+ Xsdt = (EFI_ACPI_DESCRIPTION_HEADER *)(UINTN) Rsdp->XsdtAddress;
+ Fadt = ScanTableInXSDT (Xsdt, EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE);
+ if (Fadt != NULL) {
+ Facs = FindAcpiFacsFromFadt (Fadt);
+ if (Facs != NULL) {
+ return Facs;
+ }
+ }
+ }
+
+ //
+ // Search RSDT
+ //
+ Rsdt = (EFI_ACPI_DESCRIPTION_HEADER *)(UINTN) Rsdp->RsdtAddress;
+ Fadt = ScanTableInRSDT (Rsdt, EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE);
+ if (Fadt != NULL) {
+ Facs = FindAcpiFacsFromFadt (Fadt);
+ if (Facs != NULL) {
+ return Facs;
+ }
+ }
+
+ return NULL;
+}
+
+/**
+ To find Facs in Acpi tables.
+
+ To find Firmware ACPI control strutcure in Acpi Tables since the S3 waking vector is stored
+ in the table.
+
+ @return Facs table pointer.
+**/
+EFI_ACPI_2_0_FIRMWARE_ACPI_CONTROL_STRUCTURE *
+FindAcpiFacsTable (
+ VOID
+ )
+{
+ EFI_ACPI_2_0_FIRMWARE_ACPI_CONTROL_STRUCTURE *Facs;
+
+ Facs = FindAcpiFacsTableByAcpiGuid (&gEfiAcpi20TableGuid);
+ if (Facs != NULL) {
+ return Facs;
+ }
+
+ return FindAcpiFacsTableByAcpiGuid (&gEfiAcpi10TableGuid);
+}
+
+/**
+ Allocates and fills in the Page Directory and Page Table Entries to
+ establish a 1:1 Virtual to Physical mapping.
+ If BootScriptExector driver will run in 64-bit mode, this function will establish the 1:1
+ virtual to physical mapping page table.
+ If BootScriptExector driver will not run in 64-bit mode, this function will do nothing.
+
+ @return the 1:1 Virtual to Physical identity mapping page table base address.
+
+**/
+EFI_PHYSICAL_ADDRESS
+S3CreateIdentityMappingPageTables (
+ VOID
+ )
+{
+ if (FeaturePcdGet (PcdDxeIplSwitchToLongMode)) {
+ UINT32 RegEax;
+ UINT32 RegEdx;
+ UINT8 PhysicalAddressBits;
+ UINT32 NumberOfPml4EntriesNeeded;
+ UINT32 NumberOfPdpEntriesNeeded;
+ EFI_PHYSICAL_ADDRESS S3NvsPageTableAddress;
+ UINTN TotalPageTableSize;
+ VOID *Hob;
+ BOOLEAN Page1GSupport;
+
+ Page1GSupport = FALSE;
+ if (PcdGetBool(PcdUse1GPageTable)) {
+ AsmCpuid (0x80000000, &RegEax, NULL, NULL, NULL);
+ if (RegEax >= 0x80000001) {
+ AsmCpuid (0x80000001, NULL, NULL, NULL, &RegEdx);
+ if ((RegEdx & BIT26) != 0) {
+ Page1GSupport = TRUE;
+ }
+ }
+ }
+
+ //
+ // 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;
+ }
+
+ //
+ // Calculate the table entries needed.
+ //
+ if (PhysicalAddressBits <= 39 ) {
+ NumberOfPml4EntriesNeeded = 1;
+ NumberOfPdpEntriesNeeded = (UINT32)LShiftU64 (1, (PhysicalAddressBits - 30));
+ } else {
+ NumberOfPml4EntriesNeeded = (UINT32)LShiftU64 (1, (PhysicalAddressBits - 39));
+ NumberOfPdpEntriesNeeded = 512;
+ }
+
+ //
+ // We need calculate whole page size then allocate once, because S3 restore page table does not know each page in Nvs.
+ //
+ if (!Page1GSupport) {
+ TotalPageTableSize = (UINTN)(1 + NumberOfPml4EntriesNeeded + NumberOfPml4EntriesNeeded * NumberOfPdpEntriesNeeded);
+ } else {
+ TotalPageTableSize = (UINTN)(1 + NumberOfPml4EntriesNeeded);
+ }
+ DEBUG ((EFI_D_ERROR, "TotalPageTableSize - %x pages\n", TotalPageTableSize));
+
+ //
+ // By architecture only one PageMapLevel4 exists - so lets allocate storage for it.
+ //
+ S3NvsPageTableAddress = (EFI_PHYSICAL_ADDRESS)(UINTN)AllocateMemoryBelow4G (EfiReservedMemoryType, EFI_PAGES_TO_SIZE(TotalPageTableSize));
+ ASSERT (S3NvsPageTableAddress != 0);
+ return S3NvsPageTableAddress;
+ } else {
+ //
+ // If DXE is running 32-bit mode, no need to establish page table.
+ //
+ return (EFI_PHYSICAL_ADDRESS) 0;
+ }
+}
+
+/**
+ Gets the buffer of legacy memory below 1 MB
+ This function is to get the buffer in legacy memory below 1MB that is required during S3 resume.
+
+ @param This A pointer to the EFI_ACPI_S3_SAVE_PROTOCOL instance.
+ @param Size The returned size of legacy memory below 1 MB.
+
+ @retval EFI_SUCCESS Size is successfully returned.
+ @retval EFI_INVALID_PARAMETER The pointer Size is NULL.
+
+**/
+EFI_STATUS
+EFIAPI
+LegacyGetS3MemorySize (
+ IN EFI_ACPI_S3_SAVE_PROTOCOL *This,
+ OUT UINTN *Size
+ )
+{
+ if (Size == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ *Size = mLegacyRegionSize;
+ return EFI_SUCCESS;
+}
+
+/**
+ Save the S3 boot script.
+
+ Note that we trigger DxeSmmReadyToLock here -- otherwise the script wouldn't
+ be saved actually. Triggering this protocol installation event in turn locks
+ down SMM, so no further changes to LockBoxes or SMRAM are possible
+ afterwards.
+**/
+STATIC
+VOID
+EFIAPI
+SaveS3BootScript (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+ EFI_S3_SAVE_STATE_PROTOCOL *BootScript;
+ EFI_HANDLE Handle;
+ STATIC CONST UINT8 Info[] = { 0xDE, 0xAD, 0xBE, 0xEF };
+
+ Status = gBS->LocateProtocol (&gEfiS3SaveStateProtocolGuid, NULL,
+ (VOID **) &BootScript);
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Despite the opcode documentation in the PI spec, the protocol
+ // implementation embeds a deep copy of the info in the boot script, rather
+ // than storing just a pointer to runtime or NVS storage.
+ //
+ Status = BootScript->Write(BootScript, EFI_BOOT_SCRIPT_INFORMATION_OPCODE,
+ (UINT32) sizeof Info,
+ (EFI_PHYSICAL_ADDRESS)(UINTN) &Info);
+ ASSERT_EFI_ERROR (Status);
+
+ Handle = NULL;
+ Status = gBS->InstallProtocolInterface (&Handle,
+ &gEfiDxeSmmReadyToLockProtocolGuid, EFI_NATIVE_INTERFACE,
+ NULL);
+ ASSERT_EFI_ERROR (Status);
+}
+
+
+/**
+ Prepares all information that is needed in the S3 resume boot path.
+
+ Allocate the resources or prepare informations and save in ACPI variable set for S3 resume boot path
+
+ @param This A pointer to the EFI_ACPI_S3_SAVE_PROTOCOL instance.
+ @param LegacyMemoryAddress The base address of legacy memory.
+
+ @retval EFI_NOT_FOUND Some necessary information cannot be found.
+ @retval EFI_SUCCESS All information was saved successfully.
+ @retval EFI_OUT_OF_RESOURCES Resources were insufficient to save all the information.
+ @retval EFI_INVALID_PARAMETER The memory range is not located below 1 MB.
+
+**/
+EFI_STATUS
+EFIAPI
+S3Ready (
+ IN EFI_ACPI_S3_SAVE_PROTOCOL *This,
+ IN VOID *LegacyMemoryAddress
+ )
+{
+ EFI_STATUS Status;
+ EFI_PHYSICAL_ADDRESS AcpiS3ContextBuffer;
+ ACPI_S3_CONTEXT *AcpiS3Context;
+ STATIC BOOLEAN AlreadyEntered;
+ IA32_DESCRIPTOR *Idtr;
+ IA32_IDT_GATE_DESCRIPTOR *IdtGate;
+
+ DEBUG ((EFI_D_INFO, "S3Ready!\n"));
+
+ //
+ // Platform may invoke AcpiS3Save->S3Save() before ExitPmAuth, because we need save S3 information there, while BDS ReadyToBoot may invoke it again.
+ // So if 2nd S3Save() is triggered later, we need ignore it.
+ //
+ if (AlreadyEntered) {
+ return EFI_SUCCESS;
+ }
+ AlreadyEntered = TRUE;
+
+ AcpiS3Context = AllocateMemoryBelow4G (EfiReservedMemoryType, sizeof(*AcpiS3Context));
+ ASSERT (AcpiS3Context != NULL);
+ AcpiS3ContextBuffer = (EFI_PHYSICAL_ADDRESS)(UINTN)AcpiS3Context;
+
+ //
+ // Get ACPI Table because we will save its position to variable
+ //
+ AcpiS3Context->AcpiFacsTable = (EFI_PHYSICAL_ADDRESS)(UINTN)FindAcpiFacsTable ();
+ ASSERT (AcpiS3Context->AcpiFacsTable != 0);
+
+ IdtGate = AllocateMemoryBelow4G (EfiReservedMemoryType, sizeof(IA32_IDT_GATE_DESCRIPTOR) * 0x100 + sizeof(IA32_DESCRIPTOR));
+ Idtr = (IA32_DESCRIPTOR *)(IdtGate + 0x100);
+ Idtr->Base = (UINTN)IdtGate;
+ Idtr->Limit = (UINT16)(sizeof(IA32_IDT_GATE_DESCRIPTOR) * 0x100 - 1);
+ AcpiS3Context->IdtrProfile = (EFI_PHYSICAL_ADDRESS)(UINTN)Idtr;
+
+ Status = SaveLockBox (
+ &mAcpiS3IdtrProfileGuid,
+ (VOID *)(UINTN)Idtr,
+ (UINTN)sizeof(IA32_DESCRIPTOR)
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ Status = SetLockBoxAttributes (&mAcpiS3IdtrProfileGuid, LOCK_BOX_ATTRIBUTE_RESTORE_IN_PLACE);
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Allocate page table
+ //
+ AcpiS3Context->S3NvsPageTableAddress = S3CreateIdentityMappingPageTables ();
+
+ //
+ // Allocate stack
+ //
+ AcpiS3Context->BootScriptStackSize = PcdGet32 (PcdS3BootScriptStackSize);
+ AcpiS3Context->BootScriptStackBase = (EFI_PHYSICAL_ADDRESS)(UINTN)AllocateMemoryBelow4G (EfiReservedMemoryType, PcdGet32 (PcdS3BootScriptStackSize));
+ ASSERT (AcpiS3Context->BootScriptStackBase != 0);
+
+ //
+ // Allocate a code buffer < 4G for S3 debug to load external code, set invalid code instructions in it.
+ //
+ AcpiS3Context->S3DebugBufferAddress = (EFI_PHYSICAL_ADDRESS)(UINTN)AllocateMemoryBelow4G (EfiReservedMemoryType, EFI_PAGE_SIZE);
+ SetMem ((VOID *)(UINTN)AcpiS3Context->S3DebugBufferAddress, EFI_PAGE_SIZE, 0xff);
+
+ DEBUG((EFI_D_INFO, "AcpiS3Context: AcpiFacsTable is 0x%8x\n", AcpiS3Context->AcpiFacsTable));
+ DEBUG((EFI_D_INFO, "AcpiS3Context: IdtrProfile is 0x%8x\n", AcpiS3Context->IdtrProfile));
+ DEBUG((EFI_D_INFO, "AcpiS3Context: S3NvsPageTableAddress is 0x%8x\n", AcpiS3Context->S3NvsPageTableAddress));
+ DEBUG((EFI_D_INFO, "AcpiS3Context: S3DebugBufferAddress is 0x%8x\n", AcpiS3Context->S3DebugBufferAddress));
+
+ Status = SaveLockBox (
+ &gEfiAcpiVariableGuid,
+ &AcpiS3ContextBuffer,
+ sizeof(AcpiS3ContextBuffer)
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ Status = SaveLockBox (
+ &gEfiAcpiS3ContextGuid,
+ (VOID *)(UINTN)AcpiS3Context,
+ (UINTN)sizeof(*AcpiS3Context)
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ Status = SetLockBoxAttributes (&gEfiAcpiS3ContextGuid, LOCK_BOX_ATTRIBUTE_RESTORE_IN_PLACE);
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Save the boot script too. Note that this requires/includes emitting the
+ // DxeSmmReadyToLock event, which in turn locks down SMM.
+ //
+ SaveS3BootScript ();
+ return EFI_SUCCESS;
+}
+
+/**
+ The Driver Entry Point.
+
+ The function is the driver Entry point which will produce AcpiS3SaveProtocol.
+
+ @param ImageHandle A handle for the image that is initializing this driver
+ @param SystemTable A pointer to the EFI system table
+
+ @retval EFI_SUCCESS: Driver initialized successfully
+ @retval EFI_LOAD_ERROR: Failed to Initialize or has been loaded
+ @retval EFI_OUT_OF_RESOURCES Could not allocate needed resources
+
+**/
+EFI_STATUS
+EFIAPI
+InstallAcpiS3Save (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+
+ if (!QemuFwCfgS3Enabled()) {
+ return EFI_LOAD_ERROR;
+ }
+
+ if (!FeaturePcdGet(PcdPlatformCsmSupport)) {
+ //
+ // More memory for no CSM tip, because GDT need relocation
+ //
+ mLegacyRegionSize = 0x250;
+ } else {
+ mLegacyRegionSize = 0x100;
+ }
+
+ Status = gBS->InstallMultipleProtocolInterfaces (
+ &ImageHandle,
+ &gEfiAcpiS3SaveProtocolGuid, &mS3Save,
+ &gEfiLockBoxProtocolGuid, NULL,
+ NULL
+ );
+ ASSERT_EFI_ERROR (Status);
+ return Status;
+}
diff --git a/OvmfPkg/AcpiS3SaveDxe/AcpiS3Save.h b/OvmfPkg/AcpiS3SaveDxe/AcpiS3Save.h
new file mode 100644
index 000000000..65974a340
--- /dev/null
+++ b/OvmfPkg/AcpiS3SaveDxe/AcpiS3Save.h
@@ -0,0 +1,59 @@
+/** @file
+ This is an implementation of the ACPI S3 Save protocol. This is defined in
+ S3 boot path specification 0.9.
+
+Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.<BR>
+
+This program and the accompanying materials
+are licensed and made available under the terms and conditions
+of the BSD License which accompanies this distribution. The
+full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef _ACPI_S3_SAVE_H_
+#define _ACPI_S3_SAVE_H_
+
+/**
+ Gets the buffer of legacy memory below 1 MB
+ This function is to get the buffer in legacy memory below 1MB that is required during S3 resume.
+
+ @param This A pointer to the EFI_ACPI_S3_SAVE_PROTOCOL instance.
+ @param Size The returned size of legacy memory below 1 MB.
+
+ @retval EFI_SUCCESS Size is successfully returned.
+ @retval EFI_INVALID_PARAMETER The pointer Size is NULL.
+
+**/
+EFI_STATUS
+EFIAPI
+LegacyGetS3MemorySize (
+ IN EFI_ACPI_S3_SAVE_PROTOCOL * This,
+ OUT UINTN * Size
+ );
+
+/**
+ Prepares all information that is needed in the S3 resume boot path.
+
+ Allocate the resources or prepare informations and save in ACPI variable set for S3 resume boot path
+
+ @param This A pointer to the EFI_ACPI_S3_SAVE_PROTOCOL instance.
+ @param LegacyMemoryAddress The base address of legacy memory.
+
+ @retval EFI_NOT_FOUND Some necessary information cannot be found.
+ @retval EFI_SUCCESS All information was saved successfully.
+ @retval EFI_OUT_OF_RESOURCES Resources were insufficient to save all the information.
+ @retval EFI_INVALID_PARAMETER The memory range is not located below 1 MB.
+
+**/
+EFI_STATUS
+EFIAPI
+S3Ready (
+ IN EFI_ACPI_S3_SAVE_PROTOCOL *This,
+ IN VOID *LegacyMemoryAddress
+ );
+#endif
diff --git a/OvmfPkg/AcpiS3SaveDxe/AcpiS3SaveDxe.inf b/OvmfPkg/AcpiS3SaveDxe/AcpiS3SaveDxe.inf
new file mode 100644
index 000000000..b53e7850e
--- /dev/null
+++ b/OvmfPkg/AcpiS3SaveDxe/AcpiS3SaveDxe.inf
@@ -0,0 +1,81 @@
+## @file
+# Component description file for AcpiS3Save module.
+#
+# This is an implementation of the ACPI S3 Save protocol.
+# Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>
+#
+# This program and the accompanying materials are
+# licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = AcpiS3SaveDxe
+ FILE_GUID = 6B79BBC0-26B9-4FE9-B631-551D8AB078C6
+ MODULE_TYPE = DXE_DRIVER
+ VERSION_STRING = 1.0
+
+ ENTRY_POINT = InstallAcpiS3Save
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64
+#
+
+[Sources]
+ AcpiS3Save.h
+ AcpiS3Save.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ IntelFrameworkPkg/IntelFrameworkPkg.dec
+ IntelFrameworkModulePkg/IntelFrameworkModulePkg.dec
+ OvmfPkg/OvmfPkg.dec
+
+[LibraryClasses]
+ PcdLib
+ UefiRuntimeServicesTableLib
+ UefiBootServicesTableLib
+ UefiDriverEntryPoint
+ BaseMemoryLib
+ HobLib
+ UefiLib
+ LockBoxLib
+ DebugLib
+ DxeServicesLib
+ QemuFwCfgLib
+
+[Guids]
+ gEfiAcpiVariableGuid # ALWAYS_CONSUMED
+ gEfiAcpiS3ContextGuid # ALWAYS_CONSUMED
+ gEfiAcpi20TableGuid # ALWAYS_CONSUMED System Table
+ gEfiAcpi10TableGuid # ALWAYS_CONSUMED System Table
+
+[Protocols]
+ gEfiAcpiS3SaveProtocolGuid # PROTOCOL ALWAYS_PRODUCED
+ gEfiLockBoxProtocolGuid # PROTOCOL ALWAYS_PRODUCED
+ gEfiLegacyBiosProtocolGuid # PROTOCOL ALWAYS_CONSUMED
+ gEfiLegacyRegion2ProtocolGuid # PROTOCOL SOMETIMES_CONSUMED
+ gFrameworkEfiMpServiceProtocolGuid # PROTOCOL SOMETIMES_CONSUMED
+ gEfiS3SaveStateProtocolGuid # PROTOCOL ALWAYS_CONSUMED
+ gEfiDxeSmmReadyToLockProtocolGuid # PROTOCOL ALWAYS_CONSUMED
+
+[FeaturePcd]
+ gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdPlatformCsmSupport ## CONSUMES
+ gEfiMdeModulePkgTokenSpaceGuid.PcdDxeIplSwitchToLongMode
+
+[Pcd]
+ gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdS3AcpiReservedMemorySize ## CONSUMES
+ gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdS3BootScriptStackSize ## CONSUMES
+ gEfiMdeModulePkgTokenSpaceGuid.PcdUse1GPageTable
+
+[Depex]
+ gEfiVariableArchProtocolGuid AND gEfiVariableWriteArchProtocolGuid AND gEfiS3SaveStateProtocolGuid
diff --git a/OvmfPkg/Include/Guid/OvmfPlatformConfig.h b/OvmfPkg/Include/Guid/OvmfPlatformConfig.h
new file mode 100644
index 000000000..ea3c26c43
--- /dev/null
+++ b/OvmfPkg/Include/Guid/OvmfPlatformConfig.h
@@ -0,0 +1,24 @@
+/** @file
+ GUID for UEFI variables that are specific to OVMF configuration.
+
+ 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 __OVMF_PLATFORM_CONFIG_H__
+#define __OVMF_PLATFORM_CONFIG_H__
+
+#define OVMF_PLATFORM_CONFIG_GUID \
+{0x7235c51c, 0x0c80, 0x4cab, {0x87, 0xac, 0x3b, 0x08, 0x4a, 0x63, 0x04, 0xb1}}
+
+extern EFI_GUID gOvmfPlatformConfigGuid;
+
+#endif
diff --git a/OvmfPkg/Include/Library/QemuFwCfgLib.h b/OvmfPkg/Include/Library/QemuFwCfgLib.h
index 2519fc297..8d3b835d4 100644
--- a/OvmfPkg/Include/Library/QemuFwCfgLib.h
+++ b/OvmfPkg/Include/Library/QemuFwCfgLib.h
@@ -214,5 +214,19 @@ InternalQemuFwCfgIsAvailable (
VOID
);
+
+/**
+ 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
+ );
+
#endif
diff --git a/OvmfPkg/Library/LockBoxLib/LockBoxBase.c b/OvmfPkg/Library/LockBoxLib/LockBoxBase.c
new file mode 100644
index 000000000..8f367701f
--- /dev/null
+++ b/OvmfPkg/Library/LockBoxLib/LockBoxBase.c
@@ -0,0 +1,42 @@
+/** @file
+
+ Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.<BR>
+
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include <Uefi.h>
+
+#include <Library/DebugLib.h>
+#include <LockBoxLib.h>
+
+/**
+ Allocates a buffer of type EfiACPIMemoryNVS.
+
+ Allocates the number bytes specified by AllocationSize of type
+ EfiACPIMemoryNVS and returns a pointer to the allocated buffer.
+ If AllocationSize is 0, then a valid buffer of 0 size is
+ returned. If there is not enough memory remaining to satisfy
+ the request, then NULL is returned.
+
+ @param AllocationSize The number of bytes to allocate.
+
+ @return A pointer to the allocated buffer or NULL if allocation fails.
+
+**/
+VOID *
+EFIAPI
+AllocateAcpiNvsPool (
+ IN UINTN AllocationSize
+ )
+{
+ ASSERT_EFI_ERROR (RETURN_UNSUPPORTED);
+ return NULL;
+}
diff --git a/OvmfPkg/Library/LockBoxLib/LockBoxBaseLib.inf b/OvmfPkg/Library/LockBoxLib/LockBoxBaseLib.inf
new file mode 100644
index 000000000..7203d0777
--- /dev/null
+++ b/OvmfPkg/Library/LockBoxLib/LockBoxBaseLib.inf
@@ -0,0 +1,44 @@
+## @file
+#
+# Library implementing the LockBox interface for OVMF
+#
+# Copyright (C) 2013, Red Hat, Inc.
+# 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 = LockBoxBaseLib
+ FILE_GUID = 17CA9B37-5BAB-492C-A09C-7121FBE34CE6
+ MODULE_TYPE = BASE
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = LockBoxLib
+
+ CONSTRUCTOR = LockBoxLibInitialize
+
+[Sources]
+ LockBoxBase.c
+ LockBoxLib.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ OvmfPkg/OvmfPkg.dec
+
+[LibraryClasses]
+ BaseMemoryLib
+ DebugLib
+
+[Pcd]
+ gUefiOvmfPkgTokenSpaceGuid.PcdOvmfLockBoxStorageBase
+ gUefiOvmfPkgTokenSpaceGuid.PcdOvmfLockBoxStorageSize
diff --git a/OvmfPkg/Library/LockBoxLib/LockBoxDxe.c b/OvmfPkg/Library/LockBoxLib/LockBoxDxe.c
new file mode 100644
index 000000000..c8f2ec8a4
--- /dev/null
+++ b/OvmfPkg/Library/LockBoxLib/LockBoxDxe.c
@@ -0,0 +1,119 @@
+/** @file
+
+ Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.<BR>
+
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include <Uefi.h>
+
+#include <Library/MemoryAllocationLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <LockBoxLib.h>
+
+/**
+ Allocate memory below 4G memory address.
+
+ This function allocates memory below 4G memory address.
+
+ @param MemoryType Memory type of memory to allocate.
+ @param Size Size of memory to allocate.
+
+ @return Allocated address for output.
+
+**/
+STATIC
+VOID *
+AllocateMemoryBelow4G (
+ IN EFI_MEMORY_TYPE MemoryType,
+ IN UINTN Size
+ )
+{
+ UINTN Pages;
+ EFI_PHYSICAL_ADDRESS Address;
+ EFI_STATUS Status;
+ VOID* Buffer;
+ UINTN AllocRemaining;
+
+ Pages = EFI_SIZE_TO_PAGES (Size);
+ Address = 0xffffffff;
+
+ //
+ // Since we need to use gBS->AllocatePages to get a buffer below
+ // 4GB, there is a good chance that space will be wasted for very
+ // small allocation. We keep track of unused portions of the page
+ // allocations, and use these to allocate memory for small buffers.
+ //
+ ASSERT (mLockBoxGlobal->Signature == LOCK_BOX_GLOBAL_SIGNATURE);
+ if ((UINTN) mLockBoxGlobal->SubPageRemaining >= Size) {
+ Buffer = (VOID*)(UINTN) mLockBoxGlobal->SubPageBuffer;
+ mLockBoxGlobal->SubPageBuffer += (UINT32) Size;
+ mLockBoxGlobal->SubPageRemaining -= (UINT32) Size;
+ return Buffer;
+ }
+
+ Status = gBS->AllocatePages (
+ AllocateMaxAddress,
+ MemoryType,
+ Pages,
+ &Address
+ );
+ if (EFI_ERROR (Status)) {
+ return NULL;
+ }
+
+ Buffer = (VOID *) (UINTN) Address;
+ ZeroMem (Buffer, EFI_PAGES_TO_SIZE (Pages));
+
+ AllocRemaining = EFI_PAGES_TO_SIZE (Pages) - Size;
+ if (AllocRemaining > (UINTN) mLockBoxGlobal->SubPageRemaining) {
+ mLockBoxGlobal->SubPageBuffer = (UINT32) (Address + Size);
+ mLockBoxGlobal->SubPageRemaining = (UINT32) AllocRemaining;
+ }
+
+ return Buffer;
+}
+
+
+/**
+ Allocates a buffer of type EfiACPIMemoryNVS.
+
+ Allocates the number bytes specified by AllocationSize of type
+ EfiACPIMemoryNVS and returns a pointer to the allocated buffer.
+ If AllocationSize is 0, then a valid buffer of 0 size is
+ returned. If there is not enough memory remaining to satisfy
+ the request, then NULL is returned.
+
+ @param AllocationSize The number of bytes to allocate.
+
+ @return A pointer to the allocated buffer or NULL if allocation fails.
+
+**/
+VOID *
+EFIAPI
+AllocateAcpiNvsPool (
+ IN UINTN AllocationSize
+ )
+{
+ return AllocateMemoryBelow4G (EfiACPIMemoryNVS, AllocationSize);
+}
+
+
+EFI_STATUS
+EFIAPI
+LockBoxDxeLibInitialize (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ return LockBoxLibInitialize ();
+}
diff --git a/OvmfPkg/Library/LockBoxLib/LockBoxDxeLib.inf b/OvmfPkg/Library/LockBoxLib/LockBoxDxeLib.inf
new file mode 100644
index 000000000..a4d27a598
--- /dev/null
+++ b/OvmfPkg/Library/LockBoxLib/LockBoxDxeLib.inf
@@ -0,0 +1,45 @@
+## @file
+#
+# Library implementing the LockBox interface for OVMF
+#
+# Copyright (C) 2013, Red Hat, Inc.
+# 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 = LockBoxDxeLib
+ FILE_GUID = f61c9a34-2e18-44ce-af2f-21a998e64fda
+ MODULE_TYPE = DXE_DRIVER
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = LockBoxLib
+
+ CONSTRUCTOR = LockBoxDxeLibInitialize
+
+[Sources]
+ LockBoxDxe.c
+ LockBoxLib.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ OvmfPkg/OvmfPkg.dec
+
+[LibraryClasses]
+ BaseMemoryLib
+ DebugLib
+ UefiBootServicesTableLib
+
+[Pcd]
+ gUefiOvmfPkgTokenSpaceGuid.PcdOvmfLockBoxStorageBase
+ gUefiOvmfPkgTokenSpaceGuid.PcdOvmfLockBoxStorageSize
diff --git a/OvmfPkg/Library/LockBoxLib/LockBoxLib.c b/OvmfPkg/Library/LockBoxLib/LockBoxLib.c
new file mode 100644
index 000000000..af3bb7f46
--- /dev/null
+++ b/OvmfPkg/Library/LockBoxLib/LockBoxLib.c
@@ -0,0 +1,376 @@
+/** @file
+
+ Library implementing the LockBox interface for OVMF
+
+ Copyright (C) 2013, Red Hat, Inc.
+ 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
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, WITHOUT
+ WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include <Uefi.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/LockBoxLib.h>
+#include <Library/PcdLib.h>
+#include <LockBoxLib.h>
+
+#pragma pack(1)
+typedef struct {
+ EFI_GUID Guid;
+ EFI_PHYSICAL_ADDRESS OrigAddress;
+ EFI_PHYSICAL_ADDRESS CopyAddress;
+ UINT32 Size;
+ UINT64 Attributes;
+} LOCK_BOX_ENTRY;
+#pragma pack()
+
+LOCK_BOX_GLOBAL *mLockBoxGlobal = NULL;
+STATIC LOCK_BOX_ENTRY *StartOfEntries = NULL;
+STATIC LOCK_BOX_ENTRY *EndOfEntries = NULL;
+
+RETURN_STATUS
+EFIAPI
+LockBoxLibInitialize (
+ VOID
+ )
+{
+ UINTN NumEntries;
+
+ if (PcdGet32 (PcdOvmfLockBoxStorageSize) < sizeof (LOCK_BOX_GLOBAL)) {
+ return RETURN_UNSUPPORTED;
+ }
+
+ mLockBoxGlobal = (LOCK_BOX_GLOBAL *)(UINTN) PcdGet32 (PcdOvmfLockBoxStorageBase);
+ StartOfEntries = ((LOCK_BOX_ENTRY *) (mLockBoxGlobal + 1));
+ NumEntries = ((PcdGet32 (PcdOvmfLockBoxStorageSize) - sizeof (LOCK_BOX_GLOBAL)) /
+ sizeof (LOCK_BOX_ENTRY));
+ EndOfEntries = StartOfEntries + NumEntries;
+ if (mLockBoxGlobal->Signature != LOCK_BOX_GLOBAL_SIGNATURE) {
+ //
+ // Note: This code depends on the lock box being cleared in early
+ // PEI before usage, so the SubPageBuffer and SubPageRemaining
+ // fields don't need to be set to 0.
+ //
+ mLockBoxGlobal->Signature = LOCK_BOX_GLOBAL_SIGNATURE;
+ }
+ return RETURN_SUCCESS;
+}
+
+
+/**
+ Find LockBox entry based on GUID.
+
+ @param[in] Guid The GUID to search for.
+
+ @return Address of the LOCK_BOX_ENTRY found.
+
+ If NULL, then the item was not found, and there is no space
+ left to store a new item.
+
+ If non-NULL and LOCK_BOX_ENTRY.Size == 0, then the item was not
+ found, but a new item can be inserted at the returned location.
+
+ If non-NULL and LOCK_BOX_ENTRY.Size > 0, then the item was found.
+**/
+STATIC
+LOCK_BOX_ENTRY *
+EFIAPI
+FindHeaderByGuid (
+ IN CONST EFI_GUID *Guid
+ )
+{
+ LOCK_BOX_ENTRY *Header;
+
+ for (Header = StartOfEntries; Header < EndOfEntries; Header++) {
+ if (Header->Size == 0 || CompareGuid (Guid, &Header->Guid)) {
+ return Header;
+ }
+ }
+
+ return NULL;
+}
+
+
+/**
+ This function will save confidential information to lockbox.
+
+ @param Guid the guid to identify the confidential information
+ @param Buffer the address of the confidential information
+ @param Length the length of the confidential information
+
+ @retval RETURN_SUCCESS the information is saved successfully.
+ @retval RETURN_INVALID_PARAMETER the Guid is NULL, or Buffer is NULL, or
+ Length is 0
+ @retval RETURN_ALREADY_STARTED the requested GUID already exist.
+ @retval RETURN_OUT_OF_RESOURCES no enough resource to save the information.
+ @retval RETURN_ACCESS_DENIED it is too late to invoke this interface
+ @retval RETURN_NOT_STARTED it is too early to invoke this interface
+ @retval RETURN_UNSUPPORTED the service is not supported by
+ implementaion.
+**/
+RETURN_STATUS
+EFIAPI
+SaveLockBox (
+ IN GUID *Guid,
+ IN VOID *Buffer,
+ IN UINTN Length
+ )
+{
+ LOCK_BOX_ENTRY *Header;
+ VOID *CopyBuffer;
+
+ DEBUG ((DEBUG_VERBOSE, "%a: Guid=%g Buffer=%p Length=0x%x\n", __FUNCTION__,
+ Guid, Buffer, (UINT32) Length));
+
+ if (Guid == NULL || Buffer == NULL || Length == 0) {
+ return RETURN_INVALID_PARAMETER;
+ }
+
+ if (Length > 0xFFFFFFFF) {
+ return RETURN_OUT_OF_RESOURCES;
+ }
+
+ Header = FindHeaderByGuid (Guid);
+ if (Header == NULL) {
+ return RETURN_OUT_OF_RESOURCES;
+ }
+
+ if (Header->Size > 0) {
+ return RETURN_ALREADY_STARTED;
+ }
+
+ CopyBuffer = AllocateAcpiNvsPool (Length);
+ if (CopyBuffer == NULL) {
+ return RETURN_OUT_OF_RESOURCES;
+ }
+
+ //
+ // overwrite the current terminator header with new metadata
+ //
+ CopyGuid (&Header->Guid, Guid);
+ Header->OrigAddress = (UINTN) Buffer;
+ Header->CopyAddress = (UINTN) CopyBuffer;
+ Header->Size = (UINT32) Length;
+ Header->Attributes = 0;
+
+ //
+ // copy contents
+ //
+ CopyMem (CopyBuffer, Buffer, Length);
+
+ return RETURN_SUCCESS;
+}
+
+
+/**
+ This function will set lockbox attributes.
+
+ @param Guid the guid to identify the confidential information
+ @param Attributes the attributes of the lockbox
+
+ @retval RETURN_SUCCESS the information is saved successfully.
+ @retval RETURN_INVALID_PARAMETER attributes is invalid.
+ @retval RETURN_NOT_FOUND the requested GUID not found.
+ @retval RETURN_ACCESS_DENIED it is too late to invoke this interface
+ @retval RETURN_NOT_STARTED it is too early to invoke this interface
+ @retval RETURN_UNSUPPORTED the service is not supported by
+ implementaion.
+**/
+RETURN_STATUS
+EFIAPI
+SetLockBoxAttributes (
+ IN GUID *Guid,
+ IN UINT64 Attributes
+ )
+{
+ LOCK_BOX_ENTRY *Header;
+
+ DEBUG ((DEBUG_VERBOSE, "%a: Guid=%g Attributes=0x%Lx\n", __FUNCTION__, Guid,
+ Attributes));
+
+ if (Guid == NULL) {
+ return RETURN_INVALID_PARAMETER;
+ }
+
+ Header = FindHeaderByGuid (Guid);
+ if (!Header || Header->Size == 0) {
+ return RETURN_NOT_FOUND;
+ }
+ Header->Attributes = Attributes;
+
+ return RETURN_SUCCESS;
+}
+
+
+/**
+ This function will update confidential information to lockbox.
+
+ @param Guid the guid to identify the original confidential information
+ @param Offset the offset of the original confidential information
+ @param Buffer the address of the updated confidential information
+ @param Length the length of the updated confidential information
+
+ @retval RETURN_SUCCESS the information is saved successfully.
+ @retval RETURN_INVALID_PARAMETER the Guid is NULL, or Buffer is NULL, or
+ Length is 0.
+ @retval RETURN_NOT_FOUND the requested GUID not found.
+ @retval RETURN_BUFFER_TOO_SMALL the original buffer to too small to hold
+ new information.
+ @retval RETURN_ACCESS_DENIED it is too late to invoke this interface
+ @retval RETURN_NOT_STARTED it is too early to invoke this interface
+ @retval RETURN_UNSUPPORTED the service is not supported by
+ implementaion.
+**/
+RETURN_STATUS
+EFIAPI
+UpdateLockBox (
+ IN GUID *Guid,
+ IN UINTN Offset,
+ IN VOID *Buffer,
+ IN UINTN Length
+ )
+{
+ LOCK_BOX_ENTRY *Header;
+
+ DEBUG ((DEBUG_VERBOSE, "%a: Guid=%g Offset=0x%x Length=0x%x\n", __FUNCTION__,
+ Guid, (UINT32) Offset, (UINT32) Length));
+
+ if (Guid == NULL || Buffer == NULL || Length == 0) {
+ return RETURN_INVALID_PARAMETER;
+ }
+
+ Header = FindHeaderByGuid (Guid);
+ if (!Header || Header->Size == 0) {
+ return RETURN_NOT_FOUND;
+ }
+
+ if (Header->Size < Offset ||
+ Length > Header->Size - Offset) {
+ return RETURN_BUFFER_TOO_SMALL;
+ }
+
+ CopyMem ((UINT8 *)(UINTN) (Header->CopyAddress) + Offset, Buffer, Length);
+
+ return RETURN_SUCCESS;
+}
+
+
+/**
+ This function will restore confidential information from lockbox.
+
+ @param Guid the guid to identify the confidential information
+ @param Buffer the address of the restored confidential information
+ NULL means restored to original address, Length MUST be NULL at
+ same time.
+ @param Length the length of the restored confidential information
+
+ @retval RETURN_SUCCESS the information is restored successfully.
+ @retval RETURN_INVALID_PARAMETER the Guid is NULL, or one of Buffer and
+ Length is NULL.
+ @retval RETURN_WRITE_PROTECTED Buffer and Length are NULL, but the LockBox
+ has no LOCK_BOX_ATTRIBUTE_RESTORE_IN_PLACE
+ attribute.
+ @retval RETURN_BUFFER_TOO_SMALL the Length is too small to hold the
+ confidential information.
+ @retval RETURN_NOT_FOUND the requested GUID not found.
+ @retval RETURN_NOT_STARTED it is too early to invoke this interface
+ @retval RETURN_ACCESS_DENIED not allow to restore to the address
+ @retval RETURN_UNSUPPORTED the service is not supported by
+ implementaion.
+**/
+RETURN_STATUS
+EFIAPI
+RestoreLockBox (
+ IN GUID *Guid,
+ IN VOID *Buffer, OPTIONAL
+ IN OUT UINTN *Length OPTIONAL
+ )
+{
+ LOCK_BOX_ENTRY *Header;
+
+ DEBUG ((DEBUG_VERBOSE, "%a: Guid=%g Buffer=%p\n", __FUNCTION__, Guid,
+ Buffer));
+
+ if ((Guid == NULL) ||
+ ((Buffer == NULL) && (Length != NULL)) ||
+ ((Buffer != NULL) && (Length == NULL))) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Header = FindHeaderByGuid (Guid);
+ if (!Header || Header->Size == 0) {
+ return RETURN_NOT_FOUND;
+ }
+
+ if (Buffer == NULL) {
+ if (!(Header->Attributes & LOCK_BOX_ATTRIBUTE_RESTORE_IN_PLACE)) {
+ return RETURN_WRITE_PROTECTED;
+ }
+ if (Header->OrigAddress + (Header->Size - 1) > MAX_ADDRESS) {
+ return RETURN_UNSUPPORTED;
+ }
+ Buffer = (VOID *)(UINTN) Header->OrigAddress;
+ }
+
+ //
+ // Set RestoreLength
+ //
+ if (Length != NULL) {
+ if (Header->Size > *Length) {
+ //
+ // Input buffer is too small to hold all data.
+ //
+ *Length = Header->Size;
+ return EFI_BUFFER_TOO_SMALL;
+ }
+ *Length = Header->Size;
+ }
+
+ CopyMem (Buffer, (VOID*)(UINTN) Header->CopyAddress, Header->Size);
+
+ return RETURN_SUCCESS;
+}
+
+
+/**
+ This function will restore confidential information from all lockbox which
+ have RestoreInPlace attribute.
+
+ @retval RETURN_SUCCESS the information is restored successfully.
+ @retval RETURN_NOT_STARTED it is too early to invoke this interface
+ @retval RETURN_UNSUPPORTED the service is not supported by
+ implementaion.
+**/
+RETURN_STATUS
+EFIAPI
+RestoreAllLockBoxInPlace (
+ VOID
+ )
+{
+ LOCK_BOX_ENTRY *Header;
+
+ for (Header = StartOfEntries;
+ Header < EndOfEntries && Header->Size > 0;
+ Header++) {
+ if (Header->Attributes & LOCK_BOX_ATTRIBUTE_RESTORE_IN_PLACE) {
+ VOID *Buffer;
+
+ if (Header->OrigAddress + (Header->Size - 1) > MAX_ADDRESS) {
+ return RETURN_UNSUPPORTED;
+ }
+ Buffer = (VOID *)(UINTN) Header->OrigAddress;
+ CopyMem (Buffer, (VOID*)(UINTN)Header->CopyAddress, Header->Size);
+ DEBUG ((DEBUG_VERBOSE, "%a: Guid=%g Buffer=%p\n", __FUNCTION__,
+ Header->Guid, Buffer));
+ }
+ }
+ return RETURN_SUCCESS;
+}
diff --git a/OvmfPkg/Library/LockBoxLib/LockBoxLib.h b/OvmfPkg/Library/LockBoxLib/LockBoxLib.h
new file mode 100644
index 000000000..5adb65fef
--- /dev/null
+++ b/OvmfPkg/Library/LockBoxLib/LockBoxLib.h
@@ -0,0 +1,60 @@
+/** @file
+
+ Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.<BR>
+
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef __LOCK_BOX_LIB_IMPL_H__
+#define __LOCK_BOX_LIB_IMPL_H__
+
+#pragma pack(1)
+
+typedef struct {
+ UINT32 Signature;
+ UINT32 SubPageBuffer;
+ UINT32 SubPageRemaining;
+} LOCK_BOX_GLOBAL;
+
+#define LOCK_BOX_GLOBAL_SIGNATURE SIGNATURE_32('L', 'B', 'G', 'S')
+
+extern LOCK_BOX_GLOBAL *mLockBoxGlobal;
+
+#pragma pack()
+
+/**
+ Allocates a buffer of type EfiACPIMemoryNVS.
+
+ Allocates the number bytes specified by AllocationSize of type
+ EfiACPIMemoryNVS and returns a pointer to the allocated buffer.
+ If AllocationSize is 0, then a valid buffer of 0 size is
+ returned. If there is not enough memory remaining to satisfy
+ the request, then NULL is returned.
+
+ @param AllocationSize The number of bytes to allocate.
+
+ @return A pointer to the allocated buffer or NULL if allocation fails.
+
+**/
+VOID *
+EFIAPI
+AllocateAcpiNvsPool (
+ IN UINTN AllocationSize
+ );
+
+
+RETURN_STATUS
+EFIAPI
+LockBoxLibInitialize (
+ VOID
+ );
+
+
+#endif
diff --git a/OvmfPkg/Library/PlatformBdsLib/BdsPlatform.c b/OvmfPkg/Library/PlatformBdsLib/BdsPlatform.c
index ab9c93eaf..9f953acf7 100644
--- a/OvmfPkg/Library/PlatformBdsLib/BdsPlatform.c
+++ b/OvmfPkg/Library/PlatformBdsLib/BdsPlatform.c
@@ -1156,25 +1156,11 @@ Returns:
BdsLibEnumerateAllBootOption (BootOptionList);
SetBootOrderFromQemu (BootOptionList);
-
- //
- // Please uncomment above ConnectAll and EnumerateAll code and remove following first boot
- // checking code in real production tip.
//
- // In BOOT_WITH_FULL_CONFIGURATION boot mode, should always connect every device
- // and do enumerate all the default boot options. But in development system board, the boot mode
- // cannot be BOOT_ASSUMING_NO_CONFIGURATION_CHANGES because the machine box
- // is always open. So the following code only do the ConnectAll and EnumerateAll at first boot.
+ // The BootOrder variable may have changed, reload the in-memory list with
+ // it.
//
- Status = BdsLibBuildOptionFromVar (BootOptionList, L"BootOrder");
- if (EFI_ERROR(Status)) {
- //
- // If cannot find "BootOrder" variable, it may be first boot.
- // Try to connect all devices and enumerate all boot options here.
- //
- BdsLibConnectAll ();
- BdsLibEnumerateAllBootOption (BootOptionList);
- }
+ BdsLibBuildOptionFromVar (BootOptionList, L"BootOrder");
//
// To give the User a chance to enter Setup here, if user set TimeOut is 0.
diff --git a/OvmfPkg/Library/PlatformBdsLib/QemuBootOrder.c b/OvmfPkg/Library/PlatformBdsLib/QemuBootOrder.c
index c8379b8fc..bd0fb7687 100644
--- a/OvmfPkg/Library/PlatformBdsLib/QemuBootOrder.c
+++ b/OvmfPkg/Library/PlatformBdsLib/QemuBootOrder.c
@@ -763,37 +763,27 @@ TranslateOfwNodes (
TargetLun[0],
TargetLun[1]
);
- } else if (NumNodes >= 3 &&
- SubstringEq (OfwNode[1].DriverName, "ethernet") &&
- SubstringEq (OfwNode[2].DriverName, "ethernet-phy")
- ) {
+ } else {
//
- // OpenFirmware device path (Ethernet NIC):
+ // Generic OpenFirmware device path for PCI devices:
//
- // /pci@i0cf8/ethernet@3[,2]/ethernet-phy@0
- // ^ ^ ^
- // | | fixed
+ // /pci@i0cf8/ethernet@3[,2]
+ // ^ ^
// | PCI slot[, function] holding Ethernet card
// PCI root at system bus port, PIO
//
// UEFI device path prefix (dependent on presence of nonzero PCI function):
//
- // PciRoot(0x0)/Pci(0x3,0x0)/MAC(525400E15EEF,0x1)
- // PciRoot(0x0)/Pci(0x3,0x2)/MAC(525400E15EEF,0x1)
- // ^ ^
- // MAC address IfType (1 == Ethernet)
- //
- // (Some UEFI NIC drivers don't set 0x1 for IfType.)
+ // PciRoot(0x0)/Pci(0x3,0x0)
+ // PciRoot(0x0)/Pci(0x3,0x2)
//
Written = UnicodeSPrintAsciiFormat (
Translated,
*TranslatedSize * sizeof (*Translated), // BufferSize in bytes
- "PciRoot(0x0)/Pci(0x%x,0x%x)/MAC",
+ "PciRoot(0x0)/Pci(0x%x,0x%x)",
PciDevFun[0],
PciDevFun[1]
);
- } else {
- return RETURN_UNSUPPORTED;
}
//
@@ -1121,6 +1111,47 @@ BootOrderComplete (
/**
+ Delete Boot#### variables that stand for such active boot options that have
+ been dropped (ie. have not been selected by either matching or "survival
+ policy").
+
+ @param[in] ActiveOption The array of active boot options to scan. Each
+ entry not marked as appended will trigger the
+ deletion of the matching Boot#### variable.
+
+ @param[in] ActiveCount Number of elements in ActiveOption.
+**/
+STATIC
+VOID
+PruneBootVariables (
+ IN CONST ACTIVE_OPTION *ActiveOption,
+ IN UINTN ActiveCount
+ )
+{
+ UINTN Idx;
+
+ for (Idx = 0; Idx < ActiveCount; ++Idx) {
+ if (!ActiveOption[Idx].Appended) {
+ CHAR16 VariableName[9];
+
+ UnicodeSPrintAsciiFormat (VariableName, sizeof VariableName, "Boot%04x",
+ ActiveOption[Idx].BootOption->BootCurrent);
+
+ //
+ // "The space consumed by the deleted variable may not be available until
+ // the next power cycle", but that's good enough.
+ //
+ gRT->SetVariable (VariableName, &gEfiGlobalVariableGuid,
+ 0, // Attributes, 0 means deletion
+ 0, // DataSize, 0 means deletion
+ NULL // Data
+ );
+ }
+ }
+}
+
+
+/**
Set the boot order based on configuration retrieved from QEMU.
@@ -1269,12 +1300,13 @@ SetBootOrderFromQemu (
BootOrder.Produced * sizeof (*BootOrder.Data),
BootOrder.Data
);
- DEBUG ((
- DEBUG_INFO,
- "%a: setting BootOrder: %a\n",
- __FUNCTION__,
- Status == EFI_SUCCESS ? "success" : "error"
- ));
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a: setting BootOrder: %r\n", __FUNCTION__, Status));
+ goto ErrorFreeActiveOption;
+ }
+
+ DEBUG ((DEBUG_INFO, "%a: setting BootOrder: success\n", __FUNCTION__));
+ PruneBootVariables (ActiveOption, ActiveCount);
}
ErrorFreeActiveOption:
diff --git a/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgLib.c b/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgLib.c
index 3c5963f31..92c85c1d3 100644
--- a/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgLib.c
+++ b/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgLib.c
@@ -294,3 +294,31 @@ QemuFwCfgFindFile (
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_STATUS Status;
+ FIRMWARE_CONFIG_ITEM FwCfgItem;
+ UINTN FwCfgSize;
+ UINT8 SystemStates[6];
+
+ Status = QemuFwCfgFindFile ("etc/system-states", &FwCfgItem, &FwCfgSize);
+ if (Status != RETURN_SUCCESS || FwCfgSize != sizeof SystemStates) {
+ return FALSE;
+ }
+ QemuFwCfgSelectItem (FwCfgItem);
+ QemuFwCfgReadBytes (sizeof SystemStates, SystemStates);
+ return (BOOLEAN) (SystemStates[3] & BIT7);
+}
diff --git a/OvmfPkg/OvmfPkg.dec b/OvmfPkg/OvmfPkg.dec
index 034ccd8ef..aca9cb7cc 100644
--- a/OvmfPkg/OvmfPkg.dec
+++ b/OvmfPkg/OvmfPkg.dec
@@ -42,6 +42,7 @@
[Guids]
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}}
[Protocols]
gVirtioDeviceProtocolGuid = {0xfa920010, 0x6785, 0x4941, {0xb6, 0xec, 0x49, 0x8c, 0x57, 0x9f, 0x16, 0x0a}}
@@ -84,6 +85,9 @@
gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPageTablesSize|0x0|UINT32|0x12
gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPeiTempRamBase|0x0|UINT32|0x13
gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPeiTempRamSize|0x0|UINT32|0x14
+ gUefiOvmfPkgTokenSpaceGuid.PcdS3AcpiReservedMemoryBase|0x0|UINT32|0x17
+ gUefiOvmfPkgTokenSpaceGuid.PcdOvmfLockBoxStorageBase|0x0|UINT32|0x18
+ gUefiOvmfPkgTokenSpaceGuid.PcdOvmfLockBoxStorageSize|0x0|UINT32|0x19
[PcdsDynamic, PcdsDynamicEx]
gUefiOvmfPkgTokenSpaceGuid.PcdEmuVariableEvent|0|UINT64|2
diff --git a/OvmfPkg/OvmfPkgIa32.dsc b/OvmfPkg/OvmfPkgIa32.dsc
index 88d479db2..f7064b737 100644
--- a/OvmfPkg/OvmfPkgIa32.dsc
+++ b/OvmfPkg/OvmfPkgIa32.dsc
@@ -1,7 +1,7 @@
## @file
# EFI/Framework Open Virtual Machine Firmware (OVMF) platform
#
-# 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
@@ -99,7 +99,7 @@
QemuFwCfgLib|OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgLib.inf
VirtioLib|OvmfPkg/Library/VirtioLib/VirtioLib.inf
LoadLinuxLib|OvmfPkg/Library/LoadLinuxLib/LoadLinuxLib.inf
- LockBoxLib|MdeModulePkg/Library/LockBoxNullLib/LockBoxNullLib.inf
+ LockBoxLib|OvmfPkg/Library/LockBoxLib/LockBoxBaseLib.inf
CustomizedDisplayLib|MdeModulePkg/Library/CustomizedDisplayLib/CustomizedDisplayLib.inf
!ifdef $(SOURCE_DEBUG_ENABLE)
@@ -121,6 +121,9 @@
TpmMeasurementLib|SecurityPkg/Library/DxeTpmMeasurementLib/DxeTpmMeasurementLib.inf
!endif
+ S3BootScriptLib|MdeModulePkg/Library/PiDxeS3BootScriptLib/DxeS3BootScriptLib.inf
+ SmbusLib|MdePkg/Library/BaseSmbusLibNull/BaseSmbusLibNull.inf
+
[LibraryClasses.common]
!if $(SECURE_BOOT_ENABLE) == TRUE
BaseCryptLib|CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf
@@ -244,6 +247,10 @@
DpcLib|MdeModulePkg/Library/DxeDpcLib/DxeDpcLib.inf
PlatformBdsLib|OvmfPkg/Library/PlatformBdsLib/PlatformBdsLib.inf
CpuExceptionHandlerLib|UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeCpuExceptionHandlerLib.inf
+ LockBoxLib|OvmfPkg/Library/LockBoxLib/LockBoxDxeLib.inf
+!ifdef $(SOURCE_DEBUG_ENABLE)
+ DebugAgentLib|SourceLevelDebugPkg/Library/DebugAgent/DxeDebugAgentLib.inf
+!endif
[LibraryClasses.common.UEFI_APPLICATION]
HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf
@@ -320,6 +327,8 @@
gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingBase|0
gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareBase|0
gEfiMdeModulePkgTokenSpaceGuid.PcdPciDisableBusEnumeration|FALSE
+ gEfiMdeModulePkgTokenSpaceGuid.PcdVideoHorizontalResolution|800
+ gEfiMdeModulePkgTokenSpaceGuid.PcdVideoVerticalResolution|600
################################################################################
@@ -351,6 +360,10 @@
<LibraryClasses>
PcdLib|MdePkg/Library/PeiPcdLib/PeiPcdLib.inf
}
+ UefiCpuPkg/Universal/Acpi/S3Resume2Pei/S3Resume2Pei.inf {
+ <LibraryClasses>
+ PcdLib|MdePkg/Library/PeiPcdLib/PeiPcdLib.inf
+ }
#
# DXE Phase modules
@@ -423,7 +436,10 @@
MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleRuntimeDxe.inf
MdeModulePkg/Universal/Console/ConPlatformDxe/ConPlatformDxe.inf
MdeModulePkg/Universal/Console/ConSplitterDxe/ConSplitterDxe.inf
- MdeModulePkg/Universal/Console/GraphicsConsoleDxe/GraphicsConsoleDxe.inf
+ MdeModulePkg/Universal/Console/GraphicsConsoleDxe/GraphicsConsoleDxe.inf {
+ <LibraryClasses>
+ PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf
+ }
MdeModulePkg/Universal/Console/TerminalDxe/TerminalDxe.inf
MdeModulePkg/Universal/DevicePathDxe/DevicePathDxe.inf {
<LibraryClasses>
@@ -469,6 +485,9 @@
MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableDxe.inf
OvmfPkg/AcpiPlatformDxe/AcpiPlatformDxe.inf
OvmfPkg/AcpiTables/AcpiTables.inf
+ OvmfPkg/AcpiS3SaveDxe/AcpiS3SaveDxe.inf
+ MdeModulePkg/Universal/Acpi/S3SaveStateDxe/S3SaveStateDxe.inf
+ MdeModulePkg/Universal/Acpi/BootScriptExecutorDxe/BootScriptExecutorDxe.inf
#
# Network Support
@@ -498,7 +517,10 @@
MdeModulePkg/Bus/Usb/UsbMassStorageDxe/UsbMassStorageDxe.inf
!ifdef $(CSM_ENABLE)
- IntelFrameworkModulePkg/Csm/BiosThunk/VideoDxe/VideoDxe.inf
+ IntelFrameworkModulePkg/Csm/BiosThunk/VideoDxe/VideoDxe.inf {
+ <LibraryClasses>
+ PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf
+ }
IntelFrameworkModulePkg/Csm/LegacyBiosDxe/LegacyBiosDxe.inf
OvmfPkg/Csm/Csm16/Csm16.inf
!endif
@@ -538,3 +560,5 @@
}
OvmfPkg/SecureBootConfigDxe/SecureBootConfigDxe.inf
!endif
+
+ OvmfPkg/PlatformDxe/Platform.inf
diff --git a/OvmfPkg/OvmfPkgIa32.fdf b/OvmfPkg/OvmfPkgIa32.fdf
index 7c4e6cda6..1f78b5bf9 100644
--- a/OvmfPkg/OvmfPkgIa32.fdf
+++ b/OvmfPkg/OvmfPkgIa32.fdf
@@ -130,22 +130,28 @@ FV = SECFV
[FD.MEMFD]
BaseAddress = 0x800000
-Size = 0x800000
+Size = 0x900000
ErasePolarity = 1
BlockSize = 0x10000
-NumBlocks = 0x80
+NumBlocks = 0x90
0x000000|0x006000
gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPageTablesBase|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPageTablesSize
+0x006000|0x001000
+gUefiOvmfPkgTokenSpaceGuid.PcdOvmfLockBoxStorageBase|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfLockBoxStorageSize
+
0x010000|0x008000
gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPeiTempRamBase|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPeiTempRamSize
+0x018000|0x008000
+gUefiOvmfPkgTokenSpaceGuid.PcdS3AcpiReservedMemoryBase|gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdS3AcpiReservedMemorySize
+
0x020000|0x0E0000
gUefiOvmfPkgTokenSpaceGuid.PcdOvmfPeiMemFvBase|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfPeiMemFvSize
FV = PEIFV
-0x100000|0x700000
+0x100000|0x800000
gUefiOvmfPkgTokenSpaceGuid.PcdOvmfDxeMemFvBase|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfDxeMemFvSize
FV = DXEFV
@@ -212,6 +218,7 @@ INF MdeModulePkg/Universal/PCD/Pei/Pcd.inf
INF IntelFrameworkModulePkg/Universal/StatusCode/Pei/StatusCodePei.inf
INF OvmfPkg/PlatformPei/PlatformPei.inf
INF MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf
+INF UefiCpuPkg/Universal/Acpi/S3Resume2Pei/S3Resume2Pei.inf
################################################################################
@@ -314,6 +321,9 @@ INF OvmfPkg/SmbiosPlatformDxe/SmbiosPlatformDxe.inf
INF MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableDxe.inf
INF OvmfPkg/AcpiPlatformDxe/AcpiPlatformDxe.inf
INF RuleOverride=ACPITABLE OvmfPkg/AcpiTables/AcpiTables.inf
+INF OvmfPkg/AcpiS3SaveDxe/AcpiS3SaveDxe.inf
+INF MdeModulePkg/Universal/Acpi/S3SaveStateDxe/S3SaveStateDxe.inf
+INF MdeModulePkg/Universal/Acpi/BootScriptExecutorDxe/BootScriptExecutorDxe.inf
INF RuleOverride = BINARY FatBinPkg/EnhancedFatDxe/Fat.inf
@@ -366,6 +376,7 @@ INF RuleOverride=CSM OvmfPkg/Csm/Csm16/Csm16.inf
!endif
INF OvmfPkg/QemuVideoDxe/QemuVideoDxe.inf
+INF OvmfPkg/PlatformDxe/Platform.inf
################################################################################
diff --git a/OvmfPkg/OvmfPkgIa32X64.dsc b/OvmfPkg/OvmfPkgIa32X64.dsc
index f19b65842..26d1132a8 100644
--- a/OvmfPkg/OvmfPkgIa32X64.dsc
+++ b/OvmfPkg/OvmfPkgIa32X64.dsc
@@ -1,7 +1,7 @@
## @file
# EFI/Framework Open Virtual Machine Firmware (OVMF) platform
#
-# 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
@@ -104,7 +104,7 @@
QemuFwCfgLib|OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgLib.inf
VirtioLib|OvmfPkg/Library/VirtioLib/VirtioLib.inf
LoadLinuxLib|OvmfPkg/Library/LoadLinuxLib/LoadLinuxLib.inf
- LockBoxLib|MdeModulePkg/Library/LockBoxNullLib/LockBoxNullLib.inf
+ LockBoxLib|OvmfPkg/Library/LockBoxLib/LockBoxBaseLib.inf
CustomizedDisplayLib|MdeModulePkg/Library/CustomizedDisplayLib/CustomizedDisplayLib.inf
!ifdef $(SOURCE_DEBUG_ENABLE)
@@ -126,6 +126,9 @@
TpmMeasurementLib|SecurityPkg/Library/DxeTpmMeasurementLib/DxeTpmMeasurementLib.inf
!endif
+ S3BootScriptLib|MdeModulePkg/Library/PiDxeS3BootScriptLib/DxeS3BootScriptLib.inf
+ SmbusLib|MdePkg/Library/BaseSmbusLibNull/BaseSmbusLibNull.inf
+
[LibraryClasses.common]
!if $(SECURE_BOOT_ENABLE) == TRUE
BaseCryptLib|CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf
@@ -249,6 +252,10 @@
DpcLib|MdeModulePkg/Library/DxeDpcLib/DxeDpcLib.inf
PlatformBdsLib|OvmfPkg/Library/PlatformBdsLib/PlatformBdsLib.inf
CpuExceptionHandlerLib|UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeCpuExceptionHandlerLib.inf
+ LockBoxLib|OvmfPkg/Library/LockBoxLib/LockBoxDxeLib.inf
+!ifdef $(SOURCE_DEBUG_ENABLE)
+ DebugAgentLib|SourceLevelDebugPkg/Library/DebugAgent/DxeDebugAgentLib.inf
+!endif
[LibraryClasses.common.UEFI_APPLICATION]
HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf
@@ -326,6 +333,8 @@
gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingBase|0
gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareBase|0
gEfiMdeModulePkgTokenSpaceGuid.PcdPciDisableBusEnumeration|FALSE
+ gEfiMdeModulePkgTokenSpaceGuid.PcdVideoHorizontalResolution|800
+ gEfiMdeModulePkgTokenSpaceGuid.PcdVideoVerticalResolution|600
################################################################################
@@ -357,6 +366,10 @@
<LibraryClasses>
PcdLib|MdePkg/Library/PeiPcdLib/PeiPcdLib.inf
}
+ UefiCpuPkg/Universal/Acpi/S3Resume2Pei/S3Resume2Pei.inf {
+ <LibraryClasses>
+ PcdLib|MdePkg/Library/PeiPcdLib/PeiPcdLib.inf
+ }
[Components.X64]
#
@@ -430,7 +443,10 @@
MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleRuntimeDxe.inf
MdeModulePkg/Universal/Console/ConPlatformDxe/ConPlatformDxe.inf
MdeModulePkg/Universal/Console/ConSplitterDxe/ConSplitterDxe.inf
- MdeModulePkg/Universal/Console/GraphicsConsoleDxe/GraphicsConsoleDxe.inf
+ MdeModulePkg/Universal/Console/GraphicsConsoleDxe/GraphicsConsoleDxe.inf {
+ <LibraryClasses>
+ PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf
+ }
MdeModulePkg/Universal/Console/TerminalDxe/TerminalDxe.inf
MdeModulePkg/Universal/DevicePathDxe/DevicePathDxe.inf {
<LibraryClasses>
@@ -476,6 +492,9 @@
MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableDxe.inf
OvmfPkg/AcpiPlatformDxe/AcpiPlatformDxe.inf
OvmfPkg/AcpiTables/AcpiTables.inf
+ OvmfPkg/AcpiS3SaveDxe/AcpiS3SaveDxe.inf
+ MdeModulePkg/Universal/Acpi/S3SaveStateDxe/S3SaveStateDxe.inf
+ MdeModulePkg/Universal/Acpi/BootScriptExecutorDxe/BootScriptExecutorDxe.inf
#
# Network Support
@@ -505,7 +524,10 @@
MdeModulePkg/Bus/Usb/UsbMassStorageDxe/UsbMassStorageDxe.inf
!ifdef $(CSM_ENABLE)
- IntelFrameworkModulePkg/Csm/BiosThunk/VideoDxe/VideoDxe.inf
+ IntelFrameworkModulePkg/Csm/BiosThunk/VideoDxe/VideoDxe.inf {
+ <LibraryClasses>
+ PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf
+ }
IntelFrameworkModulePkg/Csm/LegacyBiosDxe/LegacyBiosDxe.inf
OvmfPkg/Csm/Csm16/Csm16.inf
!endif
@@ -545,3 +567,5 @@
}
OvmfPkg/SecureBootConfigDxe/SecureBootConfigDxe.inf
!endif
+
+ OvmfPkg/PlatformDxe/Platform.inf
diff --git a/OvmfPkg/OvmfPkgIa32X64.fdf b/OvmfPkg/OvmfPkgIa32X64.fdf
index 3cb49de30..e78995b32 100644
--- a/OvmfPkg/OvmfPkgIa32X64.fdf
+++ b/OvmfPkg/OvmfPkgIa32X64.fdf
@@ -130,22 +130,28 @@ FV = SECFV
[FD.MEMFD]
BaseAddress = 0x800000
-Size = 0x800000
+Size = 0x900000
ErasePolarity = 1
BlockSize = 0x10000
-NumBlocks = 0x80
+NumBlocks = 0x90
0x000000|0x006000
gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPageTablesBase|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPageTablesSize
+0x006000|0x001000
+gUefiOvmfPkgTokenSpaceGuid.PcdOvmfLockBoxStorageBase|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfLockBoxStorageSize
+
0x010000|0x008000
gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPeiTempRamBase|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPeiTempRamSize
+0x018000|0x008000
+gUefiOvmfPkgTokenSpaceGuid.PcdS3AcpiReservedMemoryBase|gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdS3AcpiReservedMemorySize
+
0x020000|0x0E0000
gUefiOvmfPkgTokenSpaceGuid.PcdOvmfPeiMemFvBase|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfPeiMemFvSize
FV = PEIFV
-0x100000|0x700000
+0x100000|0x800000
gUefiOvmfPkgTokenSpaceGuid.PcdOvmfDxeMemFvBase|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfDxeMemFvSize
FV = DXEFV
@@ -212,6 +218,7 @@ INF MdeModulePkg/Universal/PCD/Pei/Pcd.inf
INF IntelFrameworkModulePkg/Universal/StatusCode/Pei/StatusCodePei.inf
INF OvmfPkg/PlatformPei/PlatformPei.inf
INF MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf
+INF UefiCpuPkg/Universal/Acpi/S3Resume2Pei/S3Resume2Pei.inf
################################################################################
@@ -314,6 +321,9 @@ INF OvmfPkg/SmbiosPlatformDxe/SmbiosPlatformDxe.inf
INF MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableDxe.inf
INF OvmfPkg/AcpiPlatformDxe/AcpiPlatformDxe.inf
INF RuleOverride=ACPITABLE OvmfPkg/AcpiTables/AcpiTables.inf
+INF OvmfPkg/AcpiS3SaveDxe/AcpiS3SaveDxe.inf
+INF MdeModulePkg/Universal/Acpi/S3SaveStateDxe/S3SaveStateDxe.inf
+INF MdeModulePkg/Universal/Acpi/BootScriptExecutorDxe/BootScriptExecutorDxe.inf
INF RuleOverride = BINARY USE = X64 FatBinPkg/EnhancedFatDxe/Fat.inf
@@ -366,6 +376,7 @@ INF RuleOverride=CSM OvmfPkg/Csm/Csm16/Csm16.inf
!endif
INF OvmfPkg/QemuVideoDxe/QemuVideoDxe.inf
+INF OvmfPkg/PlatformDxe/Platform.inf
################################################################################
diff --git a/OvmfPkg/OvmfPkgX64.dsc b/OvmfPkg/OvmfPkgX64.dsc
index c4799791b..66459c217 100644
--- a/OvmfPkg/OvmfPkgX64.dsc
+++ b/OvmfPkg/OvmfPkgX64.dsc
@@ -1,7 +1,7 @@
## @file
# EFI/Framework Open Virtual Machine Firmware (OVMF) platform
#
-# 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
@@ -104,7 +104,7 @@
QemuFwCfgLib|OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgLib.inf
VirtioLib|OvmfPkg/Library/VirtioLib/VirtioLib.inf
LoadLinuxLib|OvmfPkg/Library/LoadLinuxLib/LoadLinuxLib.inf
- LockBoxLib|MdeModulePkg/Library/LockBoxNullLib/LockBoxNullLib.inf
+ LockBoxLib|OvmfPkg/Library/LockBoxLib/LockBoxBaseLib.inf
CustomizedDisplayLib|MdeModulePkg/Library/CustomizedDisplayLib/CustomizedDisplayLib.inf
!ifdef $(SOURCE_DEBUG_ENABLE)
@@ -126,6 +126,9 @@
TpmMeasurementLib|SecurityPkg/Library/DxeTpmMeasurementLib/DxeTpmMeasurementLib.inf
!endif
+ S3BootScriptLib|MdeModulePkg/Library/PiDxeS3BootScriptLib/DxeS3BootScriptLib.inf
+ SmbusLib|MdePkg/Library/BaseSmbusLibNull/BaseSmbusLibNull.inf
+
[LibraryClasses.common]
!if $(SECURE_BOOT_ENABLE) == TRUE
BaseCryptLib|CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf
@@ -249,6 +252,10 @@
DpcLib|MdeModulePkg/Library/DxeDpcLib/DxeDpcLib.inf
PlatformBdsLib|OvmfPkg/Library/PlatformBdsLib/PlatformBdsLib.inf
CpuExceptionHandlerLib|UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeCpuExceptionHandlerLib.inf
+ LockBoxLib|OvmfPkg/Library/LockBoxLib/LockBoxDxeLib.inf
+!ifdef $(SOURCE_DEBUG_ENABLE)
+ DebugAgentLib|SourceLevelDebugPkg/Library/DebugAgent/DxeDebugAgentLib.inf
+!endif
[LibraryClasses.common.UEFI_APPLICATION]
HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf
@@ -325,6 +332,8 @@
gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingBase|0
gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareBase|0
gEfiMdeModulePkgTokenSpaceGuid.PcdPciDisableBusEnumeration|FALSE
+ gEfiMdeModulePkgTokenSpaceGuid.PcdVideoHorizontalResolution|800
+ gEfiMdeModulePkgTokenSpaceGuid.PcdVideoVerticalResolution|600
################################################################################
@@ -356,6 +365,10 @@
<LibraryClasses>
PcdLib|MdePkg/Library/PeiPcdLib/PeiPcdLib.inf
}
+ UefiCpuPkg/Universal/Acpi/S3Resume2Pei/S3Resume2Pei.inf {
+ <LibraryClasses>
+ PcdLib|MdePkg/Library/PeiPcdLib/PeiPcdLib.inf
+ }
#
# DXE Phase modules
@@ -428,7 +441,10 @@
MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleRuntimeDxe.inf
MdeModulePkg/Universal/Console/ConPlatformDxe/ConPlatformDxe.inf
MdeModulePkg/Universal/Console/ConSplitterDxe/ConSplitterDxe.inf
- MdeModulePkg/Universal/Console/GraphicsConsoleDxe/GraphicsConsoleDxe.inf
+ MdeModulePkg/Universal/Console/GraphicsConsoleDxe/GraphicsConsoleDxe.inf {
+ <LibraryClasses>
+ PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf
+ }
MdeModulePkg/Universal/Console/TerminalDxe/TerminalDxe.inf
MdeModulePkg/Universal/DevicePathDxe/DevicePathDxe.inf {
<LibraryClasses>
@@ -474,6 +490,9 @@
MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableDxe.inf
OvmfPkg/AcpiPlatformDxe/AcpiPlatformDxe.inf
OvmfPkg/AcpiTables/AcpiTables.inf
+ OvmfPkg/AcpiS3SaveDxe/AcpiS3SaveDxe.inf
+ MdeModulePkg/Universal/Acpi/S3SaveStateDxe/S3SaveStateDxe.inf
+ MdeModulePkg/Universal/Acpi/BootScriptExecutorDxe/BootScriptExecutorDxe.inf
#
# Network Support
@@ -503,7 +522,10 @@
MdeModulePkg/Bus/Usb/UsbMassStorageDxe/UsbMassStorageDxe.inf
!ifdef $(CSM_ENABLE)
- IntelFrameworkModulePkg/Csm/BiosThunk/VideoDxe/VideoDxe.inf
+ IntelFrameworkModulePkg/Csm/BiosThunk/VideoDxe/VideoDxe.inf {
+ <LibraryClasses>
+ PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf
+ }
IntelFrameworkModulePkg/Csm/LegacyBiosDxe/LegacyBiosDxe.inf
OvmfPkg/Csm/Csm16/Csm16.inf
!endif
@@ -543,3 +565,5 @@
}
OvmfPkg/SecureBootConfigDxe/SecureBootConfigDxe.inf
!endif
+
+ OvmfPkg/PlatformDxe/Platform.inf
diff --git a/OvmfPkg/OvmfPkgX64.fdf b/OvmfPkg/OvmfPkgX64.fdf
index bd1dc1bc5..c5bc6ac16 100644
--- a/OvmfPkg/OvmfPkgX64.fdf
+++ b/OvmfPkg/OvmfPkgX64.fdf
@@ -130,22 +130,28 @@ FV = SECFV
[FD.MEMFD]
BaseAddress = 0x800000
-Size = 0x800000
+Size = 0x900000
ErasePolarity = 1
BlockSize = 0x10000
-NumBlocks = 0x80
+NumBlocks = 0x90
0x000000|0x006000
gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPageTablesBase|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPageTablesSize
+0x006000|0x001000
+gUefiOvmfPkgTokenSpaceGuid.PcdOvmfLockBoxStorageBase|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfLockBoxStorageSize
+
0x010000|0x008000
gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPeiTempRamBase|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPeiTempRamSize
+0x018000|0x008000
+gUefiOvmfPkgTokenSpaceGuid.PcdS3AcpiReservedMemoryBase|gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdS3AcpiReservedMemorySize
+
0x020000|0x0E0000
gUefiOvmfPkgTokenSpaceGuid.PcdOvmfPeiMemFvBase|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfPeiMemFvSize
FV = PEIFV
-0x100000|0x700000
+0x100000|0x800000
gUefiOvmfPkgTokenSpaceGuid.PcdOvmfDxeMemFvBase|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfDxeMemFvSize
FV = DXEFV
@@ -212,6 +218,7 @@ INF MdeModulePkg/Universal/PCD/Pei/Pcd.inf
INF IntelFrameworkModulePkg/Universal/StatusCode/Pei/StatusCodePei.inf
INF OvmfPkg/PlatformPei/PlatformPei.inf
INF MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf
+INF UefiCpuPkg/Universal/Acpi/S3Resume2Pei/S3Resume2Pei.inf
################################################################################
@@ -314,6 +321,9 @@ INF OvmfPkg/SmbiosPlatformDxe/SmbiosPlatformDxe.inf
INF MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableDxe.inf
INF OvmfPkg/AcpiPlatformDxe/AcpiPlatformDxe.inf
INF RuleOverride=ACPITABLE OvmfPkg/AcpiTables/AcpiTables.inf
+INF OvmfPkg/AcpiS3SaveDxe/AcpiS3SaveDxe.inf
+INF MdeModulePkg/Universal/Acpi/S3SaveStateDxe/S3SaveStateDxe.inf
+INF MdeModulePkg/Universal/Acpi/BootScriptExecutorDxe/BootScriptExecutorDxe.inf
INF RuleOverride = BINARY FatBinPkg/EnhancedFatDxe/Fat.inf
@@ -366,6 +376,7 @@ INF RuleOverride=CSM OvmfPkg/Csm/Csm16/Csm16.inf
!endif
INF OvmfPkg/QemuVideoDxe/QemuVideoDxe.inf
+INF OvmfPkg/PlatformDxe/Platform.inf
################################################################################
diff --git a/OvmfPkg/PlatformDxe/Platform.c b/OvmfPkg/PlatformDxe/Platform.c
new file mode 100644
index 000000000..4ec327e76
--- /dev/null
+++ b/OvmfPkg/PlatformDxe/Platform.c
@@ -0,0 +1,871 @@
+/** @file
+ This driver effectuates OVMF's platform configuration settings and exposes
+ them via HII.
+
+ Copyright (C) 2014, Red Hat, Inc.
+ Copyright (c) 2009 - 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 <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/DevicePathLib.h>
+#include <Library/HiiLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/PrintLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiHiiServicesLib.h>
+#include <Protocol/DevicePath.h>
+#include <Protocol/GraphicsOutput.h>
+#include <Protocol/HiiConfigAccess.h>
+#include <Guid/MdeModuleHii.h>
+#include <Guid/OvmfPlatformConfig.h>
+
+#include "Platform.h"
+#include "PlatformConfig.h"
+
+//
+// The HiiAddPackages() library function requires that any controller (or
+// image) handle, to be associated with the HII packages under installation, be
+// "decorated" with a device path. The tradition seems to be a vendor device
+// path.
+//
+// We'd like to associate our HII packages with the driver's image handle. The
+// first idea is to use the driver image's device path. Unfortunately, loaded
+// images only come with an EFI_LOADED_IMAGE_DEVICE_PATH_PROTOCOL (not the
+// usual EFI_DEVICE_PATH_PROTOCOL), ie. a different GUID. In addition, even the
+// EFI_LOADED_IMAGE_DEVICE_PATH_PROTOCOL interface may be NULL, if the image
+// has been loaded from an "unnamed" memory source buffer.
+//
+// Hence let's just stick with the tradition -- use a dedicated vendor device
+// path, with the driver's FILE_GUID.
+//
+#pragma pack(1)
+typedef struct {
+ VENDOR_DEVICE_PATH VendorDevicePath;
+ EFI_DEVICE_PATH_PROTOCOL End;
+} PKG_DEVICE_PATH;
+#pragma pack()
+
+STATIC PKG_DEVICE_PATH mPkgDevicePath = {
+ {
+ {
+ HARDWARE_DEVICE_PATH,
+ HW_VENDOR_DP,
+ {
+ (UINT8) (sizeof (VENDOR_DEVICE_PATH) ),
+ (UINT8) (sizeof (VENDOR_DEVICE_PATH) >> 8)
+ }
+ },
+ EFI_CALLER_ID_GUID
+ },
+ {
+ END_DEVICE_PATH_TYPE,
+ END_ENTIRE_DEVICE_PATH_SUBTYPE,
+ {
+ (UINT8) (END_DEVICE_PATH_LENGTH ),
+ (UINT8) (END_DEVICE_PATH_LENGTH >> 8)
+ }
+ }
+};
+
+//
+// The configuration interface between the HII engine (form display etc) and
+// this driver.
+//
+STATIC EFI_HII_CONFIG_ACCESS_PROTOCOL mConfigAccess;
+
+//
+// The handle representing our list of packages after installation.
+//
+STATIC EFI_HII_HANDLE mInstalledPackages;
+
+//
+// The arrays below constitute our HII package list. They are auto-generated by
+// the VFR compiler and linked into the driver image during the build.
+//
+// - The strings package receives its C identifier from the driver's BASE_NAME,
+// plus "Strings".
+//
+// - The forms package receives its C identifier from the VFR file's basename,
+// plus "Bin".
+//
+//
+extern UINT8 PlatformDxeStrings[];
+extern UINT8 PlatformFormsBin[];
+
+//
+// We want to be notified about GOP installations until we find one GOP
+// interface that lets us populate the form.
+//
+STATIC EFI_EVENT mGopEvent;
+
+//
+// The registration record underneath this pointer allows us to iterate through
+// the GOP instances one by one.
+//
+STATIC VOID *mGopTracker;
+
+//
+// Cache the resolutions we get from the GOP.
+//
+typedef struct {
+ UINT32 X;
+ UINT32 Y;
+} GOP_MODE;
+
+STATIC UINTN mNumGopModes;
+STATIC GOP_MODE *mGopModes;
+
+
+/**
+ Load the persistent platform configuration and translate it to binary form
+ state.
+
+ If the platform configuration is missing, then the function fills in a
+ default state.
+
+ @param[out] MainFormState Binary form/widget state after translation.
+
+ @retval EFI_SUCCESS Form/widget state ready.
+ @return Error codes from underlying functions.
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+PlatformConfigToFormState (
+ OUT MAIN_FORM_STATE *MainFormState
+ )
+{
+ EFI_STATUS Status;
+ PLATFORM_CONFIG PlatformConfig;
+ UINT64 OptionalElements;
+ UINTN ModeNumber;
+
+ ZeroMem (MainFormState, sizeof *MainFormState);
+
+ Status = PlatformConfigLoad (&PlatformConfig, &OptionalElements);
+ switch (Status) {
+ case EFI_SUCCESS:
+ if (OptionalElements & PLATFORM_CONFIG_F_GRAPHICS_RESOLUTION) {
+ //
+ // Format the preferred resolution as text.
+ //
+ UnicodeSPrintAsciiFormat (
+ (CHAR16 *) MainFormState->CurrentPreferredResolution,
+ sizeof MainFormState->CurrentPreferredResolution,
+ "%Ldx%Ld",
+ (INT64) PlatformConfig.HorizontalResolution,
+ (INT64) PlatformConfig.VerticalResolution);
+
+ //
+ // Try to locate it in the drop-down list too. This may not succeed, but
+ // that's fine.
+ //
+ for (ModeNumber = 0; ModeNumber < mNumGopModes; ++ModeNumber) {
+ if (mGopModes[ModeNumber].X == PlatformConfig.HorizontalResolution &&
+ mGopModes[ModeNumber].Y == PlatformConfig.VerticalResolution) {
+ MainFormState->NextPreferredResolution = (UINT32) ModeNumber;
+ break;
+ }
+ }
+
+ break;
+ }
+ //
+ // fall through otherwise
+ //
+
+ case EFI_NOT_FOUND:
+ UnicodeSPrintAsciiFormat (
+ (CHAR16 *) MainFormState->CurrentPreferredResolution,
+ sizeof MainFormState->CurrentPreferredResolution,
+ "Unset");
+ break;
+
+ default:
+ return Status;
+ }
+
+ return EFI_SUCCESS;
+}
+
+
+/**
+ This function is called by the HII machinery when it fetches the form state.
+
+ See the precise documentation in the UEFI spec.
+
+ @param[in] This The Config Access Protocol instance.
+
+ @param[in] Request A <ConfigRequest> format UCS-2 string describing the
+ query.
+
+ @param[out] Progress A pointer into Request on output, identifying the query
+ element where processing failed.
+
+ @param[out] Results A <MultiConfigAltResp> format UCS-2 string that has
+ all values filled in for the names in the Request
+ string.
+
+ @retval EFI_SUCCESS Extraction of form state in <MultiConfigAltResp>
+ encoding successful.
+ @return Status codes from underlying functions.
+
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+ExtractConfig (
+ IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
+ IN CONST EFI_STRING Request,
+ OUT EFI_STRING *Progress,
+ OUT EFI_STRING *Results
+)
+{
+ MAIN_FORM_STATE MainFormState;
+ EFI_STATUS Status;
+
+ DEBUG ((EFI_D_VERBOSE, "%a: Request=\"%s\"\n", __FUNCTION__, Request));
+
+ Status = PlatformConfigToFormState (&MainFormState);
+ if (EFI_ERROR (Status)) {
+ *Progress = Request;
+ return Status;
+ }
+
+ //
+ // Answer the textual request keying off the binary form state.
+ //
+ Status = gHiiConfigRouting->BlockToConfig (gHiiConfigRouting, Request,
+ (VOID *) &MainFormState, sizeof MainFormState,
+ Results, Progress);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR, "%a: BlockToConfig(): %r, Progress=\"%s\"\n",
+ __FUNCTION__, Status, (Status == EFI_DEVICE_ERROR) ? NULL : *Progress));
+ } else {
+ DEBUG ((EFI_D_VERBOSE, "%a: Results=\"%s\"\n", __FUNCTION__, *Results));
+ }
+ return Status;
+}
+
+
+/**
+ Interpret the binary form state and save it as persistent platform
+ configuration.
+
+ @param[in] MainFormState Binary form/widget state to verify and save.
+
+ @retval EFI_SUCCESS Platform configuration saved.
+ @return Error codes from underlying functions.
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+FormStateToPlatformConfig (
+ IN CONST MAIN_FORM_STATE *MainFormState
+ )
+{
+ EFI_STATUS Status;
+ PLATFORM_CONFIG PlatformConfig;
+ CONST GOP_MODE *GopMode;
+
+ //
+ // There's nothing to do with the textual CurrentPreferredResolution field.
+ // We verify and translate the selection in the drop-down list.
+ //
+ if (MainFormState->NextPreferredResolution >= mNumGopModes) {
+ return EFI_INVALID_PARAMETER;
+ }
+ GopMode = mGopModes + MainFormState->NextPreferredResolution;
+
+ ZeroMem (&PlatformConfig, sizeof PlatformConfig);
+ PlatformConfig.HorizontalResolution = GopMode->X;
+ PlatformConfig.VerticalResolution = GopMode->Y;
+
+ Status = PlatformConfigSave (&PlatformConfig);
+ return Status;
+}
+
+
+/**
+ This function is called by the HII machinery when it wants the driver to
+ interpret and persist the form state.
+
+ See the precise documentation in the UEFI spec.
+
+ @param[in] This The Config Access Protocol instance.
+
+ @param[in] Configuration A <ConfigResp> format UCS-2 string describing the
+ form state.
+
+ @param[out] Progress A pointer into Configuration on output,
+ identifying the element where processing failed.
+
+ @retval EFI_SUCCESS Configuration verified, state permanent.
+
+ @return Status codes from underlying functions.
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+RouteConfig (
+ IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
+ IN CONST EFI_STRING Configuration,
+ OUT EFI_STRING *Progress
+)
+{
+ MAIN_FORM_STATE MainFormState;
+ UINTN BlockSize;
+ EFI_STATUS Status;
+
+ DEBUG ((EFI_D_VERBOSE, "%a: Configuration=\"%s\"\n", __FUNCTION__,
+ Configuration));
+
+ //
+ // the "read" step in RMW
+ //
+ Status = PlatformConfigToFormState (&MainFormState);
+ if (EFI_ERROR (Status)) {
+ *Progress = Configuration;
+ return Status;
+ }
+
+ //
+ // the "modify" step in RMW
+ //
+ // (Update the binary form state. This update may be partial, which is why in
+ // general we must pre-load the form state from the platform config.)
+ //
+ BlockSize = sizeof MainFormState;
+ Status = gHiiConfigRouting->ConfigToBlock (gHiiConfigRouting, Configuration,
+ (VOID *) &MainFormState, &BlockSize, Progress);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR, "%a: ConfigToBlock(): %r, Progress=\"%s\"\n",
+ __FUNCTION__, Status,
+ (Status == EFI_BUFFER_TOO_SMALL) ? NULL : *Progress));
+ return Status;
+ }
+
+ //
+ // the "write" step in RMW
+ //
+ Status = FormStateToPlatformConfig (&MainFormState);
+ if (EFI_ERROR (Status)) {
+ *Progress = Configuration;
+ }
+ return Status;
+}
+
+
+STATIC
+EFI_STATUS
+EFIAPI
+Callback (
+ IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
+ IN EFI_BROWSER_ACTION Action,
+ IN EFI_QUESTION_ID QuestionId,
+ IN UINT8 Type,
+ IN OUT EFI_IFR_TYPE_VALUE *Value,
+ OUT EFI_BROWSER_ACTION_REQUEST *ActionRequest
+ )
+{
+ DEBUG ((EFI_D_VERBOSE, "%a: Action=0x%Lx QuestionId=%d Type=%d\n",
+ __FUNCTION__, (UINT64) Action, QuestionId, Type));
+
+ if (Action != EFI_BROWSER_ACTION_CHANGED) {
+ return EFI_UNSUPPORTED;
+ }
+
+ switch (QuestionId) {
+ case QUESTION_SAVE_EXIT:
+ *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_SUBMIT_EXIT;
+ break;
+
+ case QUESTION_DISCARD_EXIT:
+ *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_DISCARD_EXIT;
+ break;
+
+ default:
+ break;
+ }
+
+ return EFI_SUCCESS;
+}
+
+
+/**
+ Query and save all resolutions supported by the GOP.
+
+ @param[in] Gop The Graphics Output Protocol instance to query.
+
+ @param[out] NumGopModes The number of modes supported by the GOP. On output,
+ this parameter will be positive.
+
+ @param[out] GopModes On output, a dynamically allocated array containing
+ the resolutions returned by the GOP. The caller is
+ responsible for freeing the array after use.
+
+ @retval EFI_UNSUPPORTED No modes found.
+ @retval EFI_OUT_OF_RESOURCES Failed to allocate GopModes.
+ @return Error codes from Gop->QueryMode().
+
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+QueryGopModes (
+ IN EFI_GRAPHICS_OUTPUT_PROTOCOL *Gop,
+ OUT UINTN *NumGopModes,
+ OUT GOP_MODE **GopModes
+ )
+{
+ EFI_STATUS Status;
+ UINT32 ModeNumber;
+
+ if (Gop->Mode->MaxMode == 0) {
+ return EFI_UNSUPPORTED;
+ }
+ *NumGopModes = Gop->Mode->MaxMode;
+
+ *GopModes = AllocatePool (Gop->Mode->MaxMode * sizeof **GopModes);
+ if (*GopModes == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ for (ModeNumber = 0; ModeNumber < Gop->Mode->MaxMode; ++ModeNumber) {
+ EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *Info;
+ UINTN SizeOfInfo;
+
+ Status = Gop->QueryMode (Gop, ModeNumber, &SizeOfInfo, &Info);
+ if (EFI_ERROR (Status)) {
+ goto FreeGopModes;
+ }
+
+ (*GopModes)[ModeNumber].X = Info->HorizontalResolution;
+ (*GopModes)[ModeNumber].Y = Info->VerticalResolution;
+ FreePool (Info);
+ }
+
+ return EFI_SUCCESS;
+
+FreeGopModes:
+ FreePool (*GopModes);
+
+ return Status;
+}
+
+
+/**
+ Create a set of "one-of-many" (ie. "drop down list") option IFR opcodes,
+ based on available GOP resolutions, to be placed under a "one-of-many" (ie.
+ "drop down list") opcode.
+
+ @param[in] PackageList The package list with the formset and form for
+ which the drop down options are produced. Option
+ names are added as new strings to PackageList.
+
+ @param[out] OpCodeBuffer On output, a dynamically allocated opcode buffer
+ with drop down list options corresponding to GOP
+ resolutions. The caller is responsible for freeing
+ OpCodeBuffer with HiiFreeOpCodeHandle() after use.
+
+ @param[in] NumGopModes Number of entries in GopModes.
+
+ @param[in] GopModes Array of resolutions retrieved from the GOP.
+
+ @retval EFI_SUCESS Opcodes have been successfully produced.
+
+ @return Status codes from underlying functions. PackageList may
+ have been extended with new strings. OpCodeBuffer is
+ unchanged.
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+CreateResolutionOptions (
+ IN EFI_HII_HANDLE *PackageList,
+ OUT VOID **OpCodeBuffer,
+ IN UINTN NumGopModes,
+ IN GOP_MODE *GopModes
+ )
+{
+ EFI_STATUS Status;
+ VOID *OutputBuffer;
+ UINTN ModeNumber;
+
+ OutputBuffer = HiiAllocateOpCodeHandle ();
+ if (OutputBuffer == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ for (ModeNumber = 0; ModeNumber < NumGopModes; ++ModeNumber) {
+ CHAR16 Desc[MAXSIZE_RES_CUR];
+ EFI_STRING_ID NewString;
+ VOID *OpCode;
+
+ UnicodeSPrintAsciiFormat (Desc, sizeof Desc, "%Ldx%Ld",
+ (INT64) GopModes[ModeNumber].X, (INT64) GopModes[ModeNumber].Y);
+ NewString = HiiSetString (PackageList, 0 /* new string */, Desc,
+ NULL /* for all languages */);
+ if (NewString == 0) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto FreeOutputBuffer;
+ }
+ OpCode = HiiCreateOneOfOptionOpCode (OutputBuffer, NewString,
+ 0 /* Flags */, EFI_IFR_NUMERIC_SIZE_4, ModeNumber);
+ if (OpCode == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto FreeOutputBuffer;
+ }
+ }
+
+ *OpCodeBuffer = OutputBuffer;
+ return EFI_SUCCESS;
+
+FreeOutputBuffer:
+ HiiFreeOpCodeHandle (OutputBuffer);
+
+ return Status;
+}
+
+
+/**
+ Populate the form identified by the (PackageList, FormSetGuid, FormId)
+ triplet.
+
+ The drop down list of video resolutions is generated from (NumGopModes,
+ GopModes).
+
+ @retval EFI_SUCESS Form successfully updated.
+ @return Status codes from underlying functions.
+
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+PopulateForm (
+ IN EFI_HII_HANDLE *PackageList,
+ IN EFI_GUID *FormSetGuid,
+ IN EFI_FORM_ID FormId,
+ IN UINTN NumGopModes,
+ IN GOP_MODE *GopModes
+ )
+{
+ EFI_STATUS Status;
+ VOID *OpCodeBuffer;
+ VOID *OpCode;
+ EFI_IFR_GUID_LABEL *Anchor;
+ VOID *OpCodeBuffer2;
+
+ OpCodeBuffer2 = NULL;
+
+ //
+ // 1. Allocate an empty opcode buffer.
+ //
+ OpCodeBuffer = HiiAllocateOpCodeHandle ();
+ if (OpCodeBuffer == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ //
+ // 2. Create a label opcode (which is a Tiano extension) inside the buffer.
+ // The label's number must match the "anchor" label in the form.
+ //
+ OpCode = HiiCreateGuidOpCode (OpCodeBuffer, &gEfiIfrTianoGuid,
+ NULL /* optional copy origin */, sizeof *Anchor);
+ if (OpCode == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto FreeOpCodeBuffer;
+ }
+ Anchor = OpCode;
+ Anchor->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
+ Anchor->Number = LABEL_RES_NEXT;
+
+ //
+ // 3. Create the opcodes inside the buffer that are to be inserted into the
+ // form.
+ //
+ // 3.1. Get a list of resolutions.
+ //
+ Status = CreateResolutionOptions (PackageList, &OpCodeBuffer2,
+ NumGopModes, GopModes);
+ if (EFI_ERROR (Status)) {
+ goto FreeOpCodeBuffer;
+ }
+
+ //
+ // 3.2. Create a one-of-many question with the above options.
+ //
+ OpCode = HiiCreateOneOfOpCode (
+ OpCodeBuffer, // create opcode inside this
+ // opcode buffer,
+ QUESTION_RES_NEXT, // ID of question,
+ FORMSTATEID_MAIN_FORM, // identifies form state
+ // storage,
+ (UINT16) OFFSET_OF (MAIN_FORM_STATE, // value of question stored
+ NextPreferredResolution), // at this offset,
+ STRING_TOKEN (STR_RES_NEXT), // Prompt,
+ STRING_TOKEN (STR_RES_NEXT_HELP), // Help,
+ 0, // QuestionFlags,
+ EFI_IFR_NUMERIC_SIZE_4, // see sizeof
+ // NextPreferredResolution,
+ OpCodeBuffer2, // buffer with possible
+ // choices,
+ NULL // DEFAULT opcodes
+ );
+ if (OpCode == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto FreeOpCodeBuffer2;
+ }
+
+ //
+ // 4. Update the form with the opcode buffer.
+ //
+ Status = HiiUpdateForm (PackageList, FormSetGuid, FormId,
+ OpCodeBuffer, // buffer with head anchor, and new contents to be
+ // inserted at it
+ NULL // buffer with tail anchor, for deleting old
+ // contents up to it
+ );
+
+FreeOpCodeBuffer2:
+ HiiFreeOpCodeHandle (OpCodeBuffer2);
+
+FreeOpCodeBuffer:
+ HiiFreeOpCodeHandle (OpCodeBuffer);
+
+ return Status;
+}
+
+
+/**
+ Load and execute the platform configuration.
+
+ @retval EFI_SUCCESS Configuration loaded and executed.
+ @return Status codes from PlatformConfigLoad().
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+ExecutePlatformConfig (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+ PLATFORM_CONFIG PlatformConfig;
+ UINT64 OptionalElements;
+
+ Status = PlatformConfigLoad (&PlatformConfig, &OptionalElements);
+ if (EFI_ERROR (Status)) {
+ DEBUG (((Status == EFI_NOT_FOUND) ? EFI_D_VERBOSE : EFI_D_ERROR,
+ "%a: failed to load platform config: %r\n", __FUNCTION__, Status));
+ return Status;
+ }
+
+ if (OptionalElements & PLATFORM_CONFIG_F_GRAPHICS_RESOLUTION) {
+ //
+ // Pass the preferred resolution to GraphicsConsoleDxe via dynamic PCDs.
+ //
+ PcdSet32 (PcdVideoHorizontalResolution,
+ PlatformConfig.HorizontalResolution);
+ PcdSet32 (PcdVideoVerticalResolution,
+ PlatformConfig.VerticalResolution);
+ }
+
+ return EFI_SUCCESS;
+}
+
+
+/**
+ Notification callback for GOP interface installation.
+
+ @param[in] Event Event whose notification function is being invoked.
+
+ @param[in] Context The pointer to the notification function's context, which
+ is implementation-dependent.
+**/
+STATIC
+VOID
+EFIAPI
+GopInstalled (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+{
+ EFI_STATUS Status;
+ EFI_GRAPHICS_OUTPUT_PROTOCOL *Gop;
+
+ ASSERT (Event == mGopEvent);
+
+ //
+ // Check further GOPs.
+ //
+ for (;;) {
+ mNumGopModes = 0;
+ mGopModes = NULL;
+
+ Status = gBS->LocateProtocol (&gEfiGraphicsOutputProtocolGuid, mGopTracker,
+ (VOID **) &Gop);
+ if (EFI_ERROR (Status)) {
+ return;
+ }
+
+ Status = QueryGopModes (Gop, &mNumGopModes, &mGopModes);
+ if (EFI_ERROR (Status)) {
+ continue;
+ }
+
+ Status = PopulateForm (mInstalledPackages, &gOvmfPlatformConfigGuid,
+ FORMID_MAIN_FORM, mNumGopModes, mGopModes);
+ if (EFI_ERROR (Status)) {
+ FreePool (mGopModes);
+ continue;
+ }
+
+ break;
+ }
+
+ //
+ // Success -- so uninstall this callback. Closing the event removes all
+ // pending notifications and all protocol registrations.
+ //
+ Status = gBS->CloseEvent (mGopEvent);
+ ASSERT_EFI_ERROR (Status);
+ mGopEvent = NULL;
+ mGopTracker = NULL;
+}
+
+
+/**
+ Entry point for this driver.
+
+ @param[in] ImageHandle Image handle of this driver.
+ @param[in] SystemTable Pointer to SystemTable.
+
+ @retval EFI_SUCESS Driver has loaded successfully.
+ @retval EFI_OUT_OF_RESOURCES Failed to install HII packages.
+ @return Error codes from lower level functions.
+
+**/
+EFI_STATUS
+EFIAPI
+PlatformInit (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+
+ ExecutePlatformConfig ();
+
+ mConfigAccess.ExtractConfig = &ExtractConfig;
+ mConfigAccess.RouteConfig = &RouteConfig;
+ mConfigAccess.Callback = &Callback;
+
+ //
+ // Declare ourselves suitable for HII communication.
+ //
+ Status = gBS->InstallMultipleProtocolInterfaces (&ImageHandle,
+ &gEfiDevicePathProtocolGuid, &mPkgDevicePath,
+ &gEfiHiiConfigAccessProtocolGuid, &mConfigAccess,
+ NULL);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Publish the HII package list to HII Database.
+ //
+ mInstalledPackages = HiiAddPackages (
+ &gEfiCallerIdGuid, // PackageListGuid
+ ImageHandle, // associated DeviceHandle
+ PlatformDxeStrings, // 1st package
+ PlatformFormsBin, // 2nd package
+ NULL // terminator
+ );
+ if (mInstalledPackages == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto UninstallProtocols;
+ }
+
+ Status = gBS->CreateEvent (EVT_NOTIFY_SIGNAL, TPL_CALLBACK, &GopInstalled,
+ NULL /* Context */, &mGopEvent);
+ if (EFI_ERROR (Status)) {
+ goto RemovePackages;
+ }
+
+ Status = gBS->RegisterProtocolNotify (&gEfiGraphicsOutputProtocolGuid,
+ mGopEvent, &mGopTracker);
+ if (EFI_ERROR (Status)) {
+ goto CloseGopEvent;
+ }
+
+ //
+ // Check already installed GOPs.
+ //
+ Status = gBS->SignalEvent (mGopEvent);
+ ASSERT_EFI_ERROR (Status);
+
+ return EFI_SUCCESS;
+
+CloseGopEvent:
+ gBS->CloseEvent (mGopEvent);
+
+RemovePackages:
+ HiiRemovePackages (mInstalledPackages);
+
+UninstallProtocols:
+ gBS->UninstallMultipleProtocolInterfaces (ImageHandle,
+ &gEfiDevicePathProtocolGuid, &mPkgDevicePath,
+ &gEfiHiiConfigAccessProtocolGuid, &mConfigAccess,
+ NULL);
+ return Status;
+}
+
+/**
+ Unload the driver.
+
+ @param[in] ImageHandle Handle that identifies the image to evict.
+
+ @retval EFI_SUCCESS The image has been unloaded.
+**/
+EFI_STATUS
+EFIAPI
+PlatformUnload (
+ IN EFI_HANDLE ImageHandle
+ )
+{
+ if (mGopEvent == NULL) {
+ //
+ // The GOP callback ran successfully and unregistered itself. Release the
+ // resources allocated there.
+ //
+ ASSERT (mGopModes != NULL);
+ FreePool (mGopModes);
+ } else {
+ //
+ // Otherwise we need to unregister the callback.
+ //
+ ASSERT (mGopModes == NULL);
+ gBS->CloseEvent (mGopEvent);
+ }
+
+ //
+ // Release resources allocated by the entry point.
+ //
+ HiiRemovePackages (mInstalledPackages);
+ gBS->UninstallMultipleProtocolInterfaces (ImageHandle,
+ &gEfiDevicePathProtocolGuid, &mPkgDevicePath,
+ &gEfiHiiConfigAccessProtocolGuid, &mConfigAccess,
+ NULL);
+ return EFI_SUCCESS;
+}
diff --git a/OvmfPkg/PlatformDxe/Platform.h b/OvmfPkg/PlatformDxe/Platform.h
new file mode 100644
index 000000000..432eb5bc2
--- /dev/null
+++ b/OvmfPkg/PlatformDxe/Platform.h
@@ -0,0 +1,43 @@
+/** @file
+ This driver effectuates OVMF's platform configuration settings and exposes
+ them via HII.
+
+ 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.
+**/
+
+#ifndef _PLATFORM_H_
+#define _PLATFORM_H_
+
+//
+// Macro and type definitions that connect the form with the HII driver code.
+//
+#define FORMSTATEID_MAIN_FORM 1
+#define FORMID_MAIN_FORM 1
+
+#define QUESTION_RES_CUR 1
+#define MAXSIZE_RES_CUR 16
+
+#define LABEL_RES_NEXT 1
+#define QUESTION_RES_NEXT 2
+
+#define QUESTION_SAVE_EXIT 3
+#define QUESTION_DISCARD_EXIT 4
+
+//
+// This structure describes the form state. Its fields relate strictly to the
+// visual widgets on the form.
+//
+typedef struct {
+ UINT16 CurrentPreferredResolution[MAXSIZE_RES_CUR];
+ UINT32 NextPreferredResolution;
+} MAIN_FORM_STATE;
+
+#endif // _PLATFORM_H_
diff --git a/OvmfPkg/PlatformDxe/Platform.inf b/OvmfPkg/PlatformDxe/Platform.inf
new file mode 100644
index 000000000..16cd9ab75
--- /dev/null
+++ b/OvmfPkg/PlatformDxe/Platform.inf
@@ -0,0 +1,69 @@
+## @file
+# This driver effectuates OVMF's platform configuration settings and exposes
+# them via HII.
+#
+# Copyright (C) 2014, Red Hat, Inc.
+# Copyright (c) 2009 - 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 = PlatformDxe
+ FILE_GUID = D9DCC5DF-4007-435E-9098-8970935504B2
+ MODULE_TYPE = DXE_DRIVER
+ VERSION_STRING = 1.0
+ ENTRY_POINT = PlatformInit
+ UNLOAD_IMAGE = PlatformUnload
+
+[Sources]
+ Platform.c
+ Platform.uni
+ PlatformConfig.c
+ PlatformForms.vfr
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ OvmfPkg/OvmfPkg.dec
+
+[LibraryClasses]
+ BaseLib
+ BaseMemoryLib
+ DebugLib
+ DevicePathLib
+ HiiLib
+ MemoryAllocationLib
+ PrintLib
+ UefiBootServicesTableLib
+ UefiHiiServicesLib
+ UefiLib
+ UefiRuntimeServicesTableLib
+ UefiDriverEntryPoint
+
+[Pcd]
+ gEfiMdeModulePkgTokenSpaceGuid.PcdVideoHorizontalResolution
+ gEfiMdeModulePkgTokenSpaceGuid.PcdVideoVerticalResolution
+
+[Protocols]
+ gEfiDevicePathProtocolGuid ## PRODUCES
+ gEfiGraphicsOutputProtocolGuid ## CONSUMES
+ gEfiHiiConfigAccessProtocolGuid ## PRODUCES
+
+[Guids]
+ gEfiIfrTianoGuid
+ gOvmfPlatformConfigGuid
+
+[Depex]
+ gEfiHiiConfigRoutingProtocolGuid AND
+ gEfiHiiDatabaseProtocolGuid AND
+ gEfiVariableArchProtocolGuid AND
+ gEfiVariableWriteArchProtocolGuid
diff --git a/OvmfPkg/PlatformDxe/Platform.uni b/OvmfPkg/PlatformDxe/Platform.uni
new file mode 100644
index 000000000..d8d5b0bb4
--- /dev/null
+++ b/OvmfPkg/PlatformDxe/Platform.uni
Binary files differ
diff --git a/OvmfPkg/PlatformDxe/PlatformConfig.c b/OvmfPkg/PlatformDxe/PlatformConfig.c
new file mode 100644
index 000000000..3468f8815
--- /dev/null
+++ b/OvmfPkg/PlatformDxe/PlatformConfig.c
@@ -0,0 +1,131 @@
+/** @file
+
+ Utility functions for serializing (persistently storing) and deserializing
+ OVMF's platform configuration.
+
+ 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 <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/UefiLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+#include <Guid/OvmfPlatformConfig.h>
+
+#include "PlatformConfig.h"
+
+//
+// Name of the UEFI variable that we use for persistent storage.
+//
+STATIC CHAR16 mVariableName[] = L"PlatformConfig";
+
+
+/**
+ Serialize and persistently save platform configuration.
+
+ @param[in] PlatformConfig The platform configuration to serialize and save.
+
+ @return Status codes returned by gRT->SetVariable().
+**/
+EFI_STATUS
+EFIAPI
+PlatformConfigSave (
+ IN PLATFORM_CONFIG *PlatformConfig
+ )
+{
+ EFI_STATUS Status;
+
+ //
+ // We could implement any kind of translation here, as part of serialization.
+ // For example, we could expose the platform configuration in separate
+ // variables with human-readable contents, allowing other tools to access
+ // them more easily. For now, just save a binary dump.
+ //
+ Status = gRT->SetVariable (mVariableName, &gOvmfPlatformConfigGuid,
+ EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS |
+ EFI_VARIABLE_RUNTIME_ACCESS,
+ sizeof *PlatformConfig, PlatformConfig);
+ return Status;
+}
+
+
+/**
+ Load and deserialize platform configuration.
+
+ When the function fails, output parameters are indeterminate.
+
+ @param[out] PlatformConfig The platform configuration to receive the
+ loaded data.
+
+ @param[out] OptionalElements This bitmap describes the presence of optional
+ configuration elements that have been loaded.
+ PLATFORM_CONFIG_F_DOWNGRADE means that some
+ unknown elements, present in the wire format,
+ have been ignored.
+
+ @retval EFI_SUCCESS Loading & deserialization successful.
+ @return Error codes returned by GetVariable2().
+**/
+EFI_STATUS
+EFIAPI
+PlatformConfigLoad (
+ OUT PLATFORM_CONFIG *PlatformConfig,
+ OUT UINT64 *OptionalElements
+ )
+{
+ VOID *Data;
+ UINTN DataSize;
+ EFI_STATUS Status;
+
+ //
+ // Any translation done in PlatformConfigSave() would have to be mirrored
+ // here. For now, just load the binary dump.
+ //
+ // Versioning of the binary wire format is implemented based on size
+ // (only incremental changes, ie. new fields), and on GUID.
+ // (Incompatible changes require a GUID change.)
+ //
+ Status = GetVariable2 (mVariableName, &gOvmfPlatformConfigGuid, &Data,
+ &DataSize);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ *OptionalElements = 0;
+ if (DataSize > sizeof *PlatformConfig) {
+ //
+ // Handle firmware downgrade -- keep only leading part.
+ //
+ CopyMem (PlatformConfig, Data, sizeof *PlatformConfig);
+ *OptionalElements |= PLATFORM_CONFIG_F_DOWNGRADE;
+ } else {
+ CopyMem (PlatformConfig, Data, DataSize);
+
+ //
+ // Handle firmware upgrade -- zero out missing fields.
+ //
+ ZeroMem ((UINT8 *)PlatformConfig + DataSize,
+ sizeof *PlatformConfig - DataSize);
+ }
+
+ //
+ // Based on DataSize, report the optional features that we recognize.
+ //
+ if (DataSize >= (OFFSET_OF (PLATFORM_CONFIG, VerticalResolution) +
+ sizeof PlatformConfig->VerticalResolution)) {
+ *OptionalElements |= PLATFORM_CONFIG_F_GRAPHICS_RESOLUTION;
+ }
+
+ FreePool (Data);
+ return EFI_SUCCESS;
+}
diff --git a/OvmfPkg/PlatformDxe/PlatformConfig.h b/OvmfPkg/PlatformDxe/PlatformConfig.h
new file mode 100644
index 000000000..3fd698256
--- /dev/null
+++ b/OvmfPkg/PlatformDxe/PlatformConfig.h
@@ -0,0 +1,59 @@
+/** @file
+
+ Utility functions for serializing (persistently storing) and deserializing
+ OVMF's platform configuration.
+
+ 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.
+
+**/
+
+#ifndef _PLATFORM_CONFIG_H_
+#define _PLATFORM_CONFIG_H_
+
+#include <Base.h>
+
+//
+// This structure participates in driver configuration. It does not
+// (necessarily) reflect the wire format in the persistent store.
+//
+#pragma pack(1)
+typedef struct {
+ //
+ // preferred graphics console resolution when booting
+ //
+ UINT32 HorizontalResolution;
+ UINT32 VerticalResolution;
+} PLATFORM_CONFIG;
+#pragma pack()
+
+//
+// Please see the API documentation near the function definitions.
+//
+EFI_STATUS
+EFIAPI
+PlatformConfigSave (
+ IN PLATFORM_CONFIG *PlatformConfig
+ );
+
+EFI_STATUS
+EFIAPI
+PlatformConfigLoad (
+ OUT PLATFORM_CONFIG *PlatformConfig,
+ OUT UINT64 *OptionalElements
+ );
+
+//
+// Feature flags for OptionalElements.
+//
+#define PLATFORM_CONFIG_F_GRAPHICS_RESOLUTION BIT0
+#define PLATFORM_CONFIG_F_DOWNGRADE BIT63
+
+#endif // _PLATFORM_CONFIG_H_
diff --git a/OvmfPkg/PlatformDxe/PlatformForms.vfr b/OvmfPkg/PlatformDxe/PlatformForms.vfr
new file mode 100644
index 000000000..a254572ba
--- /dev/null
+++ b/OvmfPkg/PlatformDxe/PlatformForms.vfr
@@ -0,0 +1,74 @@
+// *++
+//
+// Copyright (C) 2014, Red Hat, Inc.
+// Copyright (c) 2009 - 2011, Intel Corporation. All rights reserved.<BR>
+//
+// This program and the accompanying materials are licensed and made available
+// under the terms and conditions of the BSD License which accompanies this
+// distribution. The full text of the license may be found at
+// http://opensource.org/licenses/bsd-license.php
+//
+// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR
+// IMPLIED.
+//
+// Module Name:
+//
+// PlatformForms.vfr
+//
+// Abstract:
+//
+// Form definitions for exposing some of OVMF's platform knobs via HII.
+//
+// --*/
+
+#include <Guid/OvmfPlatformConfig.h>
+#include "Platform.h"
+
+formset
+ guid = OVMF_PLATFORM_CONFIG_GUID,
+ title = STRING_TOKEN(STR_FORMSET_TITLE),
+ help = STRING_TOKEN(STR_FORMSET_HELP),
+
+ varstore MAIN_FORM_STATE,
+ varid = FORMSTATEID_MAIN_FORM,
+ name = MainFormState,
+ guid = OVMF_PLATFORM_CONFIG_GUID;
+
+ form
+ formid = FORMID_MAIN_FORM,
+ title = STRING_TOKEN(STR_MAIN_FORM_TITLE);
+
+ //
+ // Display the current preference in a read-only string field.
+ //
+ string
+ varid = MainFormState.CurrentPreferredResolution,
+ questionid = QUESTION_RES_CUR,
+ prompt = STRING_TOKEN(STR_RES_CUR),
+ help = STRING_TOKEN(STR_RES_CUR_HELP),
+ flags = READ_ONLY,
+ minsize = 0,
+ maxsize = MAXSIZE_RES_CUR,
+ endstring;
+
+ //
+ // We'll dynamically generate a one-of-many selection at this label.
+ //
+ label LABEL_RES_NEXT;
+
+ text
+ help = STRING_TOKEN(STR_SAVE_EXIT),
+ text = STRING_TOKEN(STR_SAVE_EXIT),
+ flags = INTERACTIVE,
+ key = QUESTION_SAVE_EXIT;
+
+ text
+ help = STRING_TOKEN(STR_DISCARD_EXIT),
+ text = STRING_TOKEN(STR_DISCARD_EXIT),
+ flags = INTERACTIVE,
+ key = QUESTION_DISCARD_EXIT;
+
+ endform;
+
+endformset;
diff --git a/OvmfPkg/PlatformPei/Fv.c b/OvmfPkg/PlatformPei/Fv.c
index 1ee417a09..3ed775c85 100644
--- a/OvmfPkg/PlatformPei/Fv.c
+++ b/OvmfPkg/PlatformPei/Fv.c
@@ -13,6 +13,7 @@
**/
#include "PiPei.h"
+#include "Platform.h"
#include <Library/DebugLib.h>
#include <Library/HobLib.h>
#include <Library/PeiServicesLib.h>
@@ -36,12 +37,12 @@ PeiFvInitialization (
//
// Create a memory allocation HOB for the PEI FV.
//
- // Note: This should be changed to ACPI NVS when S3 resume is enabled.
+ // Allocate as ACPI NVS is S3 is supported
//
BuildMemoryAllocationHob (
PcdGet32 (PcdOvmfPeiMemFvBase),
PcdGet32 (PcdOvmfPeiMemFvSize),
- EfiBootServicesData
+ mS3Supported ? EfiACPIMemoryNVS : EfiBootServicesData
);
//
diff --git a/OvmfPkg/PlatformPei/MemDetect.c b/OvmfPkg/PlatformPei/MemDetect.c
index 29df5370b..15b279e44 100644
--- a/OvmfPkg/PlatformPei/MemDetect.c
+++ b/OvmfPkg/PlatformPei/MemDetect.c
@@ -24,6 +24,7 @@ Module Name:
//
// The Library classes this module consumes
//
+#include <Library/BaseMemoryLib.h>
#include <Library/DebugLib.h>
#include <Library/HobLib.h>
#include <Library/IoLib.h>
@@ -99,16 +100,21 @@ PublishPeiMemory (
UINT64 MemorySize;
UINT64 LowerMemorySize;
- LowerMemorySize = GetSystemMemorySizeBelow4gb ();
-
- //
- // Determine the range of memory to use during PEI
- //
- MemoryBase = PcdGet32 (PcdOvmfDxeMemFvBase) + PcdGet32 (PcdOvmfDxeMemFvSize);
- MemorySize = LowerMemorySize - MemoryBase;
- if (MemorySize > SIZE_64MB) {
- MemoryBase = LowerMemorySize - SIZE_64MB;
- MemorySize = SIZE_64MB;
+ if (mBootMode == BOOT_ON_S3_RESUME) {
+ MemoryBase = PcdGet32 (PcdS3AcpiReservedMemoryBase);
+ MemorySize = PcdGet32 (PcdS3AcpiReservedMemorySize);
+ } else {
+ LowerMemorySize = GetSystemMemorySizeBelow4gb ();
+
+ //
+ // Determine the range of memory to use during PEI
+ //
+ MemoryBase = PcdGet32 (PcdOvmfDxeMemFvBase) + PcdGet32 (PcdOvmfDxeMemFvSize);
+ MemorySize = LowerMemorySize - MemoryBase;
+ if (MemorySize > SIZE_64MB) {
+ MemoryBase = LowerMemorySize - SIZE_64MB;
+ MemorySize = SIZE_64MB;
+ }
}
//
@@ -142,18 +148,22 @@ QemuInitializeRam (
LowerMemorySize = GetSystemMemorySizeBelow4gb ();
UpperMemorySize = GetSystemMemorySizeAbove4gb ();
- //
- // Create memory HOBs
- //
- AddMemoryRangeHob (BASE_1MB, LowerMemorySize);
- AddMemoryRangeHob (0, BASE_512KB + BASE_128KB);
+ if (mBootMode != BOOT_ON_S3_RESUME) {
+ //
+ // Create memory HOBs
+ //
+ AddMemoryRangeHob (BASE_1MB, LowerMemorySize);
+ AddMemoryRangeHob (0, BASE_512KB + BASE_128KB);
+ }
MtrrSetMemoryAttribute (BASE_1MB, LowerMemorySize - BASE_1MB, CacheWriteBack);
MtrrSetMemoryAttribute (0, BASE_512KB + BASE_128KB, CacheWriteBack);
if (UpperMemorySize != 0) {
- AddUntestedMemoryBaseSizeHob (BASE_4GB, UpperMemorySize);
+ if (mBootMode != BOOT_ON_S3_RESUME) {
+ AddUntestedMemoryBaseSizeHob (BASE_4GB, UpperMemorySize);
+ }
MtrrSetMemoryAttribute (BASE_4GB, UpperMemorySize, CacheWriteBack);
}
@@ -173,4 +183,62 @@ InitializeRamRegions (
} else {
XenPublishRamRegions ();
}
+
+ if (mS3Supported && mBootMode != BOOT_ON_S3_RESUME) {
+ //
+ // This is the memory range that will be used for PEI on S3 resume
+ //
+ BuildMemoryAllocationHob (
+ (EFI_PHYSICAL_ADDRESS)(UINTN) PcdGet32 (PcdS3AcpiReservedMemoryBase),
+ (UINT64)(UINTN) PcdGet32 (PcdS3AcpiReservedMemorySize),
+ EfiACPIMemoryNVS
+ );
+
+ //
+ // Cover the initial RAM area used as stack and temporary PEI heap.
+ //
+ // This is reserved as ACPI NVS so it can be used on S3 resume.
+ //
+ BuildMemoryAllocationHob (
+ PcdGet32 (PcdOvmfSecPeiTempRamBase),
+ PcdGet32 (PcdOvmfSecPeiTempRamSize),
+ EfiACPIMemoryNVS
+ );
+
+#ifdef MDE_CPU_X64
+ //
+ // Reserve the initial page tables built by the reset vector code.
+ //
+ // Since this memory range will be used by the Reset Vector on S3
+ // resume, it must be reserved as ACPI NVS.
+ //
+ BuildMemoryAllocationHob (
+ (EFI_PHYSICAL_ADDRESS)(UINTN) PcdGet32 (PcdOvmfSecPageTablesBase),
+ (UINT64)(UINTN) PcdGet32 (PcdOvmfSecPageTablesSize),
+ EfiACPIMemoryNVS
+ );
+#endif
+ }
+
+ if (mBootMode != BOOT_ON_S3_RESUME) {
+ //
+ // Reserve the lock box storage area
+ //
+ // Since this memory range will be used on S3 resume, it must be
+ // reserved as ACPI NVS.
+ //
+ // If S3 is unsupported, then various drivers might still write to the
+ // LockBox area. We ought to prevent DXE from serving allocation requests
+ // such that they would overlap the LockBox storage.
+ //
+ ZeroMem (
+ (VOID*)(UINTN) PcdGet32 (PcdOvmfLockBoxStorageBase),
+ (UINTN) PcdGet32 (PcdOvmfLockBoxStorageSize)
+ );
+ BuildMemoryAllocationHob (
+ (EFI_PHYSICAL_ADDRESS)(UINTN) PcdGet32 (PcdOvmfLockBoxStorageBase),
+ (UINT64)(UINTN) PcdGet32 (PcdOvmfLockBoxStorageSize),
+ mS3Supported ? EfiACPIMemoryNVS : EfiBootServicesData
+ );
+ }
}
diff --git a/OvmfPkg/PlatformPei/Platform.c b/OvmfPkg/PlatformPei/Platform.c
index a7221b317..11b4cb7a1 100644
--- a/OvmfPkg/PlatformPei/Platform.c
+++ b/OvmfPkg/PlatformPei/Platform.c
@@ -30,6 +30,7 @@
#include <Library/PciLib.h>
#include <Library/PeimEntryPoint.h>
#include <Library/PeiServicesLib.h>
+#include <Library/QemuFwCfgLib.h>
#include <Library/ResourcePublicationLib.h>
#include <Guid/MemoryTypeInformation.h>
#include <Ppi/MasterBootMode.h>
@@ -59,6 +60,11 @@ EFI_PEI_PPI_DESCRIPTOR mPpiBootMode[] = {
};
+EFI_BOOT_MODE mBootMode = BOOT_WITH_FULL_CONFIGURATION;
+
+BOOLEAN mS3Supported = FALSE;
+
+
VOID
AddIoMemoryBaseSizeHob (
EFI_PHYSICAL_ADDRESS MemoryBase,
@@ -266,11 +272,16 @@ MiscInitialization (
VOID
BootModeInitialization (
+ VOID
)
{
- EFI_STATUS Status;
+ EFI_STATUS Status;
- Status = PeiServicesSetBootMode (BOOT_WITH_FULL_CONFIGURATION);
+ if (CmosRead8 (0xF) == 0xFE) {
+ mBootMode = BOOT_ON_S3_RESUME;
+ }
+
+ Status = PeiServicesSetBootMode (mBootMode);
ASSERT_EFI_ERROR (Status);
Status = PeiServicesInstallPpi (mPpiBootMode);
@@ -348,6 +359,11 @@ InitializePlatform (
XenDetect ();
+ if (QemuFwCfgS3Enabled ()) {
+ DEBUG ((EFI_D_INFO, "S3 support was detected on QEMU\n"));
+ mS3Supported = TRUE;
+ }
+
BootModeInitialization ();
PublishPeiMemory ();
@@ -359,11 +375,13 @@ InitializePlatform (
InitializeXen ();
}
- ReserveEmuVariableNvStore ();
+ if (mBootMode != BOOT_ON_S3_RESUME) {
+ ReserveEmuVariableNvStore ();
- PeiFvInitialization ();
+ PeiFvInitialization ();
- MemMapInitialization ();
+ MemMapInitialization ();
+ }
MiscInitialization ();
diff --git a/OvmfPkg/PlatformPei/Platform.h b/OvmfPkg/PlatformPei/Platform.h
index 5cce7961b..31640e9b3 100644
--- a/OvmfPkg/PlatformPei/Platform.h
+++ b/OvmfPkg/PlatformPei/Platform.h
@@ -96,4 +96,8 @@ XenPublishRamRegions (
VOID
);
+extern EFI_BOOT_MODE mBootMode;
+
+extern BOOLEAN mS3Supported;
+
#endif // _PLATFORM_PEI_H_INCLUDED_
diff --git a/OvmfPkg/PlatformPei/PlatformPei.inf b/OvmfPkg/PlatformPei/PlatformPei.inf
index 7c646ab8a..3b47bb70d 100644
--- a/OvmfPkg/PlatformPei/PlatformPei.inf
+++ b/OvmfPkg/PlatformPei/PlatformPei.inf
@@ -2,7 +2,7 @@
# Platform PEI driver
#
# This module provides platform specific function to detect boot mode.
-# 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
@@ -36,6 +36,7 @@
Xen.c
[Packages]
+ IntelFrameworkModulePkg/IntelFrameworkModulePkg.dec
MdePkg/MdePkg.dec
MdeModulePkg/MdeModulePkg.dec
UefiCpuPkg/UefiCpuPkg.dec
@@ -54,6 +55,7 @@
PeiServicesLib
PeiServicesTablePointerLib
PeimEntryPoint
+ QemuFwCfgLib
MtrrLib
PcdLib
@@ -63,6 +65,14 @@
gUefiOvmfPkgTokenSpaceGuid.PcdOvmfDxeMemFvBase
gUefiOvmfPkgTokenSpaceGuid.PcdOvmfDxeMemFvSize
gUefiOvmfPkgTokenSpaceGuid.PcdAcpiPmBaseAddress
+ gUefiOvmfPkgTokenSpaceGuid.PcdS3AcpiReservedMemoryBase
+ gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPeiTempRamBase
+ gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPeiTempRamSize
+ gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPageTablesBase
+ gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPageTablesSize
+ gUefiOvmfPkgTokenSpaceGuid.PcdOvmfLockBoxStorageBase
+ gUefiOvmfPkgTokenSpaceGuid.PcdOvmfLockBoxStorageSize
+ gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdS3AcpiReservedMemorySize
gEfiMdeModulePkgTokenSpaceGuid.PcdVariableStoreSize
gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize
gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize
diff --git a/OvmfPkg/QemuVideoDxe/Driver.c b/OvmfPkg/QemuVideoDxe/Driver.c
index e71af6e85..c44b8b260 100644
--- a/OvmfPkg/QemuVideoDxe/Driver.c
+++ b/OvmfPkg/QemuVideoDxe/Driver.c
@@ -170,6 +170,7 @@ QemuVideoControllerDriverStart (
IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
)
{
+ EFI_TPL OldTpl;
EFI_STATUS Status;
QEMU_VIDEO_PRIVATE_DATA *Private;
EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath;
@@ -178,12 +179,15 @@ QemuVideoControllerDriverStart (
QEMU_VIDEO_CARD *Card;
EFI_PCI_IO_PROTOCOL *ChildPciIo;
+ OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
+
//
// Allocate Private context data for GOP inteface.
//
Private = AllocateZeroPool (sizeof (QEMU_VIDEO_PRIVATE_DATA));
if (Private == NULL) {
- return EFI_OUT_OF_RESOURCES;
+ Status = EFI_OUT_OF_RESOURCES;
+ goto RestoreTpl;
}
//
@@ -394,6 +398,7 @@ QemuVideoControllerDriverStart (
goto UninstallGop;
}
+ gBS->RestoreTPL (OldTpl);
return EFI_SUCCESS;
UninstallGop:
@@ -424,6 +429,9 @@ ClosePciIo:
FreePrivate:
FreePool (Private);
+RestoreTpl:
+ gBS->RestoreTPL (OldTpl);
+
return Status;
}
diff --git a/OvmfPkg/Sec/SecMain.c b/OvmfPkg/Sec/SecMain.c
index 0edc4f9af..670ad8d76 100644
--- a/OvmfPkg/Sec/SecMain.c
+++ b/OvmfPkg/Sec/SecMain.c
@@ -469,6 +469,50 @@ FindPeiCoreImageBaseInFv (
return EFI_SUCCESS;
}
+
+/**
+ Reads 8-bits of CMOS data.
+
+ Reads the 8-bits of CMOS data at the location specified by Index.
+ The 8-bit read value is returned.
+
+ @param Index The CMOS location to read.
+
+ @return The value read.
+
+**/
+STATIC
+UINT8
+CmosRead8 (
+ IN UINTN Index
+ )
+{
+ IoWrite8 (0x70, (UINT8) Index);
+ return IoRead8 (0x71);
+}
+
+
+STATIC
+BOOLEAN
+IsS3Resume (
+ VOID
+ )
+{
+ return (CmosRead8 (0xF) == 0xFE);
+}
+
+
+STATIC
+EFI_STATUS
+GetS3ResumePeiFv (
+ IN OUT EFI_FIRMWARE_VOLUME_HEADER **PeiFv
+ )
+{
+ *PeiFv = (EFI_FIRMWARE_VOLUME_HEADER*)(UINTN) PcdGet32 (PcdOvmfPeiMemFvBase);
+ return EFI_SUCCESS;
+}
+
+
/**
Locates the PEI Core entry point address
@@ -488,9 +532,15 @@ FindPeiCoreImageBase (
{
*PeiCoreImageBase = 0;
- FindMainFv (BootFv);
+ if (IsS3Resume ()) {
+ DEBUG ((EFI_D_VERBOSE, "SEC: S3 resume\n"));
+ GetS3ResumePeiFv (BootFv);
+ } else {
+ DEBUG ((EFI_D_VERBOSE, "SEC: Normal boot\n"));
+ FindMainFv (BootFv);
- DecompressMemFvs (BootFv);
+ DecompressMemFvs (BootFv);
+ }
FindPeiCoreImageBaseInFv (*BootFv, PeiCoreImageBase);
}
diff --git a/PcAtChipsetPkg/PcatRealTimeClockRuntimeDxe/PcRtc.c b/PcAtChipsetPkg/PcatRealTimeClockRuntimeDxe/PcRtc.c
index ab4ea8206..a77009a21 100644
--- a/PcAtChipsetPkg/PcatRealTimeClockRuntimeDxe/PcRtc.c
+++ b/PcAtChipsetPkg/PcatRealTimeClockRuntimeDxe/PcRtc.c
@@ -1,7 +1,7 @@
/** @file
RTC Architectural Protocol GUID as defined in DxeCis 0.96.
-Copyright (c) 2006 - 2011, 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
@@ -392,6 +392,26 @@ PcRtcSetTime (
}
return Status;
}
+
+ //
+ // Write timezone and daylight to RTC variable
+ //
+ TimerVar = Time->Daylight;
+ TimerVar = (UINT32) ((TimerVar << 16) | (UINT16)(Time->TimeZone));
+ Status = EfiSetVariable (
+ L"RTC",
+ &gEfiCallerIdGuid,
+ EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
+ sizeof (TimerVar),
+ &TimerVar
+ );
+ if (EFI_ERROR (Status)) {
+ if (!EfiAtRuntime ()) {
+ EfiReleaseLock (&Global->RtcLock);
+ }
+ return EFI_DEVICE_ERROR;
+ }
+
//
// Read Register B, and inhibit updates of the RTC
//
@@ -427,17 +447,6 @@ PcRtcSetTime (
Global->SavedTimeZone = Time->TimeZone;
Global->Daylight = Time->Daylight;
- TimerVar = Time->Daylight;
- TimerVar = (UINT32) ((TimerVar << 16) | (UINT16)(Time->TimeZone));
- Status = EfiSetVariable (
- L"RTC",
- &gEfiCallerIdGuid,
- EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
- sizeof (TimerVar),
- &TimerVar
- );
- ASSERT_EFI_ERROR (Status);
-
return EFI_SUCCESS;
}
@@ -635,27 +644,13 @@ PcRtcSetWakeupTime (
return EFI_DEVICE_ERROR;
}
//
- // Read Register B, and inhibit updates of the RTC
+ // Read Register B
//
- RegisterB.Data = RtcRead (RTC_ADDRESS_REGISTER_B);
-
- RegisterB.Bits.Set = 1;
- RtcWrite (RTC_ADDRESS_REGISTER_B, RegisterB.Data);
+ RegisterB.Data = RtcRead (RTC_ADDRESS_REGISTER_B);
if (Enable) {
ConvertEfiTimeToRtcTime (&RtcTime, RegisterB, &Century);
-
- //
- // Set RTC alarm time
- //
- RtcWrite (RTC_ADDRESS_SECONDS_ALARM, RtcTime.Second);
- RtcWrite (RTC_ADDRESS_MINUTES_ALARM, RtcTime.Minute);
- RtcWrite (RTC_ADDRESS_HOURS_ALARM, RtcTime.Hour);
-
- RegisterB.Bits.Aie = 1;
-
} else {
- RegisterB.Bits.Aie = 0;
//
// if the alarm is disable, record the current setting.
//
@@ -668,11 +663,6 @@ PcRtcSetWakeupTime (
RtcTime.TimeZone = Global->SavedTimeZone;
RtcTime.Daylight = Global->Daylight;
}
- //
- // Allow updates of the RTC registers
- //
- RegisterB.Bits.Set = 0;
- RtcWrite (RTC_ADDRESS_REGISTER_B, RegisterB.Data);
//
// Set the Y/M/D info to variable as it has no corresponding hw registers.
@@ -685,8 +675,36 @@ PcRtcSetWakeupTime (
&RtcTime
);
if (EFI_ERROR (Status)) {
+ if (!EfiAtRuntime ()) {
+ EfiReleaseLock (&Global->RtcLock);
+ }
return EFI_DEVICE_ERROR;
}
+
+ //
+ // Inhibit updates of the RTC
+ //
+ RegisterB.Bits.Set = 1;
+ RtcWrite (RTC_ADDRESS_REGISTER_B, RegisterB.Data);
+
+ if (Enable) {
+ //
+ // Set RTC alarm time
+ //
+ RtcWrite (RTC_ADDRESS_SECONDS_ALARM, RtcTime.Second);
+ RtcWrite (RTC_ADDRESS_MINUTES_ALARM, RtcTime.Minute);
+ RtcWrite (RTC_ADDRESS_HOURS_ALARM, RtcTime.Hour);
+
+ RegisterB.Bits.Aie = 1;
+
+ } else {
+ RegisterB.Bits.Aie = 0;
+ }
+ //
+ // Allow updates of the RTC registers
+ //
+ RegisterB.Bits.Set = 0;
+ RtcWrite (RTC_ADDRESS_REGISTER_B, RegisterB.Data);
//
// Release RTC Lock.
diff --git a/PerformancePkg/Dp_App/DpInternal.h b/PerformancePkg/Dp_App/DpInternal.h
index eb4f27489..fff299535 100644
--- a/PerformancePkg/Dp_App/DpInternal.h
+++ b/PerformancePkg/Dp_App/DpInternal.h
@@ -6,7 +6,7 @@
Dp application. In addition to global data, function declarations for
DpUtilities.c, DpTrace.c, and DpProfile.c are included here.
- Copyright (c) 2009 - 2012, Intel Corporation. All rights reserved.<BR>
+ Copyright (c) 2009 - 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
@@ -151,6 +151,7 @@ DurationInMicroSeconds (
**/
UINTN
+EFIAPI
PrintToken (
IN UINT16 Token,
...
diff --git a/PerformancePkg/Dp_App/DpUtilities.c b/PerformancePkg/Dp_App/DpUtilities.c
index 65efb80c8..73666aadd 100644
--- a/PerformancePkg/Dp_App/DpUtilities.c
+++ b/PerformancePkg/Dp_App/DpUtilities.c
@@ -1,7 +1,7 @@
/** @file
Utility functions used by the Dp application.
- Copyright (c) 2009 - 2013, Intel Corporation. All rights reserved.<BR>
+ Copyright (c) 2009 - 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
@@ -402,6 +402,7 @@ DurationInMicroSeconds (
**/
UINTN
+EFIAPI
PrintToken (
IN UINT16 Token,
...
diff --git a/SecurityPkg/Library/DxeTcgPhysicalPresenceLib/DxeTcgPhysicalPresenceLib.c b/SecurityPkg/Library/DxeTcgPhysicalPresenceLib/DxeTcgPhysicalPresenceLib.c
index ebc7367fa..8a5e7d17c 100644
--- a/SecurityPkg/Library/DxeTcgPhysicalPresenceLib/DxeTcgPhysicalPresenceLib.c
+++ b/SecurityPkg/Library/DxeTcgPhysicalPresenceLib/DxeTcgPhysicalPresenceLib.c
@@ -8,7 +8,7 @@
ExecutePendingTpmRequest() will receive untrusted input and do validation.
-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
@@ -1059,6 +1059,9 @@ ExecutePendingTpmRequest (
sizeof (UINT8),
&NewFlags
);
+ if (EFI_ERROR (Status)) {
+ return;
+ }
}
@@ -1162,19 +1165,20 @@ TcgPhysicalPresenceLibProcessRequest (
&PpiFlags
);
if (EFI_ERROR (Status)) {
- if (Status == EFI_NOT_FOUND) {
- PpiFlags = FLAG_NO_PPI_PROVISION;
- Status = gRT->SetVariable (
- PHYSICAL_PRESENCE_FLAGS_VARIABLE,
- &gEfiPhysicalPresenceGuid,
- EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
- sizeof (UINT8),
- &PpiFlags
- );
+ PpiFlags = FLAG_NO_PPI_PROVISION;
+ Status = gRT->SetVariable (
+ PHYSICAL_PRESENCE_FLAGS_VARIABLE,
+ &gEfiPhysicalPresenceGuid,
+ EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
+ sizeof (UINT8),
+ &PpiFlags
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR, "[TPM] Set physical presence flag failed, Status = %r\n", Status));
+ return ;
}
- ASSERT_EFI_ERROR (Status);
}
- DEBUG ((EFI_D_ERROR, "[TPM] PpiFlags = %x, Status = %r\n", PpiFlags, Status));
+ DEBUG ((EFI_D_INFO, "[TPM] PpiFlags = %x\n", PpiFlags));
//
// This flags variable controls whether physical presence is required for TPM command.
@@ -1205,18 +1209,19 @@ TcgPhysicalPresenceLibProcessRequest (
&TcgPpData
);
if (EFI_ERROR (Status)) {
- if (Status == EFI_NOT_FOUND) {
- ZeroMem ((VOID*)&TcgPpData, sizeof (TcgPpData));
- DataSize = sizeof (EFI_PHYSICAL_PRESENCE);
- Status = gRT->SetVariable (
- PHYSICAL_PRESENCE_VARIABLE,
- &gEfiPhysicalPresenceGuid,
- EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
- DataSize,
- &TcgPpData
- );
+ ZeroMem ((VOID*)&TcgPpData, sizeof (TcgPpData));
+ DataSize = sizeof (EFI_PHYSICAL_PRESENCE);
+ Status = gRT->SetVariable (
+ PHYSICAL_PRESENCE_VARIABLE,
+ &gEfiPhysicalPresenceGuid,
+ EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
+ DataSize,
+ &TcgPpData
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR, "[TPM] Set physical presence variable failed, Status = %r\n", Status));
+ return;
}
- ASSERT_EFI_ERROR (Status);
}
DEBUG ((EFI_D_INFO, "[TPM] Flags=%x, PPRequest=%x\n", PpiFlags, TcgPpData.PPRequest));
diff --git a/SecurityPkg/Library/DxeTpm2MeasureBootLib/DxeTpm2MeasureBootLib.c b/SecurityPkg/Library/DxeTpm2MeasureBootLib/DxeTpm2MeasureBootLib.c
index 3c81b5af5..8482031e4 100644
--- a/SecurityPkg/Library/DxeTpm2MeasureBootLib/DxeTpm2MeasureBootLib.c
+++ b/SecurityPkg/Library/DxeTpm2MeasureBootLib/DxeTpm2MeasureBootLib.c
@@ -15,7 +15,7 @@
TrEEMeasureGptTable() function will receive untrusted GPT partition table, and parse
partition data carefully.
-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
@@ -351,7 +351,9 @@ TrEEMeasurePeImage (
ImageLoad->ImageLengthInMemory = ImageSize;
ImageLoad->ImageLinkTimeAddress = LinkTimeBase;
ImageLoad->LengthOfDevicePath = FilePathSize;
- CopyMem (ImageLoad->DevicePath, FilePath, FilePathSize);
+ if ((FilePath != NULL) && (FilePathSize != 0)) {
+ CopyMem (ImageLoad->DevicePath, FilePath, FilePathSize);
+ }
//
// Log the PE data
diff --git a/SecurityPkg/Library/DxeTpmMeasureBootLib/DxeTpmMeasureBootLib.c b/SecurityPkg/Library/DxeTpmMeasureBootLib/DxeTpmMeasureBootLib.c
index d11ec1337..5bfa282bc 100644
--- a/SecurityPkg/Library/DxeTpmMeasureBootLib/DxeTpmMeasureBootLib.c
+++ b/SecurityPkg/Library/DxeTpmMeasureBootLib/DxeTpmMeasureBootLib.c
@@ -15,7 +15,7 @@
TcgMeasureGptTable() function will receive untrusted GPT partition table, and parse
partition data carefully.
-Copyright (c) 2009 - 2013, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2009 - 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
@@ -371,7 +371,9 @@ TcgMeasurePeImage (
ImageLoad->ImageLengthInMemory = ImageSize;
ImageLoad->ImageLinkTimeAddress = LinkTimeBase;
ImageLoad->LengthOfDevicePath = FilePathSize;
- CopyMem (ImageLoad->DevicePath, FilePath, FilePathSize);
+ if ((FilePath != NULL) && (FilePathSize != 0)) {
+ CopyMem (ImageLoad->DevicePath, FilePath, FilePathSize);
+ }
//
// Check PE/COFF image
diff --git a/SecurityPkg/Library/DxeTrEEPhysicalPresenceLib/DxeTrEEPhysicalPresenceLib.c b/SecurityPkg/Library/DxeTrEEPhysicalPresenceLib/DxeTrEEPhysicalPresenceLib.c
index 28b809bce..b2b22e518 100644
--- a/SecurityPkg/Library/DxeTrEEPhysicalPresenceLib/DxeTrEEPhysicalPresenceLib.c
+++ b/SecurityPkg/Library/DxeTrEEPhysicalPresenceLib/DxeTrEEPhysicalPresenceLib.c
@@ -7,7 +7,7 @@
TrEEExecutePendingTpmRequest() will receive untrusted input and do validation.
-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
@@ -568,19 +568,20 @@ TrEEPhysicalPresenceLibProcessRequest (
&PpiFlags
);
if (EFI_ERROR (Status)) {
- if (Status == EFI_NOT_FOUND) {
- PpiFlags = 0;
- Status = gRT->SetVariable (
- TREE_PHYSICAL_PRESENCE_FLAGS_VARIABLE,
- &gEfiTrEEPhysicalPresenceGuid,
- EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
- sizeof (UINT8),
- &PpiFlags
- );
+ PpiFlags = 0;
+ Status = gRT->SetVariable (
+ TREE_PHYSICAL_PRESENCE_FLAGS_VARIABLE,
+ &gEfiTrEEPhysicalPresenceGuid,
+ EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
+ sizeof (UINT8),
+ &PpiFlags
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR, "[TPM2] Set physical presence flag failed, Status = %r\n", Status));
+ return ;
}
- ASSERT_EFI_ERROR (Status);
}
- DEBUG ((EFI_D_ERROR, "[TPM2] PpiFlags = %x, Status = %r\n", PpiFlags, Status));
+ DEBUG ((EFI_D_INFO, "[TPM2] PpiFlags = %x\n", PpiFlags));
//
// This flags variable controls whether physical presence is required for TPM command.
@@ -611,27 +612,28 @@ TrEEPhysicalPresenceLibProcessRequest (
&TcgPpData
);
if (EFI_ERROR (Status)) {
- if (Status == EFI_NOT_FOUND) {
- ZeroMem ((VOID*)&TcgPpData, sizeof (TcgPpData));
- DataSize = sizeof (EFI_TREE_PHYSICAL_PRESENCE);
- Status = gRT->SetVariable (
- TREE_PHYSICAL_PRESENCE_VARIABLE,
- &gEfiTrEEPhysicalPresenceGuid,
- EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
- DataSize,
- &TcgPpData
- );
+ ZeroMem ((VOID*)&TcgPpData, sizeof (TcgPpData));
+ DataSize = sizeof (EFI_TREE_PHYSICAL_PRESENCE);
+ Status = gRT->SetVariable (
+ TREE_PHYSICAL_PRESENCE_VARIABLE,
+ &gEfiTrEEPhysicalPresenceGuid,
+ EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
+ DataSize,
+ &TcgPpData
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR, "[TPM2] Set physical presence variable failed, Status = %r\n", Status));
+ return ;
}
- ASSERT_EFI_ERROR (Status);
}
- DEBUG ((EFI_D_ERROR, "[TPM2] Flags=%x, PPRequest=%x (LastPPRequest=%x)\n", PpiFlags, TcgPpData.PPRequest, TcgPpData.LastPPRequest));
+ DEBUG ((EFI_D_INFO, "[TPM2] Flags=%x, PPRequest=%x (LastPPRequest=%x)\n", PpiFlags, TcgPpData.PPRequest, TcgPpData.LastPPRequest));
//
// Execute pending TPM request.
//
TrEEExecutePendingTpmRequest (PlatformAuth, &TcgPpData, PpiFlags);
- DEBUG ((EFI_D_ERROR, "[TPM2] PPResponse = %x (LastPPRequest=%x, Flags=%x)\n", TcgPpData.PPResponse, TcgPpData.LastPPRequest, PpiFlags));
+ DEBUG ((EFI_D_INFO, "[TPM2] PPResponse = %x (LastPPRequest=%x, Flags=%x)\n", TcgPpData.PPResponse, TcgPpData.LastPPRequest, PpiFlags));
}
diff --git a/SecurityPkg/SecurityPkg.dec b/SecurityPkg/SecurityPkg.dec
index f2b3ac66e..bc058731f 100644
--- a/SecurityPkg/SecurityPkg.dec
+++ b/SecurityPkg/SecurityPkg.dec
@@ -229,14 +229,6 @@
# If 1, TCG platform type is server.
gEfiSecurityPkgTokenSpaceGuid.PcdTpmPlatformClass|0|UINT8|0x00000006
- ## The PCD is used to control whether to support hiding the TPM.
- # If TRUE, PcdHideTpm controls whether to hide the TPM.
- gEfiSecurityPkgTokenSpaceGuid.PcdHideTpmSupport|FALSE|BOOLEAN|0x00000007
-
-[PcdsDynamic, PcdsDynamicEx]
- ## The PCD is used to control whether to hide the TPM.
- gEfiSecurityPkgTokenSpaceGuid.PcdHideTpm|FALSE|BOOLEAN|0x00010002
-
[PcdsFixedAtBuild, PcdsPatchableInModule, PcdsDynamic, PcdsDynamicEx]
## This PCD indicates the presence or absence of the platform operator.
gEfiSecurityPkgTokenSpaceGuid.PcdTpmPhysicalPresence|TRUE|BOOLEAN|0x00010001
diff --git a/SecurityPkg/SecurityPkg.dsc b/SecurityPkg/SecurityPkg.dsc
index 591062c04..0a01050a8 100644
--- a/SecurityPkg/SecurityPkg.dsc
+++ b/SecurityPkg/SecurityPkg.dsc
@@ -120,10 +120,10 @@
[Components]
SecurityPkg/VariableAuthenticated/Pei/VariablePei.inf
SecurityPkg/Library/DxeImageVerificationLib/DxeImageVerificationLib.inf
- SecurityPkg/Library/DxeDeferImageLoadLib/DxeDeferImageLoadLib.inf
+ #SecurityPkg/Library/DxeDeferImageLoadLib/DxeDeferImageLoadLib.inf
SecurityPkg/Library/DxeImageAuthenticationStatusLib/DxeImageAuthenticationStatusLib.inf
- SecurityPkg/UserIdentification/UserIdentifyManagerDxe/UserIdentifyManagerDxe.inf
- SecurityPkg/UserIdentification/UserProfileManagerDxe/UserProfileManagerDxe.inf
+ #SecurityPkg/UserIdentification/UserIdentifyManagerDxe/UserIdentifyManagerDxe.inf
+ #SecurityPkg/UserIdentification/UserProfileManagerDxe/UserProfileManagerDxe.inf
#
# Application
@@ -163,8 +163,8 @@
SecurityPkg/Library/HashLibTpm2/HashLibTpm2.inf
[Components.IA32, Components.X64, Components.IPF]
- SecurityPkg/UserIdentification/PwdCredentialProviderDxe/PwdCredentialProviderDxe.inf
- SecurityPkg/UserIdentification/UsbCredentialProviderDxe/UsbCredentialProviderDxe.inf
+# SecurityPkg/UserIdentification/PwdCredentialProviderDxe/PwdCredentialProviderDxe.inf
+# SecurityPkg/UserIdentification/UsbCredentialProviderDxe/UsbCredentialProviderDxe.inf
SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigDxe.inf
SecurityPkg/VariableAuthenticated/RuntimeDxe/VariableRuntimeDxe.inf
diff --git a/SecurityPkg/Tcg/MemoryOverwriteControl/TcgMor.c b/SecurityPkg/Tcg/MemoryOverwriteControl/TcgMor.c
index def965f13..a4acc14e9 100644
--- a/SecurityPkg/Tcg/MemoryOverwriteControl/TcgMor.c
+++ b/SecurityPkg/Tcg/MemoryOverwriteControl/TcgMor.c
@@ -4,7 +4,7 @@
This driver initilize MemoryOverwriteRequestControl variable. It
will clear MOR_CLEAR_MEMORY_BIT bit if it is set.
-Copyright (c) 2009 - 2012, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2009 - 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
@@ -35,6 +35,7 @@ OnReadyToBoot (
IN VOID *Context
)
{
+ EFI_STATUS Status;
UINTN DataSize;
if (MOR_CLEAR_MEMORY_VALUE (mMorControl) == 0x0) {
@@ -50,14 +51,16 @@ OnReadyToBoot (
mMorControl &= 0xFE;
DataSize = sizeof (mMorControl);
- gRT->SetVariable (
- MEMORY_OVERWRITE_REQUEST_VARIABLE_NAME,
- &gEfiMemoryOverwriteControlDataGuid,
- EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
- DataSize,
- &mMorControl
- );
-
+ Status = gRT->SetVariable (
+ MEMORY_OVERWRITE_REQUEST_VARIABLE_NAME,
+ &gEfiMemoryOverwriteControlDataGuid,
+ EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
+ DataSize,
+ &mMorControl
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR, "TcgMor: Clear MOR_CLEAR_MEMORY_BIT failure, Status = %r\n"));
+ }
}
@@ -98,7 +101,6 @@ MorDriverEntryPoint (
// Set default value to 0
//
mMorControl = 0;
- DEBUG ((EFI_D_INFO, "TcgMor: Create gEfiMemoryOverwriteControlDataGuid!\n"));
Status = gRT->SetVariable (
MEMORY_OVERWRITE_REQUEST_VARIABLE_NAME,
&gEfiMemoryOverwriteControlDataGuid,
@@ -106,8 +108,7 @@ MorDriverEntryPoint (
DataSize,
&mMorControl
);
- ASSERT_EFI_ERROR (Status);
-
+ DEBUG ((EFI_D_INFO, "TcgMor: Create MOR variable! Status = %r\n", Status));
} else {
//
// Create a Ready To Boot Event and Clear the MorControl bit in the call back function.
diff --git a/SecurityPkg/Tcg/TcgConfigDxe/TcgConfig.vfr b/SecurityPkg/Tcg/TcgConfigDxe/TcgConfig.vfr
index fc601471d..9e4e63d76 100644
--- a/SecurityPkg/Tcg/TcgConfigDxe/TcgConfig.vfr
+++ b/SecurityPkg/Tcg/TcgConfigDxe/TcgConfig.vfr
@@ -1,7 +1,7 @@
/** @file
VFR file used by the TCG configuration component.
-Copyright (c) 2011 - 2012, Intel Corporation. All rights reserved.<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
which accompanies this distribution. The full text of the license may be found at
@@ -44,13 +44,6 @@ formset
endcheckbox;
endif;
- suppressif TRUE;
- checkbox varid = TCG_CONFIGURATION.OriginalHideTpm,
- prompt = STRING_TOKEN(STR_NULL),
- help = STRING_TOKEN(STR_NULL),
- endcheckbox;
- endif;
-
text
help = STRING_TOKEN(STR_TPM_STATE_HELP),
text = STRING_TOKEN(STR_TPM_STATE_PROMPT),
@@ -58,18 +51,6 @@ formset
subtitle text = STRING_TOKEN(STR_NULL);
- label LABEL_TCG_CONFIGURATION_HIDETPM;
-
- checkbox varid = TCG_CONFIGURATION.HideTpm,
- questionid = KEY_HIDE_TPM,
- prompt = STRING_TOKEN(STR_HIDE_TPM_PROMPT),
- help = STRING_TOKEN(STR_HIDE_TPM_HELP),
- flags = RESET_REQUIRED,
- endcheckbox;
-
- label LABEL_END;
-
- grayoutif ideqval TCG_CONFIGURATION.OriginalHideTpm == 1;
oneof varid = TCG_CONFIGURATION.TpmOperation,
questionid = KEY_TPM_ACTION,
prompt = STRING_TOKEN(STR_TPM_OPERATION),
@@ -102,8 +83,6 @@ formset
subtitle text = STRING_TOKEN(STR_NULL);
- endif;
-
endform;
endformset;
diff --git a/SecurityPkg/Tcg/TcgConfigDxe/TcgConfigDriver.c b/SecurityPkg/Tcg/TcgConfigDxe/TcgConfigDriver.c
index a9a10c9e1..787251828 100644
--- a/SecurityPkg/Tcg/TcgConfigDxe/TcgConfigDriver.c
+++ b/SecurityPkg/Tcg/TcgConfigDxe/TcgConfigDriver.c
@@ -1,7 +1,7 @@
/** @file
The module entry point for Tcg configuration module.
-Copyright (c) 2011 - 2013, Intel Corporation. All rights reserved.<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
which accompanies this distribution. The full text of the license may be found at
@@ -75,7 +75,6 @@ TcgConfigDriverEntryPoint (
}
PrivateData->TcgProtocol = TcgProtocol;
- PrivateData->HideTpm = (BOOLEAN) (PcdGetBool (PcdHideTpmSupport) && PcdGetBool (PcdHideTpm));
//
// Install TCG configuration form
diff --git a/SecurityPkg/Tcg/TcgConfigDxe/TcgConfigDxe.inf b/SecurityPkg/Tcg/TcgConfigDxe/TcgConfigDxe.inf
index cdfc89c2e..ba6201741 100644
--- a/SecurityPkg/Tcg/TcgConfigDxe/TcgConfigDxe.inf
+++ b/SecurityPkg/Tcg/TcgConfigDxe/TcgConfigDxe.inf
@@ -1,7 +1,7 @@
## @file
# Component name for Tcg configuration module.
#
-# Copyright (c) 2011 - 2013, Intel Corporation. All rights reserved.<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
# which accompanies this distribution. The full text of the license may be found at
@@ -63,11 +63,7 @@
gEfiHiiConfigRoutingProtocolGuid ## CONSUMES
gEfiTcgProtocolGuid ## CONSUMES
-[FixedPcd]
- gEfiSecurityPkgTokenSpaceGuid.PcdHideTpmSupport
-
[Pcd]
- gEfiSecurityPkgTokenSpaceGuid.PcdHideTpm
gEfiSecurityPkgTokenSpaceGuid.PcdTpmInstanceGuid
[Depex]
diff --git a/SecurityPkg/Tcg/TcgConfigDxe/TcgConfigImpl.c b/SecurityPkg/Tcg/TcgConfigDxe/TcgConfigImpl.c
index 5a52a6b87..c2e3b34a2 100644
--- a/SecurityPkg/Tcg/TcgConfigDxe/TcgConfigImpl.c
+++ b/SecurityPkg/Tcg/TcgConfigDxe/TcgConfigImpl.c
@@ -1,7 +1,7 @@
/** @file
HII Config Access protocol implementation of TCG configuration module.
-Copyright (c) 2011 - 2012, Intel Corporation. All rights reserved.<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
which accompanies this distribution. The full text of the license may be found at
@@ -182,11 +182,6 @@ TcgExtractConfig (
ZeroMem (&Configuration, sizeof (TCG_CONFIGURATION));
Configuration.TpmOperation = PHYSICAL_PRESENCE_ENABLE;
- Configuration.HideTpm = (BOOLEAN) (PcdGetBool (PcdHideTpmSupport) && PcdGetBool (PcdHideTpm));
- //
- // Read the original value of HideTpm from PrivateData which won't be changed by Setup in this boot.
- //
- Configuration.OriginalHideTpm = PrivateData->HideTpm;
//
// Display current TPM state.
@@ -307,8 +302,6 @@ TcgRouteConfig (
return Status;
}
- PcdSetBool (PcdHideTpm, TcgConfiguration.HideTpm);
-
return EFI_SUCCESS;
}
@@ -425,11 +418,6 @@ InstallTcgConfigForm (
EFI_STATUS Status;
EFI_HII_HANDLE HiiHandle;
EFI_HANDLE DriverHandle;
- VOID *StartOpCodeHandle;
- VOID *EndOpCodeHandle;
- EFI_IFR_GUID_LABEL *StartLabel;
- EFI_IFR_GUID_LABEL *EndLabel;
-
EFI_HII_CONFIG_ACCESS_PROTOCOL *ConfigAccess;
DriverHandle = NULL;
@@ -473,39 +461,6 @@ InstallTcgConfigForm (
PrivateData->HiiHandle = HiiHandle;
- //
- // Remove the Hide TPM question from the IFR
- //
- if (!PcdGetBool (PcdHideTpmSupport)) {
- //
- // Allocate space for creation of UpdateData Buffer
- //
- StartOpCodeHandle = HiiAllocateOpCodeHandle ();
- ASSERT (StartOpCodeHandle != NULL);
-
- EndOpCodeHandle = HiiAllocateOpCodeHandle ();
- ASSERT (EndOpCodeHandle != NULL);
-
- //
- // Create Hii Extend Label OpCode as the start opcode
- //
- StartLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (StartOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL));
- StartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
- StartLabel->Number = LABEL_TCG_CONFIGURATION_HIDETPM;
-
- //
- // Create Hii Extend Label OpCode as the end opcode
- //
- EndLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (EndOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL));
- EndLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
- EndLabel->Number = LABEL_END;
-
- HiiUpdateForm (HiiHandle, NULL, TCG_CONFIGURATION_FORM_ID, StartOpCodeHandle, EndOpCodeHandle);
-
- HiiFreeOpCodeHandle (StartOpCodeHandle);
- HiiFreeOpCodeHandle (EndOpCodeHandle);
- }
-
return EFI_SUCCESS;
}
diff --git a/SecurityPkg/Tcg/TcgConfigDxe/TcgConfigImpl.h b/SecurityPkg/Tcg/TcgConfigDxe/TcgConfigImpl.h
index cbfca7439..ecc6a6d85 100644
--- a/SecurityPkg/Tcg/TcgConfigDxe/TcgConfigImpl.h
+++ b/SecurityPkg/Tcg/TcgConfigDxe/TcgConfigImpl.h
@@ -2,7 +2,7 @@
The header file of HII Config Access protocol implementation of TCG
configuration module.
-Copyright (c) 2011, Intel Corporation. All rights reserved.<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
which accompanies this distribution. The full text of the license may be found at
@@ -62,8 +62,6 @@ typedef struct {
EFI_HANDLE DriverHandle;
EFI_TCG_PROTOCOL *TcgProtocol;
-
- BOOLEAN HideTpm;
} TCG_CONFIG_PRIVATE_DATA;
extern TCG_CONFIG_PRIVATE_DATA mTcgConfigPrivateDateTemplate;
diff --git a/SecurityPkg/Tcg/TcgConfigDxe/TcgConfigNvData.h b/SecurityPkg/Tcg/TcgConfigDxe/TcgConfigNvData.h
index 359f4a2bf..eaa6fe801 100644
--- a/SecurityPkg/Tcg/TcgConfigDxe/TcgConfigNvData.h
+++ b/SecurityPkg/Tcg/TcgConfigDxe/TcgConfigNvData.h
@@ -1,7 +1,7 @@
/** @file
Header file for NV data structure definition.
-Copyright (c) 2011, Intel Corporation. All rights reserved.<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
which accompanies this distribution. The full text of the license may be found at
@@ -22,19 +22,15 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#define TCG_CONFIGURATION_VARSTORE_ID 0x0001
#define TCG_CONFIGURATION_FORM_ID 0x0001
-#define KEY_HIDE_TPM 0x2000
-#define KEY_TPM_ACTION 0x3000
-#define KEY_TPM_MOR_ENABLE 0x4000
+#define KEY_TPM_ACTION 0x3000
-#define LABEL_TCG_CONFIGURATION_HIDETPM 0x0001
-#define LABEL_END 0xffff
+#define LABEL_TCG_CONFIGURATION_TPM_OPERATION 0x0001
+#define LABEL_END 0xffff
//
// Nv Data structure referenced by IFR
//
typedef struct {
- BOOLEAN HideTpm;
- BOOLEAN OriginalHideTpm;
UINT8 TpmOperation;
BOOLEAN TpmEnable;
BOOLEAN TpmActivate;
diff --git a/SecurityPkg/Tcg/TcgPei/TcgPei.c b/SecurityPkg/Tcg/TcgPei/TcgPei.c
index ae905f765..f3f4b3f4c 100644
--- a/SecurityPkg/Tcg/TcgPei/TcgPei.c
+++ b/SecurityPkg/Tcg/TcgPei/TcgPei.c
@@ -1,7 +1,7 @@
/** @file
Initialize TPM device and measure FVs before handing off control to DXE.
-Copyright (c) 2005 - 2013, Intel Corporation. All rights reserved.<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
which accompanies this distribution. The full text of the license may be found at
@@ -711,10 +711,6 @@ PeimEntryMA (
return EFI_UNSUPPORTED;
}
- if (PcdGetBool (PcdHideTpmSupport) && PcdGetBool (PcdHideTpm)) {
- return EFI_UNSUPPORTED;
- }
-
//
// Initialize TPM device
//
diff --git a/SecurityPkg/Tcg/TcgPei/TcgPei.inf b/SecurityPkg/Tcg/TcgPei/TcgPei.inf
index 48a3e6436..cf90eaec8 100644
--- a/SecurityPkg/Tcg/TcgPei/TcgPei.inf
+++ b/SecurityPkg/Tcg/TcgPei/TcgPei.inf
@@ -1,7 +1,7 @@
## @file
# This module will initialize TPM device and measure FVs in PEI phase.
#
-# 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
@@ -63,7 +63,6 @@
gEfiEndOfPeiSignalPpiGuid
[Pcd]
- gEfiSecurityPkgTokenSpaceGuid.PcdHideTpm
gEfiSecurityPkgTokenSpaceGuid.PcdPhysicalPresenceLifetimeLock
gEfiSecurityPkgTokenSpaceGuid.PcdPhysicalPresenceCmdEnable
gEfiSecurityPkgTokenSpaceGuid.PcdPhysicalPresenceHwEnable
@@ -73,7 +72,6 @@
gEfiSecurityPkgTokenSpaceGuid.PcdTpmScrtmPolicy
[FixedPcd]
- gEfiSecurityPkgTokenSpaceGuid.PcdHideTpmSupport
gEfiMdeModulePkgTokenSpaceGuid.PcdPeiCoreMaxFvSupported ## CONSUMES
[Depex]
diff --git a/SecurityPkg/Tcg/TcgSmm/TcgSmm.c b/SecurityPkg/Tcg/TcgSmm/TcgSmm.c
index 045c1846f..6080eff3b 100644
--- a/SecurityPkg/Tcg/TcgSmm/TcgSmm.c
+++ b/SecurityPkg/Tcg/TcgSmm/TcgSmm.c
@@ -8,7 +8,7 @@
PhysicalPresenceCallback() and MemoryClearCallback() will receive untrusted input and do some check.
-Copyright (c) 2011 - 2013, Intel Corporation. All rights reserved.<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
which accompanies this distribution. The full text of the license may be found at
@@ -68,6 +68,8 @@ PhysicalPresenceCallback (
&PpData
);
if (EFI_ERROR (Status)) {
+ mTcgNvs->PhysicalPresence.ReturnCode = PP_SUBMIT_REQUEST_GENERAL_FAILURE;
+ DEBUG ((EFI_D_ERROR, "[TPM] Get PP variable failure! Status = %r\n", Status));
return EFI_SUCCESS;
}
@@ -116,6 +118,7 @@ PhysicalPresenceCallback (
);
if (EFI_ERROR (Status)) {
mTcgNvs->PhysicalPresence.ReturnCode = PP_SUBMIT_REQUEST_GENERAL_FAILURE;
+ DEBUG ((EFI_D_ERROR, "[TPM] Get PP flags failure! Status = %r\n", Status));
return EFI_SUCCESS;
}
@@ -226,6 +229,8 @@ MemoryClearCallback (
&MorControl
);
if (EFI_ERROR (Status)) {
+ mTcgNvs->MemoryClear.ReturnCode = MOR_REQUEST_GENERAL_FAILURE;
+ DEBUG ((EFI_D_ERROR, "[TPM] Get MOR variable failure! Status = %r\n", Status));
return EFI_SUCCESS;
}
@@ -245,6 +250,7 @@ MemoryClearCallback (
);
if (EFI_ERROR (Status)) {
mTcgNvs->MemoryClear.ReturnCode = MOR_REQUEST_GENERAL_FAILURE;
+ DEBUG ((EFI_D_ERROR, "[TPM] Set MOR variable failure! Status = %r\n", Status));
}
return EFI_SUCCESS;
diff --git a/SecurityPkg/Tcg/TrEEConfig/TpmDetection.c b/SecurityPkg/Tcg/TrEEConfig/TpmDetection.c
index b8aab1ffd..516f7c92a 100644
--- a/SecurityPkg/Tcg/TrEEConfig/TpmDetection.c
+++ b/SecurityPkg/Tcg/TrEEConfig/TpmDetection.c
@@ -1,7 +1,7 @@
/** @file
TPM1.2/dTPM2.0 auto detection.
-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
@@ -14,6 +14,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#include <PiPei.h>
+#include <Ppi/ReadOnlyVariable2.h>
#include <Library/BaseLib.h>
#include <Library/BaseMemoryLib.h>
@@ -64,25 +65,42 @@ DetectTpmDevice (
{
EFI_STATUS Status;
EFI_BOOT_MODE BootMode;
+ TREE_DEVICE_DETECTION TrEEDeviceDetection;
+ EFI_PEI_READ_ONLY_VARIABLE2_PPI *VariablePpi;
+ UINTN Size;
Status = PeiServicesGetBootMode (&BootMode);
ASSERT_EFI_ERROR (Status);
//
- // In S3, we rely on Setup option, because we save to Setup in normal boot.
+ // In S3, we rely on normal boot Detection, because we save to ReadOnly Variable in normal boot.
//
if (BootMode == BOOT_ON_S3_RESUME) {
DEBUG ((EFI_D_ERROR, "DetectTpmDevice: S3 mode\n"));
- return SetupTpmDevice;
- }
- if (PcdGetBool (PcdHideTpmSupport) && PcdGetBool (PcdHideTpm)) {
- DEBUG ((EFI_D_ERROR, "DetectTpmDevice: Tpm is hide\n"));
- return TPM_DEVICE_NULL;
+ Status = PeiServicesLocatePpi (&gEfiPeiReadOnlyVariable2PpiGuid, 0, NULL, (VOID **) &VariablePpi);
+ ASSERT_EFI_ERROR (Status);
+
+ Size = sizeof(TREE_DEVICE_DETECTION);
+ ZeroMem (&TrEEDeviceDetection, sizeof(TrEEDeviceDetection));
+ Status = VariablePpi->GetVariable (
+ VariablePpi,
+ TREE_DEVICE_DETECTION_NAME,
+ &gTrEEConfigFormSetGuid,
+ NULL,
+ &Size,
+ &TrEEDeviceDetection
+ );
+ if (!EFI_ERROR (Status) &&
+ (TrEEDeviceDetection.TpmDeviceDetected >= TPM_DEVICE_MIN) &&
+ (TrEEDeviceDetection.TpmDeviceDetected <= TPM_DEVICE_MAX)) {
+ DEBUG ((EFI_D_ERROR, "TpmDevice from DeviceDetection: %x\n", TrEEDeviceDetection.TpmDeviceDetected));
+ return TrEEDeviceDetection.TpmDeviceDetected;
+ }
}
DEBUG ((EFI_D_ERROR, "DetectTpmDevice:\n"));
- if ((!IsDtpmPresent ()) || (SetupTpmDevice == TPM_DEVICE_NULL)) {
+ if (!IsDtpmPresent ()) {
// dTPM not available
return TPM_DEVICE_NULL;
}
@@ -96,7 +114,11 @@ DetectTpmDevice (
return TPM_DEVICE_2_0_DTPM;
}
- Status = Tpm12Startup (TPM_ST_CLEAR);
+ if (BootMode == BOOT_ON_S3_RESUME) {
+ Status = Tpm12Startup (TPM_ST_STATE);
+ } else {
+ Status = Tpm12Startup (TPM_ST_CLEAR);
+ }
if (EFI_ERROR (Status)) {
return TPM_DEVICE_2_0_DTPM;
}
diff --git a/SecurityPkg/Tcg/TrEEConfig/TrEEConfig.vfr b/SecurityPkg/Tcg/TrEEConfig/TrEEConfig.vfr
index 74e236319..84b55a9f1 100644
--- a/SecurityPkg/Tcg/TrEEConfig/TrEEConfig.vfr
+++ b/SecurityPkg/Tcg/TrEEConfig/TrEEConfig.vfr
@@ -20,8 +20,9 @@ formset
help = STRING_TOKEN(STR_TREE_HELP),
classguid = EFI_HII_PLATFORM_SETUP_FORMSET_GUID,
- varstore TREE_CONFIGURATION,
+ efivarstore TREE_CONFIGURATION,
varid = TREE_CONFIGURATION_VARSTORE_ID,
+ attribute = 0x03, // EFI variable attribures EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE
name = TREE_CONFIGURATION,
guid = TREE_CONFIG_FORM_SET_GUID;
@@ -40,7 +41,6 @@ formset
prompt = STRING_TOKEN(STR_TREE_DEVICE_PROMPT),
help = STRING_TOKEN(STR_TREE_DEVICE_HELP),
flags = INTERACTIVE,
- option text = STRING_TOKEN(STR_TREE_TPM_DISABLE), value = TPM_DEVICE_NULL, flags = RESET_REQUIRED;
option text = STRING_TOKEN(STR_TREE_TPM_1_2), value = TPM_DEVICE_1_2, flags = DEFAULT | MANUFACTURING | RESET_REQUIRED;
option text = STRING_TOKEN(STR_TREE_TPM_2_0_DTPM), value = TPM_DEVICE_2_0_DTPM, flags = RESET_REQUIRED;
endoneof;
@@ -52,10 +52,11 @@ formset
subtitle text = STRING_TOKEN(STR_NULL);
subtitle text = STRING_TOKEN(STR_TREE_PP_OPERATION);
- oneof varid = TREE_CONFIGURATION.Tpm2Operation,
+ oneof name = Tpm2Operation,
+ questionid = KEY_TPM2_OPERATION,
prompt = STRING_TOKEN(STR_TREE_OPERATION),
help = STRING_TOKEN(STR_TREE_OPERATION_HELP),
- flags = INTERACTIVE,
+ flags = INTERACTIVE | NUMERIC_SIZE_1,
option text = STRING_TOKEN(STR_TREE_NO_ACTION), value = TREE_PHYSICAL_PRESENCE_NO_ACTION, flags = DEFAULT | MANUFACTURING | RESET_REQUIRED;
option text = STRING_TOKEN(STR_TREE_CLEAR), value = TREE_PHYSICAL_PRESENCE_CLEAR_CONTROL_CLEAR, flags = RESET_REQUIRED;
endoneof;
diff --git a/SecurityPkg/Tcg/TrEEConfig/TrEEConfigDriver.c b/SecurityPkg/Tcg/TrEEConfig/TrEEConfigDriver.c
index f3c8e5f65..2ad02c05a 100644
--- a/SecurityPkg/Tcg/TrEEConfig/TrEEConfigDriver.c
+++ b/SecurityPkg/Tcg/TrEEConfig/TrEEConfigDriver.c
@@ -38,8 +38,10 @@ TrEEConfigDriverEntryPoint (
EFI_STATUS Status;
TREE_CONFIG_PRIVATE_DATA *PrivateData;
TREE_CONFIGURATION TrEEConfiguration;
+ TREE_DEVICE_DETECTION TrEEDeviceDetection;
UINTN Index;
UINTN DataSize;
+ EDKII_VARIABLE_LOCK_PROTOCOL *VariableLockProtocol;
Status = gBS->OpenProtocol (
ImageHandle,
@@ -79,37 +81,80 @@ TrEEConfigDriverEntryPoint (
&TrEEConfiguration
);
if (EFI_ERROR (Status)) {
+ //
+ // Variable not ready, set default value
+ //
+ TrEEConfiguration.TpmDevice = TPM_DEVICE_DEFAULT;
}
+
//
- // We should always reinit PP request.
+ // Validation
//
- TrEEConfiguration.Tpm2Operation = TREE_PHYSICAL_PRESENCE_NO_ACTION;
+ if ((TrEEConfiguration.TpmDevice > TPM_DEVICE_MAX) || (TrEEConfiguration.TpmDevice < TPM_DEVICE_MIN)) {
+ TrEEConfiguration.TpmDevice = TPM_DEVICE_DEFAULT;
+ }
//
- // Sync data from PCD to variable, so that we do not need detect again in S3 phase.
+ // Save to variable so platform driver can get it.
//
+ Status = gRT->SetVariable (
+ TREE_STORAGE_NAME,
+ &gTrEEConfigFormSetGuid,
+ EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,
+ sizeof(TrEEConfiguration),
+ &TrEEConfiguration
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR, "TrEEConfigDriver: Fail to set TREE_STORAGE_NAME\n"));
+ }
//
- // Get data from PCD to make sure data consistant - platform driver is suppose to construct this PCD accroding to Variable
+ // Sync data from PCD to variable, so that we do not need detect again in S3 phase.
//
+ TrEEDeviceDetection.TpmDeviceDetected = TPM_DEVICE_NULL;
for (Index = 0; Index < sizeof(mTpmInstanceId)/sizeof(mTpmInstanceId[0]); Index++) {
if (CompareGuid (PcdGetPtr(PcdTpmInstanceGuid), &mTpmInstanceId[Index].TpmInstanceGuid)) {
- TrEEConfiguration.TpmDevice = mTpmInstanceId[Index].TpmDevice;
+ TrEEDeviceDetection.TpmDeviceDetected = mTpmInstanceId[Index].TpmDevice;
break;
}
}
+ PrivateData->TpmDeviceDetected = TrEEDeviceDetection.TpmDeviceDetected;
+
//
// Save to variable so platform driver can get it.
//
Status = gRT->SetVariable (
- TREE_STORAGE_NAME,
+ TREE_DEVICE_DETECTION_NAME,
&gTrEEConfigFormSetGuid,
- EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
- sizeof(TrEEConfiguration),
- &TrEEConfiguration
+ EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,
+ sizeof(TrEEDeviceDetection),
+ &TrEEDeviceDetection
);
- ASSERT_EFI_ERROR (Status);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR, "TrEEConfigDriver: Fail to set TREE_DEVICE_DETECTION_NAME\n"));
+ Status = gRT->SetVariable (
+ TREE_DEVICE_DETECTION_NAME,
+ &gTrEEConfigFormSetGuid,
+ EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,
+ 0,
+ NULL
+ );
+ ASSERT_EFI_ERROR (Status);
+ }
+
+ //
+ // We should lock TrEEDeviceDetection, because it contains information needed at S3.
+ //
+ Status = gBS->LocateProtocol (&gEdkiiVariableLockProtocolGuid, NULL, (VOID **)&VariableLockProtocol);
+ if (!EFI_ERROR (Status)) {
+ Status = VariableLockProtocol->RequestToLock (
+ VariableLockProtocol,
+ TREE_DEVICE_DETECTION_NAME,
+ &gTrEEConfigFormSetGuid
+ );
+ ASSERT_EFI_ERROR (Status);
+ }
//
// Install TrEE configuration form
diff --git a/SecurityPkg/Tcg/TrEEConfig/TrEEConfigDxe.inf b/SecurityPkg/Tcg/TrEEConfig/TrEEConfigDxe.inf
index 0878fb651..042ad878d 100644
--- a/SecurityPkg/Tcg/TrEEConfig/TrEEConfigDxe.inf
+++ b/SecurityPkg/Tcg/TrEEConfig/TrEEConfigDxe.inf
@@ -62,6 +62,7 @@
[Protocols]
gEfiHiiConfigAccessProtocolGuid ## PRODUCES
gEfiHiiConfigRoutingProtocolGuid ## CONSUMES
+ gEdkiiVariableLockProtocolGuid ## CONSUMES
[Pcd]
gEfiSecurityPkgTokenSpaceGuid.PcdTpmInstanceGuid
diff --git a/SecurityPkg/Tcg/TrEEConfig/TrEEConfigImpl.c b/SecurityPkg/Tcg/TrEEConfig/TrEEConfigImpl.c
index 41bafa286..2748505fe 100644
--- a/SecurityPkg/Tcg/TrEEConfig/TrEEConfigImpl.c
+++ b/SecurityPkg/Tcg/TrEEConfig/TrEEConfigImpl.c
@@ -86,96 +86,7 @@ TrEEExtractConfig (
OUT EFI_STRING *Results
)
{
- EFI_STATUS Status;
- UINTN BufferSize;
- TREE_CONFIGURATION Configuration;
- TREE_CONFIG_PRIVATE_DATA *PrivateData;
- EFI_STRING ConfigRequestHdr;
- EFI_STRING ConfigRequest;
- BOOLEAN AllocatedRequest;
- UINTN Size;
- UINTN Index;
-
- if (Progress == NULL || Results == NULL) {
- return EFI_INVALID_PARAMETER;
- }
-
- *Progress = Request;
- if ((Request != NULL) && !HiiIsConfigHdrMatch (Request, &gTrEEConfigFormSetGuid, TREE_STORAGE_NAME)) {
- return EFI_NOT_FOUND;
- }
-
- ConfigRequestHdr = NULL;
- ConfigRequest = NULL;
- AllocatedRequest = FALSE;
- Size = 0;
-
- PrivateData = TREE_CONFIG_PRIVATE_DATA_FROM_THIS (This);
-
- //
- // Convert buffer data to <ConfigResp> by helper function BlockToConfig()
- //
- BufferSize = sizeof (Configuration);
- Status = gRT->GetVariable (
- TREE_STORAGE_NAME,
- &gTrEEConfigFormSetGuid,
- NULL,
- &BufferSize,
- &Configuration
- );
- ASSERT_EFI_ERROR (Status);
-
- //
- // Get data from PCD to make sure data consistant - platform driver is suppose to construct this PCD accroding to Variable
- //
- for (Index = 0; Index < sizeof(mTpmInstanceId)/sizeof(mTpmInstanceId[0]); Index++) {
- if (CompareGuid (PcdGetPtr(PcdTpmInstanceGuid), &mTpmInstanceId[Index].TpmInstanceGuid)) {
- Configuration.TpmDevice = mTpmInstanceId[Index].TpmDevice;
- break;
- }
- }
-
- BufferSize = sizeof (Configuration);
- ConfigRequest = Request;
- if ((Request == NULL) || (StrStr (Request, L"OFFSET") == NULL)) {
- //
- // Request has no request element, construct full request string.
- // Allocate and fill a buffer large enough to hold the <ConfigHdr> template
- // followed by "&OFFSET=0&WIDTH=WWWWWWWWWWWWWWWW" followed by a Null-terminator
- //
- ConfigRequestHdr = HiiConstructConfigHdr (&gTrEEConfigFormSetGuid, TREE_STORAGE_NAME, PrivateData->DriverHandle);
- Size = (StrLen (ConfigRequestHdr) + 32 + 1) * sizeof (CHAR16);
- ConfigRequest = AllocateZeroPool (Size);
- ASSERT (ConfigRequest != NULL);
- AllocatedRequest = TRUE;
- UnicodeSPrint (ConfigRequest, Size, L"%s&OFFSET=0&WIDTH=%016LX", ConfigRequestHdr, (UINT64) BufferSize);
- FreePool (ConfigRequestHdr);
- }
-
- Status = gHiiConfigRouting->BlockToConfig (
- gHiiConfigRouting,
- ConfigRequest,
- (UINT8 *) &Configuration,
- BufferSize,
- Results,
- Progress
- );
- //
- // Free the allocated config request string.
- //
- if (AllocatedRequest) {
- FreePool (ConfigRequest);
- }
- //
- // Set Progress string to the original request string.
- //
- if (Request == NULL) {
- *Progress = NULL;
- } else if (StrStr (Request, L"OFFSET") == NULL) {
- *Progress = Request + StrLen (Request);
- }
-
- return Status;
+ return EFI_UNSUPPORTED;
}
/**
@@ -252,59 +163,7 @@ TrEERouteConfig (
OUT EFI_STRING *Progress
)
{
- EFI_STATUS Status;
- UINTN BufferSize;
- TREE_CONFIGURATION TrEEConfiguration;
-
- if (Configuration == NULL || Progress == NULL) {
- return EFI_INVALID_PARAMETER;
- }
-
- *Progress = Configuration;
- if (!HiiIsConfigHdrMatch (Configuration, &gTrEEConfigFormSetGuid, TREE_STORAGE_NAME)) {
- return EFI_NOT_FOUND;
- }
-
- BufferSize = sizeof (TrEEConfiguration);
- Status = gRT->GetVariable (
- TREE_STORAGE_NAME,
- &gTrEEConfigFormSetGuid,
- NULL,
- &BufferSize,
- &TrEEConfiguration
- );
- ASSERT_EFI_ERROR (Status);
-
- //
- // Convert <ConfigResp> to buffer data by helper function ConfigToBlock()
- //
- BufferSize = sizeof (TREE_CONFIGURATION);
- Status = gHiiConfigRouting->ConfigToBlock (
- gHiiConfigRouting,
- Configuration,
- (UINT8 *) &TrEEConfiguration,
- &BufferSize,
- Progress
- );
- if (EFI_ERROR (Status)) {
- return Status;
- }
-
- //
- // Save to variable so platform driver can get it.
- //
- Status = gRT->SetVariable (
- TREE_STORAGE_NAME,
- &gTrEEConfigFormSetGuid,
- EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
- sizeof(TrEEConfiguration),
- &TrEEConfiguration
- );
-
- SaveTrEEPpRequest (TrEEConfiguration.Tpm2Operation
- );
-
- return Status;
+ return EFI_UNSUPPORTED;
}
/**
@@ -343,13 +202,17 @@ TrEECallback (
if ((This == NULL) || (Value == NULL) || (ActionRequest == NULL)) {
return EFI_INVALID_PARAMETER;
}
-
- if ((Action != EFI_BROWSER_ACTION_CHANGED) ||
- (QuestionId != KEY_TPM_DEVICE)) {
- return EFI_UNSUPPORTED;
+
+ if (Action == EFI_BROWSER_ACTION_CHANGED) {
+ if (QuestionId == KEY_TPM_DEVICE) {
+ return EFI_SUCCESS;
+ }
+ if (QuestionId == KEY_TPM2_OPERATION) {
+ return SaveTrEEPpRequest (Value->u8);
+ }
}
- return EFI_SUCCESS;
+ return EFI_UNSUPPORTED;
}
/**
@@ -413,6 +276,24 @@ InstallTrEEConfigForm (
PrivateData->HiiHandle = HiiHandle;
+ //
+ // Update static data
+ //
+ switch (PrivateData->TpmDeviceDetected) {
+ case TPM_DEVICE_NULL:
+ HiiSetString (PrivateData->HiiHandle, STRING_TOKEN (STR_TREE_DEVICE_STATE_CONTENT), L"Not Found", NULL);
+ break;
+ case TPM_DEVICE_1_2:
+ HiiSetString (PrivateData->HiiHandle, STRING_TOKEN (STR_TREE_DEVICE_STATE_CONTENT), L"TPM 1.2", NULL);
+ break;
+ case TPM_DEVICE_2_0_DTPM:
+ HiiSetString (PrivateData->HiiHandle, STRING_TOKEN (STR_TREE_DEVICE_STATE_CONTENT), L"TPM 2.0 (DTPM)", NULL);
+ break;
+ default:
+ HiiSetString (PrivateData->HiiHandle, STRING_TOKEN (STR_TREE_DEVICE_STATE_CONTENT), L"Unknown", NULL);
+ break;
+ }
+
return EFI_SUCCESS;
}
diff --git a/SecurityPkg/Tcg/TrEEConfig/TrEEConfigImpl.h b/SecurityPkg/Tcg/TrEEConfig/TrEEConfigImpl.h
index 0d62c831d..720c698e7 100644
--- a/SecurityPkg/Tcg/TrEEConfig/TrEEConfigImpl.h
+++ b/SecurityPkg/Tcg/TrEEConfig/TrEEConfigImpl.h
@@ -21,6 +21,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#include <Protocol/HiiConfigAccess.h>
#include <Protocol/HiiConfigRouting.h>
#include <Protocol/TrEEProtocol.h>
+#include <Protocol/VariableLock.h>
#include <Library/BaseLib.h>
#include <Library/BaseMemoryLib.h>
@@ -60,6 +61,7 @@ typedef struct {
EFI_HII_HANDLE HiiHandle;
EFI_HANDLE DriverHandle;
+ UINT8 TpmDeviceDetected;
} TREE_CONFIG_PRIVATE_DATA;
extern TREE_CONFIG_PRIVATE_DATA mTrEEConfigPrivateDateTemplate;
diff --git a/SecurityPkg/Tcg/TrEEConfig/TrEEConfigNvData.h b/SecurityPkg/Tcg/TrEEConfig/TrEEConfigNvData.h
index cb9f5a818..14e5d926a 100644
--- a/SecurityPkg/Tcg/TrEEConfig/TrEEConfigNvData.h
+++ b/SecurityPkg/Tcg/TrEEConfig/TrEEConfigNvData.h
@@ -23,22 +23,32 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#define TREE_CONFIGURATION_FORM_ID 0x0001
#define KEY_TPM_DEVICE 0x2000
+#define KEY_TPM2_OPERATION 0x2001
#define TPM_DEVICE_NULL 0
#define TPM_DEVICE_1_2 1
#define TPM_DEVICE_2_0_DTPM 2
+#define TPM_DEVICE_MIN TPM_DEVICE_1_2
#define TPM_DEVICE_MAX TPM_DEVICE_2_0_DTPM
#define TPM_DEVICE_DEFAULT TPM_DEVICE_1_2
//
-// Nv Data structure referenced by IFR
+// Nv Data structure referenced by IFR, TPM device user desired
//
typedef struct {
UINT8 TpmDevice;
- UINT8 Tpm2Operation;
} TREE_CONFIGURATION;
+//
+// Variable saved for S3, TPM detected, only valid in S3 path.
+// This variable is ReadOnly.
+//
+typedef struct {
+ UINT8 TpmDeviceDetected;
+} TREE_DEVICE_DETECTION;
+
#define TREE_STORAGE_NAME L"TREE_CONFIGURATION"
+#define TREE_DEVICE_DETECTION_NAME L"TREE_DEVICE_DETECTION"
#define TPM_INSTANCE_ID_LIST { \
{TPM_DEVICE_INTERFACE_NONE, TPM_DEVICE_NULL}, \
diff --git a/SecurityPkg/Tcg/TrEEConfig/TrEEConfigPei.inf b/SecurityPkg/Tcg/TrEEConfig/TrEEConfigPei.inf
index c6a489aee..c3a843539 100644
--- a/SecurityPkg/Tcg/TrEEConfig/TrEEConfigPei.inf
+++ b/SecurityPkg/Tcg/TrEEConfig/TrEEConfigPei.inf
@@ -2,7 +2,7 @@
# Component name for TrEE configuration module.
# NOTE: This module is only for reference only, each platform should have its own setup page.
#
-# 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
@@ -55,12 +55,8 @@
[Ppis]
gEfiPeiReadOnlyVariable2PpiGuid
-[FixedPcd]
- gEfiSecurityPkgTokenSpaceGuid.PcdHideTpmSupport
-
[Pcd]
gEfiSecurityPkgTokenSpaceGuid.PcdTpmInstanceGuid
- gEfiSecurityPkgTokenSpaceGuid.PcdHideTpm
gEfiSecurityPkgTokenSpaceGuid.PcdTpmInitializationPolicy
gEfiSecurityPkgTokenSpaceGuid.PcdTpmAutoDetection
gEfiSecurityPkgTokenSpaceGuid.PcdTpmBaseAddress
diff --git a/SecurityPkg/Tcg/TrEEConfig/TrEEConfigPeim.c b/SecurityPkg/Tcg/TrEEConfig/TrEEConfigPeim.c
index 77d640dd4..9c1e917ab 100644
--- a/SecurityPkg/Tcg/TrEEConfig/TrEEConfigPeim.c
+++ b/SecurityPkg/Tcg/TrEEConfig/TrEEConfigPeim.c
@@ -94,8 +94,8 @@ TrEEConfigPeimEntryPoint (
//
// Validation
//
- if (TrEEConfiguration.TpmDevice > TPM_DEVICE_MAX) {
- TrEEConfiguration.TpmDevice = TPM_DEVICE_DEFAULT;
+ if ((TrEEConfiguration.TpmDevice > TPM_DEVICE_MAX) || (TrEEConfiguration.TpmDevice < TPM_DEVICE_MIN)) {
+ TrEEConfiguration.TpmDevice = TPM_DEVICE_DEFAULT;
}
//
@@ -105,8 +105,12 @@ TrEEConfigPeimEntryPoint (
if (PcdGetBool (PcdTpmAutoDetection)) {
TpmDevice = DetectTpmDevice (TrEEConfiguration.TpmDevice);
- DEBUG ((EFI_D_ERROR, "TrEEConfiguration.TpmDevice final: %x\n", TpmDevice));
- TrEEConfiguration.TpmDevice = TpmDevice;
+ DEBUG ((EFI_D_ERROR, "TpmDevice final: %x\n", TpmDevice));
+ if (TpmDevice != TPM_DEVICE_NULL) {
+ TrEEConfiguration.TpmDevice = TpmDevice;
+ }
+ } else {
+ TpmDevice = TrEEConfiguration.TpmDevice;
}
//
@@ -114,11 +118,14 @@ TrEEConfigPeimEntryPoint (
// This is work-around because there is no gurantee DynamicHiiPcd can return correct value in DXE phase.
// Using DynamicPcd instead.
//
+ // NOTE: TrEEConfiguration variable contains the desired TpmDevice type,
+ // while PcdTpmInstanceGuid PCD contains the real detected TpmDevice type
+ //
for (Index = 0; Index < sizeof(mTpmInstanceId)/sizeof(mTpmInstanceId[0]); Index++) {
- if (TrEEConfiguration.TpmDevice == mTpmInstanceId[Index].TpmDevice) {
+ if (TpmDevice == mTpmInstanceId[Index].TpmDevice) {
Size = sizeof(mTpmInstanceId[Index].TpmInstanceGuid);
PcdSetPtr (PcdTpmInstanceGuid, &Size, &mTpmInstanceId[Index].TpmInstanceGuid);
- DEBUG ((EFI_D_ERROR, "TrEEConfiguration.TpmDevice PCD: %g\n", &mTpmInstanceId[Index].TpmInstanceGuid));
+ DEBUG ((EFI_D_ERROR, "TpmDevice PCD: %g\n", &mTpmInstanceId[Index].TpmInstanceGuid));
break;
}
}
diff --git a/SecurityPkg/Tcg/TrEEPei/TrEEPei.c b/SecurityPkg/Tcg/TrEEPei/TrEEPei.c
index 5b5ff6c3a..5dfbd8d89 100644
--- a/SecurityPkg/Tcg/TrEEPei/TrEEPei.c
+++ b/SecurityPkg/Tcg/TrEEPei/TrEEPei.c
@@ -1,7 +1,7 @@
/** @file
Initialize TPM2 device and measure FVs before handing off control to DXE.
-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
@@ -620,10 +620,6 @@ PeimEntryMA (
return EFI_UNSUPPORTED;
}
- if (PcdGetBool (PcdHideTpmSupport) && PcdGetBool (PcdHideTpm)) {
- return EFI_UNSUPPORTED;
- }
-
//
// Update for Performance optimization
//
diff --git a/SecurityPkg/Tcg/TrEEPei/TrEEPei.inf b/SecurityPkg/Tcg/TrEEPei/TrEEPei.inf
index 3de112c5c..719f2b4a6 100644
--- a/SecurityPkg/Tcg/TrEEPei/TrEEPei.inf
+++ b/SecurityPkg/Tcg/TrEEPei/TrEEPei.inf
@@ -1,7 +1,7 @@
## @file
# This module will initialize TPM2 device and measure FVs in PEI phase.
#
-# 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
@@ -58,7 +58,6 @@
gEfiEndOfPeiSignalPpiGuid
[Pcd]
- gEfiSecurityPkgTokenSpaceGuid.PcdHideTpm
gEfiMdeModulePkgTokenSpaceGuid.PcdFirmwareVersionString ## CONSUMES
gEfiSecurityPkgTokenSpaceGuid.PcdTpmInstanceGuid
gEfiSecurityPkgTokenSpaceGuid.PcdTpm2InitializationPolicy
@@ -66,7 +65,6 @@
gEfiSecurityPkgTokenSpaceGuid.PcdTpm2ScrtmPolicy
[FixedPcd]
- gEfiSecurityPkgTokenSpaceGuid.PcdHideTpmSupport
gEfiMdeModulePkgTokenSpaceGuid.PcdPeiCoreMaxFvSupported ## CONSUMES
[Depex]
diff --git a/SecurityPkg/Tcg/TrEESmm/TrEESmm.c b/SecurityPkg/Tcg/TrEESmm/TrEESmm.c
index 4826b7916..14303d545 100644
--- a/SecurityPkg/Tcg/TrEESmm/TrEESmm.c
+++ b/SecurityPkg/Tcg/TrEESmm/TrEESmm.c
@@ -9,7 +9,7 @@
PhysicalPresenceCallback() and MemoryClearCallback() will receive untrusted input and do some check.
-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
@@ -84,6 +84,8 @@ PhysicalPresenceCallback (
&PpData
);
if (EFI_ERROR (Status)) {
+ mTcgNvs->PhysicalPresence.ReturnCode = PP_SUBMIT_REQUEST_GENERAL_FAILURE;
+ DEBUG ((EFI_D_ERROR, "[TPM] Get PP variable failure! Status = %r\n", Status));
return EFI_SUCCESS;
}
@@ -116,6 +118,7 @@ PhysicalPresenceCallback (
if (EFI_ERROR (Status)) {
mTcgNvs->PhysicalPresence.ReturnCode = PP_SUBMIT_REQUEST_GENERAL_FAILURE;
+ DEBUG ((EFI_D_ERROR, "[TPM] Set PP variable failure! Status = %r\n", Status));
return EFI_SUCCESS;
}
mTcgNvs->PhysicalPresence.ReturnCode = PP_SUBMIT_REQUEST_SUCCESS;
@@ -133,6 +136,7 @@ PhysicalPresenceCallback (
);
if (EFI_ERROR (Status)) {
mTcgNvs->PhysicalPresence.ReturnCode = PP_SUBMIT_REQUEST_GENERAL_FAILURE;
+ DEBUG ((EFI_D_ERROR, "[TPM] Get PP flags failure! Status = %r\n", Status));
return EFI_SUCCESS;
}
@@ -220,6 +224,8 @@ MemoryClearCallback (
&MorControl
);
if (EFI_ERROR (Status)) {
+ mTcgNvs->MemoryClear.ReturnCode = MOR_REQUEST_GENERAL_FAILURE;
+ DEBUG ((EFI_D_ERROR, "[TPM] Get MOR variable failure! Status = %r\n", Status));
return EFI_SUCCESS;
}
@@ -239,6 +245,7 @@ MemoryClearCallback (
);
if (EFI_ERROR (Status)) {
mTcgNvs->MemoryClear.ReturnCode = MOR_REQUEST_GENERAL_FAILURE;
+ DEBUG ((EFI_D_ERROR, "[TPM] Set MOR variable failure! Status = %r\n", Status));
}
return EFI_SUCCESS;
diff --git a/SecurityPkg/UserIdentification/PwdCredentialProviderDxe/PwdCredentialProvider.c b/SecurityPkg/UserIdentification/PwdCredentialProviderDxe/PwdCredentialProvider.c
index cf7fe4079..b9e89cbfe 100644
--- a/SecurityPkg/UserIdentification/PwdCredentialProviderDxe/PwdCredentialProvider.c
+++ b/SecurityPkg/UserIdentification/PwdCredentialProviderDxe/PwdCredentialProvider.c
@@ -1,7 +1,7 @@
/** @file
Password Credential Provider driver implementation.
-Copyright (c) 2009 - 2011, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2009 - 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
@@ -1428,6 +1428,11 @@ PasswordProviderInit (
EFI_STATUS Status;
//
+ // It is NOT robust enough to be included in production.
+ //
+ #error "This implementation is just a sample, please comment this line if you really want to use this driver."
+
+ //
// Init credential table.
//
Status = InitCredentialTable ();
diff --git a/SecurityPkg/UserIdentification/UsbCredentialProviderDxe/UsbCredentialProvider.c b/SecurityPkg/UserIdentification/UsbCredentialProviderDxe/UsbCredentialProvider.c
index f851bb2e2..046a50052 100644
--- a/SecurityPkg/UserIdentification/UsbCredentialProviderDxe/UsbCredentialProvider.c
+++ b/SecurityPkg/UserIdentification/UsbCredentialProviderDxe/UsbCredentialProvider.c
@@ -1,7 +1,7 @@
/** @file
Usb Credential Provider driver implemenetation.
-Copyright (c) 2009 - 2012, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2009 - 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
@@ -1377,6 +1377,11 @@ UsbProviderInit (
EFI_STATUS Status;
//
+ // It is NOT robust enough to be included in production.
+ //
+ #error "This implementation is just a sample, please comment this line if you really want to use this driver."
+
+ //
// Init credential table.
//
Status = InitCredentialTable ();
diff --git a/SecurityPkg/UserIdentification/UserIdentifyManagerDxe/UserIdentifyManager.c b/SecurityPkg/UserIdentification/UserIdentifyManagerDxe/UserIdentifyManager.c
index adcf9bf65..a7467b366 100644
--- a/SecurityPkg/UserIdentification/UserIdentifyManagerDxe/UserIdentifyManager.c
+++ b/SecurityPkg/UserIdentification/UserIdentifyManagerDxe/UserIdentifyManager.c
@@ -1,7 +1,7 @@
/** @file
This driver manages user information and produces user manager protocol.
-Copyright (c) 2009 - 2011, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2009 - 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
@@ -3736,6 +3736,11 @@ UserIdentifyManagerInit (
EFI_STATUS Status;
//
+ // It is NOT robust enough to be included in production.
+ //
+ #error "This implementation is just a sample, please comment this line if you really want to use this driver."
+
+ //
// Initiate form browser.
//
InitFormBrowser ();
diff --git a/SecurityPkg/VariableAuthenticated/RuntimeDxe/AuthService.c b/SecurityPkg/VariableAuthenticated/RuntimeDxe/AuthService.c
index ee45ec977..07a41b06f 100644
--- a/SecurityPkg/VariableAuthenticated/RuntimeDxe/AuthService.c
+++ b/SecurityPkg/VariableAuthenticated/RuntimeDxe/AuthService.c
@@ -15,7 +15,7 @@
They will do basic validation for authentication data structure, then call crypto library
to verify the signature.
-Copyright (c) 2009 - 2013, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2009 - 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
@@ -450,22 +450,26 @@ AutenticatedVariableServiceInitialize (
Add public key in store and return its index.
@param[in] PubKey Input pointer to Public Key data
+ @param[in] VariableDataEntry The variable data entry
@return Index of new added item
**/
UINT32
AddPubKeyInStore (
- IN UINT8 *PubKey
+ IN UINT8 *PubKey,
+ IN VARIABLE_ENTRY_CONSISTENCY *VariableDataEntry
)
{
- EFI_STATUS Status;
- BOOLEAN IsFound;
- UINT32 Index;
- VARIABLE_POINTER_TRACK Variable;
- UINT8 *Ptr;
- UINT8 *Data;
- UINTN DataSize;
+ EFI_STATUS Status;
+ BOOLEAN IsFound;
+ UINT32 Index;
+ VARIABLE_POINTER_TRACK Variable;
+ UINT8 *Ptr;
+ UINT8 *Data;
+ UINTN DataSize;
+ VARIABLE_ENTRY_CONSISTENCY PublicKeyEntry;
+ UINT32 Attributes;
if (PubKey == NULL) {
return 0;
@@ -478,8 +482,8 @@ AddPubKeyInStore (
&mVariableModuleGlobal->VariableGlobal,
FALSE
);
- ASSERT_EFI_ERROR (Status);
if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR, "Get public key database variable failure, Status = %r\n", Status));
return 0;
}
@@ -530,8 +534,8 @@ AddPubKeyInStore (
&mVariableModuleGlobal->VariableGlobal,
FALSE
);
- ASSERT_EFI_ERROR (Status);
if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR, "Get public key database variable failure, Status = %r\n", Status));
return 0;
}
@@ -546,6 +550,21 @@ AddPubKeyInStore (
}
}
+ //
+ // Check the variable space for both public key and variable data.
+ //
+ PublicKeyEntry.VariableSize = (mPubKeyNumber + 1) * EFI_CERT_TYPE_RSA2048_SIZE;
+ PublicKeyEntry.Guid = &gEfiAuthenticatedVariableGuid;
+ PublicKeyEntry.Name = AUTHVAR_KEYDB_NAME;
+ Attributes = VARIABLE_ATTRIBUTE_NV_BS_RT | EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS;
+
+ if (!CheckRemainingSpaceForConsistency (Attributes, &PublicKeyEntry, VariableDataEntry, NULL)) {
+ //
+ // No enough variable space.
+ //
+ return 0;
+ }
+
CopyMem (mPubKeyStore + mPubKeyNumber * EFI_CERT_TYPE_RSA2048_SIZE, PubKey, EFI_CERT_TYPE_RSA2048_SIZE);
Index = ++mPubKeyNumber;
//
@@ -556,13 +575,16 @@ AddPubKeyInStore (
&gEfiAuthenticatedVariableGuid,
mPubKeyStore,
mPubKeyNumber * EFI_CERT_TYPE_RSA2048_SIZE,
- EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS,
+ Attributes,
0,
0,
&Variable,
NULL
);
- ASSERT_EFI_ERROR (Status);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR, "Update public key database variable failure, Status = %r\n", Status));
+ return 0;
+ }
}
return Index;
@@ -1268,6 +1290,7 @@ ProcessVariable (
EFI_CERT_BLOCK_RSA_2048_SHA256 *CertBlock;
UINT32 KeyIndex;
UINT64 MonotonicCount;
+ VARIABLE_ENTRY_CONSISTENCY VariableDataEntry;
KeyIndex = 0;
CertData = NULL;
@@ -1393,10 +1416,14 @@ ProcessVariable (
// Now, the signature has been verified!
//
if (IsFirstTime && !IsDeletion) {
+ VariableDataEntry.VariableSize = DataSize - AUTHINFO_SIZE;
+ VariableDataEntry.Guid = VendorGuid;
+ VariableDataEntry.Name = VariableName;
+
//
// Update public key database variable if need.
//
- KeyIndex = AddPubKeyInStore (PubKey);
+ KeyIndex = AddPubKeyInStore (PubKey, &VariableDataEntry);
if (KeyIndex == 0) {
return EFI_OUT_OF_RESOURCES;
}
diff --git a/SecurityPkg/VariableAuthenticated/RuntimeDxe/Variable.c b/SecurityPkg/VariableAuthenticated/RuntimeDxe/Variable.c
index 28d026a0a..6a33a78da 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 - 2013, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2009 - 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
@@ -610,7 +610,7 @@ IsValidPubKeyIndex (
return FALSE;
}
- Variable = GetStartPointer (mNvVariableCache);
+ Variable = GetStartPointer ((VARIABLE_STORE_HEADER *) (UINTN) mVariableModuleGlobal->VariableGlobal.NonVolatileVariableBase);
while (IsValidVariableHeader (Variable)) {
if ((Variable->State == VAR_ADDED || Variable->State == (VAR_IN_DELETED_TRANSITION & VAR_ADDED)) &&
@@ -860,6 +860,7 @@ Reclaim (
if (EFI_ERROR (Status)) {
goto Done;
}
+ ASSERT ((NewPubKeyIndex != NULL) && (NewPubKeyStore != NULL));
//
// Refresh the PubKeyIndex for all valid variables (ADDED and IN_DELETED_TRANSITION).
@@ -1509,6 +1510,134 @@ VariableGetBestLanguage (
}
/**
+ This function is to check if the remaining variable space is enough to set
+ all Variables from argument list successfully. The purpose of the check
+ is to keep the consistency of the Variables to be in variable storage.
+
+ Note: Variables are assumed to be in same storage.
+ The set sequence of Variables will be same with the sequence of VariableEntry from argument list,
+ so follow the argument sequence to check the Variables.
+
+ @param[in] Attributes Variable attributes for Variable entries.
+ @param ... The variable argument list with type VARIABLE_ENTRY_CONSISTENCY *.
+ A NULL terminates the list. The VariableSize of
+ VARIABLE_ENTRY_CONSISTENCY is the variable data size as input.
+ It will be changed to variable total size as output.
+
+ @retval TRUE Have enough variable space to set the Variables successfully.
+ @retval FALSE No enough variable space to set the Variables successfully.
+
+**/
+BOOLEAN
+EFIAPI
+CheckRemainingSpaceForConsistency (
+ IN UINT32 Attributes,
+ ...
+ )
+{
+ EFI_STATUS Status;
+ VA_LIST Args;
+ VARIABLE_ENTRY_CONSISTENCY *VariableEntry;
+ UINT64 MaximumVariableStorageSize;
+ UINT64 RemainingVariableStorageSize;
+ UINT64 MaximumVariableSize;
+ UINTN TotalNeededSize;
+ UINTN OriginalVarSize;
+ VARIABLE_STORE_HEADER *VariableStoreHeader;
+ VARIABLE_POINTER_TRACK VariablePtrTrack;
+ VARIABLE_HEADER *NextVariable;
+ UINTN VarNameSize;
+ UINTN VarDataSize;
+
+ //
+ // Non-Volatile related.
+ //
+ VariableStoreHeader = mNvVariableCache;
+
+ Status = VariableServiceQueryVariableInfoInternal (
+ Attributes,
+ &MaximumVariableStorageSize,
+ &RemainingVariableStorageSize,
+ &MaximumVariableSize
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ TotalNeededSize = 0;
+ VA_START (Args, Attributes);
+ VariableEntry = VA_ARG (Args, VARIABLE_ENTRY_CONSISTENCY *);
+ while (VariableEntry != NULL) {
+ //
+ // Calculate variable total size.
+ //
+ VarNameSize = StrSize (VariableEntry->Name);
+ VarNameSize += GET_PAD_SIZE (VarNameSize);
+ VarDataSize = VariableEntry->VariableSize;
+ VarDataSize += GET_PAD_SIZE (VarDataSize);
+ VariableEntry->VariableSize = HEADER_ALIGN (sizeof (VARIABLE_HEADER) + VarNameSize + VarDataSize);
+
+ TotalNeededSize += VariableEntry->VariableSize;
+ VariableEntry = VA_ARG (Args, VARIABLE_ENTRY_CONSISTENCY *);
+ }
+ VA_END (Args);
+
+ if (RemainingVariableStorageSize >= TotalNeededSize) {
+ //
+ // Already have enough space.
+ //
+ return TRUE;
+ } else if (AtRuntime ()) {
+ //
+ // At runtime, no reclaim.
+ // The original variable space of Variables can't be reused.
+ //
+ return FALSE;
+ }
+
+ VA_START (Args, Attributes);
+ VariableEntry = VA_ARG (Args, VARIABLE_ENTRY_CONSISTENCY *);
+ while (VariableEntry != NULL) {
+ //
+ // Check if Variable[Index] has been present and get its size.
+ //
+ OriginalVarSize = 0;
+ VariablePtrTrack.StartPtr = GetStartPointer (VariableStoreHeader);
+ VariablePtrTrack.EndPtr = GetEndPointer (VariableStoreHeader);
+ Status = FindVariableEx (
+ VariableEntry->Name,
+ VariableEntry->Guid,
+ FALSE,
+ &VariablePtrTrack
+ );
+ if (!EFI_ERROR (Status)) {
+ //
+ // Get size of Variable[Index].
+ //
+ NextVariable = GetNextVariablePtr (VariablePtrTrack.CurrPtr);
+ OriginalVarSize = (UINTN) NextVariable - (UINTN) VariablePtrTrack.CurrPtr;
+ //
+ // Add the original size of Variable[Index] to remaining variable storage size.
+ //
+ RemainingVariableStorageSize += OriginalVarSize;
+ }
+ if (VariableEntry->VariableSize > RemainingVariableStorageSize) {
+ //
+ // No enough space for Variable[Index].
+ //
+ VA_END (Args);
+ return FALSE;
+ }
+ //
+ // Sub the (new) size of Variable[Index] from remaining variable storage size.
+ //
+ RemainingVariableStorageSize -= VariableEntry->VariableSize;
+ VariableEntry = VA_ARG (Args, VARIABLE_ENTRY_CONSISTENCY *);
+ }
+ VA_END (Args);
+
+ return TRUE;
+}
+
+/**
Hook the operations in PlatformLangCodes, LangCodes, PlatformLang and Lang.
When setting Lang/LangCodes, simultaneously update PlatformLang/PlatformLangCodes.
@@ -1522,8 +1651,13 @@ VariableGetBestLanguage (
@param[in] DataSize Size of data. 0 means delete.
+ @retval EFI_SUCCESS The update operation is successful or ignored.
+ @retval EFI_WRITE_PROTECTED Update PlatformLangCodes/LangCodes at runtime.
+ @retval EFI_OUT_OF_RESOURCES No enough variable space to do the update operation.
+ @retval Others Other errors happened during the update operation.
+
**/
-VOID
+EFI_STATUS
AutoUpdateLangVariable (
IN CHAR16 *VariableName,
IN VOID *Data,
@@ -1537,12 +1671,13 @@ AutoUpdateLangVariable (
UINT32 Attributes;
VARIABLE_POINTER_TRACK Variable;
BOOLEAN SetLanguageCodes;
+ VARIABLE_ENTRY_CONSISTENCY VariableEntry[2];
//
// Don't do updates for delete operation
//
if (DataSize == 0) {
- return;
+ return EFI_SUCCESS;
}
SetLanguageCodes = FALSE;
@@ -1552,7 +1687,7 @@ AutoUpdateLangVariable (
// PlatformLangCodes is a volatile variable, so it can not be updated at runtime.
//
if (AtRuntime ()) {
- return;
+ return EFI_WRITE_PROTECTED;
}
SetLanguageCodes = TRUE;
@@ -1582,7 +1717,7 @@ AutoUpdateLangVariable (
// LangCodes is a volatile variable, so it can not be updated at runtime.
//
if (AtRuntime ()) {
- return;
+ return EFI_WRITE_PROTECTED;
}
SetLanguageCodes = TRUE;
@@ -1626,11 +1761,13 @@ AutoUpdateLangVariable (
//
// Neither PlatformLang nor Lang is set, directly return
//
- return;
+ return EFI_SUCCESS;
}
}
}
+ Status = EFI_SUCCESS;
+
//
// According to UEFI spec, "Lang" and "PlatformLang" is NV|BS|RT attributions.
//
@@ -1657,16 +1794,31 @@ AutoUpdateLangVariable (
BestLang = GetLangFromSupportedLangCodes (mVariableModuleGlobal->LangCodes, Index, TRUE);
//
- // Successfully convert PlatformLang to Lang, and set the BestLang value into Lang variable simultaneously.
+ // Check the variable space for both Lang and PlatformLang variable.
//
- FindVariable (EFI_LANG_VARIABLE_NAME, &gEfiGlobalVariableGuid, &Variable, &mVariableModuleGlobal->VariableGlobal, FALSE);
-
- Status = UpdateVariable (EFI_LANG_VARIABLE_NAME, &gEfiGlobalVariableGuid, BestLang,
- ISO_639_2_ENTRY_SIZE + 1, Attributes, 0, 0, &Variable, NULL);
+ VariableEntry[0].VariableSize = ISO_639_2_ENTRY_SIZE + 1;
+ VariableEntry[0].Guid = &gEfiGlobalVariableGuid;
+ VariableEntry[0].Name = EFI_LANG_VARIABLE_NAME;
+
+ VariableEntry[1].VariableSize = AsciiStrSize (BestPlatformLang);
+ VariableEntry[1].Guid = &gEfiGlobalVariableGuid;
+ VariableEntry[1].Name = EFI_PLATFORM_LANG_VARIABLE_NAME;
+ if (!CheckRemainingSpaceForConsistency (VARIABLE_ATTRIBUTE_NV_BS_RT, &VariableEntry[0], &VariableEntry[1], NULL)) {
+ //
+ // No enough variable space to set both Lang and PlatformLang successfully.
+ //
+ Status = EFI_OUT_OF_RESOURCES;
+ } else {
+ //
+ // Successfully convert PlatformLang to Lang, and set the BestLang value into Lang variable simultaneously.
+ //
+ FindVariable (EFI_LANG_VARIABLE_NAME, &gEfiGlobalVariableGuid, &Variable, &mVariableModuleGlobal->VariableGlobal, FALSE);
- DEBUG ((EFI_D_INFO, "Variable Driver Auto Update PlatformLang, PlatformLang:%a, Lang:%a\n", BestPlatformLang, BestLang));
+ Status = UpdateVariable (EFI_LANG_VARIABLE_NAME, &gEfiGlobalVariableGuid, BestLang,
+ ISO_639_2_ENTRY_SIZE + 1, Attributes, 0, 0, &Variable, NULL);
+ }
- ASSERT_EFI_ERROR(Status);
+ DEBUG ((EFI_D_INFO, "Variable Driver Auto Update PlatformLang, PlatformLang:%a, Lang:%a Status: %r\n", BestPlatformLang, BestLang, Status));
}
}
@@ -1691,18 +1843,43 @@ AutoUpdateLangVariable (
BestPlatformLang = GetLangFromSupportedLangCodes (mVariableModuleGlobal->PlatformLangCodes, Index, FALSE);
//
- // Successfully convert Lang to PlatformLang, and set the BestPlatformLang value into PlatformLang variable simultaneously.
+ // Check the variable space for both PlatformLang and Lang variable.
//
- FindVariable (EFI_PLATFORM_LANG_VARIABLE_NAME, &gEfiGlobalVariableGuid, &Variable, &mVariableModuleGlobal->VariableGlobal, FALSE);
+ VariableEntry[0].VariableSize = AsciiStrSize (BestPlatformLang);
+ VariableEntry[0].Guid = &gEfiGlobalVariableGuid;
+ VariableEntry[0].Name = EFI_PLATFORM_LANG_VARIABLE_NAME;
+
+ VariableEntry[1].VariableSize = ISO_639_2_ENTRY_SIZE + 1;
+ VariableEntry[1].Guid = &gEfiGlobalVariableGuid;
+ VariableEntry[1].Name = EFI_LANG_VARIABLE_NAME;
+ if (!CheckRemainingSpaceForConsistency (VARIABLE_ATTRIBUTE_NV_BS_RT, &VariableEntry[0], &VariableEntry[1], NULL)) {
+ //
+ // No enough variable space to set both PlatformLang and Lang successfully.
+ //
+ Status = EFI_OUT_OF_RESOURCES;
+ } else {
+ //
+ // Successfully convert Lang to PlatformLang, and set the BestPlatformLang value into PlatformLang variable simultaneously.
+ //
+ FindVariable (EFI_PLATFORM_LANG_VARIABLE_NAME, &gEfiGlobalVariableGuid, &Variable, &mVariableModuleGlobal->VariableGlobal, FALSE);
- Status = UpdateVariable (EFI_PLATFORM_LANG_VARIABLE_NAME, &gEfiGlobalVariableGuid, BestPlatformLang,
- AsciiStrSize (BestPlatformLang), Attributes, 0, 0, &Variable, NULL);
+ Status = UpdateVariable (EFI_PLATFORM_LANG_VARIABLE_NAME, &gEfiGlobalVariableGuid, BestPlatformLang,
+ AsciiStrSize (BestPlatformLang), Attributes, 0, 0, &Variable, NULL);
+ }
- DEBUG ((EFI_D_INFO, "Variable Driver Auto Update Lang, Lang:%a, PlatformLang:%a\n", BestLang, BestPlatformLang));
- ASSERT_EFI_ERROR (Status);
+ DEBUG ((EFI_D_INFO, "Variable Driver Auto Update Lang, Lang:%a, PlatformLang:%a Status: %r\n", BestLang, BestPlatformLang, Status));
}
}
}
+
+ if (SetLanguageCodes) {
+ //
+ // Continue to set PlatformLangCodes or LangCodes.
+ //
+ return EFI_SUCCESS;
+ } else {
+ return Status;
+ }
}
/**
@@ -2986,11 +3163,20 @@ VariableServiceSetVariable (
goto Done;
}
}
-
- //
- // Hook the operation of setting PlatformLangCodes/PlatformLang and LangCodes/Lang.
- //
- AutoUpdateLangVariable (VariableName, Data, DataSize);
+
+ if (!FeaturePcdGet (PcdUefiVariableDefaultLangDeprecate)) {
+ //
+ // Hook the operation of setting PlatformLangCodes/PlatformLang and LangCodes/Lang.
+ //
+ Status = AutoUpdateLangVariable (VariableName, Data, DataSize);
+ if (EFI_ERROR (Status)) {
+ //
+ // The auto update operation failed, directly return to avoid inconsistency between PlatformLang and Lang.
+ //
+ goto Done;
+ }
+ }
+
//
// Process PK, KEK, Sigdb seperately.
//
@@ -3040,14 +3226,12 @@ Done:
@param MaximumVariableSize Pointer to the maximum size of an individual EFI variables
associated with the attributes specified.
- @return EFI_INVALID_PARAMETER An invalid combination of attribute bits was supplied.
@return EFI_SUCCESS Query successfully.
- @return EFI_UNSUPPORTED The attribute is not supported on this platform.
**/
EFI_STATUS
EFIAPI
-VariableServiceQueryVariableInfo (
+VariableServiceQueryVariableInfoInternal (
IN UINT32 Attributes,
OUT UINT64 *MaximumVariableStorageSize,
OUT UINT64 *RemainingVariableStorageSize,
@@ -3060,38 +3244,12 @@ VariableServiceQueryVariableInfo (
VARIABLE_STORE_HEADER *VariableStoreHeader;
UINT64 CommonVariableTotalSize;
UINT64 HwErrVariableTotalSize;
+ EFI_STATUS Status;
+ VARIABLE_POINTER_TRACK VariablePtrTrack;
CommonVariableTotalSize = 0;
HwErrVariableTotalSize = 0;
- if(MaximumVariableStorageSize == NULL || RemainingVariableStorageSize == NULL || MaximumVariableSize == NULL || Attributes == 0) {
- return EFI_INVALID_PARAMETER;
- }
-
- if((Attributes & (EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_HARDWARE_ERROR_RECORD)) == 0) {
- //
- // Make sure the Attributes combination is supported by the platform.
- //
- return EFI_UNSUPPORTED;
- } else if ((Attributes & (EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS)) == EFI_VARIABLE_RUNTIME_ACCESS) {
- //
- // Make sure if runtime bit is set, boot service bit is set also.
- //
- return EFI_INVALID_PARAMETER;
- } else if (AtRuntime () && ((Attributes & EFI_VARIABLE_RUNTIME_ACCESS) == 0)) {
- //
- // Make sure RT Attribute is set if we are in Runtime phase.
- //
- return EFI_INVALID_PARAMETER;
- } else if ((Attributes & (EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_HARDWARE_ERROR_RECORD)) == EFI_VARIABLE_HARDWARE_ERROR_RECORD) {
- //
- // Make sure Hw Attribute is set with NV.
- //
- return EFI_INVALID_PARAMETER;
- }
-
- AcquireLockOnlyAtBootTime(&mVariableModuleGlobal->VariableGlobal.VariableServicesLock);
-
if((Attributes & EFI_VARIABLE_NON_VOLATILE) == 0) {
//
// Query is Volatile related.
@@ -3163,6 +3321,27 @@ VariableServiceQueryVariableInfo (
} else {
CommonVariableTotalSize += VariableSize;
}
+ } else if (Variable->State == (VAR_IN_DELETED_TRANSITION & VAR_ADDED)) {
+ //
+ // If it is a IN_DELETED_TRANSITION variable,
+ // and there is not also a same ADDED one at the same time,
+ // this IN_DELETED_TRANSITION variable is valid.
+ //
+ VariablePtrTrack.StartPtr = GetStartPointer (VariableStoreHeader);
+ VariablePtrTrack.EndPtr = GetEndPointer (VariableStoreHeader);
+ Status = FindVariableEx (
+ GetVariableNamePtr (Variable),
+ &Variable->VendorGuid,
+ FALSE,
+ &VariablePtrTrack
+ );
+ if (!EFI_ERROR (Status) && VariablePtrTrack.CurrPtr->State != VAR_ADDED) {
+ if ((Variable->Attributes & EFI_VARIABLE_HARDWARE_ERROR_RECORD) == EFI_VARIABLE_HARDWARE_ERROR_RECORD) {
+ HwErrVariableTotalSize += VariableSize;
+ } else {
+ CommonVariableTotalSize += VariableSize;
+ }
+ }
}
}
@@ -3184,10 +3363,79 @@ VariableServiceQueryVariableInfo (
*MaximumVariableSize = *RemainingVariableStorageSize - sizeof (VARIABLE_HEADER);
}
- ReleaseLockOnlyAtBootTime (&mVariableModuleGlobal->VariableGlobal.VariableServicesLock);
return EFI_SUCCESS;
}
+/**
+
+ 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
+ for the EFI variables associated with the attributes specified.
+ @param RemainingVariableStorageSize Pointer to the remaining size of the storage space available
+ for EFI variables associated with the attributes specified.
+ @param MaximumVariableSize Pointer to the maximum size of an individual EFI variables
+ associated with the attributes specified.
+
+ @return EFI_INVALID_PARAMETER An invalid combination of attribute bits was supplied.
+ @return EFI_SUCCESS Query successfully.
+ @return EFI_UNSUPPORTED The attribute is not supported on this platform.
+
+**/
+EFI_STATUS
+EFIAPI
+VariableServiceQueryVariableInfo (
+ IN UINT32 Attributes,
+ OUT UINT64 *MaximumVariableStorageSize,
+ OUT UINT64 *RemainingVariableStorageSize,
+ OUT UINT64 *MaximumVariableSize
+ )
+{
+ EFI_STATUS Status;
+
+ if(MaximumVariableStorageSize == NULL || RemainingVariableStorageSize == NULL || MaximumVariableSize == NULL || Attributes == 0) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if((Attributes & (EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_HARDWARE_ERROR_RECORD)) == 0) {
+ //
+ // Make sure the Attributes combination is supported by the platform.
+ //
+ return EFI_UNSUPPORTED;
+ } else if ((Attributes & (EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS)) == EFI_VARIABLE_RUNTIME_ACCESS) {
+ //
+ // Make sure if runtime bit is set, boot service bit is set also.
+ //
+ return EFI_INVALID_PARAMETER;
+ } else if (AtRuntime () && ((Attributes & EFI_VARIABLE_RUNTIME_ACCESS) == 0)) {
+ //
+ // Make sure RT Attribute is set if we are in Runtime phase.
+ //
+ return EFI_INVALID_PARAMETER;
+ } else if ((Attributes & (EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_HARDWARE_ERROR_RECORD)) == EFI_VARIABLE_HARDWARE_ERROR_RECORD) {
+ //
+ // Make sure Hw Attribute is set with NV.
+ //
+ return EFI_INVALID_PARAMETER;
+ }
+
+ AcquireLockOnlyAtBootTime(&mVariableModuleGlobal->VariableGlobal.VariableServicesLock);
+
+ Status = VariableServiceQueryVariableInfoInternal (
+ Attributes,
+ MaximumVariableStorageSize,
+ RemainingVariableStorageSize,
+ MaximumVariableSize
+ );
+
+ ReleaseLockOnlyAtBootTime (&mVariableModuleGlobal->VariableGlobal.VariableServicesLock);
+ return Status;
+}
/**
This function reclaims variable storage if free size is below the threshold.
diff --git a/SecurityPkg/VariableAuthenticated/RuntimeDxe/Variable.h b/SecurityPkg/VariableAuthenticated/RuntimeDxe/Variable.h
index b4512d2cc..c0497afe5 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 - 2013, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2009 - 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
@@ -111,10 +111,8 @@ typedef struct {
typedef struct {
EFI_GUID *Guid;
CHAR16 *Name;
- UINT32 Attributes;
- UINTN DataSize;
- VOID *Data;
-} VARIABLE_CACHE_ENTRY;
+ UINTN VariableSize;
+} VARIABLE_ENTRY_CONSISTENCY;
typedef struct {
EFI_GUID Guid;
@@ -220,6 +218,32 @@ DataSizeOfVariable (
);
/**
+ This function is to check if the remaining variable space is enough to set
+ all Variables from argument list successfully. The purpose of the check
+ is to keep the consistency of the Variables to be in variable storage.
+
+ Note: Variables are assumed to be in same storage.
+ The set sequence of Variables will be same with the sequence of VariableEntry from argument list,
+ so follow the argument sequence to check the Variables.
+
+ @param[in] Attributes Variable attributes for Variable entries.
+ @param ... The variable argument list with type VARIABLE_ENTRY_CONSISTENCY *.
+ A NULL terminates the list. The VariableSize of
+ VARIABLE_ENTRY_CONSISTENCY is the variable data size as input.
+ It will be changed to variable total size as output.
+
+ @retval TRUE Have enough variable space to set the Variables successfully.
+ @retval FALSE No enough variable space to set the Variables successfully.
+
+**/
+BOOLEAN
+EFIAPI
+CheckRemainingSpaceForConsistency (
+ IN UINT32 Attributes,
+ ...
+ );
+
+/**
Update the variable region with Variable information. If EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS is set,
index of associated public key is needed.
@@ -580,6 +604,34 @@ VariableServiceSetVariable (
@param MaximumVariableSize Pointer to the maximum size of an individual EFI variables
associated with the attributes specified.
+ @return EFI_SUCCESS Query successfully.
+
+**/
+EFI_STATUS
+EFIAPI
+VariableServiceQueryVariableInfoInternal (
+ IN UINT32 Attributes,
+ OUT UINT64 *MaximumVariableStorageSize,
+ OUT UINT64 *RemainingVariableStorageSize,
+ OUT UINT64 *MaximumVariableSize
+ );
+
+/**
+
+ 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
+ for the EFI variables associated with the attributes specified.
+ @param RemainingVariableStorageSize Pointer to the remaining size of the storage space available
+ for EFI variables associated with the attributes specified.
+ @param MaximumVariableSize Pointer to the maximum size of an individual EFI variables
+ associated with the attributes specified.
+
@return EFI_INVALID_PARAMETER An invalid combination of attribute bits was supplied.
@return EFI_SUCCESS Query successfully.
@return EFI_UNSUPPORTED The attribute is not supported on this platform.
diff --git a/SecurityPkg/VariableAuthenticated/RuntimeDxe/VariableDxe.c b/SecurityPkg/VariableAuthenticated/RuntimeDxe/VariableDxe.c
index 1d71e4f80..949fb6424 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 - 2013, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2009 - 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
@@ -388,7 +388,9 @@ FtwNotificationEvent (
}
Status = VariableWriteServiceInitialize ();
- ASSERT_EFI_ERROR (Status);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "Variable write service initialization failed. Status = %r\n", Status));
+ }
//
// Install the Variable Write Architectural protocol.
diff --git a/SecurityPkg/VariableAuthenticated/RuntimeDxe/VariableRuntimeDxe.inf b/SecurityPkg/VariableAuthenticated/RuntimeDxe/VariableRuntimeDxe.inf
index 5b257aea0..41e85c015 100644
--- a/SecurityPkg/VariableAuthenticated/RuntimeDxe/VariableRuntimeDxe.inf
+++ b/SecurityPkg/VariableAuthenticated/RuntimeDxe/VariableRuntimeDxe.inf
@@ -99,10 +99,11 @@
gEfiMdeModulePkgTokenSpaceGuid.PcdHwErrStorageSize
[FeaturePcd]
- gEfiMdeModulePkgTokenSpaceGuid.PcdVariableCollectStatistics ## SOMETIME_CONSUMES (statistic the information of variable.)
+ gEfiMdeModulePkgTokenSpaceGuid.PcdVariableCollectStatistics ## CONSUMES # statistic the information of variable.
+ gEfiMdePkgTokenSpaceGuid.PcdUefiVariableDefaultLangDeprecate ## CONSUMES
[Depex]
- gEfiFirmwareVolumeBlockProtocolGuid AND gEfiFaultTolerantWriteProtocolGuid
+ TRUE
# [Event]
# ##
diff --git a/SecurityPkg/VariableAuthenticated/RuntimeDxe/VariableSmm.c b/SecurityPkg/VariableAuthenticated/RuntimeDxe/VariableSmm.c
index 4ac582d49..63ac43615 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 - 2013, 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
@@ -848,7 +848,9 @@ SmmFtwNotificationEvent (
mVariableModuleGlobal->FvbInstance = FvbProtocol;
Status = VariableWriteServiceInitialize ();
- ASSERT_EFI_ERROR (Status);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "Variable write service initialization failed. Status = %r\n", Status));
+ }
//
// Notify the variable wrapper driver the variable write service is ready
diff --git a/SecurityPkg/VariableAuthenticated/RuntimeDxe/VariableSmm.inf b/SecurityPkg/VariableAuthenticated/RuntimeDxe/VariableSmm.inf
index e7c6de8b9..0e3fc514b 100644
--- a/SecurityPkg/VariableAuthenticated/RuntimeDxe/VariableSmm.inf
+++ b/SecurityPkg/VariableAuthenticated/RuntimeDxe/VariableSmm.inf
@@ -102,7 +102,8 @@
gEfiMdeModulePkgTokenSpaceGuid.PcdHwErrStorageSize
[FeaturePcd]
- gEfiMdeModulePkgTokenSpaceGuid.PcdVariableCollectStatistics ## SOMETIME_CONSUMES (statistic the information of variable.)
+ gEfiMdeModulePkgTokenSpaceGuid.PcdVariableCollectStatistics ## CONSUMES # statistic the information of variable.
+ gEfiMdePkgTokenSpaceGuid.PcdUefiVariableDefaultLangDeprecate ## CONSUMES
[Depex]
TRUE
diff --git a/ShellPkg/Application/Shell/Shell.c b/ShellPkg/Application/Shell/Shell.c
index ba3be3f6c..fa7201642 100644
--- a/ShellPkg/Application/Shell/Shell.c
+++ b/ShellPkg/Application/Shell/Shell.c
@@ -2,7 +2,7 @@
This is THE shell (application)
Copyright (c) 2009 - 2014, Intel Corporation. All rights reserved.<BR>
- Copyright (c) 2013, Hewlett-Packard Development Company, L.P.
+ (C) Copyright 2013-2014, Hewlett-Packard Development Company, L.P.
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
@@ -2481,7 +2481,7 @@ RunCommand(
//
switch (Type = GetOperationType(FirstParameter)) {
case File_Sys_Change:
- Status = ChangeMappedDrive(CleanOriginal);
+ Status = ChangeMappedDrive (FirstParameter);
break;
case Internal_Command:
case Script_File_Name:
diff --git a/ShellPkg/Application/Shell/ShellProtocol.c b/ShellPkg/Application/Shell/ShellProtocol.c
index 116e3f206..9cc4ca38c 100644
--- a/ShellPkg/Application/Shell/ShellProtocol.c
+++ b/ShellPkg/Application/Shell/ShellProtocol.c
@@ -1770,6 +1770,19 @@ EfiShellRemoveDupInFileList(
}
return (EFI_SUCCESS);
}
+
+//
+// This is the same structure as the external version, but it has no CONST qualifiers.
+//
+typedef struct {
+ LIST_ENTRY Link; ///< Linked list members.
+ EFI_STATUS Status; ///< Status of opening the file. Valid only if Handle != NULL.
+ CHAR16 *FullName; ///< Fully qualified filename.
+ CHAR16 *FileName; ///< name of this file.
+ SHELL_FILE_HANDLE Handle; ///< Handle for interacting with the opened file or NULL if closed.
+ EFI_FILE_INFO *Info; ///< Pointer to the FileInfo struct for this file or NULL.
+} EFI_SHELL_FILE_INFO_NO_CONST;
+
/**
Allocates and duplicates a EFI_SHELL_FILE_INFO node.
@@ -1786,7 +1799,12 @@ InternalDuplicateShellFileInfo(
IN BOOLEAN Save
)
{
- EFI_SHELL_FILE_INFO *NewNode;
+ EFI_SHELL_FILE_INFO_NO_CONST *NewNode;
+
+ //
+ // try to confirm that the objects are in sync
+ //
+ ASSERT(sizeof(EFI_SHELL_FILE_INFO_NO_CONST) == sizeof(EFI_SHELL_FILE_INFO));
NewNode = AllocateZeroPool(sizeof(EFI_SHELL_FILE_INFO));
if (NewNode == NULL) {
@@ -1799,7 +1817,11 @@ InternalDuplicateShellFileInfo(
if ( NewNode->FullName == NULL
|| NewNode->FileName == NULL
|| NewNode->Info == NULL
- ){
+ ){
+ SHELL_FREE_NON_NULL(NewNode->FullName);
+ SHELL_FREE_NON_NULL(NewNode->FileName);
+ SHELL_FREE_NON_NULL(NewNode->Info);
+ SHELL_FREE_NON_NULL(NewNode);
return(NULL);
}
NewNode->Status = Node->Status;
@@ -1811,7 +1833,7 @@ InternalDuplicateShellFileInfo(
StrCpy((CHAR16*)NewNode->FileName, Node->FileName);
CopyMem(NewNode->Info, Node->Info, (UINTN)Node->Info->Size);
- return(NewNode);
+ return((EFI_SHELL_FILE_INFO*)NewNode);
}
/**
@@ -1876,7 +1898,7 @@ CreateAndPopulateShellFileInfo(
TempString = StrnCatGrow(&TempString, &Size, BasePath, 0);
if (TempString == NULL) {
FreePool((VOID*)ShellFileListItem->FileName);
- FreePool(ShellFileListItem->Info);
+ SHELL_FREE_NON_NULL(ShellFileListItem->Info);
FreePool(ShellFileListItem);
return (NULL);
}
@@ -2083,6 +2105,7 @@ ShellSearchHandle(
EFI_SHELL_FILE_INFO *ShellInfo;
EFI_SHELL_FILE_INFO *ShellInfoNode;
EFI_SHELL_FILE_INFO *NewShellNode;
+ EFI_FILE_INFO *FileInfo;
BOOLEAN Directory;
CHAR16 *NewFullName;
UINTN Size;
@@ -2110,30 +2133,44 @@ ShellSearchHandle(
if (CurrentFilePattern[0] == CHAR_NULL
&&NextFilePatternStart[0] == CHAR_NULL
- ){
+ ){
//
- // Add the current parameter FileHandle to the list, then end...
+ // we want the parent or root node (if no parent)
//
if (ParentNode == NULL) {
- Status = EFI_INVALID_PARAMETER;
+ //
+ // We want the root node. create the node.
+ //
+ FileInfo = FileHandleGetInfo(FileHandle);
+ NewShellNode = CreateAndPopulateShellFileInfo(
+ L":",
+ EFI_SUCCESS,
+ L"\\",
+ FileHandle,
+ FileInfo
+ );
+ SHELL_FREE_NON_NULL(FileInfo);
} else {
+ //
+ // Add the current parameter FileHandle to the list, then end...
+ //
NewShellNode = InternalDuplicateShellFileInfo((EFI_SHELL_FILE_INFO*)ParentNode, TRUE);
- if (NewShellNode == NULL) {
- Status = EFI_OUT_OF_RESOURCES;
- } else {
- NewShellNode->Handle = NULL;
- if (*FileList == NULL) {
- *FileList = AllocateZeroPool(sizeof(EFI_SHELL_FILE_INFO));
- InitializeListHead(&((*FileList)->Link));
- }
+ }
+ if (NewShellNode == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ } else {
+ NewShellNode->Handle = NULL;
+ if (*FileList == NULL) {
+ *FileList = AllocateZeroPool(sizeof(EFI_SHELL_FILE_INFO));
+ InitializeListHead(&((*FileList)->Link));
+ }
- //
- // Add to the returning to use list
- //
- InsertTailList(&(*FileList)->Link, &NewShellNode->Link);
+ //
+ // Add to the returning to use list
+ //
+ InsertTailList(&(*FileList)->Link, &NewShellNode->Link);
- Status = EFI_SUCCESS;
- }
+ Status = EFI_SUCCESS;
}
} else {
Status = EfiShellFindFilesInDir(FileHandle, &ShellInfo);
@@ -2995,9 +3032,12 @@ InternalEfiShellGetListAlias(
/**
Convert a null-terminated unicode string, in-place, to all lowercase.
Then return it.
+
+ @param Str The null-terminated string to be converted to all lowercase.
+
+ @return The null-terminated string converted into all lowercase.
**/
-STATIC
-CHAR16 *
+STATIC CHAR16 *
ToLower (
CHAR16 *Str
)
@@ -3538,3 +3578,4 @@ InernalEfiShellStartMonitor(
}
return (Status);
}
+
diff --git a/ShellPkg/Library/UefiHandleParsingLib/UefiHandleParsingLib.c b/ShellPkg/Library/UefiHandleParsingLib/UefiHandleParsingLib.c
index 7c2e9c735..0cd35b4fd 100644
--- a/ShellPkg/Library/UefiHandleParsingLib/UefiHandleParsingLib.c
+++ b/ShellPkg/Library/UefiHandleParsingLib/UefiHandleParsingLib.c
@@ -2,7 +2,7 @@
Provides interface to advanced shell functionality for parsing both handle and protocol database.
Copyright (c) 2013 Hewlett-Packard Development Company, L.P.
- Copyright (c) 2010 - 2013, Intel Corporation. All rights reserved.<BR>
+ 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
@@ -20,6 +20,43 @@ EFI_HANDLE mHandleParsingHiiHandle;
HANDLE_INDEX_LIST mHandleList = {{{NULL,NULL},0,0},0};
/**
+ Function to translate the EFI_MEMORY_TYPE into a string.
+
+ @param[in] Memory The memory type.
+
+ @retval A string representation of the type allocated from BS Pool.
+**/
+CHAR16*
+EFIAPI
+ConvertMemoryType (
+ IN CONST EFI_MEMORY_TYPE Memory
+ )
+{
+ CHAR16 *RetVal;
+ RetVal = NULL;
+
+ switch (Memory) {
+ case EfiReservedMemoryType: StrnCatGrow(&RetVal, NULL, L"EfiReservedMemoryType", 0); break;
+ case EfiLoaderCode: StrnCatGrow(&RetVal, NULL, L"EfiLoaderCode", 0); break;
+ case EfiLoaderData: StrnCatGrow(&RetVal, NULL, L"EfiLoaderData", 0); break;
+ case EfiBootServicesCode: StrnCatGrow(&RetVal, NULL, L"EfiBootServicesCode", 0); break;
+ case EfiBootServicesData: StrnCatGrow(&RetVal, NULL, L"EfiBootServicesData", 0); break;
+ case EfiRuntimeServicesCode: StrnCatGrow(&RetVal, NULL, L"EfiRuntimeServicesCode", 0); break;
+ case EfiRuntimeServicesData: StrnCatGrow(&RetVal, NULL, L"EfiRuntimeServicesData", 0); break;
+ case EfiConventionalMemory: StrnCatGrow(&RetVal, NULL, L"EfiConventionalMemory", 0); break;
+ case EfiUnusableMemory: StrnCatGrow(&RetVal, NULL, L"EfiUnusableMemory", 0); break;
+ case EfiACPIReclaimMemory: StrnCatGrow(&RetVal, NULL, L"EfiACPIReclaimMemory", 0); break;
+ case EfiACPIMemoryNVS: StrnCatGrow(&RetVal, NULL, L"EfiACPIMemoryNVS", 0); break;
+ case EfiMemoryMappedIO: StrnCatGrow(&RetVal, NULL, L"EfiMemoryMappedIO", 0); break;
+ case EfiMemoryMappedIOPortSpace: StrnCatGrow(&RetVal, NULL, L"EfiMemoryMappedIOPortSpace", 0); break;
+ case EfiPalCode: StrnCatGrow(&RetVal, NULL, L"EfiPalCode", 0); break;
+ case EfiMaxMemoryType: StrnCatGrow(&RetVal, NULL, L"EfiMaxMemoryType", 0); break;
+ default: ASSERT(FALSE);
+ }
+ return (RetVal);
+}
+
+/**
Constructor for the library.
@param[in] ImageHandle Ignored.
@@ -63,7 +100,16 @@ HandleParsingLibDestructor (
return (EFI_SUCCESS);
}
-/*
+/**
+ Function to dump information about LoadedImage.
+
+ This will allocate the return buffer from boot services pool.
+
+ @param[in] TheHandle The handle that has LoadedImage installed.
+ @param[in] Verbose TRUE for additional information, FALSE otherwise.
+
+ @retval A poitner to a string containing the information.
+**/
CHAR16*
EFIAPI
LoadedImageProtocolDumpInformation(
@@ -71,96 +117,59 @@ LoadedImageProtocolDumpInformation(
IN CONST BOOLEAN Verbose
)
{
- EFI_LOADED_IMAGE_PROTOCOL *Image;
+ EFI_LOADED_IMAGE_PROTOCOL *LoadedImage;
EFI_STATUS Status;
- EFI_DEVICE_PATH_PROTOCOL *DevPath;
- EFI_DEVICE_PATH_PROTOCOL *DevPathNode;
- VOID *Buffer;
- UINTN BufferSize;
- UINT32 AuthenticationStatus;
- EFI_GUID *NameGuid;
- EFI_FIRMWARE_VOLUME_PROTOCOL *FV;
- EFI_FIRMWARE_VOLUME2_PROTOCOL *FV2;
-
- FV = NULL;
- FV2 = NULL;
- Buffer = NULL;
- BufferSize = 0;
-
- Status = HandleProtocol (
- TheHandle,
- &gEfiLoadedImageProtocolGuid,
- &Image);
- ASSERT_EFI_ERROR(Status);
+ CHAR16 *RetVal;
+ CHAR16 *Temp;
+ CHAR16 *CodeType;
+ CHAR16 *DataType;
- DevPath = UnpackDevicePath (Image->FilePath);
+ if (!Verbose) {
+ return (CatSPrint(NULL, L"LoadedImage"));
+ }
- if (DevPath == NULL) {
+ Temp = HiiGetString(mHandleParsingHiiHandle, STRING_TOKEN(STR_LI_DUMP_MAIN), NULL);
+ RetVal = AllocateZeroPool (PcdGet16 (PcdShellPrintBufferSize));
+ if (Temp == NULL || RetVal == NULL) {
+ SHELL_FREE_NON_NULL(Temp);
+ SHELL_FREE_NON_NULL(RetVal);
return NULL;
}
- DevPathNode = DevPath;
-
- while (!IsDevicePathEnd (DevPathNode)) {
- //
- // Find the Fv File path
- //
- NameGuid = GetNameGuidFromFwVolDevicePathNode ((MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *)DevPathNode);
- if (NameGuid != NULL) {
- Status = BS->HandleProtocol (
- Image->DeviceHandle,
- &gEfiFirmwareVolumeProtocolGuid,
- &FV
- );
- if (!EFI_ERROR (Status)) {
- Status = FV->ReadSection (
- FV,
- NameGuid,
- EFI_SECTION_USER_INTERFACE,
- 0,
- &Buffer,
- &BufferSize,
- &AuthenticationStatus
- );
- if (!EFI_ERROR (Status)) {
- break;
- }
+ Status = gBS->OpenProtocol (
+ TheHandle,
+ &gEfiLoadedImageProtocolGuid,
+ (VOID**)&LoadedImage,
+ gImageHandle,
+ NULL,
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL
+ );
- Buffer = NULL;
- } else {
- Status = BS->HandleProtocol (
- Image->DeviceHandle,
- &gEfiFirmwareVolume2ProtocolGuid,
- &FV2
- );
- if (!EFI_ERROR (Status)) {
- Status = FV2->ReadSection (
- FV2,
- NameGuid,
- EFI_SECTION_USER_INTERFACE,
- 0,
- &Buffer,
- &BufferSize,
- &AuthenticationStatus
- );
- if (!EFI_ERROR (Status)) {
- break;
- }
+ DataType = ConvertMemoryType(LoadedImage->ImageDataType);
+ CodeType = ConvertMemoryType(LoadedImage->ImageCodeType);
+
+ RetVal = CatSPrint(RetVal,
+ Temp,
+ LoadedImage->Revision,
+ LoadedImage->ParentHandle,
+ LoadedImage->SystemTable,
+ LoadedImage->DeviceHandle,
+ LoadedImage->FilePath,
+ LoadedImage->LoadOptionsSize,
+ LoadedImage->LoadOptions,
+ LoadedImage->ImageBase,
+ LoadedImage->ImageSize,
+ CodeType,
+ DataType,
+ LoadedImage->Unload);
- Buffer = NULL;
- }
- }
- }
- //
- // Next device path node
- //
- DevPathNode = NextDevicePathNode (DevPathNode);
- }
+
+ SHELL_FREE_NON_NULL(Temp);
+ SHELL_FREE_NON_NULL(CodeType);
+ SHELL_FREE_NON_NULL(DataType);
- FreePool (DevPath);
- return Buffer;
+ return RetVal;
}
-*/
/**
Function to dump information about PciRootBridgeIo.
@@ -463,7 +472,7 @@ STATIC CONST GUID_INFO_BLOCK mGuidStringListNT[] = {
};
STATIC CONST GUID_INFO_BLOCK mGuidStringList[] = {
- {STRING_TOKEN(STR_LOADED_IMAGE), &gEfiLoadedImageProtocolGuid, NULL},
+ {STRING_TOKEN(STR_LOADED_IMAGE), &gEfiLoadedImageProtocolGuid, LoadedImageProtocolDumpInformation},
{STRING_TOKEN(STR_DEVICE_PATH), &gEfiDevicePathProtocolGuid, DevicePathProtocolDumpInformation},
{STRING_TOKEN(STR_IMAGE_PATH), &gEfiLoadedImageDevicePathProtocolGuid, DevicePathProtocolDumpInformation},
{STRING_TOKEN(STR_DEVICE_PATH_UTIL), &gEfiDevicePathUtilitiesProtocolGuid, NULL},
diff --git a/ShellPkg/Library/UefiHandleParsingLib/UefiHandleParsingLib.uni b/ShellPkg/Library/UefiHandleParsingLib/UefiHandleParsingLib.uni
index 998a386fa..6f7c383b4 100644
--- a/ShellPkg/Library/UefiHandleParsingLib/UefiHandleParsingLib.uni
+++ b/ShellPkg/Library/UefiHandleParsingLib/UefiHandleParsingLib.uni
Binary files differ
diff --git a/ShellPkg/Library/UefiShellDebug1CommandsLib/SetVar.c b/ShellPkg/Library/UefiShellDebug1CommandsLib/SetVar.c
index 7c3aa542b..9e57998ff 100644
--- a/ShellPkg/Library/UefiShellDebug1CommandsLib/SetVar.c
+++ b/ShellPkg/Library/UefiShellDebug1CommandsLib/SetVar.c
@@ -139,7 +139,8 @@ ShellCommandRunSetVar (
Attributes |= EFI_VARIABLE_BOOTSERVICE_ACCESS;
}
if (ShellCommandLineGetFlag(Package, L"-rt")) {
- Attributes |= EFI_VARIABLE_RUNTIME_ACCESS;
+ Attributes |= EFI_VARIABLE_RUNTIME_ACCESS |
+ EFI_VARIABLE_BOOTSERVICE_ACCESS;
}
if (ShellCommandLineGetFlag(Package, L"-nv")) {
Attributes |= EFI_VARIABLE_NON_VOLATILE;
diff --git a/ShellPkg/Library/UefiShellDriver1CommandsLib/UefiShellDriver1CommandsLib.c b/ShellPkg/Library/UefiShellDriver1CommandsLib/UefiShellDriver1CommandsLib.c
index 957fde9b8..95cd9a0ca 100644
--- a/ShellPkg/Library/UefiShellDriver1CommandsLib/UefiShellDriver1CommandsLib.c
+++ b/ShellPkg/Library/UefiShellDriver1CommandsLib/UefiShellDriver1CommandsLib.c
@@ -1,7 +1,7 @@
/** @file
Main file for NULL named library for level 1 shell command functions.
- 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
diff --git a/ShellPkg/Library/UefiShellDriver1CommandsLib/UefiShellDriver1CommandsLib.h b/ShellPkg/Library/UefiShellDriver1CommandsLib/UefiShellDriver1CommandsLib.h
index 8962d3289..668584092 100644
--- a/ShellPkg/Library/UefiShellDriver1CommandsLib/UefiShellDriver1CommandsLib.h
+++ b/ShellPkg/Library/UefiShellDriver1CommandsLib/UefiShellDriver1CommandsLib.h
@@ -1,7 +1,7 @@
/** @file
Main file for NULL named library for Profile1 shell command functions.
- Copyright (c) 2010 - 2013, 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
diff --git a/ShellPkg/Library/UefiShellDriver1CommandsLib/Unload.c b/ShellPkg/Library/UefiShellDriver1CommandsLib/Unload.c
index 4e1ac0da8..cb2c07b69 100644
--- a/ShellPkg/Library/UefiShellDriver1CommandsLib/Unload.c
+++ b/ShellPkg/Library/UefiShellDriver1CommandsLib/Unload.c
@@ -1,7 +1,7 @@
/** @file
Main file for Unload shell Driver1 function.
- Copyright (c) 2010 - 2013, 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
@@ -15,43 +15,6 @@
#include "UefiShellDriver1CommandsLib.h"
/**
- Function to translate the EFI_MEMORY_TYPE into a string.
-
- @param[in] Memory The memory type.
-
- @retval A string representation of the type allocated from BS Pool.
-**/
-CHAR16*
-EFIAPI
-ConvertMemoryType (
- IN CONST EFI_MEMORY_TYPE Memory
- )
-{
- CHAR16 *RetVal;
- RetVal = NULL;
-
- switch (Memory) {
- case EfiReservedMemoryType: StrnCatGrow(&RetVal, NULL, L"EfiReservedMemoryType", 0); break;
- case EfiLoaderCode: StrnCatGrow(&RetVal, NULL, L"EfiLoaderCode", 0); break;
- case EfiLoaderData: StrnCatGrow(&RetVal, NULL, L"EfiLoaderData", 0); break;
- case EfiBootServicesCode: StrnCatGrow(&RetVal, NULL, L"EfiBootServicesCode", 0); break;
- case EfiBootServicesData: StrnCatGrow(&RetVal, NULL, L"EfiBootServicesData", 0); break;
- case EfiRuntimeServicesCode: StrnCatGrow(&RetVal, NULL, L"EfiRuntimeServicesCode", 0); break;
- case EfiRuntimeServicesData: StrnCatGrow(&RetVal, NULL, L"EfiRuntimeServicesData", 0); break;
- case EfiConventionalMemory: StrnCatGrow(&RetVal, NULL, L"EfiConventionalMemory", 0); break;
- case EfiUnusableMemory: StrnCatGrow(&RetVal, NULL, L"EfiUnusableMemory", 0); break;
- case EfiACPIReclaimMemory: StrnCatGrow(&RetVal, NULL, L"EfiACPIReclaimMemory", 0); break;
- case EfiACPIMemoryNVS: StrnCatGrow(&RetVal, NULL, L"EfiACPIMemoryNVS", 0); break;
- case EfiMemoryMappedIO: StrnCatGrow(&RetVal, NULL, L"EfiMemoryMappedIO", 0); break;
- case EfiMemoryMappedIOPortSpace: StrnCatGrow(&RetVal, NULL, L"EfiMemoryMappedIOPortSpace", 0); break;
- case EfiPalCode: StrnCatGrow(&RetVal, NULL, L"EfiPalCode", 0); break;
- case EfiMaxMemoryType: StrnCatGrow(&RetVal, NULL, L"EfiMaxMemoryType", 0); break;
- default: ASSERT(FALSE);
- }
- return (RetVal);
-}
-
-/**
Function to dump LoadedImage info from TheHandle.
@param[in] TheHandle The handle to dump info from.
@@ -65,42 +28,14 @@ DumpLoadedImageProtocolInfo (
IN EFI_HANDLE TheHandle
)
{
- EFI_LOADED_IMAGE_PROTOCOL *Image;
- EFI_STATUS Status;
- CHAR16 *DevicePathText;
- CHAR16 *CodeTypeText;
- CHAR16 *DataTypeText;
- CHAR8 *PdbPointer;
+ CHAR16 *TheString;
- Image = NULL;
-
- Status = gBS->OpenProtocol(TheHandle, &gEfiLoadedImageProtocolGuid, (VOID**)&Image, gImageHandle, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL);
- if (EFI_ERROR(Status)) {
- return (EFI_INVALID_PARAMETER);
- }
- DevicePathText = ConvertDevicePathToText(Image->FilePath, TRUE, TRUE);
- CodeTypeText = ConvertMemoryType(Image->ImageCodeType);
- DataTypeText = ConvertMemoryType(Image->ImageDataType);
- PdbPointer = (CHAR8*)PeCoffLoaderGetPdbPointer(Image->ImageBase);
- ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_UNLOAD_VERBOSE), gShellDriver1HiiHandle,
- ConvertHandleToHandleIndex(TheHandle),
- TheHandle,
- Image,
- Image->ParentHandle,
- Image->SystemTable,
- Image->DeviceHandle,
- DevicePathText,
- PdbPointer,
- Image->ImageBase,
- Image->ImageSize,
- CodeTypeText,
- DataTypeText
- );
-
- SHELL_FREE_NON_NULL(DevicePathText);
- SHELL_FREE_NON_NULL(CodeTypeText);
- SHELL_FREE_NON_NULL(DataTypeText);
+ TheString = GetProtocolInformationDump(TheHandle, &gEfiLoadedImageProtocolGuid, TRUE);
+
+ ShellPrintEx(-1, -1, L"%s", TheString);
+ SHELL_FREE_NON_NULL(TheString);
+
return (EFI_SUCCESS);
}
diff --git a/ShellPkg/Library/UefiShellLevel2CommandsLib/Ls.c b/ShellPkg/Library/UefiShellLevel2CommandsLib/Ls.c
index 63af5eab1..64ce4ae2c 100644
--- a/ShellPkg/Library/UefiShellLevel2CommandsLib/Ls.c
+++ b/ShellPkg/Library/UefiShellLevel2CommandsLib/Ls.c
@@ -437,7 +437,7 @@ PrintLsOutput(
}
}
- if (!Sfo && HeaderPrinted == FALSE) {
+ if (!Sfo && !HeaderPrinted) {
PrintNonSfoHeader(CorrectedPath);
}
PrintFileInformation(Sfo, Node, &FileCount, &FileSize, &DirCount);
@@ -457,6 +457,9 @@ PrintLsOutput(
ShellCloseFileMetaArg(&ListHead);
CorrectedPath[0] = CHAR_NULL;
CorrectedPath = StrnCatGrow(&CorrectedPath, &LongestPath, RootPath, 0);
+ if (CorrectedPath == NULL) {
+ return SHELL_OUT_OF_RESOURCES;
+ }
if (CorrectedPath[StrLen(CorrectedPath)-1] != L'\\'
&&CorrectedPath[StrLen(CorrectedPath)-1] != L'/') {
CorrectedPath = StrnCatGrow(&CorrectedPath, &LongestPath, L"\\", 0);
@@ -498,7 +501,7 @@ PrintLsOutput(
SHELL_FREE_NON_NULL(CorrectedPath);
ShellCloseFileMetaArg(&ListHead);
- if (Found == NULL && FoundOne == FALSE) {
+ if (Found == NULL && !FoundOne) {
return (SHELL_NOT_FOUND);
}
diff --git a/SourceLevelDebugPkg/Library/DebugAgent/DxeDebugAgent/DxeDebugAgentLib.c b/SourceLevelDebugPkg/Library/DebugAgent/DxeDebugAgent/DxeDebugAgentLib.c
index 71130d8aa..e424c0f8d 100644
--- a/SourceLevelDebugPkg/Library/DebugAgent/DxeDebugAgent/DxeDebugAgentLib.c
+++ b/SourceLevelDebugPkg/Library/DebugAgent/DxeDebugAgent/DxeDebugAgentLib.c
@@ -1,7 +1,7 @@
/** @file
Debug Agent library implementition for Dxe Core and Dxr modules.
- Copyright (c) 2010 - 2013, 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
@@ -283,16 +283,21 @@ SetupDebugAgentEnviroment (
//
InitializeDebugIdt ();
- if (Mailbox != NULL) {
- //
- // If Mailbox exists, copy it into one global variable,
- //
- CopyMem (&mMailbox, Mailbox, sizeof (DEBUG_AGENT_MAILBOX));
- } else {
- ZeroMem (&mMailbox, sizeof (DEBUG_AGENT_MAILBOX));
- }
+ //
+ // If mMailboxPointer is not set before, set it
+ //
+ if (mMailboxPointer == NULL) {
+ if (Mailbox != NULL) {
+ //
+ // If Mailbox exists, copy it into one global variable
+ //
+ CopyMem (&mMailbox, Mailbox, sizeof (DEBUG_AGENT_MAILBOX));
+ } else {
+ ZeroMem (&mMailbox, sizeof (DEBUG_AGENT_MAILBOX));
+ }
+ mMailboxPointer = &mMailbox;
+ }
- mMailboxPointer = &mMailbox;
//
// Initialize debug communication port
//
@@ -521,6 +526,10 @@ InitializeDebugAgent (
VerifyMailboxChecksum (Mailbox);
}
//
+ // Save Mailbox pointer in global variable
+ //
+ mMailboxPointer = Mailbox;
+ //
// Set up IDT table and prepare for IDT entries
//
SetupDebugAgentEnviroment (Mailbox);
diff --git a/StdLib/EfiSocketLib/Socket.c b/StdLib/EfiSocketLib/Socket.c
index c7084a1a0..49c288d90 100644
--- a/StdLib/EfiSocketLib/Socket.c
+++ b/StdLib/EfiSocketLib/Socket.c
@@ -1834,10 +1834,9 @@ EslSocketConnect (
case SOCKET_STATE_CONNECTED:
//
- // Already connected
+ // Connected
//
- pSocket->errno = EISCONN;
- Status = EFI_ALREADY_STARTED;
+ Status = EFI_SUCCESS;
break;
}
diff --git a/StdLib/LibC/StdLib/Malloc.c b/StdLib/LibC/StdLib/Malloc.c
index 3f79deb49..df6e70247 100644
--- a/StdLib/LibC/StdLib/Malloc.c
+++ b/StdLib/LibC/StdLib/Malloc.c
@@ -14,20 +14,19 @@
either a null pointer or a unique pointer. The value of a pointer that
refers to freed space is indeterminate.
-Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>
-This program and the accompanying materials
-are licensed and made available under the terms and conditions of the BSD License
-which accompanies this distribution. The full text of the license may be found at
-http://opensource.org/licenses/bsd-license.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.
-
+ 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
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
*/
-#include <Base.h>
#include <Uefi.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/UefiBootServicesTableLib.h>
+#include <Library/BaseLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/DebugLib.h>
@@ -37,23 +36,31 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#include <stdlib.h>
#include <errno.h>
+#define CPOOL_HEAD_SIGNATURE SIGNATURE_32('C','p','h','d')
+
/** The UEFI functions do not provide a way to determine the size of an
allocated region of memory given just a pointer to the start of that
region. Since this is required for the implementation of realloc,
- the memory head structure from Core/Dxe/Mem/Pool.c has been reproduced
- here.
+ the memory head structure, CPOOL_HEAD, containing the necessary
+ information is prepended to the requested space.
- NOTE: If the UEFI implementation is changed, the realloc function may cease
- to function properly.
+ The order of members is important. This structure is 8-byte aligned,
+ as per the UEFI specification for memory allocation functions. By
+ specifying Size as a 64-bit value and placing it immediately before
+ Data, it ensures that Data will always be 8-byte aligned.
+
+ On IA32 systems, this structure is 24 bytes long, excluding Data.
+ On X64 systems, this structure is 32 bytes long, excluding Data.
**/
-#define POOL_HEAD_SIGNATURE SIGNATURE_32('p','h','d','0')
typedef struct {
+ LIST_ENTRY List;
UINT32 Signature;
- UINT32 Size;
- EFI_MEMORY_TYPE Type;
- UINTN Reserved;
+ UINT64 Size;
CHAR8 Data[1];
-} POOL_HEAD;
+} CPOOL_HEAD;
+
+// List of memory allocated by malloc/calloc/etc.
+static LIST_ENTRY MemPoolHead = INITIALIZE_LIST_HEAD_VARIABLE(MemPoolHead);
/****************************/
@@ -76,19 +83,41 @@ typedef struct {
void *
malloc(size_t Size)
{
+ CPOOL_HEAD *Head;
void *RetVal;
EFI_STATUS Status;
+ UINTN NodeSize;
if( Size == 0) {
errno = EINVAL; // Make errno diffenent, just in case of a lingering ENOMEM.
+ DEBUG((DEBUG_ERROR, "ERROR malloc: Zero Size\n"));
return NULL;
}
- Status = gBS->AllocatePool( EfiLoaderData, (UINTN)Size, &RetVal);
+ NodeSize = (UINTN)(Size + sizeof(CPOOL_HEAD));
+
+ DEBUG((DEBUG_POOL, "malloc(%d): NodeSz: %d", Size, NodeSize));
+
+ Status = gBS->AllocatePool( EfiLoaderData, NodeSize, &Head);
if( Status != EFI_SUCCESS) {
RetVal = NULL;
errno = ENOMEM;
+ DEBUG((DEBUG_ERROR, "\nERROR malloc: AllocatePool returned %r\n", Status));
+ }
+ else {
+ assert(Head != NULL);
+ // Fill out the pool header
+ Head->Signature = CPOOL_HEAD_SIGNATURE;
+ Head->Size = NodeSize;
+
+ // Add this node to the list
+ (void)InsertTailList(&MemPoolHead, (LIST_ENTRY *)Head);
+
+ // Return a pointer to the data
+ RetVal = (void*)Head->Data;
+ DEBUG((DEBUG_POOL, " Head: %p, Returns %p\n", Head, RetVal));
}
+
return RetVal;
}
@@ -113,13 +142,15 @@ calloc(size_t Num, size_t Size)
size_t NumSize;
NumSize = Num * Size;
- if (NumSize == 0) {
- return NULL;
- }
+ RetVal = NULL;
+ if (NumSize != 0) {
RetVal = malloc(NumSize);
if( RetVal != NULL) {
(VOID)ZeroMem( RetVal, NumSize);
}
+ }
+ DEBUG((DEBUG_POOL, "0x%p = calloc(%d, %d)\n", RetVal, Num, Size));
+
return RetVal;
}
@@ -137,9 +168,24 @@ calloc(size_t Num, size_t Size)
void
free(void *Ptr)
{
+ CPOOL_HEAD *Head;
+
+ Head = BASE_CR(Ptr, CPOOL_HEAD, Data);
+ assert(Head != NULL);
+ DEBUG((DEBUG_POOL, "free(%p): Head: %p\n", Ptr, Head));
+
if(Ptr != NULL) {
- (void) gBS->FreePool (Ptr);
+ if (Head->Signature == CPOOL_HEAD_SIGNATURE) {
+ (void) RemoveEntryList((LIST_ENTRY *)Head); // Remove this node from the malloc pool
+ (void) gBS->FreePool (Head); // Now free the associated memory
+ }
+ else {
+ errno = EFAULT;
+ DEBUG((DEBUG_ERROR, "ERROR free(0x%p): Signature is 0x%8X, expected 0x%8X\n",
+ Ptr, Head->Signature, CPOOL_HEAD_SIGNATURE));
}
+ }
+ DEBUG((DEBUG_POOL, "free Done\n"));
}
/** The realloc function changes the size of the object pointed to by Ptr to
@@ -185,27 +231,31 @@ free(void *Ptr)
NULL is returned and errno will be unchanged.
**/
void *
-realloc(void *Ptr, size_t NewSize)
+realloc(void *Ptr, size_t ReqSize)
{
void *RetVal = NULL;
- POOL_HEAD *Head;
- UINTN OldSize = 0;
- UINTN NumCpy;
+ CPOOL_HEAD *Head = NULL;
+ size_t OldSize = 0;
+ size_t NewSize;
+ size_t NumCpy;
// Find out the size of the OLD memory region
if( Ptr != NULL) {
- Head = BASE_CR (Ptr, POOL_HEAD, Data);
+ Head = BASE_CR (Ptr, CPOOL_HEAD, Data);
assert(Head != NULL);
- if (Head->Signature != POOL_HEAD_SIGNATURE) {
+ if (Head->Signature != CPOOL_HEAD_SIGNATURE) {
errno = EFAULT;
+ DEBUG((DEBUG_ERROR, "ERROR realloc(0x%p): Signature is 0x%8X, expected 0x%8X\n",
+ Ptr, Head->Signature, CPOOL_HEAD_SIGNATURE));
return NULL;
}
- OldSize = Head->Size;
+ OldSize = (size_t)Head->Size;
}
// At this point, Ptr is either NULL or a valid pointer to an allocated space
+ NewSize = (size_t)(ReqSize + (sizeof(CPOOL_HEAD)));
- if( NewSize > 0) {
+ if( ReqSize > 0) {
RetVal = malloc(NewSize); // Get the NEW memory region
if( Ptr != NULL) { // If there is an OLD region...
if( RetVal != NULL) { // and the NEW region was successfully allocated
@@ -216,13 +266,16 @@ realloc(void *Ptr, size_t NewSize)
(VOID)CopyMem( RetVal, Ptr, NumCpy); // Copy old data to the new region.
free( Ptr); // and reclaim the old region.
}
+ else {
+ errno = ENOMEM;
+ }
}
}
else {
- if( Ptr != NULL) {
free( Ptr); // Reclaim the old region.
}
- }
+ DEBUG((DEBUG_POOL, "0x%p = realloc(%p, %d): Head: %p NewSz: %d\n",
+ RetVal, Ptr, ReqSize, Head, NewSize));
return RetVal;
}