]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Library/DxeCapsuleLibFmp/DxeCapsuleReportLib.c
MdeModulePkg/CapsuleLib: Support result rolling over.
[mirror_edk2.git] / MdeModulePkg / Library / DxeCapsuleLibFmp / DxeCapsuleReportLib.c
index a0ed2d0b7e69b2f77ad5ac6d7e33630f5f95287f..ce79a5a619a17fda59f05aaa4b41bdf126b29a0b 100644 (file)
@@ -30,6 +30,7 @@
 #include <Library/HobLib.h>\r
 #include <Library/PrintLib.h>\r
 #include <Library/ReportStatusCodeLib.h>\r
+#include <Library/DevicePathLib.h>\r
 #include <Library/CapsuleLib.h>\r
 \r
 #include <IndustryStandard/WindowsUxCapsule.h>\r
@@ -104,7 +105,7 @@ IsFmpCapsuleProcessed (
     CapsuleResult = &mCapsuleResultVariableCache[Index].CapsuleResultHeader;\r
     if (CapsuleResult->VariableTotalSize >= sizeof(EFI_CAPSULE_RESULT_VARIABLE_HEADER)) {\r
       if (CompareGuid(&CapsuleResult->CapsuleGuid, &gEfiFmpCapsuleGuid)) {\r
-        if (CapsuleResult->VariableTotalSize >= sizeof(EFI_CAPSULE_RESULT_VARIABLE_HEADER) + sizeof(EFI_CAPSULE_RESULT_VARIABLE_FMP)) {\r
+        if (CapsuleResult->VariableTotalSize >= sizeof(EFI_CAPSULE_RESULT_VARIABLE_HEADER) + sizeof(EFI_CAPSULE_RESULT_VARIABLE_FMP) + sizeof(CHAR16) * 2) {\r
           CapsuleResultFmp = (EFI_CAPSULE_RESULT_VARIABLE_FMP *)(CapsuleResult + 1);\r
           if (CompareGuid(&CapsuleResultFmp->UpdateImageTypeId, &ImageHeader->UpdateImageTypeId) &&\r
               (CapsuleResultFmp->UpdateImageIndex == ImageHeader->UpdateImageIndex) &&\r
@@ -166,7 +167,7 @@ WriteNewCapsuleResultVariableCache (
   Get a new capsule status variable index.\r
 \r
   @return A new capsule status variable index.\r
-  @retval -1  No new capsule status variable index.\r
+  @retval 0  No new capsule status variable index. Rolling over.\r
 **/\r
 INTN\r
 GetNewCapsuleResultIndex (\r
@@ -177,7 +178,8 @@ GetNewCapsuleResultIndex (
 \r
   CurrentIndex = GetCurrentCapsuleLastIndex();\r
   if (CurrentIndex >= PcdGet16(PcdCapsuleMax)) {\r
-    return -1;\r
+    DEBUG((DEBUG_INFO, "  CapsuleResult variable Rolling Over!\n"));\r
+    return 0;\r
   }\r
 \r
   return CurrentIndex + 1;\r
@@ -205,9 +207,7 @@ WriteNewCapsuleResultVariable (
 \r
   CapsuleResultIndex = GetNewCapsuleResultIndex();\r
   DEBUG((DEBUG_INFO, "New CapsuleResultIndex - 0x%x\n", CapsuleResultIndex));\r
-  if (CapsuleResultIndex == -1) {\r
-    return EFI_OUT_OF_RESOURCES;\r
-  }\r
+\r
   UnicodeSPrint(\r
     CapsuleResultStr,\r
     sizeof(CapsuleResultStr),\r
@@ -256,6 +256,7 @@ RecordCapsuleStatusVariable (
   EFI_STATUS                          Status;\r
 \r
   CapsuleResultVariable.VariableTotalSize = sizeof(CapsuleResultVariable);\r
+  CapsuleResultVariable.Reserved = 0;\r
   CopyGuid (&CapsuleResultVariable.CapsuleGuid, &CapsuleHeader->CapsuleGuid);\r
   ZeroMem(&CapsuleResultVariable.CapsuleProcessed, sizeof(CapsuleResultVariable.CapsuleProcessed));\r
   gRT->GetTime(&CapsuleResultVariable.CapsuleProcessed, NULL);\r
@@ -279,6 +280,7 @@ RecordCapsuleStatusVariable (
   @param[in] CapsuleStatus  The capsule process stauts\r
   @param[in] PayloadIndex   FMP payload index\r
   @param[in] ImageHeader    FMP image header\r
+  @param[in] FmpDevicePath  DevicePath associated with the FMP producer\r
 \r
   @retval EFI_SUCCESS          The capsule status variable is recorded.\r
   @retval EFI_OUT_OF_RESOURCES No resource to record the capsule status variable.\r
@@ -288,35 +290,63 @@ RecordFmpCapsuleStatusVariable (
   IN EFI_CAPSULE_HEADER                            *CapsuleHeader,\r
   IN EFI_STATUS                                    CapsuleStatus,\r
   IN UINTN                                         PayloadIndex,\r
-  IN EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER  *ImageHeader\r
+  IN EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER  *ImageHeader,\r
+  IN EFI_DEVICE_PATH_PROTOCOL                      *FmpDevicePath OPTIONAL\r
   )\r
 {\r
-  UINT8                               CapsuleResultVariable[sizeof(EFI_CAPSULE_RESULT_VARIABLE_HEADER) + sizeof(EFI_CAPSULE_RESULT_VARIABLE_FMP)];\r
   EFI_CAPSULE_RESULT_VARIABLE_HEADER  *CapsuleResultVariableHeader;\r
   EFI_CAPSULE_RESULT_VARIABLE_FMP     *CapsuleResultVariableFmp;\r
   EFI_STATUS                          Status;\r
-\r
-  CapsuleResultVariableHeader = (VOID *)&CapsuleResultVariable[0];\r
-  CapsuleResultVariableHeader->VariableTotalSize = sizeof(CapsuleResultVariable);\r
+  UINT8                               *CapsuleResultVariable;\r
+  UINTN                               CapsuleResultVariableSize;\r
+  CHAR16                              *DevicePathStr;\r
+  UINTN                               DevicePathStrSize;\r
+\r
+  DevicePathStr = NULL;\r
+  if (FmpDevicePath != NULL) {\r
+    DevicePathStr = ConvertDevicePathToText (FmpDevicePath, FALSE, FALSE);\r
+  }\r
+  if (DevicePathStr != NULL) {\r
+    DevicePathStrSize = StrSize(DevicePathStr);\r
+  } else {\r
+    DevicePathStrSize = sizeof(CHAR16);\r
+  }\r
+  //\r
+  // Allocate zero CHAR16 for CapsuleFileName.\r
+  //\r
+  CapsuleResultVariableSize = sizeof(EFI_CAPSULE_RESULT_VARIABLE_HEADER) + sizeof(EFI_CAPSULE_RESULT_VARIABLE_FMP) + sizeof(CHAR16) + DevicePathStrSize;\r
+  CapsuleResultVariable     = AllocateZeroPool (CapsuleResultVariableSize);\r
+  if (CapsuleResultVariable == NULL) {\r
+    return EFI_OUT_OF_RESOURCES;\r
+  }\r
+  CapsuleResultVariableHeader = (VOID *)CapsuleResultVariable;\r
+  CapsuleResultVariableHeader->VariableTotalSize = (UINT32)CapsuleResultVariableSize;\r
+  CapsuleResultVariableHeader->Reserved = 0;\r
   CopyGuid(&CapsuleResultVariableHeader->CapsuleGuid, &CapsuleHeader->CapsuleGuid);\r
   ZeroMem(&CapsuleResultVariableHeader->CapsuleProcessed, sizeof(CapsuleResultVariableHeader->CapsuleProcessed));\r
   gRT->GetTime(&CapsuleResultVariableHeader->CapsuleProcessed, NULL);\r
   CapsuleResultVariableHeader->CapsuleStatus = CapsuleStatus;\r
 \r
-  CapsuleResultVariableFmp = (VOID *)&CapsuleResultVariable[sizeof(EFI_CAPSULE_RESULT_VARIABLE_HEADER)];\r
+  CapsuleResultVariableFmp = (VOID *)(CapsuleResultVariable + sizeof(EFI_CAPSULE_RESULT_VARIABLE_HEADER));\r
   CapsuleResultVariableFmp->Version = 0x1;\r
   CapsuleResultVariableFmp->PayloadIndex = (UINT8)PayloadIndex;\r
   CapsuleResultVariableFmp->UpdateImageIndex = ImageHeader->UpdateImageIndex;\r
   CopyGuid (&CapsuleResultVariableFmp->UpdateImageTypeId, &ImageHeader->UpdateImageTypeId);\r
+  if (DevicePathStr != NULL) {\r
+    CopyMem ((UINT8 *)CapsuleResultVariableFmp + sizeof(EFI_CAPSULE_RESULT_VARIABLE_FMP) + sizeof(CHAR16), DevicePathStr, DevicePathStrSize);\r
+    FreePool (DevicePathStr);\r
+    DevicePathStr = NULL;\r
+  }\r
 \r
   //\r
   // Save Local Cache\r
   //\r
-  Status = WriteNewCapsuleResultVariableCache(&CapsuleResultVariable, sizeof(CapsuleResultVariable));\r
+  Status = WriteNewCapsuleResultVariableCache(CapsuleResultVariable, CapsuleResultVariableSize);\r
 \r
   if ((CapsuleHeader->Flags & CAPSULE_FLAGS_PERSIST_ACROSS_RESET) != 0) {\r
-    Status = WriteNewCapsuleResultVariable(&CapsuleResultVariable, sizeof(CapsuleResultVariable));\r
+    Status = WriteNewCapsuleResultVariable(CapsuleResultVariable, CapsuleResultVariableSize);\r
   }\r
+  FreePool (CapsuleResultVariable);\r
   return Status;\r
 }\r
 \r