]> git.proxmox.com Git - mirror_edk2.git/blobdiff - OvmfPkg/VirtioBlkDxe/VirtioBlk.c
OvmfPkg: VirtioBlkInit(): expose virtio-blk topology in BlockIo
[mirror_edk2.git] / OvmfPkg / VirtioBlkDxe / VirtioBlk.c
index 5815cdf375dc79c8f531ec8ce06cf27d9497df89..55184faab2f5e41e266c5ab5688847cbb33d1436 100644 (file)
@@ -595,8 +595,15 @@ VirtioBlkInit (
   UINT32     Features;\r
   UINT64     NumSectors;\r
   UINT32     BlockSize;\r
+  UINT8      PhysicalBlockExp;\r
+  UINT8      AlignmentOffset;\r
+  UINT32     OptIoSize;\r
   UINT16     QueueSize;\r
 \r
+  PhysicalBlockExp = 0;\r
+  AlignmentOffset = 0;\r
+  OptIoSize = 0;\r
+\r
   //\r
   // Execute virtio-0.9.5, 2.2.1 Device Initialization Sequence.\r
   //\r
@@ -662,6 +669,28 @@ VirtioBlkInit (
     BlockSize = 512;\r
   }\r
 \r
+  if (Features & VIRTIO_BLK_F_TOPOLOGY) {\r
+    Status = VIRTIO_CFG_READ (Dev, Topology.PhysicalBlockExp,\r
+               &PhysicalBlockExp);\r
+    if (EFI_ERROR (Status)) {\r
+      goto Failed;\r
+    }\r
+    if (PhysicalBlockExp >= 32) {\r
+      Status = EFI_UNSUPPORTED;\r
+      goto Failed;\r
+    }\r
+\r
+    Status = VIRTIO_CFG_READ (Dev, Topology.AlignmentOffset, &AlignmentOffset);\r
+    if (EFI_ERROR (Status)) {\r
+      goto Failed;\r
+    }\r
+\r
+    Status = VIRTIO_CFG_READ (Dev, Topology.OptIoSize, &OptIoSize);\r
+    if (EFI_ERROR (Status)) {\r
+      goto Failed;\r
+    }\r
+  }\r
+\r
   //\r
   // step 4b -- allocate virtqueue\r
   //\r
@@ -728,9 +757,8 @@ VirtioBlkInit (
   }\r
 \r
   //\r
-  // Populate the exported interface's attributes; see UEFI spec v2.3.1 +\r
-  // Errata C, 12.8 EFI Block I/O Protocol. We stick to the lowest possible\r
-  // EFI_BLOCK_IO_PROTOCOL revision for now.\r
+  // Populate the exported interface's attributes; see UEFI spec v2.4, 12.9 EFI\r
+  // Block I/O Protocol.\r
   //\r
   Dev->BlockIo.Revision              = 0;\r
   Dev->BlockIo.Media                 = &Dev->BlockIoMedia;\r
@@ -748,6 +776,14 @@ VirtioBlkInit (
   Dev->BlockIoMedia.IoAlign          = 0;\r
   Dev->BlockIoMedia.LastBlock        = DivU64x32 (NumSectors,\r
                                          BlockSize / 512) - 1;\r
+\r
+  if (Features & VIRTIO_BLK_F_TOPOLOGY) {\r
+    Dev->BlockIo.Revision = EFI_BLOCK_IO_PROTOCOL_REVISION3;\r
+\r
+    Dev->BlockIoMedia.LowestAlignedLba = AlignmentOffset;\r
+    Dev->BlockIoMedia.LogicalBlocksPerPhysicalBlock = 1u << PhysicalBlockExp;\r
+    Dev->BlockIoMedia.OptimalTransferLengthGranularity = OptIoSize;\r
+  }\r
   return EFI_SUCCESS;\r
 \r
 ReleaseQueue:\r