--- /dev/null
+ /** @file\r
+ ARM implementation of architecture specific routines related to\r
+ PersistAcrossReset capsules\r
+\r
+ Copyright (c) 2018, Linaro, Ltd. All rights reserved.<BR>\r
+\r
+ This program and the accompanying materials are licensed and made available\r
+ under the terms and conditions of the BSD License which accompanies this\r
+ distribution. The full text of the license may be found at\r
+ http://opensource.org/licenses/bsd-license.php\r
+\r
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include "CapsuleService.h"\r
+\r
+#include <Library/CacheMaintenanceLib.h>\r
+\r
+/**\r
+ Whether the platform supports capsules that persist across reset. Note that\r
+ some platforms only support such capsules at boot time.\r
+\r
+ @return TRUE if a PersistAcrossReset capsule may be passed to UpdateCapsule()\r
+ at this time\r
+ FALSE otherwise\r
+**/\r
+BOOLEAN\r
+IsPersistAcrossResetCapsuleSupported (\r
+ VOID\r
+ )\r
+{\r
+ //\r
+ // ARM requires the capsule payload to be cleaned to the point of coherency\r
+ // (PoC), but only permits doing so using cache maintenance instructions that\r
+ // operate on virtual addresses. Since at runtime, we don't know the virtual\r
+ // addresses of the data structures that make up the scatter/gather list, we\r
+ // cannot perform the maintenance, and all we can do is give up.\r
+ //\r
+ return FeaturePcdGet (PcdSupportUpdateCapsuleReset) && !EfiAtRuntime ();\r
+}\r
+\r
+/**\r
+ Writes Back a range of data cache lines covering a set of capsules in memory.\r
+\r
+ Writes Back the data cache lines specified by ScatterGatherList.\r
+\r
+ @param ScatterGatherList Physical address of the data structure that\r
+ describes a set of capsules in memory\r
+\r
+**/\r
+VOID\r
+CapsuleCacheWriteBack (\r
+ IN EFI_PHYSICAL_ADDRESS ScatterGatherList\r
+ )\r
+{\r
+ EFI_CAPSULE_BLOCK_DESCRIPTOR *Desc;\r
+\r
+ Desc = (EFI_CAPSULE_BLOCK_DESCRIPTOR *)(UINTN)ScatterGatherList;\r
+ do {\r
+ WriteBackDataCacheRange (Desc, sizeof *Desc);\r
+\r
+ if (Desc->Length > 0) {\r
+ WriteBackDataCacheRange ((VOID *)(UINTN)Desc->Union.DataBlock,\r
+ Desc->Length\r
+ );\r
+ Desc++;\r
+ } else if (Desc->Union.ContinuationPointer > 0) {\r
+ Desc = (EFI_CAPSULE_BLOCK_DESCRIPTOR *)(UINTN)Desc->Union.ContinuationPointer;\r
+ }\r
+ } while (Desc->Length > 0 || Desc->Union.ContinuationPointer > 0);\r
+\r
+ WriteBackDataCacheRange (Desc, sizeof *Desc);\r
+}\r
--- /dev/null
+/** @file\r
+ Default implementation of architecture specific routines related to\r
+ PersistAcrossReset capsules\r
+\r
+ Copyright (c) 2018, Linaro, Ltd. All rights reserved.<BR>\r
+\r
+ This program and the accompanying materials are licensed and made available\r
+ under the terms and conditions of the BSD License which accompanies this\r
+ distribution. The full text of the license may be found at\r
+ http://opensource.org/licenses/bsd-license.php\r
+\r
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include "CapsuleService.h"\r
+\r
+/**\r
+ Whether the platform supports capsules that persist across reset. Note that\r
+ some platforms only support such capsules at boot time.\r
+\r
+ @return TRUE if a PersistAcrossReset capsule may be passed to UpdateCapsule()\r
+ at this time\r
+ FALSE otherwise\r
+**/\r
+BOOLEAN\r
+IsPersistAcrossResetCapsuleSupported (\r
+ VOID\r
+ )\r
+{\r
+ return FeaturePcdGet (PcdSupportUpdateCapsuleReset);\r
+}\r
+\r
+/**\r
+ Writes Back a range of data cache lines covering a set of capsules in memory.\r
+\r
+ Writes Back the data cache lines specified by ScatterGatherList.\r
+\r
+ @param ScatterGatherList Physical address of the data structure that\r
+ describes a set of capsules in memory\r
+\r
+**/\r
+VOID\r
+CapsuleCacheWriteBack (\r
+ IN EFI_PHYSICAL_ADDRESS ScatterGatherList\r
+ )\r
+{\r
+}\r
#\r
# The following information is for reference only and not required by the build tools.\r
#\r
-# VALID_ARCHITECTURES = IA32 X64 IPF EBC\r
+# VALID_ARCHITECTURES = IA32 X64 IPF EBC ARM AARCH64\r
#\r
\r
[Sources]\r
CapsuleService.c\r
+ CapsuleService.h\r
\r
-[Sources.Ia32, Sources.IPF, Sources.EBC, Sources.ARM, Sources.AARCH64]\r
+[Sources.Ia32, Sources.IPF, Sources.EBC]\r
SaveLongModeContext.c\r
+ CapsuleReset.c\r
\r
[Sources.X64]\r
X64/SaveLongModeContext.c\r
+ CapsuleReset.c\r
+\r
+[Sources.ARM, Sources.AARCH64]\r
+ SaveLongModeContext.c\r
+ Arm/CapsuleReset.c\r
\r
[Packages]\r
MdePkg/MdePkg.dec\r
UefiLib\r
BaseMemoryLib\r
\r
+[LibraryClasses.ARM, LibraryClasses.AARCH64]\r
+ CacheMaintenanceLib\r
+\r
[Guids]\r
## SOMETIMES_PRODUCES ## Variable:L"CapsuleUpdateData" # (Process across reset capsule image) for capsule updated data\r
## SOMETIMES_PRODUCES ## Variable:L"CapsuleLongModeBuffer" # The long mode buffer used by IA32 Capsule PEIM to call X64 CapsuleCoalesce code to handle >4GB capsule blocks\r
\r
**/\r
\r
-#include <Uefi.h>\r
-\r
-#include <Protocol/Capsule.h>\r
-#include <Guid/CapsuleVendor.h>\r
-#include <Guid/FmpCapsule.h>\r
-\r
-#include <Library/DebugLib.h>\r
-#include <Library/PcdLib.h>\r
-#include <Library/CapsuleLib.h>\r
-#include <Library/UefiDriverEntryPoint.h>\r
-#include <Library/UefiBootServicesTableLib.h>\r
-#include <Library/UefiRuntimeServicesTableLib.h>\r
-#include <Library/UefiRuntimeLib.h>\r
-#include <Library/BaseLib.h>\r
-#include <Library/PrintLib.h>\r
-#include <Library/BaseMemoryLib.h>\r
+#include "CapsuleService.h"\r
+\r
//\r
// Handle for the installation of Capsule Architecture Protocol.\r
//\r
UINT32 mMaxSizePopulateCapsule = 0;\r
UINT32 mMaxSizeNonPopulateCapsule = 0;\r
\r
-/**\r
- Create the variable to save the base address of page table and stack\r
- for transferring into long mode in IA32 PEI.\r
-**/\r
-VOID\r
-SaveLongModeContext (\r
- VOID\r
- );\r
-\r
/**\r
Passes capsules to the firmware with both virtual and physical mapping. Depending on the intended\r
consumption, the firmware may process the capsule immediately. If the payload should persist\r
//\r
// Check if the platform supports update capsule across a system reset\r
//\r
- if (!FeaturePcdGet(PcdSupportUpdateCapsuleReset)) {\r
+ if (!IsPersistAcrossResetCapsuleSupported ()) {\r
return EFI_UNSUPPORTED;\r
}\r
\r
+ CapsuleCacheWriteBack (ScatterGatherList);\r
+\r
//\r
// Construct variable name CapsuleUpdateData, CapsuleUpdateData1, CapsuleUpdateData2...\r
// if user calls UpdateCapsule multiple times.\r
//\r
//Check if the platform supports update capsule across a system reset\r
//\r
- if (!FeaturePcdGet(PcdSupportUpdateCapsuleReset)) {\r
+ if (!IsPersistAcrossResetCapsuleSupported ()) {\r
return EFI_UNSUPPORTED;\r
}\r
*ResetType = EfiResetWarm;\r
--- /dev/null
+/** @file\r
+ Capsule Runtime Driver produces two UEFI capsule runtime services.\r
+ (UpdateCapsule, QueryCapsuleCapabilities)\r
+ It installs the Capsule Architectural Protocol defined in PI1.0a to signify \r
+ the capsule runtime services are ready.\r
+\r
+ Copyright (c) 2006 - 2017, Intel Corporation. All rights reserved.<BR>\r
+ Copyright (c) 2018, Linaro, Ltd. All rights reserved.<BR>\r
+\r
+ This program and the accompanying materials are licensed and made available\r
+ under the terms and conditions of the BSD License which accompanies this\r
+ distribution. The full text of the license may be found at\r
+ http://opensource.org/licenses/bsd-license.php\r
+\r
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include <Uefi.h>\r
+\r
+#include <Protocol/Capsule.h>\r
+#include <Guid/CapsuleVendor.h>\r
+#include <Guid/FmpCapsule.h>\r
+\r
+#include <Library/DebugLib.h>\r
+#include <Library/PcdLib.h>\r
+#include <Library/CapsuleLib.h>\r
+#include <Library/UefiDriverEntryPoint.h>\r
+#include <Library/UefiBootServicesTableLib.h>\r
+#include <Library/UefiRuntimeServicesTableLib.h>\r
+#include <Library/UefiRuntimeLib.h>\r
+#include <Library/BaseLib.h>\r
+#include <Library/PrintLib.h>\r
+#include <Library/BaseMemoryLib.h>\r
+\r
+/**\r
+ Create the variable to save the base address of page table and stack\r
+ for transferring into long mode in IA32 PEI.\r
+**/\r
+VOID\r
+SaveLongModeContext (\r
+ VOID\r
+ );\r
+\r
+/**\r
+ Whether the platform supports capsules that persist across reset. Note that\r
+ some platforms only support such capsules at boot time.\r
+\r
+ @return TRUE if a PersistAcrossReset capsule may be passed to UpdateCapsule()\r
+ at this time\r
+ FALSE otherwise\r
+**/\r
+BOOLEAN\r
+IsPersistAcrossResetCapsuleSupported (\r
+ VOID\r
+ );\r
+\r
+/**\r
+ Writes Back a range of data cache lines covering a set of capsules in memory.\r
+\r
+ Writes Back the data cache lines specified by ScatterGatherList.\r
+\r
+ @param ScatterGatherList Physical address of the data structure that\r
+ describes a set of capsules in memory\r
+\r
+**/\r
+VOID\r
+CapsuleCacheWriteBack (\r
+ IN EFI_PHYSICAL_ADDRESS ScatterGatherList\r
+ );\r