From patchwork Thu Feb 12 11:19:12 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ard Biesheuvel X-Patchwork-Id: 44621 Return-Path: X-Original-To: linaro@patches.linaro.org Delivered-To: linaro@patches.linaro.org Received: from mail-ee0-f72.google.com (mail-ee0-f72.google.com [74.125.83.72]) by ip-10-151-82-157.ec2.internal (Postfix) with ESMTPS id 5EA662151D for ; Thu, 12 Feb 2015 11:21:22 +0000 (UTC) Received: by mail-ee0-f72.google.com with SMTP id e53sf6544104eek.3 for ; Thu, 12 Feb 2015 03:21:21 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:delivered-to:from:to:date:message-id:in-reply-to :references:subject:precedence:reply-to:list-id:list-unsubscribe :list-archive:list-post:list-help:list-subscribe:mime-version :content-type:content-transfer-encoding:errors-to:x-original-sender :x-original-authentication-results:mailing-list; bh=DAuXmqbdWEJn69H2QM0cvGUCIdn2za1g4Zia87/NANU=; b=ZvDhOCkK1rR2rvcRMpZKEBw2YVWiafgrYLDCB1jPnWX7jQTymxDkNKuNW+aGvsw6rL kVQO1zCbO7ybjqwDkuhT6oo7Iikms4PzjuPJtqC0t6JyH1j/LOLY92XN6/VjFfyv1HvT mcbw2f49/OWWvGiQyRB/DJaxlWSCn/PLJzTSbDbzZE63+pcAV8N9IaC1OfldkWhmNoLi 6SwLreIEGsEHfQqaq5ZxJl0F1mNeOtisJM0K9Pjyfl0EkOnTd9d97SasVWaIE53C5PfE 2/KrOoNBLcx49BXCLrO5Wh06/dtFoJqzVjKMmdP22afhdy2P5VSDUemgEFzUPGpn2A4g EiAA== X-Gm-Message-State: ALoCoQnNfi2Yg330AZIxTQIVtUfmV1rc2ne3rYOvIB//gyeBOEwgsT6wRszIZ9pUGepwIHyeqwSV X-Received: by 10.180.212.76 with SMTP id ni12mr466459wic.0.1423740081638; Thu, 12 Feb 2015 03:21:21 -0800 (PST) X-BeenThere: patchwork-forward@linaro.org Received: by 10.153.8.136 with SMTP id dk8ls151050lad.97.gmail; Thu, 12 Feb 2015 03:21:21 -0800 (PST) X-Received: by 10.112.137.196 with SMTP id qk4mr2773971lbb.33.1423740081351; Thu, 12 Feb 2015 03:21:21 -0800 (PST) Received: from mail-lb0-f177.google.com (mail-lb0-f177.google.com. [209.85.217.177]) by mx.google.com with ESMTPS id wm7si2715201lbb.72.2015.02.12.03.21.21 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 12 Feb 2015 03:21:21 -0800 (PST) Received-SPF: pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.217.177 as permitted sender) client-ip=209.85.217.177; Received: by mail-lb0-f177.google.com with SMTP id z11so8846141lbi.8 for ; Thu, 12 Feb 2015 03:21:21 -0800 (PST) X-Received: by 10.112.125.4 with SMTP id mm4mr2825423lbb.86.1423740081122; Thu, 12 Feb 2015 03:21:21 -0800 (PST) X-Forwarded-To: patchwork-forward@linaro.org X-Forwarded-For: patch@linaro.org patchwork-forward@linaro.org Delivered-To: patch@linaro.org Received: by 10.112.35.133 with SMTP id h5csp378718lbj; Thu, 12 Feb 2015 03:21:19 -0800 (PST) X-Received: by 10.50.142.106 with SMTP id rv10mr3185752igb.18.1423740079095; Thu, 12 Feb 2015 03:21:19 -0800 (PST) Received: from lists.sourceforge.net (lists.sourceforge.net. [216.34.181.88]) by mx.google.com with ESMTPS id 80si1478346iok.46.2015.02.12.03.21.18 (version=TLSv1 cipher=RC4-SHA bits=128/128); Thu, 12 Feb 2015 03:21:19 -0800 (PST) Received-SPF: pass (google.com: domain of edk2-devel-bounces@lists.sourceforge.net designates 216.34.181.88 as permitted sender) client-ip=216.34.181.88; Received: from localhost ([127.0.0.1] helo=sfs-ml-3.v29.ch3.sourceforge.com) by sfs-ml-3.v29.ch3.sourceforge.com with esmtp (Exim 4.76) (envelope-from ) id 1YLrpX-0000vB-1M; Thu, 12 Feb 2015 11:21:11 +0000 Received: from sog-mx-1.v43.ch3.sourceforge.com ([172.29.43.191] helo=mx.sourceforge.net) by sfs-ml-3.v29.ch3.sourceforge.com with esmtp (Exim 4.76) (envelope-from ) id 1YLrpS-0000uF-Ru for edk2-devel@lists.sourceforge.net; Thu, 12 Feb 2015 11:21:06 +0000 Received-SPF: pass (sog-mx-1.v43.ch3.sourceforge.com: domain of linaro.org designates 209.85.220.48 as permitted sender) client-ip=209.85.220.48; envelope-from=ard.biesheuvel@linaro.org; helo=mail-pa0-f48.google.com; Received: from mail-pa0-f48.google.com ([209.85.220.48]) by sog-mx-1.v43.ch3.sourceforge.com with esmtps (TLSv1:RC4-SHA:128) (Exim 4.76) id 1YLrpQ-0006sz-7d for edk2-devel@lists.sourceforge.net; Thu, 12 Feb 2015 11:21:06 +0000 Received: by mail-pa0-f48.google.com with SMTP id eu11so10823362pac.7 for ; Thu, 12 Feb 2015 03:20:58 -0800 (PST) X-Received: by 10.70.88.105 with SMTP id bf9mr5483613pdb.77.1423740058522; Thu, 12 Feb 2015 03:20:58 -0800 (PST) Received: from ards-macbook-pro.local ([210.177.145.249]) by mx.google.com with ESMTPSA id n4sm3554887pdl.12.2015.02.12.03.20.55 (version=TLSv1.1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Thu, 12 Feb 2015 03:20:57 -0800 (PST) From: Ard Biesheuvel To: edk2-devel@lists.sourceforge.net, olivier.martin@arm.com, lersek@redhat.com, roy.franz@linaro.org, leif.lindholm@linaro.org, stefano.stabellini@eu.citrix.com, ian.campbell@citrix.com, anthony.perard@citrix.com, xen-devel@lists.xen.org, julien.grall@linaro.org, jordan.l.justen@intel.com, michael.d.kinney@intel.com, feng.tian@intel.com Date: Thu, 12 Feb 2015 19:19:12 +0800 Message-Id: <1423739961-5945-21-git-send-email-ard.biesheuvel@linaro.org> X-Mailer: git-send-email 1.8.3.2 In-Reply-To: <1423739961-5945-1-git-send-email-ard.biesheuvel@linaro.org> References: <1423739961-5945-1-git-send-email-ard.biesheuvel@linaro.org> X-Spam-Score: -1.5 (-) X-Spam-Report: Spam Filtering performed by mx.sourceforge.net. See http://spamassassin.org/tag/ for more details. -1.5 SPF_CHECK_PASS SPF reports sender host as permitted sender for sender-domain -0.0 SPF_PASS SPF: sender matches SPF record X-Headers-End: 1YLrpQ-0006sz-7d Subject: [edk2] [PATCH v4 20/29] Ovmf/Xen: add separate driver for Xen PCI device X-BeenThere: edk2-devel@lists.sourceforge.net X-Mailman-Version: 2.1.9 Precedence: list Reply-To: edk2-devel@lists.sourceforge.net List-Id: List-Unsubscribe: , List-Archive: List-Post: , List-Help: , List-Subscribe: , MIME-Version: 1.0 Errors-To: edk2-devel-bounces@lists.sourceforge.net X-Removed-Original-Auth: Dkim didn't pass. X-Original-Sender: ard.biesheuvel@linaro.org X-Original-Authentication-Results: mx.google.com; spf=pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.217.177 as permitted sender) smtp.mail=patch+caf_=patchwork-forward=linaro.org@linaro.org Mailing-list: list patchwork-forward@linaro.org; contact patchwork-forward+owners@linaro.org X-Google-Group-Id: 836684582541 Prepare for making XenBusDxe suitable for use with non-PCI devices (such as the DT node exposed by Xen on ARM) by introducing a separate DXE driver that binds to the Xen virtual PCI device and exposes the abstract XENIO_PROTOCOL for XenBusDxe to bind against. Contributed-under: TianoCore Contribution Agreement 1.0 Reviewed-by: Laszlo Ersek Signed-off-by: Ard Biesheuvel --- OvmfPkg/XenIoPciDxe/XenIoPciDxe.c | 367 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ OvmfPkg/XenIoPciDxe/XenIoPciDxe.inf | 45 +++++++++++++++++ 2 files changed, 412 insertions(+) diff --git a/OvmfPkg/XenIoPciDxe/XenIoPciDxe.c b/OvmfPkg/XenIoPciDxe/XenIoPciDxe.c new file mode 100644 index 000000000000..c205cf74db34 --- /dev/null +++ b/OvmfPkg/XenIoPciDxe/XenIoPciDxe.c @@ -0,0 +1,367 @@ +/** @file + + Driver for the virtual Xen PCI device + + Copyright (C) 2012, Red Hat, Inc. + Copyright (c) 2012, Intel Corporation. All rights reserved.
+ Copyright (C) 2013, ARM Ltd. + Copyright (C) 2015, Linaro Ltd. + + 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 +#include +#include +#include +#include +#include +#include + +#include +#include + +#define PCI_VENDOR_ID_XEN 0x5853 +#define PCI_DEVICE_ID_XEN_PLATFORM 0x0001 + +/** + + Device probe function for this driver. + + The DXE core calls this function for any given device in order to see if the + driver can drive the device. + + @param[in] This The EFI_DRIVER_BINDING_PROTOCOL object + incorporating this driver (independently of + any device). + + @param[in] DeviceHandle The device to probe. + + @param[in] RemainingDevicePath Relevant only for bus drivers, ignored. + + + @retval EFI_SUCCESS The driver supports the device being probed. + + @retval EFI_UNSUPPORTED The driver does not support the device being probed. + + @return Error codes from the OpenProtocol() boot service or + the PciIo protocol. + +**/ +STATIC +EFI_STATUS +EFIAPI +XenIoPciDeviceBindingSupported ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE DeviceHandle, + IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath + ) +{ + EFI_STATUS Status; + EFI_PCI_IO_PROTOCOL *PciIo; + PCI_TYPE00 Pci; + + // + // Attempt to open the device with the PciIo set of interfaces. On success, + // the protocol is "instantiated" for the PCI device. Covers duplicate open + // attempts (EFI_ALREADY_STARTED). + // + Status = gBS->OpenProtocol ( + DeviceHandle, // candidate device + &gEfiPciIoProtocolGuid, // for generic PCI access + (VOID **)&PciIo, // handle to instantiate + This->DriverBindingHandle, // requestor driver identity + DeviceHandle, // ControllerHandle, according to + // the UEFI Driver Model + EFI_OPEN_PROTOCOL_BY_DRIVER // get exclusive PciIo access to + // the device; to be released + ); + if (EFI_ERROR (Status)) { + return Status; + } + + // + // Read entire PCI configuration header for more extensive check ahead. + // + Status = PciIo->Pci.Read ( + PciIo, // (protocol, device) + // handle + EfiPciIoWidthUint32, // access width & copy + // mode + 0, // Offset + sizeof Pci / sizeof (UINT32), // Count + &Pci // target buffer + ); + + if (Status == EFI_SUCCESS) { + if ((Pci.Hdr.VendorId == PCI_VENDOR_ID_XEN) && + (Pci.Hdr.DeviceId == PCI_DEVICE_ID_XEN_PLATFORM)) { + Status = EFI_SUCCESS; + } else { + Status = EFI_UNSUPPORTED; + } + } + + // + // We needed PCI IO access only transitorily, to see whether we support the + // device or not. + // + gBS->CloseProtocol (DeviceHandle, &gEfiPciIoProtocolGuid, + This->DriverBindingHandle, DeviceHandle); + + return Status; +} + +/** + + After we've pronounced support for a specific device in + DriverBindingSupported(), we start managing said device (passed in by the + Driver Exeuction Environment) with the following service. + + See DriverBindingSupported() for specification references. + + @param[in] This The EFI_DRIVER_BINDING_PROTOCOL object + incorporating this driver (independently of + any device). + + @param[in] DeviceHandle The supported device to drive. + + @param[in] RemainingDevicePath Relevant only for bus drivers, ignored. + + + @retval EFI_SUCCESS The device was started. + + @retval EFI_OUT_OF_RESOURCES Memory allocation failed. + + @return Error codes from the OpenProtocol() boot + service, the PciIo protocol or the + InstallProtocolInterface() boot service. + +**/ +STATIC +EFI_STATUS +EFIAPI +XenIoPciDeviceBindingStart ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE DeviceHandle, + IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath + ) +{ + EFI_STATUS Status; + XENIO_PROTOCOL *XenIo; + EFI_PCI_IO_PROTOCOL *PciIo; + EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *BarDesc; + + XenIo = (XENIO_PROTOCOL *) AllocateZeroPool (sizeof *XenIo); + if (XenIo == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + Status = gBS->OpenProtocol (DeviceHandle, &gEfiPciIoProtocolGuid, + (VOID **)&PciIo, This->DriverBindingHandle, + DeviceHandle, EFI_OPEN_PROTOCOL_BY_DRIVER); + if (EFI_ERROR (Status)) { + goto FreeXenIo; + } + + // + // The BAR1 of this PCI device is used for shared memory and is supposed to + // look like MMIO. The address space of the BAR1 will be used to map the + // Grant Table. + // + Status = PciIo->GetBarAttributes (PciIo, PCI_BAR_IDX1, NULL, (VOID**) &BarDesc); + ASSERT_EFI_ERROR (Status); + ASSERT (BarDesc->ResType == ACPI_ADDRESS_SPACE_TYPE_MEM); + + /* Get a Memory address for mapping the Grant Table. */ + DEBUG ((EFI_D_INFO, "XenIoPci: BAR at %LX\n", BarDesc->AddrRangeMin)); + XenIo->GrantTableAddress = BarDesc->AddrRangeMin; + FreePool (BarDesc); + + Status = gBS->InstallProtocolInterface (&DeviceHandle, + &gXenIoProtocolGuid, EFI_NATIVE_INTERFACE, XenIo); + + if (!EFI_ERROR (Status)) { + return EFI_SUCCESS; + } + + gBS->CloseProtocol (DeviceHandle, &gEfiPciIoProtocolGuid, + This->DriverBindingHandle, DeviceHandle); + +FreeXenIo: + FreePool (XenIo); + + return Status; +} + +/** + + Stop driving the XenIo PCI device + + @param[in] This The EFI_DRIVER_BINDING_PROTOCOL object + incorporating this driver (independently of any + device). + + @param[in] DeviceHandle Stop driving this device. + + @param[in] NumberOfChildren Since this function belongs to a device driver + only (as opposed to a bus driver), the caller + environment sets NumberOfChildren to zero, and + we ignore it. + + @param[in] ChildHandleBuffer Ignored (corresponding to NumberOfChildren). + + @retval EFI_SUCCESS Driver instance has been stopped and the PCI + configuration attributes have been restored. + + @return Error codes from the OpenProtocol() or + CloseProtocol(), UninstallProtocolInterface() + boot services. + +**/ +STATIC +EFI_STATUS +EFIAPI +XenIoPciDeviceBindingStop ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE DeviceHandle, + IN UINTN NumberOfChildren, + IN EFI_HANDLE *ChildHandleBuffer + ) +{ + EFI_STATUS Status; + XENIO_PROTOCOL *XenIo; + + Status = gBS->OpenProtocol ( + DeviceHandle, // candidate device + &gXenIoProtocolGuid, // retrieve the XenIo iface + (VOID **)&XenIo, // target pointer + This->DriverBindingHandle, // requestor driver identity + DeviceHandle, // requesting lookup for dev. + EFI_OPEN_PROTOCOL_GET_PROTOCOL // lookup only, no ref. added + ); + if (EFI_ERROR (Status)) { + return Status; + } + + // + // Handle Stop() requests for in-use driver instances gracefully. + // + Status = gBS->UninstallProtocolInterface (DeviceHandle, + &gXenIoProtocolGuid, XenIo); + if (EFI_ERROR (Status)) { + return Status; + } + + Status = gBS->CloseProtocol (DeviceHandle, &gEfiPciIoProtocolGuid, + This->DriverBindingHandle, DeviceHandle); + + FreePool (XenIo); + + return Status; +} + + +// +// The static object that groups the Supported() (ie. probe), Start() and +// Stop() functions of the driver together. Refer to UEFI Spec 2.3.1 + Errata +// C, 10.1 EFI Driver Binding Protocol. +// +STATIC EFI_DRIVER_BINDING_PROTOCOL gDriverBinding = { + &XenIoPciDeviceBindingSupported, + &XenIoPciDeviceBindingStart, + &XenIoPciDeviceBindingStop, + 0x10, // Version, must be in [0x10 .. 0xFFFFFFEF] for IHV-developed drivers + NULL, // ImageHandle, to be overwritten by + // EfiLibInstallDriverBindingComponentName2() in XenIoPciDeviceEntryPoint() + NULL // DriverBindingHandle, ditto +}; + + +// +// The purpose of the following scaffolding (EFI_COMPONENT_NAME_PROTOCOL and +// EFI_COMPONENT_NAME2_PROTOCOL implementation) is to format the driver's name +// in English, for display on standard console devices. This is recommended for +// UEFI drivers that follow the UEFI Driver Model. Refer to the Driver Writer's +// Guide for UEFI 2.3.1 v1.01, 11 UEFI Driver and Controller Names. +// +STATIC +EFI_UNICODE_STRING_TABLE mDriverNameTable[] = { + { "eng;en", L"XenIo PCI Driver" }, + { NULL, NULL } +}; + +STATIC +EFI_COMPONENT_NAME_PROTOCOL gComponentName; + +EFI_STATUS +EFIAPI +XenIoPciGetDriverName ( + IN EFI_COMPONENT_NAME_PROTOCOL *This, + IN CHAR8 *Language, + OUT CHAR16 **DriverName + ) +{ + return LookupUnicodeString2 ( + Language, + This->SupportedLanguages, + mDriverNameTable, + DriverName, + (BOOLEAN)(This == &gComponentName) // Iso639Language + ); +} + +EFI_STATUS +EFIAPI +XenIoPciGetDeviceName ( + IN EFI_COMPONENT_NAME_PROTOCOL *This, + IN EFI_HANDLE DeviceHandle, + IN EFI_HANDLE ChildHandle, + IN CHAR8 *Language, + OUT CHAR16 **ControllerName + ) +{ + return EFI_UNSUPPORTED; +} + +STATIC +EFI_COMPONENT_NAME_PROTOCOL gComponentName = { + &XenIoPciGetDriverName, + &XenIoPciGetDeviceName, + "eng" // SupportedLanguages, ISO 639-2 language codes +}; + +STATIC +EFI_COMPONENT_NAME2_PROTOCOL gComponentName2 = { + (EFI_COMPONENT_NAME2_GET_DRIVER_NAME) &XenIoPciGetDriverName, + (EFI_COMPONENT_NAME2_GET_CONTROLLER_NAME) &XenIoPciGetDeviceName, + "en" // SupportedLanguages, RFC 4646 language codes +}; + + +// +// Entry point of this driver. +// +EFI_STATUS +EFIAPI +XenIoPciDeviceEntryPoint ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + return EfiLibInstallDriverBindingComponentName2 ( + ImageHandle, + SystemTable, + &gDriverBinding, + ImageHandle, + &gComponentName, + &gComponentName2 + ); +} diff --git a/OvmfPkg/XenIoPciDxe/XenIoPciDxe.inf b/OvmfPkg/XenIoPciDxe/XenIoPciDxe.inf new file mode 100644 index 000000000000..b32075a38163 --- /dev/null +++ b/OvmfPkg/XenIoPciDxe/XenIoPciDxe.inf @@ -0,0 +1,45 @@ +## @file +# Driver for the virtual Xen PCI device +# +# Copyright (C) 2015, Linaro Ltd. +# +# 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. +# +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = XenIoPciDxe + FILE_GUID = cf569f50-de44-4f54-b4d7-f4ae25cda599 + MODULE_TYPE = UEFI_DRIVER + VERSION_STRING = 1.0 + ENTRY_POINT = XenIoPciDeviceEntryPoint + +[Packages] + MdePkg/MdePkg.dec + OvmfPkg/OvmfPkg.dec + +[Sources] + XenIoPciDxe.c + +[LibraryClasses] + UefiDriverEntryPoint + UefiBootServicesTableLib + MemoryAllocationLib + BaseMemoryLib + BaseLib + UefiLib + DebugLib + +[Protocols] + gEfiDriverBindingProtocolGuid + gEfiPciIoProtocolGuid + gEfiComponentName2ProtocolGuid + gEfiComponentNameProtocolGuid + gXenIoProtocolGuid