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]
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