TianoCore EDK2 master
Loading...
Searching...
No Matches
VirtioBlk.c File Reference

Go to the source code of this file.

Macros

#define VIRTIO_CFG_WRITE(Dev, Field, Value)
 
#define VIRTIO_CFG_READ(Dev, Field, Pointer)
 

Functions

EFI_STATUS EFIAPI VirtioBlkReset (IN EFI_BLOCK_IO_PROTOCOL *This, IN BOOLEAN ExtendedVerification)
 
STATIC EFI_STATUS EFIAPI VerifyReadWriteRequest (IN EFI_BLOCK_IO_MEDIA *Media, IN EFI_LBA Lba, IN UINTN PositiveBufferSize, IN BOOLEAN RequestIsWrite)
 
STATIC EFI_STATUS EFIAPI SynchronousRequest (IN VBLK_DEV *Dev, IN EFI_LBA Lba, IN UINTN BufferSize, IN OUT volatile VOID *Buffer, IN BOOLEAN RequestIsWrite)
 
EFI_STATUS EFIAPI VirtioBlkReadBlocks (IN EFI_BLOCK_IO_PROTOCOL *This, IN UINT32 MediaId, IN EFI_LBA Lba, IN UINTN BufferSize, OUT VOID *Buffer)
 
EFI_STATUS EFIAPI VirtioBlkWriteBlocks (IN EFI_BLOCK_IO_PROTOCOL *This, IN UINT32 MediaId, IN EFI_LBA Lba, IN UINTN BufferSize, IN VOID *Buffer)
 
EFI_STATUS EFIAPI VirtioBlkFlushBlocks (IN EFI_BLOCK_IO_PROTOCOL *This)
 
EFI_STATUS EFIAPI VirtioBlkDriverBindingSupported (IN EFI_DRIVER_BINDING_PROTOCOL *This, IN EFI_HANDLE DeviceHandle, IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath)
 
STATIC EFI_STATUS EFIAPI VirtioBlkInit (IN OUT VBLK_DEV *Dev)
 
STATIC VOID EFIAPI VirtioBlkUninit (IN OUT VBLK_DEV *Dev)
 
STATIC VOID EFIAPI VirtioBlkExitBoot (IN EFI_EVENT Event, IN VOID *Context)
 
EFI_STATUS EFIAPI VirtioBlkDriverBindingStart (IN EFI_DRIVER_BINDING_PROTOCOL *This, IN EFI_HANDLE DeviceHandle, IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath)
 
EFI_STATUS EFIAPI VirtioBlkDriverBindingStop (IN EFI_DRIVER_BINDING_PROTOCOL *This, IN EFI_HANDLE DeviceHandle, IN UINTN NumberOfChildren, IN EFI_HANDLE *ChildHandleBuffer)
 
EFI_STATUS EFIAPI VirtioBlkGetDriverName (IN EFI_COMPONENT_NAME_PROTOCOL *This, IN CHAR8 *Language, OUT CHAR16 **DriverName)
 
EFI_STATUS EFIAPI VirtioBlkGetDeviceName (IN EFI_COMPONENT_NAME_PROTOCOL *This, IN EFI_HANDLE DeviceHandle, IN EFI_HANDLE ChildHandle, IN CHAR8 *Language, OUT CHAR16 **ControllerName)
 
EFI_STATUS EFIAPI VirtioBlkEntryPoint (IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable)
 

Variables

STATIC EFI_DRIVER_BINDING_PROTOCOL gDriverBinding
 
STATIC EFI_UNICODE_STRING_TABLE mDriverNameTable []
 
STATIC EFI_COMPONENT_NAME_PROTOCOL gComponentName
 
STATIC EFI_COMPONENT_NAME2_PROTOCOL gComponentName2
 

Detailed Description

This driver produces Block I/O Protocol instances for virtio-blk devices.

The implementation is basic:

  • No attach/detach (ie. removable media).
  • Although the non-blocking interfaces of EFI_BLOCK_IO2_PROTOCOL could be a good match for multiple in-flight virtio-blk requests, we stick to synchronous requests and EFI_BLOCK_IO_PROTOCOL for now.

Copyright (C) 2012, Red Hat, Inc. Copyright (c) 2012 - 2018, Intel Corporation. All rights reserved.
Copyright (c) 2017, AMD Inc, All rights reserved.
Copyright (c) 2024, Arm Limited. All rights reserved.

