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