]> git.proxmox.com Git - mirror_edk2.git/blobdiff - OvmfPkg/VirtioBlkDxe/VirtioBlk.c
OvmfPkg: S3 Resume: fake LockBox protocol for BootScriptExecutorDxe
[mirror_edk2.git] / OvmfPkg / VirtioBlkDxe / VirtioBlk.c
index 55283cb3ba66b866a0cdd7c0517a83b81841ce7d..35fc88e35bfbe73cb263a36fde69bc1b6c152331 100644 (file)
@@ -56,7 +56,8 @@
                        one of UINT8, UINT16, UINT32, UINT64.\r
 \r
 \r
-  @return  Status code returned by Virtio->WriteDevice() / Virtio->ReadDevice().\r
+  @return  Status code returned by Virtio->WriteDevice() /\r
+           Virtio->ReadDevice().\r
 \r
 **/\r
 \r
@@ -531,8 +532,8 @@ VirtioBlkDriverBindingSupported (
 \r
   //\r
   // Attempt to open the device with the VirtIo set of interfaces. On success,\r
-  // the protocol is "instantiated" for the VirtIo device. Covers duplicate open\r
-  // attempts (EFI_ALREADY_STARTED).\r
+  // the protocol is "instantiated" for the VirtIo device. Covers duplicate\r
+  // open attempts (EFI_ALREADY_STARTED).\r
   //\r
   Status = gBS->OpenProtocol (\r
                   DeviceHandle,               // candidate device\r
@@ -594,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
@@ -661,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
@@ -700,7 +730,7 @@ VirtioBlkInit (
   // step 4c -- Report GPFN (guest-physical frame number) of queue.\r
   //\r
   Status = Dev->VirtIo->SetQueueAddress (Dev->VirtIo,\r
-      (UINT32)(UINTN) Dev->Ring.Base >> EFI_PAGE_SHIFT);\r
+      (UINT32) ((UINTN) Dev->Ring.Base >> EFI_PAGE_SHIFT));\r
   if (EFI_ERROR (Status)) {\r
     goto ReleaseQueue;\r
   }\r
@@ -727,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
@@ -747,6 +776,24 @@ VirtioBlkInit (
   Dev->BlockIoMedia.IoAlign          = 0;\r
   Dev->BlockIoMedia.LastBlock        = DivU64x32 (NumSectors,\r
                                          BlockSize / 512) - 1;\r
+\r
+  DEBUG ((DEBUG_INFO, "%a: LbaSize=0x%x[B] NumBlocks=0x%Lx[Lba]\n",\r
+    __FUNCTION__, Dev->BlockIoMedia.BlockSize,\r
+    Dev->BlockIoMedia.LastBlock + 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
+    DEBUG ((DEBUG_INFO, "%a: FirstAligned=0x%Lx[Lba] PhysBlkSize=0x%x[Lba]\n",\r
+      __FUNCTION__, Dev->BlockIoMedia.LowestAlignedLba,\r
+      Dev->BlockIoMedia.LogicalBlocksPerPhysicalBlock));\r
+    DEBUG ((DEBUG_INFO, "%a: OptimalTransferLengthGranularity=0x%x[Lba]\n",\r
+      __FUNCTION__, Dev->BlockIoMedia.OptimalTransferLengthGranularity));\r
+  }\r
   return EFI_SUCCESS;\r
 \r
 ReleaseQueue:\r