/** @file\r
BDS routines to handle capsules.\r
\r
-Copyright (c) 2004 - 2008, Intel Corporation. <BR>\r
-All rights reserved. This program and the accompanying materials\r
+Copyright (c) 2004 - 2013, Intel Corporation. All rights reserved.<BR>\r
+This program and the accompanying materials\r
are licensed and made available under the terms and conditions of the BSD License\r
which accompanies this distribution. The full text of the license may be found at\r
http://opensource.org/licenses/bsd-license.php\r
**/\r
#include "Bds.h"\r
\r
-/**\r
- This function locks the block \r
-\r
- @param CpuIo A instance of EFI_CPU_IO_PROTOCOL. \r
- @param Base The base address flash region to be locked.\r
-\r
-**/\r
-VOID\r
-BdsLockFv (\r
- IN EFI_CPU_IO_PROTOCOL *CpuIo,\r
- IN EFI_PHYSICAL_ADDRESS Base\r
- )\r
-{\r
- EFI_FV_BLOCK_MAP_ENTRY *BlockMap;\r
- EFI_FIRMWARE_VOLUME_HEADER *FvHeader;\r
- EFI_PHYSICAL_ADDRESS BaseAddress;\r
- UINT8 Data;\r
- UINT32 BlockLength;\r
- UINTN Index;\r
-\r
- BaseAddress = Base - 0x400000 + 2;\r
- FvHeader = (EFI_FIRMWARE_VOLUME_HEADER *) ((UINTN) (Base));\r
- BlockMap = &(FvHeader->BlockMap[0]);\r
-\r
- while ((BlockMap->NumBlocks != 0) && (BlockMap->Length != 0)) {\r
- BlockLength = BlockMap->Length;\r
- for (Index = 0; Index < BlockMap->NumBlocks; Index++) {\r
- CpuIo->Mem.Read (\r
- CpuIo,\r
- EfiCpuIoWidthUint8,\r
- BaseAddress,\r
- 1,\r
- &Data\r
- );\r
- Data = (UINT8) (Data | 0x3);\r
- CpuIo->Mem.Write (\r
- CpuIo,\r
- EfiCpuIoWidthUint8,\r
- BaseAddress,\r
- 1,\r
- &Data\r
- );\r
- BaseAddress += BlockLength;\r
- }\r
-\r
- BlockMap++;\r
- }\r
-}\r
-\r
/**\r
\r
This routine is called to see if there are any capsules we need to process.\r
\r
**/\r
EFI_STATUS\r
-ProcessCapsules (\r
+EFIAPI\r
+BdsProcessCapsules (\r
EFI_BOOT_MODE BootMode\r
)\r
{\r
VOID **CapsulePtr;\r
VOID **CapsulePtrCache;\r
EFI_GUID *CapsuleGuidCache; \r
- CAPSULE_HOB_INFO *CapsuleHobInfo;\r
+ BOOLEAN NeedReset;\r
\r
- CapsuleNumber = 0;\r
+ CapsuleNumber = 0;\r
CapsuleTotalNumber = 0;\r
- CacheIndex = 0;\r
- CacheNumber = 0;\r
- CapsulePtr = NULL;\r
- CapsulePtrCache = NULL;\r
- CapsuleGuidCache = NULL;\r
+ CacheIndex = 0;\r
+ CacheNumber = 0;\r
+ CapsulePtr = NULL;\r
+ CapsulePtrCache = NULL;\r
+ CapsuleGuidCache = NULL;\r
+ NeedReset = FALSE;\r
\r
//\r
// We don't do anything else if the boot mode is not flash-update\r
//\r
if (BootMode != BOOT_ON_FLASH_UPDATE) {\r
+ DEBUG ((EFI_D_ERROR, "Boot mode is not correct for capsule update.\n"));\r
return EFI_INVALID_PARAMETER;\r
}\r
\r
// Find all capsule images from hob\r
//\r
HobPointer.Raw = GetHobList ();\r
- while ((HobPointer.Raw = GetNextGuidHob (&gEfiCapsuleVendorGuid, HobPointer.Raw)) != NULL) {\r
+ while ((HobPointer.Raw = GetNextHob (EFI_HOB_TYPE_UEFI_CAPSULE, HobPointer.Raw)) != NULL) {\r
CapsuleTotalNumber ++;\r
-\r
HobPointer.Raw = GET_NEXT_HOB (HobPointer);\r
}\r
\r
//\r
// We didn't find a hob, so had no errors.\r
//\r
+ DEBUG ((EFI_D_ERROR, "We can not find capsule data in capsule update boot mode.\n"));\r
+ DEBUG ((EFI_D_ERROR, "Please check the followings are correct if unexpected capsule update error happens.\n"));\r
+ DEBUG ((EFI_D_ERROR, "1. CapsuleX64 is built as X64 module when PEI is IA32 and DXE is X64\n"));\r
+ DEBUG ((EFI_D_ERROR, "2. Capsule data should persist in memory across a system reset.\n"));\r
PlatformBdsLockNonUpdatableFlash ();\r
return EFI_SUCCESS;\r
}\r
// Find all capsule images from hob\r
//\r
HobPointer.Raw = GetHobList ();\r
- while ((HobPointer.Raw = GetNextGuidHob (&gEfiCapsuleVendorGuid, HobPointer.Raw)) != NULL) {\r
- CapsuleHobInfo = GET_GUID_HOB_DATA (HobPointer.Guid);\r
- CapsulePtr [CapsuleNumber++] = (VOID *)(UINTN)(CapsuleHobInfo->BaseAddress);\r
-\r
+ while ((HobPointer.Raw = GetNextHob (EFI_HOB_TYPE_UEFI_CAPSULE, HobPointer.Raw)) != NULL) {\r
+ CapsulePtr [CapsuleNumber++] = (VOID *) (UINTN) HobPointer.Capsule->BaseAddress;\r
HobPointer.Raw = GET_NEXT_HOB (HobPointer);\r
}\r
\r
for (Index = 0; Index < CapsuleTotalNumber; Index++) {\r
CapsuleHeader = (EFI_CAPSULE_HEADER*) CapsulePtr [Index];\r
if ((CapsuleHeader->Flags & CAPSULE_FLAGS_POPULATE_SYSTEM_TABLE) == 0) {\r
+ //\r
+ // Always reset system after all capsule processed if FMP capsule exist\r
+ //\r
+ if (CompareGuid (&gEfiFmpCapsuleGuid, &CapsuleHeader->CapsuleGuid)){\r
+ NeedReset = TRUE;\r
+ }\r
+\r
//\r
// Call capsule library to process capsule image.\r
//\r
}\r
}\r
\r
+ if (NeedReset) {\r
+ Print(L"Capsule Request Cold Reboot.\n");\r
+\r
+ for (Index = 5; Index > 0; Index--) {\r
+ Print(L"\rResetting system in %d seconds ...", Index);\r
+ gBS->Stall (1000000);\r
+ }\r
+\r
+ gRT->ResetSystem (EfiResetCold, EFI_SUCCESS, 0, NULL);\r
+\r
+ CpuDeadLoop ();\r
+ }\r
+\r
PlatformBdsLockNonUpdatableFlash ();\r
\r
//\r
\r
return Status;\r
}\r
+\r