From 6476804e3cd2e1da23dee03024a21ab0e5c1f8ec Mon Sep 17 00:00:00 2001 From: Laszlo Ersek Date: Wed, 18 Dec 2013 19:57:46 +0000 Subject: [PATCH] OvmfPkg: VirtioBlkInit(): expose virtio-blk topology in BlockIo UEFI spec virtio spec ======================================= ================================= LowestAlignedLba EFI_LBA (UINT64) alignment_offset u8 +-------------------------------------- +-------------------------------- | first LBA that is aligned to a | offset of first aligned | physical block boundary (SCSI | logical block | definition) LogicalBlocksPerPhysicalBlock UINT32 physical_block_exp u8 +-------------------------------------- +-------------------------------- | number of logical blocks per | # of logical blocks per | physical block [...] does not contain | physical block (log2) | an exponential value OptimalTransferLengthGranularity UINT32 opt_io_size le32 +-------------------------------------- +-------------------------------- | optimal transfer length granularity | optimal (suggested maximum) I/O | as a number of logical blocks [...] A | size in blocks | value of 0 means there is no reported | optimal transfer length granularity Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Laszlo Ersek Reviewed-by: Jordan Justen git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@15004 6f19259b-4bc3-4df7-8a09-765794883524 --- OvmfPkg/VirtioBlkDxe/VirtioBlk.c | 42 +++++++++++++++++++++++++++++--- 1 file changed, 39 insertions(+), 3 deletions(-) diff --git a/OvmfPkg/VirtioBlkDxe/VirtioBlk.c b/OvmfPkg/VirtioBlkDxe/VirtioBlk.c index 5815cdf375..55184faab2 100644 --- a/OvmfPkg/VirtioBlkDxe/VirtioBlk.c +++ b/OvmfPkg/VirtioBlkDxe/VirtioBlk.c @@ -595,8 +595,15 @@ VirtioBlkInit ( UINT32 Features; UINT64 NumSectors; UINT32 BlockSize; + UINT8 PhysicalBlockExp; + UINT8 AlignmentOffset; + UINT32 OptIoSize; UINT16 QueueSize; + PhysicalBlockExp = 0; + AlignmentOffset = 0; + OptIoSize = 0; + // // Execute virtio-0.9.5, 2.2.1 Device Initialization Sequence. // @@ -662,6 +669,28 @@ VirtioBlkInit ( BlockSize = 512; } + if (Features & VIRTIO_BLK_F_TOPOLOGY) { + Status = VIRTIO_CFG_READ (Dev, Topology.PhysicalBlockExp, + &PhysicalBlockExp); + if (EFI_ERROR (Status)) { + goto Failed; + } + if (PhysicalBlockExp >= 32) { + Status = EFI_UNSUPPORTED; + goto Failed; + } + + Status = VIRTIO_CFG_READ (Dev, Topology.AlignmentOffset, &AlignmentOffset); + if (EFI_ERROR (Status)) { + goto Failed; + } + + Status = VIRTIO_CFG_READ (Dev, Topology.OptIoSize, &OptIoSize); + if (EFI_ERROR (Status)) { + goto Failed; + } + } + // // step 4b -- allocate virtqueue // @@ -728,9 +757,8 @@ VirtioBlkInit ( } // - // Populate the exported interface's attributes; see UEFI spec v2.3.1 + - // Errata C, 12.8 EFI Block I/O Protocol. We stick to the lowest possible - // EFI_BLOCK_IO_PROTOCOL revision for now. + // Populate the exported interface's attributes; see UEFI spec v2.4, 12.9 EFI + // Block I/O Protocol. // Dev->BlockIo.Revision = 0; Dev->BlockIo.Media = &Dev->BlockIoMedia; @@ -748,6 +776,14 @@ VirtioBlkInit ( Dev->BlockIoMedia.IoAlign = 0; Dev->BlockIoMedia.LastBlock = DivU64x32 (NumSectors, BlockSize / 512) - 1; + + if (Features & VIRTIO_BLK_F_TOPOLOGY) { + Dev->BlockIo.Revision = EFI_BLOCK_IO_PROTOCOL_REVISION3; + + Dev->BlockIoMedia.LowestAlignedLba = AlignmentOffset; + Dev->BlockIoMedia.LogicalBlocksPerPhysicalBlock = 1u << PhysicalBlockExp; + Dev->BlockIoMedia.OptimalTransferLengthGranularity = OptIoSize; + } return EFI_SUCCESS; ReleaseQueue: