From: Vidya Sagar <vidyas@nvidia.com>
To: Jeremy Linton <jeremy.linton@arm.com>,
<linux-arm-kernel@lists.infradead.org>,
<linux-pci@vger.kernel.org>
Cc: <lorenzo.pieralisi@arm.com>, <bhelgaas@google.com>,
<catalin.marinas@arm.com>, <will@kernel.org>, <robh@kernel.org>,
<sudeep.holla@arm.com>, <mark.rutland@arm.com>,
<linux-kernel@vger.kernel.org>
Subject: Re: [PATCH] arm64: PCI: Enable SMC conduit
Date: Tue, 12 Jan 2021 21:46:31 +0530 [thread overview]
Message-ID: <9ecfbc2e-5f33-dd3c-0c3b-ee7c463b3e68@nvidia.com> (raw)
In-Reply-To: <20210105045735.1709825-1-jeremy.linton@arm.com>
On 1/5/2021 10:27 AM, Jeremy Linton wrote:
> External email: Use caution opening links or attachments
>
>
> Given that most arm64 platform's PCI implementations needs quirks
> to deal with problematic config accesses, this is a good place to
> apply a firmware abstraction. The ARM PCI SMMCCC spec details a
> standard SMC conduit designed to provide a simple PCI config
> accessor. This specification enhances the existing ACPI/PCI
> abstraction and expects power, config, etc functionality is handled
> by the platform. It also is very explicit that the resulting config
> space registers must behave as is specified by the pci specification.
>
> Lets hook the normal ACPI/PCI config path, and when we detect
> missing MADT data, attempt to probe the SMC conduit. If the conduit
> exists and responds for the requested segment number (provided by the
> ACPI namespace) attach a custom pci_ecam_ops which redirects
> all config read/write requests to the firmware.
>
> This patch is based on the Arm PCI Config space access document @
> https://developer.arm.com/documentation/den0115/latest
>
> Signed-off-by: Jeremy Linton <jeremy.linton@arm.com>
> ---
> arch/arm64/kernel/pci.c | 87 +++++++++++++++++++++++++++++++++++++++
> include/linux/arm-smccc.h | 26 ++++++++++++
> 2 files changed, 113 insertions(+)
>
> diff --git a/arch/arm64/kernel/pci.c b/arch/arm64/kernel/pci.c
> index 1006ed2d7c60..56d3773aaa25 100644
> --- a/arch/arm64/kernel/pci.c
> +++ b/arch/arm64/kernel/pci.c
> @@ -7,6 +7,7 @@
> */
>
> #include <linux/acpi.h>
> +#include <linux/arm-smccc.h>
> #include <linux/init.h>
> #include <linux/io.h>
> #include <linux/kernel.h>
> @@ -107,6 +108,90 @@ static int pci_acpi_root_prepare_resources(struct acpi_pci_root_info *ci)
> return status;
> }
>
> +static int smccc_pcie_check_conduit(u16 seg)
> +{
> + struct arm_smccc_res res;
> +
> + if (arm_smccc_1_1_get_conduit() == SMCCC_CONDUIT_NONE)
> + return -EOPNOTSUPP;
> +
> + arm_smccc_smc(SMCCC_PCI_VERSION, 0, 0, 0, 0, 0, 0, 0, &res);
> + if ((int)res.a0 < 0)
> + return -EOPNOTSUPP;
> +
> + arm_smccc_smc(SMCCC_PCI_SEG_INFO, seg, 0, 0, 0, 0, 0, 0, &res);
> + if ((int)res.a0 < 0)
> + return -EOPNOTSUPP;
> +
> + pr_info("PCI: SMC conduit attached to segment %d\n", seg);
Shouldn't this print be moved towards the end of
pci_acpi_setup_smccc_mapping() API?
> +
> + return 0;
> +}
> +
> +static int smccc_pcie_config_read(struct pci_bus *bus, unsigned int devfn,
> + int where, int size, u32 *val)
> +{
> + struct arm_smccc_res res;
> +
> + devfn |= bus->number << 8;
> + devfn |= bus->domain_nr << 16;
> +
> + arm_smccc_smc(SMCCC_PCI_READ, devfn, where, size, 0, 0, 0, 0, &res);
> + if (res.a0) {
> + *val = ~0;
> + return -PCIBIOS_BAD_REGISTER_NUMBER;
> + }
> +
> + *val = res.a1;
> + return PCIBIOS_SUCCESSFUL;
> +}
> +
> +static int smccc_pcie_config_write(struct pci_bus *bus, unsigned int devfn,
> + int where, int size, u32 val)
> +{
> + struct arm_smccc_res res;
> +
> + devfn |= bus->number << 8;
> + devfn |= bus->domain_nr << 16;
> +
> + arm_smccc_smc(SMCCC_PCI_WRITE, devfn, where, size, val, 0, 0, 0, &res);
> + if (res.a0)
> + return -PCIBIOS_BAD_REGISTER_NUMBER;
> +
> + return PCIBIOS_SUCCESSFUL;
> +}
> +
> +static const struct pci_ecam_ops smccc_pcie_ecam_ops = {
> + .bus_shift = 8,
> + .pci_ops = {
> + .read = smccc_pcie_config_read,
> + .write = smccc_pcie_config_write,
> + }
> +};
> +
> +static struct pci_config_window *
> +pci_acpi_setup_smccc_mapping(struct acpi_pci_root *root)
> +{
> + struct device *dev = &root->device->dev;
> + struct resource *bus_res = &root->secondary;
> + struct pci_config_window *cfg;
> +
> + cfg = kzalloc(sizeof(*cfg), GFP_KERNEL);
> + if (!cfg)
> + return ERR_PTR(-ENOMEM);
> +
> + cfg->parent = dev;
> + cfg->ops = &smccc_pcie_ecam_ops;
> + cfg->busr.start = bus_res->start;
> + cfg->busr.end = bus_res->end;
> + cfg->busr.flags = IORESOURCE_BUS;
> +
> + cfg->res.name = "PCI SMCCC";
> + if (cfg->ops->init)
Since there is no init implemented, what is the purpose of having this?
> + cfg->ops->init(cfg);
> + return cfg;
> +}
> +
> /*
> * Lookup the bus range for the domain in MCFG, and set up config space
> * mapping.
> @@ -125,6 +210,8 @@ pci_acpi_setup_ecam_mapping(struct acpi_pci_root *root)
>
> ret = pci_mcfg_lookup(root, &cfgres, &ecam_ops);
> if (ret) {
> + if (!smccc_pcie_check_conduit(seg))
> + return pci_acpi_setup_smccc_mapping(root);
> dev_err(dev, "%04x:%pR ECAM region not found\n", seg, bus_res);
> return NULL;
> }
> diff --git a/include/linux/arm-smccc.h b/include/linux/arm-smccc.h
> index f860645f6512..327f52533c71 100644
> --- a/include/linux/arm-smccc.h
> +++ b/include/linux/arm-smccc.h
> @@ -89,6 +89,32 @@
>
> #define SMCCC_ARCH_WORKAROUND_RET_UNAFFECTED 1
>
> +/* PCI ECAM conduit */
> +#define SMCCC_PCI_VERSION \
> + ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \
> + ARM_SMCCC_SMC_32, \
> + ARM_SMCCC_OWNER_STANDARD, 0x0130)
> +
> +#define SMCCC_PCI_FEATURES \
> + ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \
> + ARM_SMCCC_SMC_32, \
> + ARM_SMCCC_OWNER_STANDARD, 0x0131)
> +
> +#define SMCCC_PCI_READ \
> + ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \
> + ARM_SMCCC_SMC_32, \
> + ARM_SMCCC_OWNER_STANDARD, 0x0132)
> +
> +#define SMCCC_PCI_WRITE \
> + ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \
> + ARM_SMCCC_SMC_32, \
> + ARM_SMCCC_OWNER_STANDARD, 0x0133)
> +
> +#define SMCCC_PCI_SEG_INFO \
> + ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \
> + ARM_SMCCC_SMC_32, \
> + ARM_SMCCC_OWNER_STANDARD, 0x0134)
> +
> /* Paravirtualised time calls (defined by ARM DEN0057A) */
> #define ARM_SMCCC_HV_PV_TIME_FEATURES \
> ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \
> --
> 2.26.2
>
next prev parent reply other threads:[~2021-01-12 16:18 UTC|newest]
Thread overview: 32+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-01-05 4:57 [PATCH] arm64: PCI: Enable SMC conduit Jeremy Linton
2021-01-07 15:28 ` Rob Herring
2021-01-07 16:23 ` Jeremy Linton
2021-01-07 17:36 ` Rob Herring
2021-01-07 19:45 ` Jeremy Linton
2021-01-07 20:35 ` Rob Herring
2021-01-07 18:14 ` Will Deacon
2021-01-07 19:18 ` Jeremy Linton
2021-01-07 21:05 ` Jon Masters
2021-01-07 21:49 ` Rob Herring
2021-01-08 10:32 ` Lorenzo Pieralisi
2021-01-22 19:48 ` Will Deacon
2021-01-26 16:46 ` Jeremy Linton
2021-01-26 22:54 ` Will Deacon
2021-01-28 18:50 ` Jeremy Linton
2021-01-28 23:31 ` Bjorn Helgaas
[not found] ` <CACCGGCc3zULqHgUh3Q9wA5WtPBnQ4eq_v2+1qA8bOBCQZJ5YoQ@mail.gmail.com>
2021-02-25 9:30 ` Lorenzo Pieralisi
2021-02-25 22:31 ` Jeremy Linton
2021-01-26 17:08 ` Vikram Sethi
2021-01-26 22:53 ` Will Deacon
2021-03-25 13:12 ` Lorenzo Pieralisi
2021-03-25 20:45 ` Marcin Wojtas
2021-03-25 21:12 ` Jon Masters
2021-03-26 9:27 ` Marcin Wojtas
2021-06-16 17:36 ` Jason Gunthorpe
[not found] ` <CA+kK7ZijdNERQSauEvAffR7JLbfZ512na2-9cJrU0vFbNnDGwQ@mail.gmail.com>
2021-06-18 14:05 ` Jason Gunthorpe
2021-06-19 16:34 ` Jon Masters
2021-06-19 16:38 ` Jon Masters
2021-06-20 0:26 ` Jason Gunthorpe
2021-06-18 15:10 ` Jeremy Linton
2021-01-12 16:16 ` Vidya Sagar [this message]
2021-01-12 16:57 ` Jeremy Linton
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=9ecfbc2e-5f33-dd3c-0c3b-ee7c463b3e68@nvidia.com \
--to=vidyas@nvidia.com \
--cc=bhelgaas@google.com \
--cc=catalin.marinas@arm.com \
--cc=jeremy.linton@arm.com \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-pci@vger.kernel.org \
--cc=lorenzo.pieralisi@arm.com \
--cc=mark.rutland@arm.com \
--cc=robh@kernel.org \
--cc=sudeep.holla@arm.com \
--cc=will@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).