Patches 1-5 & 8 are committed as r14963-14968. Olivier, can you review and commit Laszlo's patches 6 & 7 from v5?
Thanks, -Jordan On Wed, Nov 27, 2013 at 11:10 AM, Laszlo Ersek <ler...@redhat.com> wrote: > Testing: > > - OvmfPkg, X64: > - VirtioNetDxe: > - PXE boot on libvirt's virtual network > - DataSource socket utility from AppPkg (guest to host) > - VirtioBlkDxe: booted > - Fedora 19 > - Windows 2012 R2 > - Windows 2008 R2 (SeaBIOS CSM build of OVMF) > - VirtioScsiDxe: booted > - RHEL-6 > > - ArmVExpress-RTSM-AEMv8Ax4-foundation, Aarch64 Foundation model: > - VirtioBlkDxe: booted > - Linaro OpenEmbedded 13.10 image (semihosting + virtio-blk) > - Linaro OpenEmbedded 13.10 image (virtio-blk only) > - Fedora 19 image (with EFI stub, virtio-blk only) > > Notes: > - Kept Olivier's C-u and S-o-b in the first place everywhere. > - When I touched a patch, I added my changes below Olivier's S-o-b, and > added my own C-u and S-o-b too. > - When I didn't touch a patch, and Jordan was explicitly OK with it (as > in, R-b), I added his R-b. > > Summary list of changes in v5 (in the order visible in the squashed diff > below; patches contain broken out v4->v5 lists): > > - VirtioMmioDeviceLib.inf: drop UefiDriverEntryPoint library dependency > - VirtioFlush(): update comment block in VirtioLib.[hc]; error code is > propagated from VirtIo->SetQueueNotify(). > - typo fix in VirtioMmioInstallDevice() comment block > - add disclaimer (two instances) about the protocol being work in > progress > - ensure / document that the VIRTIO_BLK_DEVICE_PATH structure must be > packed > - fix whitespace damage in definition of "mVirtioBlockDevicePath" > - plug MmioDevice leak in VirtioMmioUninstallDevice() > - return EFI_INVALID_PARAMETER in VirtioMmioGetQueueAddress() if > QueueAddress is NULL > - VirtioMmioSetQueueSize(): fix return value (it's a status code) > - VirtioMmioSetPageSize(): check against EFI_PAGE_SIZE with "if" plus > EFI_UNSUPPORTED, rather than ASSERT() > - VirtioMmioDeviceWrite(), VirtioMmioDeviceRead(): remove redundant > (FieldSize > 8) checks > - 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 > - VirtioPciIoRead(): restore the original requirement that FieldSize > equal BufferSize exactly (not only divide it). The looping added in v4 > did not match the comment block, and the only place that used it in v4 > (ie. VirtioNetGetFeatures()) needs an open-coded loop anyway (will be > done in a later part of v5). > - updated comment block on VirtioPciDeviceRead() > - return EFI_UNSUPPORTED instead of failed ASSERT() in > VirtioPciSetPageSize() > - 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 > > Changes not visible in the squashed diff (because the end result is the > same in both v4 and v5): > > - ArmPlatformPkg/ArmVExpressPkg: Added the empty 'ArmFvpDxe' platform > UEFI driver: > - For uniformity, add the empty driver to > ArmVExpress-RTSM-AEMv8Ax4-foundation.* too in this patch, not just > ArmVExpress-RTSM-AEMv8Ax4.*. V4 added the empty driver to > ArmVExpress-RTSM-AEMv8Ax4-foundation.* not sooner than the next > patch, fusing it with other (= virtio) functionality. Let's split > these changes cleanly. > > - ArmPlatformPkg/ArmFvpDxe: Added Virtio Block support: > - the platform driver is added to all platform DSC and FDF files in > the previous patch; this patch focuses on virtio only > > Squashed diff between v4 and v5 (17 lines of context for readability): > >> diff --git a/OvmfPkg/Library/VirtioMmioDeviceLib/VirtioMmioDeviceLib.inf >> b/OvmfPkg/Library/VirtioMmioDeviceLib/VirtioMmioDeviceLib.inf >> index 126afec..2e266a9 100644 >> --- a/OvmfPkg/Library/VirtioMmioDeviceLib/VirtioMmioDeviceLib.inf >> +++ b/OvmfPkg/Library/VirtioMmioDeviceLib/VirtioMmioDeviceLib.inf >> @@ -22,22 +22,21 @@ >> VERSION_STRING = 1.0 >> LIBRARY_CLASS = VirtioMmioDeviceLib >> >> [Sources] >> VirtioMmioDevice.c >> VirtioMmioDeviceFunctions.c >> >> [Packages] >> MdePkg/MdePkg.dec >> OvmfPkg/OvmfPkg.dec >> >> [LibraryClasses] >> BaseMemoryLib >> DebugLib >> IoLib >> MemoryAllocationLib >> UefiBootServicesTableLib >> - UefiDriverEntryPoint >> UefiLib >> >> [Protocols] >> gVirtioDeviceProtocolGuid ## PRODUCES >> diff --git a/OvmfPkg/Include/Library/VirtioLib.h >> b/OvmfPkg/Include/Library/VirtioLib.h >> index df4fc62..36527a5 100644 >> --- a/OvmfPkg/Include/Library/VirtioLib.h >> +++ b/OvmfPkg/Include/Library/VirtioLib.h >> @@ -154,32 +154,32 @@ VirtioAppendDesc ( >> >> /** >> >> Notify the host about the descriptor chain just built, and wait until the >> host processes it. >> >> @param[in] VirtIo The target virtio device to notify. >> >> @param[in] VirtQueueId Identifies the queue for the target device. >> >> @param[in,out] Ring The virtio ring with descriptors to submit. >> >> @param[in] Indices Indices->NextDescIdx is not accessed. >> Indices->HeadDescIdx identifies the head >> descriptor >> of the descriptor chain. >> >> >> - @return Error code from VirtioWriteDevice() if it fails. >> + @return Error code from VirtIo->SetQueueNotify() if it fails. >> >> @retval EFI_SUCCESS Otherwise, the host processed all descriptors. >> >> **/ >> EFI_STATUS >> EFIAPI >> VirtioFlush ( >> IN VIRTIO_DEVICE_PROTOCOL *VirtIo, >> IN UINT16 VirtQueueId, >> IN OUT VRING *Ring, >> IN DESC_INDICES *Indices >> ); >> >> #endif // _VIRTIO_LIB_H_ >> diff --git a/OvmfPkg/Include/Library/VirtioMmioDeviceLib.h >> b/OvmfPkg/Include/Library/VirtioMmioDeviceLib.h >> index ac71014..3f63a65 100644 >> --- a/OvmfPkg/Include/Library/VirtioMmioDeviceLib.h >> +++ b/OvmfPkg/Include/Library/VirtioMmioDeviceLib.h >> @@ -9,40 +9,41 @@ >> distribution. The full text of the license may be found at >> http://opensource.org/licenses/bsd-license.php >> >> THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, >> WITHOUT >> WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. >> >> **/ >> >> #ifndef _VIRTIO_MMIO_DEVICE_LIB_H_ >> #define _VIRTIO_MMIO_DEVICE_LIB_H_ >> >> /** >> >> Initialize VirtIo Device and Install VIRTIO_DEVICE_PROTOCOL protocol >> >> @param[in] BaseAddress Base Address of the VirtIo MMIO Device >> >> - @param[in] Handle Handle of the device the driver should be >> attached to. >> + @param[in] Handle Handle of the device the driver should be attached >> + to. >> >> @retval EFI_SUCCESS The VirtIo Device has been installed >> successfully. >> >> - @retval EFI_OUT_OF_RESOURCES The function failed too allocate memory >> require >> + @retval EFI_OUT_OF_RESOURCES The function failed to allocate memory >> required >> by the Virtio MMIO device initialization. >> >> @retval EFI_UNSUPPORTED BaseAddress does not point to a VirtIo MMIO >> device. >> >> @return Status code returned by >> InstallProtocolInterface >> Boot Service function. >> >> **/ >> EFI_STATUS >> VirtioMmioInstallDevice ( >> IN PHYSICAL_ADDRESS BaseAddress, >> IN EFI_HANDLE Handle >> ); >> >> /** >> >> diff --git a/OvmfPkg/Include/Protocol/VirtioDevice.h >> b/OvmfPkg/Include/Protocol/VirtioDevice.h >> index 71541f8..a6bb516 100644 >> --- a/OvmfPkg/Include/Protocol/VirtioDevice.h >> +++ b/OvmfPkg/Include/Protocol/VirtioDevice.h >> @@ -1,22 +1,25 @@ >> /** @file >> Virtio Device >> >> Copyright (c) 2013, ARM Ltd. All rights reserved.<BR> >> >> + DISCLAIMER: the VIRTIO_DEVICE_PROTOCOL introduced here is a work in >> progress, >> + and should not be used outside of the EDK II tree. >> + >> This program and the accompanying materials are licensed and made >> available >> under the terms and conditions of the BSD License which accompanies this >> distribution. The full text of the license may be found at >> http://opensource.org/licenses/bsd-license.php >> >> THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, >> WITHOUT >> WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. >> >> **/ >> >> #ifndef __VIRTIO_DEVICE_H__ >> #define __VIRTIO_DEVICE_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)) >> >> @@ -327,34 +330,37 @@ EFI_STATUS >> @param[in] DeviceStatus The 8-bit value for the Device status field >> >> @retval EFI_SUCCESS The data was written successfully. >> @retval EFI_UNSUPPORTED The underlying IO device doesn't support the >> provided address offset and write size. >> **/ >> typedef >> EFI_STATUS >> (EFIAPI *VIRTIO_SET_DEVICE_STATUS) ( >> IN VIRTIO_DEVICE_PROTOCOL *This, >> IN UINT8 DeviceStatus >> ); >> >> >> /// >> /// This protocol provides an abstraction over the VirtIo transport layer >> /// >> +/// DISCLAIMER: this protocol is a work in progress, and should not be used >> +/// outside of the EDK II tree. >> +/// >> struct _VIRTIO_DEVICE_PROTOCOL { >> /// VirtIo Specification Revision encoded with VIRTIO_SPEC_REVISION() >> UINT32 Revision; >> /// From the Virtio Spec >> INT32 SubSystemDeviceId; >> >> VIRTIO_GET_DEVICE_FEATURES GetDeviceFeatures; >> VIRTIO_SET_GUEST_FEATURES SetGuestFeatures; >> >> VIRTIO_GET_QUEUE_ADDRESS GetQueueAddress; >> VIRTIO_SET_QUEUE_ADDRESS SetQueueAddress; >> >> VIRTIO_SET_QUEUE_SEL SetQueueSel; >> >> VIRTIO_SET_QUEUE_NOTIFY SetQueueNotify; >> >> VIRTIO_SET_QUEUE_ALIGN SetQueueAlign; >> diff --git a/ArmPlatformPkg/ArmVExpressPkg/ArmFvpDxe/ArmFvpDxe.c >> b/ArmPlatformPkg/ArmVExpressPkg/ArmFvpDxe/ArmFvpDxe.c >> index 0cf5b7b..1885b69 100644 >> --- a/ArmPlatformPkg/ArmVExpressPkg/ArmFvpDxe/ArmFvpDxe.c >> +++ b/ArmPlatformPkg/ArmVExpressPkg/ArmFvpDxe/ArmFvpDxe.c >> @@ -5,56 +5,58 @@ >> This program and the accompanying materials >> are licensed and made available under the terms and conditions of the BSD >> License >> which accompanies this distribution. The full text of the license may be >> found at >> http://opensource.org/licenses/bsd-license.php >> >> THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, >> WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR >> IMPLIED. >> >> **/ >> >> #include <Library/UefiLib.h> >> #include <Library/VirtioMmioDeviceLib.h> >> #include <Library/DebugLib.h> >> #include <Library/UefiBootServicesTableLib.h> >> >> #define ARM_FVP_BASE_VIRTIO_BLOCK_BASE 0x1c130000 >> >> +#pragma pack(1) >> typedef struct { >> VENDOR_DEVICE_PATH Vendor; >> EFI_DEVICE_PATH_PROTOCOL End; >> } VIRTIO_BLK_DEVICE_PATH; >> +#pragma pack() >> >> VIRTIO_BLK_DEVICE_PATH mVirtioBlockDevicePath = >> { >> { >> { >> HARDWARE_DEVICE_PATH, >> HW_VENDOR_DP, >> { >> (UINT8)( sizeof(VENDOR_DEVICE_PATH) ), >> (UINT8)((sizeof(VENDOR_DEVICE_PATH)) >> 8) >> } >> }, >> EFI_CALLER_ID_GUID, >> }, >> { >> END_DEVICE_PATH_TYPE, >> END_ENTIRE_DEVICE_PATH_SUBTYPE, >> - { >> + { >> sizeof (EFI_DEVICE_PATH_PROTOCOL), >> 0 >> } >> } >> }; >> >> EFI_STATUS >> EFIAPI >> ArmFvpInitialise ( >> IN EFI_HANDLE ImageHandle, >> IN EFI_SYSTEM_TABLE *SystemTable >> ) >> { >> EFI_STATUS Status; >> >> Status = gBS->InstallProtocolInterface (&ImageHandle, >> &gEfiDevicePathProtocolGuid, EFI_NATIVE_INTERFACE, >> diff --git a/OvmfPkg/Library/VirtioLib/VirtioLib.c >> b/OvmfPkg/Library/VirtioLib/VirtioLib.c >> index 9bbd141..54cf225 100644 >> --- a/OvmfPkg/Library/VirtioLib/VirtioLib.c >> +++ b/OvmfPkg/Library/VirtioLib/VirtioLib.c >> @@ -236,35 +236,35 @@ VirtioAppendDesc ( >> >> /** >> >> Notify the host about the descriptor chain just built, and wait until the >> host processes it. >> >> @param[in] VirtIo The target virtio device to notify. >> >> @param[in] VirtQueueId Identifies the queue for the target device. >> >> @param[in,out] Ring The virtio ring with descriptors to submit. >> >> @param[in] Indices Indices->NextDescIdx is not accessed. >> Indices->HeadDescIdx identifies the head >> descriptor >> of the descriptor chain. >> >> >> - @return Error code from VirtioWriteDevice() if it fails. >> + @return Error code from VirtIo->SetQueueNotify() if it fails. >> >> @retval EFI_SUCCESS Otherwise, the host processed all descriptors. >> >> **/ >> EFI_STATUS >> EFIAPI >> VirtioFlush ( >> IN VIRTIO_DEVICE_PROTOCOL *VirtIo, >> IN UINT16 VirtQueueId, >> IN OUT VRING *Ring, >> IN DESC_INDICES *Indices >> ) >> { >> UINT16 NextAvailIdx; >> EFI_STATUS Status; >> UINTN PollPeriodUsecs; >> >> diff --git a/OvmfPkg/Library/VirtioMmioDeviceLib/VirtioMmioDevice.c >> b/OvmfPkg/Library/VirtioMmioDeviceLib/VirtioMmioDevice.c >> index 4d8578e..7543e15 100644 >> --- a/OvmfPkg/Library/VirtioMmioDeviceLib/VirtioMmioDevice.c >> +++ b/OvmfPkg/Library/VirtioMmioDeviceLib/VirtioMmioDevice.c >> @@ -185,20 +185,21 @@ VirtioMmioUninstallDevice ( >> if (EFI_ERROR (Status)) { >> return Status; >> } >> >> // Get the MMIO device from the VirtIo Device instance >> MmioDevice = VIRTIO_MMIO_DEVICE_FROM_VIRTIO_DEVICE (VirtioDevice); >> >> // Uninstall the protocol interface >> Status = gBS->UninstallProtocolInterface (DeviceHandle, >> &gVirtioDeviceProtocolGuid, &MmioDevice->VirtioDevice >> ); >> if (EFI_ERROR (Status)) { >> return Status; >> } >> >> // Uninitialize the VirtIo Device >> VirtioMmioUninit (MmioDevice); >> + FreePool (MmioDevice); >> >> return EFI_SUCCESS; >> } >> diff --git a/OvmfPkg/Library/VirtioMmioDeviceLib/VirtioMmioDeviceFunctions.c >> b/OvmfPkg/Library/VirtioMmioDeviceLib/VirtioMmioDeviceFunctions.c >> index bcba062..068e1ed 100644 >> --- a/OvmfPkg/Library/VirtioMmioDeviceLib/VirtioMmioDeviceFunctions.c >> +++ b/OvmfPkg/Library/VirtioMmioDeviceLib/VirtioMmioDeviceFunctions.c >> @@ -34,35 +34,35 @@ VirtioMmioGetDeviceFeatures ( >> Device = VIRTIO_MMIO_DEVICE_FROM_VIRTIO_DEVICE (This); >> >> *DeviceFeatures = VIRTIO_CFG_READ (Device, >> VIRTIO_MMIO_OFFSET_HOST_FEATURES); >> >> return EFI_SUCCESS; >> } >> >> EFI_STATUS >> EFIAPI >> VirtioMmioGetQueueAddress ( >> IN VIRTIO_DEVICE_PROTOCOL *This, >> OUT UINT32 *QueueAddress >> ) >> { >> VIRTIO_MMIO_DEVICE *Device; >> >> if (QueueAddress == NULL) { >> - >> + return EFI_INVALID_PARAMETER; >> } >> >> Device = VIRTIO_MMIO_DEVICE_FROM_VIRTIO_DEVICE (This); >> >> *QueueAddress = VIRTIO_CFG_READ (Device, VIRTIO_MMIO_OFFSET_QUEUE_PFN); >> >> return EFI_SUCCESS; >> } >> >> EFI_STATUS >> EFIAPI >> VirtioMmioGetQueueSize ( >> IN VIRTIO_DEVICE_PROTOCOL *This, >> OUT UINT16 *QueueNumMax >> ) >> { >> VIRTIO_MMIO_DEVICE *Device; >> @@ -95,35 +95,37 @@ VirtioMmioGetDeviceStatus ( >> >> *DeviceStatus = VIRTIO_CFG_READ (Device, VIRTIO_MMIO_OFFSET_STATUS) & >> 0xFF; >> >> return EFI_SUCCESS; >> } >> >> EFI_STATUS >> EFIAPI >> VirtioMmioSetQueueSize ( >> VIRTIO_DEVICE_PROTOCOL *This, >> UINT16 QueueSize >> ) >> { >> VIRTIO_MMIO_DEVICE *Device; >> >> Device = VIRTIO_MMIO_DEVICE_FROM_VIRTIO_DEVICE (This); >> >> - return VIRTIO_CFG_WRITE (Device, VIRTIO_MMIO_OFFSET_QUEUE_NUM, QueueSize); >> + VIRTIO_CFG_WRITE (Device, VIRTIO_MMIO_OFFSET_QUEUE_NUM, QueueSize); >> + >> + return EFI_SUCCESS; >> } >> >> EFI_STATUS >> EFIAPI >> VirtioMmioSetDeviceStatus ( >> VIRTIO_DEVICE_PROTOCOL *This, >> UINT8 DeviceStatus >> ) >> { >> VIRTIO_MMIO_DEVICE *Device; >> >> Device = VIRTIO_MMIO_DEVICE_FROM_VIRTIO_DEVICE (This); >> >> VIRTIO_CFG_WRITE (Device, VIRTIO_MMIO_OFFSET_STATUS, DeviceStatus); >> >> return EFI_SUCCESS; >> } >> @@ -155,35 +157,37 @@ VirtioMmioSetQueueAlignment ( >> >> Device = VIRTIO_MMIO_DEVICE_FROM_VIRTIO_DEVICE (This); >> >> VIRTIO_CFG_WRITE (Device, VIRTIO_MMIO_OFFSET_QUEUE_ALIGN, Alignment); >> >> return EFI_SUCCESS; >> } >> >> EFI_STATUS >> EFIAPI >> VirtioMmioSetPageSize ( >> VIRTIO_DEVICE_PROTOCOL *This, >> UINT32 PageSize >> ) >> { >> VIRTIO_MMIO_DEVICE *Device; >> >> - ASSERT (PageSize == EFI_PAGE_SIZE); >> + if (PageSize != EFI_PAGE_SIZE) { >> + return EFI_UNSUPPORTED; >> + } >> >> Device = VIRTIO_MMIO_DEVICE_FROM_VIRTIO_DEVICE (This); >> >> VIRTIO_CFG_WRITE (Device, VIRTIO_MMIO_OFFSET_GUEST_PAGE_SIZE, PageSize); >> >> return EFI_SUCCESS; >> } >> >> EFI_STATUS >> EFIAPI >> VirtioMmioSetQueueSel ( >> VIRTIO_DEVICE_PROTOCOL *This, >> UINT16 Sel >> ) >> { >> VIRTIO_MMIO_DEVICE *Device; >> >> @@ -226,38 +230,34 @@ VirtioMmioSetGuestFeatures ( >> } >> >> EFI_STATUS >> EFIAPI >> VirtioMmioDeviceWrite ( >> IN VIRTIO_DEVICE_PROTOCOL *This, >> IN UINTN FieldOffset, >> IN UINTN FieldSize, >> IN UINT64 Value >> ) >> { >> UINTN DstBaseAddress; >> VIRTIO_MMIO_DEVICE *Device; >> >> Device = VIRTIO_MMIO_DEVICE_FROM_VIRTIO_DEVICE (This); >> >> // Double-check fieldsize >> - if (FieldSize > 8) { >> - return EFI_INVALID_PARAMETER; >> - } >> - >> if ((FieldSize != 1) && (FieldSize != 2) && >> (FieldSize != 4) && (FieldSize != 8)) { >> return EFI_INVALID_PARAMETER; >> } >> >> // Compute base address >> DstBaseAddress = Device->BaseAddress + >> VIRTIO_DEVICE_SPECIFIC_CONFIGURATION_OFFSET_MMIO + FieldOffset; >> >> // >> // The device-specific memory area of Virtio-MMIO can only be written in >> // byte accesses. This is not currently in the Virtio spec. >> // >> MmioWriteBuffer8 (DstBaseAddress, FieldSize, (UINT8*)&Value); >> >> return EFI_SUCCESS; >> } >> @@ -267,38 +267,34 @@ EFIAPI >> VirtioMmioDeviceRead ( >> IN VIRTIO_DEVICE_PROTOCOL *This, >> IN UINTN FieldOffset, >> IN UINTN FieldSize, >> IN UINTN BufferSize, >> OUT VOID *Buffer >> ) >> { >> UINTN SrcBaseAddress; >> VIRTIO_MMIO_DEVICE *Device; >> >> Device = VIRTIO_MMIO_DEVICE_FROM_VIRTIO_DEVICE (This); >> >> // Parameter validation >> ASSERT (FieldSize == BufferSize); >> >> // Double-check fieldsize >> - if (FieldSize > 8) { >> - return EFI_INVALID_PARAMETER; >> - } >> - >> if ((FieldSize != 1) && (FieldSize != 2) && >> (FieldSize != 4) && (FieldSize != 8)) { >> return EFI_INVALID_PARAMETER; >> } >> >> // Compute base address >> SrcBaseAddress = Device->BaseAddress + >> VIRTIO_DEVICE_SPECIFIC_CONFIGURATION_OFFSET_MMIO + FieldOffset; >> >> // >> // The device-specific memory area of Virtio-MMIO can only be read in >> // byte reads. This is not currently in the Virtio spec. >> // >> MmioReadBuffer8 (SrcBaseAddress, BufferSize, Buffer); >> >> return EFI_SUCCESS; >> } >> diff --git a/OvmfPkg/VirtioBlkDxe/VirtioBlk.c >> b/OvmfPkg/VirtioBlkDxe/VirtioBlk.c >> index 0dcb05c..e0be7b0 100644 >> --- a/OvmfPkg/VirtioBlkDxe/VirtioBlk.c >> +++ b/OvmfPkg/VirtioBlkDxe/VirtioBlk.c >> @@ -608,35 +608,35 @@ VirtioBlkInit ( >> NextDevStat |= VSTAT_ACK; // step 2 -- acknowledge device presence >> Status = Dev->VirtIo->SetDeviceStatus (Dev->VirtIo, NextDevStat); >> if (EFI_ERROR (Status)) { >> goto Failed; >> } >> >> NextDevStat |= VSTAT_DRIVER; // step 3 -- we know how to drive it >> Status = Dev->VirtIo->SetDeviceStatus (Dev->VirtIo, NextDevStat); >> if (EFI_ERROR (Status)) { >> goto Failed; >> } >> >> // >> // Set Page Size - MMIO VirtIo Specific >> // >> Status = Dev->VirtIo->SetPageSize (Dev->VirtIo, EFI_PAGE_SIZE); >> if (EFI_ERROR (Status)) { >> - goto ReleaseQueue; >> + goto Failed; >> } >> >> // >> // step 4a -- retrieve and validate features >> // >> Status = Dev->VirtIo->GetDeviceFeatures (Dev->VirtIo, &Features); >> if (EFI_ERROR (Status)) { >> goto Failed; >> } >> >> Status = VIRTIO_CFG_READ (Dev, Capacity, &NumSectors); >> if (EFI_ERROR (Status)) { >> goto Failed; >> } >> if (NumSectors == 0) { >> Status = EFI_UNSUPPORTED; >> goto Failed; >> @@ -669,44 +669,49 @@ VirtioBlkInit ( >> goto Failed; >> } >> Status = Dev->VirtIo->GetQueueNumMax (Dev->VirtIo, &QueueSize); >> if (EFI_ERROR (Status)) { >> goto Failed; >> } >> if (QueueSize < 3) { // SynchronousRequest() uses at most three >> descriptors >> Status = EFI_UNSUPPORTED; >> goto Failed; >> } >> >> Status = VirtioRingInit (QueueSize, &Dev->Ring); >> if (EFI_ERROR (Status)) { >> goto Failed; >> } >> >> // >> - // Additional steps for MMIO: align the queue appropriately, and set the >> size >> - Dev->VirtIo->SetQueueNum (Dev->VirtIo, QueueSize); >> + // Additional steps for MMIO: align the queue appropriately, and set the >> + // size. If anything fails from here on, we must release the ring >> resources. >> + // >> + Status = Dev->VirtIo->SetQueueNum (Dev->VirtIo, QueueSize); >> + if (EFI_ERROR (Status)) { >> + goto ReleaseQueue; >> + } >> + >> Status = Dev->VirtIo->SetQueueAlign (Dev->VirtIo, EFI_PAGE_SIZE); >> if (EFI_ERROR (Status)) { >> goto ReleaseQueue; >> } >> >> // >> - // step 4c -- Report GPFN (guest-physical frame number) of queue. If >> anything >> - // fails from here on, we must release the ring resources. >> + // step 4c -- Report GPFN (guest-physical frame number) of queue. >> // >> Status = Dev->VirtIo->SetQueueAddress (Dev->VirtIo, >> (UINTN) Dev->Ring.Base >> EFI_PAGE_SHIFT); >> if (EFI_ERROR (Status)) { >> goto ReleaseQueue; >> } >> >> >> // >> // step 5 -- Report understood features. There are no virtio-blk specific >> // features to negotiate in virtio-0.9.5, plus we do not want any of the >> // device-independent (known or unknown) VIRTIO_F_* capabilities (see >> // Appendix B). >> // >> Status = Dev->VirtIo->SetGuestFeatures (Dev->VirtIo, 0); >> if (EFI_ERROR (Status)) { >> goto ReleaseQueue; >> @@ -827,38 +832,34 @@ VirtioBlkDriverBindingStart ( >> ) >> { >> VBLK_DEV *Dev; >> EFI_STATUS Status; >> >> Dev = (VBLK_DEV *) AllocateZeroPool (sizeof *Dev); >> if (Dev == NULL) { >> return EFI_OUT_OF_RESOURCES; >> } >> >> Status = gBS->OpenProtocol (DeviceHandle, &gVirtioDeviceProtocolGuid, >> (VOID **)&Dev->VirtIo, This->DriverBindingHandle, >> DeviceHandle, EFI_OPEN_PROTOCOL_BY_DRIVER); >> if (EFI_ERROR (Status)) { >> goto FreeVirtioBlk; >> } >> >> - if (Dev->VirtIo->SubSystemDeviceId != VIRTIO_SUBSYSTEM_BLOCK_DEVICE) { >> - return EFI_UNSUPPORTED; >> - } >> - >> // >> // VirtIo access granted, configure virtio-blk device. >> // >> Status = VirtioBlkInit (Dev); >> if (EFI_ERROR (Status)) { >> goto CloseVirtIo; >> } >> >> // >> // Setup complete, attempt to export the driver instance's BlockIo >> interface. >> // >> Dev->Signature = VBLK_SIG; >> Status = gBS->InstallProtocolInterface (&DeviceHandle, >> &gEfiBlockIoProtocolGuid, EFI_NATIVE_INTERFACE, >> &Dev->BlockIo); >> if (EFI_ERROR (Status)) { >> goto UninitDev; >> diff --git a/OvmfPkg/VirtioNetDxe/DriverBinding.c >> b/OvmfPkg/VirtioNetDxe/DriverBinding.c >> index 330f1f3..93995c6 100644 >> --- a/OvmfPkg/VirtioNetDxe/DriverBinding.c >> +++ b/OvmfPkg/VirtioNetDxe/DriverBinding.c >> @@ -35,51 +35,51 @@ >> >> Only VirtioNetSnpPopulate() may call this function. >> >> If the function fails for any reason, the virtio-net device is moved to >> VSTAT_FAILED instead of being reset. This serves only informative purposes >> for the host side. >> >> param[in,out] Dev The VNET_DEV structure being created for >> the virtio-net device. >> param[out] MacAddress MAC address configured by the host. >> param[out] MediaPresentSupported Link status is made available by the >> host. >> param[out] MediaPresent If link status is made available by the >> host, the current link status is stored >> in >> *MediaPresent. Otherwise MediaPresent is >> unused. >> >> @retval EFI_UNSUPPORTED The host doesn't supply a MAC address. >> - @return Status codes from >> Dev->VirtIo->Io.Read(), >> - VIRTIO_CFG_READ() and >> VIRTIO_CFG_WRITE(). >> + @return Status codes from VirtIo protocol >> members. >> @retval EFI_SUCCESS Configuration values retrieved. >> */ >> STATIC >> EFI_STATUS >> EFIAPI >> VirtioNetGetFeatures ( >> IN OUT VNET_DEV *Dev, >> OUT EFI_MAC_ADDRESS *MacAddress, >> OUT BOOLEAN *MediaPresentSupported, >> OUT BOOLEAN *MediaPresent >> ) >> { >> EFI_STATUS Status; >> UINT8 NextDevStat; >> UINT32 Features; >> + UINTN MacIdx; >> UINT16 LinkStatus; >> >> // >> // Interrogate the device for features (virtio-0.9.5, 2.2.1 Device >> // Initialization Sequence), but don't complete setting it up. >> // >> NextDevStat = 0; // step 1 -- reset device >> Status = Dev->VirtIo->SetDeviceStatus (Dev->VirtIo, NextDevStat); >> if (EFI_ERROR (Status)) { >> return Status; >> } >> >> NextDevStat |= VSTAT_ACK; // step 2 -- acknowledge device presence >> Status = Dev->VirtIo->SetDeviceStatus (Dev->VirtIo, NextDevStat); >> if (EFI_ERROR (Status)) { >> goto YieldDevice; >> } >> @@ -91,43 +91,44 @@ VirtioNetGetFeatures ( >> } >> >> // >> // step 4a -- retrieve and validate features >> // >> Status = Dev->VirtIo->GetDeviceFeatures (Dev->VirtIo, &Features); >> if (EFI_ERROR (Status)) { >> goto YieldDevice; >> } >> >> // >> // get MAC address byte-wise >> // >> if ((Features & VIRTIO_NET_F_MAC) == 0) { >> Status = EFI_UNSUPPORTED; >> goto YieldDevice; >> } >> - Status = Dev->VirtIo->ReadDevice (Dev->VirtIo, >> - OFFSET_OF_VNET (Mac), // Offset >> - sizeof(UINT8), // FieldSize >> - SIZE_OF_VNET (Mac), // BufferSize >> - MacAddress // Buffer >> - ); >> - >> - if (EFI_ERROR (Status)) { >> - goto YieldDevice; >> + for (MacIdx = 0; MacIdx < SIZE_OF_VNET (Mac); ++MacIdx) { >> + Status = Dev->VirtIo->ReadDevice (Dev->VirtIo, >> + OFFSET_OF_VNET (Mac) + MacIdx, // Offset >> + 1, // FieldSize >> + 1, // BufferSize >> + &MacAddress->Addr[MacIdx] // Buffer >> + ); >> + if (EFI_ERROR (Status)) { >> + goto YieldDevice; >> + } >> } >> >> // >> // check if link status is reported, and if so, what the link status is >> // >> if ((Features & VIRTIO_NET_F_STATUS) == 0) { >> *MediaPresentSupported = FALSE; >> } >> else { >> *MediaPresentSupported = TRUE; >> Status = VIRTIO_CFG_READ (Dev, LinkStatus, &LinkStatus); >> if (EFI_ERROR (Status)) { >> goto YieldDevice; >> } >> *MediaPresent = !!(LinkStatus & VIRTIO_NET_S_LINK_UP); >> } >> >> @@ -445,38 +446,34 @@ VirtioNetDriverBindingStart ( >> >> // >> // allocate space for the driver instance >> // >> Dev = (VNET_DEV *) AllocateZeroPool (sizeof *Dev); >> if (Dev == NULL) { >> return EFI_OUT_OF_RESOURCES; >> } >> Dev->Signature = VNET_SIG; >> >> Status = gBS->OpenProtocol (DeviceHandle, &gVirtioDeviceProtocolGuid, >> (VOID **)&Dev->VirtIo, This->DriverBindingHandle, >> DeviceHandle, EFI_OPEN_PROTOCOL_BY_DRIVER); >> if (EFI_ERROR (Status)) { >> goto FreeVirtioNet; >> } >> >> - if (Dev->VirtIo->SubSystemDeviceId != VIRTIO_SUBSYSTEM_NETWORK_CARD) { >> - return EFI_UNSUPPORTED; >> - } >> - >> // >> // now we can run a basic one-shot virtio-net initialization required to >> // retrieve the MAC address >> // >> Status = VirtioNetSnpPopulate (Dev); >> if (EFI_ERROR (Status)) { >> goto CloseVirtIo; >> } >> >> // >> // get the device path of the virtio-net device -- one-shot open >> // >> Status = gBS->OpenProtocol (DeviceHandle, &gEfiDevicePathProtocolGuid, >> (VOID **)&DevicePath, This->DriverBindingHandle, >> DeviceHandle, EFI_OPEN_PROTOCOL_GET_PROTOCOL); >> if (EFI_ERROR (Status)) { >> goto Evacuate; >> diff --git a/OvmfPkg/VirtioNetDxe/SnpInitialize.c >> b/OvmfPkg/VirtioNetDxe/SnpInitialize.c >> index 56a55db..8dcf9da 100644 >> --- a/OvmfPkg/VirtioNetDxe/SnpInitialize.c >> +++ b/OvmfPkg/VirtioNetDxe/SnpInitialize.c >> @@ -65,41 +65,61 @@ VirtioNetInitRing ( >> if (EFI_ERROR (Status)) { >> return Status; >> } >> >> // >> // For each packet (RX and TX alike), we need two descriptors: >> // one for the virtio-net request header, and another one for the data >> // >> if (QueueSize < 2) { >> return EFI_UNSUPPORTED; >> } >> Status = VirtioRingInit (QueueSize, Ring); >> if (EFI_ERROR (Status)) { >> return Status; >> } >> >> // >> + // Additional steps for MMIO: align the queue appropriately, and set the >> + // size. If anything fails from here on, we must release the ring >> resources. >> + // >> + Status = Dev->VirtIo->SetQueueNum (Dev->VirtIo, QueueSize); >> + if (EFI_ERROR (Status)) { >> + goto ReleaseQueue; >> + } >> + >> + Status = Dev->VirtIo->SetQueueAlign (Dev->VirtIo, EFI_PAGE_SIZE); >> + if (EFI_ERROR (Status)) { >> + goto ReleaseQueue; >> + } >> + >> + // >> // step 4c -- report GPFN (guest-physical frame number) of queue >> // >> Status = Dev->VirtIo->SetQueueAddress (Dev->VirtIo, >> (UINTN) Ring->Base >> EFI_PAGE_SHIFT); >> if (EFI_ERROR (Status)) { >> - VirtioRingUninit (Ring); >> + goto ReleaseQueue; >> } >> + >> + return EFI_SUCCESS; >> + >> +ReleaseQueue: >> + VirtioRingUninit (Ring); >> + >> return Status; >> } >> >> >> /** >> Set up static scaffolding for the VirtioNetTransmit() and >> VirtioNetGetStatus() SNP methods. >> >> This function may only be called by VirtioNetInitialize(). >> >> The structures laid out and resources configured include: >> - fully populate the TX queue with a static pattern of virtio descriptor >> chains, >> - tracking of heads of free descriptor chains from the above, >> - one common virtio-net request header (never modified by the host) for >> all >> pending TX packets, >> - select polling over TX interrupt. >> @@ -368,35 +388,35 @@ VirtioNetInitialize ( >> NextDevStat = VSTAT_ACK; // step 2 -- acknowledge device presence >> Status = Dev->VirtIo->SetDeviceStatus (Dev->VirtIo, NextDevStat); >> if (EFI_ERROR (Status)) { >> goto InitFailed; >> } >> >> NextDevStat |= VSTAT_DRIVER; // step 3 -- we know how to drive it >> Status = Dev->VirtIo->SetDeviceStatus (Dev->VirtIo, NextDevStat); >> if (EFI_ERROR (Status)) { >> goto DeviceFailed; >> } >> >> // >> // Set Page Size - MMIO VirtIo Specific >> // >> Status = Dev->VirtIo->SetPageSize (Dev->VirtIo, EFI_PAGE_SIZE); >> if (EFI_ERROR (Status)) { >> - goto ReleaseTxRing; >> + goto DeviceFailed; >> } >> >> // >> // step 4a -- retrieve features. Note that we're past validating required >> // features in VirtioNetGetFeatures(). >> // >> Status = Dev->VirtIo->GetDeviceFeatures (Dev->VirtIo, &Features); >> if (EFI_ERROR (Status)) { >> goto DeviceFailed; >> } >> >> ASSERT (Features & VIRTIO_NET_F_MAC); >> ASSERT (Dev->Snm.MediaPresentSupported == >> !!(Features & VIRTIO_NET_F_STATUS)); >> >> // >> // step 4b, 4c -- allocate and report virtqueues >> diff --git a/OvmfPkg/VirtioPciDeviceDxe/VirtioPciDevice.c >> b/OvmfPkg/VirtioPciDeviceDxe/VirtioPciDevice.c >> index c513622..c03a273 100644 >> --- a/OvmfPkg/VirtioPciDeviceDxe/VirtioPciDevice.c >> +++ b/OvmfPkg/VirtioPciDeviceDxe/VirtioPciDevice.c >> @@ -66,59 +66,60 @@ STATIC VIRTIO_DEVICE_PROTOCOL mDeviceProtocolTemplate = { >> @return Status code returned by PciIo->Io.Read(). >> >> **/ >> EFI_STATUS >> EFIAPI >> VirtioPciIoRead ( >> IN VIRTIO_PCI_DEVICE *Dev, >> IN UINTN FieldOffset, >> IN UINTN FieldSize, >> IN UINTN BufferSize, >> OUT VOID *Buffer >> ) >> { >> UINTN Count; >> EFI_PCI_IO_PROTOCOL_WIDTH Width; >> EFI_PCI_IO_PROTOCOL *PciIo; >> >> - // The BufferSize must be a multiple of FieldSize >> - ASSERT ((BufferSize % FieldSize) == 0); >> + ASSERT (FieldSize == BufferSize); >> >> PciIo = Dev->PciIo; >> - Count = BufferSize / FieldSize; >> + Count = 1; >> >> switch (FieldSize) { >> case 1: >> Width = EfiPciIoWidthUint8; >> break; >> >> case 2: >> Width = EfiPciIoWidthUint16; >> break; >> >> case 8: >> + // >> // The 64bit PCI I/O is broken down into two 32bit reads to prevent >> // any alignment or width issues. >> // The UEFI spec says under EFI_PCI_IO_PROTOCOL.Io.Write(): >> // >> // The I/O operations are carried out exactly as requested. The caller >> // is responsible for any alignment and I/O width issues which the >> // bus, device, platform, or type of I/O might require. For example on >> - // some platforms, width requests of EfiPciIoWidthUint64 do not work >> - Count = Count * 2; >> + // some platforms, width requests of EfiPciIoWidthUint64 do not work. >> + // >> + 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, >> diff --git a/OvmfPkg/VirtioPciDeviceDxe/VirtioPciFunctions.c >> b/OvmfPkg/VirtioPciDeviceDxe/VirtioPciFunctions.c >> index 586bec6..9c40fd9 100644 >> --- a/OvmfPkg/VirtioPciDeviceDxe/VirtioPciFunctions.c >> +++ b/OvmfPkg/VirtioPciDeviceDxe/VirtioPciFunctions.c >> @@ -10,40 +10,40 @@ >> under the terms and conditions of the BSD License which accompanies this >> distribution. The full text of the license may be found at >> http://opensource.org/licenses/bsd-license.php >> >> THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, >> WITHOUT >> WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. >> >> **/ >> #include <Library/BaseMemoryLib.h> >> #include <Library/DebugLib.h> >> #include <Library/MemoryAllocationLib.h> >> #include <Library/UefiBootServicesTableLib.h> >> #include <Library/UefiLib.h> >> #include "VirtioPciDevice.h" >> >> /** >> >> - Read a word from Region 0 of the device specified by PciIo. >> + Read a word from Region 0 of the device specified by VirtIo Device >> protocol. >> >> The function implements the ReadDevice protocol member of >> VIRTIO_DEVICE_PROTOCOL. >> >> - @param[in] PciIo Source PCI device. >> + @param[in] This VirtIo Device protocol. >> >> @param[in] FieldOffset Source offset. >> >> @param[in] FieldSize Source field size, must be in { 1, 2, 4, 8 }. >> >> @param[in] BufferSize Number of bytes available in the target buffer. >> Must >> equal FieldSize. >> >> @param[out] Buffer Target buffer. >> >> >> @return Status code returned by PciIo->Io.Read(). >> >> **/ >> EFI_STATUS >> EFIAPI >> VirtioPciDeviceRead ( >> @@ -221,37 +221,35 @@ VirtioPciSetQueueSel ( >> EFI_STATUS >> EFIAPI >> VirtioPciSetQueueAlignment ( >> VIRTIO_DEVICE_PROTOCOL *This, >> UINT32 Alignment >> ) >> { >> return EFI_SUCCESS; >> } >> >> EFI_STATUS >> EFIAPI >> VirtioPciSetPageSize ( >> VIRTIO_DEVICE_PROTOCOL *This, >> UINT32 PageSize >> ) >> { >> - ASSERT (PageSize == EFI_PAGE_SIZE); >> - >> - return EFI_SUCCESS; >> + return (PageSize == EFI_PAGE_SIZE) ? EFI_SUCCESS : EFI_UNSUPPORTED; >> } >> >> EFI_STATUS >> EFIAPI >> VirtioPciSetQueueNotify ( >> VIRTIO_DEVICE_PROTOCOL *This, >> UINT16 Index >> ) >> { >> VIRTIO_PCI_DEVICE *Dev; >> >> Dev = VIRTIO_PCI_DEVICE_FROM_VIRTIO_DEVICE (This); >> >> return VirtioPciIoWrite (Dev, VIRTIO_PCI_OFFSET_QUEUE_NOTIFY, sizeof >> (UINT16), >> Index); >> } >> >> diff --git a/OvmfPkg/VirtioScsiDxe/VirtioScsi.c >> b/OvmfPkg/VirtioScsiDxe/VirtioScsi.c >> index 9702985..267f5f9 100644 >> --- a/OvmfPkg/VirtioScsiDxe/VirtioScsi.c >> +++ b/OvmfPkg/VirtioScsiDxe/VirtioScsi.c >> @@ -36,42 +36,42 @@ >> THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, >> WITHOUT >> WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. >> >> **/ >> >> #include <IndustryStandard/VirtioScsi.h> >> #include <Library/BaseMemoryLib.h> >> #include <Library/DebugLib.h> >> #include <Library/MemoryAllocationLib.h> >> #include <Library/UefiBootServicesTableLib.h> >> #include <Library/UefiLib.h> >> #include <Library/VirtioLib.h> >> >> #include "VirtioScsi.h" >> >> /** >> >> - Convenience macros to read and write region 0 IO space elements of the >> - virtio-scsi VirtIo device, for configuration purposes. >> + Convenience macros to read and write configuration elements of the >> + virtio-scsi VirtIo device. >> >> 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. >> >> - @param[in] Dev Pointer to the VirtIo Device Protocol >> + @param[in] Dev Pointer to the VSCSI_DEV structure. >> >> @param[in] Field A field name from VSCSI_HDR, identifying the >> virtio-scsi >> configuration item to access. >> >> @param[in] Value (VIRTIO_CFG_WRITE() only.) The value to write to the >> selected configuration item. >> >> @param[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. >> >> >> @return Status codes returned by Virtio->WriteDevice() / >> Virtio->ReadDevice(). >> >> **/ >> >> #define VIRTIO_CFG_WRITE(Dev, Field, Value) ((Dev)->VirtIo->WriteDevice ( >> \ >> @@ -724,35 +724,35 @@ VirtioScsiInit ( >> NextDevStat |= VSTAT_ACK; // step 2 -- acknowledge device presence >> Status = Dev->VirtIo->SetDeviceStatus (Dev->VirtIo, NextDevStat); >> if (EFI_ERROR (Status)) { >> goto Failed; >> } >> >> NextDevStat |= VSTAT_DRIVER; // step 3 -- we know how to drive it >> Status = Dev->VirtIo->SetDeviceStatus (Dev->VirtIo, NextDevStat); >> if (EFI_ERROR (Status)) { >> goto Failed; >> } >> >> // >> // Set Page Size - MMIO VirtIo Specific >> // >> Status = Dev->VirtIo->SetPageSize (Dev->VirtIo, EFI_PAGE_SIZE); >> if (EFI_ERROR (Status)) { >> - goto ReleaseQueue; >> + goto Failed; >> } >> >> // >> // step 4a -- retrieve and validate features >> // >> Status = Dev->VirtIo->GetDeviceFeatures (Dev->VirtIo, &Features); >> if (EFI_ERROR (Status)) { >> goto Failed; >> } >> Dev->InOutSupported = !!(Features & VIRTIO_SCSI_F_INOUT); >> >> Status = VIRTIO_CFG_READ (Dev, MaxChannel, &MaxChannel); >> if (EFI_ERROR (Status)) { >> goto Failed; >> } >> if (MaxChannel != 0) { >> // >> @@ -811,36 +811,49 @@ VirtioScsiInit ( >> if (EFI_ERROR (Status)) { >> goto Failed; >> } >> // >> // VirtioScsiPassThru() uses at most four descriptors >> // >> if (QueueSize < 4) { >> Status = EFI_UNSUPPORTED; >> goto Failed; >> } >> >> Status = VirtioRingInit (QueueSize, &Dev->Ring); >> if (EFI_ERROR (Status)) { >> goto Failed; >> } >> >> // >> - // step 4c -- Report GPFN (guest-physical frame number) of queue. If >> anything >> - // fails from here on, we must release the ring resources. >> + // Additional steps for MMIO: align the queue appropriately, and set the >> + // size. If anything fails from here on, we must release the ring >> resources. >> + // >> + Status = Dev->VirtIo->SetQueueNum (Dev->VirtIo, QueueSize); >> + if (EFI_ERROR (Status)) { >> + goto ReleaseQueue; >> + } >> + >> + Status = Dev->VirtIo->SetQueueAlign (Dev->VirtIo, EFI_PAGE_SIZE); >> + if (EFI_ERROR (Status)) { >> + goto ReleaseQueue; >> + } >> + >> + // >> + // step 4c -- Report GPFN (guest-physical frame number) of queue. >> // >> Status = Dev->VirtIo->SetQueueAddress (Dev->VirtIo, >> (UINTN) Dev->Ring.Base >> EFI_PAGE_SHIFT); >> if (EFI_ERROR (Status)) { >> goto ReleaseQueue; >> } >> >> // >> // step 5 -- Report understood features and guest-tuneables. We want none >> of >> // the known (or unknown) VIRTIO_SCSI_F_* or VIRTIO_F_* capabilities (see >> // virtio-0.9.5, Appendices B and I), except bidirectional transfers. >> // >> Status = Dev->VirtIo->SetGuestFeatures (Dev->VirtIo, >> Features & VIRTIO_SCSI_F_INOUT); >> if (EFI_ERROR (Status)) { >> goto ReleaseQueue; >> } > > Olivier Martin (8): > OvmfPkg/VirtioDevice.h: Introduced VIRTIO_DEVICE_PROTOCOL protocol > OvmfPkg/VirtioPciDeviceDxe: Implement VIRTIO_DEVICE_PROTOCOL for > VirtIo Devices over PCI > OvmfPkg/VirtioMmioDeviceLib: Implement VIRTIO_DEVICE_PROTOCOL for > VirtIo Devices over MMIO > OvmfPkg: Make the VirtIo devices use the new VIRTIO_DEVICE_PROTOCOL > OvmfPkg/Virtio.h: Removed definition of VIRTIO_HDR > ArmPlatformPkg/ArmVExpressPkg: Added the empty 'ArmFvpDxe' platform > UEFI driver > ArmPlatformPkg/ArmFvpDxe: Added Virtio Block support > OvmfPkg/Virtio: Removed VirtioReadDevice() / VirtIoWriteDevice() > functions > > .../ArmVExpressPkg/ArmFvpDxe/ArmFvpDxe.inf | 35 ++ > .../VirtioMmioDeviceLib/VirtioMmioDeviceLib.inf | 42 ++ > OvmfPkg/VirtioBlkDxe/VirtioBlk.inf | 4 +- > OvmfPkg/VirtioNetDxe/VirtioNet.inf | 2 +- > OvmfPkg/VirtioPciDeviceDxe/VirtioPciDeviceDxe.inf | 43 ++ > OvmfPkg/VirtioScsiDxe/VirtioScsi.inf | 2 +- > OvmfPkg/Include/IndustryStandard/Virtio.h | 18 - > OvmfPkg/Include/IndustryStandard/VirtioBlk.h | 21 +- > OvmfPkg/Include/IndustryStandard/VirtioNet.h | 14 +- > OvmfPkg/Include/IndustryStandard/VirtioScsi.h | 27 +- > OvmfPkg/Include/Library/VirtioLib.h | 77 +-- > OvmfPkg/Include/Library/VirtioMmioDeviceLib.h | 66 ++ > OvmfPkg/Include/Protocol/VirtioDevice.h | 382 ++++++++++++ > .../Library/VirtioMmioDeviceLib/VirtioMmioDevice.h | 147 +++++ > OvmfPkg/VirtioBlkDxe/VirtioBlk.h | 32 +- > OvmfPkg/VirtioNetDxe/VirtioNet.h | 26 +- > OvmfPkg/VirtioPciDeviceDxe/VirtioPciDevice.h | 166 +++++ > OvmfPkg/VirtioScsiDxe/VirtioScsi.h | 24 +- > .../ArmVExpressPkg/ArmFvpDxe/ArmFvpDxe.c | 75 +++ > OvmfPkg/Library/VirtioLib/VirtioLib.c | 158 +---- > .../Library/VirtioMmioDeviceLib/VirtioMmioDevice.c | 205 +++++++ > .../VirtioMmioDeviceFunctions.c | 300 +++++++++ > OvmfPkg/VirtioBlkDxe/VirtioBlk.c | 194 +++--- > OvmfPkg/VirtioNetDxe/ComponentName.c | 6 +- > OvmfPkg/VirtioNetDxe/DriverBinding.c | 137 ++--- > OvmfPkg/VirtioNetDxe/Events.c | 2 +- > OvmfPkg/VirtioNetDxe/SnpGetStatus.c | 2 +- > OvmfPkg/VirtioNetDxe/SnpInitialize.c | 59 +- > OvmfPkg/VirtioNetDxe/SnpReceive.c | 12 +- > OvmfPkg/VirtioNetDxe/SnpShutdown.c | 2 +- > OvmfPkg/VirtioNetDxe/SnpTransmit.c | 12 +- > OvmfPkg/VirtioPciDeviceDxe/VirtioPciDevice.c | 668 > +++++++++++++++++++++ > OvmfPkg/VirtioPciDeviceDxe/VirtioPciFunctions.c | 283 +++++++++ > OvmfPkg/VirtioScsiDxe/VirtioScsi.c | 192 +++--- > .../ArmVExpress-RTSM-AEMv8Ax4-foundation.dsc | 10 + > .../ArmVExpress-RTSM-AEMv8Ax4-foundation.fdf | 6 + > .../ArmVExpressPkg/ArmVExpress-RTSM-AEMv8Ax4.dsc | 10 + > .../ArmVExpressPkg/ArmVExpress-RTSM-AEMv8Ax4.fdf | 8 +- > OvmfPkg/OvmfPkg.dec | 1 + > OvmfPkg/OvmfPkgIa32.dsc | 1 + > OvmfPkg/OvmfPkgIa32.fdf | 1 + > OvmfPkg/OvmfPkgIa32X64.dsc | 1 + > OvmfPkg/OvmfPkgIa32X64.fdf | 1 + > OvmfPkg/OvmfPkgX64.dsc | 1 + > OvmfPkg/OvmfPkgX64.fdf | 1 + > 45 files changed, 2813 insertions(+), 663 deletions(-) > create mode 100644 ArmPlatformPkg/ArmVExpressPkg/ArmFvpDxe/ArmFvpDxe.inf > create mode 100644 > OvmfPkg/Library/VirtioMmioDeviceLib/VirtioMmioDeviceLib.inf > create mode 100644 OvmfPkg/VirtioPciDeviceDxe/VirtioPciDeviceDxe.inf > create mode 100644 OvmfPkg/Include/Library/VirtioMmioDeviceLib.h > create mode 100644 OvmfPkg/Include/Protocol/VirtioDevice.h > create mode 100644 OvmfPkg/Library/VirtioMmioDeviceLib/VirtioMmioDevice.h > create mode 100644 OvmfPkg/VirtioPciDeviceDxe/VirtioPciDevice.h > create mode 100644 ArmPlatformPkg/ArmVExpressPkg/ArmFvpDxe/ArmFvpDxe.c > create mode 100644 OvmfPkg/Library/VirtioMmioDeviceLib/VirtioMmioDevice.c > create mode 100644 > OvmfPkg/Library/VirtioMmioDeviceLib/VirtioMmioDeviceFunctions.c > create mode 100644 OvmfPkg/VirtioPciDeviceDxe/VirtioPciDevice.c > create mode 100644 OvmfPkg/VirtioPciDeviceDxe/VirtioPciFunctions.c > > -- > 1.8.3.1 > > > ------------------------------------------------------------------------------ > Rapidly troubleshoot problems before they affect your business. Most IT > organizations don't have a clear picture of how application performance > affects their revenue. With AppDynamics, you get 100% visibility into your > Java,.NET, & PHP application. Start your 15-day FREE TRIAL of AppDynamics Pro! > http://pubads.g.doubleclick.net/gampad/clk?id=84349351&iu=/4140/ostg.clktrk > _______________________________________________ > edk2-devel mailing list > edk2-devel@lists.sourceforge.net > https://lists.sourceforge.net/lists/listinfo/edk2-devel ------------------------------------------------------------------------------ Rapidly troubleshoot problems before they affect your business. Most IT organizations don't have a clear picture of how application performance affects their revenue. With AppDynamics, you get 100% visibility into your Java,.NET, & PHP application. Start your 15-day FREE TRIAL of AppDynamics Pro! http://pubads.g.doubleclick.net/gampad/clk?id=84349831&iu=/4140/ostg.clktrk _______________________________________________ edk2-devel mailing list edk2-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/edk2-devel