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 <lersek@redhat.com>
Reviewed-by: Jordan Justen <jordan.l.justen@intel.com>

git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@15004 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
Laszlo Ersek 2013-12-18 19:57:46 +00:00 committed by jljusten
parent 21479c3c80
commit 6476804e3c
1 changed files with 39 additions and 3 deletions

View File

@ -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: