X-Git-Url: https://git.proxmox.com/?p=mirror_edk2.git;a=blobdiff_plain;f=OvmfPkg%2FLibrary%2FPlatformBdsLib%2FQemuBootOrder.c;h=c9b8556fab0f28c8932ce78deaa3ce640b9e8225;hp=2273d829c168d6080daa37aebdc3915f3f7c5f0b;hb=863986b3c8e67736d361b68e293d01e6f92f825c;hpb=2cd086a675535b6fc4cb54a75d10ca6f26a2da9e diff --git a/OvmfPkg/Library/PlatformBdsLib/QemuBootOrder.c b/OvmfPkg/Library/PlatformBdsLib/QemuBootOrder.c index 2273d829c1..c9b8556fab 100644 --- a/OvmfPkg/Library/PlatformBdsLib/QemuBootOrder.c +++ b/OvmfPkg/Library/PlatformBdsLib/QemuBootOrder.c @@ -1,7 +1,7 @@ /** @file Rewrite the BootOrder NvVar based on QEMU's "bootorder" fw_cfg file. - Copyright (C) 2012, Red Hat, Inc. + Copyright (C) 2012 - 2013, Red Hat, Inc. This program and the accompanying materials are licensed and made available under the terms and conditions of the BSD License which accompanies this @@ -20,7 +20,7 @@ #include #include #include -#include +#include #include @@ -31,9 +31,10 @@ /** - Number of nodes in OpenFirmware device paths that is required and examined. + Numbers of nodes in OpenFirmware device paths that are required and examined. **/ -#define FIXED_OFW_NODES 4 +#define REQUIRED_OFW_NODES 2 +#define EXAMINED_OFW_NODES 4 /** @@ -118,7 +119,7 @@ SubstringEq ( ++Chr; } - return (Pos == Substring.Len && *Chr == '\0'); + return (BOOLEAN)(Pos == Substring.Len && *Chr == '\0'); } @@ -497,7 +498,7 @@ TranslateOfwNodes ( // // Get PCI device and optional PCI function. Assume a single PCI root. // - if (NumNodes < FIXED_OFW_NODES || + if (NumNodes < REQUIRED_OFW_NODES || !SubstringEq (OfwNode[0].DriverName, "pci") ) { return RETURN_UNSUPPORTED; @@ -513,7 +514,8 @@ TranslateOfwNodes ( return RETURN_UNSUPPORTED; } - if (SubstringEq (OfwNode[1].DriverName, "ide") && + if (NumNodes >= 4 && + SubstringEq (OfwNode[1].DriverName, "ide") && SubstringEq (OfwNode[2].DriverName, "drive") && SubstringEq (OfwNode[3].DriverName, "disk") ) { @@ -562,7 +564,8 @@ TranslateOfwNodes ( Secondary ? "Secondary" : "Primary", Slave ? "Slave" : "Master" ); - } else if (SubstringEq (OfwNode[1].DriverName, "isa") && + } else if (NumNodes >= 4 && + SubstringEq (OfwNode[1].DriverName, "isa") && SubstringEq (OfwNode[2].DriverName, "fdc") && SubstringEq (OfwNode[3].DriverName, "floppy") ) { @@ -603,9 +606,109 @@ TranslateOfwNodes ( PciDevFun[1], AcpiUid ); - } else { - return RETURN_UNSUPPORTED; - } + } else if (NumNodes >= 3 && + SubstringEq (OfwNode[1].DriverName, "scsi") && + SubstringEq (OfwNode[2].DriverName, "disk") + ) { + // + // OpenFirmware device path (virtio-blk disk): + // + // /pci@i0cf8/scsi@6[,3]/disk@0,0 + // ^ ^ ^ ^ ^ + // | | | fixed + // | | PCI function corresponding to disk (optional) + // | PCI slot holding disk + // PCI root at system bus port, PIO + // + // UEFI device path prefix: + // + // PciRoot(0x0)/Pci(0x6,0x0)/HD( -- if PCI function is 0 or absent + // PciRoot(0x0)/Pci(0x6,0x3)/HD( -- if PCI function is present and nonzero + // + Written = UnicodeSPrintAsciiFormat ( + Translated, + *TranslatedSize * sizeof (*Translated), // BufferSize in bytes + "PciRoot(0x0)/Pci(0x%x,0x%x)/HD(", + PciDevFun[0], + PciDevFun[1] + ); + } else if (NumNodes >= 4 && + SubstringEq (OfwNode[1].DriverName, "scsi") && + SubstringEq (OfwNode[2].DriverName, "channel") && + SubstringEq (OfwNode[3].DriverName, "disk") + ) { + // + // OpenFirmware device path (virtio-scsi disk): + // + // /pci@i0cf8/scsi@7[,3]/channel@0/disk@2,3 + // ^ ^ ^ ^ ^ + // | | | | LUN + // | | | target + // | | channel (unused, fixed 0) + // | PCI slot[, function] holding SCSI controller + // PCI root at system bus port, PIO + // + // UEFI device path prefix: + // + // PciRoot(0x0)/Pci(0x7,0x0)/Scsi(0x2,0x3) + // -- if PCI function is 0 or absent + // PciRoot(0x0)/Pci(0x7,0x3)/Scsi(0x2,0x3) + // -- if PCI function is present and nonzero + // + UINT32 TargetLun[2]; + + TargetLun[1] = 0; + NumEntries = sizeof (TargetLun) / sizeof (TargetLun[0]); + if (ParseUnitAddressHexList ( + OfwNode[3].UnitAddress, + TargetLun, + &NumEntries + ) != RETURN_SUCCESS + ) { + return RETURN_UNSUPPORTED; + } + + Written = UnicodeSPrintAsciiFormat ( + Translated, + *TranslatedSize * sizeof (*Translated), // BufferSize in bytes + "PciRoot(0x0)/Pci(0x%x,0x%x)/Scsi(0x%x,0x%x)", + PciDevFun[0], + PciDevFun[1], + TargetLun[0], + TargetLun[1] + ); + } else if (NumNodes >= 3 && + SubstringEq (OfwNode[1].DriverName, "ethernet") && + SubstringEq (OfwNode[2].DriverName, "ethernet-phy") + ) { + // + // OpenFirmware device path (Ethernet NIC): + // + // /pci@i0cf8/ethernet@3[,2]/ethernet-phy@0 + // ^ ^ ^ + // | | fixed + // | PCI slot[, function] holding Ethernet card + // PCI root at system bus port, PIO + // + // UEFI device path prefix (dependent on presence of nonzero PCI function): + // + // PciRoot(0x0)/Pci(0x3,0x0)/MAC(525400E15EEF,0x1) + // PciRoot(0x0)/Pci(0x3,0x2)/MAC(525400E15EEF,0x1) + // ^ ^ + // MAC address IfType (1 == Ethernet) + // + // (Some UEFI NIC drivers don't set 0x1 for IfType.) + // + Written = UnicodeSPrintAsciiFormat ( + Translated, + *TranslatedSize * sizeof (*Translated), // BufferSize in bytes + "PciRoot(0x0)/Pci(0x%x,0x%x)/MAC", + PciDevFun[0], + PciDevFun[1] + ); + } else { + return RETURN_UNSUPPORTED; + } // // There's no way to differentiate between "completely used up without @@ -676,7 +779,7 @@ TranslateOfwPath ( { UINTN NumNodes; RETURN_STATUS Status; - OFW_NODE Node[FIXED_OFW_NODES]; + OFW_NODE Node[EXAMINED_OFW_NODES]; BOOLEAN IsFinal; OFW_NODE Skip; @@ -692,7 +795,7 @@ TranslateOfwPath ( ++NumNodes; Status = ParseOfwNode ( Ptr, - (NumNodes < FIXED_OFW_NODES) ? &Node[NumNodes] : &Skip, + (NumNodes < EXAMINED_OFW_NODES) ? &Node[NumNodes] : &Skip, &IsFinal ); } @@ -712,7 +815,7 @@ TranslateOfwPath ( Status = TranslateOfwNodes ( Node, - NumNodes < FIXED_OFW_NODES ? NumNodes : FIXED_OFW_NODES, + NumNodes < EXAMINED_OFW_NODES ? NumNodes : EXAMINED_OFW_NODES, Translated, TranslatedSize); switch (Status) { @@ -763,18 +866,17 @@ BOOLEAN Match ( IN CONST CHAR16 *Translated, IN UINTN TranslatedLength, - IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath, - IN CONST EFI_DEVICE_PATH_TO_TEXT_PROTOCOL *DevPathToText + IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath ) { CHAR16 *Converted; BOOLEAN Result; - Converted = DevPathToText->ConvertDevicePathToText ( - DevicePath, - FALSE, // DisplayOnly - FALSE // AllowShortcuts - ); + Converted = ConvertDevicePathToText ( + DevicePath, + FALSE, // DisplayOnly + FALSE // AllowShortcuts + ); if (Converted == NULL) { return FALSE; } @@ -782,7 +884,7 @@ Match ( // // Is Translated a prefix of Converted? // - Result = (StrnCmp (Converted, Translated, TranslatedLength) == 0); + Result = (BOOLEAN)(StrnCmp (Converted, Translated, TranslatedLength) == 0); DEBUG (( DEBUG_VERBOSE, "%a: against \"%s\": %a\n", @@ -830,9 +932,6 @@ SetBootOrderFromQemu ( ) { RETURN_STATUS Status; - - EFI_DEVICE_PATH_TO_TEXT_PROTOCOL *DevPathToText; - FIRMWARE_CONFIG_ITEM FwCfgItem; UINTN FwCfgSize; CHAR8 *FwCfg; @@ -843,15 +942,6 @@ SetBootOrderFromQemu ( UINTN TranslatedSize; CHAR16 Translated[TRANSLATION_OUTPUT_SIZE]; - Status = gBS->LocateProtocol ( - &gEfiDevicePathToTextProtocolGuid, - NULL, // optional registration key - (VOID **) &DevPathToText - ); - if (Status != EFI_SUCCESS) { - return Status; - } - Status = QemuFwCfgFindFile ("bootorder", &FwCfgItem, &FwCfgSize); if (Status != RETURN_SUCCESS) { return Status; @@ -916,8 +1006,7 @@ SetBootOrderFromQemu ( Match ( Translated, TranslatedSize, // contains length, not size, in CHAR16's here - BootOption->DevicePath, - DevPathToText + BootOption->DevicePath ) ) { //