/** Extract device path for given HII handle and class guid. @param Handle The HII handle. @retval NULL Fail to get the device path string. @return PathString Get the device path string. **/ CHAR16 * BmmExtractDevicePathFromHiiHandle ( IN EFI_HII_HANDLE Handle ) { EFI_STATUS Status; EFI_HANDLE DriverHandle; ASSERT (Handle != NULL); if (Handle == NULL) { return NULL; } Status = gHiiDatabase->GetPackageListHandle (gHiiDatabase, Handle, &DriverHandle); if (EFI_ERROR (Status)) { return NULL; } // // Get device path string. // return ConvertDevicePathToText(DevicePathFromHandle (DriverHandle), FALSE, FALSE); }
/** This function gets driver name from Component Name 2 protocol interface and Component Name protocol interface in turn. It first tries UEFI 2.0 Component Name 2 protocol interface and try to get the driver name. If the attempt fails, it then gets the driver name from EFI 1.1 Component Name protocol for backward compatibility support. @param DriverBindingHandle The handle on which the Component Name (2) protocol instance is retrieved. @return A pointer to the Unicode string to return. This Unicode string is the name of the controller specified by ControllerHandle and ChildHandle. **/ CHAR16 * DriverHealthManagerGetDriverName ( IN EFI_HANDLE DriverBindingHandle ) { EFI_STATUS Status; CHAR16 *DriverName; // // Get driver name from UEFI 2.0 Component Name 2 protocol interface. // Status = DriverHealthManagerGetDriverNameWorker (&gEfiComponentName2ProtocolGuid, DriverBindingHandle, &DriverName); if (EFI_ERROR (Status)) { // // If it fails to get the driver name from Component Name protocol interface, we should fall back on // EFI 1.1 Component Name protocol interface. // Status = DriverHealthManagerGetDriverNameWorker (&gEfiComponentNameProtocolGuid, DriverBindingHandle, &DriverName); } if (!EFI_ERROR (Status)) { return AllocateCopyPool (StrSize (DriverName), DriverName); } else { return ConvertDevicePathToText (DevicePathFromHandle (DriverBindingHandle), FALSE, TRUE); } }
/** Gets the name of the loaded image. @param[in] TheHandle The handle of the driver to get info on. @param[out] Name The pointer to the pointer. Valid upon a successful return. @retval EFI_SUCCESS The operation was successful. **/ EFI_STATUS GetDriverImageName ( IN EFI_HANDLE TheHandle, OUT CHAR16 **Name ) { // get loaded image and devicepathtotext on image->Filepath EFI_LOADED_IMAGE_PROTOCOL *LoadedImage; EFI_STATUS Status; EFI_DEVICE_PATH_PROTOCOL *DevicePath; if (TheHandle == NULL || Name == NULL) { return (EFI_INVALID_PARAMETER); } Status = gBS->OpenProtocol ( TheHandle, &gEfiLoadedImageProtocolGuid, (VOID **) &LoadedImage, gImageHandle, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL ); if (EFI_ERROR(Status)) { return (Status); } DevicePath = LoadedImage->FilePath; *Name = ConvertDevicePathToText(DevicePath, TRUE, TRUE); return (EFI_SUCCESS); }
EFIAPI DevicePathToStr ( IN EFI_DEVICE_PATH_PROTOCOL *DevPath ) { return ConvertDevicePathToText (DevPath, TRUE, TRUE); }
/** Get a device path (in text format) for a given handle. @param[in] TheHandle The handle to get the device path for. @retval NULL An error occured. @return A pointer to the driver path as a string. The callee must free this memory. **/ CHAR16* GetDevicePathTextForHandle( IN EFI_HANDLE TheHandle ) { EFI_STATUS Status; EFI_LOADED_IMAGE_PROTOCOL *LoadedImage; EFI_DEVICE_PATH_PROTOCOL *ImageDevicePath; EFI_DEVICE_PATH_PROTOCOL *FinalPath; CHAR16 *RetVal; FinalPath = NULL; Status = gBS->OpenProtocol ( TheHandle, &gEfiLoadedImageProtocolGuid, (VOID**)&LoadedImage, gImageHandle, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL ); if (!EFI_ERROR (Status)) { Status = gBS->OpenProtocol ( LoadedImage->DeviceHandle, &gEfiDevicePathProtocolGuid, (VOID**)&ImageDevicePath, gImageHandle, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL ); if (!EFI_ERROR (Status)) { FinalPath = AppendDevicePath (ImageDevicePath, LoadedImage->FilePath); gBS->CloseProtocol( LoadedImage->DeviceHandle, &gEfiDevicePathProtocolGuid, gImageHandle, NULL); } gBS->CloseProtocol( TheHandle, &gEfiLoadedImageProtocolGuid, gImageHandle, NULL); } if (FinalPath == NULL) { return (NULL); } RetVal = gEfiShellProtocol->GetFilePathFromDevicePath(FinalPath); if (RetVal == NULL) { RetVal = ConvertDevicePathToText(FinalPath, TRUE, TRUE); } FreePool(FinalPath); return (RetVal); }
/** Locate all handles that carry the specified protocol, filter them with a callback function, and pass each handle that passes the filter to another callback. @param[in] ProtocolGuid The protocol to look for. @param[in] Filter The filter function to pass each handle to. If this parameter is NULL, then all handles are processed. @param[in] Process The callback function to pass each handle to that clears the filter. **/ STATIC VOID FilterAndProcess ( IN EFI_GUID *ProtocolGuid, IN FILTER_FUNCTION Filter OPTIONAL, IN CALLBACK_FUNCTION Process ) { EFI_STATUS Status; EFI_HANDLE *Handles; UINTN NoHandles; UINTN Idx; Status = gBS->LocateHandleBuffer (ByProtocol, ProtocolGuid, NULL /* SearchKey */, &NoHandles, &Handles); if (EFI_ERROR (Status)) { // // This is not an error, just an informative condition. // DEBUG ((EFI_D_VERBOSE, "%a: %g: %r\n", __FUNCTION__, ProtocolGuid, Status)); return; } ASSERT (NoHandles > 0); for (Idx = 0; Idx < NoHandles; ++Idx) { CHAR16 *DevicePathText; STATIC CHAR16 Fallback[] = L"<device path unavailable>"; // // The ConvertDevicePathToText() function handles NULL input transparently. // DevicePathText = ConvertDevicePathToText ( DevicePathFromHandle (Handles[Idx]), FALSE, // DisplayOnly FALSE // AllowShortcuts ); if (DevicePathText == NULL) { DevicePathText = Fallback; } if (Filter == NULL || Filter (Handles[Idx], DevicePathText)) { Process (Handles[Idx], DevicePathText); } if (DevicePathText != Fallback) { FreePool (DevicePathText); } } gBS->FreePool (Handles); }
/** Dump SMI child context. @param HandlerType the handler type @param Context the handler context @param ContextSize the handler context size **/ VOID DumpSmiChildContext ( IN EFI_GUID *HandlerType, IN VOID *Context, IN UINTN ContextSize ) { CHAR16 *Str; if (CompareGuid (HandlerType, &gEfiSmmSwDispatch2ProtocolGuid)) { Print(L" SwSmi=\"0x%lx\"", ((SMI_HANDLER_PROFILE_SW_REGISTER_CONTEXT *)Context)->SwSmiInputValue); } else if (CompareGuid (HandlerType, &gEfiSmmSxDispatch2ProtocolGuid)) { Print(L" SxType=\"%a\"", SxTypeToString(((EFI_SMM_SX_REGISTER_CONTEXT *)Context)->Type)); Print(L" SxPhase=\"%a\"", SxPhaseToString(((EFI_SMM_SX_REGISTER_CONTEXT *)Context)->Phase)); } else if (CompareGuid (HandlerType, &gEfiSmmPowerButtonDispatch2ProtocolGuid)) { Print(L" PowerButtonPhase=\"%a\"", PowerButtonPhaseToString(((EFI_SMM_POWER_BUTTON_REGISTER_CONTEXT *)Context)->Phase)); } else if (CompareGuid (HandlerType, &gEfiSmmStandbyButtonDispatch2ProtocolGuid)) { Print(L" StandbyButtonPhase=\"%a\"", StandbyButtonPhaseToString(((EFI_SMM_STANDBY_BUTTON_REGISTER_CONTEXT *)Context)->Phase)); } else if (CompareGuid (HandlerType, &gEfiSmmPeriodicTimerDispatch2ProtocolGuid)) { Print(L" PeriodicTimerPeriod=\"%ld\"", ((EFI_SMM_PERIODIC_TIMER_REGISTER_CONTEXT *)Context)->Period); Print(L" PeriodicTimerSmiTickInterval=\"%ld\"", ((EFI_SMM_PERIODIC_TIMER_REGISTER_CONTEXT *)Context)->SmiTickInterval); } else if (CompareGuid (HandlerType, &gEfiSmmGpiDispatch2ProtocolGuid)) { Print(L" GpiNum=\"0x%lx\"", ((EFI_SMM_GPI_REGISTER_CONTEXT *)Context)->GpiNum); } else if (CompareGuid (HandlerType, &gEfiSmmIoTrapDispatch2ProtocolGuid)) { Print(L" IoTrapAddress=\"0x%x\"", ((EFI_SMM_IO_TRAP_REGISTER_CONTEXT *)Context)->Address); Print(L" IoTrapLength=\"0x%x\"", ((EFI_SMM_IO_TRAP_REGISTER_CONTEXT *)Context)->Length); Print(L" IoTrapType=\"%a\"", IoTrapTypeToString(((EFI_SMM_IO_TRAP_REGISTER_CONTEXT *)Context)->Type)); } else if (CompareGuid (HandlerType, &gEfiSmmUsbDispatch2ProtocolGuid)) { Print(L" UsbType=\"0x%x\"", UsbTypeToString(((SMI_HANDLER_PROFILE_USB_REGISTER_CONTEXT *)Context)->Type)); Str = ConvertDevicePathToText((EFI_DEVICE_PATH_PROTOCOL *)(((SMI_HANDLER_PROFILE_USB_REGISTER_CONTEXT *)Context) + 1), TRUE, TRUE); Print(L" UsbDevicePath=\"%s\"", Str); if (Str != NULL) { FreePool (Str); } } else { Print(L" Context=\""); InternalDumpData (Context, ContextSize); Print(L"\""); } }
/** Create an action OpCode with QuestionID and DevicePath on a given OpCodeHandle. @param[in] QuestionID The question ID. @param[in] DevicePath Points to device path. @param[in] OpCodeHandle Points to container for dynamic created opcodes. **/ VOID AddDevicePath ( IN UINTN QuestionID, IN EFI_DEVICE_PATH_PROTOCOL *DevicePath, IN VOID *OpCodeHandle ) { EFI_DEVICE_PATH_PROTOCOL *Next; EFI_STRING_ID NameID; EFI_STRING DriverName; // // Get driver file name node. // Next = DevicePath; while (!IsDevicePathEnd (Next)) { DevicePath = Next; Next = NextDevicePathNode (Next); } // // Display the device path in form. // DriverName = ConvertDevicePathToText (DevicePath, FALSE, FALSE); NameID = HiiSetString (mCallbackInfo->HiiHandle, 0, DriverName, NULL); FreePool (DriverName); if (NameID == 0) { return ; } HiiCreateActionOpCode ( OpCodeHandle, // Container for dynamic created opcodes (UINT16) QuestionID, // Question ID NameID, // Prompt text STRING_TOKEN (STR_NULL_STRING), // Help text EFI_IFR_FLAG_CALLBACK, // Question flag 0 // Action String ID ); }
/** Append some of the unselected active boot options to the boot order. This function should accommodate any further policy changes in "boot option survival". Currently we're adding back everything that starts with neither PciRoot() nor HD(). @param[in,out] BootOrder The structure holding the boot order to complete. The caller is responsible for initializing (and potentially populating) it before calling this function. @param[in,out] ActiveOption The array of active boot options to scan. Entries marked as Appended will be skipped. Those of the rest that satisfy the survival policy will be added to BootOrder with BootOrderAppend(). @param[in] ActiveCount Number of elements in ActiveOption. @retval RETURN_SUCCESS BootOrder has been extended with any eligible boot options. @return Error codes returned by BootOrderAppend(). **/ STATIC RETURN_STATUS BootOrderComplete ( IN OUT BOOT_ORDER *BootOrder, IN OUT ACTIVE_OPTION *ActiveOption, IN UINTN ActiveCount ) { RETURN_STATUS Status; UINTN Idx; Status = RETURN_SUCCESS; Idx = 0; while (!RETURN_ERROR (Status) && Idx < ActiveCount) { if (!ActiveOption[Idx].Appended) { CONST BDS_COMMON_OPTION *Current; CONST EFI_DEVICE_PATH_PROTOCOL *FirstNode; Current = ActiveOption[Idx].BootOption; FirstNode = Current->DevicePath; if (FirstNode != NULL) { CHAR16 *Converted; STATIC CHAR16 ConvFallBack[] = L"<unable to convert>"; BOOLEAN Keep; Converted = ConvertDevicePathToText (FirstNode, FALSE, FALSE); if (Converted == NULL) { Converted = ConvFallBack; } Keep = TRUE; if (DevicePathType(FirstNode) == MEDIA_DEVICE_PATH && DevicePathSubType(FirstNode) == MEDIA_HARDDRIVE_DP) { // // drop HD() // Keep = FALSE; } else if (DevicePathType(FirstNode) == ACPI_DEVICE_PATH && DevicePathSubType(FirstNode) == ACPI_DP) { ACPI_HID_DEVICE_PATH *Acpi; Acpi = (ACPI_HID_DEVICE_PATH *) FirstNode; if ((Acpi->HID & PNP_EISA_ID_MASK) == PNP_EISA_ID_CONST && EISA_ID_TO_NUM (Acpi->HID) == 0x0a03) { // // drop PciRoot() // Keep = FALSE; } } if (Keep) { Status = BootOrderAppend (BootOrder, &ActiveOption[Idx]); if (!RETURN_ERROR (Status)) { DEBUG ((DEBUG_VERBOSE, "%a: keeping \"%s\"\n", __FUNCTION__, Converted)); } } else { DEBUG ((DEBUG_VERBOSE, "%a: dropping \"%s\"\n", __FUNCTION__, Converted)); } if (Converted != ConvFallBack) { FreePool (Converted); } } } ++Idx; } return Status; }
/** Dump Provisioned Capsule. @param[in] DumpCapsuleInfo The flag to indicate whether to dump the capsule inforomation. **/ VOID DumpProvisionedCapsule ( IN BOOLEAN DumpCapsuleInfo ) { EFI_STATUS Status; CHAR16 CapsuleVarName[30]; CHAR16 *TempVarName; UINTN Index; EFI_PHYSICAL_ADDRESS *CapsuleDataPtr64; UINT16 *BootNext; CHAR16 BootOptionName[20]; EFI_BOOT_MANAGER_LOAD_OPTION BootNextOptionEntry; EFI_DEVICE_PATH_PROTOCOL *DevicePath; EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *Fs; EFI_SHELL_PROTOCOL *ShellProtocol; Index = 0; CapsuleDataPtr64 = NULL; BootNext = NULL; ShellProtocol = GetShellProtocol (); if (ShellProtocol == NULL) { Print (L"Get Shell Protocol Fail\n"); return ; } // // Dump capsule provisioned on Memory // Print (L"#########################\n"); Print (L"### Capsule on Memory ###\n"); Print (L"#########################\n"); StrCpyS (CapsuleVarName, sizeof(CapsuleVarName)/sizeof(CHAR16), EFI_CAPSULE_VARIABLE_NAME); TempVarName = CapsuleVarName + StrLen (CapsuleVarName); while (TRUE) { if (Index > 0) { UnicodeValueToStringS ( TempVarName, sizeof (CapsuleVarName) - ((UINTN)TempVarName - (UINTN)CapsuleVarName), 0, Index, 0 ); } Status = GetVariable2 ( CapsuleVarName, &gEfiCapsuleVendorGuid, (VOID **) &CapsuleDataPtr64, NULL ); if (EFI_ERROR (Status) || CapsuleDataPtr64 == NULL) { if (Index == 0) { Print (L"No data.\n"); } break; } Index++; Print (L"Capsule Description at 0x%08x\n", *CapsuleDataPtr64); DumpBlockDescriptors ((EFI_CAPSULE_BLOCK_DESCRIPTOR*) (UINTN) *CapsuleDataPtr64, DumpCapsuleInfo); } // // Dump capsule provisioned on Disk // Print (L"#########################\n"); Print (L"### Capsule on Disk #####\n"); Print (L"#########################\n"); Status = GetVariable2 ( L"BootNext", &gEfiGlobalVariableGuid, (VOID **) &BootNext, NULL ); if (EFI_ERROR (Status) || BootNext == NULL) { Print (L"Get BootNext Variable Fail. Status = %r\n", Status); } else { UnicodeSPrint (BootOptionName, sizeof (BootOptionName), L"Boot%04x", *BootNext); Status = EfiBootManagerVariableToLoadOption (BootOptionName, &BootNextOptionEntry); if (!EFI_ERROR (Status)) { // // Display description and device path // GetEfiSysPartitionFromBootOptionFilePath (BootNextOptionEntry.FilePath, &DevicePath, &Fs); if(!EFI_ERROR (Status)) { Print (L"Capsules are provisioned on BootOption: %s\n", BootNextOptionEntry.Description); Print (L" %s %s\n", ShellProtocol->GetMapFromDevicePath (&DevicePath), ConvertDevicePathToText(DevicePath, TRUE, TRUE)); DumpCapsuleFromDisk (Fs, DumpCapsuleInfo); } } } }
/** Function to read in HII configuration information from a file. @param[in] Handle The handle to get info for. @param[in] FileName The filename to read the info from. **/ SHELL_STATUS EFIAPI ConfigFromFile( IN EFI_HANDLE Handle, IN CONST CHAR16 *FileName ) { EFI_HII_DATABASE_PROTOCOL *HiiDatabase; EFI_STATUS Status; VOID *MainBuffer; UINT64 Temp; UINTN MainBufferSize; EFI_HII_HANDLE HiiHandle; SHELL_FILE_HANDLE FileHandle; CHAR16 *TempDevPathString; EFI_HII_PACKAGE_LIST_HEADER *PackageListHeader; EFI_HII_PACKAGE_HEADER *PackageHeader; EFI_DEVICE_PATH_PROTOCOL *DevPath; UINTN HandleIndex; HiiDatabase = NULL; MainBufferSize = 0; MainBuffer = NULL; FileHandle = NULL; Status = ShellOpenFileByName(FileName, &FileHandle, EFI_FILE_MODE_READ, 0); if (EFI_ERROR(Status)) { ShellPrintHiiEx( -1, -1, NULL, STRING_TOKEN(STR_GEN_FILE_OPEN), gShellDriver1HiiHandle, FileName, Status); return (SHELL_DEVICE_ERROR); } // // Locate HII Database protocol // Status = gBS->LocateProtocol ( &gEfiHiiDatabaseProtocolGuid, NULL, (VOID **) &HiiDatabase ); if (EFI_ERROR(Status) || HiiDatabase == NULL) { ShellPrintHiiEx( -1, -1, NULL, STRING_TOKEN(STR_GEN_PROTOCOL_NF), gShellDriver1HiiHandle, L"EfiHiiDatabaseProtocol", &gEfiHiiDatabaseProtocolGuid); ShellCloseFile(&FileHandle); return (SHELL_NOT_FOUND); } Status = ShellGetFileSize(FileHandle, &Temp); MainBufferSize = (UINTN)Temp; if (EFI_ERROR(Status)) { ShellPrintHiiEx( -1, -1, NULL, STRING_TOKEN(STR_FILE_READ_FAIL), gShellDriver1HiiHandle, FileName, Status); ShellCloseFile(&FileHandle); return (SHELL_DEVICE_ERROR); } MainBuffer = AllocateZeroPool((UINTN)MainBufferSize); if (EFI_ERROR(Status)) { ShellPrintHiiEx( -1, -1, NULL, STRING_TOKEN(STR_GEN_OUT_MEM), gShellDriver1HiiHandle); ShellCloseFile(&FileHandle); return (SHELL_DEVICE_ERROR); } Status = ShellReadFile(FileHandle, &MainBufferSize, MainBuffer); if (EFI_ERROR(Status)) { ShellPrintHiiEx( -1, -1, NULL, STRING_TOKEN(STR_FILE_READ_FAIL), gShellDriver1HiiHandle, FileName, Status); ShellCloseFile(&FileHandle); SHELL_FREE_NON_NULL(MainBuffer); return (SHELL_DEVICE_ERROR); } ShellCloseFile(&FileHandle); if (Handle != NULL) { // // User override in place. Just do it. // HiiHandle = NULL; Status = ConvertHandleToHiiHandle(Handle, &HiiHandle, HiiDatabase); if (EFI_ERROR(Status)) { ShellPrintHiiEx( -1, -1, NULL, STRING_TOKEN(STR_GEN_HANDLE_NOT), gShellDriver1HiiHandle, ConvertHandleToHandleIndex(Handle), L"Device"); ShellCloseFile(&FileHandle); return (SHELL_DEVICE_ERROR); } Status = HiiDatabase->UpdatePackageList(HiiDatabase, HiiHandle, MainBuffer); if (EFI_ERROR(Status)) { ShellPrintHiiEx( -1, -1, NULL, STRING_TOKEN(STR_GEN_UEFI_FUNC_ERROR), gShellDriver1HiiHandle, L"HiiDatabase->UpdatePackageList", Status); return (SHELL_DEVICE_ERROR); } } else { // // we need to parse the buffer and try to match the device paths for each item to try to find it's device path. // for (PackageListHeader = (EFI_HII_PACKAGE_LIST_HEADER*)MainBuffer ; PackageListHeader != NULL && ((CHAR8*)PackageListHeader) < (((CHAR8*)MainBuffer)+MainBufferSize) ; PackageListHeader = (EFI_HII_PACKAGE_LIST_HEADER*)(((CHAR8*)(PackageListHeader)) + PackageListHeader->PackageLength )) { for (PackageHeader = (EFI_HII_PACKAGE_HEADER*)(((CHAR8*)(PackageListHeader))+sizeof(EFI_HII_PACKAGE_LIST_HEADER)) ; PackageHeader != NULL && ((CHAR8*)PackageHeader) < (((CHAR8*)MainBuffer)+MainBufferSize) && PackageHeader->Type != EFI_HII_PACKAGE_END ; PackageHeader = (EFI_HII_PACKAGE_HEADER*)(((CHAR8*)(PackageHeader))+PackageHeader->Length)) { if (PackageHeader->Type == EFI_HII_PACKAGE_DEVICE_PATH) { HiiHandle = NULL; Status = FindHiiHandleViaDevPath((EFI_DEVICE_PATH_PROTOCOL*)(((CHAR8*)PackageHeader) + sizeof(EFI_HII_PACKAGE_HEADER)), &HiiHandle, HiiDatabase); if (EFI_ERROR(Status)) { // // print out an error. // TempDevPathString = ConvertDevicePathToText((EFI_DEVICE_PATH_PROTOCOL*)(((CHAR8*)PackageHeader) + sizeof(EFI_HII_PACKAGE_HEADER)), TRUE, TRUE); ShellPrintHiiEx( -1, -1, NULL, STRING_TOKEN(STR_DRVCFG_IN_FILE_NF), gShellDriver1HiiHandle, TempDevPathString); SHELL_FREE_NON_NULL(TempDevPathString); } else { Status = HiiDatabase->UpdatePackageList(HiiDatabase, HiiHandle, PackageListHeader); if (EFI_ERROR(Status)) { ShellPrintHiiEx( -1, -1, NULL, STRING_TOKEN(STR_GEN_UEFI_FUNC_ERROR), gShellDriver1HiiHandle, L"HiiDatabase->UpdatePackageList", Status); return (SHELL_DEVICE_ERROR); } else { DevPath = (EFI_DEVICE_PATH_PROTOCOL*)(((CHAR8*)PackageHeader) + sizeof(EFI_HII_PACKAGE_HEADER)); gBS->LocateDevicePath(&gEfiHiiConfigAccessProtocolGuid, &DevPath, &Handle); HandleIndex = ConvertHandleToHandleIndex(Handle); ShellPrintHiiEx( -1, -1, NULL, STRING_TOKEN(STR_DRVCFG_DONE_HII), gShellDriver1HiiHandle, HandleIndex); } } } } } } SHELL_FREE_NON_NULL(MainBuffer); ShellPrintHiiEx( -1, -1, NULL, STRING_TOKEN(STR_DRVCFG_COMP), gShellDriver1HiiHandle); return (SHELL_SUCCESS); }
/** Update the form to include the driver health instances. @param ConfigureOnly Only include the configure required driver health instances when TRUE, include all the driver health instances otherwise. **/ VOID DriverHealthManagerUpdateForm ( BOOLEAN ConfigureOnly ) { EFI_STATUS Status; EFI_IFR_GUID_LABEL *StartLabel; EFI_IFR_GUID_LABEL *EndLabel; VOID *StartOpCodeHandle; VOID *EndOpCodeHandle; UINTN Index; EFI_STRING_ID Prompt; EFI_STRING_ID Help; CHAR16 String[512]; UINTN StringCount; EFI_STRING TmpString; EFI_STRING DriverName; EFI_STRING ControllerName; UINTN MessageIndex; EFI_HANDLE DriverHandle; EFI_STRING_ID DevicePath; EFI_GUID FormsetGuid; EfiBootManagerFreeDriverHealthInfo (mDriverHealthManagerHealthInfo, mDriverHealthManagerHealthInfoCount); mDriverHealthManagerHealthInfo = EfiBootManagerGetDriverHealthInfo (&mDriverHealthManagerHealthInfoCount); // // Allocate space for creation of UpdateData Buffer // StartOpCodeHandle = HiiAllocateOpCodeHandle (); ASSERT (StartOpCodeHandle != NULL); EndOpCodeHandle = HiiAllocateOpCodeHandle (); ASSERT (EndOpCodeHandle != NULL); // // Create Hii Extend Label OpCode as the start opcode // StartLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (StartOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL)); StartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL; StartLabel->Number = LABEL_BEGIN; // // Create Hii Extend Label OpCode as the end opcode // EndLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (EndOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL)); EndLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL; EndLabel->Number = LABEL_END; for (Index = 0; Index < mDriverHealthManagerHealthInfoCount; Index++) { if (ConfigureOnly && mDriverHealthManagerHealthInfo[Index].HealthStatus != EfiDriverHealthStatusConfigurationRequired) { continue; } DriverName = DriverHealthManagerGetDriverName (mDriverHealthManagerHealthInfo[Index].DriverHealthHandle); ASSERT (DriverName != NULL); if (mDriverHealthManagerHealthInfo[Index].ControllerHandle == NULL) { // // The ControllerHandle is set to NULL and the HealthStatus is set to EfiDriverHealthStatusHealthy // if all the controllers managed by the driver are in healthy state. // ASSERT (mDriverHealthManagerHealthInfo[Index].HealthStatus == EfiDriverHealthStatusHealthy); UnicodeSPrint (String, sizeof (String), L"%s", DriverName); } else { ControllerName = DriverHealthManagerGetControllerName ( mDriverHealthManagerHealthInfo[Index].DriverHealthHandle, mDriverHealthManagerHealthInfo[Index].ControllerHandle, mDriverHealthManagerHealthInfo[Index].ChildHandle ); ASSERT (ControllerName != NULL); UnicodeSPrint (String, sizeof (String), L"%s %s", DriverName, ControllerName); FreePool (ControllerName); } FreePool (DriverName); Prompt = HiiSetString (mDriverHealthManagerHiiHandle, 0, String, NULL); switch(mDriverHealthManagerHealthInfo[Index].HealthStatus) { case EfiDriverHealthStatusRepairRequired: TmpString = HiiGetString (mDriverHealthManagerHiiHandle, STRING_TOKEN (STR_REPAIR_REQUIRED), NULL); break; case EfiDriverHealthStatusConfigurationRequired: TmpString = HiiGetString (mDriverHealthManagerHiiHandle, STRING_TOKEN (STR_CONFIGURATION_REQUIRED), NULL); break; case EfiDriverHealthStatusFailed: TmpString = HiiGetString (mDriverHealthManagerHiiHandle, STRING_TOKEN (STR_FAILED), NULL); break; case EfiDriverHealthStatusReconnectRequired: TmpString = HiiGetString (mDriverHealthManagerHiiHandle, STRING_TOKEN (STR_RECONNECT_REQUIRED), NULL); break; case EfiDriverHealthStatusRebootRequired: TmpString = HiiGetString (mDriverHealthManagerHiiHandle, STRING_TOKEN (STR_REBOOT_REQUIRED), NULL); break; default: ASSERT (mDriverHealthManagerHealthInfo[Index].HealthStatus == EfiDriverHealthStatusHealthy); TmpString = HiiGetString (mDriverHealthManagerHiiHandle, STRING_TOKEN (STR_HEALTHY), NULL); break; } StringCount = UnicodeSPrint (String, sizeof (String), L"%s\n", TmpString); FreePool (TmpString); // // Add the message of the Module itself provided as the help. // if (mDriverHealthManagerHealthInfo[Index].MessageList != NULL) { for (MessageIndex = 0; mDriverHealthManagerHealthInfo[Index].MessageList[MessageIndex].HiiHandle != NULL; MessageIndex++) { TmpString = HiiGetString ( mDriverHealthManagerHealthInfo[Index].MessageList[MessageIndex].HiiHandle, mDriverHealthManagerHealthInfo[Index].MessageList[MessageIndex].StringId, NULL ); StringCount += UnicodeSPrint (String + StringCount, sizeof (String) - sizeof (String[0]) * StringCount, L"\n%s", TmpString); FreePool (TmpString); } } Help = HiiSetString (mDriverHealthManagerHiiHandle, 0, String, NULL); switch (mDriverHealthManagerHealthInfo[Index].HealthStatus) { case EfiDriverHealthStatusConfigurationRequired: Status = mDriverHealthManagerDatabase->GetPackageListHandle ( mDriverHealthManagerDatabase, mDriverHealthManagerHealthInfo[Index].HiiHandle, &DriverHandle ); ASSERT_EFI_ERROR (Status); TmpString = ConvertDevicePathToText (DevicePathFromHandle (DriverHandle), FALSE, TRUE); DevicePath = HiiSetString (mDriverHealthManagerHiiHandle, 0, TmpString, NULL); FreePool (TmpString); Status = DriverHealthManagerGetFormsetId (mDriverHealthManagerHealthInfo[Index].HiiHandle, &FormsetGuid); ASSERT_EFI_ERROR (Status); HiiCreateGotoExOpCode ( StartOpCodeHandle, 0, Prompt, Help, 0, 0, 0, &FormsetGuid, DevicePath ); break; case EfiDriverHealthStatusRepairRequired: case EfiDriverHealthStatusReconnectRequired: case EfiDriverHealthStatusRebootRequired: HiiCreateActionOpCode ( StartOpCodeHandle, (EFI_QUESTION_ID) (Index + QUESTION_ID_DRIVER_HEALTH_BASE), Prompt, Help, EFI_IFR_FLAG_CALLBACK, 0 ); break; default: ASSERT (mDriverHealthManagerHealthInfo[Index].HealthStatus == EfiDriverHealthStatusHealthy || mDriverHealthManagerHealthInfo[Index].HealthStatus == EfiDriverHealthStatusFailed); HiiCreateTextOpCode ( StartOpCodeHandle, Prompt, Help, 0 ); break; } } Status = HiiUpdateForm ( mDriverHealthManagerHiiHandle, ConfigureOnly ? PcdGetPtr (PcdDriverHealthConfigureForm) : &mDriverHealthManagerForm, DRIVER_HEALTH_FORM_ID, StartOpCodeHandle, EndOpCodeHandle ); ASSERT_EFI_ERROR (Status); HiiFreeOpCodeHandle (StartOpCodeHandle); HiiFreeOpCodeHandle (EndOpCodeHandle); }
EFIAPI GetResourcePadding ( IN EFI_PCI_HOT_PLUG_INIT_PROTOCOL *This, IN EFI_DEVICE_PATH_PROTOCOL *HpcDevicePath, IN UINT64 HpcPciAddress, OUT EFI_HPC_STATE *HpcState, OUT VOID **Padding, OUT EFI_HPC_PADDING_ATTRIBUTES *Attributes ) { DEBUG_CODE ( EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS *Address; CHAR16 *DevicePathString; Address = (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS *)&HpcPciAddress; DevicePathString = ConvertDevicePathToText (HpcDevicePath, FALSE, FALSE); DEBUG ((EFI_D_VERBOSE, "%a: Address=%02x:%02x.%x DevicePath=%s\n", __FUNCTION__, Address->Bus, Address->Device, Address->Function, (DevicePathString == NULL) ? L"<unavailable>" : DevicePathString)); if (DevicePathString != NULL) { FreePool (DevicePathString); } ); if (HpcState == NULL || Padding == NULL || Attributes == NULL) { return EFI_INVALID_PARAMETER; } *Padding = AllocateCopyPool (sizeof mPadding, &mPadding);
/** Function to compare 2 device paths for use in QuickSort. @param[in] Buffer1 pointer to Device Path poiner to compare @param[in] Buffer2 pointer to second DevicePath pointer to compare @retval 0 Buffer1 equal to Buffer2 @retval <0 Buffer1 is less than Buffer2 @retval >0 Buffer1 is greater than Buffer2 **/ INTN EFIAPI DevicePathCompare ( IN CONST VOID *Buffer1, IN CONST VOID *Buffer2 ) { EFI_DEVICE_PATH_PROTOCOL *DevicePath1; EFI_DEVICE_PATH_PROTOCOL *DevicePath2; CHAR16 *TextPath1; CHAR16 *TextPath2; EFI_STATUS Status; INTN RetVal; DevicePath1 = *(EFI_DEVICE_PATH_PROTOCOL**)Buffer1; DevicePath2 = *(EFI_DEVICE_PATH_PROTOCOL**)Buffer2; if (DevicePath1 == NULL) { if (DevicePath2 == NULL) { return 0; } return -1; } if (DevicePath2 == NULL) { return 1; } if (mUnicodeCollation == NULL) { Status = gBS->LocateProtocol( &gEfiUnicodeCollation2ProtocolGuid, NULL, (VOID**)&mUnicodeCollation); ASSERT_EFI_ERROR(Status); } TextPath1 = ConvertDevicePathToText( DevicePath1, FALSE, FALSE); TextPath2 = ConvertDevicePathToText( DevicePath2, FALSE, FALSE); if (TextPath1 == NULL) { RetVal = -1; } else if (TextPath2 == NULL) { RetVal = 1; } else { RetVal = mUnicodeCollation->StriColl( mUnicodeCollation, TextPath1, TextPath2); } USL_FREE_NON_NULL(TextPath1); USL_FREE_NON_NULL(TextPath2); return (RetVal); }
/** Download an image from a TFTP server @param[in] DevicePath Device path of the TFTP boot option @param[in] ControllerHandle Handle of the network controller @param[in] RemainingDevicePath Device path of the TFTP boot option but the first node that identifies the network controller @param[in] Type Type to allocate memory pages @param[out] Image Address of the bufer where the image is stored in case of success @param[out] ImageSize Size in number of bytes of the i;age in case of success @retval EFI_SUCCESS The image was returned. @retval !EFI_SUCCESS Something went wrong. **/ EFI_STATUS BdsTftpLoadImage ( IN OUT EFI_DEVICE_PATH **DevicePath, IN EFI_HANDLE ControllerHandle, IN EFI_DEVICE_PATH *RemainingDevicePath, IN EFI_ALLOCATE_TYPE Type, IN OUT EFI_PHYSICAL_ADDRESS *Image, OUT UINTN *ImageSize ) { EFI_STATUS Status; EFI_HANDLE Dhcp4ChildHandle; EFI_DHCP4_PROTOCOL *Dhcp4; BOOLEAN Dhcp4ToStop; EFI_HANDLE Mtftp4ChildHandle; EFI_MTFTP4_PROTOCOL *Mtftp4; DHCP4_OPTION ParaList; EFI_DHCP4_PACKET_OPTION *OptionList[2]; EFI_DHCP4_CONFIG_DATA Dhcp4CfgData; EFI_DHCP4_MODE_DATA Dhcp4Mode; EFI_MTFTP4_CONFIG_DATA Mtftp4CfgData; IPv4_DEVICE_PATH *IPv4DevicePathNode; CHAR16 *PathName; CHAR8 *AsciiFilePath; EFI_MTFTP4_TOKEN Mtftp4Token; UINT64 FileSize; UINT64 TftpBufferSize; BDS_TFTP_CONTEXT *TftpContext; ASSERT(IS_DEVICE_PATH_NODE (RemainingDevicePath, MESSAGING_DEVICE_PATH, MSG_IPv4_DP)); IPv4DevicePathNode = (IPv4_DEVICE_PATH*)RemainingDevicePath; Dhcp4ChildHandle = NULL; Dhcp4 = NULL; Dhcp4ToStop = FALSE; Mtftp4ChildHandle = NULL; Mtftp4 = NULL; AsciiFilePath = NULL; TftpContext = NULL; if (!IPv4DevicePathNode->StaticIpAddress) { // // Using the DHCP4 Service Binding Protocol, create a child handle of the DHCP4 service and // install the DHCP4 protocol on it. Then, open the DHCP protocol. // Status = NetLibCreateServiceChild ( ControllerHandle, gImageHandle, &gEfiDhcp4ServiceBindingProtocolGuid, &Dhcp4ChildHandle ); if (!EFI_ERROR (Status)) { Status = gBS->OpenProtocol ( Dhcp4ChildHandle, &gEfiDhcp4ProtocolGuid, (VOID **) &Dhcp4, gImageHandle, ControllerHandle, EFI_OPEN_PROTOCOL_BY_DRIVER ); } if (EFI_ERROR (Status)) { Print (L"Unable to open DHCP4 protocol\n"); goto Error; } } // // Using the MTFTP4 Service Binding Protocol, create a child handle of the MTFTP4 service and // install the MTFTP4 protocol on it. Then, open the MTFTP4 protocol. // Status = NetLibCreateServiceChild ( ControllerHandle, gImageHandle, &gEfiMtftp4ServiceBindingProtocolGuid, &Mtftp4ChildHandle ); if (!EFI_ERROR (Status)) { Status = gBS->OpenProtocol ( Mtftp4ChildHandle, &gEfiMtftp4ProtocolGuid, (VOID **) &Mtftp4, gImageHandle, ControllerHandle, EFI_OPEN_PROTOCOL_BY_DRIVER ); } if (EFI_ERROR (Status)) { Print (L"Unable to open MTFTP4 protocol\n"); goto Error; } if (!IPv4DevicePathNode->StaticIpAddress) { // // Configure the DHCP4, all default settings. It is acceptable for the configuration to // fail if the return code is equal to EFI_ACCESS_DENIED which means that the configuration // has been done by another instance of the DHCP4 protocol or that the DHCP configuration // process has been started but is not completed yet. // ZeroMem (&Dhcp4CfgData, sizeof (EFI_DHCP4_CONFIG_DATA)); ParaList.Head.OpCode = DHCP_TAG_PARA_LIST; ParaList.Head.Length = 2; ParaList.Head.Data[0] = DHCP_TAG_NETMASK; ParaList.Route = DHCP_TAG_ROUTER; OptionList[0] = &ParaList.Head; Dhcp4CfgData.OptionCount = 1; Dhcp4CfgData.OptionList = OptionList; Status = Dhcp4->Configure (Dhcp4, &Dhcp4CfgData); if (EFI_ERROR (Status)) { if (Status != EFI_ACCESS_DENIED) { Print (L"Error while configuring the DHCP4 protocol\n"); goto Error; } } // // Start the DHCP configuration. This may have already been done thus do not leave in error // if the return code is EFI_ALREADY_STARTED. // Status = Dhcp4->Start (Dhcp4, NULL); if (EFI_ERROR (Status)) { if (Status != EFI_ALREADY_STARTED) { Print (L"DHCP configuration failed\n"); goto Error; } } else { Dhcp4ToStop = TRUE; } Status = Dhcp4->GetModeData (Dhcp4, &Dhcp4Mode); if (EFI_ERROR (Status)) { goto Error; } if (Dhcp4Mode.State != Dhcp4Bound) { Status = EFI_TIMEOUT; Print (L"DHCP configuration failed\n"); goto Error; } } // // Configure the TFTP4 protocol // ZeroMem (&Mtftp4CfgData, sizeof (EFI_MTFTP4_CONFIG_DATA)); Mtftp4CfgData.UseDefaultSetting = FALSE; Mtftp4CfgData.TimeoutValue = 4; Mtftp4CfgData.TryCount = 6; if (IPv4DevicePathNode->StaticIpAddress) { CopyMem (&Mtftp4CfgData.StationIp , &IPv4DevicePathNode->LocalIpAddress, sizeof (EFI_IPv4_ADDRESS)); CopyMem (&Mtftp4CfgData.SubnetMask, &IPv4DevicePathNode->SubnetMask, sizeof (EFI_IPv4_ADDRESS)); CopyMem (&Mtftp4CfgData.GatewayIp , &IPv4DevicePathNode->GatewayIpAddress, sizeof (EFI_IPv4_ADDRESS)); } else { CopyMem (&Mtftp4CfgData.StationIp , &Dhcp4Mode.ClientAddress, sizeof (EFI_IPv4_ADDRESS)); CopyMem (&Mtftp4CfgData.SubnetMask, &Dhcp4Mode.SubnetMask , sizeof (EFI_IPv4_ADDRESS)); CopyMem (&Mtftp4CfgData.GatewayIp , &Dhcp4Mode.RouterAddress, sizeof (EFI_IPv4_ADDRESS)); } CopyMem (&Mtftp4CfgData.ServerIp , &IPv4DevicePathNode->RemoteIpAddress, sizeof (EFI_IPv4_ADDRESS)); Status = Mtftp4->Configure (Mtftp4, &Mtftp4CfgData); if (EFI_ERROR (Status)) { Print (L"Error while configuring the MTFTP4 protocol\n"); goto Error; } // The Device Path might contain multiple FilePath nodes PathName = ConvertDevicePathToText ((EFI_DEVICE_PATH_PROTOCOL*)(IPv4DevicePathNode + 1), FALSE, FALSE); AsciiFilePath = AllocatePool (StrLen (PathName) + 1); UnicodeStrToAsciiStr (PathName, AsciiFilePath); // // Try to get the size of the file in bytes from the server. If it fails, // start with a 8MB buffer to download the file. // FileSize = 0; if (Mtftp4GetFileSize (Mtftp4, AsciiFilePath, &FileSize) == EFI_SUCCESS) { TftpBufferSize = FileSize; } else { TftpBufferSize = SIZE_16MB; } TftpContext = AllocatePool (sizeof (BDS_TFTP_CONTEXT)); if (TftpContext == NULL) { Status = EFI_OUT_OF_RESOURCES; goto Error; } TftpContext->FileSize = FileSize; for (; TftpBufferSize <= FixedPcdGet32 (PcdMaxTftpFileSize); TftpBufferSize = (TftpBufferSize + SIZE_16MB) & (~(SIZE_16MB-1))) { // // Allocate a buffer to hold the whole file. // Status = gBS->AllocatePages ( Type, EfiBootServicesCode, EFI_SIZE_TO_PAGES (TftpBufferSize), Image ); if (EFI_ERROR (Status)) { Print (L"Failed to allocate space for image\n"); goto Error; } TftpContext->DownloadedNbOfBytes = 0; TftpContext->LastReportedNbOfBytes = 0; ZeroMem (&Mtftp4Token, sizeof (EFI_MTFTP4_TOKEN)); Mtftp4Token.Filename = (UINT8*)AsciiFilePath; Mtftp4Token.BufferSize = TftpBufferSize; Mtftp4Token.Buffer = (VOID *)(UINTN)*Image; Mtftp4Token.CheckPacket = Mtftp4CheckPacket; Mtftp4Token.Context = (VOID*)TftpContext; Print (L"Downloading the file <%a> from the TFTP server\n", AsciiFilePath); Status = Mtftp4->ReadFile (Mtftp4, &Mtftp4Token); Print (L"\n"); if (EFI_ERROR (Status)) { gBS->FreePages (*Image, EFI_SIZE_TO_PAGES (TftpBufferSize)); if (Status == EFI_BUFFER_TOO_SMALL) { Print (L"Downloading failed, file larger than expected.\n"); continue; } else { goto Error; } } *ImageSize = Mtftp4Token.BufferSize; break; } Error: if (Dhcp4ChildHandle != NULL) { if (Dhcp4 != NULL) { if (Dhcp4ToStop) { Dhcp4->Stop (Dhcp4); } gBS->CloseProtocol ( Dhcp4ChildHandle, &gEfiDhcp4ProtocolGuid, gImageHandle, ControllerHandle ); } NetLibDestroyServiceChild ( ControllerHandle, gImageHandle, &gEfiDhcp4ServiceBindingProtocolGuid, Dhcp4ChildHandle ); } if (Mtftp4ChildHandle != NULL) { if (Mtftp4 != NULL) { if (AsciiFilePath != NULL) { FreePool (AsciiFilePath); } if (TftpContext != NULL) { FreePool (TftpContext); } gBS->CloseProtocol ( Mtftp4ChildHandle, &gEfiMtftp4ProtocolGuid, gImageHandle, ControllerHandle ); } NetLibDestroyServiceChild ( ControllerHandle, gImageHandle, &gEfiMtftp4ServiceBindingProtocolGuid, Mtftp4ChildHandle ); } if (EFI_ERROR (Status)) { *Image = 0; Print (L"Failed to download the file - Error=%r\n", Status); } return Status; }
/** Convert the UEFI DevicePath to full text representation with DevPathToText, then match the UEFI device path fragment in Translated against it. @param[in] Translated UEFI device path fragment, translated from OpenFirmware format, to search for. @param[in] TranslatedLength The length of Translated in CHAR16's. @param[in] DevicePath Boot option device path whose textual rendering to search in. @param[in] DevPathToText Binary-to-text conversion protocol for DevicePath. @retval TRUE If Translated was found at the beginning of DevicePath after converting the latter to text. @retval FALSE If DevicePath was NULL, or it could not be converted, or there was no match. **/ STATIC BOOLEAN Match ( IN CONST CHAR16 *Translated, IN UINTN TranslatedLength, IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath ) { CHAR16 *Converted; BOOLEAN Result; Converted = ConvertDevicePathToText ( DevicePath, FALSE, // DisplayOnly FALSE // AllowShortcuts ); if (Converted == NULL) { return FALSE; } // // Attempt to expand any relative UEFI device path starting with HD() to an // absolute device path first. The logic imitates BdsLibBootViaBootOption(). // We don't have to free the absolute device path, // BdsExpandPartitionPartialDevicePathToFull() has internal caching. // Result = FALSE; if (DevicePathType (DevicePath) == MEDIA_DEVICE_PATH && DevicePathSubType (DevicePath) == MEDIA_HARDDRIVE_DP) { EFI_DEVICE_PATH_PROTOCOL *AbsDevicePath; CHAR16 *AbsConverted; AbsDevicePath = BdsExpandPartitionPartialDevicePathToFull ( (HARDDRIVE_DEVICE_PATH *) DevicePath); if (AbsDevicePath == NULL) { goto Exit; } AbsConverted = ConvertDevicePathToText (AbsDevicePath, FALSE, FALSE); if (AbsConverted == NULL) { goto Exit; } DEBUG ((DEBUG_VERBOSE, "%a: expanded relative device path \"%s\" for prefix matching\n", __FUNCTION__, Converted)); FreePool (Converted); Converted = AbsConverted; } // // Is Translated a prefix of Converted? // Result = (BOOLEAN)(StrnCmp (Converted, Translated, TranslatedLength) == 0); DEBUG (( DEBUG_VERBOSE, "%a: against \"%s\": %a\n", __FUNCTION__, Converted, Result ? "match" : "no match" )); Exit: FreePool (Converted); return Result; }
/** Dump the resource map of all the devices under Bridge. @param[in] Bridge Bridge device instance. @param[in] IoNode IO resource descriptor for the bridge device. @param[in] Mem32Node Mem32 resource descriptor for the bridge device. @param[in] PMem32Node PMem32 resource descriptor for the bridge device. @param[in] Mem64Node Mem64 resource descriptor for the bridge device. @param[in] PMem64Node PMem64 resource descriptor for the bridge device. **/ VOID DumpResourceMap ( IN PCI_IO_DEVICE *Bridge, IN PCI_RESOURCE_NODE *IoNode, IN PCI_RESOURCE_NODE *Mem32Node, IN PCI_RESOURCE_NODE *PMem32Node, IN PCI_RESOURCE_NODE *Mem64Node, IN PCI_RESOURCE_NODE *PMem64Node ) { EFI_STATUS Status; LIST_ENTRY *Link; PCI_IO_DEVICE *Device; PCI_RESOURCE_NODE *ChildIoNode; PCI_RESOURCE_NODE *ChildMem32Node; PCI_RESOURCE_NODE *ChildPMem32Node; PCI_RESOURCE_NODE *ChildMem64Node; PCI_RESOURCE_NODE *ChildPMem64Node; CHAR16 *Str; DEBUG ((EFI_D_INFO, "PciBus: Resource Map for ")); Status = gBS->OpenProtocol ( Bridge->Handle, &gEfiPciRootBridgeIoProtocolGuid, NULL, NULL, NULL, EFI_OPEN_PROTOCOL_TEST_PROTOCOL ); if (EFI_ERROR (Status)) { DEBUG (( EFI_D_INFO, "Bridge [%02x|%02x|%02x]\n", Bridge->BusNumber, Bridge->DeviceNumber, Bridge->FunctionNumber )); } else { Str = ConvertDevicePathToText ( DevicePathFromHandle (Bridge->Handle), FALSE, FALSE ); DEBUG ((EFI_D_INFO, "Root Bridge %s\n", Str != NULL ? Str : L"")); if (Str != NULL) { FreePool (Str); } } DumpBridgeResource (IoNode); DumpBridgeResource (Mem32Node); DumpBridgeResource (PMem32Node); DumpBridgeResource (Mem64Node); DumpBridgeResource (PMem64Node); DEBUG ((EFI_D_INFO, "\n")); for ( Link = Bridge->ChildList.ForwardLink ; Link != &Bridge->ChildList ; Link = Link->ForwardLink ) { Device = PCI_IO_DEVICE_FROM_LINK (Link); if (IS_PCI_BRIDGE (&Device->Pci)) { ChildIoNode = (IoNode == NULL ? NULL : FindResourceNode (Device, IoNode)); ChildMem32Node = (Mem32Node == NULL ? NULL : FindResourceNode (Device, Mem32Node)); ChildPMem32Node = (PMem32Node == NULL ? NULL : FindResourceNode (Device, PMem32Node)); ChildMem64Node = (Mem64Node == NULL ? NULL : FindResourceNode (Device, Mem64Node)); ChildPMem64Node = (PMem64Node == NULL ? NULL : FindResourceNode (Device, PMem64Node)); DumpResourceMap ( Device, ChildIoNode, ChildMem32Node, ChildPMem32Node, ChildMem64Node, ChildPMem64Node ); } } }
/** The security handler is used to abstract platform-specific policy from the DXE core response to an attempt to use a file that returns a given status for the authentication check from the section extraction protocol. The possible responses in a given SAP implementation may include locking flash upon failure to authenticate, attestation logging for all signed drivers, and other exception operations. The File parameter allows for possible logging within the SAP of the driver. If File is NULL, then EFI_INVALID_PARAMETER is returned. If the file specified by File with an authentication status specified by AuthenticationStatus is safe for the DXE Core to use, then EFI_SUCCESS is returned. If the file specified by File with an authentication status specified by AuthenticationStatus is not safe for the DXE Core to use under any circumstances, then EFI_ACCESS_DENIED is returned. If the file specified by File with an authentication status specified by AuthenticationStatus is not safe for the DXE Core to use right now, but it might be possible to use it at a future time, then EFI_SECURITY_VIOLATION is returned. @param[in] AuthenticationStatus This is the authentication status returned from the securitymeasurement services for the input file. @param[in] File This is a pointer to the device path of the file that is being dispatched. This will optionally be used for logging. @param[in] FileBuffer File buffer matches the input file device path. @param[in] FileSize Size of File buffer matches the input file device path. @param[in] BootPolicy A boot policy that was used to call LoadImage() UEFI service. @retval EFI_SUCCESS The file specified by DevicePath and non-NULL FileBuffer did authenticate, and the platform policy dictates that the DXE Foundation may use the file. @retval other error value **/ EFI_STATUS EFIAPI DxeTpmMeasureBootHandler ( IN UINT32 AuthenticationStatus, IN CONST EFI_DEVICE_PATH_PROTOCOL *File, IN VOID *FileBuffer, IN UINTN FileSize, IN BOOLEAN BootPolicy ) { EFI_TCG_PROTOCOL *TcgProtocol; EFI_STATUS Status; TCG_EFI_BOOT_SERVICE_CAPABILITY ProtocolCapability; UINT32 TCGFeatureFlags; EFI_PHYSICAL_ADDRESS EventLogLocation; EFI_PHYSICAL_ADDRESS EventLogLastEntry; EFI_DEVICE_PATH_PROTOCOL *DevicePathNode; EFI_DEVICE_PATH_PROTOCOL *OrigDevicePathNode; EFI_HANDLE Handle; EFI_HANDLE TempHandle; BOOLEAN ApplicationRequired; PE_COFF_LOADER_IMAGE_CONTEXT ImageContext; EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *FvbProtocol; EFI_PHYSICAL_ADDRESS FvAddress; UINT32 Index; Status = gBS->LocateProtocol (&gEfiTcgProtocolGuid, NULL, (VOID **) &TcgProtocol); if (EFI_ERROR (Status)) { // // TCG protocol is not installed. So, TPM is not present. // Don't do any measurement, and directly return EFI_SUCCESS. // return EFI_SUCCESS; } ProtocolCapability.Size = (UINT8) sizeof (ProtocolCapability); Status = TcgProtocol->StatusCheck ( TcgProtocol, &ProtocolCapability, &TCGFeatureFlags, &EventLogLocation, &EventLogLastEntry ); if (EFI_ERROR (Status) || ProtocolCapability.TPMDeactivatedFlag) { // // TPM device doesn't work or activate. // return EFI_SUCCESS; } // // Copy File Device Path // OrigDevicePathNode = DuplicateDevicePath (File); // // 1. Check whether this device path support BlockIo protocol. // Is so, this device path may be a GPT device path. // DevicePathNode = OrigDevicePathNode; Status = gBS->LocateDevicePath (&gEfiBlockIoProtocolGuid, &DevicePathNode, &Handle); if (!EFI_ERROR (Status) && !mMeasureGptTableFlag) { // // Find the gpt partion on the given devicepath // DevicePathNode = OrigDevicePathNode; ASSERT (DevicePathNode != NULL); while (!IsDevicePathEnd (DevicePathNode)) { // // Find the Gpt partition // if (DevicePathType (DevicePathNode) == MEDIA_DEVICE_PATH && DevicePathSubType (DevicePathNode) == MEDIA_HARDDRIVE_DP) { // // Check whether it is a gpt partition or not // if (((HARDDRIVE_DEVICE_PATH *) DevicePathNode)->MBRType == MBR_TYPE_EFI_PARTITION_TABLE_HEADER && ((HARDDRIVE_DEVICE_PATH *) DevicePathNode)->SignatureType == SIGNATURE_TYPE_GUID) { // // Change the partition device path to its parent device path (disk) and get the handle. // DevicePathNode->Type = END_DEVICE_PATH_TYPE; DevicePathNode->SubType = END_ENTIRE_DEVICE_PATH_SUBTYPE; DevicePathNode = OrigDevicePathNode; Status = gBS->LocateDevicePath ( &gEfiDiskIoProtocolGuid, &DevicePathNode, &Handle ); if (!EFI_ERROR (Status)) { // // Measure GPT disk. // Status = TcgMeasureGptTable (TcgProtocol, Handle); if (!EFI_ERROR (Status)) { // // GPT disk check done. // mMeasureGptTableFlag = TRUE; } } FreePool (OrigDevicePathNode); OrigDevicePathNode = DuplicateDevicePath (File); ASSERT (OrigDevicePathNode != NULL); break; } } DevicePathNode = NextDevicePathNode (DevicePathNode); } } // // 2. Measure PE image. // ApplicationRequired = FALSE; // // Check whether this device path support FVB protocol. // DevicePathNode = OrigDevicePathNode; Status = gBS->LocateDevicePath (&gEfiFirmwareVolumeBlockProtocolGuid, &DevicePathNode, &Handle); if (!EFI_ERROR (Status)) { // // Don't check FV image, and directly return EFI_SUCCESS. // It can be extended to the specific FV authentication according to the different requirement. // if (IsDevicePathEnd (DevicePathNode)) { return EFI_SUCCESS; } // // The PE image from unmeasured Firmware volume need be measured // The PE image from measured Firmware volume will be mearsured according to policy below. // If it is driver, do not measure // If it is application, still measure. // ApplicationRequired = TRUE; if (mCacheMeasuredHandle != Handle && mMeasuredHobData != NULL) { // // Search for Root FV of this PE image // TempHandle = Handle; do { Status = gBS->HandleProtocol( TempHandle, &gEfiFirmwareVolumeBlockProtocolGuid, (VOID**)&FvbProtocol ); TempHandle = FvbProtocol->ParentHandle; } while (!EFI_ERROR(Status) && FvbProtocol->ParentHandle != NULL); // // Search in measured FV Hob // Status = FvbProtocol->GetPhysicalAddress(FvbProtocol, &FvAddress); if (EFI_ERROR(Status)){ return Status; } ApplicationRequired = FALSE; for (Index = 0; Index < mMeasuredHobData->Num; Index++) { if(mMeasuredHobData->MeasuredFvBuf[Index].BlobBase == FvAddress) { // // Cache measured FV for next measurement // mCacheMeasuredHandle = Handle; ApplicationRequired = TRUE; break; } } } } // // File is not found. // if (FileBuffer == NULL) { Status = EFI_SECURITY_VIOLATION; goto Finish; } mImageSize = FileSize; mFileBuffer = FileBuffer; // // Measure PE Image // DevicePathNode = OrigDevicePathNode; ZeroMem (&ImageContext, sizeof (ImageContext)); ImageContext.Handle = (VOID *) FileBuffer; ImageContext.ImageRead = (PE_COFF_LOADER_READ_FILE) DxeTpmMeasureBootLibImageRead; // // Get information about the image being loaded // Status = PeCoffLoaderGetImageInfo (&ImageContext); if (EFI_ERROR (Status)) { // // The information can't be got from the invalid PeImage // goto Finish; } // // Measure only application if Application flag is set // Measure drivers and applications if Application flag is not set // if ((!ApplicationRequired) || (ApplicationRequired && ImageContext.ImageType == EFI_IMAGE_SUBSYSTEM_EFI_APPLICATION)) { // // Print the image path to be measured. // DEBUG_CODE_BEGIN (); CHAR16 *ToText; ToText = ConvertDevicePathToText ( DevicePathNode, FALSE, TRUE ); if (ToText != NULL) { DEBUG ((DEBUG_INFO, "The measured image path is %s.\n", ToText)); FreePool (ToText); } DEBUG_CODE_END (); // // Measure PE image into TPM log. // Status = TcgMeasurePeImage ( TcgProtocol, (EFI_PHYSICAL_ADDRESS) (UINTN) FileBuffer, FileSize, (UINTN) ImageContext.ImageAddress, ImageContext.ImageType, DevicePathNode ); } // // Done, free the allocated resource. // Finish: if (OrigDevicePathNode != NULL) { FreePool (OrigDevicePathNode); } return Status; }
/** Get a human readable name for an image handle. The following methods will be tried orderly: 1. Image PDB 2. ComponentName2 protocol 3. FFS UI section 4. Image GUID 5. Image DevicePath 6. Unknown Driver Name @param[in] Handle @post The resulting Unicode name string is stored in the mGaugeString global array. **/ VOID DpGetNameFromHandle ( IN EFI_HANDLE Handle ) { EFI_STATUS Status; EFI_LOADED_IMAGE_PROTOCOL *Image; CHAR8 *PdbFileName; EFI_DRIVER_BINDING_PROTOCOL *DriverBinding; EFI_STRING StringPtr; EFI_DEVICE_PATH_PROTOCOL *LoadedImageDevicePath; EFI_DEVICE_PATH_PROTOCOL *DevicePath; EFI_GUID *NameGuid; CHAR16 *NameString; UINTN StringSize; CHAR8 *PlatformLanguage; EFI_COMPONENT_NAME2_PROTOCOL *ComponentName2; Image = NULL; LoadedImageDevicePath = NULL; DevicePath = NULL; // // Method 1: Get the name string from image PDB // Status = gBS->HandleProtocol ( Handle, &gEfiLoadedImageProtocolGuid, (VOID **) &Image ); if (EFI_ERROR (Status)) { Status = gBS->OpenProtocol ( Handle, &gEfiDriverBindingProtocolGuid, (VOID **) &DriverBinding, NULL, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL ); if (!EFI_ERROR (Status)) { Status = gBS->HandleProtocol ( DriverBinding->ImageHandle, &gEfiLoadedImageProtocolGuid, (VOID **) &Image ); } } if (!EFI_ERROR (Status)) { PdbFileName = PeCoffLoaderGetPdbPointer (Image->ImageBase); if (PdbFileName != NULL) { DpGetShortPdbFileName (PdbFileName, mGaugeString); return; } } // // Method 2: Get the name string from ComponentName2 protocol // Status = gBS->HandleProtocol ( Handle, &gEfiComponentName2ProtocolGuid, (VOID **) &ComponentName2 ); if (!EFI_ERROR (Status)) { // // Get the current platform language setting // PlatformLanguage = GetBestLanguageForDriver(ComponentName2->SupportedLanguages, NULL, FALSE); Status = ComponentName2->GetDriverName ( ComponentName2, PlatformLanguage != NULL ? PlatformLanguage : "en-US", &StringPtr ); if (!EFI_ERROR (Status)) { SHELL_FREE_NON_NULL (PlatformLanguage); StrnCpyS (mGaugeString, DP_GAUGE_STRING_LENGTH + 1, StringPtr, DP_GAUGE_STRING_LENGTH); mGaugeString[DP_GAUGE_STRING_LENGTH] = 0; return; } } Status = gBS->HandleProtocol ( Handle, &gEfiLoadedImageDevicePathProtocolGuid, (VOID **) &LoadedImageDevicePath ); if (!EFI_ERROR (Status) && (LoadedImageDevicePath != NULL)) { DevicePath = LoadedImageDevicePath; } else if (Image != NULL) { DevicePath = Image->FilePath; } if (DevicePath != NULL) { // // Try to get image GUID from image DevicePath // NameGuid = NULL; while (!IsDevicePathEndType (DevicePath)) { NameGuid = EfiGetNameGuidFromFwVolDevicePathNode ((MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *) DevicePath); if (NameGuid != NULL) { break; } DevicePath = NextDevicePathNode (DevicePath); } if (NameGuid != NULL) { // // Try to get the image's FFS UI section by image GUID // NameString = NULL; StringSize = 0; Status = GetSectionFromAnyFv ( NameGuid, EFI_SECTION_USER_INTERFACE, 0, (VOID **) &NameString, &StringSize ); if (!EFI_ERROR (Status)) { // // Method 3. Get the name string from FFS UI section // StrnCpyS (mGaugeString, DP_GAUGE_STRING_LENGTH + 1, NameString, DP_GAUGE_STRING_LENGTH); mGaugeString[DP_GAUGE_STRING_LENGTH] = 0; FreePool (NameString); } else { // // Method 4: Get the name string from image GUID // UnicodeSPrint (mGaugeString, sizeof (mGaugeString), L"%g", NameGuid); } return; } else { // // Method 5: Get the name string from image DevicePath // NameString = ConvertDevicePathToText (DevicePath, TRUE, FALSE); if (NameString != NULL) { StrnCpyS (mGaugeString, DP_GAUGE_STRING_LENGTH + 1, NameString, DP_GAUGE_STRING_LENGTH); mGaugeString[DP_GAUGE_STRING_LENGTH] = 0; FreePool (NameString); return; } } } // // Method 6: Unknown Driver Name // StringPtr = HiiGetString (gDpHiiHandle, STRING_TOKEN (STR_DP_ERROR_NAME), NULL); ASSERT (StringPtr != NULL); StrnCpyS (mGaugeString, DP_GAUGE_STRING_LENGTH + 1, StringPtr, DP_GAUGE_STRING_LENGTH); FreePool (StringPtr); }
static EFI_STATUS EFIAPI FSBindingStart(EFI_DRIVER_BINDING_PROTOCOL *This, EFI_HANDLE ControllerHandle, EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath) { EFI_STATUS Status; EFI_FS *Instance; EFI_DEVICE_PATH *DevicePath; PrintDebug(L"FSBindingStart\n"); /* Allocate a new instance of a filesystem */ Instance = AllocateZeroPool(sizeof(EFI_FS)); if (Instance == NULL) { Status = EFI_OUT_OF_RESOURCES; PrintStatusError(Status, L"Could not allocate a new file system instance"); return Status; } Instance->FileIoInterface.Revision = EFI_FILE_IO_INTERFACE_REVISION; Instance->FileIoInterface.OpenVolume = FileOpenVolume, /* Fill the device path for our instance */ DevicePath = DevicePathFromHandle(ControllerHandle); if (DevicePath == NULL) { Status = EFI_NO_MAPPING; PrintStatusError(Status, L"Could not get Device Path"); goto error; } Instance->DevicePathString = ConvertDevicePathToText(DevicePath, FALSE, FALSE); if (Instance->DevicePathString == NULL) { Status = EFI_OUT_OF_RESOURCES; PrintStatusError(Status, L"Could not allocate Device Path string"); goto error; } /* Get access to the Block IO protocol for this controller */ Status = BS->OpenProtocol(ControllerHandle, &gEfiBlockIo2ProtocolGuid, (VOID **) &Instance->BlockIo2, This->DriverBindingHandle, ControllerHandle, /* http://wiki.phoenix.com/wiki/index.php/EFI_BOOT_SERVICES#OpenProtocol.28.29 * EFI_OPEN_PROTOCOL_BY_DRIVER returns Access Denied here, most likely * because the disk driver has that protocol already open. So we use * EFI_OPEN_PROTOCOL_GET_PROTOCOL (which doesn't require us to close it) */ EFI_OPEN_PROTOCOL_GET_PROTOCOL); if (EFI_ERROR(Status)) { Instance->BlockIo2 = NULL; } Status = BS->OpenProtocol(ControllerHandle, &gEfiBlockIoProtocolGuid, (VOID **) &Instance->BlockIo, This->DriverBindingHandle, ControllerHandle, /* http://wiki.phoenix.com/wiki/index.php/EFI_BOOT_SERVICES#OpenProtocol.28.29 * EFI_OPEN_PROTOCOL_BY_DRIVER returns Access Denied here, most likely * because the disk driver has that protocol already open. So we use * EFI_OPEN_PROTOCOL_GET_PROTOCOL (which doesn't require us to close it) */ EFI_OPEN_PROTOCOL_GET_PROTOCOL); if (EFI_ERROR(Status)) { PrintStatusError(Status, L"Could not access BlockIO protocol"); goto error; } /* Get exclusive access to the Disk IO protocol */ Status = BS->OpenProtocol(ControllerHandle, &gEfiDiskIo2ProtocolGuid, (VOID**) &Instance->DiskIo2, This->DriverBindingHandle, ControllerHandle, EFI_OPEN_PROTOCOL_BY_DRIVER); if (EFI_ERROR(Status)) { Instance->DiskIo2 = NULL; } Status = BS->OpenProtocol(ControllerHandle, &gEfiDiskIoProtocolGuid, (VOID**) &Instance->DiskIo, This->DriverBindingHandle, ControllerHandle, EFI_OPEN_PROTOCOL_BY_DRIVER); if (EFI_ERROR(Status)) { PrintStatusError(Status, L"Could not access the DiskIo protocol"); goto error; } /* Go through GRUB target init */ Status = GrubDeviceInit(Instance); if (EFI_ERROR(Status)) { PrintStatusError(Status, L"Could not init grub device"); goto error; } Status = FSInstall(Instance, ControllerHandle); /* Unless we close the DiskIO protocol in case of error, no other * FS driver will be able to access this partition. */ if (EFI_ERROR(Status)) { GrubDeviceExit(Instance); BS->CloseProtocol(ControllerHandle, &gEfiDiskIo2ProtocolGuid, This->DriverBindingHandle, ControllerHandle); BS->CloseProtocol(ControllerHandle, &gEfiDiskIoProtocolGuid, This->DriverBindingHandle, ControllerHandle); } error: if (EFI_ERROR(Status)) FreeFsInstance(Instance); return Status; }