Re: [REGRESSION, bisect] pci: artpec-6: imprecise external abort

From: Joao Pinto
Date: Fri Oct 14 2016 - 09:15:02 EST


Hi Niklas,


On 10/14/2016 1:41 PM, Niklas Cassel wrote:
> Hello
>
> Because of recent changes to drivers/pci/host/pcie-artpec6.c,
> I was going to try out Bjorn's tag pci-v4.9-changes-2,
> however I was greeted by an imprecise external abort:
>
>
> [ 0.613082] Trying to unpack rootfs image as initramfs...
> [ 0.886577] Freeing initrd memory: 4724K (c2900000 - c2d9d000)

(snip)


> [ 1.282723] [<c07a1710>] (driver_register) from [<c0301eb4>] (do_one_initcall+0x44/0x174)
> [ 1.290919] [<c0301eb4>] (do_one_initcall) from [<c1000dc0>] (kernel_init_freeable+0x158/0x1e8)
> [ 1.299636] [<c1000dc0>] (kernel_init_freeable) from [<c0b047fc>] (kernel_init+0x8/0x10c)
> [ 1.307828] [<c0b047fc>] (kernel_init) from [<c0307e78>] (ret_from_fork+0x14/0x3c)
> [ 1.315404] Code: eafffef9 e5943008 e5930900 f57ff04f (eaffff69)
> [ 1.321503] ---[ end trace b458093682b1fb9a ]---
>
>
> a git bisect later and the cause appears to be a0601a470537 ("PCI: designware: Add iATU Unroll feature")
>
> the following patch gives me a working system again:
>
> diff --git a/drivers/pci/host/pcie-designware.c b/drivers/pci/host/pcie-designware.c
> index 035f50c03281..74510508fafc 100644
> --- a/drivers/pci/host/pcie-designware.c
> +++ b/drivers/pci/host/pcie-designware.c
> @@ -637,11 +637,11 @@ int dw_pcie_host_init(struct pcie_port *pp)
> }
> }
>
> - pp->iatu_unroll_enabled = dw_pcie_iatu_unroll_enabled(pp);
> -
> if (pp->ops->host_init)
> pp->ops->host_init(pp);
>
> + pp->iatu_unroll_enabled = dw_pcie_iatu_unroll_enabled(pp);
> +
> pp->root_bus_nr = pp->busn->start;
> if (IS_ENABLED(CONFIG_PCI_MSI)) {
> bus = pci_scan_root_bus_msi(pp->dev, pp->root_bus_nr,

Before invoking the host initialization routine, the pcie driver must check if
it going to work in Unroll Mode or not. Your work around un fortunately is not
valid, because you are forcing the host init to be always in legacy mode since
pp->iatu_unroll_enabled will be 0 (Legacy).

If you check the driver will consider the iATU mode to be Unroll if the PortView
register has the value 0xFFFFFFFF, which in 4.80 core means that the Core has
Unroll activated. From what you are refering, I think that in your setup, the
driver is assuming that your Core is in Unroll Mode for some reason. Could you
please check the value of the PortView Register?

Thanks.

Joao

>
>
> From the ARTPEC-6 SoC manual:
> By default, the PCI Express interface shall be held in reset and clock-gated.
> Software is required to enable the relevant modules
> (turns on clocks and de-asserts reset) before these modules can be used.
>
> Turning on the clocks and de-asserting reset is done in pp->ops->host_init().
> We get an external abort when calling dw_pcie_iatu_unroll_enabled,
> since that function does a read from the IP before we are allowed to do
> AXI transfers (at least in the ARTPEC-6 case, might be the same for some
> other SoCs).
>
> It appears that dw_pcie_iatu_unroll_enabled was actually called _before_
> host_init() in v4 of Joao's patch, but was changed to after host_init() in v5,
> unfortunately the patch doesn't state a reason for the move.
>