From 068fe919613197bf221c00fb84a1d94c66a7a8ca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pali=20Roh=C3=A1r?= Date: Sat, 26 Jun 2021 16:26:56 +0200 Subject: [PATCH] fix(plat/marvell/a3k): update information about PCIe abort hack MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A3700 plat_ea_handler was introduced into TF-A codebase just because of bugs in U-Boot and Linux kernel PCIe controller driver pci-aardvark.c. These bugs were finally fixed in both U-Boot and Linux kernel drivers: https://source.denx.de/u-boot/u-boot/-/commit/eccbd4ad8e4e182638eafbfb87ac139c04f24a01 https://git.kernel.org/stable/c/f18139966d072dab8e4398c95ce955a9742e04f7 Add all these information into comments, including printing error message into a3k plat_ea_handler. Also check that abort is really asynchronous and comes from lower level than EL3. Signed-off-by: Pali Rohár Change-Id: I46318d221b39773d5e25b3a0221d7738736ffdf1 --- plat/marvell/armada/a3k/common/a3700_ea.c | 65 ++++++++++++++++++++++- 1 file changed, 63 insertions(+), 2 deletions(-) diff --git a/plat/marvell/armada/a3k/common/a3700_ea.c b/plat/marvell/armada/a3k/common/a3700_ea.c index 3a4f7203b..dde92e38a 100644 --- a/plat/marvell/armada/a3k/common/a3700_ea.c +++ b/plat/marvell/armada/a3k/common/a3700_ea.c @@ -8,14 +8,75 @@ #include #include #include +#include -#define ADVK_SERROR_SYNDROME 0xbf000002 +#define A53_SERR_INT_AXI_SLVERR_ON_EXTERNAL_ACCESS 0xbf000002 + +#if !ENABLE_BACKTRACE +static const char *get_el_str(unsigned int el) +{ + if (el == MODE_EL3) { + return "EL3"; + } else if (el == MODE_EL2) { + return "EL2"; + } + return "S-EL1"; +} +#endif /* !ENABLE_BACKTRACE */ void plat_ea_handler(unsigned int ea_reason, uint64_t syndrome, void *cookie, void *handle, uint64_t flags) { - if (syndrome == ADVK_SERROR_SYNDROME) + unsigned int level = (unsigned int)GET_EL(read_spsr_el3()); + + /* + * Asynchronous External Abort with syndrome 0xbf000002 on Cortex A53 + * core means SError interrupt caused by AXI SLVERR on external access. + * + * In most cases this indicates a bug in U-Boot or Linux kernel driver + * pci-aardvark.c which implements access to A3700 PCIe config space. + * Driver does not wait for PCIe PIO transfer completion and try to + * start a new PCIe PIO transfer while previous has not finished yet. + * A3700 PCIe controller in this case sends SLVERR via AXI which results + * in a fatal Asynchronous SError interrupt on Cortex A53 CPU. + * + * Following patches fix that bug in U-Boot and Linux kernel drivers: + * https://source.denx.de/u-boot/u-boot/-/commit/eccbd4ad8e4e182638eafbfb87ac139c04f24a01 + * https://git.kernel.org/stable/c/f18139966d072dab8e4398c95ce955a9742e04f7 + * + * As a hacky workaround for unpatched U-Boot and Linux kernel drivers + * ignore all asynchronous aborts with that syndrome value received on + * CPU from level lower than EL3. + * + * Because these aborts are delivered on CPU asynchronously, they are + * imprecise and we cannot check the real reason of abort and neither + * who and why sent this abort. We expect that on A3700 it is always + * PCIe controller. + * + * Hence ignoring all aborts with this syndrome value is just a giant + * hack that we need only because of bugs in old U-Boot and Linux kernel + * versions and because it was decided that TF-A would implement this + * hack for U-Boot and Linux kernel it in this way. New patched U-Boot + * and kernel versions do not need it anymore. + * + * Links to discussion about this workaround: + * https://lore.kernel.org/linux-pci/20190316161243.29517-1-repk@triplefau.lt/ + * https://lore.kernel.org/linux-pci/971be151d24312cc533989a64bd454b4@www.loen.fr/ + * https://review.trustedfirmware.org/c/TF-A/trusted-firmware-a/+/1541 + */ + if (level < MODE_EL3 && ea_reason == ERROR_EA_ASYNC && + syndrome == A53_SERR_INT_AXI_SLVERR_ON_EXTERNAL_ACCESS) { + ERROR_NL(); + ERROR("Ignoring Asynchronous External Abort with" + " syndrome 0x%llx received on 0x%lx from %s\n", + syndrome, read_mpidr_el1(), get_el_str(level)); + ERROR("SError interrupt: AXI SLVERR on external access\n"); + ERROR("This indicates a bug in pci-aardvark.c driver\n"); + ERROR("Please update U-Boot/Linux to the latest version\n"); + ERROR_NL(); + console_flush(); return; + } plat_default_ea_handler(ea_reason, syndrome, cookie, handle, flags); }