OvmfPkg: Make the VirtIo devices use the new VIRTIO_DEVICE_PROTOCOL

This change replaces the accesses to the PCI bus from the Block, Scsi and Net drivers by
the use of the new VIRTIO_DEVICE_PROTOCOL protocol that abstracts the transport layer.
It means these drivers can be used on PCI and MMIO transport layer.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Olivier Martin <olivier.martin@arm.com>

v5:
- VirtioFlush(): update comment block in VirtioLib.[hc]; error code is
  propagated from VirtIo->SetQueueNotify().
- VirtioBlkInit(): jump to Failed label if SetPageSize() fails
- VirtioBlkInit(): fixup comment, and add error handling, near
  SetQueueNum() call
- VirtioBlkDriverBindingStart(): remove redundant (always false) check for
  a subsystem device ID different from VIRTIO_SUBSYSTEM_BLOCK_DEVICE;
  VirtioBlkDriverBindingSupported() handles it already
- VirtioNetGetFeatures(): update stale comment block
- VirtioNetGetFeatures(): retrieve MAC address byte for byte (open-coded
  loop)
- VirtioNetDriverBindingStart(): remove redundant (always false) check for
  a subsystem device ID different from VIRTIO_SUBSYSTEM_NETWORK_CARD;
  VirtioNetDriverBindingSupported() handles it already
- VirtioNetInitRing(): call SetQueueNum() and SetQueueAlign() for proper
  MMIO operation
- VirtioNetInitialize(): fix destination error label for when
  SetPageSize() fails
- VirtioScsi.c: fix comment block of VIRTIO_CFG_WRITE()/VIRTIO_CFG_READ()
- VirtioScsiInit(): fix destination error label for when SetPageSize()
  fails
- VirtioScsiInit(): call SetQueueNum() and SetQueueAlign() for proper MMIO
  operation

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@14966 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
Olivier Martin
2013-12-11 16:58:22 +00:00
committed by jljusten
parent 6fb4e772a0
commit 56f65ed838
27 changed files with 388 additions and 532 deletions

View File

@@ -3,6 +3,7 @@
Utility functions used by virtio device drivers.
Copyright (C) 2012, Red Hat, Inc.
Portion of Copyright (C) 2013, ARM Ltd.
This program and the accompanying materials are licensed and made available
under the terms and conditions of the BSD License which accompanies this
@@ -14,7 +15,6 @@
**/
#include <IndustryStandard/Pci22.h>
#include <Library/BaseLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/DebugLib.h>
@@ -26,12 +26,12 @@
/**
Write a word into Region 0 of the device specified by PciIo.
Write a word into Region 0 of the device specified by VirtIo.
Region 0 must be an iomem region. This is an internal function for the
driver-specific VIRTIO_CFG_WRITE() macros.
@param[in] PciIo Target PCI device.
@param[in] VirtIo Target VirtIo device.
@param[in] FieldOffset Destination offset.
@@ -41,63 +41,30 @@
The least significant FieldSize bytes will be used.
@return Status code returned by PciIo->Io.Write().
@return Status code returned by VirtIo->Io.Write().
**/
EFI_STATUS
EFIAPI
VirtioWrite (
IN EFI_PCI_IO_PROTOCOL *PciIo,
IN UINTN FieldOffset,
IN UINTN FieldSize,
IN UINT64 Value
VirtioWriteDevice (
IN VIRTIO_DEVICE_PROTOCOL *VirtIo,
IN UINTN FieldOffset,
IN UINTN FieldSize,
IN UINT64 Value
)
{
UINTN Count;
EFI_PCI_IO_PROTOCOL_WIDTH Width;
Count = 1;
switch (FieldSize) {
case 1:
Width = EfiPciIoWidthUint8;
break;
case 2:
Width = EfiPciIoWidthUint16;
break;
case 8:
Count = 2;
// fall through
case 4:
Width = EfiPciIoWidthUint32;
break;
default:
ASSERT (FALSE);
return EFI_INVALID_PARAMETER;
}
return PciIo->Io.Write (
PciIo,
Width,
PCI_BAR_IDX0,
FieldOffset,
Count,
&Value
);
return VirtIo->WriteDevice (VirtIo, FieldOffset, FieldSize, Value);
}
/**
Read a word from Region 0 of the device specified by PciIo.
Read a word from Region 0 of the device specified by VirtIo.
Region 0 must be an iomem region. This is an internal function for the
driver-specific VIRTIO_CFG_READ() macros.
@param[in] PciIo Source PCI device.
@param[in] VirtIo Source VirtIo device.
@param[in] FieldOffset Source offset.
@@ -109,55 +76,20 @@ VirtioWrite (
@param[out] Buffer Target buffer.
@return Status code returned by PciIo->Io.Read().
@return Status code returned by VirtIo->Io.Read().
**/
EFI_STATUS
EFIAPI
VirtioRead (
IN EFI_PCI_IO_PROTOCOL *PciIo,
IN UINTN FieldOffset,
IN UINTN FieldSize,
IN UINTN BufferSize,
OUT VOID *Buffer
VirtioReadDevice (
IN VIRTIO_DEVICE_PROTOCOL *VirtIo,
IN UINTN FieldOffset,
IN UINTN FieldSize,
IN UINTN BufferSize,
OUT VOID *Buffer
)
{
UINTN Count;
EFI_PCI_IO_PROTOCOL_WIDTH Width;
ASSERT (FieldSize == BufferSize);
Count = 1;
switch (FieldSize) {
case 1:
Width = EfiPciIoWidthUint8;
break;
case 2:
Width = EfiPciIoWidthUint16;
break;
case 8:
Count = 2;
// fall through
case 4:
Width = EfiPciIoWidthUint32;
break;
default:
ASSERT (FALSE);
return EFI_INVALID_PARAMETER;
}
return PciIo->Io.Read (
PciIo,
Width,
PCI_BAR_IDX0,
FieldOffset,
Count,
Buffer
);
return VirtIo->ReadDevice (VirtIo, FieldOffset, FieldSize, BufferSize, Buffer);
}
@@ -376,7 +308,7 @@ VirtioAppendDesc (
Notify the host about the descriptor chain just built, and wait until the
host processes it.
@param[in] PciIo The target virtio PCI device to notify.
@param[in] VirtIo The target virtio device to notify.
@param[in] VirtQueueId Identifies the queue for the target device.
@@ -387,7 +319,7 @@ VirtioAppendDesc (
of the descriptor chain.
@return Error code from VirtioWrite() if it fails.
@return Error code from VirtIo->SetQueueNotify() if it fails.
@retval EFI_SUCCESS Otherwise, the host processed all descriptors.
@@ -395,10 +327,10 @@ VirtioAppendDesc (
EFI_STATUS
EFIAPI
VirtioFlush (
IN EFI_PCI_IO_PROTOCOL *PciIo,
IN UINT16 VirtQueueId,
IN OUT VRING *Ring,
IN DESC_INDICES *Indices
IN VIRTIO_DEVICE_PROTOCOL *VirtIo,
IN UINT16 VirtQueueId,
IN OUT VRING *Ring,
IN DESC_INDICES *Indices
)
{
UINT16 NextAvailIdx;
@@ -427,12 +359,7 @@ VirtioFlush (
// OK.
//
MemoryFence();
Status = VirtioWrite (
PciIo,
OFFSET_OF (VIRTIO_HDR, VhdrQueueNotify),
sizeof (UINT16),
VirtQueueId
);
Status = VirtIo->SetQueueNotify (VirtIo, VirtQueueId);
if (EFI_ERROR (Status)) {
return Status;
}