From patchwork Sat Jul 22 22:15:40 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Aleksandr Bezzubikov X-Patchwork-Id: 9858247 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 838A3601C0 for ; Sat, 22 Jul 2017 22:17:23 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 76FE72850E for ; Sat, 22 Jul 2017 22:17:23 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 6ACD428512; Sat, 22 Jul 2017 22:17:23 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.8 required=2.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED, DKIM_SIGNED, FREEMAIL_FROM, RCVD_IN_DNSWL_HI, T_DKIM_INVALID autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id DD2162850E for ; Sat, 22 Jul 2017 22:17:22 +0000 (UTC) Received: from localhost ([::1]:48511 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dZ2iA-0003M0-2R for patchwork-qemu-devel@patchwork.kernel.org; Sat, 22 Jul 2017 18:17:22 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:60337) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dZ2gv-0003Ib-Vp for qemu-devel@nongnu.org; Sat, 22 Jul 2017 18:16:07 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1dZ2gu-0008JX-QN for qemu-devel@nongnu.org; Sat, 22 Jul 2017 18:16:05 -0400 Received: from mail-lf0-x242.google.com ([2a00:1450:4010:c07::242]:33834) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1dZ2gu-0008Id-Eg for qemu-devel@nongnu.org; Sat, 22 Jul 2017 18:16:04 -0400 Received: by mail-lf0-x242.google.com with SMTP id p11so5151583lfd.1 for ; Sat, 22 Jul 2017 15:16:04 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=rIBS7YdoDjtW2bJ3l1aFA9YuYSMk+NiXjDEoUSvWLyE=; b=nPDUIfnp8uZMflSIXaMWM3IMUOsDM+Lk+9csoI17WOQ6DRJq8rHbTN+YH9DXU+mYQE iDiuzacX/pXIVq0x+NVY5uXm4G9K5tdqYfVcQLmarF00qU5AaIOrXBdb+1/fGU1WwdIr qQNlZ+7e0Ou91Fh0pcM6QFTo7TzeZa6mDLsYxPvqzPrfktCVlc5iDeqfI3TE6n00r8e/ 6gQaJtWDTV4P00mER/QaU4gFDrwNVca3/Pk4KHs4mTB0J9T9fNGepUqja9Q4enG7CJcp KzNxflLdBuqoiK0fSj77n9pFHVlzD54UU8+1cMt5UJYsP97W6otWBhaJl/buWbgO34Vm YYtg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=rIBS7YdoDjtW2bJ3l1aFA9YuYSMk+NiXjDEoUSvWLyE=; b=chndeh3/BANxudSHe6aSYxKwwsnTxjJcwHE/bCL9G1OCraEAbbq2XPTcsIUkhhVAlt /SSOP7hZtvLVy6sEML/SVWu9XLnxifkpyR1E8b0I9A7hJTAaJkSHGeucr7qT8PELqDTU 0jeBJwYn6iCnos8c0npmm83I7W2oHotb80L9BEBWDau11xSRjBNoxG3AZHrHyRn25mpx 3PaxZbLPc+GXifIPHnyg/zAdGrvsJ5Q0K5pDvD1MG40beQhEXbEpV6e3V6c/djNp8lfd nDvZPGsJtugJaXSxjpfNikI1fkICF8WBiq68Pn0ecLd7+hjD5/6VC1FhSjwCVR5Q4Q5R FIwg== X-Gm-Message-State: AIVw1129d8Cjo6rQGE630OR5H31HzqWXuWuoGdCiPnOBd3Nn8tP1LSla i0B7fTTjTQiFaLE9CRM= X-Received: by 10.25.151.19 with SMTP id z19mr101822lfd.134.1500761762557; Sat, 22 Jul 2017 15:16:02 -0700 (PDT) Received: from localhost.localdomain (broadband-178-140-16-138.moscow.rt.ru. [178.140.16.138]) by smtp.gmail.com with ESMTPSA id t10sm757832lja.47.2017.07.22.15.16.01 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Sat, 22 Jul 2017 15:16:01 -0700 (PDT) From: Aleksandr Bezzubikov To: qemu-devel@nongnu.org Date: Sun, 23 Jul 2017 01:15:40 +0300 Message-Id: <1500761743-1669-4-git-send-email-zuban32s@gmail.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1500761743-1669-1-git-send-email-zuban32s@gmail.com> References: <1500761743-1669-1-git-send-email-zuban32s@gmail.com> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2a00:1450:4010:c07::242 Subject: [Qemu-devel] [RFC PATCH v2 3/6] hw/pci: enable SHPC for PCIE-PCI bridge X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: ehabkost@redhat.com, mst@redhat.com, seabios@seabios.org, Aleksandr Bezzubikov , kraxel@redhat.com, pbonzini@redhat.com, marcel@redhat.com, imammedo@redhat.com, rth@twiddle.net Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP Signed-off-by: Aleksandr Bezzubikov --- hw/pci-bridge/pcie_pci_bridge.c | 63 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 62 insertions(+), 1 deletion(-) diff --git a/hw/pci-bridge/pcie_pci_bridge.c b/hw/pci-bridge/pcie_pci_bridge.c index 0991a7b..38f665f 100644 --- a/hw/pci-bridge/pcie_pci_bridge.c +++ b/hw/pci-bridge/pcie_pci_bridge.c @@ -28,6 +28,7 @@ #include "hw/pci/pci_bus.h" #include "hw/pci/pci_bridge.h" #include "hw/pci/msi.h" +#include "hw/pci/shpc.h" #include "hw/pci/slotid_cap.h" typedef struct PCIEPCIBridge { @@ -35,6 +36,7 @@ typedef struct PCIEPCIBridge { PCIBridge parent_obj; uint32_t flags; + MemoryRegion bar; /*< public >*/ } PCIEPCIBridge; @@ -44,11 +46,22 @@ typedef struct PCIEPCIBridge { static void pciepci_bridge_realize(PCIDevice *d, Error **errp) { + PCIBridge *br = PCI_BRIDGE(d); + PCIEPCIBridge *bridge_dev = PCIE_PCI_BRIDGE_DEV(d); int rc, pos; Error *local_err = NULL; pci_bridge_initfn(d, TYPE_PCI_BUS); + d->config[PCI_INTERRUPT_PIN] = 0x1; + memory_region_init(&bridge_dev->bar, OBJECT(d), "shpc-bar", + shpc_bar_size(d)); + rc = shpc_init(d, &br->sec_bus, &bridge_dev->bar, 0, &local_err); + if (rc) { + error_propagate(errp, local_err); + goto error; + } + rc = pcie_cap_init(d, 0, PCI_EXP_TYPE_PCI_BRIDGE, 0, &local_err); if (rc < 0) { error_propagate(errp, local_err); @@ -78,6 +91,9 @@ static void pciepci_bridge_realize(PCIDevice *d, Error **errp) goto error; } + pci_register_bar(d, 0, PCI_BASE_ADDRESS_SPACE_MEMORY | + PCI_BASE_ADDRESS_MEM_TYPE_64, &bridge_dev->bar); + return; error: @@ -86,7 +102,9 @@ static void pciepci_bridge_realize(PCIDevice *d, Error **errp) static void pciepci_bridge_exit(PCIDevice *d) { + PCIEPCIBridge *bridge_dev = PCIE_PCI_BRIDGE_DEV(d); pcie_cap_exit(d); + shpc_cleanup(d, &bridge_dev->bar); pci_bridge_exitfn(d); } @@ -95,6 +113,7 @@ static void pciepci_bridge_reset(DeviceState *qdev) PCIDevice *d = PCI_DEVICE(qdev); pci_bridge_reset(qdev); msi_reset(d); + shpc_reset(d); } static void pcie_pci_bridge_write_config(PCIDevice *d, @@ -102,8 +121,15 @@ static void pcie_pci_bridge_write_config(PCIDevice *d, { pci_bridge_write_config(d, address, val, len); msi_write_config(d, address, val, len); + shpc_cap_write_config(d, address, val, len); } +static bool pci_device_shpc_present(void *opaque, int version_id) +{ + PCIDevice *dev = opaque; + + return shpc_present(dev); +} static Property pcie_pci_bridge_dev_properties[] = { DEFINE_PROP_END_OF_LIST(), @@ -113,14 +139,43 @@ static const VMStateDescription pciepci_bridge_dev_vmstate = { .name = TYPE_PCIE_PCI_BRIDGE_DEV, .fields = (VMStateField[]) { VMSTATE_PCI_DEVICE(parent_obj, PCIBridge), + SHPC_VMSTATE(shpc, PCIDevice, pci_device_shpc_present), VMSTATE_END_OF_LIST() } }; +static void pcie_pci_bridge_hotplug_cb(HotplugHandler *hotplug_dev, + DeviceState *dev, Error **errp) +{ + PCIDevice *pci_hotplug_dev = PCI_DEVICE(hotplug_dev); + + if (!shpc_present(pci_hotplug_dev)) { + error_setg(errp, "standard hotplug controller has been disabled for " + "this %s", TYPE_PCIE_PCI_BRIDGE_DEV); + return; + } + shpc_device_hotplug_cb(hotplug_dev, dev, errp); +} + +static void pcie_pci_bridge_hot_unplug_request_cb(HotplugHandler *hotplug_dev, + DeviceState *dev, + Error **errp) +{ + PCIDevice *pci_hotplug_dev = PCI_DEVICE(hotplug_dev); + + if (!shpc_present(pci_hotplug_dev)) { + error_setg(errp, "standard hotplug controller has been disabled for " + "this %s", TYPE_PCIE_PCI_BRIDGE_DEV); + return; + } + shpc_device_hot_unplug_request_cb(hotplug_dev, dev, errp); +} + static void pciepci_bridge_class_init(ObjectClass *klass, void *data) { PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); DeviceClass *dc = DEVICE_CLASS(klass); + HotplugHandlerClass *hc = HOTPLUG_HANDLER_CLASS(klass); k->is_express = 1; k->is_bridge = 1; @@ -134,13 +189,19 @@ static void pciepci_bridge_class_init(ObjectClass *klass, void *data) dc->vmsd = &pciepci_bridge_dev_vmstate; dc->reset = &pciepci_bridge_reset; set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories); + hc->plug = pcie_pci_bridge_hotplug_cb; + hc->unplug_request = pcie_pci_bridge_hot_unplug_request_cb; } static const TypeInfo pciepci_bridge_info = { .name = TYPE_PCIE_PCI_BRIDGE_DEV, .parent = TYPE_PCI_BRIDGE, .instance_size = sizeof(PCIEPCIBridge), - .class_init = pciepci_bridge_class_init + .class_init = pciepci_bridge_class_init, + .interfaces = (InterfaceInfo[]) { + { TYPE_HOTPLUG_HANDLER }, + { }, + } }; static void pciepci_register(void)