SPDX-License-Identifier: BSD-2-Clause-Patent

Definition in file VirtioBlk.c.

Macro Definition Documentation

◆ VIRTIO_CFG_READ

#define VIRTIO_CFG_READ (   Dev,
  Field,
  Pointer 
)
Value:
((Dev)->VirtIo->ReadDevice ( \
(Dev)->VirtIo, \
OFFSET_OF_VBLK (Field), \
SIZE_OF_VBLK (Field), \
sizeof *(Pointer), \
(Pointer) \
))

Definition at line 67 of file VirtioBlk.c.

◆ VIRTIO_CFG_WRITE

#define VIRTIO_CFG_WRITE (   Dev,
  Field,
  Value 
)
Value:
((Dev)->VirtIo->WriteDevice ( \
(Dev)->VirtIo, \
OFFSET_OF_VBLK (Field), \
SIZE_OF_VBLK (Field), \
(Value) \
))

Convenience macros to read and write region 0 IO space elements of the virtio-blk device, for configuration purposes.

The following macros make it possible to specify only the "core parameters" for such accesses and to derive the rest. By the time VIRTIO_CFG_WRITE() returns, the transaction will have been completed.

Parameters
[in]DevPointer to the VBLK_DEV structure whose VirtIo space we're accessing. Dev->VirtIo must be valid.
[in]FieldA field name from VBLK_HDR, identifying the virtio-blk configuration item to access.
[in]Value(VIRTIO_CFG_WRITE() only.) The value to write to the selected configuration item.
[out]Pointer(VIRTIO_CFG_READ() only.) The object to receive the value read from the configuration item. Its type must be one of UINT8, UINT16, UINT32, UINT64.
Returns
Status code returned by Virtio->WriteDevice() / Virtio->ReadDevice().

Definition at line 60 of file VirtioBlk.c.

Function Documentation

◆ SynchronousRequest()

STATIC EFI_STATUS EFIAPI SynchronousRequest ( IN VBLK_DEV Dev,
IN EFI_LBA  Lba,
IN UINTN  BufferSize,
IN OUT volatile VOID *  Buffer,
IN BOOLEAN  RequestIsWrite 
)

Format a read / write / flush request as three consecutive virtio descriptors, push them to the host, and poll for the response.

This is the main workhorse function. Two use cases are supported, read/write and flush. The function may only be called after the request parameters have been verified by

Parameters handled commonly:

Parameters
[in]DevThe virtio-blk device the request is targeted at.

Flush request:

Parameters
[in]LbaMust be zero.
[in]BufferSizeMust be zero.
[in,out]BufferIgnored by the function.
[in]RequestIsWriteMust be TRUE.

Read/Write request:

Parameters
[in]LbaLogical Block Address: number of logical blocks to skip from the beginning of the device.
[in]BufferSizeSize of buffer to transfer, in bytes. The caller is responsible to ensure this parameter is positive.
[in,out]BufferThe guest side area to read data from the device into, or write data to the device from.
[in]RequestIsWriteTRUE iff data transfer goes from guest to device.

Return values are common to both use cases, and are appropriate to be forwarded by the EFI_BLOCK_IO_PROTOCOL functions (ReadBlocks(), WriteBlocks(), FlushBlocks()).

Return values
EFI_SUCCESSTransfer complete.
EFI_DEVICE_ERRORFailed to notify host side via VirtIo write, or unable to parse host response, or host response is not VIRTIO_BLK_S_OK or failed to map Buffer for a bus master operation.

Definition at line 235 of file VirtioBlk.c.

◆ VerifyReadWriteRequest()

STATIC EFI_STATUS EFIAPI VerifyReadWriteRequest ( IN EFI_BLOCK_IO_MEDIA Media,
IN EFI_LBA  Lba,
IN UINTN  PositiveBufferSize,
IN BOOLEAN  RequestIsWrite 
)

Verify correctness of the read/write (not flush) request submitted to the EFI_BLOCK_IO_PROTOCOL instance.

This function provides most verification steps described in:

UEFI Spec 2.3.1 + Errata C, 12.8 EFI Block I/O Protocol, 12.8 EFI Block I/O Protocol,

  • EFI_BLOCK_IO_PROTOCOL.ReadBlocks()
  • EFI_BLOCK_IO_PROTOCOL.WriteBlocks()

