From nobody Sat Jul 12 13:26:34 2025 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; spf=none (zoho.com: 198.145.21.10 is neither permitted nor denied by domain of lists.01.org) smtp.mailfrom=edk2-devel-bounces@lists.01.org Return-Path: Received: from ml01.01.org (ml01.01.org [198.145.21.10]) by mx.zohomail.com with SMTPS id 1520386632000259.35126103943264; Tue, 6 Mar 2018 17:37:12 -0800 (PST) Received: from [127.0.0.1] (localhost [IPv6:::1]) by ml01.01.org (Postfix) with ESMTP id 56E75224E6911; Tue, 6 Mar 2018 17:30:52 -0800 (PST) Received: from foss.arm.com (foss.arm.com [217.140.101.70]) by ml01.01.org (Postfix) with ESMTP id BC75A2235229E for ; Tue, 6 Mar 2018 17:30:50 -0800 (PST) Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.72.51.249]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 5383F1435; Tue, 6 Mar 2018 17:37:05 -0800 (PST) Received: from usa.arm.com (dbox2.austin.arm.com [10.118.34.22]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id 132733F24A; Tue, 6 Mar 2018 17:37:05 -0800 (PST) X-Original-To: edk2-devel@lists.01.org Received-SPF: none (zoho.com: 198.145.21.10 is neither permitted nor denied by domain of lists.01.org) client-ip=198.145.21.10; envelope-from=edk2-devel-bounces@lists.01.org; helo=ml01.01.org; Received-SPF: Pass (sender SPF authorized) identity=mailfrom; client-ip=217.140.101.70; helo=foss.arm.com; envelope-from=daniil.egranov@arm.com; receiver=edk2-devel@lists.01.org From: Daniil Egranov To: edk2-devel@lists.01.org Date: Tue, 6 Mar 2018 19:36:36 -0600 Message-Id: <20180307013637.16462-4-daniil.egranov@arm.com> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20180307013637.16462-1-daniil.egranov@arm.com> References: <20180307013637.16462-1-daniil.egranov@arm.com> Subject: [edk2] [PATCH 3/4] NonDiscoverablePciDeviceDxe: Added MMIO Virtio support X-BeenThere: edk2-devel@lists.01.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: EDK II Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: leif.lindholm@linaro.org, ard.biesheuvel@linaro.org MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Errors-To: edk2-devel-bounces@lists.01.org Sender: "edk2-devel" X-ZohoMail: RSF_4 Z_629925259 SPT_0 Content-Type: text/plain; charset="utf-8" Added PCI IO to MMIO translation for Virtio case into the PCI IO=20 protocol functions. Added Virtio device type into the PCI IO protocol initialization procedure. Contributed-under: TianoCore Contribution Agreement 1.1 Signed-off-by: Daniil Egranov --- .../NonDiscoverablePciDeviceDxe.c | 3 +- .../NonDiscoverablePciDeviceDxe.inf | 5 +- .../NonDiscoverablePciDeviceIo.c | 240 +++++++++++++++++= +++- 3 files changed, 241 insertions(+), 7 deletions(-) diff --git a/MdeModulePkg/Bus/Pci/NonDiscoverablePciDeviceDxe/NonDiscoverab= lePciDeviceDxe.c b/MdeModulePkg/Bus/Pci/NonDiscoverablePciDeviceDxe/NonDisc= overablePciDeviceDxe.c index 3e9ff6620d..2c3eeca914 100644 --- a/MdeModulePkg/Bus/Pci/NonDiscoverablePciDeviceDxe/NonDiscoverablePciDe= viceDxe.c +++ b/MdeModulePkg/Bus/Pci/NonDiscoverablePciDeviceDxe/NonDiscoverablePciDe= viceDxe.c @@ -1,6 +1,6 @@ /** @file =20 - Copyright (C) 2016, Linaro Ltd. All rights reserved.
+ Copyright (C) 2016-2018, Linaro Ltd. All rights reserved.
=20 This program and the accompanying materials are licensed and made availa= ble under the terms and conditions of the BSD License which accompanies this @@ -32,6 +32,7 @@ SupportedNonDiscoverableDevices[] =3D { &gEdkiiNonDiscoverableUfsDeviceGuid, &gEdkiiNonDiscoverableUhciDeviceGuid, &gEdkiiNonDiscoverableXhciDeviceGuid, + &gEdkiiNonDiscoverableVirtioDeviceGuid }; =20 // diff --git a/MdeModulePkg/Bus/Pci/NonDiscoverablePciDeviceDxe/NonDiscoverab= lePciDeviceDxe.inf b/MdeModulePkg/Bus/Pci/NonDiscoverablePciDeviceDxe/NonDi= scoverablePciDeviceDxe.inf index ac551a82ab..a7bf5a5fc1 100644 --- a/MdeModulePkg/Bus/Pci/NonDiscoverablePciDeviceDxe/NonDiscoverablePciDe= viceDxe.inf +++ b/MdeModulePkg/Bus/Pci/NonDiscoverablePciDeviceDxe/NonDiscoverablePciDe= viceDxe.inf @@ -1,7 +1,7 @@ ## @file # PCI I/O driver for non-discoverable devices. # -# Copyright (C) 2016, Linaro Ltd. +# Copyright (C) 2016-2018, Linaro Ltd. # # This program and the accompanying materials are licensed and made availa= ble # under the terms and conditions of the BSD License which accompanies this @@ -30,6 +30,7 @@ [Packages] MdePkg/MdePkg.dec MdeModulePkg/MdeModulePkg.dec + OvmfPkg/OvmfPkg.dec =20 [LibraryClasses] BaseMemoryLib @@ -54,3 +55,5 @@ gEdkiiNonDiscoverableUfsDeviceGuid ## CONSUMES ## GUID gEdkiiNonDiscoverableUhciDeviceGuid ## CONSUMES ## GUID gEdkiiNonDiscoverableXhciDeviceGuid ## CONSUMES ## GUID + gEdkiiNonDiscoverableVirtioDeviceGuid ## CONSUMES ## GUID + diff --git a/MdeModulePkg/Bus/Pci/NonDiscoverablePciDeviceDxe/NonDiscoverab= lePciDeviceIo.c b/MdeModulePkg/Bus/Pci/NonDiscoverablePciDeviceDxe/NonDisco= verablePciDeviceIo.c index 0e42ae4bf6..cb99bf0ba6 100644 --- a/MdeModulePkg/Bus/Pci/NonDiscoverablePciDeviceDxe/NonDiscoverablePciDe= viceIo.c +++ b/MdeModulePkg/Bus/Pci/NonDiscoverablePciDeviceDxe/NonDiscoverablePciDe= viceIo.c @@ -1,7 +1,7 @@ /** @file =20 Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.
- Copyright (c) 2016, Linaro, Ltd. All rights reserved.
+ Copyright (c) 2016-2018, Linaro, Ltd. All rights reserved.
=20 This program and the accompanying materials are licensed and made available under the terms and conditions of the BS= D License @@ -17,8 +17,12 @@ =20 #include =20 +#include + #include =20 +#include + #include =20 typedef struct { @@ -374,6 +378,82 @@ PciIoMemWrite ( } =20 /** + Translate PCI IO to MMIO for VirtIo Non-Discoverable devices. + + @param BaseAddress A base MMIO memory address of a VirtIo dev= ice. + @param PciIoOffset PCI IO offset. + @param DevConfigAddress The address is a device specific config sp= ace. + + @retval EFI_SUCCESS The address translated successfully. + @retval EFI_UNSUPPORTED The PCI IO address can not be translated. + +**/ +STATIC +EFI_STATUS +EFIAPI +VirtioPciIoToMemIoTranslation ( + IN UINTN BaseAddress, + IN UINTN PciIoOffset, + IN OUT UINTN *Address, + IN OUT BOOLEAN *DevConfigAddress + ) +{ + EFI_STATUS Status; + UINTN Offset; + INTN DevConfigSpaceOffset; + + Status =3D EFI_SUCCESS; + Offset =3D PciIoOffset; + *DevConfigAddress =3D FALSE; + DevConfigSpaceOffset =3D 0; + + // + //Check if it's device specific config space + // + if (PciIoOffset >=3D VIRTIO_DEVICE_SPECIFIC_CONFIGURATION_OFFSET_PCI ) { + Offset =3D VIRTIO_DEVICE_SPECIFIC_CONFIGURATION_OFFSET_PCI; + DevConfigSpaceOffset =3D PciIoOffset - VIRTIO_DEVICE_SPECIFIC_CONFIGUR= ATION_OFFSET_PCI; + *DevConfigAddress =3D TRUE; + } + + switch (Offset) { + case VIRTIO_PCI_OFFSET_DEVICE_FEATURES: + *Address =3D BaseAddress + VIRTIO_MMIO_OFFSET_HOST_FEATURES; + break; + case VIRTIO_PCI_OFFSET_GUEST_FEATURES: + *Address =3D BaseAddress + VIRTIO_MMIO_OFFSET_GUEST_FEATURES; + break; + case VIRTIO_PCI_OFFSET_QUEUE_ADDRESS: + *Address =3D BaseAddress + VIRTIO_MMIO_OFFSET_QUEUE_PFN; + break; + case VIRTIO_PCI_OFFSET_QUEUE_SIZE: + *Address =3D BaseAddress + VIRTIO_MMIO_OFFSET_QUEUE_NUM_MAX; + break; + case VIRTIO_PCI_OFFSET_QUEUE_SELECT: + *Address =3D BaseAddress + VIRTIO_MMIO_OFFSET_QUEUE_SEL; + break; + case VIRTIO_PCI_OFFSET_QUEUE_NOTIFY: + *Address =3D BaseAddress + VIRTIO_MMIO_OFFSET_QUEUE_NOTIFY; + break; + case VIRTIO_PCI_OFFSET_QUEUE_DEVICE_STATUS: + *Address =3D BaseAddress + VIRTIO_MMIO_OFFSET_STATUS; + break; + case VIRTIO_PCI_OFFSET_QUEUE_DEVICE_ISR: + Status =3D EFI_UNSUPPORTED; + break; + case VIRTIO_DEVICE_SPECIFIC_CONFIGURATION_OFFSET_PCI: + case VIRTIO_DEVICE_SPECIFIC_CONFIGURATION_OFFSET_PCI_WITH_MSI_X: + *Address =3D BaseAddress + VIRTIO_DEVICE_SPECIFIC_CONFIGURATION_OFFSET= _MMIO + DevConfigSpaceOffset; + break; + default: + Status =3D EFI_UNSUPPORTED; + break; + } + + return Status; +} + +/** Enable a PCI driver to access PCI controller registers in the PCI memory= or I/O space. =20 @param This A pointer to the EFI_PCI_IO_PROTOCOL insta= nce. @@ -398,8 +478,72 @@ PciIoIoRead ( IN OUT VOID *Buffer ) { - ASSERT (FALSE); - return EFI_UNSUPPORTED; + NON_DISCOVERABLE_PCI_DEVICE *Dev; + EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Desc; + UINTN Length; + UINTN Address; + UINT32 ReadData; + BOOLEAN IsDevConfigSpace; + EFI_STATUS Status; + + if (Buffer =3D=3D NULL) { + return EFI_INVALID_PARAMETER; + } + + Dev =3D NON_DISCOVERABLE_PCI_DEVICE_FROM_PCI_IO (This); + + // + // Only allow accesses to the BARs we emulate + // + Status =3D GetBarResource (Dev, BarIndex, &Desc); + if (EFI_ERROR (Status)) { + return Status; + } + + Length =3D Count << ((UINTN)Width & 0x3); + if (Offset + Length > Desc->AddrLen) { + return EFI_UNSUPPORTED; + } + + // + // Non-Discoverable devices are MMIO devices. Translate PCI IO requests = to MMIO. + // + + // + // VirtIo + // + if (CompareGuid (Dev->Device->Type, &gEdkiiNonDiscoverableVirtioDeviceGu= id)) { + // + // Check for a valid data size + // + if ((Length !=3D 1) && (Length !=3D 2) && + (Length !=3D 4) && (Length !=3D 8)) { + return EFI_INVALID_PARAMETER; + } + + Status =3D VirtioPciIoToMemIoTranslation (Desc->AddrRangeMin, Offset, = &Address, &IsDevConfigSpace); + if (!EFI_ERROR (Status)) { + if (IsDevConfigSpace =3D=3D TRUE) { // Device-specific configuration= registers + // + // The device-specific memory area of Virtio-MMIO can only be writ= ten in + // byte accesses. This is not currently in the Virtio spec. + // + MmioReadBuffer8 (Address, Length, Buffer); + } else if (Length < 8) { // 32-bit MMIO registers + ReadData =3D MmioRead32 (Address); + // The PCI IO register width may not be the same as MMIO register. + // Virtio MMIO registers are always 32-bit + CopyMem (Buffer, &ReadData, Length); + } else { + Status =3D EFI_INVALID_PARAMETER; + } + } + } else { + Status =3D EFI_UNSUPPORTED; + } + + ASSERT_EFI_ERROR (Status); + return Status; } =20 /** @@ -427,8 +571,72 @@ PciIoIoWrite ( IN OUT VOID *Buffer ) { - ASSERT (FALSE); - return EFI_UNSUPPORTED; + NON_DISCOVERABLE_PCI_DEVICE *Dev; + EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Desc; + UINTN Length; + UINTN Address; + UINT32 WriteData; + BOOLEAN IsDevConfigSpace; + EFI_STATUS Status; + + if (Buffer =3D=3D NULL) { + return EFI_INVALID_PARAMETER; + } + + Dev =3D NON_DISCOVERABLE_PCI_DEVICE_FROM_PCI_IO (This); + + // + // Only allow accesses to the BARs we emulate + // + Status =3D GetBarResource (Dev, BarIndex, &Desc); + if (EFI_ERROR (Status)) { + return Status; + } + + Length =3D Count << ((UINTN)Width & 0x3); + if (Offset + Length > Desc->AddrLen) { + return EFI_UNSUPPORTED; + } + + // + // Non-Discoverable devices are MMIO devices. Translate PCI IO requests = to MMIO. + // + + // + // VirtIo + // + if (CompareGuid (Dev->Device->Type, &gEdkiiNonDiscoverableVirtioDeviceGu= id)) { + // + // Check for a valid data size + // + if ((Length !=3D 1) && (Length !=3D 2) && + (Length !=3D 4) && (Length !=3D 8)) { + return EFI_INVALID_PARAMETER; + } + + Status =3D VirtioPciIoToMemIoTranslation (Desc->AddrRangeMin, Offset, = &Address, &IsDevConfigSpace); + if (!EFI_ERROR (Status)) { + if (IsDevConfigSpace =3D=3D TRUE) { // Device-specific configuration= registers + // + // The device-specific memory area of Virtio-MMIO can only be writ= ten in + // byte accesses. This is not currently in the Virtio spec. + // + MmioWriteBuffer8 (Address, Length, Buffer); + } else if (Length < 8) { // 32-bit MMIO registers + // The PCI IO register width may not be the same as MMIO register. + // Virtio MMIO registers are always 32-bit + CopyMem (&WriteData, Buffer, Length); + MmioWrite32 (Address, WriteData); + } else { + return EFI_INVALID_PARAMETER; + } + } + } else { + Status =3D EFI_UNSUPPORTED; + } + + ASSERT_EFI_ERROR (Status); + return Status; } =20 /** @@ -1408,6 +1616,7 @@ InitializePciIoProtocol ( { EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Desc; INTN Idx; + UINT32 VirtioMagicValue; =20 InitializeListHead (&Dev->UncachedAllocationList); =20 @@ -1471,6 +1680,15 @@ InitializePciIoProtocol ( Dev->ConfigSpace.Hdr.ClassCode[1] =3D 0x9; // UFS controller subclass; Dev->ConfigSpace.Hdr.ClassCode[2] =3D PCI_CLASS_MASS_STORAGE; Dev->BarOffset =3D 0; + } else if (CompareGuid (Dev->Device->Type, + &gEdkiiNonDiscoverableVirtioDeviceGuid)) { + Dev->ConfigSpace.Hdr.VendorId =3D VIRTIO_VENDOR_ID; // Required Virtio= vendor + Dev->ConfigSpace.Hdr.DeviceId =3D 0x1000; // Required Virtio device id + Dev->ConfigSpace.Hdr.RevisionID =3D 0x0; + Dev->ConfigSpace.Hdr.ClassCode[0] =3D 0x0; // don't care + Dev->ConfigSpace.Hdr.ClassCode[1] =3D 0x0; // don't care + Dev->ConfigSpace.Hdr.ClassCode[2] =3D 0x0; // don't care + Dev->BarOffset =3D 0; } else { ASSERT_EFI_ERROR (EFI_INVALID_PARAMETER); } @@ -1496,6 +1714,18 @@ InitializePciIoProtocol ( } =20 Dev->ConfigSpace.Device.Bar[Idx] =3D (UINT32)Desc->AddrRangeMin; + + // + // Initialize Virtio device Id + // + if (CompareGuid (Dev->Device->Type, &gEdkiiNonDiscoverableVirtioDevice= Guid)) { + VirtioMagicValue =3D MmioRead32 (Dev->ConfigSpace.Device.Bar[Idx] + = VIRTIO_MMIO_OFFSET_MAGIC); + if (VirtioMagicValue =3D=3D VIRTIO_MMIO_MAGIC) { + Dev->ConfigSpace.Device.SubsystemID =3D MmioRead32 (Dev->ConfigSpa= ce.Device.Bar[Idx] + + VIRTIO_MMIO_OFFS= ET_DEVICE_ID); + } + } + Dev->BarCount++; =20 if (Desc->AddrSpaceGranularity =3D=3D 64) { --=20 2.11.0 _______________________________________________ edk2-devel mailing list edk2-devel@lists.01.org https://lists.01.org/mailman/listinfo/edk2-devel