EFI_LOADED_IMAGE_PROTOCOL *ImageInfo;\r
EFI_BLOCK_IO_PROTOCOL *BlkIo;\r
VOID *Buffer;\r
+ LIST_ENTRY TempBootLists;\r
\r
//\r
// Record the performance data for End of BDS\r
//\r
return BdsLibDoLegacyBoot (Option);\r
}\r
+ \r
+ //\r
+ // If the boot option point to Internal FV shell, make sure it is valid\r
+ //\r
+ Status = UpdateFvFileDevicePath (&DevicePath, &gEfiShellFileGuid);\r
+ if (!EFI_ERROR(Status)) {\r
+ if (Option->DevicePath != NULL) {\r
+ FreePool (Option->DevicePath);\r
+ }\r
+ Option->DevicePath = AllocateZeroPool (GetDevicePathSize (DevicePath));\r
+ CopyMem (Option->DevicePath, DevicePath, GetDevicePathSize (DevicePath));\r
+ //\r
+ // Update the shell boot option\r
+ //\r
+ InitializeListHead (&TempBootLists);\r
+ BdsLibRegisterNewOption (&TempBootLists, DevicePath, L"EFI Internal Shell", L"BootOrder"); \r
+ }\r
\r
DEBUG ((EFI_D_INFO | EFI_D_LOAD, "Booting EFI 1.1 way %S\n", Option->Description));\r
\r
}\r
\r
}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+UpdateFvFileDevicePath (\r
+ IN OUT EFI_DEVICE_PATH_PROTOCOL **DevicePath,\r
+ IN EFI_GUID *FileGuid\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+ According to a file guild, check a Fv file device path is valid. If it is invalid,\r
+ try to return the valid device path.\r
+ FV address maybe changes for memory layout adjust from time to time, use this funciton \r
+ could promise the Fv file device path is right.\r
+\r
+Arguments:\r
+ DevicePath - on input, the Fv file device path need to check\r
+ on output, the updated valid Fv file device path\r
+ \r
+ FileGuid - the Fv file guild\r
+ \r
+Returns:\r
+ EFI_INVALID_PARAMETER - the input DevicePath or FileGuid is invalid parameter\r
+ EFI_UNSUPPORTED - the input DevicePath does not contain Fv file guild at all\r
+ EFI_ALREADY_STARTED - the input DevicePath has pointed to Fv file, it is valid\r
+ EFI_SUCCESS - has successfully updated the invalid DevicePath, and return the updated\r
+ device path in DevicePath\r
+ \r
+--*/\r
+{\r
+ EFI_DEVICE_PATH_PROTOCOL *TempDevicePath;\r
+ EFI_DEVICE_PATH_PROTOCOL *LastDeviceNode;\r
+ EFI_STATUS Status;\r
+ EFI_GUID *GuidPoint;\r
+ UINTN Index;\r
+ UINTN FvHandleCount;\r
+ EFI_HANDLE *FvHandleBuffer;\r
+ EFI_FV_FILETYPE Type;\r
+ UINTN Size;\r
+ EFI_FV_FILE_ATTRIBUTES Attributes;\r
+ UINT32 AuthenticationStatus;\r
+ BOOLEAN FindFvFile;\r
+ EFI_LOADED_IMAGE_PROTOCOL *LoadedImage;\r
+ EFI_FIRMWARE_VOLUME2_PROTOCOL *Fv;\r
+ MEDIA_FW_VOL_FILEPATH_DEVICE_PATH FvFileNode;\r
+ EFI_HANDLE FoundFvHandle;\r
+ EFI_DEVICE_PATH_PROTOCOL *NewDevicePath;\r
+ \r
+ if ((DevicePath == NULL) || (*DevicePath == NULL)) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+ if (FileGuid == NULL) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+ //\r
+ // Check whether the device path point to the default the input Fv file\r
+ //\r
+ TempDevicePath = *DevicePath; \r
+ LastDeviceNode = TempDevicePath;\r
+ while (!EfiIsDevicePathEnd (TempDevicePath)) {\r
+ LastDeviceNode = TempDevicePath;\r
+ TempDevicePath = EfiNextDevicePathNode (TempDevicePath);\r
+ }\r
+\r
+ GuidPoint = EfiGetNameGuidFromFwVolDevicePathNode ((CONST MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *)LastDeviceNode);\r
+\r
+ if (GuidPoint == NULL) {\r
+ //\r
+ // if this option does not points to a Fv file, just return EFI_UNSUPPORTED\r
+ //\r
+ return EFI_UNSUPPORTED;\r
+ }\r
+\r
+ if (!CompareGuid (GuidPoint, FileGuid)) {\r
+ //\r
+ // If the Fv file is not the input file guid, just return EFI_UNSUPPORTED\r
+ //\r
+ return EFI_UNSUPPORTED;\r
+ }\r
+ \r
+ //\r
+ // Check whether the input Fv file device path is valid\r
+ //\r
+ TempDevicePath = *DevicePath; \r
+ FoundFvHandle = NULL;\r
+ Status = gBS->LocateDevicePath (\r
+ &gEfiFirmwareVolume2ProtocolGuid,\r
+ &TempDevicePath, \r
+ &FoundFvHandle\r
+ );\r
+ if (!EFI_ERROR (Status)) {\r
+ Status = gBS->HandleProtocol (\r
+ FoundFvHandle,\r
+ &gEfiFirmwareVolume2ProtocolGuid,\r
+ (VOID **) &Fv\r
+ );\r
+ if (!EFI_ERROR (Status)) {\r
+ //\r
+ // Set FV ReadFile Buffer as NULL, only need to check whether input Fv file exist there\r
+ //\r
+ Status = Fv->ReadFile (\r
+ Fv,\r
+ FileGuid,\r
+ NULL,\r
+ &Size,\r
+ &Type,\r
+ &Attributes,\r
+ &AuthenticationStatus\r
+ );\r
+ if (!EFI_ERROR (Status)) {\r
+ return EFI_ALREADY_STARTED;\r
+ }\r
+ }\r
+ }\r
+ \r
+ //\r
+ // Look for the input wanted FV file in current FV\r
+ // First, try to look for in Bds own FV. Bds and input wanted FV file usually are in the same FV\r
+ //\r
+ FindFvFile = FALSE;\r
+ FoundFvHandle = NULL;\r
+ Status = gBS->HandleProtocol (\r
+ mBdsImageHandle,\r
+ &gEfiLoadedImageProtocolGuid,\r
+ (VOID **) &LoadedImage\r
+ );\r
+ if (!EFI_ERROR (Status)) {\r
+ Status = gBS->HandleProtocol (\r
+ LoadedImage->DeviceHandle,\r
+ &gEfiFirmwareVolume2ProtocolGuid,\r
+ (VOID **) &Fv\r
+ );\r
+ if (!EFI_ERROR (Status)) {\r
+ Status = Fv->ReadFile (\r
+ Fv,\r
+ FileGuid,\r
+ NULL,\r
+ &Size,\r
+ &Type,\r
+ &Attributes,\r
+ &AuthenticationStatus\r
+ );\r
+ if (!EFI_ERROR (Status)) {\r
+ FindFvFile = TRUE;\r
+ FoundFvHandle = LoadedImage->DeviceHandle;\r
+ }\r
+ }\r
+ }\r
+ //\r
+ // Second, if fail to find, try to enumerate all FV\r
+ //\r
+ if (!FindFvFile) {\r
+ gBS->LocateHandleBuffer (\r
+ ByProtocol,\r
+ &gEfiFirmwareVolume2ProtocolGuid,\r
+ NULL,\r
+ &FvHandleCount,\r
+ &FvHandleBuffer\r
+ );\r
+ for (Index = 0; Index < FvHandleCount; Index++) {\r
+ gBS->HandleProtocol (\r
+ FvHandleBuffer[Index],\r
+ &gEfiFirmwareVolume2ProtocolGuid,\r
+ (VOID **) &Fv\r
+ );\r
+\r
+ Status = Fv->ReadFile (\r
+ Fv,\r
+ FileGuid,\r
+ NULL,\r
+ &Size,\r
+ &Type,\r
+ &Attributes,\r
+ &AuthenticationStatus\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ //\r
+ // Skip if input Fv file not in the FV\r
+ //\r
+ continue;\r
+ }\r
+ FindFvFile = TRUE;\r
+ FoundFvHandle = FvHandleBuffer[Index];\r
+ break;\r
+ } \r
+ }\r
+\r
+ if (FindFvFile) {\r
+ //\r
+ // Build the shell device path\r
+ //\r
+ NewDevicePath = DevicePathFromHandle (FoundFvHandle);\r
+ EfiInitializeFwVolDevicepathNode (&FvFileNode, FileGuid);\r
+ NewDevicePath = AppendDevicePathNode (NewDevicePath, (EFI_DEVICE_PATH_PROTOCOL *) &FvFileNode);\r
+ *DevicePath = NewDevicePath;\r
+ return EFI_SUCCESS;\r
+ }\r
+\r
+ return EFI_NOT_FOUND;\r
+}\r