]> git.proxmox.com Git - mirror_edk2.git/commitdiff
OvmfPkg/LegacyBbs: Add boot entries for VirtIO and NVME devices
authorDavid Woodhouse <dwmw2@infradead.org>
Wed, 26 Jun 2019 11:37:40 +0000 (12:37 +0100)
committerLaszlo Ersek <lersek@redhat.com>
Wed, 26 Jun 2019 13:06:44 +0000 (15:06 +0200)
Iterate over the available block devices in much the same way as
BdsLibEnumerateAllBootOption() does, but limiting to those devices
which are PCI-backed, which can be represented in the BbsTable.

One day we might need to extend the BbsTable to allow us to distinguish
between different NVMe namespaces on a device.

Signed-off-by: David Woodhouse <dwmw2@infradead.org>
Acked-by: Laszlo Ersek <lersek@redhat.com>
Message-Id: <20190626113742.819933-3-dwmw2@infradead.org>

OvmfPkg/Csm/LegacyBiosDxe/LegacyBbs.c

index 6b1dd344f3446336caf96d40f3b28058153618c0..5e4c7a249ef15fb07234fa9413ba6b859235b1ee 100644 (file)
@@ -140,10 +140,14 @@ LegacyBiosBuildBbs (
   IN  BBS_TABLE                 *BbsTable\r
   )\r
 {\r
-  UINTN     BbsIndex;\r
-  HDD_INFO  *HddInfo;\r
-  UINTN     HddIndex;\r
-  UINTN     Index;\r
+  UINTN       BbsIndex;\r
+  HDD_INFO    *HddInfo;\r
+  UINTN       HddIndex;\r
+  UINTN       Index;\r
+  EFI_HANDLE  *BlockIoHandles;\r
+  UINTN       NumberBlockIoHandles;\r
+  UINTN       BlockIndex;\r
+  EFI_STATUS  Status;\r
 \r
   //\r
   // First entry is floppy.\r
@@ -252,8 +256,151 @@ LegacyBiosBuildBbs (
     }\r
   }\r
 \r