Driver Writer's Guide for UEFI 2.3.1 v1.01,

  • 24.2.2. ReadBlocks() and ReadBlocksEx() Implementation
  • 24.2.3 WriteBlocks() and WriteBlockEx() Implementation

Request sizes are limited to 1 GB (checked). This is not a practical limitation, just conformance to virtio-0.9.5, 2.3.2 Descriptor Table: "no descriptor chain may be more than 2^32 bytes long in total".

Some Media characteristics are hardcoded in VirtioBlkInit() below (like non-removable media, no restriction on buffer alignment etc); we rely on those here without explicit mention.

Parameters
[in]MediaThe EFI_BLOCK_IO_MEDIA characteristics for this driver instance, extracted from the underlying virtio-blk device at initialization time. We validate the request against this set of attributes.
[in]LbaLogical Block Address: number of logical blocks to skip from the beginning of the device.
[in]PositiveBufferSizeSize of buffer to transfer, in bytes. The caller is responsible to ensure this parameter is positive.
[in]RequestIsWriteTRUE iff data transfer goes from guest to device.

@return Validation result to be forwarded outwards by ReadBlocks() and WriteBlocks, as required by the specs above.

Definition at line 145 of file VirtioBlk.c.

◆ VirtioBlkDriverBindingStart()

EFI_STATUS EFIAPI VirtioBlkDriverBindingStart ( IN EFI_DRIVER_BINDING_PROTOCOL This,
IN EFI_HANDLE  DeviceHandle,
IN EFI_DEVICE_PATH_PROTOCOL RemainingDevicePath 
)

After we've pronounced support for a specific device in DriverBindingSupported(), we start managing said device (passed in by the Driver Execution Environment) with the following service.

See DriverBindingSupported() for specification references.

Parameters
[in]ThisThe EFI_DRIVER_BINDING_PROTOCOL object incorporating this driver (independently of any device).
[in]DeviceHandleThe supported device to drive.
[in]RemainingDevicePathRelevant only for bus drivers, ignored.
Return values
EFI_SUCCESSDriver instance has been created and initialized for the virtio-blk device, it is now accessible via EFI_BLOCK_IO_PROTOCOL.
EFI_OUT_OF_RESOURCESMemory allocation failed.
Returns
Error codes from the OpenProtocol() boot service, the VirtIo protocol, VirtioBlkInit(), or the InstallProtocolInterface() boot service.

Definition at line 1092 of file VirtioBlk.c.

◆ VirtioBlkDriverBindingStop()

EFI_STATUS EFIAPI VirtioBlkDriverBindingStop ( IN EFI_DRIVER_BINDING_PROTOCOL This,
IN EFI_HANDLE  DeviceHandle,
IN UINTN  NumberOfChildren,
IN EFI_HANDLE ChildHandleBuffer 
)

Stop driving a virtio-blk device and remove its BlockIo interface.

This function replays the success path of DriverBindingStart() in reverse. The host side virtio-blk device is reset, so that the OS boot loader or the OS may reinitialize it.

Parameters
[in]ThisThe EFI_DRIVER_BINDING_PROTOCOL object incorporating this driver (independently of any device).
[in]DeviceHandleStop driving this device.
[in]NumberOfChildrenSince this function belongs to a device driver only (as opposed to a bus driver), the caller environment sets NumberOfChildren to zero, and we ignore it.
[in]ChildHandleBufferIgnored (corresponding to NumberOfChildren).

Definition at line 1197 of file VirtioBlk.c.

◆ VirtioBlkDriverBindingSupported()

EFI_STATUS EFIAPI VirtioBlkDriverBindingSupported ( IN EFI_DRIVER_BINDING_PROTOCOL This,
IN EFI_HANDLE  DeviceHandle,
IN EFI_DEVICE_PATH_PROTOCOL RemainingDevicePath 
)

Device probe function for this driver.

The DXE core calls this function for any given device in order to see if the driver can drive the device.

Specs relevant in the general sense:

  • UEFI Spec 2.3.1 + Errata C:
    • 6.3 Protocol Handler Services – for accessing the underlying device
    • 10.1 EFI Driver Binding Protocol – for exporting ourselves
  • Driver Writer's Guide for UEFI 2.3.1 v1.01:
    • 5.1.3.4 OpenProtocol() and CloseProtocol() – for accessing the underlying device
    • 9 Driver Binding Protocol – for exporting ourselves
