Done and committed in SVN rev14980 and rev14981. Thanks Laszlo, Jordan and Mark for your feedbacks and support.
> -----Original Message----- > From: Jordan Justen [mailto:jljus...@gmail.com] > Sent: 11 December 2013 17:02 > To: Laszlo Ersek; Olivier Martin > Cc: edk2-devel@lists.sourceforge.net > Subject: Re: [edk2] [PATCH v5 0/8] OvmfPkg/Arm*Pkg: Introduce and use > the new VIRTIO_DEVICE_PROTOCOL protocol > > 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.cl > ktrk > > _______________________________________________ > > 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