On 07/14/15 01:18, Jordan Justen wrote: > Reviewed-by: Jordan Justen <jordan.l.jus...@intel.com>
Greatly appreciated! I committed the series to SVN as r17943 through r17965, inclusive. Now back to the end-of-dxe series... :) Thanks! Laszlo > > On 2015-07-07 08:09:25, Laszlo Ersek wrote: >> The OFW device path that QEMU exports in the "bootorder" fw_cfg file, for >> a device that is plugged into the main PCI root bus, is: >> >> /pci@i0cf8/... >> >> Whereas the same device plugged into the N'th extra root bus results in: >> >> /pci@i0cf8,N/pci-bridge@0/... >> >> (N is in hex.) >> >> Extend TranslatePciOfwNodes() so that it not assume a single PCI root; >> instead it parse the extra root bus serial number if present, and resolve >> it in the translation to the UEFI devpath fragment. >> >> Note that the "pci-bridge@0" node is a characteristic of QEMU's PXB >> device. It reflects the actual emulated PCI hierarchy. We don't parse it >> specifically in this patch, because it is automatically handled by the >> bridge sequence translator added recently in SVN rev 17385 (git commit >> feca17fa4b) -- "OvmfPkg: QemuBootOrderLib: parse OFW device path nodes of >> PCI bridges". >> >> The macro EXAMINED_OFW_NODES need not be raised from 6. The longest OFW >> device paths that we wish to recognize under this new scheme comprise 5 >> nodes. The initial "extra root bus" OFW fragment, visible at the top, >> takes up 2 nodes, after which the longest device-specific patterns (IDE >> disk, IDE CD-ROM, ISA floppy, virtio-scsi disk) take 3 more nodes each. >> >> Cc: Jordan Justen <jordan.l.jus...@intel.com> >> Contributed-under: TianoCore Contribution Agreement 1.0 >> Signed-off-by: Laszlo Ersek <ler...@redhat.com> >> --- >> >> Notes: >> v3: >> - updated to the most recently agreed upon OFW notation for extra root >> buses >> >> v2: >> - new in v2 >> >> OvmfPkg/Library/QemuBootOrderLib/QemuBootOrderLib.c | 152 >> ++++++++++++++++---- >> 1 file changed, 128 insertions(+), 24 deletions(-) >> >> diff --git a/OvmfPkg/Library/QemuBootOrderLib/QemuBootOrderLib.c >> b/OvmfPkg/Library/QemuBootOrderLib/QemuBootOrderLib.c >> index 276d675..2e96343 100644 >> --- a/OvmfPkg/Library/QemuBootOrderLib/QemuBootOrderLib.c >> +++ b/OvmfPkg/Library/QemuBootOrderLib/QemuBootOrderLib.c >> @@ -27,6 +27,7 @@ >> #include <Guid/GlobalVariable.h> >> #include <Guid/VirtioMmioTransport.h> >> >> +#include "ExtraRootBusMap.h" >> >> /** >> OpenFirmware to UEFI device path translation output buffer size in >> CHAR16's. >> @@ -556,6 +557,11 @@ ParseOfwNode ( >> >> @param[in] NumNodes Number of elements in OfwNode. >> >> + @param[in] ExtraPciRoots An EXTRA_ROOT_BUS_MAP object created with >> + CreateExtraRootBusMap(), to be used for >> + translating positions of extra root buses >> to >> + bus numbers. >> + >> @param[out] Translated Destination array receiving the UEFI path >> fragment, allocated by the caller. If the >> return value differs from RETURN_SUCCESS, >> its >> @@ -576,16 +582,23 @@ ParseOfwNode ( >> @retval RETURN_UNSUPPORTED The array of OpenFirmware device nodes >> can't >> be translated in the current >> implementation. >> >> + @retval RETURN_PROTOCOL_ERROR The initial OpenFirmware node refers to >> an >> + extra PCI root bus (by serial number) >> that >> + is invalid according to ExtraPciRoots. >> + >> **/ >> STATIC >> RETURN_STATUS >> TranslatePciOfwNodes ( >> - IN CONST OFW_NODE *OfwNode, >> - IN UINTN NumNodes, >> - OUT CHAR16 *Translated, >> - IN OUT UINTN *TranslatedSize >> + IN CONST OFW_NODE *OfwNode, >> + IN UINTN NumNodes, >> + IN CONST EXTRA_ROOT_BUS_MAP *ExtraPciRoots, >> + OUT CHAR16 *Translated, >> + IN OUT UINTN *TranslatedSize >> ) >> { >> + UINT32 PciRoot; >> + CHAR8 *Comma; >> UINTN FirstNonBridge; >> CHAR16 Bridges[BRIDGE_TRANSLATION_OUTPUT_SIZE]; >> UINTN BridgesLen; >> @@ -594,7 +607,17 @@ TranslatePciOfwNodes ( >> UINTN Written; >> >> // >> - // Get PCI device and optional PCI function. Assume a single PCI root. >> + // Resolve the PCI root bus number. >> + // >> + // The initial OFW node for the main root bus (ie. bus number 0) is: >> + // >> + // /pci@i0cf8 >> + // >> + // For extra root buses, the initial OFW node is >> + // >> + // /pci@i0cf8,4 >> + // ^ >> + // root bus serial number (not PCI bus number) >> // >> if (NumNodes < REQUIRED_PCI_OFW_NODES || >> !SubstringEq (OfwNode[0].DriverName, "pci") >> @@ -602,6 +625,35 @@ TranslatePciOfwNodes ( >> return RETURN_UNSUPPORTED; >> } >> >> + PciRoot = 0; >> + Comma = ScanMem8 (OfwNode[0].UnitAddress.Ptr, OfwNode[0].UnitAddress.Len, >> + ','); >> + if (Comma != NULL) { >> + SUBSTRING PciRootSerialSubString; >> + UINT64 PciRootSerial; >> + >> + // >> + // Parse the root bus serial number from the unit address after the >> comma. >> + // >> + PciRootSerialSubString.Ptr = Comma + 1; >> + PciRootSerialSubString.Len = OfwNode[0].UnitAddress.Len - >> + (PciRootSerialSubString.Ptr - >> + OfwNode[0].UnitAddress.Ptr); >> + NumEntries = 1; >> + if (RETURN_ERROR (ParseUnitAddressHexList (PciRootSerialSubString, >> + &PciRootSerial, &NumEntries))) { >> + return RETURN_UNSUPPORTED; >> + } >> + >> + // >> + // Map the extra root bus's serial number to its actual bus number. >> + // >> + if (EFI_ERROR (MapRootBusPosToBusNr (ExtraPciRoots, PciRootSerial, >> + &PciRoot))) { >> + return RETURN_PROTOCOL_ERROR; >> + } >> + } >> + >> // >> // Translate a sequence of PCI bridges. For each bridge, the OFW node is: >> // >> @@ -709,7 +761,8 @@ TranslatePciOfwNodes ( >> Written = UnicodeSPrintAsciiFormat ( >> Translated, >> *TranslatedSize * sizeof (*Translated), // BufferSize in bytes >> - "PciRoot(0x0)%s/Pci(0x%Lx,0x%Lx)/Ata(%a,%a,0x0)", >> + "PciRoot(0x%x)%s/Pci(0x%Lx,0x%Lx)/Ata(%a,%a,0x0)", >> + PciRoot, >> Bridges, >> PciDevFun[0], >> PciDevFun[1], >> @@ -753,7 +806,8 @@ TranslatePciOfwNodes ( >> Written = UnicodeSPrintAsciiFormat ( >> Translated, >> *TranslatedSize * sizeof (*Translated), // BufferSize in bytes >> - "PciRoot(0x0)%s/Pci(0x%Lx,0x%Lx)/Floppy(0x%Lx)", >> + "PciRoot(0x%x)%s/Pci(0x%Lx,0x%Lx)/Floppy(0x%Lx)", >> + PciRoot, >> Bridges, >> PciDevFun[0], >> PciDevFun[1], >> @@ -781,7 +835,8 @@ TranslatePciOfwNodes ( >> Written = UnicodeSPrintAsciiFormat ( >> Translated, >> *TranslatedSize * sizeof (*Translated), // BufferSize in bytes >> - "PciRoot(0x0)%s/Pci(0x%Lx,0x%Lx)/HD(", >> + "PciRoot(0x%x)%s/Pci(0x%Lx,0x%Lx)/HD(", >> + PciRoot, >> Bridges, >> PciDevFun[0], >> PciDevFun[1] >> @@ -825,7 +880,8 @@ TranslatePciOfwNodes ( >> Written = UnicodeSPrintAsciiFormat ( >> Translated, >> *TranslatedSize * sizeof (*Translated), // BufferSize in bytes >> - "PciRoot(0x0)%s/Pci(0x%Lx,0x%Lx)/Scsi(0x%Lx,0x%Lx)", >> + "PciRoot(0x%x)%s/Pci(0x%Lx,0x%Lx)/Scsi(0x%Lx,0x%Lx)", >> + PciRoot, >> Bridges, >> PciDevFun[0], >> PciDevFun[1], >> @@ -849,7 +905,8 @@ TranslatePciOfwNodes ( >> Written = UnicodeSPrintAsciiFormat ( >> Translated, >> *TranslatedSize * sizeof (*Translated), // BufferSize in bytes >> - "PciRoot(0x0)%s/Pci(0x%Lx,0x%Lx)", >> + "PciRoot(0x%x)%s/Pci(0x%Lx,0x%Lx)", >> + PciRoot, >> Bridges, >> PciDevFun[0], >> PciDevFun[1] >> @@ -1057,6 +1114,11 @@ TranslateMmioOfwNodes ( >> >> @param[in] NumNodes Number of elements in OfwNode. >> >> + @param[in] ExtraPciRoots An EXTRA_ROOT_BUS_MAP object created with >> + CreateExtraRootBusMap(), to be used for >> + translating positions of extra root buses >> to >> + bus numbers. >> + >> @param[out] Translated Destination array receiving the UEFI path >> fragment, allocated by the caller. If the >> return value differs from RETURN_SUCCESS, >> its >> @@ -1077,14 +1139,19 @@ TranslateMmioOfwNodes ( >> @retval RETURN_UNSUPPORTED The array of OpenFirmware device nodes >> can't >> be translated in the current >> implementation. >> >> + @retval RETURN_PROTOCOL_ERROR The array of OpenFirmware device nodes >> has >> + been (partially) recognized, but it >> contains >> + a logic error / doesn't match system >> state. >> + >> **/ >> STATIC >> RETURN_STATUS >> TranslateOfwNodes ( >> - IN CONST OFW_NODE *OfwNode, >> - IN UINTN NumNodes, >> - OUT CHAR16 *Translated, >> - IN OUT UINTN *TranslatedSize >> + IN CONST OFW_NODE *OfwNode, >> + IN UINTN NumNodes, >> + IN CONST EXTRA_ROOT_BUS_MAP *ExtraPciRoots, >> + OUT CHAR16 *Translated, >> + IN OUT UINTN *TranslatedSize >> ) >> { >> RETURN_STATUS Status; >> @@ -1092,8 +1159,8 @@ TranslateOfwNodes ( >> Status = RETURN_UNSUPPORTED; >> >> if (FeaturePcdGet (PcdQemuBootOrderPciTranslation)) { >> - Status = TranslatePciOfwNodes (OfwNode, NumNodes, Translated, >> - TranslatedSize); >> + Status = TranslatePciOfwNodes (OfwNode, NumNodes, ExtraPciRoots, >> + Translated, TranslatedSize); >> } >> if (Status == RETURN_UNSUPPORTED && >> FeaturePcdGet (PcdQemuBootOrderMmioTranslation)) { >> @@ -1117,6 +1184,11 @@ TranslateOfwNodes ( >> characters. In other error cases, it >> points to >> the byte that caused the error. >> >> + @param[in] ExtraPciRoots An EXTRA_ROOT_BUS_MAP object created with >> + CreateExtraRootBusMap(), to be used for >> + translating positions of extra root buses >> to >> + bus numbers. >> + >> @param[out] Translated Destination array receiving the UEFI path >> fragment, allocated by the caller. If the >> return value differs from RETURN_SUCCESS, >> its >> @@ -1142,6 +1214,12 @@ TranslateOfwNodes ( >> the current implementation. Further >> calls >> to this function are possible. >> >> + @retval RETURN_PROTOCOL_ERROR The OpenFirmware device path has been >> + (partially) recognized, but it contains >> a >> + logic error / doesn't match system >> state. >> + Further calls to this function are >> + possible. >> + >> @retval RETURN_NOT_FOUND Translation terminated. On input, *Ptr >> was >> pointing to the empty string or "HALT". >> On >> output, *Ptr points to the empty string >> @@ -1154,9 +1232,10 @@ TranslateOfwNodes ( >> STATIC >> RETURN_STATUS >> TranslateOfwPath ( >> - IN OUT CONST CHAR8 **Ptr, >> - OUT CHAR16 *Translated, >> - IN OUT UINTN *TranslatedSize >> + IN OUT CONST CHAR8 **Ptr, >> + IN CONST EXTRA_ROOT_BUS_MAP *ExtraPciRoots, >> + OUT CHAR16 *Translated, >> + IN OUT UINTN *TranslatedSize >> ) >> { >> UINTN NumNodes; >> @@ -1204,6 +1283,7 @@ TranslateOfwPath ( >> Status = TranslateOfwNodes ( >> Node, >> NumNodes < EXAMINED_OFW_NODES ? NumNodes : EXAMINED_OFW_NODES, >> + ExtraPciRoots, >> Translated, >> TranslatedSize); >> switch (Status) { >> @@ -1219,6 +1299,11 @@ TranslateOfwPath ( >> DEBUG ((DEBUG_VERBOSE, "%a: unsupported\n", __FUNCTION__)); >> break; >> >> + case RETURN_PROTOCOL_ERROR: >> + DEBUG ((DEBUG_VERBOSE, "%a: logic error / system state mismatch\n", >> + __FUNCTION__)); >> + break; >> + >> default: >> ASSERT (0); >> } >> @@ -1512,6 +1597,8 @@ SetBootOrderFromQemu ( >> ACTIVE_OPTION *ActiveOption; >> UINTN ActiveCount; >> >> + EXTRA_ROOT_BUS_MAP *ExtraPciRoots; >> + >> UINTN TranslatedSize; >> CHAR16 Translated[TRANSLATION_OUTPUT_SIZE]; >> >> @@ -1556,13 +1643,24 @@ SetBootOrderFromQemu ( >> goto ErrorFreeBootOrder; >> } >> >> + if (FeaturePcdGet (PcdQemuBootOrderPciTranslation)) { >> + Status = CreateExtraRootBusMap (&ExtraPciRoots); >> + if (EFI_ERROR (Status)) { >> + goto ErrorFreeActiveOption; >> + } >> + } else { >> + ExtraPciRoots = NULL; >> + } >> + >> // >> // translate each OpenFirmware path >> // >> TranslatedSize = sizeof (Translated) / sizeof (Translated[0]); >> - Status = TranslateOfwPath (&FwCfgPtr, Translated, &TranslatedSize); >> + Status = TranslateOfwPath (&FwCfgPtr, ExtraPciRoots, Translated, >> + &TranslatedSize); >> while (Status == RETURN_SUCCESS || >> Status == RETURN_UNSUPPORTED || >> + Status == RETURN_PROTOCOL_ERROR || >> Status == RETURN_BUFFER_TOO_SMALL) { >> if (Status == RETURN_SUCCESS) { >> UINTN Idx; >> @@ -1582,7 +1680,7 @@ SetBootOrderFromQemu ( >> // >> Status = BootOrderAppend (&BootOrder, &ActiveOption[Idx]); >> if (Status != RETURN_SUCCESS) { >> - goto ErrorFreeActiveOption; >> + goto ErrorFreeExtraPciRoots; >> } >> break; >> } >> @@ -1590,7 +1688,8 @@ SetBootOrderFromQemu ( >> } // translation successful >> >> TranslatedSize = sizeof (Translated) / sizeof (Translated[0]); >> - Status = TranslateOfwPath (&FwCfgPtr, Translated, &TranslatedSize); >> + Status = TranslateOfwPath (&FwCfgPtr, ExtraPciRoots, Translated, >> + &TranslatedSize); >> } // scanning of OpenFirmware paths done >> >> if (Status == RETURN_NOT_FOUND && BootOrder.Produced > 0) { >> @@ -1601,7 +1700,7 @@ SetBootOrderFromQemu ( >> // >> Status = BootOrderComplete (&BootOrder, ActiveOption, ActiveCount); >> if (RETURN_ERROR (Status)) { >> - goto ErrorFreeActiveOption; >> + goto ErrorFreeExtraPciRoots; >> } >> >> // >> @@ -1619,13 +1718,18 @@ SetBootOrderFromQemu ( >> ); >> if (EFI_ERROR (Status)) { >> DEBUG ((DEBUG_ERROR, "%a: setting BootOrder: %r\n", __FUNCTION__, >> Status)); >> - goto ErrorFreeActiveOption; >> + goto ErrorFreeExtraPciRoots; >> } >> >> DEBUG ((DEBUG_INFO, "%a: setting BootOrder: success\n", __FUNCTION__)); >> PruneBootVariables (ActiveOption, ActiveCount); >> } >> >> +ErrorFreeExtraPciRoots: >> + if (ExtraPciRoots != NULL) { >> + DestroyExtraRootBusMap (ExtraPciRoots); >> + } >> + >> ErrorFreeActiveOption: >> FreePool (ActiveOption); >> >> -- >> 1.8.3.1 >> ------------------------------------------------------------------------------ Don't Limit Your Business. Reach for the Cloud. GigeNET's Cloud Solutions provide you with the tools and support that you need to offload your IT needs and focus on growing your business. Configured For All Businesses. Start Your Cloud Today. https://www.gigenetcloud.com/ _______________________________________________ edk2-devel mailing list edk2-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/edk2-devel