summaryrefslogtreecommitdiff
path: root/MdeModulePkg/Universal/CapsuleRuntimeDxe
diff options
context:
space:
mode:
authorkx <kx@radix.pro>2024-06-04 06:43:08 +0300
committerkx <kx@radix.pro>2024-06-04 06:43:08 +0300
commit7e2ccccace24636f29ddc210b94606abd4c7e42b (patch)
tree545d43ea12671048956cafeb12303e84d601e571 /MdeModulePkg/Universal/CapsuleRuntimeDxe
parent27b044605cd5f6b33a3d231576003850b3fe305b (diff)
downloadedk2-trunk.tar.xz
Renormalized end-of-lines from master@27b044605cd5f6b33a3d231576003850b3fe305btrunk
Diffstat (limited to 'MdeModulePkg/Universal/CapsuleRuntimeDxe')
-rw-r--r--MdeModulePkg/Universal/CapsuleRuntimeDxe/Arm/CapsuleReset.c70
-rw-r--r--MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleCache.c112
-rw-r--r--MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleCacheNull.c62
-rw-r--r--MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleReset.c56
-rw-r--r--MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleRuntimeDxe.inf218
-rw-r--r--MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleRuntimeDxe.uni34
-rw-r--r--MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleRuntimeDxeExtra.uni28
-rw-r--r--MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleService.c832
-rw-r--r--MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleService.h140
-rw-r--r--MdeModulePkg/Universal/CapsuleRuntimeDxe/SaveLongModeContext.c42
-rw-r--r--MdeModulePkg/Universal/CapsuleRuntimeDxe/X64/SaveLongModeContext.c422
11 files changed, 1008 insertions, 1008 deletions
diff --git a/MdeModulePkg/Universal/CapsuleRuntimeDxe/Arm/CapsuleReset.c b/MdeModulePkg/Universal/CapsuleRuntimeDxe/Arm/CapsuleReset.c
index b974d6067f..da1ad083b1 100644
--- a/MdeModulePkg/Universal/CapsuleRuntimeDxe/Arm/CapsuleReset.c
+++ b/MdeModulePkg/Universal/CapsuleRuntimeDxe/Arm/CapsuleReset.c
@@ -1,35 +1,35 @@
-/** @file
- ARM implementation of architecture specific routines related to
- PersistAcrossReset capsules
-
- Copyright (c) 2018, Linaro, Ltd. All rights reserved.<BR>
- Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
-
- SPDX-License-Identifier: BSD-2-Clause-Patent
-
-**/
-
-#include "CapsuleService.h"
-
-/**
- Whether the platform supports capsules that persist across reset. Note that
- some platforms only support such capsules at boot time.
-
- @return TRUE if a PersistAcrossReset capsule may be passed to UpdateCapsule()
- at this time
- FALSE otherwise
-**/
-BOOLEAN
-IsPersistAcrossResetCapsuleSupported (
- VOID
- )
-{
- //
- // ARM requires the capsule payload to be cleaned to the point of coherency
- // (PoC), but only permits doing so using cache maintenance instructions that
- // operate on virtual addresses. Since at runtime, we don't know the virtual
- // addresses of the data structures that make up the scatter/gather list, we
- // cannot perform the maintenance, and all we can do is give up.
- //
- return FeaturePcdGet (PcdSupportUpdateCapsuleReset) && !EfiAtRuntime ();
-}
+/** @file
+ ARM implementation of architecture specific routines related to
+ PersistAcrossReset capsules
+
+ Copyright (c) 2018, Linaro, Ltd. All rights reserved.<BR>
+ Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "CapsuleService.h"
+
+/**
+ Whether the platform supports capsules that persist across reset. Note that
+ some platforms only support such capsules at boot time.
+
+ @return TRUE if a PersistAcrossReset capsule may be passed to UpdateCapsule()
+ at this time
+ FALSE otherwise
+**/
+BOOLEAN
+IsPersistAcrossResetCapsuleSupported (
+ VOID
+ )
+{
+ //
+ // ARM requires the capsule payload to be cleaned to the point of coherency
+ // (PoC), but only permits doing so using cache maintenance instructions that
+ // operate on virtual addresses. Since at runtime, we don't know the virtual
+ // addresses of the data structures that make up the scatter/gather list, we
+ // cannot perform the maintenance, and all we can do is give up.
+ //
+ return FeaturePcdGet (PcdSupportUpdateCapsuleReset) && !EfiAtRuntime ();
+}
diff --git a/MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleCache.c b/MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleCache.c
index 5eab31df3c..9809adaafe 100644
--- a/MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleCache.c
+++ b/MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleCache.c
@@ -1,56 +1,56 @@
-/** @file
- Flush the cache is required for most architectures while do capsule
- update. It is not support at Runtime.
-
- Copyright (c) 2018, Linaro, Ltd. All rights reserved.<BR>
- Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
-
- SPDX-License-Identifier: BSD-2-Clause-Patent
-
-**/
-
-#include "CapsuleService.h"
-
-#include <Library/CacheMaintenanceLib.h>
-
-/**
- Writes Back a range of data cache lines covering a set of capsules in memory.
-
- Writes Back the data cache lines specified by ScatterGatherList.
-
- @param ScatterGatherList Physical address of the data structure that
- describes a set of capsules in memory
-
-**/
-VOID
-CapsuleCacheWriteBack (
- IN EFI_PHYSICAL_ADDRESS ScatterGatherList
- )
-{
- EFI_CAPSULE_BLOCK_DESCRIPTOR *Desc;
-
- if (!EfiAtRuntime ()) {
- Desc = (EFI_CAPSULE_BLOCK_DESCRIPTOR *)(UINTN)ScatterGatherList;
- do {
- WriteBackDataCacheRange (
- (VOID *)(UINTN)Desc,
- (UINTN)sizeof (*Desc)
- );
-
- if (Desc->Length > 0) {
- WriteBackDataCacheRange (
- (VOID *)(UINTN)Desc->Union.DataBlock,
- (UINTN)Desc->Length
- );
- Desc++;
- } else if (Desc->Union.ContinuationPointer > 0) {
- Desc = (EFI_CAPSULE_BLOCK_DESCRIPTOR *)(UINTN)Desc->Union.ContinuationPointer;
- }
- } while (Desc->Length > 0 || Desc->Union.ContinuationPointer > 0);
-
- WriteBackDataCacheRange (
- (VOID *)(UINTN)Desc,
- (UINTN)sizeof (*Desc)
- );
- }
-}
+/** @file
+ Flush the cache is required for most architectures while do capsule
+ update. It is not support at Runtime.
+
+ Copyright (c) 2018, Linaro, Ltd. All rights reserved.<BR>
+ Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "CapsuleService.h"
+
+#include <Library/CacheMaintenanceLib.h>
+
+/**
+ Writes Back a range of data cache lines covering a set of capsules in memory.
+
+ Writes Back the data cache lines specified by ScatterGatherList.
+
+ @param ScatterGatherList Physical address of the data structure that
+ describes a set of capsules in memory
+
+**/
+VOID
+CapsuleCacheWriteBack (
+ IN EFI_PHYSICAL_ADDRESS ScatterGatherList
+ )
+{
+ EFI_CAPSULE_BLOCK_DESCRIPTOR *Desc;
+
+ if (!EfiAtRuntime ()) {
+ Desc = (EFI_CAPSULE_BLOCK_DESCRIPTOR *)(UINTN)ScatterGatherList;
+ do {
+ WriteBackDataCacheRange (
+ (VOID *)(UINTN)Desc,
+ (UINTN)sizeof (*Desc)
+ );
+
+ if (Desc->Length > 0) {
+ WriteBackDataCacheRange (
+ (VOID *)(UINTN)Desc->Union.DataBlock,
+ (UINTN)Desc->Length
+ );
+ Desc++;
+ } else if (Desc->Union.ContinuationPointer > 0) {
+ Desc = (EFI_CAPSULE_BLOCK_DESCRIPTOR *)(UINTN)Desc->Union.ContinuationPointer;
+ }
+ } while (Desc->Length > 0 || Desc->Union.ContinuationPointer > 0);
+
+ WriteBackDataCacheRange (
+ (VOID *)(UINTN)Desc,
+ (UINTN)sizeof (*Desc)
+ );
+ }
+}
diff --git a/MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleCacheNull.c b/MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleCacheNull.c
index b795928ab6..302ea97c88 100644
--- a/MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleCacheNull.c
+++ b/MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleCacheNull.c
@@ -1,31 +1,31 @@
-/** @file
- Null function version of cache function.
-
- Copyright (c) 2018, Linaro, Ltd. All rights reserved.<BR>
- Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
-
- SPDX-License-Identifier: BSD-2-Clause-Patent
-
-**/
-
-#include "CapsuleService.h"
-
-#include <Library/CacheMaintenanceLib.h>
-
-/**
- Writes Back a range of data cache lines covering a set of capsules in memory.
-
- Writes Back the data cache lines specified by ScatterGatherList.
-
- Null version, do nothing.
-
- @param ScatterGatherList Physical address of the data structure that
- describes a set of capsules in memory
-
-**/
-VOID
-CapsuleCacheWriteBack (
- IN EFI_PHYSICAL_ADDRESS ScatterGatherList
- )
-{
-}
+/** @file
+ Null function version of cache function.
+
+ Copyright (c) 2018, Linaro, Ltd. All rights reserved.<BR>
+ Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "CapsuleService.h"
+
+#include <Library/CacheMaintenanceLib.h>
+
+/**
+ Writes Back a range of data cache lines covering a set of capsules in memory.
+
+ Writes Back the data cache lines specified by ScatterGatherList.
+
+ Null version, do nothing.
+
+ @param ScatterGatherList Physical address of the data structure that
+ describes a set of capsules in memory
+
+**/
+VOID
+CapsuleCacheWriteBack (
+ IN EFI_PHYSICAL_ADDRESS ScatterGatherList
+ )
+{
+}
diff --git a/MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleReset.c b/MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleReset.c
index f3cb6d5f8b..c6a1335f15 100644
--- a/MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleReset.c
+++ b/MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleReset.c
@@ -1,28 +1,28 @@
-/** @file
- Default implementation of architecture specific routines related to
- PersistAcrossReset capsules
-
- Copyright (c) 2018, Linaro, Ltd. All rights reserved.<BR>
- Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
-
- SPDX-License-Identifier: BSD-2-Clause-Patent
-
-**/
-
-#include "CapsuleService.h"
-
-/**
- Whether the platform supports capsules that persist across reset. Note that
- some platforms only support such capsules at boot time.
-
- @return TRUE if a PersistAcrossReset capsule may be passed to UpdateCapsule()
- at this time
- FALSE otherwise
-**/
-BOOLEAN
-IsPersistAcrossResetCapsuleSupported (
- VOID
- )
-{
- return FeaturePcdGet (PcdSupportUpdateCapsuleReset);
-}
+/** @file
+ Default implementation of architecture specific routines related to
+ PersistAcrossReset capsules
+
+ Copyright (c) 2018, Linaro, Ltd. All rights reserved.<BR>
+ Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "CapsuleService.h"
+
+/**
+ Whether the platform supports capsules that persist across reset. Note that
+ some platforms only support such capsules at boot time.
+
+ @return TRUE if a PersistAcrossReset capsule may be passed to UpdateCapsule()
+ at this time
+ FALSE otherwise
+**/
+BOOLEAN
+IsPersistAcrossResetCapsuleSupported (
+ VOID
+ )
+{
+ return FeaturePcdGet (PcdSupportUpdateCapsuleReset);
+}
diff --git a/MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleRuntimeDxe.inf b/MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleRuntimeDxe.inf
index 601eada170..5a0b762c5e 100644
--- a/MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleRuntimeDxe.inf
+++ b/MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleRuntimeDxe.inf
@@ -1,109 +1,109 @@
-## @file
-# Capsule Runtime Driver produces two UEFI capsule runtime services: (UpdateCapsule, QueryCapsuleCapabilities).
-#
-# It installs the Capsule Architectural Protocol defined in PI1.0a to signify
-# the capsule runtime services are ready.
-#
-# Copyright (c) 2006 - 2020, Intel Corporation. All rights reserved.<BR>
-# Copyright (c) 2020, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
-# Copyright (c) 2022, Loongson Technology Corporation Limited. All rights reserved.<BR>
-# SPDX-License-Identifier: BSD-2-Clause-Patent
-#
-##
-
-[Defines]
- INF_VERSION = 0x00010005
- BASE_NAME = CapsuleRuntimeDxe
- MODULE_UNI_FILE = CapsuleRuntimeDxe.uni
- FILE_GUID = 42857F0A-13F2-4B21-8A23-53D3F714B840
- MODULE_TYPE = DXE_RUNTIME_DRIVER
- VERSION_STRING = 1.0
- ENTRY_POINT = CapsuleServiceInitialize
-
-#
-# The following information is for reference only and not required by the build tools.
-#
-# VALID_ARCHITECTURES = IA32 X64 EBC ARM AARCH64 RISCV64 LOONGARCH64
-#
-
-[Sources]
- CapsuleService.c
- CapsuleService.h
-
-[Sources.Ia32, Sources.EBC, Sources.ARM, Sources.AARCH64, Sources.RISCV64, Sources.LOONGARCH64]
- SaveLongModeContext.c
-
-[Sources.Ia32, Sources.X64, Sources.ARM, Sources.AARCH64, Sources.RISCV64, Sources.LOONGARCH64]
- CapsuleCache.c
-
-[Sources.Ia32, Sources.X64, Sources.EBC, Sources.RISCV64, Sources.LOONGARCH64]
- CapsuleReset.c
-
-[Sources.ARM, Sources.AARCH64]
- Arm/CapsuleReset.c
-
-[Sources.EBC]
- CapsuleCacheNull.c
-
-[Sources.X64]
- X64/SaveLongModeContext.c
-
-[Packages]
- MdePkg/MdePkg.dec
- MdeModulePkg/MdeModulePkg.dec
-
-[LibraryClasses]
- UefiBootServicesTableLib
- PcdLib
- DebugLib
- UefiRuntimeServicesTableLib
- UefiDriverEntryPoint
- CapsuleLib
- UefiRuntimeLib
- BaseLib
- PrintLib
- BaseMemoryLib
- CacheMaintenanceLib
-
-[LibraryClasses.X64]
- UefiLib
- BaseMemoryLib
-
-[Guids]
- ## SOMETIMES_PRODUCES ## Variable:L"CapsuleUpdateData" # (Process across reset capsule image) for capsule updated data
- ## SOMETIMES_PRODUCES ## Variable:L"CapsuleLongModeBuffer" # The long mode buffer used by IA32 Capsule PEIM to call X64 CapsuleCoalesce code to handle >4GB capsule blocks
- gEfiCapsuleVendorGuid
- gEfiFmpCapsuleGuid ## SOMETIMES_CONSUMES ## GUID # FMP capsule GUID
-
-[Protocols]
- gEfiCapsuleArchProtocolGuid ## PRODUCES
-
-[Protocols.X64]
- ## UNDEFINED ## NOTIFY
- ## SOMETIMES_CONSUMES
- gEdkiiVariableLockProtocolGuid
-
-[FeaturePcd]
- gEfiMdeModulePkgTokenSpaceGuid.PcdSupportUpdateCapsuleReset ## CONSUMES
- gEfiMdeModulePkgTokenSpaceGuid.PcdSupportProcessCapsuleAtRuntime ## CONSUMES
-
-[FeaturePcd.X64]
- gEfiMdeModulePkgTokenSpaceGuid.PcdDxeIplSwitchToLongMode ## CONSUMES
-
-[Pcd]
- gEfiMdeModulePkgTokenSpaceGuid.PcdMaxSizeNonPopulateCapsule ## SOMETIMES_CONSUMES
- gEfiMdeModulePkgTokenSpaceGuid.PcdMaxSizePopulateCapsule ## SOMETIMES_CONSUMES # Populate Image requires reset support.
- gEfiMdeModulePkgTokenSpaceGuid.PcdCapsuleInRamSupport ## CONSUMES
-
-[Pcd.X64]
- gEfiMdeModulePkgTokenSpaceGuid.PcdCapsulePeiLongModeStackSize ## SOMETIMES_CONSUMES
- gEfiMdeModulePkgTokenSpaceGuid.PcdUse1GPageTable ## SOMETIMES_CONSUMES
-
-[Depex]
- gEfiVariableWriteArchProtocolGuid # Depends on variable write functionality to produce capsule data variable
-
-# [Hob.X64]
-# UNDEFINED ## SOMETIMES_CONSUMES # CPU
-
-[UserExtensions.TianoCore."ExtraFiles"]
- CapsuleRuntimeDxeExtra.uni
+## @file
+# Capsule Runtime Driver produces two UEFI capsule runtime services: (UpdateCapsule, QueryCapsuleCapabilities).
+#
+# It installs the Capsule Architectural Protocol defined in PI1.0a to signify
+# the capsule runtime services are ready.
+#
+# Copyright (c) 2006 - 2020, Intel Corporation. All rights reserved.<BR>
+# Copyright (c) 2020, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
+# Copyright (c) 2022, Loongson Technology Corporation Limited. All rights reserved.<BR>
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = CapsuleRuntimeDxe
+ MODULE_UNI_FILE = CapsuleRuntimeDxe.uni
+ FILE_GUID = 42857F0A-13F2-4B21-8A23-53D3F714B840
+ MODULE_TYPE = DXE_RUNTIME_DRIVER
+ VERSION_STRING = 1.0
+ ENTRY_POINT = CapsuleServiceInitialize
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64 EBC ARM AARCH64 RISCV64 LOONGARCH64
+#
+
+[Sources]
+ CapsuleService.c
+ CapsuleService.h
+
+[Sources.Ia32, Sources.EBC, Sources.ARM, Sources.AARCH64, Sources.RISCV64, Sources.LOONGARCH64]
+ SaveLongModeContext.c
+
+[Sources.Ia32, Sources.X64, Sources.ARM, Sources.AARCH64, Sources.RISCV64, Sources.LOONGARCH64]
+ CapsuleCache.c
+
+[Sources.Ia32, Sources.X64, Sources.EBC, Sources.RISCV64, Sources.LOONGARCH64]
+ CapsuleReset.c
+
+[Sources.ARM, Sources.AARCH64]
+ Arm/CapsuleReset.c
+
+[Sources.EBC]
+ CapsuleCacheNull.c
+
+[Sources.X64]
+ X64/SaveLongModeContext.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+
+[LibraryClasses]
+ UefiBootServicesTableLib
+ PcdLib
+ DebugLib
+ UefiRuntimeServicesTableLib
+ UefiDriverEntryPoint
+ CapsuleLib
+ UefiRuntimeLib
+ BaseLib
+ PrintLib
+ BaseMemoryLib
+ CacheMaintenanceLib
+
+[LibraryClasses.X64]
+ UefiLib
+ BaseMemoryLib
+
+[Guids]
+ ## SOMETIMES_PRODUCES ## Variable:L"CapsuleUpdateData" # (Process across reset capsule image) for capsule updated data
+ ## SOMETIMES_PRODUCES ## Variable:L"CapsuleLongModeBuffer" # The long mode buffer used by IA32 Capsule PEIM to call X64 CapsuleCoalesce code to handle >4GB capsule blocks
+ gEfiCapsuleVendorGuid
+ gEfiFmpCapsuleGuid ## SOMETIMES_CONSUMES ## GUID # FMP capsule GUID
+
+[Protocols]
+ gEfiCapsuleArchProtocolGuid ## PRODUCES
+
+[Protocols.X64]
+ ## UNDEFINED ## NOTIFY
+ ## SOMETIMES_CONSUMES
+ gEdkiiVariableLockProtocolGuid
+
+[FeaturePcd]
+ gEfiMdeModulePkgTokenSpaceGuid.PcdSupportUpdateCapsuleReset ## CONSUMES
+ gEfiMdeModulePkgTokenSpaceGuid.PcdSupportProcessCapsuleAtRuntime ## CONSUMES
+
+[FeaturePcd.X64]
+ gEfiMdeModulePkgTokenSpaceGuid.PcdDxeIplSwitchToLongMode ## CONSUMES
+
+[Pcd]
+ gEfiMdeModulePkgTokenSpaceGuid.PcdMaxSizeNonPopulateCapsule ## SOMETIMES_CONSUMES
+ gEfiMdeModulePkgTokenSpaceGuid.PcdMaxSizePopulateCapsule ## SOMETIMES_CONSUMES # Populate Image requires reset support.
+ gEfiMdeModulePkgTokenSpaceGuid.PcdCapsuleInRamSupport ## CONSUMES
+
+[Pcd.X64]
+ gEfiMdeModulePkgTokenSpaceGuid.PcdCapsulePeiLongModeStackSize ## SOMETIMES_CONSUMES
+ gEfiMdeModulePkgTokenSpaceGuid.PcdUse1GPageTable ## SOMETIMES_CONSUMES
+
+[Depex]
+ gEfiVariableWriteArchProtocolGuid # Depends on variable write functionality to produce capsule data variable
+
+# [Hob.X64]
+# UNDEFINED ## SOMETIMES_CONSUMES # CPU
+
+[UserExtensions.TianoCore."ExtraFiles"]
+ CapsuleRuntimeDxeExtra.uni
diff --git a/MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleRuntimeDxe.uni b/MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleRuntimeDxe.uni
index b161af45c1..64c7b9d5d0 100644
--- a/MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleRuntimeDxe.uni
+++ b/MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleRuntimeDxe.uni
@@ -1,17 +1,17 @@
-// /** @file
-// Capsule Runtime Driver produces two UEFI capsule runtime services: (UpdateCapsule, QueryCapsuleCapabilities).
-//
-// It installs the Capsule Architectural Protocol defined in PI1.0a to signify
-// the capsule runtime services are ready.
-//
-// Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
-//
-// SPDX-License-Identifier: BSD-2-Clause-Patent
-//
-// **/
-
-
-#string STR_MODULE_ABSTRACT #language en-US "Produces two UEFI capsule runtime services: (UpdateCapsule, QueryCapsuleCapabilities)"
-
-#string STR_MODULE_DESCRIPTION #language en-US "It installs the Capsule Architectural Protocol defined in PI1.0a to signify the capsule runtime services are ready."
-
+// /** @file
+// Capsule Runtime Driver produces two UEFI capsule runtime services: (UpdateCapsule, QueryCapsuleCapabilities).
+//
+// It installs the Capsule Architectural Protocol defined in PI1.0a to signify
+// the capsule runtime services are ready.
+//
+// Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
+//
+// SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+// **/
+
+
+#string STR_MODULE_ABSTRACT #language en-US "Produces two UEFI capsule runtime services: (UpdateCapsule, QueryCapsuleCapabilities)"
+
+#string STR_MODULE_DESCRIPTION #language en-US "It installs the Capsule Architectural Protocol defined in PI1.0a to signify the capsule runtime services are ready."
+
diff --git a/MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleRuntimeDxeExtra.uni b/MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleRuntimeDxeExtra.uni
index f97bfd64ab..bcefef39b0 100644
--- a/MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleRuntimeDxeExtra.uni
+++ b/MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleRuntimeDxeExtra.uni
@@ -1,14 +1,14 @@
-// /** @file
-// CapsuleRuntimeDxe Localized Strings and Content
-//
-// Copyright (c) 2013 - 2018, Intel Corporation. All rights reserved.<BR>
-//
-// SPDX-License-Identifier: BSD-2-Clause-Patent
-//
-// **/
-
-#string STR_PROPERTIES_MODULE_NAME
-#language en-US
-"Runtime Firmware Update DXE Driver"
-
-
+// /** @file
+// CapsuleRuntimeDxe Localized Strings and Content
+//
+// Copyright (c) 2013 - 2018, Intel Corporation. All rights reserved.<BR>
+//
+// SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+// **/
+
+#string STR_PROPERTIES_MODULE_NAME
+#language en-US
+"Runtime Firmware Update DXE Driver"
+
+
diff --git a/MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleService.c b/MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleService.c
index f8047c23e1..c7b5b3cc7a 100644
--- a/MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleService.c
+++ b/MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleService.c
@@ -1,416 +1,416 @@
-/** @file
- Capsule Runtime Driver produces two UEFI capsule runtime services.
- (UpdateCapsule, QueryCapsuleCapabilities)
- It installs the Capsule Architectural Protocol defined in PI1.0a to signify
- the capsule runtime services are ready.
-
-Copyright (c) 2006 - 2020, Intel Corporation. All rights reserved.<BR>
-SPDX-License-Identifier: BSD-2-Clause-Patent
-
-**/
-
-#include "CapsuleService.h"
-
-//
-// Handle for the installation of Capsule Architecture Protocol.
-//
-EFI_HANDLE mNewHandle = NULL;
-
-//
-// The times of calling UpdateCapsule ()
-//
-UINTN mTimes = 0;
-
-UINT32 mMaxSizePopulateCapsule = 0;
-UINT32 mMaxSizeNonPopulateCapsule = 0;
-
-/**
- Passes capsules to the firmware with both virtual and physical mapping. Depending on the intended
- consumption, the firmware may process the capsule immediately. If the payload should persist
- across a system reset, the reset value returned from EFI_QueryCapsuleCapabilities must
- be passed into ResetSystem() and will cause the capsule to be processed by the firmware as
- part of the reset process.
-
- @param CapsuleHeaderArray Virtual pointer to an array of virtual pointers to the capsules
- being passed into update capsule.
- @param CapsuleCount Number of pointers to EFI_CAPSULE_HEADER in
- CaspuleHeaderArray.
- @param ScatterGatherList Physical pointer to a set of
- EFI_CAPSULE_BLOCK_DESCRIPTOR that describes the
- location in physical memory of a set of capsules.
-
- @retval EFI_SUCCESS Valid capsule was passed. If
- CAPSULE_FLAGS_PERSIT_ACROSS_RESET is not set, the
- capsule has been successfully processed by the firmware.
- @retval EFI_DEVICE_ERROR The capsule update was started, but failed due to a device error.
- @retval EFI_INVALID_PARAMETER CapsuleSize is NULL, or an incompatible set of flags were
- set in the capsule header.
- @retval EFI_INVALID_PARAMETER CapsuleCount is Zero.
- @retval EFI_INVALID_PARAMETER For across reset capsule image, ScatterGatherList is NULL.
- @retval EFI_UNSUPPORTED CapsuleImage is not recognized by the firmware.
- @retval EFI_OUT_OF_RESOURCES When ExitBootServices() has been previously called this error indicates the capsule
- is compatible with this platform but is not capable of being submitted or processed
- in runtime. The caller may resubmit the capsule prior to ExitBootServices().
- @retval EFI_OUT_OF_RESOURCES When ExitBootServices() has not been previously called then this error indicates
- the capsule is compatible with this platform but there are insufficient resources to process.
- @retval EFI_UNSUPPORTED This call is not supported by this platform at the time the call is made.
- The platform should describe this runtime service as unsupported at runtime
- via an EFI_RT_PROPERTIES_TABLE configuration table.
-
-**/
-EFI_STATUS
-EFIAPI
-UpdateCapsule (
- IN EFI_CAPSULE_HEADER **CapsuleHeaderArray,
- IN UINTN CapsuleCount,
- IN EFI_PHYSICAL_ADDRESS ScatterGatherList OPTIONAL
- )
-{
- UINTN ArrayNumber;
- EFI_STATUS Status;
- EFI_CAPSULE_HEADER *CapsuleHeader;
- BOOLEAN NeedReset;
- BOOLEAN InitiateReset;
- CHAR16 CapsuleVarName[30];
- CHAR16 *TempVarName;
-
- //
- // Check if platform support Capsule In RAM or not.
- // Platform could choose to drop CapsulePei/CapsuleX64 and do not support Capsule In RAM.
- //
- if (!PcdGetBool (PcdCapsuleInRamSupport)) {
- return EFI_UNSUPPORTED;
- }
-
- //
- // Capsule Count can't be less than one.
- //
- if (CapsuleCount < 1) {
- return EFI_INVALID_PARAMETER;
- }
-
- NeedReset = FALSE;
- InitiateReset = FALSE;
- CapsuleHeader = NULL;
- CapsuleVarName[0] = 0;
-
- for (ArrayNumber = 0; ArrayNumber < CapsuleCount; ArrayNumber++) {
- //
- // A capsule which has the CAPSULE_FLAGS_POPULATE_SYSTEM_TABLE flag must have
- // CAPSULE_FLAGS_PERSIST_ACROSS_RESET set in its header as well.
- //
- CapsuleHeader = CapsuleHeaderArray[ArrayNumber];
- if ((CapsuleHeader->Flags & (CAPSULE_FLAGS_PERSIST_ACROSS_RESET | CAPSULE_FLAGS_POPULATE_SYSTEM_TABLE)) == CAPSULE_FLAGS_POPULATE_SYSTEM_TABLE) {
- return EFI_INVALID_PARAMETER;
- }
-
- //
- // A capsule which has the CAPSULE_FLAGS_INITIATE_RESET flag must have
- // CAPSULE_FLAGS_PERSIST_ACROSS_RESET set in its header as well.
- //
- if ((CapsuleHeader->Flags & (CAPSULE_FLAGS_PERSIST_ACROSS_RESET | CAPSULE_FLAGS_INITIATE_RESET)) == CAPSULE_FLAGS_INITIATE_RESET) {
- return EFI_INVALID_PARAMETER;
- }
-
- //
- // Check FMP capsule flag
- //
- if ( CompareGuid (&CapsuleHeader->CapsuleGuid, &gEfiFmpCapsuleGuid)
- && ((CapsuleHeader->Flags & CAPSULE_FLAGS_POPULATE_SYSTEM_TABLE) != 0))
- {
- return EFI_INVALID_PARAMETER;
- }
-
- //
- // Check Capsule image without populate flag by firmware support capsule function
- //
- if ((CapsuleHeader->Flags & CAPSULE_FLAGS_POPULATE_SYSTEM_TABLE) == 0) {
- Status = SupportCapsuleImage (CapsuleHeader);
- if (EFI_ERROR (Status)) {
- return Status;
- }
- }
- }
-
- //
- // Walk through all capsules, record whether there is a capsule needs reset
- // or initiate reset. And then process capsules which has no reset flag directly.
- //
- for (ArrayNumber = 0; ArrayNumber < CapsuleCount; ArrayNumber++) {
- CapsuleHeader = CapsuleHeaderArray[ArrayNumber];
- //
- // Here should be in the boot-time for non-reset capsule image
- // Platform specific update for the non-reset capsule image.
- //
- if ((CapsuleHeader->Flags & CAPSULE_FLAGS_PERSIST_ACROSS_RESET) == 0) {
- if (EfiAtRuntime () && !FeaturePcdGet (PcdSupportProcessCapsuleAtRuntime)) {
- Status = EFI_OUT_OF_RESOURCES;
- } else {
- Status = ProcessCapsuleImage (CapsuleHeader);
- }
-
- if (EFI_ERROR (Status)) {
- return Status;
- }
- } else {
- NeedReset = TRUE;
- if ((CapsuleHeader->Flags & CAPSULE_FLAGS_INITIATE_RESET) != 0) {
- InitiateReset = TRUE;
- }
- }
- }
-
- //
- // After launching all capsules who has no reset flag, if no more capsules claims
- // for a system reset just return.
- //
- if (!NeedReset) {
- return EFI_SUCCESS;
- }
-
- //
- // ScatterGatherList is only referenced if the capsules are defined to persist across
- // system reset.
- //
- if (ScatterGatherList == (EFI_PHYSICAL_ADDRESS)(UINTN)NULL) {
- return EFI_INVALID_PARAMETER;
- }
-
- //
- // Check if the platform supports update capsule across a system reset
- //
- if (!IsPersistAcrossResetCapsuleSupported ()) {
- return EFI_UNSUPPORTED;
- }
-
- CapsuleCacheWriteBack (ScatterGatherList);
-
- //
- // Construct variable name CapsuleUpdateData, CapsuleUpdateData1, CapsuleUpdateData2...
- // if user calls UpdateCapsule multiple times.
- //
- StrCpyS (CapsuleVarName, sizeof (CapsuleVarName)/sizeof (CHAR16), EFI_CAPSULE_VARIABLE_NAME);
- TempVarName = CapsuleVarName + StrLen (CapsuleVarName);
- if (mTimes > 0) {
- UnicodeValueToStringS (
- TempVarName,
- sizeof (CapsuleVarName) - ((UINTN)TempVarName - (UINTN)CapsuleVarName),
- 0,
- mTimes,
- 0
- );
- }
-
- //
- // ScatterGatherList is only referenced if the capsules are defined to persist across
- // system reset. Set its value into NV storage to let pre-boot driver to pick it up
- // after coming through a system reset.
- //
- Status = EfiSetVariable (
- CapsuleVarName,
- &gEfiCapsuleVendorGuid,
- EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS,
- sizeof (UINTN),
- (VOID *)&ScatterGatherList
- );
- if (!EFI_ERROR (Status)) {
- //
- // Variable has been set successfully, increase variable index.
- //
- mTimes++;
- if (InitiateReset) {
- //
- // Firmware that encounters a capsule which has the CAPSULE_FLAGS_INITIATE_RESET Flag set in its header
- // will initiate a reset of the platform which is compatible with the passed-in capsule request and will
- // not return back to the caller.
- //
- EfiResetSystem (EfiResetWarm, EFI_SUCCESS, 0, NULL);
- }
- }
-
- return Status;
-}
-
-/**
- Returns if the capsule can be supported via UpdateCapsule().
- Notice: When PcdCapsuleInRamSupport is unsupported, even this routine returns a valid answer,
- the capsule still is unsupported via UpdateCapsule().
-
- @param CapsuleHeaderArray Virtual pointer to an array of virtual pointers to the capsules
- being passed into update capsule.
- @param CapsuleCount Number of pointers to EFI_CAPSULE_HEADER in
- CaspuleHeaderArray.
- @param MaxiumCapsuleSize On output the maximum size that UpdateCapsule() can
- support as an argument to UpdateCapsule() via
- CapsuleHeaderArray and ScatterGatherList.
- @param ResetType Returns the type of reset required for the capsule update.
-
- @retval EFI_SUCCESS Valid answer returned.
- @retval EFI_UNSUPPORTED The capsule image is not supported on this platform, and
- MaximumCapsuleSize and ResetType are undefined.
- @retval EFI_INVALID_PARAMETER MaximumCapsuleSize is NULL, or ResetTyep is NULL,
- Or CapsuleCount is Zero, or CapsuleImage is not valid.
- @retval EFI_OUT_OF_RESOURCES When ExitBootServices() has been previously called this error indicates
- the capsule is compatible with this platform but is not capable of
- being submitted or processed in runtime.
- The caller may resubmit the capsule prior to ExitBootServices().
- @retval EFI_OUT_OF_RESOURCES When ExitBootServices() has not been previously called then this error
- indicates the capsule is compatible with this platform but there are
- insufficient resources to process.
- @retval EFI_UNSUPPORTED This call is not supported by this platform at the time the call is made.
- The platform should describe this runtime service as unsupported at runtime
- via an EFI_RT_PROPERTIES_TABLE configuration table.
-
-**/
-EFI_STATUS
-EFIAPI
-QueryCapsuleCapabilities (
- IN EFI_CAPSULE_HEADER **CapsuleHeaderArray,
- IN UINTN CapsuleCount,
- OUT UINT64 *MaxiumCapsuleSize,
- OUT EFI_RESET_TYPE *ResetType
- )
-{
- EFI_STATUS Status;
- UINTN ArrayNumber;
- EFI_CAPSULE_HEADER *CapsuleHeader;
- BOOLEAN NeedReset;
-
- //
- // Capsule Count can't be less than one.
- //
- if (CapsuleCount < 1) {
- return EFI_INVALID_PARAMETER;
- }
-
- //
- // Check whether input parameter is valid
- //
- if ((MaxiumCapsuleSize == NULL) || (ResetType == NULL)) {
- return EFI_INVALID_PARAMETER;
- }
-
- CapsuleHeader = NULL;
- NeedReset = FALSE;
-
- for (ArrayNumber = 0; ArrayNumber < CapsuleCount; ArrayNumber++) {
- CapsuleHeader = CapsuleHeaderArray[ArrayNumber];
- //
- // A capsule which has the CAPSULE_FLAGS_POPULATE_SYSTEM_TABLE flag must have
- // CAPSULE_FLAGS_PERSIST_ACROSS_RESET set in its header as well.
- //
- if ((CapsuleHeader->Flags & (CAPSULE_FLAGS_PERSIST_ACROSS_RESET | CAPSULE_FLAGS_POPULATE_SYSTEM_TABLE)) == CAPSULE_FLAGS_POPULATE_SYSTEM_TABLE) {
- return EFI_INVALID_PARAMETER;
- }
-
- //
- // A capsule which has the CAPSULE_FLAGS_INITIATE_RESET flag must have
- // CAPSULE_FLAGS_PERSIST_ACROSS_RESET set in its header as well.
- //
- if ((CapsuleHeader->Flags & (CAPSULE_FLAGS_PERSIST_ACROSS_RESET | CAPSULE_FLAGS_INITIATE_RESET)) == CAPSULE_FLAGS_INITIATE_RESET) {
- return EFI_INVALID_PARAMETER;
- }
-
- //
- // Check FMP capsule flag
- //
- if ( CompareGuid (&CapsuleHeader->CapsuleGuid, &gEfiFmpCapsuleGuid)
- && ((CapsuleHeader->Flags & CAPSULE_FLAGS_POPULATE_SYSTEM_TABLE) != 0))
- {
- return EFI_INVALID_PARAMETER;
- }
-
- //
- // Check Capsule image without populate flag is supported by firmware
- //
- if ((CapsuleHeader->Flags & CAPSULE_FLAGS_POPULATE_SYSTEM_TABLE) == 0) {
- Status = SupportCapsuleImage (CapsuleHeader);
- if (EFI_ERROR (Status)) {
- return Status;
- }
- }
- }
-
- //
- // Find out whether there is any capsule defined to persist across system reset.
- //
- for (ArrayNumber = 0; ArrayNumber < CapsuleCount; ArrayNumber++) {
- CapsuleHeader = CapsuleHeaderArray[ArrayNumber];
- if ((CapsuleHeader->Flags & CAPSULE_FLAGS_PERSIST_ACROSS_RESET) != 0) {
- NeedReset = TRUE;
- break;
- }
- }
-
- if (NeedReset) {
- //
- // Check if the platform supports update capsule across a system reset
- //
- if (!IsPersistAcrossResetCapsuleSupported ()) {
- return EFI_UNSUPPORTED;
- }
-
- *ResetType = EfiResetWarm;
- *MaxiumCapsuleSize = (UINT64)mMaxSizePopulateCapsule;
- } else {
- //
- // For non-reset capsule image.
- //
- *ResetType = EfiResetCold;
- *MaxiumCapsuleSize = (UINT64)mMaxSizeNonPopulateCapsule;
- }
-
- return EFI_SUCCESS;
-}
-
-/**
-
- This code installs UEFI capsule runtime service.
-
- @param ImageHandle The firmware allocated handle for the EFI image.
- @param SystemTable A pointer to the EFI System Table.
-
- @retval EFI_SUCCESS UEFI Capsule Runtime Services are installed successfully.
-
-**/
-EFI_STATUS
-EFIAPI
-CapsuleServiceInitialize (
- IN EFI_HANDLE ImageHandle,
- IN EFI_SYSTEM_TABLE *SystemTable
- )
-{
- EFI_STATUS Status;
-
- mMaxSizePopulateCapsule = PcdGet32 (PcdMaxSizePopulateCapsule);
- mMaxSizeNonPopulateCapsule = PcdGet32 (PcdMaxSizeNonPopulateCapsule);
-
- //
- // When PEI phase is IA32, DXE phase is X64, it is possible that capsule data are
- // put above 4GB, so capsule PEI will transfer to long mode to get capsule data.
- // The page table and stack is used to transfer processor mode from IA32 to long mode.
- // Create the base address of page table and stack, and save them into variable.
- // This is not needed when capsule with reset type is not supported.
- //
- SaveLongModeContext ();
-
- //
- // Install capsule runtime services into UEFI runtime service tables.
- //
- gRT->UpdateCapsule = UpdateCapsule;
- gRT->QueryCapsuleCapabilities = QueryCapsuleCapabilities;
-
- //
- // Install the Capsule Architectural Protocol on a new handle
- // to signify the capsule runtime services are ready.
- //
- Status = gBS->InstallMultipleProtocolInterfaces (
- &mNewHandle,
- &gEfiCapsuleArchProtocolGuid,
- NULL,
- NULL
- );
- ASSERT_EFI_ERROR (Status);
-
- return Status;
-}
+/** @file
+ Capsule Runtime Driver produces two UEFI capsule runtime services.
+ (UpdateCapsule, QueryCapsuleCapabilities)
+ It installs the Capsule Architectural Protocol defined in PI1.0a to signify
+ the capsule runtime services are ready.
+
+Copyright (c) 2006 - 2020, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "CapsuleService.h"
+
+//
+// Handle for the installation of Capsule Architecture Protocol.
+//
+EFI_HANDLE mNewHandle = NULL;
+
+//
+// The times of calling UpdateCapsule ()
+//
+UINTN mTimes = 0;
+
+UINT32 mMaxSizePopulateCapsule = 0;
+UINT32 mMaxSizeNonPopulateCapsule = 0;
+
+/**
+ Passes capsules to the firmware with both virtual and physical mapping. Depending on the intended
+ consumption, the firmware may process the capsule immediately. If the payload should persist
+ across a system reset, the reset value returned from EFI_QueryCapsuleCapabilities must
+ be passed into ResetSystem() and will cause the capsule to be processed by the firmware as
+ part of the reset process.
+
+ @param CapsuleHeaderArray Virtual pointer to an array of virtual pointers to the capsules
+ being passed into update capsule.
+ @param CapsuleCount Number of pointers to EFI_CAPSULE_HEADER in
+ CaspuleHeaderArray.
+ @param ScatterGatherList Physical pointer to a set of
+ EFI_CAPSULE_BLOCK_DESCRIPTOR that describes the
+ location in physical memory of a set of capsules.
+
+ @retval EFI_SUCCESS Valid capsule was passed. If
+ CAPSULE_FLAGS_PERSIT_ACROSS_RESET is not set, the
+ capsule has been successfully processed by the firmware.
+ @retval EFI_DEVICE_ERROR The capsule update was started, but failed due to a device error.
+ @retval EFI_INVALID_PARAMETER CapsuleSize is NULL, or an incompatible set of flags were
+ set in the capsule header.
+ @retval EFI_INVALID_PARAMETER CapsuleCount is Zero.
+ @retval EFI_INVALID_PARAMETER For across reset capsule image, ScatterGatherList is NULL.
+ @retval EFI_UNSUPPORTED CapsuleImage is not recognized by the firmware.
+ @retval EFI_OUT_OF_RESOURCES When ExitBootServices() has been previously called this error indicates the capsule
+ is compatible with this platform but is not capable of being submitted or processed
+ in runtime. The caller may resubmit the capsule prior to ExitBootServices().
+ @retval EFI_OUT_OF_RESOURCES When ExitBootServices() has not been previously called then this error indicates
+ the capsule is compatible with this platform but there are insufficient resources to process.
+ @retval EFI_UNSUPPORTED This call is not supported by this platform at the time the call is made.
+ The platform should describe this runtime service as unsupported at runtime
+ via an EFI_RT_PROPERTIES_TABLE configuration table.
+
+**/
+EFI_STATUS
+EFIAPI
+UpdateCapsule (
+ IN EFI_CAPSULE_HEADER **CapsuleHeaderArray,
+ IN UINTN CapsuleCount,
+ IN EFI_PHYSICAL_ADDRESS ScatterGatherList OPTIONAL
+ )
+{
+ UINTN ArrayNumber;
+ EFI_STATUS Status;
+ EFI_CAPSULE_HEADER *CapsuleHeader;
+ BOOLEAN NeedReset;
+ BOOLEAN InitiateReset;
+ CHAR16 CapsuleVarName[30];
+ CHAR16 *TempVarName;
+
+ //
+ // Check if platform support Capsule In RAM or not.
+ // Platform could choose to drop CapsulePei/CapsuleX64 and do not support Capsule In RAM.
+ //
+ if (!PcdGetBool (PcdCapsuleInRamSupport)) {
+ return EFI_UNSUPPORTED;
+ }
+
+ //
+ // Capsule Count can't be less than one.
+ //
+ if (CapsuleCount < 1) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ NeedReset = FALSE;
+ InitiateReset = FALSE;
+ CapsuleHeader = NULL;
+ CapsuleVarName[0] = 0;
+
+ for (ArrayNumber = 0; ArrayNumber < CapsuleCount; ArrayNumber++) {
+ //
+ // A capsule which has the CAPSULE_FLAGS_POPULATE_SYSTEM_TABLE flag must have
+ // CAPSULE_FLAGS_PERSIST_ACROSS_RESET set in its header as well.
+ //
+ CapsuleHeader = CapsuleHeaderArray[ArrayNumber];
+ if ((CapsuleHeader->Flags & (CAPSULE_FLAGS_PERSIST_ACROSS_RESET | CAPSULE_FLAGS_POPULATE_SYSTEM_TABLE)) == CAPSULE_FLAGS_POPULATE_SYSTEM_TABLE) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // A capsule which has the CAPSULE_FLAGS_INITIATE_RESET flag must have
+ // CAPSULE_FLAGS_PERSIST_ACROSS_RESET set in its header as well.
+ //
+ if ((CapsuleHeader->Flags & (CAPSULE_FLAGS_PERSIST_ACROSS_RESET | CAPSULE_FLAGS_INITIATE_RESET)) == CAPSULE_FLAGS_INITIATE_RESET) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // Check FMP capsule flag
+ //
+ if ( CompareGuid (&CapsuleHeader->CapsuleGuid, &gEfiFmpCapsuleGuid)
+ && ((CapsuleHeader->Flags & CAPSULE_FLAGS_POPULATE_SYSTEM_TABLE) != 0))
+ {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // Check Capsule image without populate flag by firmware support capsule function
+ //
+ if ((CapsuleHeader->Flags & CAPSULE_FLAGS_POPULATE_SYSTEM_TABLE) == 0) {
+ Status = SupportCapsuleImage (CapsuleHeader);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ }
+ }
+
+ //
+ // Walk through all capsules, record whether there is a capsule needs reset
+ // or initiate reset. And then process capsules which has no reset flag directly.
+ //
+ for (ArrayNumber = 0; ArrayNumber < CapsuleCount; ArrayNumber++) {
+ CapsuleHeader = CapsuleHeaderArray[ArrayNumber];
+ //
+ // Here should be in the boot-time for non-reset capsule image
+ // Platform specific update for the non-reset capsule image.
+ //
+ if ((CapsuleHeader->Flags & CAPSULE_FLAGS_PERSIST_ACROSS_RESET) == 0) {
+ if (EfiAtRuntime () && !FeaturePcdGet (PcdSupportProcessCapsuleAtRuntime)) {
+ Status = EFI_OUT_OF_RESOURCES;
+ } else {
+ Status = ProcessCapsuleImage (CapsuleHeader);
+ }
+
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ } else {
+ NeedReset = TRUE;
+ if ((CapsuleHeader->Flags & CAPSULE_FLAGS_INITIATE_RESET) != 0) {
+ InitiateReset = TRUE;
+ }
+ }
+ }
+
+ //
+ // After launching all capsules who has no reset flag, if no more capsules claims
+ // for a system reset just return.
+ //
+ if (!NeedReset) {
+ return EFI_SUCCESS;
+ }
+
+ //
+ // ScatterGatherList is only referenced if the capsules are defined to persist across
+ // system reset.
+ //
+ if (ScatterGatherList == (EFI_PHYSICAL_ADDRESS)(UINTN)NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // Check if the platform supports update capsule across a system reset
+ //
+ if (!IsPersistAcrossResetCapsuleSupported ()) {
+ return EFI_UNSUPPORTED;
+ }
+
+ CapsuleCacheWriteBack (ScatterGatherList);
+
+ //
+ // Construct variable name CapsuleUpdateData, CapsuleUpdateData1, CapsuleUpdateData2...
+ // if user calls UpdateCapsule multiple times.
+ //
+ StrCpyS (CapsuleVarName, sizeof (CapsuleVarName)/sizeof (CHAR16), EFI_CAPSULE_VARIABLE_NAME);
+ TempVarName = CapsuleVarName + StrLen (CapsuleVarName);
+ if (mTimes > 0) {
+ UnicodeValueToStringS (
+ TempVarName,
+ sizeof (CapsuleVarName) - ((UINTN)TempVarName - (UINTN)CapsuleVarName),
+ 0,
+ mTimes,
+ 0
+ );
+ }
+
+ //
+ // ScatterGatherList is only referenced if the capsules are defined to persist across
+ // system reset. Set its value into NV storage to let pre-boot driver to pick it up
+ // after coming through a system reset.
+ //
+ Status = EfiSetVariable (
+ CapsuleVarName,
+ &gEfiCapsuleVendorGuid,
+ EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS,
+ sizeof (UINTN),
+ (VOID *)&ScatterGatherList
+ );
+ if (!EFI_ERROR (Status)) {
+ //
+ // Variable has been set successfully, increase variable index.
+ //
+ mTimes++;
+ if (InitiateReset) {
+ //
+ // Firmware that encounters a capsule which has the CAPSULE_FLAGS_INITIATE_RESET Flag set in its header
+ // will initiate a reset of the platform which is compatible with the passed-in capsule request and will
+ // not return back to the caller.
+ //
+ EfiResetSystem (EfiResetWarm, EFI_SUCCESS, 0, NULL);
+ }
+ }
+
+ return Status;
+}
+
+/**
+ Returns if the capsule can be supported via UpdateCapsule().
+ Notice: When PcdCapsuleInRamSupport is unsupported, even this routine returns a valid answer,
+ the capsule still is unsupported via UpdateCapsule().
+
+ @param CapsuleHeaderArray Virtual pointer to an array of virtual pointers to the capsules
+ being passed into update capsule.
+ @param CapsuleCount Number of pointers to EFI_CAPSULE_HEADER in
+ CaspuleHeaderArray.
+ @param MaxiumCapsuleSize On output the maximum size that UpdateCapsule() can
+ support as an argument to UpdateCapsule() via
+ CapsuleHeaderArray and ScatterGatherList.
+ @param ResetType Returns the type of reset required for the capsule update.
+
+ @retval EFI_SUCCESS Valid answer returned.
+ @retval EFI_UNSUPPORTED The capsule image is not supported on this platform, and
+ MaximumCapsuleSize and ResetType are undefined.
+ @retval EFI_INVALID_PARAMETER MaximumCapsuleSize is NULL, or ResetTyep is NULL,
+ Or CapsuleCount is Zero, or CapsuleImage is not valid.
+ @retval EFI_OUT_OF_RESOURCES When ExitBootServices() has been previously called this error indicates
+ the capsule is compatible with this platform but is not capable of
+ being submitted or processed in runtime.
+ The caller may resubmit the capsule prior to ExitBootServices().
+ @retval EFI_OUT_OF_RESOURCES When ExitBootServices() has not been previously called then this error
+ indicates the capsule is compatible with this platform but there are
+ insufficient resources to process.
+ @retval EFI_UNSUPPORTED This call is not supported by this platform at the time the call is made.
+ The platform should describe this runtime service as unsupported at runtime
+ via an EFI_RT_PROPERTIES_TABLE configuration table.
+
+**/
+EFI_STATUS
+EFIAPI
+QueryCapsuleCapabilities (
+ IN EFI_CAPSULE_HEADER **CapsuleHeaderArray,
+ IN UINTN CapsuleCount,
+ OUT UINT64 *MaxiumCapsuleSize,
+ OUT EFI_RESET_TYPE *ResetType
+ )
+{
+ EFI_STATUS Status;
+ UINTN ArrayNumber;
+ EFI_CAPSULE_HEADER *CapsuleHeader;
+ BOOLEAN NeedReset;
+
+ //
+ // Capsule Count can't be less than one.
+ //
+ if (CapsuleCount < 1) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // Check whether input parameter is valid
+ //
+ if ((MaxiumCapsuleSize == NULL) || (ResetType == NULL)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ CapsuleHeader = NULL;
+ NeedReset = FALSE;
+
+ for (ArrayNumber = 0; ArrayNumber < CapsuleCount; ArrayNumber++) {
+ CapsuleHeader = CapsuleHeaderArray[ArrayNumber];
+ //
+ // A capsule which has the CAPSULE_FLAGS_POPULATE_SYSTEM_TABLE flag must have
+ // CAPSULE_FLAGS_PERSIST_ACROSS_RESET set in its header as well.
+ //
+ if ((CapsuleHeader->Flags & (CAPSULE_FLAGS_PERSIST_ACROSS_RESET | CAPSULE_FLAGS_POPULATE_SYSTEM_TABLE)) == CAPSULE_FLAGS_POPULATE_SYSTEM_TABLE) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // A capsule which has the CAPSULE_FLAGS_INITIATE_RESET flag must have
+ // CAPSULE_FLAGS_PERSIST_ACROSS_RESET set in its header as well.
+ //
+ if ((CapsuleHeader->Flags & (CAPSULE_FLAGS_PERSIST_ACROSS_RESET | CAPSULE_FLAGS_INITIATE_RESET)) == CAPSULE_FLAGS_INITIATE_RESET) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // Check FMP capsule flag
+ //
+ if ( CompareGuid (&CapsuleHeader->CapsuleGuid, &gEfiFmpCapsuleGuid)
+ && ((CapsuleHeader->Flags & CAPSULE_FLAGS_POPULATE_SYSTEM_TABLE) != 0))
+ {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // Check Capsule image without populate flag is supported by firmware
+ //
+ if ((CapsuleHeader->Flags & CAPSULE_FLAGS_POPULATE_SYSTEM_TABLE) == 0) {
+ Status = SupportCapsuleImage (CapsuleHeader);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ }
+ }
+
+ //
+ // Find out whether there is any capsule defined to persist across system reset.
+ //
+ for (ArrayNumber = 0; ArrayNumber < CapsuleCount; ArrayNumber++) {
+ CapsuleHeader = CapsuleHeaderArray[ArrayNumber];
+ if ((CapsuleHeader->Flags & CAPSULE_FLAGS_PERSIST_ACROSS_RESET) != 0) {
+ NeedReset = TRUE;
+ break;
+ }
+ }
+
+ if (NeedReset) {
+ //
+ // Check if the platform supports update capsule across a system reset
+ //
+ if (!IsPersistAcrossResetCapsuleSupported ()) {
+ return EFI_UNSUPPORTED;
+ }
+
+ *ResetType = EfiResetWarm;
+ *MaxiumCapsuleSize = (UINT64)mMaxSizePopulateCapsule;
+ } else {
+ //
+ // For non-reset capsule image.
+ //
+ *ResetType = EfiResetCold;
+ *MaxiumCapsuleSize = (UINT64)mMaxSizeNonPopulateCapsule;
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+
+ This code installs UEFI capsule runtime service.
+
+ @param ImageHandle The firmware allocated handle for the EFI image.
+ @param SystemTable A pointer to the EFI System Table.
+
+ @retval EFI_SUCCESS UEFI Capsule Runtime Services are installed successfully.
+
+**/
+EFI_STATUS
+EFIAPI
+CapsuleServiceInitialize (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+
+ mMaxSizePopulateCapsule = PcdGet32 (PcdMaxSizePopulateCapsule);
+ mMaxSizeNonPopulateCapsule = PcdGet32 (PcdMaxSizeNonPopulateCapsule);
+
+ //
+ // When PEI phase is IA32, DXE phase is X64, it is possible that capsule data are
+ // put above 4GB, so capsule PEI will transfer to long mode to get capsule data.
+ // The page table and stack is used to transfer processor mode from IA32 to long mode.
+ // Create the base address of page table and stack, and save them into variable.
+ // This is not needed when capsule with reset type is not supported.
+ //
+ SaveLongModeContext ();
+
+ //
+ // Install capsule runtime services into UEFI runtime service tables.
+ //
+ gRT->UpdateCapsule = UpdateCapsule;
+ gRT->QueryCapsuleCapabilities = QueryCapsuleCapabilities;
+
+ //
+ // Install the Capsule Architectural Protocol on a new handle
+ // to signify the capsule runtime services are ready.
+ //
+ Status = gBS->InstallMultipleProtocolInterfaces (
+ &mNewHandle,
+ &gEfiCapsuleArchProtocolGuid,
+ NULL,
+ NULL
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ return Status;
+}
diff --git a/MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleService.h b/MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleService.h
index c671626f2f..a65367509d 100644
--- a/MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleService.h
+++ b/MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleService.h
@@ -1,70 +1,70 @@
-/** @file
- Capsule Runtime Driver produces two UEFI capsule runtime services.
- (UpdateCapsule, QueryCapsuleCapabilities)
- It installs the Capsule Architectural Protocol defined in PI1.0a to signify
- the capsule runtime services are ready.
-
- Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
- Copyright (c) 2018, Linaro, Ltd. All rights reserved.<BR>
-
- SPDX-License-Identifier: BSD-2-Clause-Patent
-
-**/
-
-#ifndef _CAPSULE_SERVICE_H_
-#define _CAPSULE_SERVICE_H_
-
-#include <Uefi.h>
-
-#include <Protocol/Capsule.h>
-#include <Guid/CapsuleVendor.h>
-#include <Guid/FmpCapsule.h>
-
-#include <Library/DebugLib.h>
-#include <Library/PcdLib.h>
-#include <Library/CapsuleLib.h>
-#include <Library/UefiDriverEntryPoint.h>
-#include <Library/UefiBootServicesTableLib.h>
-#include <Library/UefiRuntimeServicesTableLib.h>
-#include <Library/UefiRuntimeLib.h>
-#include <Library/BaseLib.h>
-#include <Library/PrintLib.h>
-#include <Library/BaseMemoryLib.h>
-
-/**
- Create the variable to save the base address of page table and stack
- for transferring into long mode in IA32 PEI.
-**/
-VOID
-SaveLongModeContext (
- VOID
- );
-
-/**
- Whether the platform supports capsules that persist across reset. Note that
- some platforms only support such capsules at boot time.
-
- @return TRUE if a PersistAcrossReset capsule may be passed to UpdateCapsule()
- at this time
- FALSE otherwise
-**/
-BOOLEAN
-IsPersistAcrossResetCapsuleSupported (
- VOID
- );
-
-/**
- Writes Back a range of data cache lines covering a set of capsules in memory.
-
- Writes Back the data cache lines specified by ScatterGatherList.
-
- @param ScatterGatherList Physical address of the data structure that
- describes a set of capsules in memory
-
-**/
-VOID
-CapsuleCacheWriteBack (
- IN EFI_PHYSICAL_ADDRESS ScatterGatherList
- );
-
-#endif
+/** @file
+ Capsule Runtime Driver produces two UEFI capsule runtime services.
+ (UpdateCapsule, QueryCapsuleCapabilities)
+ It installs the Capsule Architectural Protocol defined in PI1.0a to signify
+ the capsule runtime services are ready.
+
+ Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
+ Copyright (c) 2018, Linaro, Ltd. All rights reserved.<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef _CAPSULE_SERVICE_H_
+#define _CAPSULE_SERVICE_H_
+
+#include <Uefi.h>
+
+#include <Protocol/Capsule.h>
+#include <Guid/CapsuleVendor.h>
+#include <Guid/FmpCapsule.h>
+
+#include <Library/DebugLib.h>
+#include <Library/PcdLib.h>
+#include <Library/CapsuleLib.h>
+#include <Library/UefiDriverEntryPoint.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+#include <Library/UefiRuntimeLib.h>
+#include <Library/BaseLib.h>
+#include <Library/PrintLib.h>
+#include <Library/BaseMemoryLib.h>
+
+/**
+ Create the variable to save the base address of page table and stack
+ for transferring into long mode in IA32 PEI.
+**/
+VOID
+SaveLongModeContext (
+ VOID
+ );
+
+/**
+ Whether the platform supports capsules that persist across reset. Note that
+ some platforms only support such capsules at boot time.
+
+ @return TRUE if a PersistAcrossReset capsule may be passed to UpdateCapsule()
+ at this time
+ FALSE otherwise
+**/
+BOOLEAN
+IsPersistAcrossResetCapsuleSupported (
+ VOID
+ );
+
+/**
+ Writes Back a range of data cache lines covering a set of capsules in memory.
+
+ Writes Back the data cache lines specified by ScatterGatherList.
+
+ @param ScatterGatherList Physical address of the data structure that
+ describes a set of capsules in memory
+
+**/
+VOID
+CapsuleCacheWriteBack (
+ IN EFI_PHYSICAL_ADDRESS ScatterGatherList
+ );
+
+#endif
diff --git a/MdeModulePkg/Universal/CapsuleRuntimeDxe/SaveLongModeContext.c b/MdeModulePkg/Universal/CapsuleRuntimeDxe/SaveLongModeContext.c
index 37b388902c..ff4a5403c6 100644
--- a/MdeModulePkg/Universal/CapsuleRuntimeDxe/SaveLongModeContext.c
+++ b/MdeModulePkg/Universal/CapsuleRuntimeDxe/SaveLongModeContext.c
@@ -1,21 +1,21 @@
-/** @file
- Create the NULL function to pass build in IA32/IPF/ARM/EBC.
-
-Copyright (c) 2011, Intel Corporation. All rights reserved.<BR>
-SPDX-License-Identifier: BSD-2-Clause-Patent
-
-**/
-
-#include <Uefi.h>
-
-/**
- Only when PEI is IA32 and DXE is X64, we need transfer to long mode in PEI
- in order to process capsule data above 4GB. So create a NULL function here for
- other cases.
-**/
-VOID
-SaveLongModeContext (
- VOID
- )
-{
-}
+/** @file
+ Create the NULL function to pass build in IA32/IPF/ARM/EBC.
+
+Copyright (c) 2011, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <Uefi.h>
+
+/**
+ Only when PEI is IA32 and DXE is X64, we need transfer to long mode in PEI
+ in order to process capsule data above 4GB. So create a NULL function here for
+ other cases.
+**/
+VOID
+SaveLongModeContext (
+ VOID
+ )
+{
+}
diff --git a/MdeModulePkg/Universal/CapsuleRuntimeDxe/X64/SaveLongModeContext.c b/MdeModulePkg/Universal/CapsuleRuntimeDxe/X64/SaveLongModeContext.c
index dab297dd0a..fa072820aa 100644
--- a/MdeModulePkg/Universal/CapsuleRuntimeDxe/X64/SaveLongModeContext.c
+++ b/MdeModulePkg/Universal/CapsuleRuntimeDxe/X64/SaveLongModeContext.c
@@ -1,211 +1,211 @@
-/** @file
- Create the variable to save the base address of page table and stack
- for transferring into long mode in IA32 capsule PEI.
-
-Copyright (c) 2011 - 2018, Intel Corporation. All rights reserved.<BR>
-SPDX-License-Identifier: BSD-2-Clause-Patent
-
-**/
-
-#include <Uefi.h>
-
-#include <Protocol/Capsule.h>
-#include <Protocol/DxeSmmReadyToLock.h>
-#include <Protocol/VariableLock.h>
-
-#include <Guid/CapsuleVendor.h>
-#include <Guid/AcpiS3Context.h>
-
-#include <Library/DebugLib.h>
-#include <Library/PcdLib.h>
-#include <Library/UefiBootServicesTableLib.h>
-#include <Library/UefiRuntimeServicesTableLib.h>
-#include <Library/UefiRuntimeLib.h>
-#include <Library/BaseLib.h>
-#include <Library/UefiLib.h>
-#include <Library/BaseMemoryLib.h>
-
-//
-// 8 extra pages for PF handler.
-//
-#define EXTRA_PAGE_TABLE_PAGES 8
-
-/**
- Allocate EfiReservedMemoryType below 4G memory address.
-
- This function allocates EfiReservedMemoryType below 4G memory address.
-
- @param Size Size of memory to allocate.
-
- @return Allocated Address for output.
-
-**/
-VOID *
-AllocateReservedMemoryBelow4G (
- 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,
- EfiReservedMemoryType,
- Pages,
- &Address
- );
- ASSERT_EFI_ERROR (Status);
-
- Buffer = (VOID *)(UINTN)Address;
- ZeroMem (Buffer, Size);
-
- return Buffer;
-}
-
-/**
- Register callback function upon VariableLockProtocol
- to lock EFI_CAPSULE_LONG_MODE_BUFFER_NAME 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
-VariableLockCapsuleLongModeBufferVariable (
- IN EFI_EVENT Event,
- IN VOID *Context
- )
-{
- EFI_STATUS Status;
- EDKII_VARIABLE_LOCK_PROTOCOL *VariableLock;
-
- //
- // Mark EFI_CAPSULE_LONG_MODE_BUFFER_NAME 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, EFI_CAPSULE_LONG_MODE_BUFFER_NAME, &gEfiCapsuleVendorGuid);
- ASSERT_EFI_ERROR (Status);
- }
-}
-
-/**
- 1. Allocate Reserved memory for capsule PEIM to establish a 1:1 Virtual to Physical mapping.
- 2. Allocate Reserved memroy as a stack for capsule PEIM to transfer from 32-bit mdoe to 64-bit mode.
-
-**/
-VOID
-EFIAPI
-PrepareContextForCapsulePei (
- VOID
- )
-{
- UINTN ExtraPageTablePages;
- UINT32 RegEax;
- UINT32 RegEdx;
- UINTN TotalPagesNum;
- UINT8 PhysicalAddressBits;
- UINT32 NumberOfPml4EntriesNeeded;
- UINT32 NumberOfPdpEntriesNeeded;
- BOOLEAN Page1GSupport;
- EFI_CAPSULE_LONG_MODE_BUFFER LongModeBuffer;
- EFI_STATUS Status;
- VOID *Registration;
-
- //
- // Calculate the size of page table, allocate the memory.
- //
- 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;
- }
- }
- }
-
- //
- // Create 4G page table by default,
- // and let PF handler to handle > 4G request.
- //
- PhysicalAddressBits = 32;
- ExtraPageTablePages = EXTRA_PAGE_TABLE_PAGES;
-
- //
- // 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;
- }
-
- if (!Page1GSupport) {
- TotalPagesNum = (NumberOfPdpEntriesNeeded + 1) * NumberOfPml4EntriesNeeded + 1;
- } else {
- TotalPagesNum = NumberOfPml4EntriesNeeded + 1;
- }
-
- TotalPagesNum += ExtraPageTablePages;
- DEBUG ((DEBUG_INFO, "CapsuleRuntimeDxe X64 TotalPagesNum - 0x%x pages\n", TotalPagesNum));
-
- LongModeBuffer.PageTableAddress = (EFI_PHYSICAL_ADDRESS)(UINTN)AllocateReservedMemoryBelow4G (EFI_PAGES_TO_SIZE (TotalPagesNum));
- ASSERT (LongModeBuffer.PageTableAddress != 0);
-
- //
- // Allocate stack
- //
- LongModeBuffer.StackSize = PcdGet32 (PcdCapsulePeiLongModeStackSize);
- LongModeBuffer.StackBaseAddress = (EFI_PHYSICAL_ADDRESS)(UINTN)AllocateReservedMemoryBelow4G (PcdGet32 (PcdCapsulePeiLongModeStackSize));
- ASSERT (LongModeBuffer.StackBaseAddress != 0);
-
- Status = gRT->SetVariable (
- EFI_CAPSULE_LONG_MODE_BUFFER_NAME,
- &gEfiCapsuleVendorGuid,
- EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,
- sizeof (EFI_CAPSULE_LONG_MODE_BUFFER),
- &LongModeBuffer
- );
- if (!EFI_ERROR (Status)) {
- //
- // Register callback function upon VariableLockProtocol
- // to lock EFI_CAPSULE_LONG_MODE_BUFFER_NAME variable to avoid malicious code to update it.
- //
- EfiCreateProtocolNotifyEvent (
- &gEdkiiVariableLockProtocolGuid,
- TPL_CALLBACK,
- VariableLockCapsuleLongModeBufferVariable,
- NULL,
- &Registration
- );
- } else {
- DEBUG ((DEBUG_ERROR, "FATAL ERROR: CapsuleLongModeBuffer cannot be saved: %r. Capsule in PEI may fail!\n", Status));
- gBS->FreePages (LongModeBuffer.StackBaseAddress, EFI_SIZE_TO_PAGES (LongModeBuffer.StackSize));
- }
-}
-
-/**
- Create the variable to save the base address of page table and stack
- for transferring into long mode in IA32 capsule PEI.
-**/
-VOID
-SaveLongModeContext (
- VOID
- )
-{
- if ((FeaturePcdGet (PcdSupportUpdateCapsuleReset)) && (FeaturePcdGet (PcdDxeIplSwitchToLongMode))) {
- //
- // Allocate memory for Capsule IA32 PEIM, it will create page table to transfer to long mode to access capsule above 4GB.
- //
- PrepareContextForCapsulePei ();
- }
-}
+/** @file
+ Create the variable to save the base address of page table and stack
+ for transferring into long mode in IA32 capsule PEI.
+
+Copyright (c) 2011 - 2018, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <Uefi.h>
+
+#include <Protocol/Capsule.h>
+#include <Protocol/DxeSmmReadyToLock.h>
+#include <Protocol/VariableLock.h>
+
+#include <Guid/CapsuleVendor.h>
+#include <Guid/AcpiS3Context.h>
+
+#include <Library/DebugLib.h>
+#include <Library/PcdLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+#include <Library/UefiRuntimeLib.h>
+#include <Library/BaseLib.h>
+#include <Library/UefiLib.h>
+#include <Library/BaseMemoryLib.h>
+
+//
+// 8 extra pages for PF handler.
+//
+#define EXTRA_PAGE_TABLE_PAGES 8
+
+/**
+ Allocate EfiReservedMemoryType below 4G memory address.
+
+ This function allocates EfiReservedMemoryType below 4G memory address.
+
+ @param Size Size of memory to allocate.
+
+ @return Allocated Address for output.
+
+**/
+VOID *
+AllocateReservedMemoryBelow4G (
+ 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,
+ EfiReservedMemoryType,
+ Pages,
+ &Address
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ Buffer = (VOID *)(UINTN)Address;
+ ZeroMem (Buffer, Size);
+
+ return Buffer;
+}
+
+/**
+ Register callback function upon VariableLockProtocol
+ to lock EFI_CAPSULE_LONG_MODE_BUFFER_NAME 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
+VariableLockCapsuleLongModeBufferVariable (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+{
+ EFI_STATUS Status;
+ EDKII_VARIABLE_LOCK_PROTOCOL *VariableLock;
+
+ //
+ // Mark EFI_CAPSULE_LONG_MODE_BUFFER_NAME 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, EFI_CAPSULE_LONG_MODE_BUFFER_NAME, &gEfiCapsuleVendorGuid);
+ ASSERT_EFI_ERROR (Status);
+ }
+}
+
+/**
+ 1. Allocate Reserved memory for capsule PEIM to establish a 1:1 Virtual to Physical mapping.
+ 2. Allocate Reserved memroy as a stack for capsule PEIM to transfer from 32-bit mdoe to 64-bit mode.
+
+**/
+VOID
+EFIAPI
+PrepareContextForCapsulePei (
+ VOID
+ )
+{
+ UINTN ExtraPageTablePages;
+ UINT32 RegEax;
+ UINT32 RegEdx;
+ UINTN TotalPagesNum;
+ UINT8 PhysicalAddressBits;
+ UINT32 NumberOfPml4EntriesNeeded;
+ UINT32 NumberOfPdpEntriesNeeded;
+ BOOLEAN Page1GSupport;
+ EFI_CAPSULE_LONG_MODE_BUFFER LongModeBuffer;
+ EFI_STATUS Status;
+ VOID *Registration;
+
+ //
+ // Calculate the size of page table, allocate the memory.
+ //
+ 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;
+ }
+ }
+ }
+
+ //
+ // Create 4G page table by default,
+ // and let PF handler to handle > 4G request.
+ //
+ PhysicalAddressBits = 32;
+ ExtraPageTablePages = EXTRA_PAGE_TABLE_PAGES;
+
+ //
+ // 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;
+ }
+
+ if (!Page1GSupport) {
+ TotalPagesNum = (NumberOfPdpEntriesNeeded + 1) * NumberOfPml4EntriesNeeded + 1;
+ } else {
+ TotalPagesNum = NumberOfPml4EntriesNeeded + 1;
+ }
+
+ TotalPagesNum += ExtraPageTablePages;
+ DEBUG ((DEBUG_INFO, "CapsuleRuntimeDxe X64 TotalPagesNum - 0x%x pages\n", TotalPagesNum));
+
+ LongModeBuffer.PageTableAddress = (EFI_PHYSICAL_ADDRESS)(UINTN)AllocateReservedMemoryBelow4G (EFI_PAGES_TO_SIZE (TotalPagesNum));
+ ASSERT (LongModeBuffer.PageTableAddress != 0);
+
+ //
+ // Allocate stack
+ //
+ LongModeBuffer.StackSize = PcdGet32 (PcdCapsulePeiLongModeStackSize);
+ LongModeBuffer.StackBaseAddress = (EFI_PHYSICAL_ADDRESS)(UINTN)AllocateReservedMemoryBelow4G (PcdGet32 (PcdCapsulePeiLongModeStackSize));
+ ASSERT (LongModeBuffer.StackBaseAddress != 0);
+
+ Status = gRT->SetVariable (
+ EFI_CAPSULE_LONG_MODE_BUFFER_NAME,
+ &gEfiCapsuleVendorGuid,
+ EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,
+ sizeof (EFI_CAPSULE_LONG_MODE_BUFFER),
+ &LongModeBuffer
+ );
+ if (!EFI_ERROR (Status)) {
+ //
+ // Register callback function upon VariableLockProtocol
+ // to lock EFI_CAPSULE_LONG_MODE_BUFFER_NAME variable to avoid malicious code to update it.
+ //
+ EfiCreateProtocolNotifyEvent (
+ &gEdkiiVariableLockProtocolGuid,
+ TPL_CALLBACK,
+ VariableLockCapsuleLongModeBufferVariable,
+ NULL,
+ &Registration
+ );
+ } else {
+ DEBUG ((DEBUG_ERROR, "FATAL ERROR: CapsuleLongModeBuffer cannot be saved: %r. Capsule in PEI may fail!\n", Status));
+ gBS->FreePages (LongModeBuffer.StackBaseAddress, EFI_SIZE_TO_PAGES (LongModeBuffer.StackSize));
+ }
+}
+
+/**
+ Create the variable to save the base address of page table and stack
+ for transferring into long mode in IA32 capsule PEI.
+**/
+VOID
+SaveLongModeContext (
+ VOID
+ )
+{
+ if ((FeaturePcdGet (PcdSupportUpdateCapsuleReset)) && (FeaturePcdGet (PcdDxeIplSwitchToLongMode))) {
+ //
+ // Allocate memory for Capsule IA32 PEIM, it will create page table to transfer to long mode to access capsule above 4GB.
+ //
+ PrepareContextForCapsulePei ();
+ }
+}