]> git.proxmox.com Git - mirror_edk2.git/blobdiff - UefiCpuPkg/Feature/Capsule/MicrocodeUpdateDxe/MicrocodeFmp.c
UefiCpuPkg/MicrocodeUpdate: enhance flash write logic
[mirror_edk2.git] / UefiCpuPkg / Feature / Capsule / MicrocodeUpdateDxe / MicrocodeFmp.c
index df3563d8790acd11c6187d6dbd6cd6d657145f71..97f2f353e8a7903f5928d904929b8157efe26b70 100644 (file)
@@ -174,7 +174,7 @@ FmpGetImage (
   )\r
 {\r
   MICROCODE_FMP_PRIVATE_DATA *MicrocodeFmpPrivate;\r
-  EFI_STATUS                 Status;\r
+  MICROCODE_INFO             *MicrocodeInfo;\r
 \r
   if (Image == NULL || ImageSize == NULL) {\r
     return EFI_INVALID_PARAMETER;\r
@@ -186,8 +186,16 @@ FmpGetImage (
     return EFI_INVALID_PARAMETER;\r
   }\r
 \r
-  Status = MicrocodeRead(ImageIndex, (VOID *)Image, ImageSize);\r
-  return Status;\r
+  MicrocodeInfo = &MicrocodeFmpPrivate->MicrocodeInfo[ImageIndex - 1];\r
+\r
+  if (*ImageSize < MicrocodeInfo->TotalSize) {\r
+    *ImageSize = MicrocodeInfo->TotalSize;\r
+    return EFI_BUFFER_TOO_SMALL;\r
+  }\r
+\r
+  *ImageSize = MicrocodeInfo->TotalSize;\r
+  CopyMem (Image, MicrocodeInfo->MicrocodeEntryPoint, MicrocodeInfo->TotalSize);\r
+  return EFI_SUCCESS;\r
 }\r
 \r
 /**\r
@@ -263,7 +271,7 @@ FmpSetImage (
     return EFI_INVALID_PARAMETER;\r
   }\r
 \r
-  Status = MicrocodeWrite(ImageIndex, (VOID *)Image, ImageSize, &MicrocodeFmpPrivate->LastAttempt.LastAttemptVersion, &MicrocodeFmpPrivate->LastAttempt.LastAttemptStatus, AbortReason);\r
+  Status = MicrocodeWrite(MicrocodeFmpPrivate, (VOID *)Image, ImageSize, &MicrocodeFmpPrivate->LastAttempt.LastAttemptVersion, &MicrocodeFmpPrivate->LastAttempt.LastAttemptStatus, AbortReason);\r
   DEBUG((DEBUG_INFO, "SetImage - LastAttemp Version - 0x%x, State - 0x%x\n", MicrocodeFmpPrivate->LastAttempt.LastAttemptVersion, MicrocodeFmpPrivate->LastAttempt.LastAttemptStatus));\r
   VarStatus = gRT->SetVariable(\r
                      MICROCODE_FMP_LAST_ATTEMPT_VARIABLE_NAME,\r
@@ -417,17 +425,22 @@ InitializeMicrocodeDescriptor (
   IN MICROCODE_FMP_PRIVATE_DATA *MicrocodeFmpPrivate\r
   )\r
 {\r
-  UINT8  CurrentMicrocodeCount;\r
+  UINT8    CurrentMicrocodeCount;\r
 \r
-  CurrentMicrocodeCount = (UINT8)GetMicrocodeInfo(NULL, 0);\r
+  CurrentMicrocodeCount = (UINT8)GetMicrocodeInfo (MicrocodeFmpPrivate, 0, NULL, NULL);\r
 \r
   if (CurrentMicrocodeCount > MicrocodeFmpPrivate->DescriptorCount) {\r
     if (MicrocodeFmpPrivate->ImageDescriptor != NULL) {\r
       FreePool(MicrocodeFmpPrivate->ImageDescriptor);\r
       MicrocodeFmpPrivate->ImageDescriptor = NULL;\r
     }\r
+    if (MicrocodeFmpPrivate->MicrocodeInfo != NULL) {\r
+      FreePool(MicrocodeFmpPrivate->MicrocodeInfo);\r
+      MicrocodeFmpPrivate->MicrocodeInfo = NULL;\r
+    }\r
   } else {\r
     ZeroMem(MicrocodeFmpPrivate->ImageDescriptor, MicrocodeFmpPrivate->DescriptorCount * sizeof(EFI_FIRMWARE_IMAGE_DESCRIPTOR));\r
+    ZeroMem(MicrocodeFmpPrivate->MicrocodeInfo, MicrocodeFmpPrivate->DescriptorCount * sizeof(MICROCODE_INFO));\r
   }\r
 \r
   MicrocodeFmpPrivate->DescriptorCount = CurrentMicrocodeCount;\r
@@ -438,8 +451,14 @@ InitializeMicrocodeDescriptor (
       return EFI_OUT_OF_RESOURCES;\r
     }\r
   }\r
+  if (MicrocodeFmpPrivate->MicrocodeInfo == NULL) {\r
+    MicrocodeFmpPrivate->MicrocodeInfo = AllocateZeroPool(MicrocodeFmpPrivate->DescriptorCount * sizeof(MICROCODE_INFO));\r
+    if (MicrocodeFmpPrivate->MicrocodeInfo == NULL) {\r
+      return EFI_OUT_OF_RESOURCES;\r
+    }\r
+  }\r
 \r
-  CurrentMicrocodeCount = (UINT8)GetMicrocodeInfo(MicrocodeFmpPrivate->ImageDescriptor, MicrocodeFmpPrivate->DescriptorCount);\r
+  CurrentMicrocodeCount = (UINT8)GetMicrocodeInfo (MicrocodeFmpPrivate, MicrocodeFmpPrivate->DescriptorCount, MicrocodeFmpPrivate->ImageDescriptor, MicrocodeFmpPrivate->MicrocodeInfo);\r
   ASSERT(CurrentMicrocodeCount == MicrocodeFmpPrivate->DescriptorCount);\r
 \r
   return EFI_SUCCESS;\r
@@ -460,6 +479,7 @@ InitializePrivateData (
   EFI_STATUS       Status;\r
   EFI_STATUS       VarStatus;\r
   UINTN            VarSize;\r
+  BOOLEAN          Result;\r
 \r
   MicrocodeFmpPrivate->Signature       = MICROCODE_FMP_PRIVATE_DATA_SIGNATURE;\r
   MicrocodeFmpPrivate->Handle          = NULL;\r
@@ -481,6 +501,12 @@ InitializePrivateData (
   DEBUG((DEBUG_INFO, "GetLastAttemp - %r\n", VarStatus));\r
   DEBUG((DEBUG_INFO, "GetLastAttemp Version - 0x%x, State - 0x%x\n", MicrocodeFmpPrivate->LastAttempt.LastAttemptVersion, MicrocodeFmpPrivate->LastAttempt.LastAttemptStatus));\r
 \r
+  Result = GetMicrocodeRegion(&MicrocodeFmpPrivate->MicrocodePatchAddress, &MicrocodeFmpPrivate->MicrocodePatchRegionSize);\r
+  if (!Result) {\r
+    DEBUG((DEBUG_ERROR, "Fail to get Microcode Region\n"));\r
+    return EFI_NOT_FOUND;\r
+  }\r
+\r
   Status = InitializeMicrocodeDescriptor(MicrocodeFmpPrivate);\r
 \r
   return Status;\r