OvmfPkg/QemuBootOrderLib: add StoreQemuBootOrder()
The function reads the boot order from qemu fw_cfg, translates it into device paths and stores them in 'QemuBootOrderNNNN' variables. In case there is no boot ordering configured the function will do nothing. Use case: Allow applications loaded via 'qemu -kernel bootloader.efi' obey the boot order. Signed-off-by: Gerd Hoffmann <kraxel@redhat.com> Reviewed-by: Ard Biesheuvel <ardb@kernel.org>
This commit is contained in:
		
				
					committed by
					
						![mergify[bot]](/avatar/e3df20cd7a67969c41a65f03bea54961?size=40) mergify[bot]
						mergify[bot]
					
				
			
			
				
	
			
			
			
						parent
						
							db463e8e9d
						
					
				
				
					commit
					5eeb088ad6
				
			| @@ -1686,6 +1686,128 @@ FreeFwCfg: | ||||
|   return Status; | ||||
| } | ||||
|  | ||||
| /** | ||||
|   Write qemu boot order to uefi variables. | ||||
|  | ||||
|   Attempt to retrieve the "bootorder" fw_cfg file from QEMU. Translate | ||||
|   the OpenFirmware device paths therein to UEFI device path fragments. | ||||
|  | ||||
|   On Success store the device path in QemuBootOrderNNNN variables. | ||||
| **/ | ||||
| VOID | ||||
| EFIAPI | ||||
| StoreQemuBootOrder ( | ||||
|   VOID | ||||
|   ) | ||||
| { | ||||
|   RETURN_STATUS         Status; | ||||
|   FIRMWARE_CONFIG_ITEM  FwCfgItem; | ||||
|   UINTN                 FwCfgSize; | ||||
|   CHAR8                 *FwCfg; | ||||
|   EFI_STATUS            EfiStatus; | ||||
|   EXTRA_ROOT_BUS_MAP    *ExtraPciRoots; | ||||
|   CONST CHAR8           *FwCfgPtr; | ||||
|   UINTN                 TranslatedSize; | ||||
|   CHAR16                Translated[TRANSLATION_OUTPUT_SIZE]; | ||||
|   UINTN                 VariableIndex = 0; | ||||
|   CHAR16                VariableName[20]; | ||||
|  | ||||
|   Status = QemuFwCfgFindFile ("bootorder", &FwCfgItem, &FwCfgSize); | ||||
|   if (RETURN_ERROR (Status)) { | ||||
|     return; | ||||
|   } | ||||
|  | ||||
|   if (FwCfgSize == 0) { | ||||
|     return; | ||||
|   } | ||||
|  | ||||
|   FwCfg = AllocatePool (FwCfgSize); | ||||
|   if (FwCfg == NULL) { | ||||
|     return; | ||||
|   } | ||||
|  | ||||
|   QemuFwCfgSelectItem (FwCfgItem); | ||||
|   QemuFwCfgReadBytes (FwCfgSize, FwCfg); | ||||
|   if (FwCfg[FwCfgSize - 1] != '\0') { | ||||
|     Status = RETURN_INVALID_PARAMETER; | ||||
|     goto FreeFwCfg; | ||||
|   } | ||||
|  | ||||
|   DEBUG ((DEBUG_VERBOSE, "%a: FwCfg:\n", __FUNCTION__)); | ||||
|   DEBUG ((DEBUG_VERBOSE, "%a\n", FwCfg)); | ||||
|   DEBUG ((DEBUG_VERBOSE, "%a: FwCfg: <end>\n", __FUNCTION__)); | ||||
|  | ||||
|   if (FeaturePcdGet (PcdQemuBootOrderPciTranslation)) { | ||||
|     EfiStatus = CreateExtraRootBusMap (&ExtraPciRoots); | ||||
|     if (EFI_ERROR (EfiStatus)) { | ||||
|       Status = (RETURN_STATUS)EfiStatus; | ||||
|       goto FreeFwCfg; | ||||
|     } | ||||
|   } else { | ||||
|     ExtraPciRoots = NULL; | ||||
|   } | ||||
|  | ||||
|   // | ||||
|   // Translate each OpenFirmware path to a UEFI devpath prefix. | ||||
|   // | ||||
|   FwCfgPtr       = FwCfg; | ||||
|   TranslatedSize = ARRAY_SIZE (Translated); | ||||
|   Status         = TranslateOfwPath ( | ||||
|                      &FwCfgPtr, | ||||
|                      ExtraPciRoots, | ||||
|                      Translated, | ||||
|                      &TranslatedSize | ||||
|                      ); | ||||
|   while (!RETURN_ERROR (Status)) { | ||||
|     EFI_DEVICE_PATH_PROTOCOL  *DevicePath; | ||||
|  | ||||
|     // | ||||
|     // Convert the UEFI devpath prefix to binary representation. | ||||
|     // | ||||
|     ASSERT (Translated[TranslatedSize] == L'\0'); | ||||
|     DevicePath = ConvertTextToDevicePath (Translated); | ||||
|     if (DevicePath == NULL) { | ||||
|       Status = RETURN_OUT_OF_RESOURCES; | ||||
|       goto FreeExtraPciRoots; | ||||
|     } | ||||
|  | ||||
|     UnicodeSPrint ( | ||||
|       VariableName, | ||||
|       sizeof (VariableName), | ||||
|       L"QemuBootOrder%04d", | ||||
|       VariableIndex++ | ||||
|       ); | ||||
|     DEBUG ((DEBUG_INFO, "%a: %s = %s\n", __FUNCTION__, VariableName, Translated)); | ||||
|     gRT->SetVariable ( | ||||
|            VariableName, | ||||
|            &gQemuBootOrderGuid, | ||||
|            EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS, | ||||
|            GetDevicePathSize (DevicePath), | ||||
|            DevicePath | ||||
|            ); | ||||
|     FreePool (DevicePath); | ||||
|  | ||||
|     // | ||||
|     // Move to the next OFW devpath. | ||||
|     // | ||||
|     TranslatedSize = ARRAY_SIZE (Translated); | ||||
|     Status         = TranslateOfwPath ( | ||||
|                        &FwCfgPtr, | ||||
|                        ExtraPciRoots, | ||||
|                        Translated, | ||||
|                        &TranslatedSize | ||||
|                        ); | ||||
|   } | ||||
|  | ||||
| FreeExtraPciRoots: | ||||
|   if (ExtraPciRoots != NULL) { | ||||
|     DestroyExtraRootBusMap (ExtraPciRoots); | ||||
|   } | ||||
|  | ||||
| FreeFwCfg: | ||||
|   FreePool (FwCfg); | ||||
| } | ||||
|  | ||||
| /** | ||||
|  | ||||
|   Convert the UEFI DevicePath to full text representation with DevPathToText, | ||||
|   | ||||
		Reference in New Issue
	
	Block a user