OvmfPkg: VIRTIO_DEVICE_PROTOCOL: pass VRING object to SetQueueAddress()

In virtio-1.0, it is not enough to pass the base address of the virtio
queue to the hypervisor (as a frame number); instead it will want the
addresses of the descriptor table, the available ring, and the used ring
separately. Pass the VRING object to the SetQueueAddress() member
function; this will enable a virtio-1.0 implementation. Convert the
current producers and consumers to this prototype.

Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Tested-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Reviewed-by: Jordan Justen <jordan.l.justen@intel.com>
This commit is contained in:
Laszlo Ersek 2016-03-12 03:39:00 +01:00
parent 235be6a0f1
commit 07af4eee93
9 changed files with 21 additions and 24 deletions

View File

@ -19,6 +19,8 @@
#ifndef __VIRTIO_DEVICE_H__
#define __VIRTIO_DEVICE_H__
#include <IndustryStandard/Virtio.h>
// VirtIo Specification Revision: Major[31:24].Minor[23:16].Revision[15:0
#define VIRTIO_SPEC_REVISION(major,minor,revision) \
((((major) & 0xFF) << 24) | (((minor) & 0xFF) << 16) | ((revision) & 0xFFFF))
@ -127,14 +129,12 @@ EFI_STATUS
);
/**
Write the queue address field in the Virtio Header.
The parameter Address must be the base address of the virtqueue divided
by 4096.
Write the queue address field(s) in the Virtio Header.
@param[in] This This instance of VIRTIO_DEVICE_PROTOCOL
@param[in] Address The 32-bit Queue Address field
@param[in] Ring The initialized VRING object to take the
addresses from.
@retval EFI_SUCCESS The data was written successfully.
@retval EFI_UNSUPPORTED The underlying IO device doesn't support the
@ -144,7 +144,7 @@ typedef
EFI_STATUS
(EFIAPI *VIRTIO_SET_QUEUE_ADDRESS) (
IN VIRTIO_DEVICE_PROTOCOL *This,
IN UINT32 Address
IN VRING *Ring
);
/**

View File

@ -112,8 +112,8 @@ VirtioMmioSetQueueSel (
EFI_STATUS
VirtioMmioSetQueueAddress (
VIRTIO_DEVICE_PROTOCOL *This,
UINT32 Address
IN VIRTIO_DEVICE_PROTOCOL *This,
IN VRING *Ring
);
EFI_STATUS

View File

@ -180,15 +180,16 @@ VirtioMmioSetQueueSel (
EFI_STATUS
VirtioMmioSetQueueAddress (
VIRTIO_DEVICE_PROTOCOL *This,
UINT32 Address
IN VIRTIO_DEVICE_PROTOCOL *This,
IN VRING *Ring
)
{
VIRTIO_MMIO_DEVICE *Device;
Device = VIRTIO_MMIO_DEVICE_FROM_VIRTIO_DEVICE (This);
VIRTIO_CFG_WRITE (Device, VIRTIO_MMIO_OFFSET_QUEUE_PFN, Address);
VIRTIO_CFG_WRITE (Device, VIRTIO_MMIO_OFFSET_QUEUE_PFN,
(UINT32)((UINTN)Ring->Base >> EFI_PAGE_SHIFT));
return EFI_SUCCESS;
}

View File

@ -730,8 +730,7 @@ VirtioBlkInit (
//
// step 4c -- Report GPFN (guest-physical frame number) of queue.
//
Status = Dev->VirtIo->SetQueueAddress (Dev->VirtIo,
(UINT32) ((UINTN) Dev->Ring.Base >> EFI_PAGE_SHIFT));
Status = Dev->VirtIo->SetQueueAddress (Dev->VirtIo, &Dev->Ring);
if (EFI_ERROR (Status)) {
goto ReleaseQueue;
}

View File

@ -95,8 +95,7 @@ VirtioNetInitRing (
//
// step 4c -- report GPFN (guest-physical frame number) of queue
//
Status = Dev->VirtIo->SetQueueAddress (Dev->VirtIo,
(UINT32) ((UINTN) Ring->Base >> EFI_PAGE_SHIFT));
Status = Dev->VirtIo->SetQueueAddress (Dev->VirtIo, Ring);
if (EFI_ERROR (Status)) {
goto ReleaseQueue;
}

View File

@ -124,8 +124,8 @@ VirtioPciSetGuestFeatures (
EFI_STATUS
EFIAPI
VirtioPciSetQueueAddress (
VIRTIO_DEVICE_PROTOCOL *This,
UINT32 Address
IN VIRTIO_DEVICE_PROTOCOL *This,
IN VRING *Ring
);
EFI_STATUS

View File

@ -181,8 +181,8 @@ VirtioPciSetGuestFeatures (
EFI_STATUS
EFIAPI
VirtioPciSetQueueAddress (
VIRTIO_DEVICE_PROTOCOL *This,
UINT32 Address
IN VIRTIO_DEVICE_PROTOCOL *This,
IN VRING *Ring
)
{
VIRTIO_PCI_DEVICE *Dev;
@ -190,7 +190,7 @@ VirtioPciSetQueueAddress (
Dev = VIRTIO_PCI_DEVICE_FROM_VIRTIO_DEVICE (This);
return VirtioPciIoWrite (Dev, VIRTIO_PCI_OFFSET_QUEUE_ADDRESS, sizeof (UINT32),
Address);
(UINT32)((UINTN)Ring->Base >> EFI_PAGE_SHIFT));
}
EFI_STATUS

View File

@ -284,8 +284,7 @@ VirtioRngInit (
//
// step 4c -- Report GPFN (guest-physical frame number) of queue.
//
Status = Dev->VirtIo->SetQueueAddress (Dev->VirtIo,
(UINT32) ((UINTN) Dev->Ring.Base >> EFI_PAGE_SHIFT));
Status = Dev->VirtIo->SetQueueAddress (Dev->VirtIo, &Dev->Ring);
if (EFI_ERROR (Status)) {
goto ReleaseQueue;
}

View File

@ -841,8 +841,7 @@ VirtioScsiInit (
//
// step 4c -- Report GPFN (guest-physical frame number) of queue.
//
Status = Dev->VirtIo->SetQueueAddress (Dev->VirtIo,
(UINT32) ((UINTN) Dev->Ring.Base >> EFI_PAGE_SHIFT));
Status = Dev->VirtIo->SetQueueAddress (Dev->VirtIo, &Dev->Ring);
if (EFI_ERROR (Status)) {
goto ReleaseQueue;
}