Parameters
[in]ThisThe EFI_DRIVER_BINDING_PROTOCOL object incorporating this driver (independently of any device).
[in]DeviceHandleThe device to probe.
[in]RemainingDevicePathRelevant only for bus drivers, ignored.
Return values
EFI_SUCCESSThe driver supports the device being probed.
EFI_UNSUPPORTEDBased on virtio-blk discovery, we do not support the device.
Returns
Error codes from the OpenProtocol() boot service or the VirtIo protocol.

Definition at line 652 of file VirtioBlk.c.

◆ VirtioBlkEntryPoint()

EFI_STATUS EFIAPI VirtioBlkEntryPoint ( IN EFI_HANDLE  ImageHandle,
IN EFI_SYSTEM_TABLE SystemTable 
)

Definition at line 1335 of file VirtioBlk.c.

◆ VirtioBlkExitBoot()

STATIC VOID EFIAPI VirtioBlkExitBoot ( IN EFI_EVENT  Event,
IN VOID *  Context 
)

Event notification function enqueued by ExitBootServices().

Parameters
[in]EventEvent whose notification function is being invoked.
[in]ContextPointer to the VBLK_DEV structure.

Definition at line 1043 of file VirtioBlk.c.

◆ VirtioBlkFlushBlocks()

EFI_STATUS EFIAPI VirtioBlkFlushBlocks ( IN EFI_BLOCK_IO_PROTOCOL This)

FlushBlocks() operation for virtio-blk.

See

  • UEFI Spec 2.3.1 + Errata C, 12.8 EFI Block I/O Protocol, 12.8 EFI Block I/O Protocol, EFI_BLOCK_IO_PROTOCOL.FlushBlocks().
  • Driver Writer's Guide for UEFI 2.3.1 v1.01, 24.2.4 FlushBlocks() and FlushBlocksEx() Implementation.

If the underlying virtio-blk device doesn't support flushing (ie. write-caching), then this function should not be called by higher layers, according to EFI_BLOCK_IO_MEDIA characteristics set in VirtioBlkInit(). Should they do nonetheless, we do nothing, successfully.

Definition at line 596 of file VirtioBlk.c.

◆ VirtioBlkGetDeviceName()

EFI_STATUS EFIAPI VirtioBlkGetDeviceName ( IN EFI_COMPONENT_NAME_PROTOCOL This,
IN EFI_HANDLE  DeviceHandle,
IN EFI_HANDLE  ChildHandle,
IN CHAR8 *  Language,
OUT CHAR16 **  ControllerName 
)

Definition at line 1305 of file VirtioBlk.c.

◆ VirtioBlkGetDriverName()

EFI_STATUS EFIAPI VirtioBlkGetDriverName ( IN EFI_COMPONENT_NAME_PROTOCOL This,
IN CHAR8 *  Language,
OUT CHAR16 **  DriverName 
)

Definition at line 1288 of file VirtioBlk.c.

◆ VirtioBlkInit()

STATIC EFI_STATUS EFIAPI VirtioBlkInit ( IN OUT VBLK_DEV Dev)

Set up all BlockIo and virtio-blk aspects of this driver for the specified device.

Parameters
[in,out]DevThe driver instance to configure. The caller is responsible for Dev->VirtIo's validity (ie. working IO access to the underlying virtio-blk device).
Return values
EFI_SUCCESSSetup complete.
EFI_UNSUPPORTEDThe driver is unable to work with the virtio ring or virtio-blk attributes the host provides.
Returns
Error codes from VirtioRingInit() or VIRTIO_CFG_READ() / VIRTIO_CFG_WRITE or VirtioRingMap().

Definition at line 719 of file VirtioBlk.c.

◆ VirtioBlkReadBlocks()

EFI_STATUS EFIAPI VirtioBlkReadBlocks ( IN EFI_BLOCK_IO_PROTOCOL This,
IN UINT32  MediaId,
IN EFI_LBA  Lba,
IN UINTN  BufferSize,
OUT VOID *  Buffer 
)

ReadBlocks() operation for virtio-blk.

See

  • UEFI Spec 2.3.1 + Errata C, 12.8 EFI Block I/O Protocol, 12.8 EFI Block I/O Protocol, EFI_BLOCK_IO_PROTOCOL.ReadBlocks().
  • Driver Writer's Guide for UEFI 2.3.1 v1.01, 24.2.2. ReadBlocks() and ReadBlocksEx() Implementation.

