From: Jeremy Linton <hidden> Date: 2021-08-26 07:16:04
The PFTF CM4 is an ACPI platform that is following the Arm PCIe SMC
(DEN0115) standard because its PCIe config space isn't ECAM compliant
since it is split into two parts. One part describes the root port
registers, and another contains a moveable window pointing at a given
device's 4K config space. Thus it doesn't have an MCFG table. As
Linux doesn't support the PCI/SMC, a host bridge specific _DSD is
added and associated with custom ECAM ops and cfgres. The custom cfg
op selects between those two regions, as well as disallowing
problematic accesses.
V2->V3:
Rebase to -next to pickup new MAINTAINERS entries that
needed updating.
Enforce _DSD property is exactly the same len as the
MCFG OEM field it is overriding.
More commit/comment tweaks.
V1->V2:
Only move register definitions to new .h file, add
include guards.
Change quirk namespace identifier.
Update Maintainers file.
A number of whitespace, grammar, etc fixes.
Jeremy Linton (4):
PCI: brcmstb: Break register definitions into separate header
PCI: brcmstb: Add ACPI config space quirk
PCI/ACPI: Add Broadcom bcm2711 MCFG quirk
MAINTAINERS: Widen brcmstb PCIe file scope
MAINTAINERS | 6 +-
drivers/acpi/pci_mcfg.c | 17 +++
drivers/pci/controller/Makefile | 1 +
drivers/pci/controller/pcie-brcmstb-acpi.c | 79 +++++++++++
drivers/pci/controller/pcie-brcmstb.c | 149 +-------------------
drivers/pci/controller/pcie-brcmstb.h | 155 +++++++++++++++++++++
include/linux/pci-ecam.h | 1 +
7 files changed, 257 insertions(+), 151 deletions(-)
create mode 100644 drivers/pci/controller/pcie-brcmstb-acpi.c
create mode 100644 drivers/pci/controller/pcie-brcmstb.h
--
2.31.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
From: Jeremy Linton <hidden> Date: 2021-08-26 07:16:05
We are about to create a standalone ACPI quirk module for the
bcmstb controller. Lets move the register definitions into a separate
file so they can be shared between the APCI quirk and the normal
host bridge driver.
Signed-off-by: Jeremy Linton <redacted>
Acked-by: Florian Fainelli <f.fainelli@gmail.com>
Acked-by: Bjorn Helgaas <bhelgaas@google.com>
---
drivers/pci/controller/pcie-brcmstb.c | 149 +------------------------
drivers/pci/controller/pcie-brcmstb.h | 155 ++++++++++++++++++++++++++
2 files changed, 156 insertions(+), 148 deletions(-)
create mode 100644 drivers/pci/controller/pcie-brcmstb.h
From: Jeremy Linton <hidden> Date: 2021-08-26 07:16:14
The Pi Firmware Task Force (PFTF: https://github.com/pftf) Compute
Module 4 (CM4: an embedded form factor RPi4) is an ACPI platform that
isn't ECAM compliant. Its config space is in two parts. One part is for
the root port registers and a second moveable window pointing at a
device's 4K config space. Thus it doesn't have an MCFG, and any MCFG
provided would be nonsense anyway.
Instead, a custom pci_ecam_ops quirk is created. The custom ops override
the .init and .map_bus functions. The former to assure that cfg->win
points at a single mapping that contains the root port registers and the
device config window, as well as disabling MSIs due to lack of a
GICv2M. map_bus() then provides the address of either the standard
portion of the root port registers or to the device config window after
it has been moved.
Additionally, some basic bus/device filtering exist to avoid sending
config transactions to invalid devices on the RP's primary or
secondary bus. A basic link check is also made to assure that
something is operational on the secondary side before probing the
remainder of the config space. If either of these constraints are
violated and a config operation is lost in the ether because an EP
doesn't respond an unrecoverable SERROR is raised.
Signed-off-by: Jeremy Linton <redacted>
Acked-by: Florian Fainelli <f.fainelli@gmail.com>
Acked-by: Bjorn Helgaas <bhelgaas@google.com>
---
drivers/pci/controller/Makefile | 1 +
drivers/pci/controller/pcie-brcmstb-acpi.c | 79 ++++++++++++++++++++++
include/linux/pci-ecam.h | 1 +
3 files changed, 81 insertions(+)
create mode 100644 drivers/pci/controller/pcie-brcmstb-acpi.c
@@ -0,0 +1,79 @@+// SPDX-License-Identifier: GPL-2.0++/*+*ACPIquirksforBrcm2711PCIehostcontroller+*AsusedontheRaspberryPiComputeModule4+*+*Copyright(C)2021ArmLtd.+*/++#include<linux/io.h>+#include<linux/pci.h>+#include<linux/pci-ecam.h>+#include"../pci.h"+#include"pcie-brcmstb.h"++staticintbrcm_acpi_init(structpci_config_window*cfg)+{+/*+*Thisplatformdoesn'ttechnicallyhaveanythingthatcouldbecalled+*ECAM.Itsconfigregionhasrootportspecificregistersbetween+*standardPCIedefinedconfigregisters.Thustheregionsetupbythe+*genericECAMcodeneedstobeadjusted.TheHWcanaccessbus0-ff+*butthefootprintisn'tanicepowerof2(40k).Forpurposesof+*mappingtheconfigregionwearejustgoingtosquashthestandard+*andnonstandardregisterstogetherratherthanmappingthemseparately.+*/+iounmap(cfg->win);+cfg->win=pci_remap_cfgspace(cfg->res.start,resource_size(&cfg->res));+if(!cfg->win)+gotoerr_exit;++/* MSI is nonstandard as well */+pci_no_msi();++return0;+err_exit:+dev_err(cfg->parent,"PCI: Failed to remap config\n");+return-ENOMEM;+}++staticvoid__iomem*brcm_pcie_map_conf2(structpci_bus*bus,+unsignedintdevfn,intwhere)+{+structpci_config_window*cfg=bus->sysdata;+void__iomem*base=cfg->win;+intidx;+u32up;++/* Accesses to the RC go right to the RC registers if slot==0 */+if(pci_is_root_bus(bus))+returnPCI_SLOT(devfn)?NULL:base+where;++/*+*Assurethelinkisupbeforesendingrequestsdownstream.Thisisdone+*toavoidsendingtransactionstoEPsthatdon'texist.Linkflap+*conditions/etcmakethisracemoreprobable.Theresultingunrecoverable+*SERRORswillresultinthemachinecrashing.+*/+up=readl(base+PCIE_MISC_PCIE_STATUS);+if(!(up&PCIE_MISC_PCIE_STATUS_PCIE_DL_ACTIVE_MASK))+returnNULL;++if(!(up&PCIE_MISC_PCIE_STATUS_PCIE_PHYLINKUP_MASK))+returnNULL;++/* For devices, write to the config space index register */+idx=PCIE_ECAM_OFFSET(bus->number,devfn,0);+writel(idx,base+PCIE_EXT_CFG_INDEX);+returnbase+PCIE_EXT_CFG_DATA+where;+}++conststructpci_ecam_opsbcm2711_pcie_ops={+.init=brcm_acpi_init,+.bus_shift=1,+.pci_ops={+.map_bus=brcm_pcie_map_conf2,+.read=pci_generic_config_read,+.write=pci_generic_config_write,+}+};
From: Jeremy Linton <hidden> Date: 2021-08-26 07:16:17
Now that there is a bcm2711 quirk, it needs to be enabled when the
MCFG is missing. Use an ACPI namespace _DSD property
"linux-ecam-quirk-id" as an alternative to the MCFG OEM.
Signed-off-by: Jeremy Linton <redacted>
Acked-by: Florian Fainelli <f.fainelli@gmail.com>
Acked-by: Bjorn Helgaas <bhelgaas@google.com>
---
drivers/acpi/pci_mcfg.c | 17 +++++++++++++++++
1 file changed, 17 insertions(+)
From: Jeremy Linton <hidden> Date: 2021-08-26 07:16:19
The brcmstb PCI hardware is now split across multiple files. Include
them in the maintainers block.
Signed-off-by: Jeremy Linton <redacted>
Acked-by: Florian Fainelli <f.fainelli@gmail.com>
Acked-by: Bjorn Helgaas <bhelgaas@google.com>
---
MAINTAINERS | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
From: nicolas saenz julienne <nsaenz@kernel.org> Date: 2021-08-30 08:36:51
Hi Jeremy,
sorry for the late reply, I've been on vacation.
On Thu, 2021-08-26 at 02:15 -0500, Jeremy Linton wrote:
[...]
+static void __iomem *brcm_pcie_map_conf2(struct pci_bus *bus,
+ unsigned int devfn, int where)
+{
+ struct pci_config_window *cfg = bus->sysdata;
+ void __iomem *base = cfg->win;
+ int idx;
+ u32 up;
+
+ /* Accesses to the RC go right to the RC registers if slot==0 */
+ if (pci_is_root_bus(bus))
+ return PCI_SLOT(devfn) ? NULL : base + where;
+
+ /*
+ * Assure the link is up before sending requests downstream. This is done
+ * to avoid sending transactions to EPs that don't exist. Link flap
+ * conditions/etc make this race more probable. The resulting unrecoverable
+ * SERRORs will result in the machine crashing.
+ */
+ up = readl(base + PCIE_MISC_PCIE_STATUS);
+ if (!(up & PCIE_MISC_PCIE_STATUS_PCIE_DL_ACTIVE_MASK))
+ return NULL;
+
+ if (!(up & PCIE_MISC_PCIE_STATUS_PCIE_PHYLINKUP_MASK))
+ return NULL;
Couldn't this be integrated in the original brcm_pcie_map_conf()? IIUC there is
nothing ACPI specific about it. It'd also make for less code duplication.
Regards,
Nicolas
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
From: nicolas saenz julienne <nsaenz@kernel.org> Date: 2021-08-30 08:37:09
On Thu, 2021-08-26 at 02:15 -0500, Jeremy Linton wrote:
We are about to create a standalone ACPI quirk module for the
bcmstb controller. Lets move the register definitions into a separate
file so they can be shared between the APCI quirk and the normal
host bridge driver.
Signed-off-by: Jeremy Linton <redacted>
Acked-by: Florian Fainelli <f.fainelli@gmail.com>
Acked-by: Bjorn Helgaas <bhelgaas@google.com>
---
Acked-by: Nicolas Saenz Julienne <nsaenz@kernel.org>
Regards,
Nicolas
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
From: nicolas saenz julienne <nsaenz@kernel.org> Date: 2021-08-30 08:37:58
On Thu, 2021-08-26 at 02:15 -0500, Jeremy Linton wrote:
Now that there is a bcm2711 quirk, it needs to be enabled when the
MCFG is missing. Use an ACPI namespace _DSD property
"linux-ecam-quirk-id" as an alternative to the MCFG OEM.
Signed-off-by: Jeremy Linton <redacted>
Acked-by: Florian Fainelli <f.fainelli@gmail.com>
Acked-by: Bjorn Helgaas <bhelgaas@google.com>
---
Acked-by: Nicolas Saenz Julienne <nsaenz@kernel.org>
Regards,
Nicolas
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
From: nicolas saenz julienne <nsaenz@kernel.org> Date: 2021-08-30 08:38:18
On Thu, 2021-08-26 at 02:15 -0500, Jeremy Linton wrote:
The brcmstb PCI hardware is now split across multiple files. Include
them in the maintainers block.
Signed-off-by: Jeremy Linton <redacted>
Acked-by: Florian Fainelli <f.fainelli@gmail.com>
Acked-by: Bjorn Helgaas <bhelgaas@google.com>
---
Acked-by: Nicolas Saenz Julienne <nsaenz@kernel.org>
Regards,
Nicolas
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
From: Jeremy Linton <hidden> Date: 2021-08-30 16:23:34
Hi,
On 8/30/21 3:36 AM, nicolas saenz julienne wrote:
Hi Jeremy,
sorry for the late reply, I've been on vacation.
On Thu, 2021-08-26 at 02:15 -0500, Jeremy Linton wrote:
[...]
quoted
+static void __iomem *brcm_pcie_map_conf2(struct pci_bus *bus,
+ unsigned int devfn, int where)
+{
+ struct pci_config_window *cfg = bus->sysdata;
+ void __iomem *base = cfg->win;
+ int idx;
+ u32 up;
+
+ /* Accesses to the RC go right to the RC registers if slot==0 */
+ if (pci_is_root_bus(bus))
+ return PCI_SLOT(devfn) ? NULL : base + where;
+
+ /*
+ * Assure the link is up before sending requests downstream. This is done
+ * to avoid sending transactions to EPs that don't exist. Link flap
+ * conditions/etc make this race more probable. The resulting unrecoverable
+ * SERRORs will result in the machine crashing.
+ */
+ up = readl(base + PCIE_MISC_PCIE_STATUS);
+ if (!(up & PCIE_MISC_PCIE_STATUS_PCIE_DL_ACTIVE_MASK))
+ return NULL;
+
+ if (!(up & PCIE_MISC_PCIE_STATUS_PCIE_PHYLINKUP_MASK))
+ return NULL;
Couldn't this be integrated in the original brcm_pcie_map_conf()? IIUC there is
nothing ACPI specific about it. It'd also make for less code duplication.
That is where I started with this, but it wasn't the linkup check/etc
which caused me to hoist it but the fact that if ACPI quirks are enabled
they end up statically built into the kernel. While if this host bridge
is enabled, it can end up being a module, and the resulting mess I
created trying to satisfy the CONFIG variations. I'm not much of a fan
of copy/paste programming, but that IMHO ended up being the cleanest here.
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
Hi,
On 8/30/21 3:36 AM, nicolas saenz julienne wrote:
quoted
Hi Jeremy,
sorry for the late reply, I've been on vacation.
On Thu, 2021-08-26 at 02:15 -0500, Jeremy Linton wrote:
[...]
quoted
+static void __iomem *brcm_pcie_map_conf2(struct pci_bus *bus,
+ unsigned int devfn, int where)
+{
+ struct pci_config_window *cfg = bus->sysdata;
+ void __iomem *base = cfg->win;
+ int idx;
+ u32 up;
+
+ /* Accesses to the RC go right to the RC registers if slot==0 */
+ if (pci_is_root_bus(bus))
+ return PCI_SLOT(devfn) ? NULL : base + where;
+
+ /*
+ * Assure the link is up before sending requests downstream.
This is done
+ * to avoid sending transactions to EPs that don't exist. Link flap
+ * conditions/etc make this race more probable. The resulting
unrecoverable
+ * SERRORs will result in the machine crashing.
+ */
+ up = readl(base + PCIE_MISC_PCIE_STATUS);
+ if (!(up & PCIE_MISC_PCIE_STATUS_PCIE_DL_ACTIVE_MASK))
+ return NULL;
+
+ if (!(up & PCIE_MISC_PCIE_STATUS_PCIE_PHYLINKUP_MASK))
+ return NULL;
Couldn't this be integrated in the original brcm_pcie_map_conf()? IIUC
there is
nothing ACPI specific about it. It'd also make for less code duplication.
That is where I started with this, but it wasn't the linkup check/etc
which caused me to hoist it but the fact that if ACPI quirks are enabled
they end up statically built into the kernel. While if this host bridge
is enabled, it can end up being a module, and the resulting mess I
created trying to satisfy the CONFIG variations. I'm not much of a fan
of copy/paste programming, but that IMHO ended up being the cleanest here.
Agreed, the open coding that is being done is reasonable IHMO, although
we may have to update the link up code in both pcie-brcmstb.c and this
file in the future if offsets/bits do change, nothing impossible though.
--
Florian
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
From: nicolas saenz julienne <nsaenz@kernel.org> Date: 2021-08-30 17:17:44
On Mon, 2021-08-30 at 09:27 -0700, Florian Fainelli wrote:
On 8/30/2021 9:23 AM, Jeremy Linton wrote:
quoted
Hi,
On 8/30/21 3:36 AM, nicolas saenz julienne wrote:
quoted
Hi Jeremy,
sorry for the late reply, I've been on vacation.
On Thu, 2021-08-26 at 02:15 -0500, Jeremy Linton wrote:
[...]
quoted
+static void __iomem *brcm_pcie_map_conf2(struct pci_bus *bus,
+ unsigned int devfn, int where)
+{
+ struct pci_config_window *cfg = bus->sysdata;
+ void __iomem *base = cfg->win;
+ int idx;
+ u32 up;
+
+ /* Accesses to the RC go right to the RC registers if slot==0 */
+ if (pci_is_root_bus(bus))
+ return PCI_SLOT(devfn) ? NULL : base + where;
+
+ /*
+ * Assure the link is up before sending requests downstream.
This is done
+ * to avoid sending transactions to EPs that don't exist. Link flap
+ * conditions/etc make this race more probable. The resulting
unrecoverable
+ * SERRORs will result in the machine crashing.
+ */
+ up = readl(base + PCIE_MISC_PCIE_STATUS);
+ if (!(up & PCIE_MISC_PCIE_STATUS_PCIE_DL_ACTIVE_MASK))
+ return NULL;
+
+ if (!(up & PCIE_MISC_PCIE_STATUS_PCIE_PHYLINKUP_MASK))
+ return NULL;
Couldn't this be integrated in the original brcm_pcie_map_conf()? IIUC
there is
nothing ACPI specific about it. It'd also make for less code duplication.
That is where I started with this, but it wasn't the linkup check/etc
which caused me to hoist it but the fact that if ACPI quirks are enabled
they end up statically built into the kernel. While if this host bridge
is enabled, it can end up being a module, and the resulting mess I
created trying to satisfy the CONFIG variations. I'm not much of a fan
of copy/paste programming, but that IMHO ended up being the cleanest here.
Agreed, the open coding that is being done is reasonable IHMO, although
we may have to update the link up code in both pcie-brcmstb.c and this
file in the future if offsets/bits do change, nothing impossible though.
Fair enough.
Acked-by: Nicolas Saenz Julienne <nsaenz@kernel.org>
Regards,
Nicolas
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
From: "Rafael J. Wysocki" <rafael@kernel.org> Date: 2021-09-13 16:12:18
On Thu, Aug 26, 2021 at 9:16 AM Jeremy Linton [off-list ref] wrote:
Now that there is a bcm2711 quirk, it needs to be enabled when the
MCFG is missing. Use an ACPI namespace _DSD property
"linux-ecam-quirk-id" as an alternative to the MCFG OEM.
Signed-off-by: Jeremy Linton <redacted>
Acked-by: Florian Fainelli <f.fainelli@gmail.com>
Acked-by: Bjorn Helgaas <bhelgaas@google.com>
On Thu, Aug 26, 2021 at 02:15:56AM -0500, Jeremy Linton wrote:
quoted hunk
Now that there is a bcm2711 quirk, it needs to be enabled when the
MCFG is missing. Use an ACPI namespace _DSD property
"linux-ecam-quirk-id" as an alternative to the MCFG OEM.
Signed-off-by: Jeremy Linton <redacted>
Acked-by: Florian Fainelli <f.fainelli@gmail.com>
Acked-by: Bjorn Helgaas <bhelgaas@google.com>
---
drivers/acpi/pci_mcfg.c | 17 +++++++++++++++++
1 file changed, 17 insertions(+)
From a reviewing perspective, it's not obvious why soc must be exactly
ACPI_OEM_ID_SIZE. Does that imply space-padding in the DT string or
something?
Is there any documentation for this DT property?
Also not obvious why strlen() is safe here. I mean, I looked a couple
levels deep in fwnode_property_read_string(), but whatever guarantees
null termination is buried pretty deep.
It seems a little weird to use an MCFG quirk mechanism when there's no
MCFG at all on this platform.
+ dev_err(&root->device->dev, "ECAM quirk should be %d characters\n",
+ ACPI_OEM_ID_SIZE);
+ else
+ memcpy(mcfg_oem_id, soc, ACPI_OEM_ID_SIZE);
+ }
+
for (i = 0, f = mcfg_quirks; i < ARRAY_SIZE(mcfg_quirks); i++, f++) {
if (pci_mcfg_quirk_matches(f, segment, bus_range)) {
if (f->cfgres.start)
--
2.31.1
On Thu, Aug 26, 2021 at 02:15:55AM -0500, Jeremy Linton wrote:
The Pi Firmware Task Force (PFTF: https://github.com/pftf) Compute
Module 4 (CM4: an embedded form factor RPi4) is an ACPI platform that
isn't ECAM compliant. Its config space is in two parts. One part is for
the root port registers and a second moveable window pointing at a
device's 4K config space. Thus it doesn't have an MCFG, and any MCFG
provided would be nonsense anyway.
Instead, a custom pci_ecam_ops quirk is created. The custom ops override
the .init and .map_bus functions. The former to assure that cfg->win
points at a single mapping that contains the root port registers and the
device config window, as well as disabling MSIs due to lack of a
GICv2M. map_bus() then provides the address of either the standard
portion of the root port registers or to the device config window after
it has been moved.
Additionally, some basic bus/device filtering exist to avoid sending
config transactions to invalid devices on the RP's primary or
secondary bus. A basic link check is also made to assure that
something is operational on the secondary side before probing the
remainder of the config space. If either of these constraints are
violated and a config operation is lost in the ether because an EP
doesn't respond an unrecoverable SERROR is raised.
It's not "lost"; I assume the root port raises an error because it
can't send a transaction over a link that is down.
Is "SERROR" an ARM64 thing? My guess is the root port would raise an
Unsupported Request error or similar, and the root complex turns that
into a system-specific SERROR?
Wrap this and comment below to fit in 80 columns. Nothing magic about
80 columns except for the fact that all the other code in drivers/pci
fits in that width and consistency is helpful.
+ */
+ iounmap(cfg->win);
+ cfg->win = pci_remap_cfgspace(cfg->res.start, resource_size(&cfg->res));
+ if (!cfg->win)
+ goto err_exit;
+
+ /* MSI is nonstandard as well */
+ pci_no_msi();
This doesn't seem to fit in an MCFG quirk.
+ return 0;
+err_exit:
+ dev_err(cfg->parent, "PCI: Failed to remap config\n");
+ return -ENOMEM;
+}
+
+static void __iomem *brcm_pcie_map_conf2(struct pci_bus *bus,
+ unsigned int devfn, int where)
+{
+ struct pci_config_window *cfg = bus->sysdata;
+ void __iomem *base = cfg->win;
+ int idx;
+ u32 up;
+
+ /* Accesses to the RC go right to the RC registers if slot==0 */
+ if (pci_is_root_bus(bus))
+ return PCI_SLOT(devfn) ? NULL : base + where;
+
+ /*
+ * Assure the link is up before sending requests downstream. This is done
+ * to avoid sending transactions to EPs that don't exist. Link flap
+ * conditions/etc make this race more probable. The resulting unrecoverable
+ * SERRORs will result in the machine crashing.
Is the crash because SERROR is fundamentally unrecoverable? Is there
any control over what kind of system-specific error the PCIe errors
are mapped to?
I know there are other systems where PCIe errors always cause a system
crash, but most platforms seem to be moving toward at least the
theoretical ability to recover from I/O errors.
quoted hunk
+ */
+ up = readl(base + PCIE_MISC_PCIE_STATUS);
+ if (!(up & PCIE_MISC_PCIE_STATUS_PCIE_DL_ACTIVE_MASK))
+ return NULL;
+
+ if (!(up & PCIE_MISC_PCIE_STATUS_PCIE_PHYLINKUP_MASK))
+ return NULL;
+
+ /* For devices, write to the config space index register */
+ idx = PCIE_ECAM_OFFSET(bus->number, devfn, 0);
+ writel(idx, base + PCIE_EXT_CFG_INDEX);
+ return base + PCIE_EXT_CFG_DATA + where;
+}
+
+const struct pci_ecam_ops bcm2711_pcie_ops = {
+ .init = brcm_acpi_init,
+ .bus_shift = 1,
+ .pci_ops = {
+ .map_bus = brcm_pcie_map_conf2,
+ .read = pci_generic_config_read,
+ .write = pci_generic_config_write,
+ }
+};
From: Jeremy Linton <hidden> Date: 2021-10-05 15:44:05
Hi,
Thanks for looking at this again.
On 10/5/21 10:10 AM, Bjorn Helgaas wrote:
On Thu, Aug 26, 2021 at 02:15:56AM -0500, Jeremy Linton wrote:
quoted
Now that there is a bcm2711 quirk, it needs to be enabled when the
MCFG is missing. Use an ACPI namespace _DSD property
"linux-ecam-quirk-id" as an alternative to the MCFG OEM.
Signed-off-by: Jeremy Linton <redacted>
Acked-by: Florian Fainelli <f.fainelli@gmail.com>
Acked-by: Bjorn Helgaas <bhelgaas@google.com>
---
drivers/acpi/pci_mcfg.c | 17 +++++++++++++++++
1 file changed, 17 insertions(+)
From a reviewing perspective, it's not obvious why soc must be exactly
ACPI_OEM_ID_SIZE. Does that imply space-padding in the DT string or
something?
This is at the moment an ACPI only DSD, and it must follow the MADT
OEM_ID format for now because we are effectively just overriding that
field. The rest of the code in this module is just treating it as a
fixed 6 bytes.
Is there any documentation for this DT property?
Its not a DT property, and its unclear since its linux only if it
belongs in previously linked ACPI registry.
Also not obvious why strlen() is safe here. I mean, I looked a couple
levels deep in fwnode_property_read_string(), but whatever guarantees
null termination is buried pretty deep.
I've not tracked down who, if anyone other than the AML compiler is
guaranteeing a null. The spec says something to the effect "Most other
string, however, are of variable-length and are automatically null
terminated by the compiler". Not sure if that helps any.
It seems a little weird to use an MCFG quirk mechanism when there's no
MCFG at all on this platform.
Well its just a point to hook in a CFG space quirk, and since that is
what most of the MCFG quirks are, it seemed reasonable to reuse it
rather than recreate it.
PS, had some offline convo about reposing with a simple rebase and the
ACK's applied, will do that if it helps any, but when I checked a couple
weeks back this applied to 5.15 automatically.
quoted
+ dev_err(&root->device->dev, "ECAM quirk should be %d characters\n",
+ ACPI_OEM_ID_SIZE);
+ else
+ memcpy(mcfg_oem_id, soc, ACPI_OEM_ID_SIZE);
+ }
+
for (i = 0, f = mcfg_quirks; i < ARRAY_SIZE(mcfg_quirks); i++, f++) {
if (pci_mcfg_quirk_matches(f, segment, bus_range)) {
if (f->cfgres.start)
--
2.31.1
From: Jeremy Linton <hidden> Date: 2021-10-05 15:57:37
Hi,
On 10/5/21 10:32 AM, Bjorn Helgaas wrote:
On Thu, Aug 26, 2021 at 02:15:55AM -0500, Jeremy Linton wrote:
quoted
The Pi Firmware Task Force (PFTF: https://github.com/pftf) Compute
Module 4 (CM4: an embedded form factor RPi4) is an ACPI platform that
isn't ECAM compliant. Its config space is in two parts. One part is for
the root port registers and a second moveable window pointing at a
device's 4K config space. Thus it doesn't have an MCFG, and any MCFG
provided would be nonsense anyway.
Instead, a custom pci_ecam_ops quirk is created. The custom ops override
the .init and .map_bus functions. The former to assure that cfg->win
points at a single mapping that contains the root port registers and the
device config window, as well as disabling MSIs due to lack of a
GICv2M. map_bus() then provides the address of either the standard
portion of the root port registers or to the device config window after
it has been moved.
Additionally, some basic bus/device filtering exist to avoid sending
config transactions to invalid devices on the RP's primary or
secondary bus. A basic link check is also made to assure that
something is operational on the secondary side before probing the
remainder of the config space. If either of these constraints are
violated and a config operation is lost in the ether because an EP
doesn't respond an unrecoverable SERROR is raised.
It's not "lost"; I assume the root port raises an error because it
can't send a transaction over a link that is down.
The problem is AFAIK because the root port doesn't do that.
Is "SERROR" an ARM64 thing? My guess is the root port would raise an
Unsupported Request error or similar, and the root complex turns that
into a system-specific SERROR?
AFAIK, what is happening here the CPU core has an outstanding R/W
request for which it never receives a response from the root port. So
basically its an interconnect protocol violation that the CPU is
complaining about rather than something PCIe specific.
Wrap this and comment below to fit in 80 columns. Nothing magic about
80 columns except for the fact that all the other code in drivers/pci
fits in that width and consistency is helpful.
Hmm, I thought I had wrapped these, but probably at 78, guess I will
rebase/repost.
quoted
+ */
+ iounmap(cfg->win);
+ cfg->win = pci_remap_cfgspace(cfg->res.start, resource_size(&cfg->res));
+ if (!cfg->win)
+ goto err_exit;
+
+ /* MSI is nonstandard as well */
+ pci_no_msi();
This doesn't seem to fit in an MCFG quirk.
"pcie quirk"
quoted
+ return 0;
+err_exit:
+ dev_err(cfg->parent, "PCI: Failed to remap config\n");
+ return -ENOMEM;
+}
+
+static void __iomem *brcm_pcie_map_conf2(struct pci_bus *bus,
+ unsigned int devfn, int where)
+{
+ struct pci_config_window *cfg = bus->sysdata;
+ void __iomem *base = cfg->win;
+ int idx;
+ u32 up;
+
+ /* Accesses to the RC go right to the RC registers if slot==0 */
+ if (pci_is_root_bus(bus))
+ return PCI_SLOT(devfn) ? NULL : base + where;
+
+ /*
+ * Assure the link is up before sending requests downstream. This is done
+ * to avoid sending transactions to EPs that don't exist. Link flap
+ * conditions/etc make this race more probable. The resulting unrecoverable
+ * SERRORs will result in the machine crashing.
Is the crash because SERROR is fundamentally unrecoverable? Is there
any control over what kind of system-specific error the PCIe errors
are mapped to?
Yes, that is basically where we are because the reason for the exception
can't really be pinned down. There are some thoughts about ways to work
around the problem, but they aren't pretty and probably need to be done
at an exception level higher than what the kernel is operating at. Hence
the SMC.
I know there are other systems where PCIe errors always cause a system
crash, but most platforms seem to be moving toward at least the
theoretical ability to recover from I/O errors.
Yes, that would be part of SBSA, which of course this platform isn't.
quoted
+ */
+ up = readl(base + PCIE_MISC_PCIE_STATUS);
+ if (!(up & PCIE_MISC_PCIE_STATUS_PCIE_DL_ACTIVE_MASK))
+ return NULL;
+
+ if (!(up & PCIE_MISC_PCIE_STATUS_PCIE_PHYLINKUP_MASK))
+ return NULL;
+
+ /* For devices, write to the config space index register */
+ idx = PCIE_ECAM_OFFSET(bus->number, devfn, 0);
+ writel(idx, base + PCIE_EXT_CFG_INDEX);
+ return base + PCIE_EXT_CFG_DATA + where;
+}
+
+const struct pci_ecam_ops bcm2711_pcie_ops = {
+ .init = brcm_acpi_init,
+ .bus_shift = 1,
+ .pci_ops = {
+ .map_bus = brcm_pcie_map_conf2,
+ .read = pci_generic_config_read,
+ .write = pci_generic_config_write,
+ }
+};
Hello!
On Tuesday 05 October 2021 10:57:18 Jeremy Linton wrote:
Hi,
On 10/5/21 10:32 AM, Bjorn Helgaas wrote:
quoted
On Thu, Aug 26, 2021 at 02:15:55AM -0500, Jeremy Linton wrote:
quoted
Additionally, some basic bus/device filtering exist to avoid sending
config transactions to invalid devices on the RP's primary or
secondary bus. A basic link check is also made to assure that
something is operational on the secondary side before probing the
remainder of the config space. If either of these constraints are
violated and a config operation is lost in the ether because an EP
doesn't respond an unrecoverable SERROR is raised.
It's not "lost"; I assume the root port raises an error because it
can't send a transaction over a link that is down.
The problem is AFAIK because the root port doesn't do that.
Interesting! Does it mean that PCIe Root Complex / Host Bridge (which I
guess contains also logic for Root Port) does not signal transaction
failure for config requests? Or it is just your opinion? Because I'm
dealing with similar issues and I'm trying to find a way how to detect
if some PCIe IP signal transaction error via AXI SLVERR response OR it
just does not send any response back. So if you know some way how to
check which one it is, I would like to know it too.
quoted
Is "SERROR" an ARM64 thing? My guess is the root port would raise an
Unsupported Request error or similar, and the root complex turns that
into a system-specific SERROR?
Yes, SError is arm64 specific. It is asynchronous CPU interrupt and
syndrome code then contains what happened.
AFAIK, what is happening here the CPU core has an outstanding R/W request
for which it never receives a response from the root port. So basically its
an interconnect protocol violation that the CPU is complaining about rather
than something PCIe specific.
Could you describe (ideally in commit message) which SError is
triggered? Normally if kernel receive SError interrupt it also puts into
dmesg or oops message also syndrome code which describe what kind of
error / event occurred. It could help also to other understand what is
happening there.
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
On Thursday 26 August 2021 02:15:56 Jeremy Linton wrote:
quoted hunk
Now that there is a bcm2711 quirk, it needs to be enabled when the
MCFG is missing. Use an ACPI namespace _DSD property
"linux-ecam-quirk-id" as an alternative to the MCFG OEM.
Signed-off-by: Jeremy Linton <redacted>
Acked-by: Florian Fainelli <f.fainelli@gmail.com>
Acked-by: Bjorn Helgaas <bhelgaas@google.com>
---
drivers/acpi/pci_mcfg.c | 17 +++++++++++++++++
1 file changed, 17 insertions(+)
Hello!
According to discussion described in email [1], adding a new MCFG quirk
(like above) into kernel requires adding some errata entry for
documenting buggy HW.
But this patch series does not introduce any new errata entry.
Bjorn, could you look at how to properly document these "hw bugs"?
I guess there would be lot of more requests for adding MCFG quirks as
now according to [1], doors are open for them. And it is possible that
after more years nobody would be able to maintain these quirks if would
not be properly documented.
[1] - https://lore.kernel.org/linux-pci/20210325131231.GA18590@e121166-lin.cambridge.arm.com/
quoted hunk
};
static char mcfg_oem_id[ACPI_OEM_ID_SIZE];
@@ -198,8 +201,22 @@ static void pci_mcfg_apply_quirks(struct acpi_pci_root *root, u16 segment = root->segment; struct resource *bus_range = &root->secondary; struct mcfg_fixup *f;+ const char *soc; int i;+ /*+ * This may be a machine with a PCI/SMC conduit, which means it doesn't+ * have an MCFG. Use an ACPI namespace definition instead.+ */+ if (!fwnode_property_read_string(acpi_fwnode_handle(root->device),+ "linux-ecam-quirk-id", &soc)) {+ if (strlen(soc) != ACPI_OEM_ID_SIZE)+ dev_err(&root->device->dev, "ECAM quirk should be %d characters\n",+ ACPI_OEM_ID_SIZE);+ else+ memcpy(mcfg_oem_id, soc, ACPI_OEM_ID_SIZE);+ }+ for (i = 0, f = mcfg_quirks; i < ARRAY_SIZE(mcfg_quirks); i++, f++) { if (pci_mcfg_quirk_matches(f, segment, bus_range)) { if (f->cfgres.start)
From: Jeremy Linton <hidden> Date: 2021-10-05 22:25:40
Hi,
On 10/5/21 2:43 PM, Pali Rohár wrote:
Hello!
On Tuesday 05 October 2021 10:57:18 Jeremy Linton wrote:
quoted
Hi,
On 10/5/21 10:32 AM, Bjorn Helgaas wrote:
quoted
On Thu, Aug 26, 2021 at 02:15:55AM -0500, Jeremy Linton wrote:
quoted
Additionally, some basic bus/device filtering exist to avoid sending
config transactions to invalid devices on the RP's primary or
secondary bus. A basic link check is also made to assure that
something is operational on the secondary side before probing the
remainder of the config space. If either of these constraints are
violated and a config operation is lost in the ether because an EP
doesn't respond an unrecoverable SERROR is raised.
It's not "lost"; I assume the root port raises an error because it
can't send a transaction over a link that is down.
The problem is AFAIK because the root port doesn't do that.
Interesting! Does it mean that PCIe Root Complex / Host Bridge (which I
guess contains also logic for Root Port) does not signal transaction
failure for config requests? Or it is just your opinion? Because I'm
dealing with similar issues and I'm trying to find a way how to detect
if some PCIe IP signal transaction error via AXI SLVERR response OR it
just does not send any response back. So if you know some way how to
check which one it is, I would like to know it too.
This is my _opinion_ based on what I've heard of some other IP
integration issues, and what i've seen poking at this one from the
perspective of a SW guy rather than a HW guy. So, basically worthless.
But, you should consider that most of these cores/interconnects aren't
aware of PCIe completion semantics so its the root ports responsibility
to say, gracefully translate a non-posted write that doesn't have a
completion for the interconnects its attached to, rather than tripping
something generic like a SLVERR.
Anyway, for this I would poke around the pile of exception registers,
with your specific processors manual handy because a lot of them are
implementation defined.
quoted
quoted
Is "SERROR" an ARM64 thing? My guess is the root port would raise an
Unsupported Request error or similar, and the root complex turns that
into a system-specific SERROR?
Yes, SError is arm64 specific. It is asynchronous CPU interrupt and
syndrome code then contains what happened.
quoted
AFAIK, what is happening here the CPU core has an outstanding R/W request
for which it never receives a response from the root port. So basically its
an interconnect protocol violation that the CPU is complaining about rather
than something PCIe specific.
Could you describe (ideally in commit message) which SError is
triggered? Normally if kernel receive SError interrupt it also puts into
dmesg or oops message also syndrome code which describe what kind of
error / event occurred. It could help also to other understand what is
happening there.
On Tue, Oct 05, 2021 at 10:43:32AM -0500, Jeremy Linton wrote:
On 10/5/21 10:10 AM, Bjorn Helgaas wrote:
quoted
On Thu, Aug 26, 2021 at 02:15:56AM -0500, Jeremy Linton wrote:
quoted
Now that there is a bcm2711 quirk, it needs to be enabled when the
MCFG is missing. Use an ACPI namespace _DSD property
"linux-ecam-quirk-id" as an alternative to the MCFG OEM.
Signed-off-by: Jeremy Linton <redacted>
Acked-by: Florian Fainelli <f.fainelli@gmail.com>
Acked-by: Bjorn Helgaas <bhelgaas@google.com>
---
drivers/acpi/pci_mcfg.c | 17 +++++++++++++++++
1 file changed, 17 insertions(+)
From a reviewing perspective, it's not obvious why soc must be exactly
ACPI_OEM_ID_SIZE. Does that imply space-padding in the DT string or
something?
This is at the moment an ACPI only DSD, and it must follow the MADT OEM_ID
format for now because we are effectively just overriding that field. The
rest of the code in this module is just treating it as a fixed 6 bytes.
quoted
Is there any documentation for this DT property?
Its not a DT property, and its unclear since its linux only if it
belongs in previously linked ACPI registry.
Oh, right, it comes from a _DSD.
quoted
Also not obvious why strlen() is safe here. I mean, I looked a couple
levels deep in fwnode_property_read_string(), but whatever guarantees
null termination is buried pretty deep.
I've not tracked down who, if anyone other than the AML compiler is
guaranteeing a null. The spec says something to the effect "Most other
string, however, are of variable-length and are automatically null
terminated by the compiler". Not sure if that helps any.
Doesn't help for me. The PCI core shouldn't go in the weeds no matter
what junk we might get from an AML compiler. Maybe
fwnode_property_read_string() guarantees null termination, but it's
not documented and not easy to verify.
I think a strncpy() here might be better. Not sure it's worthwhile to
emit a specific error message for the wrong length.
quoted
It seems a little weird to use an MCFG quirk mechanism when there's no
MCFG at all on this platform.
Well its just a point to hook in a CFG space quirk, and since that
is what most of the MCFG quirks are, it seemed reasonable to reuse
it rather than recreate it.
Yeah, it's ugly no matter how we slice it. The pci_no_msi()
especially has nothing to do with ECAM at all. But I don't know how
to identify this thing for a quirk. PNP0A08 devices really rely on
ECAM or a system firmware config accessor.
quoted
quoted
+ dev_err(&root->device->dev, "ECAM quirk should be %d characters\n",
+ ACPI_OEM_ID_SIZE);
+ else
+ memcpy(mcfg_oem_id, soc, ACPI_OEM_ID_SIZE);
+ }
+
for (i = 0, f = mcfg_quirks; i < ARRAY_SIZE(mcfg_quirks); i++, f++) {
if (pci_mcfg_quirk_matches(f, segment, bus_range)) {
if (f->cfgres.start)
--
2.31.1
From: Jeremy Linton <hidden> Date: 2021-10-05 22:44:48
Hi,
On 10/5/21 3:02 PM, Pali Rohár wrote:
On Thursday 26 August 2021 02:15:56 Jeremy Linton wrote:
quoted
Now that there is a bcm2711 quirk, it needs to be enabled when the
MCFG is missing. Use an ACPI namespace _DSD property
"linux-ecam-quirk-id" as an alternative to the MCFG OEM.
Signed-off-by: Jeremy Linton <redacted>
Acked-by: Florian Fainelli <f.fainelli@gmail.com>
Acked-by: Bjorn Helgaas <bhelgaas@google.com>
---
drivers/acpi/pci_mcfg.c | 17 +++++++++++++++++
1 file changed, 17 insertions(+)
Hello!
According to discussion described in email [1], adding a new MCFG quirk
(like above) into kernel requires adding some errata entry for
documenting buggy HW.
But this patch series does not introduce any new errata entry.
Nor did the quirk following that email, which was merged. Presumably
because I'm not sure anyone can predict the future, and some of the
points in that posting were made simply to fill gaps in the arguments
around why the SMC is/was a better plan. The final point about requiring
a MCFG is also flies in the face of the fact that there is an Arm/Pci
Standardized way to deal with these problems which is supported by other
OS's running on these platforms and it requires that MFCG is missing.
The idea that MCFG will magically appear for only Linux and contain
relevant info (like the non even power of two cfg region on this SoC) is
a bit wishful.
I'm certainly in no place to claim future PCIe compliance for Broadcom's
SoC's, nor its lifecycle. I'm betting few people submitting Linux
patches are, particularly for mostly community supported projects like
the RPi4/CM4/ACPI port. I'm more than happy to hack/tweak future
problems with this code, and possibly even extend it if needed. Thats
about the extent of what I can do.
Thanks,
Bjorn, could you look at how to properly document these "hw bugs"?
I guess there would be lot of more requests for adding MCFG quirks as
now according to [1], doors are open for them. And it is possible that
after more years nobody would be able to maintain these quirks if would
not be properly documented.
[1] - https://lore.kernel.org/linux-pci/20210325131231.GA18590@e121166-lin.cambridge.arm.com/
quoted
};
static char mcfg_oem_id[ACPI_OEM_ID_SIZE];
@@ -198,8 +201,22 @@ static void pci_mcfg_apply_quirks(struct acpi_pci_root *root, u16 segment = root->segment; struct resource *bus_range = &root->secondary; struct mcfg_fixup *f;+ const char *soc; int i;+ /*+ * This may be a machine with a PCI/SMC conduit, which means it doesn't+ * have an MCFG. Use an ACPI namespace definition instead.+ */+ if (!fwnode_property_read_string(acpi_fwnode_handle(root->device),+ "linux-ecam-quirk-id", &soc)) {+ if (strlen(soc) != ACPI_OEM_ID_SIZE)+ dev_err(&root->device->dev, "ECAM quirk should be %d characters\n",+ ACPI_OEM_ID_SIZE);+ else+ memcpy(mcfg_oem_id, soc, ACPI_OEM_ID_SIZE);+ }+ for (i = 0, f = mcfg_quirks; i < ARRAY_SIZE(mcfg_quirks); i++, f++) { if (pci_mcfg_quirk_matches(f, segment, bus_range)) { if (f->cfgres.start)
From: Jeremy Linton <hidden> Date: 2021-10-05 23:32:45
Hi,
On 10/5/21 5:31 PM, Bjorn Helgaas wrote:
On Tue, Oct 05, 2021 at 10:43:32AM -0500, Jeremy Linton wrote:
quoted
On 10/5/21 10:10 AM, Bjorn Helgaas wrote:
quoted
On Thu, Aug 26, 2021 at 02:15:56AM -0500, Jeremy Linton wrote:
quoted
Now that there is a bcm2711 quirk, it needs to be enabled when the
MCFG is missing. Use an ACPI namespace _DSD property
"linux-ecam-quirk-id" as an alternative to the MCFG OEM.
Signed-off-by: Jeremy Linton <redacted>
Acked-by: Florian Fainelli <f.fainelli@gmail.com>
Acked-by: Bjorn Helgaas <bhelgaas@google.com>
---
drivers/acpi/pci_mcfg.c | 17 +++++++++++++++++
1 file changed, 17 insertions(+)
From a reviewing perspective, it's not obvious why soc must be exactly
ACPI_OEM_ID_SIZE. Does that imply space-padding in the DT string or
something?
This is at the moment an ACPI only DSD, and it must follow the MADT OEM_ID
format for now because we are effectively just overriding that field. The
rest of the code in this module is just treating it as a fixed 6 bytes.
quoted
Is there any documentation for this DT property?
Its not a DT property, and its unclear since its linux only if it
belongs in previously linked ACPI registry.
Oh, right, it comes from a _DSD.
quoted
quoted
Also not obvious why strlen() is safe here. I mean, I looked a couple
levels deep in fwnode_property_read_string(), but whatever guarantees
null termination is buried pretty deep.
I've not tracked down who, if anyone other than the AML compiler is
guaranteeing a null. The spec says something to the effect "Most other
string, however, are of variable-length and are automatically null
terminated by the compiler". Not sure if that helps any.
Doesn't help for me. The PCI core shouldn't go in the weeds no matter
what junk we might get from an AML compiler. Maybe
fwnode_property_read_string() guarantees null termination, but it's
not documented and not easy to verify.
I think a strncpy() here might be better. Not sure it's worthwhile to
emit a specific error message for the wrong length.
I think we went around about this a bit, but yes strncpy() is exactly
what we want because the rest of the code assumes 6 non-null terminated
characters and strncpy won't terminate it if its longer. OTOH, i'm not
sure we really want shorter strings padded with nulls either.
strncpy() is easy though, so sure. <shrug>
quoted
quoted
It seems a little weird to use an MCFG quirk mechanism when there's no
MCFG at all on this platform.
Well its just a point to hook in a CFG space quirk, and since that
is what most of the MCFG quirks are, it seemed reasonable to reuse
it rather than recreate it.
Yeah, it's ugly no matter how we slice it. The pci_no_msi()
especially has nothing to do with ECAM at all. But I don't know how
to identify this thing for a quirk. PNP0A08 devices really rely on
ECAM or a system firmware config accessor.
quoted
quoted
quoted
+ dev_err(&root->device->dev, "ECAM quirk should be %d characters\n",
+ ACPI_OEM_ID_SIZE);
+ else
+ memcpy(mcfg_oem_id, soc, ACPI_OEM_ID_SIZE);
+ }
+
for (i = 0, f = mcfg_quirks; i < ARRAY_SIZE(mcfg_quirks); i++, f++) {
if (pci_mcfg_quirk_matches(f, segment, bus_range)) {
if (f->cfgres.start)
--
2.31.1
Hello!
On Tuesday 05 October 2021 10:57:18 Jeremy Linton wrote:
quoted
Hi,
On 10/5/21 10:32 AM, Bjorn Helgaas wrote:
quoted
On Thu, Aug 26, 2021 at 02:15:55AM -0500, Jeremy Linton wrote:
quoted
Additionally, some basic bus/device filtering exist to avoid sending
config transactions to invalid devices on the RP's primary or
secondary bus. A basic link check is also made to assure that
something is operational on the secondary side before probing the
remainder of the config space. If either of these constraints are
violated and a config operation is lost in the ether because an EP
doesn't respond an unrecoverable SERROR is raised.
It's not "lost"; I assume the root port raises an error because it
can't send a transaction over a link that is down.
The problem is AFAIK because the root port doesn't do that.
Interesting! Does it mean that PCIe Root Complex / Host Bridge (which I
guess contains also logic for Root Port) does not signal transaction
failure for config requests? Or it is just your opinion? Because I'm
dealing with similar issues and I'm trying to find a way how to detect
if some PCIe IP signal transaction error via AXI SLVERR response OR it
just does not send any response back. So if you know some way how to
check which one it is, I would like to know it too.
This is my _opinion_ based on what I've heard of some other IP
integration issues, and what i've seen poking at this one from the
perspective of a SW guy rather than a HW guy. So, basically worthless.
But, you should consider that most of these cores/interconnects aren't
aware of PCIe completion semantics so its the root ports responsibility
to say, gracefully translate a non-posted write that doesn't have a
completion for the interconnects its attached to, rather than tripping
something generic like a SLVERR.
Anyway, for this I would poke around the pile of exception registers,
with your specific processors manual handy because a lot of them are
implementation defined.
I should be able to get you an answer in the new few days whether
configuration space requests also generate an error towards the ARM CPU,
since memory space requests most definitively do.
--
Florian
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
Hello!
On Tuesday 05 October 2021 10:57:18 Jeremy Linton wrote:
quoted
Hi,
On 10/5/21 10:32 AM, Bjorn Helgaas wrote:
quoted
On Thu, Aug 26, 2021 at 02:15:55AM -0500, Jeremy Linton wrote:
quoted
Additionally, some basic bus/device filtering exist to avoid sending
config transactions to invalid devices on the RP's primary or
secondary bus. A basic link check is also made to assure that
something is operational on the secondary side before probing the
remainder of the config space. If either of these constraints are
violated and a config operation is lost in the ether because an EP
doesn't respond an unrecoverable SERROR is raised.
It's not "lost"; I assume the root port raises an error because it
can't send a transaction over a link that is down.
The problem is AFAIK because the root port doesn't do that.
Interesting! Does it mean that PCIe Root Complex / Host Bridge (which I
guess contains also logic for Root Port) does not signal transaction
failure for config requests? Or it is just your opinion? Because I'm
dealing with similar issues and I'm trying to find a way how to detect
if some PCIe IP signal transaction error via AXI SLVERR response OR it
just does not send any response back. So if you know some way how to
check which one it is, I would like to know it too.
This is my _opinion_ based on what I've heard of some other IP
integration issues, and what i've seen poking at this one from the
perspective of a SW guy rather than a HW guy. So, basically worthless.
But, you should consider that most of these cores/interconnects aren't
aware of PCIe completion semantics so its the root ports
responsibility to say, gracefully translate a non-posted write that
doesn't have a completion for the interconnects its attached to,
rather than tripping something generic like a SLVERR.
Anyway, for this I would poke around the pile of exception registers,
with your specific processors manual handy because a lot of them are
implementation defined.
I should be able to get you an answer in the new few days whether
configuration space requests also generate an error towards the ARM CPU,
since memory space requests most definitively do.
On Friday 22 October 2021 10:04:36 Florian Fainelli wrote:
On 10/5/21 7:07 PM, Florian Fainelli wrote:
quoted
On 10/5/2021 3:25 PM, Jeremy Linton wrote:
quoted
Hi,
On 10/5/21 2:43 PM, Pali Rohár wrote:
quoted
Hello!
On Tuesday 05 October 2021 10:57:18 Jeremy Linton wrote:
quoted
Hi,
On 10/5/21 10:32 AM, Bjorn Helgaas wrote:
quoted
On Thu, Aug 26, 2021 at 02:15:55AM -0500, Jeremy Linton wrote:
quoted
Additionally, some basic bus/device filtering exist to avoid sending
config transactions to invalid devices on the RP's primary or
secondary bus. A basic link check is also made to assure that
something is operational on the secondary side before probing the
remainder of the config space. If either of these constraints are
violated and a config operation is lost in the ether because an EP
doesn't respond an unrecoverable SERROR is raised.
It's not "lost"; I assume the root port raises an error because it
can't send a transaction over a link that is down.
The problem is AFAIK because the root port doesn't do that.
Interesting! Does it mean that PCIe Root Complex / Host Bridge (which I
guess contains also logic for Root Port) does not signal transaction
failure for config requests? Or it is just your opinion? Because I'm
dealing with similar issues and I'm trying to find a way how to detect
if some PCIe IP signal transaction error via AXI SLVERR response OR it
just does not send any response back. So if you know some way how to
check which one it is, I would like to know it too.
This is my _opinion_ based on what I've heard of some other IP
integration issues, and what i've seen poking at this one from the
perspective of a SW guy rather than a HW guy. So, basically worthless.
But, you should consider that most of these cores/interconnects aren't
aware of PCIe completion semantics so its the root ports
responsibility to say, gracefully translate a non-posted write that
doesn't have a completion for the interconnects its attached to,
rather than tripping something generic like a SLVERR.
Anyway, for this I would poke around the pile of exception registers,
with your specific processors manual handy because a lot of them are
implementation defined.
I should be able to get you an answer in the new few days whether
configuration space requests also generate an error towards the ARM CPU,
since memory space requests most definitively do.
Did not get an answer from the design team, but going through our bug
tracker, there were evidences of configuration space accesses also
generating external aborts:
[ 8.988237] Unhandled fault: synchronous external abort (0x96000210) at 0xffffff8009539004
[ 9.026698] PC is at pci_generic_config_read32+0x30/0xb0
So this is error caused by reading from config space.
Can you check if also writing to config space can trigger some crash? If
yes, I would like to know if write would be also synchronous or rather
asynchronous abort.
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
On Friday 22 October 2021 10:04:36 Florian Fainelli wrote:
quoted
On 10/5/21 7:07 PM, Florian Fainelli wrote:
quoted
On 10/5/2021 3:25 PM, Jeremy Linton wrote:
quoted
Hi,
On 10/5/21 2:43 PM, Pali Rohár wrote:
quoted
Hello!
On Tuesday 05 October 2021 10:57:18 Jeremy Linton wrote:
quoted
Hi,
On 10/5/21 10:32 AM, Bjorn Helgaas wrote:
quoted
On Thu, Aug 26, 2021 at 02:15:55AM -0500, Jeremy Linton wrote:
quoted
Additionally, some basic bus/device filtering exist to avoid sending
config transactions to invalid devices on the RP's primary or
secondary bus. A basic link check is also made to assure that
something is operational on the secondary side before probing the
remainder of the config space. If either of these constraints are
violated and a config operation is lost in the ether because an EP
doesn't respond an unrecoverable SERROR is raised.
It's not "lost"; I assume the root port raises an error because it
can't send a transaction over a link that is down.
The problem is AFAIK because the root port doesn't do that.
Interesting! Does it mean that PCIe Root Complex / Host Bridge (which I
guess contains also logic for Root Port) does not signal transaction
failure for config requests? Or it is just your opinion? Because I'm
dealing with similar issues and I'm trying to find a way how to detect
if some PCIe IP signal transaction error via AXI SLVERR response OR it
just does not send any response back. So if you know some way how to
check which one it is, I would like to know it too.
This is my _opinion_ based on what I've heard of some other IP
integration issues, and what i've seen poking at this one from the
perspective of a SW guy rather than a HW guy. So, basically worthless.
But, you should consider that most of these cores/interconnects aren't
aware of PCIe completion semantics so its the root ports
responsibility to say, gracefully translate a non-posted write that
doesn't have a completion for the interconnects its attached to,
rather than tripping something generic like a SLVERR.
Anyway, for this I would poke around the pile of exception registers,
with your specific processors manual handy because a lot of them are
implementation defined.
I should be able to get you an answer in the new few days whether
configuration space requests also generate an error towards the ARM CPU,
since memory space requests most definitively do.
Did not get an answer from the design team, but going through our bug
tracker, there were evidences of configuration space accesses also
generating external aborts:
[ 8.988237] Unhandled fault: synchronous external abort (0x96000210) at 0xffffff8009539004
[ 9.026698] PC is at pci_generic_config_read32+0x30/0xb0
So this is error caused by reading from config space.
Can you check if also writing to config space can trigger some crash? If
yes, I would like to know if write would be also synchronous or rather
asynchronous abort.
On Friday 22 October 2021 10:29:48 Florian Fainelli wrote:
On 10/22/21 10:17 AM, Pali Rohár wrote:
quoted
On Friday 22 October 2021 10:04:36 Florian Fainelli wrote:
quoted
On 10/5/21 7:07 PM, Florian Fainelli wrote:
quoted
On 10/5/2021 3:25 PM, Jeremy Linton wrote:
quoted
Hi,
On 10/5/21 2:43 PM, Pali Rohár wrote:
quoted
Hello!
On Tuesday 05 October 2021 10:57:18 Jeremy Linton wrote:
quoted
Hi,
On 10/5/21 10:32 AM, Bjorn Helgaas wrote:
quoted
On Thu, Aug 26, 2021 at 02:15:55AM -0500, Jeremy Linton wrote:
quoted
Additionally, some basic bus/device filtering exist to avoid sending
config transactions to invalid devices on the RP's primary or
secondary bus. A basic link check is also made to assure that
something is operational on the secondary side before probing the
remainder of the config space. If either of these constraints are
violated and a config operation is lost in the ether because an EP
doesn't respond an unrecoverable SERROR is raised.
It's not "lost"; I assume the root port raises an error because it
can't send a transaction over a link that is down.
The problem is AFAIK because the root port doesn't do that.
Interesting! Does it mean that PCIe Root Complex / Host Bridge (which I
guess contains also logic for Root Port) does not signal transaction
failure for config requests? Or it is just your opinion? Because I'm
dealing with similar issues and I'm trying to find a way how to detect
if some PCIe IP signal transaction error via AXI SLVERR response OR it
just does not send any response back. So if you know some way how to
check which one it is, I would like to know it too.
This is my _opinion_ based on what I've heard of some other IP
integration issues, and what i've seen poking at this one from the
perspective of a SW guy rather than a HW guy. So, basically worthless.
But, you should consider that most of these cores/interconnects aren't
aware of PCIe completion semantics so its the root ports
responsibility to say, gracefully translate a non-posted write that
doesn't have a completion for the interconnects its attached to,
rather than tripping something generic like a SLVERR.
Anyway, for this I would poke around the pile of exception registers,
with your specific processors manual handy because a lot of them are
implementation defined.
I should be able to get you an answer in the new few days whether
configuration space requests also generate an error towards the ARM CPU,
since memory space requests most definitively do.
Did not get an answer from the design team, but going through our bug
tracker, there were evidences of configuration space accesses also
generating external aborts:
[ 8.988237] Unhandled fault: synchronous external abort (0x96000210) at 0xffffff8009539004
[ 9.026698] PC is at pci_generic_config_read32+0x30/0xb0
So this is error caused by reading from config space.
Can you check if also writing to config space can trigger some crash? If
yes, I would like to know if write would be also synchronous or rather
asynchronous abort.
Yes it does and AFAICT it always shows up as a system error interrupt,
here is an example:
# setpci -d *:* latency_timer=40
[ 25.909644] SError Interrupt on CPU2, code 0xbf000002 -- SError
[ 25.909652] pc : pci_user_write_config_byte+0x6c/0x78
[ 25.909706] Kernel panic - not syncing: Asynchronous SError Interrupt
Ok! So writing to config space cause asynchronous abort.
Looking at the codes and 0x96000210 on all ARMv8 should be Data Abort.
0xbf...... on ARMv8 is SError interrupt and other bits are CPU core
specific. What CPU core do you have on this machine? I have just decoder
for A53 core and on this core value 0xbf000002 means "SLVERR on external
access". But I guess that it would mean also SLVERR for your CPU core.
Because Exactly same behavior I'm seeing with PCIe controller on A3720
SoC which has A53 core. It looks like that PCIe controller translates
PCIe CA and UR responses to AXI SLVERR responses which are delivered to
CPU and kernel just see these fatal error interrupts. And same issue is
not only for config requests but also for memory read / write commands.
In my case PCIe controller really receives response (timeout does not
occur) from PCIe core (which probably timeouts as it cannot send message
when link is down) but instead of translating them to SLVOK with
fabricated 0xffffffff response it sends to CPU that fatal SLVERR.
I was told that the fix for this kind of issue is to "reconfigure" PCIe
controller to never send SLVERR to CPU. And instead fabricate 0xffffffff
SLVOK response. It should be configurable in PCIe wrapper or PCIe glue
IP which do connection between CPU / AXI and PCIe core.
I do not know if there is any way how to "ignores" these SLVERR
responses from PCIe controller sent to CPU.
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel