X-Git-Url: https://git.proxmox.com/?p=mirror_edk2.git;a=blobdiff_plain;f=OvmfPkg%2FVirtio10Dxe%2FVirtio10.c;h=9ebb72c76bfdac65f2532b3caa4183d2c68d9881;hp=ef9a00710668daf041b011224a1a9cbc1ba69e7c;hb=f33d5d68abc02727dc828c1079e72ab65e1d63af;hpb=53a4c6047f3ce2ece7bb8db5b9815a1c9227dddb diff --git a/OvmfPkg/Virtio10Dxe/Virtio10.c b/OvmfPkg/Virtio10Dxe/Virtio10.c index ef9a007106..9ebb72c76b 100644 --- a/OvmfPkg/Virtio10Dxe/Virtio10.c +++ b/OvmfPkg/Virtio10Dxe/Virtio10.c @@ -21,6 +21,8 @@ #include #include #include +#include +#include #include #include @@ -184,48 +186,6 @@ GetBarType ( } -/** - Read a slice from PCI config space at the given offset, then advance the - offset. - - @param [in] PciIo The EFI_PCI_IO_PROTOCOL instance that represents the - device. - - @param [in,out] Offset On input, the offset in PCI config space to start - reading from. On output, the offset of the first byte - that was not read. On error, Offset is not modified. - - @param [in] Size The number of bytes to read. - - @param [out] Buffer On output, the bytes read from PCI config space are - stored in this object. - - @retval EFI_SUCCESS Size bytes have been transferred from PCI config space - (from Offset) to Buffer, and Offset has been incremented - by Size. - - @return Error codes from PciIo->Pci.Read(). -**/ -STATIC -EFI_STATUS -ReadConfigSpace ( - IN EFI_PCI_IO_PROTOCOL *PciIo, - IN OUT UINT32 *Offset, - IN UINTN Size, - OUT VOID *Buffer - ) -{ - EFI_STATUS Status; - - Status = PciIo->Pci.Read (PciIo, EfiPciIoWidthUint8, *Offset, Size, Buffer); - if (EFI_ERROR (Status)) { - return Status; - } - *Offset += (UINT32)Size; - return EFI_SUCCESS; -} - - /* Traverse the PCI capabilities list of a virtio-1.0 device, and capture the locations of the interesting virtio-1.0 register blocks. @@ -239,57 +199,51 @@ ReadConfigSpace ( will have been updated from the PCI capabilities found. - @param[in] CapabilityPtr The offset of the first capability in PCI - config space, taken from the standard PCI - device header. - @retval EFI_SUCCESS Traversal successful. - @return Error codes from the ReadConfigSpace() and GetBarType() - helper functions. + @return Error codes from PciCapPciIoLib, PciCapLib, and the + GetBarType() helper function. */ STATIC EFI_STATUS ParseCapabilities ( - IN OUT VIRTIO_1_0_DEV *Device, - IN UINT8 CapabilityPtr + IN OUT VIRTIO_1_0_DEV *Device ) { - UINT32 Offset; - VIRTIO_PCI_CAP_LINK CapLink; - - for (Offset = CapabilityPtr & 0xFC; - Offset > 0; - Offset = CapLink.CapNext & 0xFC - ) { - EFI_STATUS Status; + EFI_STATUS Status; + PCI_CAP_DEV *PciDevice; + PCI_CAP_LIST *CapList; + UINT16 VendorInstance; + PCI_CAP *VendorCap; + + Status = PciCapPciIoDeviceInit (Device->PciIo, &PciDevice); + if (EFI_ERROR (Status)) { + return Status; + } + Status = PciCapListInit (PciDevice, &CapList); + if (EFI_ERROR (Status)) { + goto UninitPciDevice; + } + + for (VendorInstance = 0; + !EFI_ERROR (PciCapListFindCap (CapList, PciCapNormal, + EFI_PCI_CAPABILITY_ID_VENDOR, VendorInstance, + &VendorCap)); + VendorInstance++) { UINT8 CapLen; VIRTIO_PCI_CAP VirtIoCap; VIRTIO_1_0_CONFIG *ParsedConfig; - // - // Read capability identifier and link to next capability. - // - Status = ReadConfigSpace (Device->PciIo, &Offset, sizeof CapLink, - &CapLink); - if (EFI_ERROR (Status)) { - return Status; - } - if (CapLink.CapId != 0x09) { - // - // Not a vendor-specific capability, move to the next one. - // - continue; - } - // // Big enough to accommodate a VIRTIO_PCI_CAP structure? // - Status = ReadConfigSpace (Device->PciIo, &Offset, sizeof CapLen, &CapLen); + Status = PciCapRead (PciDevice, VendorCap, + OFFSET_OF (EFI_PCI_CAPABILITY_VENDOR_HDR, Length), &CapLen, + sizeof CapLen); if (EFI_ERROR (Status)) { - return Status; + goto UninitCapList; } - if (CapLen < sizeof CapLink + sizeof CapLen + sizeof VirtIoCap) { + if (CapLen < sizeof VirtIoCap) { // // Too small, move to next. // @@ -299,11 +253,11 @@ ParseCapabilities ( // // Read interesting part of capability. // - Status = ReadConfigSpace (Device->PciIo, &Offset, sizeof VirtIoCap, - &VirtIoCap); + Status = PciCapRead (PciDevice, VendorCap, 0, &VirtIoCap, sizeof VirtIoCap); if (EFI_ERROR (Status)) { - return Status; + goto UninitCapList; } + switch (VirtIoCap.ConfigType) { case VIRTIO_PCI_CAP_COMMON_CFG: ParsedConfig = &Device->CommonConfig; @@ -326,7 +280,7 @@ ParseCapabilities ( // Status = GetBarType (Device->PciIo, VirtIoCap.Bar, &ParsedConfig->BarType); if (EFI_ERROR (Status)) { - return Status; + goto UninitCapList; } ParsedConfig->Bar = VirtIoCap.Bar; ParsedConfig->Offset = VirtIoCap.Offset; @@ -337,19 +291,18 @@ ParseCapabilities ( // This capability has an additional field called NotifyOffsetMultiplier; // parse it too. // - if (CapLen < sizeof CapLink + sizeof CapLen + sizeof VirtIoCap + - sizeof Device->NotifyOffsetMultiplier) { + if (CapLen < sizeof VirtIoCap + sizeof Device->NotifyOffsetMultiplier) { // // Too small, move to next. // continue; } - Status = ReadConfigSpace (Device->PciIo, &Offset, - sizeof Device->NotifyOffsetMultiplier, - &Device->NotifyOffsetMultiplier); + Status = PciCapRead (PciDevice, VendorCap, sizeof VirtIoCap, + &Device->NotifyOffsetMultiplier, + sizeof Device->NotifyOffsetMultiplier); if (EFI_ERROR (Status)) { - return Status; + goto UninitCapList; } } @@ -359,7 +312,15 @@ ParseCapabilities ( ParsedConfig->Exists = TRUE; } - return EFI_SUCCESS; + ASSERT_EFI_ERROR (Status); + +UninitCapList: + PciCapListUninit (CapList); + +UninitPciDevice: + PciCapPciIoDeviceUninit (PciDevice); + + return Status; } @@ -498,11 +459,10 @@ Virtio10SetQueueAddress ( UINT64 Address; UINT16 Enable; - ASSERT (RingBaseShift == 0); - Dev = VIRTIO_1_0_FROM_VIRTIO_DEVICE (This); Address = (UINTN)Ring->Desc; + Address += RingBaseShift; Status = Virtio10Transfer (Dev->PciIo, &Dev->CommonConfig, TRUE, OFFSET_OF (VIRTIO_PCI_COMMON_CFG, QueueDesc), sizeof Address, &Address); @@ -511,6 +471,7 @@ Virtio10SetQueueAddress ( } Address = (UINTN)Ring->Avail.Flags; + Address += RingBaseShift; Status = Virtio10Transfer (Dev->PciIo, &Dev->CommonConfig, TRUE, OFFSET_OF (VIRTIO_PCI_COMMON_CFG, QueueAvail), sizeof Address, &Address); @@ -519,6 +480,7 @@ Virtio10SetQueueAddress ( } Address = (UINTN)Ring->Used.Flags; + Address += RingBaseShift; Status = Virtio10Transfer (Dev->PciIo, &Dev->CommonConfig, TRUE, OFFSET_OF (VIRTIO_PCI_COMMON_CFG, QueueUsed), sizeof Address, &Address); @@ -1014,7 +976,7 @@ Virtio10BindingStart ( Device->VirtIo.SubSystemDeviceId = Pci.Hdr.DeviceId - 0x1040; - Status = ParseCapabilities (Device, Pci.Device.CapabilityPtr); + Status = ParseCapabilities (Device); if (EFI_ERROR (Status)) { goto ClosePciIo; }