Parameter checks and conformant return values are implemented in VerifyReadWriteRequest() and SynchronousRequest().

A zero BufferSize doesn't seem to be prohibited, so do nothing in that case, successfully.

Definition at line 489 of file VirtioBlk.c.

◆ VirtioBlkReset()

EFI_STATUS EFIAPI VirtioBlkReset ( IN EFI_BLOCK_IO_PROTOCOL This,
IN BOOLEAN  ExtendedVerification 
)

Definition at line 82 of file VirtioBlk.c.

◆ VirtioBlkUninit()

STATIC VOID EFIAPI VirtioBlkUninit ( IN OUT VBLK_DEV Dev)

Uninitialize the internals of a virtio-blk device that has been successfully set up with VirtioBlkInit().

Parameters
[in,out]DevThe device to clean up.

Definition at line 1013 of file VirtioBlk.c.

◆ VirtioBlkWriteBlocks()

EFI_STATUS EFIAPI VirtioBlkWriteBlocks ( IN EFI_BLOCK_IO_PROTOCOL This,
IN UINT32  MediaId,
IN EFI_LBA  Lba,
IN UINTN  BufferSize,
IN VOID *  Buffer 
)

WriteBlocks() operation for virtio-blk.

See

  • UEFI Spec 2.3.1 + Errata C, 12.8 EFI Block I/O Protocol, 12.8 EFI Block I/O Protocol, EFI_BLOCK_IO_PROTOCOL.WriteBlocks().
  • Driver Writer's Guide for UEFI 2.3.1 v1.01, 24.2.3 WriteBlocks() and WriteBlockEx() Implementation.

Parameter checks and conformant return values are implemented in VerifyReadWriteRequest() and SynchronousRequest().

A zero BufferSize doesn't seem to be prohibited, so do nothing in that case, successfully.

Definition at line 543 of file VirtioBlk.c.

Variable Documentation

◆ gComponentName

Initial value:
= {
&VirtioBlkGetDriverName,
&VirtioBlkGetDeviceName,
"eng"
}

Definition at line 1284 of file VirtioBlk.c.

◆ gComponentName2

Initial value:
= {
(EFI_COMPONENT_NAME2_GET_DRIVER_NAME)&VirtioBlkGetDriverName,
(EFI_COMPONENT_NAME2_GET_CONTROLLER_NAME)&VirtioBlkGetDeviceName,
"en"
}
EFI_STATUS(EFIAPI * EFI_COMPONENT_NAME2_GET_DRIVER_NAME)(IN EFI_COMPONENT_NAME2_PROTOCOL *This, IN CHAR8 *Language, OUT CHAR16 **DriverName)
EFI_STATUS(EFIAPI * EFI_COMPONENT_NAME2_GET_CONTROLLER_NAME)(IN EFI_COMPONENT_NAME2_PROTOCOL *This, IN EFI_HANDLE ControllerHandle, IN EFI_HANDLE ChildHandle OPTIONAL, IN CHAR8 *Language, OUT CHAR16 **ControllerName)

Definition at line 1324 of file VirtioBlk.c.

◆ gDriverBinding

Initial value:
= {
0x10,
NULL,
}
#define NULL
Definition: Base.h:319
EFI_STATUS EFIAPI VirtioBlkDriverBindingStop(IN EFI_DRIVER_BINDING_PROTOCOL *This, IN EFI_HANDLE DeviceHandle, IN UINTN NumberOfChildren, IN EFI_HANDLE *ChildHandleBuffer)
Definition: VirtioBlk.c:1197
EFI_STATUS EFIAPI VirtioBlkDriverBindingSupported(IN EFI_DRIVER_BINDING_PROTOCOL *This, IN EFI_HANDLE DeviceHandle, IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath)
Definition: VirtioBlk.c:652
EFI_STATUS EFIAPI VirtioBlkDriverBindingStart(IN EFI_DRIVER_BINDING_PROTOCOL *This, IN EFI_HANDLE DeviceHandle, IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath)
Definition: VirtioBlk.c:1092

Definition at line 1255 of file VirtioBlk.c.

◆ mDriverNameTable

STATIC EFI_UNICODE_STRING_TABLE mDriverNameTable[]
Initial value:
= {
{ "eng;en", L"Virtio Block Driver" },
{ NULL, NULL }
}

Definition at line 1278 of file VirtioBlk.c.