-  return EFI_SUCCESS;\r
+  //\r
+  // Add non-IDE block devices\r
+  //\r
+  BbsIndex = HddIndex * 2 + 1;\r
+\r
+  Status = gBS->LocateHandleBuffer (\r
+                  ByProtocol,\r
+                  &gEfiBlockIoProtocolGuid,\r
+                  NULL,\r
+                  &NumberBlockIoHandles,\r
+                  &BlockIoHandles\r
+                  );\r
+\r
+  if (!EFI_ERROR (Status)) {\r
+    UINTN                     Removable;\r
+    EFI_BLOCK_IO_PROTOCOL     *BlkIo;\r
+    EFI_PCI_IO_PROTOCOL       *PciIo;\r
+    EFI_DEVICE_PATH_PROTOCOL  *DevicePath;\r
+    EFI_DEVICE_PATH_PROTOCOL  *DevicePathNode;\r
+    EFI_HANDLE                PciHandle;\r
+    UINTN                     SegNum;\r
+    UINTN                     BusNum;\r
+    UINTN                     DevNum;\r
+    UINTN                     FuncNum;\r
+\r
+    for (Removable = 0; Removable < 2; Removable++) {\r
+      for (BlockIndex = 0; BlockIndex < NumberBlockIoHandles; BlockIndex++) {\r
+        Status = gBS->HandleProtocol (\r
+                        BlockIoHandles[BlockIndex],\r
+                        &gEfiBlockIoProtocolGuid,\r
+                        (VOID **) &BlkIo\r
+                        );\r
+\r
+        if (EFI_ERROR (Status)) {\r
+          continue;\r
+        }\r
+\r
+        //\r
+        // Skip the logical partitions\r
+        //\r
+        if (BlkIo->Media->LogicalPartition) {\r
+          continue;\r
+        }\r
+\r
+        //\r
+        // Skip the fixed block io then the removable block io\r
+        //\r
+        if (BlkIo->Media->RemovableMedia == ((Removable == 0) ? FALSE : TRUE)) {\r
+          continue;\r
+        }\r
 \r
+        //\r
+        // Get Device Path\r
+        //\r
+        Status = gBS->HandleProtocol (\r
+                        BlockIoHandles[BlockIndex],\r
+                        &gEfiDevicePathProtocolGuid,\r
+                        (VOID **) &DevicePath\r
+                        );\r
+        if (EFI_ERROR (Status)) {\r
+          continue;\r
+        }\r
+\r
+        //\r
+        // Skip ATA devices as they have already been handled\r
+        //\r
+        DevicePathNode = DevicePath;\r
+        while (!IsDevicePathEnd (DevicePathNode)) {\r
+          if (DevicePathType (DevicePathNode) == MESSAGING_DEVICE_PATH &&\r
+              DevicePathSubType (DevicePathNode) == MSG_ATAPI_DP) {\r
+            break;\r
+          }\r
+          DevicePathNode = NextDevicePathNode (DevicePathNode);\r
+        }\r
+        if (!IsDevicePathEnd (DevicePathNode)) {\r
+            continue;\r
+        }\r
+\r
+        //\r
+        //  Locate which PCI device\r
+        //\r
+        Status = gBS->LocateDevicePath (\r
+                        &gEfiPciIoProtocolGuid,\r
+                        &DevicePath,\r
+                        &PciHandle\r
+                        );\r
+        if (EFI_ERROR (Status)) {\r
+          continue;\r
+        }\r
+\r
+        Status = gBS->HandleProtocol (\r
+                        PciHandle,\r
+                        &gEfiPciIoProtocolGuid,\r
+                        (VOID **) &PciIo\r
+                        );\r
+        if (EFI_ERROR (Status)) {\r
+          continue;\r
+        }\r
+\r
+        Status = PciIo->GetLocation (\r
+                          PciIo,\r
+                          &SegNum,\r
+                          &BusNum,\r
+                          &DevNum,\r
+                          &FuncNum\r
+                          );\r
+        if (EFI_ERROR (Status)) {\r
+          continue;\r
+        }\r
+\r
+        if (SegNum != 0) {\r
+          DEBUG ((DEBUG_WARN, "CSM cannot use PCI devices in segment %Lu\n",\r
+            (UINT64) SegNum));\r
+          continue;\r
+        }\r
+\r
+        DEBUG ((DEBUG_INFO, "Add Legacy Bbs entry for PCI %d/%d/%d\n",\r
+          BusNum, DevNum, FuncNum));\r
+\r
+        BbsTable[BbsIndex].Bus                      = BusNum;\r
+        BbsTable[BbsIndex].Device                   = DevNum;\r
+        BbsTable[BbsIndex].Function                 = FuncNum;\r
+        BbsTable[BbsIndex].Class                    = 1;\r
+        BbsTable[BbsIndex].SubClass                 = 0x80;\r
+        BbsTable[BbsIndex].StatusFlags.OldPosition  = 0;\r
+        BbsTable[BbsIndex].StatusFlags.Reserved1    = 0;\r
+        BbsTable[BbsIndex].StatusFlags.Enabled      = 0;\r
+        BbsTable[BbsIndex].StatusFlags.Failed       = 0;\r
+        BbsTable[BbsIndex].StatusFlags.MediaPresent = 0;\r
+        BbsTable[BbsIndex].StatusFlags.Reserved2    = 0;\r
+        BbsTable[BbsIndex].DeviceType               = BBS_HARDDISK;\r
+        BbsTable[BbsIndex].BootPriority             = BBS_UNPRIORITIZED_ENTRY;\r
+        BbsIndex++;\r
+\r
+        if (BbsIndex == MAX_BBS_ENTRIES) {\r
+          Removable = 2;\r
+          break;\r
+        }\r
+      }\r
+    }\r
+\r
+    FreePool (BlockIoHandles);\r
+  }\r
+\r
+  return EFI_SUCCESS;\r
 }\r
 \r
 \r