summaryrefslogtreecommitdiffstats
path: root/MdeModulePkg/Library/DxeCapsuleLibFmp
diff options
context:
space:
mode:
authorStar Zeng <star.zeng@intel.com>2018-07-26 13:38:34 +0800
committerStar Zeng <star.zeng@intel.com>2018-08-01 10:15:15 +0800
commit69feaa37aeca6386de0fc635a1287e6e31851d7a (patch)
tree21389540282a45f1aafbf9b54902da51d1b5267a /MdeModulePkg/Library/DxeCapsuleLibFmp
parentfc0494a6540e9b3cca55f39c7e0d850e2bfd91bb (diff)
downloadedk2-69feaa37aeca6386de0fc635a1287e6e31851d7a.tar.gz
edk2-69feaa37aeca6386de0fc635a1287e6e31851d7a.tar.bz2
edk2-69feaa37aeca6386de0fc635a1287e6e31851d7a.zip
MdeModulePkg DxeCapsuleLib: Use Attr to know whether reset is required
Current DxeCapsuleLibFmp always do reset for FMP capsule. Actually, the code should use Attributes from FMP descriptor to know whether reset is required or not. Cc: Jiewen Yao <jiewen.yao@intel.com> Cc: Michael D Kinney <michael.d.kinney@intel.com> Contributed-under: TianoCore Contribution Agreement 1.1 Signed-off-by: Star Zeng <star.zeng@intel.com> Reviewed-by: Jiewen Yao <jiewen.yao@intel.com>
Diffstat (limited to 'MdeModulePkg/Library/DxeCapsuleLibFmp')
-rw-r--r--MdeModulePkg/Library/DxeCapsuleLibFmp/DxeCapsuleLib.c134
-rw-r--r--MdeModulePkg/Library/DxeCapsuleLibFmp/DxeCapsuleProcessLib.c40
2 files changed, 134 insertions, 40 deletions
diff --git a/MdeModulePkg/Library/DxeCapsuleLibFmp/DxeCapsuleLib.c b/MdeModulePkg/Library/DxeCapsuleLibFmp/DxeCapsuleLib.c
index 3c283e2513..d4026dd5c7 100644
--- a/MdeModulePkg/Library/DxeCapsuleLibFmp/DxeCapsuleLib.c
+++ b/MdeModulePkg/Library/DxeCapsuleLibFmp/DxeCapsuleLib.c
@@ -618,11 +618,14 @@ DumpAllFmpInfo (
@param[in] UpdateImageTypeId Used to identify device firmware targeted by this update.
@param[in] UpdateHardwareInstance The HardwareInstance to target with this update.
- @param[in,out] NoHandles The number of handles returned in Buffer.
- @param[out] Buffer[out] A pointer to the buffer to return the requested array of handles.
-
- @retval EFI_SUCCESS The array of handles was returned in Buffer, and the number of
- handles in Buffer was returned in NoHandles.
+ @param[out] NoHandles The number of handles returned in HandleBuf.
+ @param[out] HandleBuf A pointer to the buffer to return the requested array of handles.
+ @param[out] ResetRequiredBuf A pointer to the buffer to return reset required flag for
+ the requested array of handles.
+
+ @retval EFI_SUCCESS The array of handles and their reset required flag were returned in
+ HandleBuf and ResetRequiredBuf, and the number of handles in HandleBuf
+ was returned in NoHandles.
@retval EFI_NOT_FOUND No handles match the search.
@retval EFI_OUT_OF_RESOURCES There is not enough pool memory to store the matching results.
**/
@@ -630,14 +633,16 @@ EFI_STATUS
GetFmpHandleBufferByType (
IN EFI_GUID *UpdateImageTypeId,
IN UINT64 UpdateHardwareInstance,
- IN OUT UINTN *NoHandles,
- OUT EFI_HANDLE **Buffer
+ OUT UINTN *NoHandles, OPTIONAL
+ OUT EFI_HANDLE **HandleBuf, OPTIONAL
+ OUT BOOLEAN **ResetRequiredBuf OPTIONAL
)
{
EFI_STATUS Status;
EFI_HANDLE *HandleBuffer;
UINTN NumberOfHandles;
EFI_HANDLE *MatchedHandleBuffer;
+ BOOLEAN *MatchedResetRequiredBuffer;
UINTN MatchedNumberOfHandles;
EFI_FIRMWARE_MANAGEMENT_PROTOCOL *Fmp;
UINTN Index;
@@ -651,8 +656,15 @@ GetFmpHandleBufferByType (
UINTN Index2;
EFI_FIRMWARE_IMAGE_DESCRIPTOR *TempFmpImageInfo;
- *NoHandles = 0;
- *Buffer = NULL;
+ if (NoHandles != NULL) {
+ *NoHandles = 0;
+ }
+ if (HandleBuf != NULL) {
+ *HandleBuf = NULL;
+ }
+ if (ResetRequiredBuf != NULL) {
+ *ResetRequiredBuf = NULL;
+ }
Status = gBS->LocateHandleBuffer (
ByProtocol,
@@ -666,10 +678,26 @@ GetFmpHandleBufferByType (
}
MatchedNumberOfHandles = 0;
- MatchedHandleBuffer = AllocateZeroPool (sizeof(EFI_HANDLE) * NumberOfHandles);
- if (MatchedHandleBuffer == NULL) {
- FreePool (HandleBuffer);
- return EFI_OUT_OF_RESOURCES;
+
+ MatchedHandleBuffer = NULL;
+ if (HandleBuf != NULL) {
+ MatchedHandleBuffer = AllocateZeroPool (sizeof(EFI_HANDLE) * NumberOfHandles);
+ if (MatchedHandleBuffer == NULL) {
+ FreePool (HandleBuffer);
+ return EFI_OUT_OF_RESOURCES;
+ }
+ }
+
+ MatchedResetRequiredBuffer = NULL;
+ if (ResetRequiredBuf != NULL) {
+ MatchedResetRequiredBuffer = AllocateZeroPool (sizeof(BOOLEAN) * NumberOfHandles);
+ if (MatchedResetRequiredBuffer == NULL) {
+ if (MatchedHandleBuffer != NULL) {
+ FreePool (MatchedHandleBuffer);
+ }
+ FreePool (HandleBuffer);
+ return EFI_OUT_OF_RESOURCES;
+ }
}
for (Index = 0; Index < NumberOfHandles; Index++) {
@@ -731,7 +759,15 @@ GetFmpHandleBufferByType (
if ((UpdateHardwareInstance == 0) ||
((FmpImageInfoDescriptorVer >= EFI_FIRMWARE_IMAGE_DESCRIPTOR_VERSION) &&
(UpdateHardwareInstance == TempFmpImageInfo->HardwareInstance))) {
- MatchedHandleBuffer[MatchedNumberOfHandles] = HandleBuffer[Index];
+ if (MatchedHandleBuffer != NULL) {
+ MatchedHandleBuffer[MatchedNumberOfHandles] = HandleBuffer[Index];
+ }
+ if (MatchedResetRequiredBuffer != NULL) {
+ MatchedResetRequiredBuffer[MatchedNumberOfHandles] = (((TempFmpImageInfo->AttributesSupported &
+ IMAGE_ATTRIBUTE_RESET_REQUIRED) != 0) &&
+ ((TempFmpImageInfo->AttributesSetting &
+ IMAGE_ATTRIBUTE_RESET_REQUIRED) != 0));
+ }
MatchedNumberOfHandles++;
break;
}
@@ -745,8 +781,15 @@ GetFmpHandleBufferByType (
return EFI_NOT_FOUND;
}
- *NoHandles = MatchedNumberOfHandles;
- *Buffer = MatchedHandleBuffer;
+ if (NoHandles != NULL) {
+ *NoHandles = MatchedNumberOfHandles;
+ }
+ if (HandleBuf != NULL) {
+ *HandleBuf = MatchedHandleBuffer;
+ }
+ if (ResetRequiredBuf != NULL) {
+ *ResetRequiredBuf = MatchedResetRequiredBuffer;
+ }
return EFI_SUCCESS;
}
@@ -1074,7 +1117,8 @@ RecordFmpCapsuleStatus (
This function need support nested FMP capsule.
- @param[in] CapsuleHeader Points to a capsule header.
+ @param[in] CapsuleHeader Points to a capsule header.
+ @param[out] ResetRequired Indicates whether reset is required or not.
@retval EFI_SUCESS Process Capsule Image successfully.
@retval EFI_UNSUPPORTED Capsule image is not supported by the firmware.
@@ -1084,7 +1128,8 @@ RecordFmpCapsuleStatus (
**/
EFI_STATUS
ProcessFmpCapsuleImage (
- IN EFI_CAPSULE_HEADER *CapsuleHeader
+ IN EFI_CAPSULE_HEADER *CapsuleHeader,
+ OUT BOOLEAN *ResetRequired OPTIONAL
)
{
EFI_STATUS Status;
@@ -1094,6 +1139,7 @@ ProcessFmpCapsuleImage (
UINT32 ItemNum;
UINTN Index;
EFI_HANDLE *HandleBuffer;
+ BOOLEAN *ResetRequiredBuffer;
UINTN NumberOfHandles;
UINTN DriverLen;
UINT64 UpdateHardwareInstance;
@@ -1102,7 +1148,7 @@ ProcessFmpCapsuleImage (
BOOLEAN Abort;
if (!IsFmpCapsuleGuid(&CapsuleHeader->CapsuleGuid)) {
- return ProcessFmpCapsuleImage ((EFI_CAPSULE_HEADER *)((UINTN)CapsuleHeader + CapsuleHeader->HeaderSize));
+ return ProcessFmpCapsuleImage ((EFI_CAPSULE_HEADER *)((UINTN)CapsuleHeader + CapsuleHeader->HeaderSize), ResetRequired);
}
NotReady = FALSE;
@@ -1172,7 +1218,8 @@ ProcessFmpCapsuleImage (
&ImageHeader->UpdateImageTypeId,
UpdateHardwareInstance,
&NumberOfHandles,
- &HandleBuffer
+ &HandleBuffer,
+ &ResetRequiredBuffer
);
if (EFI_ERROR(Status)) {
NotReady = TRUE;
@@ -1205,6 +1252,10 @@ ProcessFmpCapsuleImage (
);
if (Status != EFI_SUCCESS) {
Abort = TRUE;
+ } else {
+ if (ResetRequired != NULL) {
+ *ResetRequired |= ResetRequiredBuffer[Index2];
+ }
}
RecordFmpCapsuleStatus (
@@ -1218,6 +1269,9 @@ ProcessFmpCapsuleImage (
if (HandleBuffer != NULL) {
FreePool(HandleBuffer);
}
+ if (ResetRequiredBuffer != NULL) {
+ FreePool(ResetRequiredBuffer);
+ }
}
if (NotReady) {
@@ -1252,8 +1306,6 @@ IsNestedFmpCapsule (
UINTN NestedCapsuleSize;
ESRT_MANAGEMENT_PROTOCOL *EsrtProtocol;
EFI_SYSTEM_RESOURCE_ENTRY Entry;
- EFI_HANDLE *HandleBuffer;
- UINTN NumberOfHandles;
EsrtGuidFound = FALSE;
if (mIsVirtualAddrConverted) {
@@ -1282,19 +1334,16 @@ IsNestedFmpCapsule (
// Check Firmware Management Protocols
//
if (!EsrtGuidFound) {
- HandleBuffer = NULL;
Status = GetFmpHandleBufferByType (
&CapsuleHeader->CapsuleGuid,
0,
- &NumberOfHandles,
- &HandleBuffer
+ NULL,
+ NULL,
+ NULL
);
if (!EFI_ERROR(Status)) {
EsrtGuidFound = TRUE;
}
- if (HandleBuffer != NULL) {
- FreePool (HandleBuffer);
- }
}
}
if (!EsrtGuidFound) {
@@ -1382,6 +1431,7 @@ SupportCapsuleImage (
Caution: This function may receive untrusted input.
@param[in] CapsuleHeader Points to a capsule header.
+ @param[out] ResetRequired Indicates whether reset is required or not.
@retval EFI_SUCESS Process Capsule Image successfully.
@retval EFI_UNSUPPORTED Capsule image is not supported by the firmware.
@@ -1390,8 +1440,9 @@ SupportCapsuleImage (
**/
EFI_STATUS
EFIAPI
-ProcessCapsuleImage (
- IN EFI_CAPSULE_HEADER *CapsuleHeader
+ProcessThisCapsuleImage (
+ IN EFI_CAPSULE_HEADER *CapsuleHeader,
+ OUT BOOLEAN *ResetRequired OPTIONAL
)
{
EFI_STATUS Status;
@@ -1428,7 +1479,7 @@ ProcessCapsuleImage (
// Process EFI FMP Capsule
//
DEBUG((DEBUG_INFO, "ProcessFmpCapsuleImage ...\n"));
- Status = ProcessFmpCapsuleImage(CapsuleHeader);
+ Status = ProcessFmpCapsuleImage(CapsuleHeader, ResetRequired);
DEBUG((DEBUG_INFO, "ProcessFmpCapsuleImage - %r\n", Status));
return Status;
@@ -1438,6 +1489,27 @@ ProcessCapsuleImage (
}
/**
+ The firmware implements to process the capsule image.
+
+ Caution: This function may receive untrusted input.
+
+ @param[in] CapsuleHeader Points to a capsule header.
+
+ @retval EFI_SUCESS Process Capsule Image successfully.
+ @retval EFI_UNSUPPORTED Capsule image is not supported by the firmware.
+ @retval EFI_VOLUME_CORRUPTED FV volume in the capsule is corrupted.
+ @retval EFI_OUT_OF_RESOURCES Not enough memory.
+**/
+EFI_STATUS
+EFIAPI
+ProcessCapsuleImage (
+ IN EFI_CAPSULE_HEADER *CapsuleHeader
+ )
+{
+ return ProcessThisCapsuleImage (CapsuleHeader, NULL);
+}
+
+/**
Callback function executed when the EndOfDxe event group is signaled.
@param[in] Event Event whose notification function is being invoked.
diff --git a/MdeModulePkg/Library/DxeCapsuleLibFmp/DxeCapsuleProcessLib.c b/MdeModulePkg/Library/DxeCapsuleLibFmp/DxeCapsuleProcessLib.c
index 26ca4e295f..176dea1960 100644
--- a/MdeModulePkg/Library/DxeCapsuleLibFmp/DxeCapsuleProcessLib.c
+++ b/MdeModulePkg/Library/DxeCapsuleLibFmp/DxeCapsuleProcessLib.c
@@ -99,13 +99,33 @@ IsValidCapsuleHeader (
);
extern BOOLEAN mDxeCapsuleLibEndOfDxe;
-BOOLEAN mNeedReset;
+BOOLEAN mNeedReset = FALSE;
VOID **mCapsulePtr;
EFI_STATUS *mCapsuleStatusArray;
UINT32 mCapsuleTotalNumber;
/**
+ The firmware implements to process the capsule image.
+
+ Caution: This function may receive untrusted input.
+
+ @param[in] CapsuleHeader Points to a capsule header.
+ @param[out] ResetRequired Indicates whether reset is required or not.
+
+ @retval EFI_SUCESS Process Capsule Image successfully.
+ @retval EFI_UNSUPPORTED Capsule image is not supported by the firmware.
+ @retval EFI_VOLUME_CORRUPTED FV volume in the capsule is corrupted.
+ @retval EFI_OUT_OF_RESOURCES Not enough memory.
+**/
+EFI_STATUS
+EFIAPI
+ProcessThisCapsuleImage (
+ IN EFI_CAPSULE_HEADER *CapsuleHeader,
+ OUT BOOLEAN *ResetRequired OPTIONAL
+ );
+
+/**
Function indicate the current completion progress of the firmware
update. Platform may override with own specific progress function.
@@ -381,6 +401,7 @@ ProcessTheseCapsules (
UINT32 Index;
ESRT_MANAGEMENT_PROTOCOL *EsrtManagement;
UINT16 EmbeddedDriverCount;
+ BOOLEAN ResetRequired;
REPORT_STATUS_CODE(EFI_PROGRESS_CODE, (EFI_SOFTWARE | PcdGet32(PcdStatusCodeSubClassCapsule) | PcdGet32(PcdCapsuleStatusCodeProcessCapsulesBegin)));
@@ -416,11 +437,11 @@ ProcessTheseCapsules (
for (Index = 0; Index < mCapsuleTotalNumber; Index++) {
CapsuleHeader = (EFI_CAPSULE_HEADER*) mCapsulePtr [Index];
if (CompareGuid (&CapsuleHeader->CapsuleGuid, &gWindowsUxCapsuleGuid)) {
- DEBUG ((DEBUG_INFO, "ProcessCapsuleImage (Ux) - 0x%x\n", CapsuleHeader));
+ DEBUG ((DEBUG_INFO, "ProcessThisCapsuleImage (Ux) - 0x%x\n", CapsuleHeader));
DEBUG ((DEBUG_INFO, "Display logo capsule is found.\n"));
- Status = ProcessCapsuleImage (CapsuleHeader);
+ Status = ProcessThisCapsuleImage (CapsuleHeader, NULL);
mCapsuleStatusArray [Index] = EFI_SUCCESS;
- DEBUG((DEBUG_INFO, "ProcessCapsuleImage (Ux) - %r\n", Status));
+ DEBUG((DEBUG_INFO, "ProcessThisCapsuleImage (Ux) - %r\n", Status));
break;
}
}
@@ -454,10 +475,11 @@ ProcessTheseCapsules (
}
if ((!FirstRound) || (EmbeddedDriverCount == 0)) {
- DEBUG((DEBUG_INFO, "ProcessCapsuleImage - 0x%x\n", CapsuleHeader));
- Status = ProcessCapsuleImage (CapsuleHeader);
+ DEBUG((DEBUG_INFO, "ProcessThisCapsuleImage - 0x%x\n", CapsuleHeader));
+ ResetRequired = FALSE;
+ Status = ProcessThisCapsuleImage (CapsuleHeader, &ResetRequired);
mCapsuleStatusArray [Index] = Status;
- DEBUG((DEBUG_INFO, "ProcessCapsuleImage - %r\n", Status));
+ DEBUG((DEBUG_INFO, "ProcessThisCapsuleImage - %r\n", Status));
if (Status != EFI_NOT_READY) {
if (EFI_ERROR(Status)) {
@@ -467,8 +489,8 @@ ProcessTheseCapsules (
REPORT_STATUS_CODE(EFI_PROGRESS_CODE, (EFI_SOFTWARE | PcdGet32(PcdStatusCodeSubClassCapsule) | PcdGet32(PcdCapsuleStatusCodeUpdateFirmwareSuccess)));
}
- if ((CapsuleHeader->Flags & PcdGet16(PcdSystemRebootAfterCapsuleProcessFlag)) != 0 ||
- IsFmpCapsule(CapsuleHeader)) {
+ mNeedReset |= ResetRequired;
+ if ((CapsuleHeader->Flags & PcdGet16(PcdSystemRebootAfterCapsuleProcessFlag)) != 0) {
mNeedReset = TRUE;
}
}