From patchwork Tue Feb 24 18:03:01 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ard Biesheuvel X-Patchwork-Id: 44986 Return-Path: X-Original-To: linaro@patches.linaro.org Delivered-To: linaro@patches.linaro.org Received: from mail-la0-f70.google.com (mail-la0-f70.google.com [209.85.215.70]) by ip-10-151-82-157.ec2.internal (Postfix) with ESMTPS id EBE7F2029F for ; Tue, 24 Feb 2015 18:07:14 +0000 (UTC) Received: by labge10 with SMTP id ge10sf18359331lab.3 for ; Tue, 24 Feb 2015 10:07:13 -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:cc:subject:precedence:list-id:list-unsubscribe:list-post :list-help:list-subscribe:mime-version:content-type :content-transfer-encoding:sender:errors-to:x-original-sender :x-original-authentication-results:mailing-list:list-archive; bh=ezOH+ki2b2DvMvlbF+sqGKU+An3z+ttUfTzWFcBnQxM=; b=W7IeNYOV3YYNHRKsHVL/PDL1a3RynVQFBsspfcq5jeoSCOZ7YI7+gwNXyXzTVwz8/w ULY+CeFdBBi9ceW5Vb8otrzi1RrCS8/n6Viio/SGxpEKX+4g26WYcmGZAHGcvU2wnGEd zBD8i8omv1Xfh9AIHKG/Zvn4Cgw7sUlMW0yurfH7Oj4yuiAhydg8aowUXKtmkUbH7Gda +MyLkZoxDOjfqkQQmleoKGdrXuk+cVYlp7f4AG5veWdkEYXSwJ76scjtodPBXVtGbyT3 Vbble2nUKYyl8PU9Q5+WlTc2vPG6Brq+WUHOSiuCe2G5u1RxGOy2PrEp254rSsPjLD+Z amdw== X-Gm-Message-State: ALoCoQmB2N7T9rhNT10kOP2xuIAiWJTmI33hPoAKcUK7n3E82/Rg0riHVn8HTWf7hRklpD9L1ujk X-Received: by 10.180.182.44 with SMTP id eb12mr2306223wic.4.1424801233888; Tue, 24 Feb 2015 10:07:13 -0800 (PST) X-BeenThere: patchwork-forward@linaro.org Received: by 10.152.8.169 with SMTP id s9ls193026laa.8.gmail; Tue, 24 Feb 2015 10:07:13 -0800 (PST) X-Received: by 10.152.10.98 with SMTP id h2mr15347394lab.18.1424801233607; Tue, 24 Feb 2015 10:07:13 -0800 (PST) Received: from mail-la0-f46.google.com (mail-la0-f46.google.com. [209.85.215.46]) by mx.google.com with ESMTPS id lg3si4600729lab.40.2015.02.24.10.07.13 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 24 Feb 2015 10:07:13 -0800 (PST) Received-SPF: pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.215.46 as permitted sender) client-ip=209.85.215.46; Received: by labhs14 with SMTP id hs14so4872054lab.4 for ; Tue, 24 Feb 2015 10:07:13 -0800 (PST) X-Received: by 10.152.87.3 with SMTP id t3mr15542561laz.19.1424801233441; Tue, 24 Feb 2015 10:07:13 -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 h5csp2079741lbj; Tue, 24 Feb 2015 10:07:12 -0800 (PST) X-Received: by 10.236.63.1 with SMTP id z1mr15408339yhc.142.1424801231347; Tue, 24 Feb 2015 10:07:11 -0800 (PST) Received: from lists.xen.org (lists.xen.org. [50.57.142.19]) by mx.google.com with ESMTPS id y16si10475522qab.48.2015.02.24.10.07.10 (version=TLSv1 cipher=RC4-SHA bits=128/128); Tue, 24 Feb 2015 10:07:11 -0800 (PST) Received-SPF: none (google.com: xen-devel-bounces@lists.xen.org does not designate permitted sender hosts) client-ip=50.57.142.19; Received: from localhost ([127.0.0.1] helo=lists.xen.org) by lists.xen.org with esmtp (Exim 4.72) (envelope-from ) id 1YQJrO-00032l-KE; Tue, 24 Feb 2015 18:05:30 +0000 Received: from mail6.bemta4.messagelabs.com ([85.158.143.247]) by lists.xen.org with esmtp (Exim 4.72) (envelope-from ) id 1YQJrM-0002yu-FB for xen-devel@lists.xen.org; Tue, 24 Feb 2015 18:05:28 +0000 Received: from [85.158.143.35] by server-1.bemta-4.messagelabs.com id DB/BC-03004-76DBCE45; Tue, 24 Feb 2015 18:05:27 +0000 X-Env-Sender: ard.biesheuvel@linaro.org X-Msg-Ref: server-8.tower-21.messagelabs.com!1424801125!12872940!1 X-Originating-IP: [74.125.82.50] X-SpamReason: No, hits=0.0 required=7.0 tests=UPPERCASE_25_50 X-StarScan-Received: X-StarScan-Version: 6.13.4; banners=-,-,- X-VirusChecked: Checked Received: (qmail 17926 invoked from network); 24 Feb 2015 18:05:26 -0000 Received: from mail-wg0-f50.google.com (HELO mail-wg0-f50.google.com) (74.125.82.50) by server-8.tower-21.messagelabs.com with RC4-SHA encrypted SMTP; 24 Feb 2015 18:05:26 -0000 Received: by wggy19 with SMTP id y19so6995612wgg.10 for ; Tue, 24 Feb 2015 10:05:25 -0800 (PST) X-Received: by 10.194.90.210 with SMTP id by18mr33873716wjb.80.1424801125783; Tue, 24 Feb 2015 10:05:25 -0800 (PST) Received: from ards-macbook-pro.lan (bl11-65-113.dsl.telepac.pt. [85.244.65.113]) by mx.google.com with ESMTPSA id w8sm12792521wja.4.2015.02.24.10.05.21 (version=TLSv1.1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Tue, 24 Feb 2015 10:05:23 -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 Date: Tue, 24 Feb 2015 18:03:01 +0000 Message-Id: <1424800990-15777-21-git-send-email-ard.biesheuvel@linaro.org> X-Mailer: git-send-email 1.8.3.2 In-Reply-To: <1424800990-15777-1-git-send-email-ard.biesheuvel@linaro.org> References: <1424800990-15777-1-git-send-email-ard.biesheuvel@linaro.org> Cc: wei.liu2@citrix.com, Ard Biesheuvel Subject: [Xen-devel] [PATCH v5 20/29] Ovmf/Xen: add separate driver for Xen PCI device X-BeenThere: xen-devel@lists.xen.org X-Mailman-Version: 2.1.13 Precedence: list List-Id: List-Unsubscribe: , List-Post: , List-Help: , List-Subscribe: , MIME-Version: 1.0 Sender: xen-devel-bounces@lists.xen.org Errors-To: xen-devel-bounces@lists.xen.org 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.215.46 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 List-Archive: 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 Reviewed-by: Anthony PERARD Signed-off-by: Ard Biesheuvel --- OvmfPkg/XenIoPciDxe/XenIoPciDxe.c | 367 ++++++++++++++++++++++++++++++++++++ OvmfPkg/XenIoPciDxe/XenIoPciDxe.inf | 45 +++++ 2 files changed, 412 insertions(+) create mode 100644 OvmfPkg/XenIoPciDxe/XenIoPciDxe.c create mode 100644 OvmfPkg/XenIoPciDxe/XenIoPciDxe.inf 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