From patchwork Thu May 6 15:31:52 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: =?utf-8?q?Pali_Roh=C3=A1r?= X-Patchwork-Id: 12242661 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-17.7 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,INCLUDES_CR_TRAILER,INCLUDES_PATCH,MAILING_LIST_MULTI, SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 621D9C433ED for ; Thu, 6 May 2021 16:03:36 +0000 (UTC) Received: from desiato.infradead.org (desiato.infradead.org [90.155.92.199]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id EF34E61078 for ; Thu, 6 May 2021 16:03:35 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org EF34E61078 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=kernel.org Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=desiato.20200630; h=Sender:Content-Transfer-Encoding :Content-Type:List-Subscribe:List-Help:List-Post:List-Archive: List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To:Message-Id:Date: Subject:Cc:To:From:Reply-To:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=+bW1T7SP9EYJiKyuQ5QW/55i9SMAJUBWKhfVzJh3WM4=; b=obcEqf4nFqvpMrhdtnqnoV2ho RYcjPSjBWIM4NfbOWUmoRzymPM9vveDvKCQmSXK21aZqieh21aDWtBi4e82JFX54FZG/U4hHrqORF DawAiPAFjuKZ9Kbl57NnjZAyeR8K9pdtRUDkeyn1idxJpRS2qCq4ptvOnX/r31L20JwmTNHDregDc br71x/lQdc2W1XPpgL/bfQZIbLavxc2KGDKIMw5hTqaILPd7wEqOMjDVaYoKzulh4G16hsDzgNjte SgT/i+/3XN9ShQF4qgGsR2KAJHlSoVQvGxIe93voHFG/9oSP0nkbIlVJSVYS+OEcWWFLNarbCWTE/ SFCjZ/qrg==; Received: from localhost ([::1] helo=desiato.infradead.org) by desiato.infradead.org with esmtp (Exim 4.94 #2 (Red Hat Linux)) id 1legHI-004g1U-M2; Thu, 06 May 2021 15:51:04 +0000 Received: from bombadil.infradead.org ([2607:7c80:54:e::133]) by desiato.infradead.org with esmtps (Exim 4.94 #2 (Red Hat Linux)) id 1lefzs-004a7F-OD for linux-arm-kernel@desiato.infradead.org; Thu, 06 May 2021 15:33:04 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=bombadil.20210309; h=Content-Transfer-Encoding: MIME-Version:References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From:Sender :Reply-To:Content-Type:Content-ID:Content-Description; bh=rVsyvk/wDz+Qse+xC55/mo9JAyVxLTxGMY+/XCFso9c=; b=Mv43crVTlhMQdHW66sNiuIkzT8 6H+8RM5JoXlCPKchNWYmUCzTKwIToLTGARmFtdFqRslsZnC0S1b/yddZFQOWpafBZohamzE2oNWXK dbMMPnstvq0RrbLZhN2GFxpODkl51dbGKdcw8O/0+Wj9OCETjzoWViZtymf7JbECScIcmDft1v2IX yb1cdp21r4vzk0WQpRk2UT3nHcPSDOImQo0heq4VWDhY+uF8wexPwddtglaRwP8J/6kxRSFpnEz2c V/r1L0o4ngVmnSp1JyucLb/Hg5n2VOn7MboLXfAJYahGNhM6WTHuPuREvW39YoXEW156QFI3tgWl6 iXM5Oiow==; Received: from mail.kernel.org ([198.145.29.99]) by bombadil.infradead.org with esmtps (Exim 4.94 #2 (Red Hat Linux)) id 1lefzn-0069hi-Pc for linux-arm-kernel@lists.infradead.org; Thu, 06 May 2021 15:33:04 +0000 Received: by mail.kernel.org (Postfix) with ESMTPSA id 35EFD61919; Thu, 6 May 2021 15:32:56 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1620315176; bh=hjo0BAh8/TrXrQZkushaXu4N5LMhaWkVsVmV1/6ftDk=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=Dh1vhcJJYtbozzm9tYZuMVr3xW2todeA5yDuns656iomD3BgScMh9g4Cp5PbUmw38 7jbsRgj7iDlnpJ75OQ43qkrEbI7VgBraSEINnbkvhN3orBjYsjqhLStfl7yt4g3tXT 9zP6un2sviaI6VU/eWUEqoL2WC0nF8dlVgjEyc1eWrEdhCbPMqw9wfq/0yrJjm1zWJ mMZ2ytRlFECFuKySVamBgQdcWQ7L0e6XtMrXlRu0X8Gk7DJ4OTNheqAZ6513100vJR EksPYnhdly9pOg5a2g+WXCNguErI7b4nUKbyqEmwIAkRQGKMrb8YuiSBDaTAKs72s8 P7DIwL0F9ulvA== Received: by pali.im (Postfix) id E16FF89A; Thu, 6 May 2021 17:32:55 +0200 (CEST) From: =?utf-8?q?Pali_Roh=C3=A1r?= To: Lorenzo Pieralisi , Thomas Petazzoni , Rob Herring , Bjorn Helgaas Cc: Russell King , =?utf-8?q?Marek_Beh=C3=BAn?= , Remi Pommarel , Xogium , Tomasz Maciej Nowak , Marc Zyngier , linux-pci@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org Subject: [PATCH 41/42] PCI: pci-bridge-emul: add support for PCIe extended capabilities Date: Thu, 6 May 2021 17:31:52 +0200 Message-Id: <20210506153153.30454-42-pali@kernel.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20210506153153.30454-1-pali@kernel.org> References: <20210506153153.30454-1-pali@kernel.org> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20210506_083259_922760_A4B1E630 X-CRM114-Status: GOOD ( 17.69 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org From: Russell King Add support for PCIe extended capabilities, which we just redirect to the emulating driver. Signed-off-by: Russell King --- drivers/pci/pci-bridge-emul.c | 52 +++++++++++++++++++++++++---------- drivers/pci/pci-bridge-emul.h | 15 ++++++++++ 2 files changed, 53 insertions(+), 14 deletions(-) diff --git a/drivers/pci/pci-bridge-emul.c b/drivers/pci/pci-bridge-emul.c index 63959e4b188a..236036fdeaa2 100644 --- a/drivers/pci/pci-bridge-emul.c +++ b/drivers/pci/pci-bridge-emul.c @@ -385,10 +385,16 @@ int pci_bridge_emul_conf_read(struct pci_bridge_emul *bridge, int where, read_op = bridge->ops->read_pcie; cfgspace = (__le32 *) &bridge->pcie_conf; behavior = bridge->pcie_cap_regs_behavior; - } else { - /* Beyond our PCIe space */ + } else if (reg < PCI_CFG_SPACE_SIZE) { + /* Rest of PCI space not implemented */ *value = 0; return PCIBIOS_SUCCESSFUL; + } else { + /* PCIe extended capability space */ + reg -= PCI_CFG_SPACE_SIZE; + read_op = bridge->ops->read_ext; + cfgspace = NULL; + behavior = NULL; } if (read_op) @@ -396,15 +402,20 @@ int pci_bridge_emul_conf_read(struct pci_bridge_emul *bridge, int where, else ret = PCI_BRIDGE_EMUL_NOT_HANDLED; - if (ret == PCI_BRIDGE_EMUL_NOT_HANDLED) - *value = le32_to_cpu(cfgspace[reg / 4]); + if (ret == PCI_BRIDGE_EMUL_NOT_HANDLED) { + if (cfgspace) + *value = le32_to_cpu(cfgspace[reg / 4]); + else + *value = 0; + } /* * Make sure we never return any reserved bit with a value * different from 0. */ - *value &= behavior[reg / 4].ro | behavior[reg / 4].rw | - behavior[reg / 4].w1c; + if (behavior) + *value &= behavior[reg / 4].ro | behavior[reg / 4].rw | + behavior[reg / 4].w1c; if (size == 1) *value = (*value >> (8 * (where & 3))) & 0xff; @@ -450,8 +461,15 @@ int pci_bridge_emul_conf_write(struct pci_bridge_emul *bridge, int where, write_op = bridge->ops->write_pcie; cfgspace = (__le32 *) &bridge->pcie_conf; behavior = bridge->pcie_cap_regs_behavior; - } else { + } else if (reg < PCI_CFG_SPACE_SIZE) { + /* Rest of PCI space not implemented */ return PCIBIOS_SUCCESSFUL; + } else { + /* PCIe extended capability space */ + reg -= PCI_CFG_SPACE_SIZE; + write_op = bridge->ops->write_ext; + cfgspace = NULL; + behavior = NULL; } shift = (where & 0x3) * 8; @@ -465,16 +483,22 @@ int pci_bridge_emul_conf_write(struct pci_bridge_emul *bridge, int where, else return PCIBIOS_BAD_REGISTER_NUMBER; - /* Keep all bits, except the RW bits */ - new = old & (~mask | ~behavior[reg / 4].rw); + if (behavior) { + /* Keep all bits, except the RW bits */ + new = old & (~mask | ~behavior[reg / 4].rw); - /* Update the value of the RW bits */ - new |= (value << shift) & (behavior[reg / 4].rw & mask); + /* Update the value of the RW bits */ + new |= (value << shift) & (behavior[reg / 4].rw & mask); - /* Clear the W1C bits */ - new &= ~((value << shift) & (behavior[reg / 4].w1c & mask)); + /* Clear the W1C bits */ + new &= ~((value << shift) & (behavior[reg / 4].w1c & mask)); + } else { + new = old & ~mask; + new |= (value << shift) & mask; + } - cfgspace[reg / 4] = cpu_to_le32(new); + if (cfgspace) + cfgspace[reg / 4] = cpu_to_le32(new); if (write_op) write_op(bridge, reg, old, new, mask); diff --git a/drivers/pci/pci-bridge-emul.h b/drivers/pci/pci-bridge-emul.h index 49bbd37ee318..2552ab660b08 100644 --- a/drivers/pci/pci-bridge-emul.h +++ b/drivers/pci/pci-bridge-emul.h @@ -90,6 +90,14 @@ struct pci_bridge_emul_ops { */ pci_bridge_emul_read_status_t (*read_pcie)(struct pci_bridge_emul *bridge, int reg, u32 *value); + + /* + * Same as ->read_base(), except it is for reading from the + * PCIe extended capability configuration space. + */ + pci_bridge_emul_read_status_t (*read_ext)(struct pci_bridge_emul *bridge, + int reg, u32 *value); + /* * Called when writing to the regular PCI bridge configuration * space. old is the current value, new is the new value being @@ -105,6 +113,13 @@ struct pci_bridge_emul_ops { */ void (*write_pcie)(struct pci_bridge_emul *bridge, int reg, u32 old, u32 new, u32 mask); + + /* + * Same as ->write_base(), except it is for writing from the + * PCIe extended capability configuration space. + */ + void (*write_ext)(struct pci_bridge_emul *bridge, int reg, + u32 old, u32 new, u32 mask); }; struct pci_bridge_reg_behavior;