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
\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
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
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
}\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
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